Actual source code: pmap.c

petsc-3.4.5 2014-06-29
  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: advanced

 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:

 32: +      PetscLayoutGetSize(PetscLayout,PetscInt *);
 33: .      PetscLayoutGetLocalSize(PetscLayout,PetscInt *);
 34: .      PetscLayoutGetRange(PetscLayout,PetscInt *rstart,PetscInt *rend);
 35: .      PetscLayoutGetRanges(PetscLayout,const PetscInt *range[]);
 36: -      PetscLayoutDestroy(PetscLayout*);

 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.

 41:     Fortran Notes:
 42:       Not available from Fortran

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

 47: @*/
 48: PetscErrorCode  PetscLayoutCreate(MPI_Comm comm,PetscLayout *map)
 49: {

 53:   PetscNew(struct _n_PetscLayout,map);

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

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

 69:     Collective on MPI_Comm

 71:    Input Parameters:
 72: .    map - the PetscLayout

 74:    Level: developer

 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.

 79:     Fortran Notes:
 80:       Not available from Fortran

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

 85: @*/
 88: PetscErrorCode  PetscLayoutDestroy(PetscLayout *map)
 89: {

 93:   if (!*map) return(0);
 94:   if (!(*map)->refcnt--) {
 95:     PetscFree((*map)->range);
 96:     ISLocalToGlobalMappingDestroy(&(*map)->mapping);
 97:     ISLocalToGlobalMappingDestroy(&(*map)->bmapping);
 98: #if defined(PETSC_THREADCOMM_ACTIVE)
 99:     PetscFree((*map)->trstarts);
100: #endif

102:     PetscFree((*map));
103:   }
104:   *map = NULL;
105:   return(0);
106: }

108: /*@C
109:      PetscLayoutSetUp - given a map where you have set either the global or local
110:            size sets up the map so that it may be used.

112:     Collective on MPI_Comm

114:    Input Parameters:
115: .    map - pointer to the map

117:    Level: developer

119:     Notes: Typical calling sequence
120:        PetscLayoutCreate(MPI_Comm,PetscLayout *);
121:        PetscLayoutSetBlockSize(PetscLayout,1);
122:        PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both
123:        PetscLayoutSetUp(PetscLayout);
124:        PetscLayoutGetSize(PetscLayout,PetscInt *);


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

129:     Fortran Notes:
130:       Not available from Fortran

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

135: @*/
138: PetscErrorCode  PetscLayoutSetUp(PetscLayout map)
139: {
140:   PetscMPIInt    rank,size;
141:   PetscInt       p;

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

148:   MPI_Comm_size(map->comm, &size);
149:   MPI_Comm_rank(map->comm, &rank);
150:   if (map->n > 0) map->n = map->n/map->bs;
151:   if (map->N > 0) map->N = map->N/map->bs;
152:   PetscSplitOwnership(map->comm,&map->n,&map->N);
153:   map->n = map->n*map->bs;
154:   map->N = map->N*map->bs;
155:   if (!map->range) {
156:     PetscMalloc((size+1)*sizeof(PetscInt), &map->range);
157:   }
158:   MPI_Allgather(&map->n, 1, MPIU_INT, map->range+1, 1, MPIU_INT, map->comm);

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

163:   map->rstart = map->range[rank];
164:   map->rend   = map->range[rank+1];
165: #if defined(PETSC_THREADCOMM_ACTIVE)
166:   /* Set the thread ownership ranges */
167:   PetscThreadCommGetOwnershipRanges(map->comm,map->n,&map->trstarts);
168: #endif
169:   return(0);
170: }

174: /*@C

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

178:      Collective on PetscLayout

180:     Input Parameter:
181: .     in - input PetscLayout to be duplicated

183:     Output Parameter:
184: .     out - the copy

186:    Level: developer

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

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

192: @*/
193: PetscErrorCode  PetscLayoutDuplicate(PetscLayout in,PetscLayout *out)
194: {
195:   PetscMPIInt    size;
197:   MPI_Comm       comm = in->comm;

200:   PetscLayoutDestroy(out);
201:   PetscLayoutCreate(comm,out);
202:   MPI_Comm_size(comm,&size);
203:   PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout));
204:   PetscMalloc((size+1)*sizeof(PetscInt),&(*out)->range);
205:   PetscMemcpy((*out)->range,in->range,(size+1)*sizeof(PetscInt));

