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->n >= 0) && (map->N >= 0) && (map->range)) PetscFunctionReturn(0); 146 147 ierr = MPI_Comm_size(map->comm, &size);CHKERRQ(ierr); 148 ierr = MPI_Comm_rank(map->comm, &rank);CHKERRQ(ierr); 149 if (map->n > 0) map->n = map->n/PetscAbs(map->bs); 150 if (map->N > 0) map->N = map->N/PetscAbs(map->bs); 151 ierr = PetscSplitOwnership(map->comm,&map->n,&map->N);CHKERRQ(ierr); 152 map->n = map->n*PetscAbs(map->bs); 153 map->N = map->N*PetscAbs(map->bs); 154 if (!map->range) { 155 ierr = PetscMalloc1((size+1), &map->range);CHKERRQ(ierr); 156 } 157 ierr = MPI_Allgather(&map->n, 1, MPIU_INT, map->range+1, 1, MPIU_INT, map->comm);CHKERRQ(ierr); 158 159 map->range[0] = 0; 160 for (p = 2; p <= size; p++) map->range[p] += map->range[p-1]; 161 162 map->rstart = map->range[rank]; 163 map->rend = map->range[rank+1]; 164 #if defined(PETSC_THREADCOMM_ACTIVE) 165 /* Set the thread ownership ranges */ 166 ierr = PetscThreadCommGetOwnershipRanges(map->comm,map->n,&map->trstarts);CHKERRQ(ierr); 167 #endif 168 PetscFunctionReturn(0); 169 } 170 171 #undef __FUNCT__ 172 #define __FUNCT__ "PetscLayoutDuplicate" 173 /*@C 174 175 PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first. 176 177 Collective on PetscLayout 178 179 Input Parameter: 180 . in - input PetscLayout to be duplicated 181 182 Output Parameter: 183 . out - the copy 184 185 Level: developer 186 187 Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 188 189 .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutReference() 190 191 @*/ 192 PetscErrorCode PetscLayoutDuplicate(PetscLayout in,PetscLayout *out) 193 { 194 PetscMPIInt size; 195 PetscErrorCode ierr; 196 MPI_Comm comm = in->comm; 197 198 PetscFunctionBegin; 199 ierr = PetscLayoutDestroy(out);CHKERRQ(ierr); 200 ierr = PetscLayoutCreate(comm,out);CHKERRQ(ierr); 201 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 202 ierr = PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout));CHKERRQ(ierr); 203 ierr = PetscMalloc1((size+1),&(*out)->range);CHKERRQ(ierr); 204 ierr = PetscMemcpy((*out)->range,in->range,(size+1)*sizeof(PetscInt));CHKERRQ(ierr); 205 206 (*out)->refcnt = 0; 207 PetscFunctionReturn(0); 208 } 209 210 #undef __FUNCT__ 211 #define __FUNCT__ "PetscLayoutReference" 212 /*@C 213 214 PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX() 215 216 Collective on PetscLayout 217 218 Input Parameter: 219 . in - input PetscLayout to be copied 220 221 Output Parameter: 222 . out - the reference location 223 224 Level: developer 225 226 Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 227 228 If the out location already contains a PetscLayout it is destroyed 229 230 .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate() 231 232 @*/ 233 PetscErrorCode PetscLayoutReference(PetscLayout in,PetscLayout *out) 234 { 235 PetscErrorCode ierr; 236 237 PetscFunctionBegin; 238 in->refcnt++; 239 ierr = PetscLayoutDestroy(out);CHKERRQ(ierr); 240 *out = in; 241 PetscFunctionReturn(0); 242 } 243 244 #undef __FUNCT__ 245 #define __FUNCT__ "PetscLayoutSetISLocalToGlobalMapping" 246 /*@C 247 248 PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout 249 250 Collective on PetscLayout 251 252 Input Parameter: 253 + in - input PetscLayout 254 - ltog - the local to global mapping 255 256 257 Level: developer 258 259 Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 260 261 If the ltog location already contains a PetscLayout it is destroyed 262 263 .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate(), PetscLayoutSetLocalToGlobalMappingBlock() 264 265 @*/ 266 PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog) 267 { 268 PetscErrorCode ierr; 269 270 PetscFunctionBegin; 271 ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr); 272 ierr = ISLocalToGlobalMappingDestroy(&in->mapping);CHKERRQ(ierr); 273 274 in->mapping = ltog; 275 PetscFunctionReturn(0); 276 } 277 278 #undef __FUNCT__ 279 #define __FUNCT__ "PetscLayoutSetISLocalToGlobalMappingBlock" 280 /*@C 281 282 PetscLayoutSetISLocalToGlobalMappingBlock - sets a ISLocalGlobalMapping into a PetscLayout 283 284 Collective on PetscLayout 285 286 Input Parameter: 287 + in - input PetscLayout 288 - ltog - the local to global block mapping 289 290 291 Level: developer 292 293 Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout 294 295 If the ltog location already contains a PetscLayout it is destroyed 296 297 .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate(), PetscLayoutSetLocalToGlobalMappingBlock() 298 299 @*/ 300 PetscErrorCode PetscLayoutSetISLocalToGlobalMappingBlock(PetscLayout in,ISLocalToGlobalMapping ltog) 301 { 302 PetscErrorCode ierr; 303 304 PetscFunctionBegin; 305 ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr); 306 ierr = ISLocalToGlobalMappingDestroy(&in->bmapping);CHKERRQ(ierr); 307 308 in->bmapping = ltog; 309 PetscFunctionReturn(0); 310 } 311 312 /*@C 313 PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object. 314 315 Collective on PetscLayout 316 317 Input Parameters: 318 + map - pointer to the map 319 - n - the local size 320 321 Level: developer 322 323 Notes: 324 Call this after the call to PetscLayoutCreate() 325 326 Fortran Notes: 327 Not available from Fortran 328 329 .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp() 330 PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 331 332 @*/ 333 #undef __FUNCT__ 334 #define __FUNCT__ "PetscLayoutSetLocalSize" 335 PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map,PetscInt n) 336 { 337 PetscFunctionBegin; 338 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); 339 map->n = n; 340 PetscFunctionReturn(0); 341 } 342 343 /*@C 344 PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object. 345 346 Not Collective 347 348 Input Parameters: 349 . map - pointer to the map 350 351 Output Parameters: 352 . n - the local size 353 354 Level: developer 355 356 Notes: 357 Call this after the call to PetscLayoutSetUp() 358 359 Fortran Notes: 360 Not available from Fortran 361 362 .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp() 363 PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 364 365 @*/ 366 #undef __FUNCT__ 367 #define __FUNCT__ "PetscLayoutGetLocalSize" 368 PetscErrorCode PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n) 369 { 370 PetscFunctionBegin; 371 *n = map->n; 372 PetscFunctionReturn(0); 373 } 374 375 /*@C 376 PetscLayoutSetSize - Sets the global size for a PetscLayout object. 377 378 Logically Collective on PetscLayout 379 380 Input Parameters: 381 + map - pointer to the map 382 - n - the global size 383 384 Level: developer 385 386 Notes: 387 Call this after the call to PetscLayoutCreate() 388 389 Fortran Notes: 390 Not available from Fortran 391 392 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 393 PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 394 395 @*/ 396 #undef __FUNCT__ 397 #define __FUNCT__ "PetscLayoutSetSize" 398 PetscErrorCode PetscLayoutSetSize(PetscLayout map,PetscInt n) 399 { 400 PetscFunctionBegin; 401 map->N = n; 402 PetscFunctionReturn(0); 403 } 404 405 /*@C 406 PetscLayoutGetSize - Gets the global size for a PetscLayout object. 407 408 Not Collective 409 410 Input Parameters: 411 . map - pointer to the map 412 413 Output Parameters: 414 . n - the global size 415 416 Level: developer 417 418 Notes: 419 Call this after the call to PetscLayoutSetUp() 420 421 Fortran Notes: 422 Not available from Fortran 423 424 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp() 425 PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize() 426 427 @*/ 428 #undef __FUNCT__ 429 #define __FUNCT__ "PetscLayoutGetSize" 430 PetscErrorCode PetscLayoutGetSize(PetscLayout map,PetscInt *n) 431 { 432 PetscFunctionBegin; 433 *n = map->N; 434 PetscFunctionReturn(0); 435 } 436 437 /*@C 438 PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object. 439 440 Logically Collective on PetscLayout 441 442 Input Parameters: 443 + map - pointer to the map 444 - bs - the size 445 446 Level: developer 447 448 Notes: 449 Call this after the call to PetscLayoutCreate() 450 451 Fortran Notes: 452 Not available from Fortran 453 454 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(), 455 PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp() 456 457 @*/ 458 #undef __FUNCT__ 459 #define __FUNCT__ "PetscLayoutSetBlockSize" 460 PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs) 461 { 462 PetscFunctionBegin; 463 if (bs < 0) PetscFunctionReturn(0); 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 = PetscAbs(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