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