Actual source code: pmap.c

petsc-3.4.2 2013-07-02
  2: /*
  3:    This file contains routines for basic map object implementation.
  4: */

  6: #include <petscvec.h>
  7: #include <petscsf.h>
  8: #include <petsc-private/threadcommimpl.h>
 11: /*@C
 12:      PetscLayoutCreate - Allocates PetscLayout space and sets the map contents to the default.

 14:     Collective on MPI_Comm

 16:    Input Parameters:
 17: +    comm - the MPI communicator
 18: -    map - pointer to the map

 20:    Level: developer

 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);

 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.

 35:     Fortran Notes:
 36:       Not available from Fortran

 38: .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
 39:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp()

 41: @*/
 42: PetscErrorCode  PetscLayoutCreate(MPI_Comm comm,PetscLayout *map)
 43: {

 47:   PetscNew(struct _n_PetscLayout,map);

 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:   return(0);
 58: }

 60: /*@C
 61:      PetscLayoutDestroy - Frees a map object and frees its range if that exists.

 63:     Collective on MPI_Comm

 65:    Input Parameters:
 66: .    map - the PetscLayout

 68:    Level: developer

 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.

 73:     Fortran Notes:
 74:       Not available from Fortran

 76: .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutCreate(),
 77:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp()

 79: @*/
 82: PetscErrorCode  PetscLayoutDestroy(PetscLayout *map)
 83: {

 87:   if (!*map) return(0);
 88:   if (!(*map)->refcnt--) {
 89:     PetscFree((*map)->range);
 90:     ISLocalToGlobalMappingDestroy(&(*map)->mapping);
 91:     ISLocalToGlobalMappingDestroy(&(*map)->bmapping);
 92: #if defined(PETSC_THREADCOMM_ACTIVE)
 93:     PetscFree((*map)->trstarts);
 94: #endif

 96:     PetscFree((*map));
 97:   }
 98:   *map = NULL;
 99:   return(0);
100: }

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.

106:     Collective on MPI_Comm

108:    Input Parameters:
109: .    map - pointer to the map

111:    Level: developer

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 *);


121:        If the local size, global size are already set and range exists then this does nothing.

123:     Fortran Notes:
124:       Not available from Fortran

126: .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
127:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutCreate()

129: @*/
132: PetscErrorCode  PetscLayoutSetUp(PetscLayout map)
133: {
134:   PetscMPIInt    rank,size;
135:   PetscInt       p;

139:   if (map->bs <= 0) map->bs = 1;
140:   if ((map->n >= 0) && (map->N >= 0) && (map->range)) return(0);

142:   MPI_Comm_size(map->comm, &size);
143:   MPI_Comm_rank(map->comm, &rank);
144:   if (map->n > 0) map->n = map->n/map->bs;
145:   if (map->N > 0) map->N = map->N/map->bs;
146:   PetscSplitOwnership(map->comm,&map->n,&map->N);
147:   map->n = map->n*map->bs;
148:   map->N = map->N*map->bs;
149:   if (!map->range) {
150:     PetscMalloc((size+1)*sizeof(PetscInt), &map->range);
151:   }
152:   MPI_Allgather(&map->n, 1, MPIU_INT, map->range+1, 1, MPIU_INT, map->comm);

154:   map->range[0] = 0;
155:   for (p = 2; p <= size; p++) map->range[p] += map->range[p-1];

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:   PetscThreadCommGetOwnershipRanges(map->comm,map->n,&map->trstarts);
162: #endif
163:   return(0);
164: }