207:   (*out)->refcnt = 0;
208:   return(0);
209: }

213: /*@C

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

217:      Collective on PetscLayout

219:     Input Parameter:
220: .     in - input PetscLayout to be copied

222:     Output Parameter:
223: .     out - the reference location

225:    Level: developer

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

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

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

233: @*/
234: PetscErrorCode  PetscLayoutReference(PetscLayout in,PetscLayout *out)
235: {

239:   in->refcnt++;
240:   PetscLayoutDestroy(out);
241:   *out = in;
242:   return(0);
243: }

247: /*@C

249:     PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout

251:      Collective on PetscLayout

253:     Input Parameter:
254: +     in - input PetscLayout
255: -     ltog - the local to global mapping


258:    Level: developer

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

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

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

266: @*/
267: PetscErrorCode  PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog)
268: {

272:   PetscObjectReference((PetscObject)ltog);
273:   ISLocalToGlobalMappingDestroy(&in->mapping);

275:   in->mapping = ltog;
276:   return(0);
277: }

281: /*@C

283:     PetscLayoutSetISLocalToGlobalMappingBlock - sets a ISLocalGlobalMapping into a PetscLayout

285:      Collective on PetscLayout

287:     Input Parameter:
288: +     in - input PetscLayout
289: -     ltog - the local to global block mapping


292:    Level: developer

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

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

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

300: @*/
301: PetscErrorCode  PetscLayoutSetISLocalToGlobalMappingBlock(PetscLayout in,ISLocalToGlobalMapping ltog)
302: {

306:   PetscObjectReference((PetscObject)ltog);
307:   ISLocalToGlobalMappingDestroy(&in->bmapping);

309:   in->bmapping = ltog;
310:   return(0);
311: }

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

316:     Collective on PetscLayout

318:    Input Parameters:
319: +    map - pointer to the map
320: -    n - the local size

322:    Level: developer

324:     Notes:
325:        Call this after the call to PetscLayoutCreate()

327:     Fortran Notes:
328:       Not available from Fortran

330: .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
331:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()

333: @*/
336: PetscErrorCode  PetscLayoutSetLocalSize(PetscLayout map,PetscInt n)
337: {
339:   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);
340:   map->n = n;
341:   return(0);
342: }

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

347:     Not Collective

349:    Input Parameters:
350: .    map - pointer to the map

352:    Output Parameters:
353: .    n - the local size

355:    Level: developer

357:     Notes:
358:        Call this after the call to PetscLayoutSetUp()

360:     Fortran Notes:
361:       Not available from Fortran

363: .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
364:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()

366: @*/
369: PetscErrorCode  PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n)
370: {
372:   *n = map->n;
373:   return(0);
374: }

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

379:     Logically Collective on PetscLayout

381:    Input Parameters:
382: +    map - pointer to the map
383: -    n - the global size

385:    Level: developer

387:     Notes:
388:        Call this after the call to PetscLayoutCreate()

390:     Fortran Notes:
391:       Not available from Fortran

393: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
394:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()

396: @*/
399: PetscErrorCode  PetscLayoutSetSize(PetscLayout map,PetscInt n)
400: {
402:   map->N = n;
403:   return(0);
404: }

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

409:     Not Collective

411:    Input Parameters:
412: .    map - pointer to the map

414:    Output Parameters:
415: .    n - the global size

417:    Level: developer

419:     Notes:
420:        Call this after the call to PetscLayoutSetUp()

