1 2 /* 3 This file contains routines for basic map object implementation. 4 */ 5 6 #include <petsc/private/isimpl.h> /*I "petscis.h" I*/ 7 8 /*@ 9 PetscLayoutCreate - Allocates PetscLayout space and sets the PetscLayout contents to the default. 10 11 Collective 12 13 Input Parameters: 14 . comm - the MPI communicator 15 16 Output Parameters: 17 . map - the new PetscLayout 18 19 Level: advanced 20 21 Notes: 22 Typical calling sequence 23 .vb 24 PetscLayoutCreate(MPI_Comm,PetscLayout *); 25 PetscLayoutSetBlockSize(PetscLayout,bs); 26 PetscLayoutSetSize(PetscLayout,N); // or PetscLayoutSetLocalSize(PetscLayout,n); 27 PetscLayoutSetUp(PetscLayout); 28 .ve 29 Alternatively, 30 .vb 31 PetscLayoutCreateFromSizes(comm,n,N,bs,&layout); 32 .ve 33 34 Optionally use any of the following 35 .vb 36 PetscLayoutGetSize(PetscLayout,PetscInt *); 37 PetscLayoutGetLocalSize(PetscLayout,PetscInt *); 38 PetscLayoutGetRange(PetscLayout,PetscInt *rstart,PetscInt *rend); 39 PetscLayoutGetRanges(PetscLayout,const PetscInt *range[]); 40 PetscLayoutDestroy(PetscLayout*); 41 .ve 42 43 The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementations; it is often not needed in 44 user codes unless you really gain something in their use. 45 46 .seealso: `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutDestroy()`, 47 `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`, 48 `PetscLayoutCreateFromSizes()` 49 50 @*/ 51 PetscErrorCode PetscLayoutCreate(MPI_Comm comm, PetscLayout *map) 52 { 53 PetscFunctionBegin; 54 PetscCall(PetscNew(map)); 55 PetscCallMPI(MPI_Comm_size(comm, &(*map)->size)); 56 (*map)->comm = comm; 57 (*map)->bs = -1; 58 (*map)->n = -1; 59 (*map)->N = -1; 60 (*map)->range = NULL; 61 (*map)->range_alloc = PETSC_TRUE; 62 (*map)->rstart = 0; 63 (*map)->rend = 0; 64 (*map)->setupcalled = PETSC_FALSE; 65 (*map)->oldn = -1; 66 (*map)->oldN = -1; 67 (*map)->oldbs = -1; 68 PetscFunctionReturn(0); 69 } 70 71 /*@ 72 PetscLayoutCreateFromSizes - Allocates PetscLayout space, sets the layout sizes, and sets the layout up. 73 74 Collective 75 76 Input Parameters: 77 + comm - the MPI communicator 78 . n - the local size (or PETSC_DECIDE) 79 . N - the global size (or PETSC_DECIDE) 80 - bs - the block size (or PETSC_DECIDE) 81 82 Output Parameters: 83 . map - the new PetscLayout 84 85 Level: advanced 86 87 Notes: 88 $ PetscLayoutCreateFromSizes(comm,n,N,bs,&layout); 89 is a shorthand for 90 .vb 91 PetscLayoutCreate(comm,&layout); 92 PetscLayoutSetLocalSize(layout,n); 93 PetscLayoutSetSize(layout,N); 94 PetscLayoutSetBlockSize(layout,bs); 95 PetscLayoutSetUp(layout); 96 .ve 97 98 .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutDestroy()`, 99 `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`, `PetscLayoutCreateFromRanges()` 100 101 @*/ 102 PetscErrorCode PetscLayoutCreateFromSizes(MPI_Comm comm, PetscInt n, PetscInt N, PetscInt bs, PetscLayout *map) 103 { 104 PetscFunctionBegin; 105 PetscCall(PetscLayoutCreate(comm, map)); 106 PetscCall(PetscLayoutSetLocalSize(*map, n)); 107 PetscCall(PetscLayoutSetSize(*map, N)); 108 PetscCall(PetscLayoutSetBlockSize(*map, bs)); 109 PetscCall(PetscLayoutSetUp(*map)); 110 PetscFunctionReturn(0); 111 } 112 113 /*@ 114 PetscLayoutDestroy - Frees a map object and frees its range if that exists. 115 116 Collective 117 118 Input Parameters: 119 . map - the PetscLayout 120 121 Level: developer 122 123 Note: 124 The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementations; it is 125 recommended they not be used in user codes unless you really gain something in their use. 126 127 .seealso: `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutCreate()`, 128 `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()` 129 130 @*/ 131 PetscErrorCode PetscLayoutDestroy(PetscLayout *map) 132 { 133 PetscFunctionBegin; 134 if (!*map) PetscFunctionReturn(0); 135 if (!(*map)->refcnt--) { 136 if ((*map)->range_alloc) PetscCall(PetscFree((*map)->range)); 137 PetscCall(ISLocalToGlobalMappingDestroy(&(*map)->mapping)); 138 PetscCall(PetscFree((*map))); 139 } 140 *map = NULL; 141 PetscFunctionReturn(0); 142 } 143 144 /*@ 145 PetscLayoutCreateFromRanges - Creates a new PetscLayout with the given ownership ranges and sets it up. 146 147 Collective 148 149 Input Parameters: 150 + comm - the MPI communicator 151 . range - the array of ownership ranges for each rank with length commsize+1 152 . mode - the copy mode for range 153 - bs - the block size (or PETSC_DECIDE) 154 155 Output Parameters: 156 . newmap - the new PetscLayout 157 158 Level: developer 159 160 .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutDestroy()`, 161 `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`, `PetscLayoutCreateFromSizes()` 162 163 @*/ 164 PetscErrorCode PetscLayoutCreateFromRanges(MPI_Comm comm, const PetscInt range[], PetscCopyMode mode, PetscInt bs, PetscLayout *newmap) 165 { 166 PetscLayout map; 167 PetscMPIInt rank; 168 169 PetscFunctionBegin; 170 PetscCallMPI(MPI_Comm_rank(comm, &rank)); 171 PetscCall(PetscLayoutCreate(comm, &map)); 172 PetscCall(PetscLayoutSetBlockSize(map, bs)); 173 switch (mode) { 174 case PETSC_COPY_VALUES: 175 PetscCall(PetscMalloc1(map->size + 1, &map->range)); 176 PetscCall(PetscArraycpy(map->range, range, map->size + 1)); 177 break; 178 case PETSC_USE_POINTER: 179 map->range_alloc = PETSC_FALSE; 180 break; 181 default: 182 map->range = (PetscInt *)range; 183 break; 184 } 185 map->rstart = map->range[rank]; 186 map->rend = map->range[rank + 1]; 187 map->n = map->rend - map->rstart; 188 map->N = map->range[map->size]; 189 if (PetscDefined(USE_DEBUG)) { /* just check that n, N and bs are consistent */ 190 PetscInt tmp; 191 PetscCall(MPIU_Allreduce(&map->n, &tmp, 1, MPIU_INT, MPI_SUM, map->comm)); 192 PetscCheck(tmp == map->N, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Sum of local lengths %" PetscInt_FMT " does not equal global length %" PetscInt_FMT ", my local length %" PetscInt_FMT ".\nThe provided PetscLayout is wrong.", tmp, map->N, map->n); 193 if (map->bs > 1) PetscCheck(map->n % map->bs == 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Local size %" PetscInt_FMT " must be divisible by blocksize %" PetscInt_FMT, map->n, map->bs); 194 if (map->bs > 1) PetscCheck(map->N % map->bs == 0, map->comm, PETSC_ERR_PLIB, "Global size %" PetscInt_FMT " must be divisible by blocksize %" PetscInt_FMT, map->N, map->bs); 195 } 196 /* lock the layout */ 197 map->setupcalled = PETSC_TRUE; 198 map->oldn = map->n; 199 map->oldN = map->N; 200 map->oldbs = map->bs; 201 *newmap = map; 202 PetscFunctionReturn(0); 203 } 204 205 /*@ 206 PetscLayoutSetUp - given a map where you have set either the global or local 207 size sets up the map so that it may be used. 208 209 Collective 210 211 Input Parameters: 212 . map - pointer to the map 213 214 Level: developer 215 216 Notes: 217 Typical calling sequence 218 $ PetscLayoutCreate(MPI_Comm,PetscLayout *); 219 $ PetscLayoutSetBlockSize(PetscLayout,1); 220 $ PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both 221 $ PetscLayoutSetUp(PetscLayout); 222 $ PetscLayoutGetSize(PetscLayout,PetscInt *); 223 224 If range exists, and local size is not set, everything gets computed from the range. 225 226 If the local size, global size are already set and range exists then this does nothing. 227 228 .seealso: `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutDestroy()`, 229 `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutCreate()`, `PetscSplitOwnership()` 230 @*/ 231 PetscErrorCode PetscLayoutSetUp(PetscLayout map) 232 { 233 PetscMPIInt rank; 234 PetscInt p; 235 236 PetscFunctionBegin; 237 PetscCheck(!map->setupcalled || !(map->n != map->oldn || map->N != map->oldN), map->comm, PETSC_ERR_ARG_WRONGSTATE, "Layout is already setup with (local=%" PetscInt_FMT ",global=%" PetscInt_FMT "), cannot call setup again with (local=%" PetscInt_FMT ",global=%" PetscInt_FMT ")", 238 map->oldn, map->oldN, map->n, map->N); 239 if (map->setupcalled) PetscFunctionReturn(0); 240 241 if (map->n > 0 && map->bs > 1) PetscCheck(map->n % map->bs == 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Local size %" PetscInt_FMT " must be divisible by blocksize %" PetscInt_FMT, map->n, map->bs); 242 if (map->N > 0 && map->bs > 1) PetscCheck(map->N % map->bs == 0, map->comm, PETSC_ERR_PLIB, "Global size %" PetscInt_FMT " must be divisible by blocksize %" PetscInt_FMT, map->N, map->bs); 243 244 PetscCallMPI(MPI_Comm_rank(map->comm, &rank)); 245 if (map->n > 0) map->n = map->n / PetscAbs(map->bs); 246 if (map->N > 0) map->N = map->N / PetscAbs(map->bs); 247 PetscCall(PetscSplitOwnership(map->comm, &map->n, &map->N)); 248 map->n = map->n * PetscAbs(map->bs); 249 map->N = map->N * PetscAbs(map->bs); 250 if (!map->range) PetscCall(PetscMalloc1(map->size + 1, &map->range)); 251 PetscCallMPI(MPI_Allgather(&map->n, 1, MPIU_INT, map->range + 1, 1, MPIU_INT, map->comm)); 252 253 map->range[0] = 0; 254 for (p = 2; p <= map->size; p++) map->range[p] += map->range[p - 1]; 255 256 map->rstart = map->range[rank]; 257 map->rend = map->range[rank + 1]; 258 259 /* lock the layout */ 260 map->setupcalled = PETSC_TRUE; 261 map->oldn = map->n; 262 map->oldN = map->N; 263 map->oldbs = map->bs; 264 PetscFunctionReturn(0); 265 } 266 267 /*@ 268 PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first. 269 270 Collective on PetscLayout 271 272 Input Parameter: 273 . in - input PetscLayout to be duplicated 274 275 Output Parameter: 276 . out - the copy 277 278 Level: developer 279 280 Notes: 281 PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 282 283 .seealso: `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutReference()` 284 @*/ 285 PetscErrorCode PetscLayoutDuplicate(PetscLayout in, PetscLayout *out) 286 { 287 MPI_Comm comm = in->comm; 288 289 PetscFunctionBegin; 290 PetscCall(PetscLayoutDestroy(out)); 291 PetscCall(PetscLayoutCreate(comm, out)); 292 PetscCall(PetscMemcpy(*out, in, sizeof(struct _n_PetscLayout))); 293 if (in->range) { 294 PetscCall(PetscMalloc1((*out)->size + 1, &(*out)->range)); 295 PetscCall(PetscArraycpy((*out)->range, in->range, (*out)->size + 1)); 296 } 297 (*out)->refcnt = 0; 298 PetscFunctionReturn(0); 299 } 300 301 /*@ 302 PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX() 303 304 Collective on PetscLayout 305 306 Input Parameter: 307 . in - input PetscLayout to be copied 308 309 Output Parameter: 310 . out - the reference location 311 312 Level: developer 313 314 Notes: 315 PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 316 317 If the out location already contains a PetscLayout it is destroyed 318 319 .seealso: `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutDuplicate()` 320 @*/ 321 PetscErrorCode PetscLayoutReference(PetscLayout in, PetscLayout *out) 322 { 323 PetscFunctionBegin; 324 in->refcnt++; 325 PetscCall(PetscLayoutDestroy(out)); 326 *out = in; 327 PetscFunctionReturn(0); 328 } 329 330 /*@ 331 PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout 332 333 Collective on PetscLayout 334 335 Input Parameters: 336 + in - input PetscLayout 337 - ltog - the local to global mapping 338 339 Level: developer 340 341 Notes: 342 PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 343 344 If the ltog location already contains a PetscLayout it is destroyed 345 346 .seealso: `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutDuplicate()` 347 @*/ 348 PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in, ISLocalToGlobalMapping ltog) 349 { 350 PetscFunctionBegin; 351 if (ltog) { 352 PetscInt bs; 353 354 PetscCall(ISLocalToGlobalMappingGetBlockSize(ltog, &bs)); 355 PetscCheck(in->bs <= 0 || bs == 1 || in->bs == bs, in->comm, PETSC_ERR_PLIB, "Blocksize of layout %" PetscInt_FMT " must match that of mapping %" PetscInt_FMT " (or the latter must be 1)", in->bs, bs); 356 PetscCall(PetscObjectReference((PetscObject)ltog)); 357 } 358 PetscCall(ISLocalToGlobalMappingDestroy(&in->mapping)); 359 in->mapping = ltog; 360 PetscFunctionReturn(0); 361 } 362 363 /*@ 364 PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object. 365 366 Collective on PetscLayout 367 368 Input Parameters: 369 + map - pointer to the map 370 - n - the local size 371 372 Level: developer 373 374 Notes: 375 Call this after the call to PetscLayoutCreate() 376 377 .seealso: `PetscLayoutCreate()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetUp()` 378 `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()` 379 @*/ 380 PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map, PetscInt n) 381 { 382 PetscFunctionBegin; 383 PetscCheck(map->bs <= 1 || (n % map->bs) == 0, map->comm, PETSC_ERR_ARG_INCOMP, "Local size %" PetscInt_FMT " not compatible with block size %" PetscInt_FMT, n, map->bs); 384 map->n = n; 385 PetscFunctionReturn(0); 386 } 387 388 /*@ 389 PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object. 390 391 Not Collective 392 393 Input Parameters: 394 . map - pointer to the map 395 396 Output Parameters: 397 . n - the local size 398 399 Level: developer 400 401 Notes: 402 Call this after the call to PetscLayoutSetUp() 403 404 Fortran Notes: 405 Not available from Fortran 406 407 .seealso: `PetscLayoutCreate()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetUp()` 408 `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()` 409 410 @*/ 411 PetscErrorCode PetscLayoutGetLocalSize(PetscLayout map, PetscInt *n) 412 { 413 PetscFunctionBegin; 414 *n = map->n; 415 PetscFunctionReturn(0); 416 } 417 418 /*@ 419 PetscLayoutSetSize - Sets the global size for a PetscLayout object. 420 421 Logically Collective on PetscLayout 422 423 Input Parameters: 424 + map - pointer to the map 425 - n - the global size 426 427 Level: developer 428 429 Notes: 430 Call this after the call to PetscLayoutCreate() 431 432 .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()` 433 `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()` 434 @*/ 435 PetscErrorCode PetscLayoutSetSize(PetscLayout map, PetscInt n) 436 { 437 PetscFunctionBegin; 438 map->N = n; 439 PetscFunctionReturn(0); 440 } 441 442 /*@ 443 PetscLayoutGetSize - Gets the global size for a PetscLayout object. 444 445 Not Collective 446 447 Input Parameters: 448 . map - pointer to the map 449 450 Output Parameters: 451 . n - the global size 452 453 Level: developer 454 455 Notes: 456 Call this after the call to PetscLayoutSetUp() 457 458 .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutSetUp()` 459 `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()` 460 @*/ 461 PetscErrorCode PetscLayoutGetSize(PetscLayout map, PetscInt *n) 462 { 463 PetscFunctionBegin; 464 *n = map->N; 465 PetscFunctionReturn(0); 466 } 467 468 /*@ 469 PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object. 470 471 Logically Collective on PetscLayout 472 473 Input Parameters: 474 + map - pointer to the map 475 - bs - the size 476 477 Level: developer 478 479 Notes: 480 Call this after the call to PetscLayoutCreate() 481 482 .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetBlockSize()`, 483 `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()` 484 @*/ 485 PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map, PetscInt bs) 486 { 487 PetscFunctionBegin; 488 if (bs < 0) PetscFunctionReturn(0); 489 PetscCheck(map->n <= 0 || (map->n % bs) == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local size %" PetscInt_FMT " not compatible with block size %" PetscInt_FMT, map->n, bs); 490 if (map->mapping) { 491 PetscInt obs; 492 493 PetscCall(ISLocalToGlobalMappingGetBlockSize(map->mapping, &obs)); 494 if (obs > 1) PetscCall(ISLocalToGlobalMappingSetBlockSize(map->mapping, bs)); 495 } 496 map->bs = bs; 497 PetscFunctionReturn(0); 498 } 499 500 /*@ 501 PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object. 502 503 Not Collective 504 505 Input Parameters: 506 . map - pointer to the map 507 508 Output Parameters: 509 . bs - the size 510 511 Level: developer 512 513 Notes: 514 Call this after the call to PetscLayoutSetUp() 515 516 .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutSetUp()` 517 `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetSize()` 518 @*/ 519 PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map, PetscInt *bs) 520 { 521 PetscFunctionBegin; 522 *bs = PetscAbs(map->bs); 523 PetscFunctionReturn(0); 524 } 525 526 /*@ 527 PetscLayoutGetRange - gets the range of values owned by this process 528 529 Not Collective 530 531 Input Parameter: 532 . map - pointer to the map 533 534 Output Parameters: 535 + rstart - first index owned by this process 536 - rend - one more than the last index owned by this process 537 538 Level: developer 539 540 Notes: 541 Call this after the call to PetscLayoutSetUp() 542 543 .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, 544 `PetscLayoutGetSize()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()` 545 @*/ 546 PetscErrorCode PetscLayoutGetRange(PetscLayout map, PetscInt *rstart, PetscInt *rend) 547 { 548 PetscFunctionBegin; 549 if (rstart) *rstart = map->rstart; 550 if (rend) *rend = map->rend; 551 PetscFunctionReturn(0); 552 } 553 554 /*@C 555 PetscLayoutGetRanges - gets the range of values owned by all processes 556 557 Not Collective 558 559 Input Parameters: 560 . map - pointer to the map 561 562 Output Parameters: 563 . range - start of each processors range of indices (the final entry is one more than the 564 last index on the last process) 565 566 Level: developer 567 568 Notes: 569 Call this after the call to PetscLayoutSetUp() 570 571 Fortran Notes: 572 Not available from Fortran 573 574 .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, 575 `PetscLayoutGetSize()`, `PetscLayoutGetRange()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()` 576 577 @*/ 578 PetscErrorCode PetscLayoutGetRanges(PetscLayout map, const PetscInt *range[]) 579 { 580 PetscFunctionBegin; 581 *range = map->range; 582 PetscFunctionReturn(0); 583 } 584 585 /*@ 586 PetscLayoutCompare - Compares two layouts 587 588 Not Collective 589 590 Input Parameters: 591 + mapa - pointer to the first map 592 - mapb - pointer to the second map 593 594 Output Parameters: 595 . congruent - PETSC_TRUE if the two layouts are congruent, PETSC_FALSE otherwise 596 597 Level: beginner 598 599 Notes: 600 601 .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetBlockSize()`, 602 `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()` 603 @*/ 604 PetscErrorCode PetscLayoutCompare(PetscLayout mapa, PetscLayout mapb, PetscBool *congruent) 605 { 606 PetscFunctionBegin; 607 *congruent = PETSC_FALSE; 608 if (mapa->N == mapb->N && mapa->range && mapb->range && mapa->size == mapb->size) PetscCall(PetscArraycmp(mapa->range, mapb->range, mapa->size + 1, congruent)); 609 PetscFunctionReturn(0); 610 } 611