168: /*@C

170:     PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first.

172:      Collective on PetscLayout

174:     Input Parameter:
175: .     in - input PetscLayout to be duplicated

177:     Output Parameter:
178: .     out - the copy

180:    Level: developer

182:     Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout

184: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutReference()

186: @*/
187: PetscErrorCode  PetscLayoutDuplicate(PetscLayout in,PetscLayout *out)
188: {
189:   PetscMPIInt    size;
191:   MPI_Comm       comm = in->comm;

194:   PetscLayoutDestroy(out);
195:   PetscLayoutCreate(comm,out);
196:   MPI_Comm_size(comm,&size);
197:   PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout));
198:   PetscMalloc((size+1)*sizeof(PetscInt),&(*out)->range);
199:   PetscMemcpy((*out)->range,in->range,(size+1)*sizeof(PetscInt));

201:   (*out)->refcnt = 0;
202:   return(0);
203: }

207: /*@C

209:     PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX()

211:      Collective on PetscLayout

213:     Input Parameter:
214: .     in - input PetscLayout to be copied

216:     Output Parameter:
217: .     out - the reference location

219:    Level: developer

221:     Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout

223:     If the out location already contains a PetscLayout it is destroyed

225: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate()

227: @*/
228: PetscErrorCode  PetscLayoutReference(PetscLayout in,PetscLayout *out)
229: {

233:   in->refcnt++;
234:   PetscLayoutDestroy(out);
235:   *out = in;
236:   return(0);
237: }

241: /*@C

243:     PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout

245:      Collective on PetscLayout

247:     Input Parameter:
248: +     in - input PetscLayout
249: -     ltog - the local to global mapping


252:    Level: developer

254:     Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout

256:     If the ltog location already contains a PetscLayout it is destroyed

258: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate(), PetscLayoutSetLocalToGlobalMappingBlock()

260: @*/
261: PetscErrorCode  PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog)
262: {

266:   PetscObjectReference((PetscObject)ltog);
267:   ISLocalToGlobalMappingDestroy(&in->mapping);

269:   in->mapping = ltog;
270:   return(0);
271: }

275: /*@C

277:     PetscLayoutSetISLocalToGlobalMappingBlock - sets a ISLocalGlobalMapping into a PetscLayout

279:      Collective on PetscLayout

281:     Input Parameter:
282: +     in - input PetscLayout
283: -     ltog - the local to global block mapping


286:    Level: developer

288:     Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout

290:     If the ltog location already contains a PetscLayout it is destroyed

292: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate(), PetscLayoutSetLocalToGlobalMappingBlock()

294: @*/
295: PetscErrorCode  PetscLayoutSetISLocalToGlobalMappingBlock(PetscLayout in,ISLocalToGlobalMapping ltog)
296: {

300:   PetscObjectReference((PetscObject)ltog);
301:   ISLocalToGlobalMappingDestroy(&in->bmapping);

303:   in->bmapping = ltog;
304:   return(0);
305: }

307: /*@C
308:      PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object.

310:     Collective on PetscLayout

312:    Input Parameters:
313: +    map - pointer to the map
314: -    n - the local size

316:    Level: developer

318:     Notes:
319:        Call this after the call to PetscLayoutCreate()

321:     Fortran Notes:
322:       Not available from Fortran

324: .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
325:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()

327: @*/
330: PetscErrorCode  PetscLayoutSetLocalSize(PetscLayout map,PetscInt n)
331: {
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:   return(0);
336: }

338: /*@C
339:      PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object.

341:     Not Collective

343:    Input Parameters:
344: .    map - pointer to the map

346:    Output Parameters:
347: .    n - the local size

349:    Level: developer

351:     Notes:
352:        Call this after the call to PetscLayoutSetUp()

354:     Fortran Notes:
355:       Not available from Fortran

357: .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
358:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()

360: @*/
363: PetscErrorCode  PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n)
364: {
366:   *n = map->n;
367:   return(0);
368: }