422:     Fortran Notes:
423:       Not available from Fortran

425: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
426:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()

428: @*/
431: PetscErrorCode  PetscLayoutGetSize(PetscLayout map,PetscInt *n)
432: {
434:   *n = map->N;
435:   return(0);
436: }

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

441:     Logically Collective on PetscLayout

443:    Input Parameters:
444: +    map - pointer to the map
445: -    bs - the size

447:    Level: developer

449:     Notes:
450:        Call this after the call to PetscLayoutCreate()

452:     Fortran Notes:
453:       Not available from Fortran

455: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(),
456:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp()

458: @*/
461: PetscErrorCode  PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs)
462: {
464:   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);
465:   if (map->bs > 0 && map->bs != bs) SETERRQ2(map->comm,PETSC_ERR_ARG_INCOMP,"Cannot change block size %D to %D",map->bs,bs);
466:   map->bs = bs;
467:   return(0);
468: }

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

473:     Not Collective

475:    Input Parameters:
476: .    map - pointer to the map

478:    Output Parameters:
479: .    bs - the size

481:    Level: developer

483:     Notes:
484:        Call this after the call to PetscLayoutSetUp()

486:     Fortran Notes:
487:       Not available from Fortran

489: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
490:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize()

492: @*/
495: PetscErrorCode  PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs)
496: {
498:   *bs = map->bs;
499:   return(0);
500: }


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

506:     Not Collective

508:    Input Parameters:
509: .    map - pointer to the map

511:    Output Parameters:
512: +    rstart - first index owned by this process
513: -    rend - one more than the last index owned by this process

515:    Level: developer

517:     Notes:
518:        Call this after the call to PetscLayoutSetUp()

520:     Fortran Notes:
521:       Not available from Fortran

523: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
524:           PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()

526: @*/
529: PetscErrorCode  PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend)
530: {
532:   if (rstart) *rstart = map->rstart;
533:   if (rend)   *rend   = map->rend;
534:   return(0);
535: }

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

540:     Not Collective

542:    Input Parameters:
543: .    map - pointer to the map

545:    Output Parameters:
546: .    range - start of each processors range of indices (the final entry is one more then the
547:              last index on the last process)

549:    Level: developer

551:     Notes:
552:        Call this after the call to PetscLayoutSetUp()

554:     Fortran Notes:
555:       Not available from Fortran

557: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
558:           PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()

560: @*/
563: PetscErrorCode  PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[])
564: {
566:   *range = map->range;
567:   return(0);
568: }

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

575:    Collective

577:    Input Arguments:
578: +  sf - star forest
579: .  layout - PetscLayout defining the global space
580: .  nleaves - number of leaf vertices on the current process, each of these references a root on any process
581: .  ilocal - locations of leaves in leafdata buffers, pass NULL for contiguous storage
582: -  iremote - remote locations of root vertices for each leaf on the current process

584:    Level: intermediate

586: .seealso: PetscSFCreate(), PetscSFView(), PetscSFSetGraph(), PetscSFGetGraph()
587: @*/
588: PetscErrorCode PetscSFSetGraphLayout(PetscSF sf,PetscLayout layout,PetscInt nleaves,const PetscInt *ilocal,PetscCopyMode localmode,const PetscInt *iremote)
589: {
591:   PetscInt       i,nroots;
592:   PetscSFNode    *remote;

595:   PetscLayoutGetLocalSize(layout,&nroots);
596:   PetscMalloc(nleaves*sizeof(PetscSFNode),&remote);
597:   for (i=0; i<nleaves; i++) {
598:     PetscInt owner = -1;
599:     PetscLayoutFindOwner(layout,iremote[i],&owner);
600:     remote[i].rank  = owner;
601:     remote[i].index = iremote[i] - layout->range[owner];
602:   }
603:   PetscSFSetGraph(sf,nroots,nleaves,ilocal,localmode,remote,PETSC_OWN_POINTER);
604:   return(0);
605: }