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