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