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 (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); 465 if (map->bs > 0 && map->bs != bs) SETERRQ2(map->comm,PETSC_ERR_ARG_INCOMP,"Cannot change block size %D to %D",map->bs,bs); 466 map->bs = bs; 467 PetscFunctionReturn(0); 468 } 469 470 /*@C 471 PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object. 472 473 Not Collective 474 475 Input Parameters: 476 . map - pointer to the map 477 478 Output Parameters: 479 . bs - the size 480 481 Level: developer 482 483 Notes: 484 Call this after the call to PetscLayoutSetUp() 485 486 Fortran Notes: 487 Not available from Fortran 488 489 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp() 490 PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize() 491 492 @*/ 493 #undef __FUNCT__ 494 #define __FUNCT__ "PetscLayoutGetBlockSize" 495 PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs) 496 { 497 PetscFunctionBegin; 498 *bs = map->bs; 499 PetscFunctionReturn(0); 500 } 501 502 503 /*@C 504 PetscLayoutGetRange - gets the range of values owned by this process 505 506 Not Collective 507 508 Input Parameters: 509 . map - pointer to the map 510 511 Output Parameters: 512 + rstart - first index owned by this process 513 - rend - one more than the last index owned by this process 514 515 Level: developer 516 517 Notes: 518 Call this after the call to PetscLayoutSetUp() 519 520 Fortran Notes: 521 Not available from Fortran 522 523 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), 524 PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 525 526 @*/ 527 #undef __FUNCT__ 528 #define __FUNCT__ "PetscLayoutGetRange" 529 PetscErrorCode PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend) 530 { 531 PetscFunctionBegin; 532 if (rstart) *rstart = map->rstart; 533 if (rend) *rend = map->rend; 534 PetscFunctionReturn(0); 535 } 536 537 /*@C 538 PetscLayoutGetRanges - gets the range of values owned by all processes 539 540 Not Collective 541 542 Input Parameters: 543 . map - pointer to the map 544 545 Output Parameters: 546 . range - start of each processors range of indices (the final entry is one more then the 547 last index on the last process) 548 549 Level: developer 550 551 Notes: 552 Call this after the call to PetscLayoutSetUp() 553 554 Fortran Notes: 555 Not available from Fortran 556 557 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), 558 PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 559 560 @*/ 561 #undef __FUNCT__ 562 #define __FUNCT__ "PetscLayoutGetRanges" 563 PetscErrorCode PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[]) 564 { 565 PetscFunctionBegin; 566 *range = map->range; 567 PetscFunctionReturn(0); 568 } 569 570 #undef __FUNCT__ 571 #define __FUNCT__ "PetscSFSetGraphLayout" 572 /*@C 573 PetscSFSetGraphLayout - Set a parallel star forest via global indices and a PetscLayout 574 575 Collective 576 577 Input Arguments: 578 + sf - star forest 579 . layout - PetscLayout defining the global space 580 . nleaves - number of leaf vertices on the current process, each of these references a root on any process 581 . ilocal - locations of leaves in leafdata buffers, pass NULL for contiguous storage 582 - iremote - remote locations of root vertices for each leaf on the current process 583 584 Level: intermediate 585 586 .seealso: PetscSFCreate(), PetscSFView(), PetscSFSetGraph(), PetscSFGetGraph() 587 @*/ 588 PetscErrorCode PetscSFSetGraphLayout(PetscSF sf,PetscLayout layout,PetscInt nleaves,const PetscInt *ilocal,PetscCopyMode localmode,const PetscInt *iremote) 589 { 590 PetscErrorCode ierr; 591 PetscInt i,nroots; 592 PetscSFNode *remote; 593 594 PetscFunctionBegin; 595 ierr = PetscLayoutGetLocalSize(layout,&nroots);CHKERRQ(ierr); 596 ierr = PetscMalloc1(nleaves,&remote);CHKERRQ(ierr); 597 for (i=0; i<nleaves; i++) { 598 PetscInt owner = -1; 599 ierr = PetscLayoutFindOwner(layout,iremote[i],&owner);CHKERRQ(ierr); 600 remote[i].rank = owner; 601 remote[i].index = iremote[i] - layout->range[owner]; 602 } 603 ierr = PetscSFSetGraph(sf,nroots,nleaves,ilocal,localmode,remote,PETSC_OWN_POINTER);CHKERRQ(ierr); 604 PetscFunctionReturn(0); 605 } 606 607