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