370: /*@C
371:      PetscLayoutSetSize - Sets the global size for a PetscLayout object.

373:     Logically Collective on PetscLayout

375:    Input Parameters:
376: +    map - pointer to the map
377: -    n - the global size

379:    Level: developer

381:     Notes:
382:        Call this after the call to PetscLayoutCreate()

384:     Fortran Notes:
385:       Not available from Fortran

387: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
388:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()

390: @*/
393: PetscErrorCode  PetscLayoutSetSize(PetscLayout map,PetscInt n)
394: {
396:   map->N = n;
397:   return(0);
398: }

400: /*@C
401:      PetscLayoutGetSize - Gets the global size for a PetscLayout object.

403:     Not Collective

405:    Input Parameters:
406: .    map - pointer to the map

408:    Output Parameters:
409: .    n - the global size

411:    Level: developer

413:     Notes:
414:        Call this after the call to PetscLayoutSetUp()

416:     Fortran Notes:
417:       Not available from Fortran

419: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
420:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()

422: @*/
425: PetscErrorCode  PetscLayoutGetSize(PetscLayout map,PetscInt *n)
426: {
428:   *n = map->N;
429:   return(0);
430: }

432: /*@C
433:      PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object.

435:     Logically Collective on PetscLayout

437:    Input Parameters:
438: +    map - pointer to the map
439: -    bs - the size

441:    Level: developer

443:     Notes:
444:        Call this after the call to PetscLayoutCreate()

446:     Fortran Notes:
447:       Not available from Fortran

449: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(),
450:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp()

452: @*/
455: PetscErrorCode  PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs)
456: {
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:   return(0);
462: }

464: /*@C
465:      PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object.

467:     Not Collective

469:    Input Parameters:
470: .    map - pointer to the map

472:    Output Parameters:
473: .    bs - the size

475:    Level: developer

477:     Notes:
478:        Call this after the call to PetscLayoutSetUp()

480:     Fortran Notes:
481:       Not available from Fortran

483: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
484:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize()

486: @*/
489: PetscErrorCode  PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs)
490: {
492:   *bs = map->bs;
493:   return(0);
494: }


497: /*@C
498:      PetscLayoutGetRange - gets the range of values owned by this process

500:     Not Collective

502:    Input Parameters:
503: .    map - pointer to the map

505:    Output Parameters:
506: +    rstart - first index owned by this process
507: -    rend - one more than the last index owned by this process

509:    Level: developer

511:     Notes:
512:        Call this after the call to PetscLayoutSetUp()

514:     Fortran Notes:
515:       Not available from Fortran

517: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
518:           PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()

520: @*/
523: PetscErrorCode  PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend)
524: {
526:   if (rstart) *rstart = map->rstart;
527:   if (rend)   *rend   = map->rend;
528:   return(0);
529: }

531: /*@C
532:      PetscLayoutGetRanges - gets the range of values owned by all processes

534:     Not Collective

536:    Input Parameters:
537: .    map - pointer to the map

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)

543:    Level: developer

545:     Notes:
546:        Call this after the call to PetscLayoutSetUp()

548:     Fortran Notes:
549:       Not available from Fortran

551: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
552:           PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()

554: @*/
557: PetscErrorCode  PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[])
558: {
560:   *range = map->range;
561:   return(0);
562: }

566: /*@C
567:    PetscSFSetGraphLayout - Set a parallel star forest via global indices and a PetscLayout

569:    Collective

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

578:    Level: intermediate

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: {
585:   PetscInt       i,nroots;
586:   PetscSFNode    *remote;

589:   PetscLayoutGetLocalSize(layout,&nroots);
590:   PetscMalloc(nleaves*sizeof(PetscSFNode),&remote);
591:   for (i=0; i<nleaves; i++) {
592:     PetscInt owner = -1;
593:     PetscLayoutFindOwner(layout,iremote[i],&owner);
594:     remote[i].rank  = owner;
595:     remote[i].index = iremote[i] - layout->range[owner];
596:   }
597:   PetscSFSetGraph(sf,nroots,nleaves,ilocal,localmode,remote,PETSC_OWN_POINTER);
598:   return(0);
599: }