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