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 implementions; 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 implementions; 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 default: 181 map->range = (PetscInt*) range; 182 break; 183 } 184 map->rstart = map->range[rank]; 185 map->rend = map->range[rank+1]; 186 map->n = map->rend - map->rstart; 187 map->N = map->range[map->size]; 188 if (PetscDefined(USE_DEBUG)) { /* just check that n, N and bs are consistent */ 189 PetscInt tmp; 190 PetscCall(MPIU_Allreduce(&map->n,&tmp,1,MPIU_INT,MPI_SUM,map->comm)); 191 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); 192 if (map->bs > 1) { 193 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 } 195 if (map->bs > 1) { 196 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); 197 } 198 } 199 /* lock the layout */ 200 map->setupcalled = PETSC_TRUE; 201 map->oldn = map->n; 202 map->oldN = map->N; 203 map->oldbs = map->bs; 204 *newmap = map; 205 PetscFunctionReturn(0); 206 } 207 208 /*@ 209 PetscLayoutSetUp - given a map where you have set either the global or local 210 size sets up the map so that it may be used. 211 212 Collective 213 214 Input Parameters: 215 . map - pointer to the map 216 217 Level: developer 218 219 Notes: 220 Typical calling sequence 221 $ PetscLayoutCreate(MPI_Comm,PetscLayout *); 222 $ PetscLayoutSetBlockSize(PetscLayout,1); 223 $ PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both 224 $ PetscLayoutSetUp(PetscLayout); 225 $ PetscLayoutGetSize(PetscLayout,PetscInt *); 226 227 If range exists, and local size is not set, everything gets computed from the range. 228 229 If the local size, global size are already set and range exists then this does nothing. 230 231 .seealso: `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutDestroy()`, 232 `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutCreate()` 233 @*/ 234 PetscErrorCode PetscLayoutSetUp(PetscLayout map) 235 { 236 PetscMPIInt rank; 237 PetscInt p; 238 239 PetscFunctionBegin; 240 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 ")", map->oldn, map->oldN, map->n, map->N); 241 if (map->setupcalled) PetscFunctionReturn(0); 242 243 if (map->n > 0 && map->bs > 1) { 244 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); 245 } 246 if (map->N > 0 && map->bs > 1) { 247 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); 248 } 249 250 PetscCallMPI(MPI_Comm_rank(map->comm, &rank)); 251 if (map->n > 0) map->n = map->n/PetscAbs(map->bs); 252 if (map->N > 0) map->N = map->N/PetscAbs(map->bs); 253 PetscCall(PetscSplitOwnership(map->comm,&map->n,&map->N)); 254 map->n = map->n*PetscAbs(map->bs); 255 map->N = map->N*PetscAbs(map->bs); 256 if (!map->range) { 257 PetscCall(PetscMalloc1(map->size+1, &map->range)); 258 } 259 PetscCallMPI(MPI_Allgather(&map->n, 1, MPIU_INT, map->range+1, 1, MPIU_INT, map->comm)); 260 261 map->range[0] = 0; 262 for (p = 2; p <= map->size; p++) map->range[p] += map->range[p-1]; 263 264 map->rstart = map->range[rank]; 265 map->rend = map->range[rank+1]; 266 267 /* lock the layout */ 268 map->setupcalled = PETSC_TRUE; 269 map->oldn = map->n; 270 map->oldN = map->N; 271 map->oldbs = map->bs; 272 PetscFunctionReturn(0); 273 } 274 275 /*@ 276 PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first. 277 278 Collective on PetscLayout 279 280 Input Parameter: 281 . in - input PetscLayout to be duplicated 282 283 Output Parameter: 284 . out - the copy 285 286 Level: developer 287 288 Notes: 289 PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 290 291 .seealso: `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutReference()` 292 @*/ 293 PetscErrorCode PetscLayoutDuplicate(PetscLayout in,PetscLayout *out) 294 { 295 MPI_Comm comm = in->comm; 296 297 PetscFunctionBegin; 298 PetscCall(PetscLayoutDestroy(out)); 299 PetscCall(PetscLayoutCreate(comm,out)); 300 PetscCall(PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout))); 301 if (in->range) { 302 PetscCall(PetscMalloc1((*out)->size+1,&(*out)->range)); 303 PetscCall(PetscArraycpy((*out)->range,in->range,(*out)->size+1)); 304 } 305 (*out)->refcnt = 0; 306 PetscFunctionReturn(0); 307 } 308 309 /*@ 310 PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX() 311 312 Collective on PetscLayout 313 314 Input Parameter: 315 . in - input PetscLayout to be copied 316 317 Output Parameter: 318 . out - the reference location 319 320 Level: developer 321 322 Notes: 323 PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 324 325 If the out location already contains a PetscLayout it is destroyed 326 327 .seealso: `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutDuplicate()` 328 @*/ 329 PetscErrorCode PetscLayoutReference(PetscLayout in,PetscLayout *out) 330 { 331 PetscFunctionBegin; 332 in->refcnt++; 333 PetscCall(PetscLayoutDestroy(out)); 334 *out = in; 335 PetscFunctionReturn(0); 336 } 337 338 /*@ 339 PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout 340 341 Collective on PetscLayout 342 343 Input Parameters: 344 + in - input PetscLayout 345 - ltog - the local to global mapping 346 347 Level: developer 348 349 Notes: 350 PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 351 352 If the ltog location already contains a PetscLayout it is destroyed 353 354 .seealso: `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutDuplicate()` 355 @*/ 356 PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog) 357 { 358 PetscFunctionBegin; 359 if (ltog) { 360 PetscInt bs; 361 362 PetscCall(ISLocalToGlobalMappingGetBlockSize(ltog,&bs)); 363 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); 364 PetscCall(PetscObjectReference((PetscObject)ltog)); 365 } 366 PetscCall(ISLocalToGlobalMappingDestroy(&in->mapping)); 367 in->mapping = ltog; 368 PetscFunctionReturn(0); 369 } 370 371 /*@ 372 PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object. 373 374 Collective on PetscLayout 375 376 Input Parameters: 377 + map - pointer to the map 378 - n - the local size 379 380 Level: developer 381 382 Notes: 383 Call this after the call to PetscLayoutCreate() 384 385 .seealso: `PetscLayoutCreate()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetUp()` 386 `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()` 387 @*/ 388 PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map,PetscInt n) 389 { 390 PetscFunctionBegin; 391 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); 392 map->n = n; 393 PetscFunctionReturn(0); 394 } 395 396 /*@C 397 PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object. 398 399 Not Collective 400 401 Input Parameters: 402 . map - pointer to the map 403 404 Output Parameters: 405 . n - the local size 406 407 Level: developer 408 409 Notes: 410 Call this after the call to PetscLayoutSetUp() 411 412 Fortran Notes: 413 Not available from Fortran 414 415 .seealso: `PetscLayoutCreate()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetUp()` 416 `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()` 417 418 @*/ 419 PetscErrorCode PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n) 420 { 421 PetscFunctionBegin; 422 *n = map->n; 423 PetscFunctionReturn(0); 424 } 425 426 /*@ 427 PetscLayoutSetSize - Sets the global size for a PetscLayout object. 428 429 Logically Collective on PetscLayout 430 431 Input Parameters: 432 + map - pointer to the map 433 - n - the global size 434 435 Level: developer 436 437 Notes: 438 Call this after the call to PetscLayoutCreate() 439 440 .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()` 441 `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()` 442 @*/ 443 PetscErrorCode PetscLayoutSetSize(PetscLayout map,PetscInt n) 444 { 445 PetscFunctionBegin; 446 map->N = n; 447 PetscFunctionReturn(0); 448 } 449 450 /*@ 451 PetscLayoutGetSize - Gets the global size for a PetscLayout object. 452 453 Not Collective 454 455 Input Parameters: 456 . map - pointer to the map 457 458 Output Parameters: 459 . n - the global size 460 461 Level: developer 462 463 Notes: 464 Call this after the call to PetscLayoutSetUp() 465 466 .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutSetUp()` 467 `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()` 468 @*/ 469 PetscErrorCode PetscLayoutGetSize(PetscLayout map,PetscInt *n) 470 { 471 PetscFunctionBegin; 472 *n = map->N; 473 PetscFunctionReturn(0); 474 } 475 476 /*@ 477 PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object. 478 479 Logically Collective on PetscLayout 480 481 Input Parameters: 482 + map - pointer to the map 483 - bs - the size 484 485 Level: developer 486 487 Notes: 488 Call this after the call to PetscLayoutCreate() 489 490 .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetBlockSize()`, 491 `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()` 492 @*/ 493 PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs) 494 { 495 PetscFunctionBegin; 496 if (bs < 0) PetscFunctionReturn(0); 497 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); 498 if (map->mapping) { 499 PetscInt obs; 500 501 PetscCall(ISLocalToGlobalMappingGetBlockSize(map->mapping,&obs)); 502 if (obs > 1) { 503 PetscCall(ISLocalToGlobalMappingSetBlockSize(map->mapping,bs)); 504 } 505 } 506 map->bs = bs; 507 PetscFunctionReturn(0); 508 } 509 510 /*@ 511 PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object. 512 513 Not Collective 514 515 Input Parameters: 516 . map - pointer to the map 517 518 Output Parameters: 519 . bs - the size 520 521 Level: developer 522 523 Notes: 524 Call this after the call to PetscLayoutSetUp() 525 526 .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutSetUp()` 527 `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetSize()` 528 @*/ 529 PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs) 530 { 531 PetscFunctionBegin; 532 *bs = PetscAbs(map->bs); 533 PetscFunctionReturn(0); 534 } 535 536 /*@ 537 PetscLayoutGetRange - gets the range of values owned by this process 538 539 Not Collective 540 541 Input Parameter: 542 . map - pointer to the map 543 544 Output Parameters: 545 + rstart - first index owned by this process 546 - rend - one more than the last index owned by this process 547 548 Level: developer 549 550 Notes: 551 Call this after the call to PetscLayoutSetUp() 552 553 .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, 554 `PetscLayoutGetSize()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()` 555 @*/ 556 PetscErrorCode PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend) 557 { 558 PetscFunctionBegin; 559 if (rstart) *rstart = map->rstart; 560 if (rend) *rend = map->rend; 561 PetscFunctionReturn(0); 562 } 563 564 /*@C 565 PetscLayoutGetRanges - gets the range of values owned by all processes 566 567 Not Collective 568 569 Input Parameters: 570 . map - pointer to the map 571 572 Output Parameters: 573 . range - start of each processors range of indices (the final entry is one more then the 574 last index on the last process) 575 576 Level: developer 577 578 Notes: 579 Call this after the call to PetscLayoutSetUp() 580 581 Fortran Notes: 582 Not available from Fortran 583 584 .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, 585 `PetscLayoutGetSize()`, `PetscLayoutGetRange()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()` 586 587 @*/ 588 PetscErrorCode PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[]) 589 { 590 PetscFunctionBegin; 591 *range = map->range; 592 PetscFunctionReturn(0); 593 } 594 595 /*@ 596 PetscLayoutCompare - Compares two layouts 597 598 Not Collective 599 600 Input Parameters: 601 + mapa - pointer to the first map 602 - mapb - pointer to the second map 603 604 Output Parameters: 605 . congruent - PETSC_TRUE if the two layouts are congruent, PETSC_FALSE otherwise 606 607 Level: beginner 608 609 Notes: 610 611 .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetBlockSize()`, 612 `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()` 613 @*/ 614 PetscErrorCode PetscLayoutCompare(PetscLayout mapa,PetscLayout mapb,PetscBool *congruent) 615 { 616 PetscFunctionBegin; 617 *congruent = PETSC_FALSE; 618 if (mapa->N == mapb->N && mapa->range && mapb->range && mapa->size == mapb->size) { 619 PetscCall(PetscArraycmp(mapa->range,mapb->range,mapa->size+1,congruent)); 620 } 621 PetscFunctionReturn(0); 622 } 623