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