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