Actual source code: pmap.c

petsc-3.6.1 2015-08-06
Report Typos and Errors
  2: /*
  3:    This file contains routines for basic map object implementation.
  4: */

  6: #include <petscvec.h>
  7: #include <petscsf.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(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:     PetscFree((*map));
 98:   }
 99:   *map = NULL;
100:   return(0);
101: }

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.

107:     Collective on MPI_Comm

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

112:    Level: developer

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


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

124:     Fortran Notes:
125:       Not available from Fortran

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

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

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/PetscAbs(map->bs);
145:   if (map->N > 0) map->N = map->N/PetscAbs(map->bs);
146:   PetscSplitOwnership(map->comm,&map->n,&map->N);
147:   map->n = map->n*PetscAbs(map->bs);
148:   map->N = map->N*PetscAbs(map->bs);
149:   if (!map->range) {
150:     PetscMalloc1(size+1, &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:   return(0);
160: }

164: /*@C

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

168:      Collective on PetscLayout

170:     Input Parameter:
171: .     in - input PetscLayout to be duplicated

173:     Output Parameter:
174: .     out - the copy

176:    Level: developer

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

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

182: @*/
183: PetscErrorCode  PetscLayoutDuplicate(PetscLayout in,PetscLayout *out)
184: {
185:   PetscMPIInt    size;
187:   MPI_Comm       comm = in->comm;

190:   PetscLayoutDestroy(out);
191:   PetscLayoutCreate(comm,out);
192:   MPI_Comm_size(comm,&size);
193:   PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout));
194:   PetscMalloc1(size+1,&(*out)->range);
195:   PetscMemcpy((*out)->range,in->range,(size+1)*sizeof(PetscInt));

197:   (*out)->refcnt = 0;
198:   return(0);
199: }

203: /*@C

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

207:      Collective on PetscLayout

209:     Input Parameter:
210: .     in - input PetscLayout to be copied

212:     Output Parameter:
213: .     out - the reference location

215:    Level: developer

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

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

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

223: @*/
224: PetscErrorCode  PetscLayoutReference(PetscLayout in,PetscLayout *out)
225: {

229:   in->refcnt++;
230:   PetscLayoutDestroy(out);
231:   *out = in;
232:   return(0);
233: }

237: /*@C

239:     PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout

241:      Collective on PetscLayout

243:     Input Parameter:
244: +     in - input PetscLayout
245: -     ltog - the local to global mapping


248:    Level: developer

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

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

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

256: @*/
257: PetscErrorCode  PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog)
258: {
260:   PetscInt       bs;

263:   ISLocalToGlobalMappingGetBlockSize(ltog,&bs);
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:   PetscObjectReference((PetscObject)ltog);
266:   ISLocalToGlobalMappingDestroy(&in->mapping);
267:   in->mapping = ltog;
268:   return(0);
269: }

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

274:     Collective on PetscLayout

276:    Input Parameters:
277: +    map - pointer to the map
278: -    n - the local size

280:    Level: developer

282:     Notes:
283:        Call this after the call to PetscLayoutCreate()

285:     Fortran Notes:
286:       Not available from Fortran

288: .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
289:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()

291: @*/
294: PetscErrorCode  PetscLayoutSetLocalSize(PetscLayout map,PetscInt n)
295: {
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:   return(0);
300: }

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

305:     Not Collective

307:    Input Parameters:
308: .    map - pointer to the map

310:    Output Parameters:
311: .    n - the local size

313:    Level: developer

315:     Notes:
316:        Call this after the call to PetscLayoutSetUp()

318:     Fortran Notes:
319:       Not available from Fortran

321: .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
322:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()

324: @*/
327: PetscErrorCode  PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n)
328: {
330:   *n = map->n;
331:   return(0);
332: }

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

337:     Logically Collective on PetscLayout

339:    Input Parameters:
340: +    map - pointer to the map
341: -    n - the global size

343:    Level: developer

345:     Notes:
346:        Call this after the call to PetscLayoutCreate()

348:     Fortran Notes:
349:       Not available from Fortran

351: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
352:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()

354: @*/
357: PetscErrorCode  PetscLayoutSetSize(PetscLayout map,PetscInt n)
358: {
360:   map->N = n;
361:   return(0);
362: }

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

367:     Not Collective

369:    Input Parameters:
370: .    map - pointer to the map

372:    Output Parameters:
373: .    n - the global size

375:    Level: developer

377:     Notes:
378:        Call this after the call to PetscLayoutSetUp()

380:     Fortran Notes:
381:       Not available from Fortran

383: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
384:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()

386: @*/
389: PetscErrorCode  PetscLayoutGetSize(PetscLayout map,PetscInt *n)
390: {
392:   *n = map->N;
393:   return(0);
394: }

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

399:     Logically Collective on PetscLayout

401:    Input Parameters:
402: +    map - pointer to the map
403: -    bs - the size

405:    Level: developer

407:     Notes:
408:        Call this after the call to PetscLayoutCreate()

410:     Fortran Notes:
411:       Not available from Fortran

413: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(),
414:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp()

416: @*/
419: PetscErrorCode  PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs)
420: {
422:   if (bs < 0) return(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;

429:     ISLocalToGlobalMappingGetBlockSize(map->mapping,&lbs);
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:   return(0);
434: }

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

439:     Not Collective

441:    Input Parameters:
442: .    map - pointer to the map

444:    Output Parameters:
445: .    bs - the size

447:    Level: developer

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

452:     Fortran Notes:
453:       Not available from Fortran

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

458: @*/
461: PetscErrorCode  PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs)
462: {
464:   *bs = PetscAbs(map->bs);
465:   return(0);
466: }


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

472:     Not Collective

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

477:    Output Parameters:
478: +    rstart - first index owned by this process
479: -    rend - one more than the last index owned by this process

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(),
490:           PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()

492: @*/
495: PetscErrorCode  PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend)
496: {
498:   if (rstart) *rstart = map->rstart;
499:   if (rend)   *rend   = map->rend;
500:   return(0);
501: }

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

506:     Not Collective

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

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)

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(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()

526: @*/
529: PetscErrorCode  PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[])
530: {
532:   *range = map->range;
533:   return(0);
534: }

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

541:    Collective

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

550:    Level: intermediate

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

561:   PetscLayoutGetLocalSize(layout,&nroots);
562:   PetscMalloc1(nleaves,&remote);
563:   for (i=0; i<nleaves; i++) {
564:     PetscInt owner = -1;
565:     PetscLayoutFindOwner(layout,iremote[i],&owner);
566:     remote[i].rank  = owner;
567:     remote[i].index = iremote[i] - layout->range[owner];
568:   }
569:   PetscSFSetGraph(sf,nroots,nleaves,ilocal,localmode,remote,PETSC_OWN_POINTER);
570:   return(0);
571: }