Actual source code: pmap.c

petsc-3.5.1 2014-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>
  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(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: #if defined(PETSC_THREADCOMM_ACTIVE)
 98:     PetscFree((*map)->trstarts);
 99: #endif

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

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

111:     Collective on MPI_Comm

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

116:    Level: developer

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


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

128:     Fortran Notes:
129:       Not available from Fortran

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

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

144:   if ((map->n >= 0) && (map->N >= 0) && (map->range)) return(0);

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

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

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

172: /*@C

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

176:      Collective on PetscLayout

178:     Input Parameter:
179: .     in - input PetscLayout to be duplicated

181:     Output Parameter:
182: .     out - the copy

184:    Level: developer

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

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

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

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

205:   (*out)->refcnt = 0;
206:   return(0);
207: }

211: /*@C

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

215:      Collective on PetscLayout

217:     Input Parameter:
218: .     in - input PetscLayout to be copied

220:     Output Parameter:
221: .     out - the reference location

223:    Level: developer

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

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

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

231: @*/
232: PetscErrorCode  PetscLayoutReference(PetscLayout in,PetscLayout *out)
233: {

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

245: /*@C

247:     PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout

249:      Collective on PetscLayout

251:     Input Parameter:
252: +     in - input PetscLayout
253: -     ltog - the local to global mapping


256:    Level: developer

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

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

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

264: @*/
265: PetscErrorCode  PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog)
266: {
268:   PetscInt       bs;

271:   ISLocalToGlobalMappingGetBlockSize(ltog,&bs);
272:   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);
273:   PetscObjectReference((PetscObject)ltog);
274:   ISLocalToGlobalMappingDestroy(&in->mapping);
275:   in->mapping = ltog;
276:   return(0);
277: }

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

282:     Collective on PetscLayout

284:    Input Parameters:
285: +    map - pointer to the map
286: -    n - the local size

288:    Level: developer

290:     Notes:
291:        Call this after the call to PetscLayoutCreate()

293:     Fortran Notes:
294:       Not available from Fortran

296: .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
297:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()

299: @*/
302: PetscErrorCode  PetscLayoutSetLocalSize(PetscLayout map,PetscInt n)
303: {
305:   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);
306:   map->n = n;
307:   return(0);
308: }

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

313:     Not Collective

315:    Input Parameters:
316: .    map - pointer to the map

318:    Output Parameters:
319: .    n - the local size

321:    Level: developer

323:     Notes:
324:        Call this after the call to PetscLayoutSetUp()

326:     Fortran Notes:
327:       Not available from Fortran

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

332: @*/
335: PetscErrorCode  PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n)
336: {
338:   *n = map->n;
339:   return(0);
340: }

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

345:     Logically Collective on PetscLayout

347:    Input Parameters:
348: +    map - pointer to the map
349: -    n - the global size

351:    Level: developer

353:     Notes:
354:        Call this after the call to PetscLayoutCreate()

356:     Fortran Notes:
357:       Not available from Fortran

359: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
360:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()

362: @*/
365: PetscErrorCode  PetscLayoutSetSize(PetscLayout map,PetscInt n)
366: {
368:   map->N = n;
369:   return(0);
370: }

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

375:     Not Collective

377:    Input Parameters:
378: .    map - pointer to the map

380:    Output Parameters:
381: .    n - the global size

383:    Level: developer

385:     Notes:
386:        Call this after the call to PetscLayoutSetUp()

388:     Fortran Notes:
389:       Not available from Fortran

391: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
392:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()

394: @*/
397: PetscErrorCode  PetscLayoutGetSize(PetscLayout map,PetscInt *n)
398: {
400:   *n = map->N;
401:   return(0);
402: }

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

407:     Logically Collective on PetscLayout

409:    Input Parameters:
410: +    map - pointer to the map
411: -    bs - the size

413:    Level: developer

415:     Notes:
416:        Call this after the call to PetscLayoutCreate()

418:     Fortran Notes:
419:       Not available from Fortran

421: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(),
422:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp()

424: @*/
427: PetscErrorCode  PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs)
428: {
430:   if (bs < 0) return(0);
431:   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);
432:   if (map->bs > 0 && map->bs != bs) SETERRQ2(map->comm,PETSC_ERR_ARG_INCOMP,"Cannot change block size %D to %D",map->bs,bs);
433:   if (map->mapping) {
434:     PetscInt       lbs;

437:     ISLocalToGlobalMappingGetBlockSize(map->mapping,&lbs);
438:     if (lbs != bs) SETERRQ2(map->comm,PETSC_ERR_PLIB,"Blocksize of localtoglobalmapping %D must match that of layout %D",lbs,bs);
439:   }
440:   map->bs = bs;
441:   return(0);
442: }

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

447:     Not Collective

449:    Input Parameters:
450: .    map - pointer to the map

452:    Output Parameters:
453: .    bs - the size

455:    Level: developer

457:     Notes:
458:        Call this after the call to PetscLayoutSetUp()

460:     Fortran Notes:
461:       Not available from Fortran

463: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
464:           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize()

466: @*/
469: PetscErrorCode  PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs)
470: {
472:   *bs = PetscAbs(map->bs);
473:   return(0);
474: }


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

480:     Not Collective

482:    Input Parameters:
483: .    map - pointer to the map

485:    Output Parameters:
486: +    rstart - first index owned by this process
487: -    rend - one more than the last index owned by this process

489:    Level: developer

491:     Notes:
492:        Call this after the call to PetscLayoutSetUp()

494:     Fortran Notes:
495:       Not available from Fortran

497: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
498:           PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()

500: @*/
503: PetscErrorCode  PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend)
504: {
506:   if (rstart) *rstart = map->rstart;
507:   if (rend)   *rend   = map->rend;
508:   return(0);
509: }

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

514:     Not Collective

516:    Input Parameters:
517: .    map - pointer to the map

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

523:    Level: developer

525:     Notes:
526:        Call this after the call to PetscLayoutSetUp()

528:     Fortran Notes:
529:       Not available from Fortran

531: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
532:           PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()

534: @*/
537: PetscErrorCode  PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[])
538: {
540:   *range = map->range;
541:   return(0);
542: }

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

549:    Collective

551:    Input Arguments:
552: +  sf - star forest
553: .  layout - PetscLayout defining the global space
554: .  nleaves - number of leaf vertices on the current process, each of these references a root on any process
555: .  ilocal - locations of leaves in leafdata buffers, pass NULL for contiguous storage
556: -  iremote - remote locations of root vertices for each leaf on the current process

558:    Level: intermediate

560: .seealso: PetscSFCreate(), PetscSFView(), PetscSFSetGraph(), PetscSFGetGraph()
561: @*/
562: PetscErrorCode PetscSFSetGraphLayout(PetscSF sf,PetscLayout layout,PetscInt nleaves,const PetscInt *ilocal,PetscCopyMode localmode,const PetscInt *iremote)
563: {
565:   PetscInt       i,nroots;
566:   PetscSFNode    *remote;

569:   PetscLayoutGetLocalSize(layout,&nroots);
570:   PetscMalloc1(nleaves,&remote);
571:   for (i=0; i<nleaves; i++) {
572:     PetscInt owner = -1;
573:     PetscLayoutFindOwner(layout,iremote[i],&owner);
574:     remote[i].rank  = owner;
575:     remote[i].index = iremote[i] - layout->range[owner];
576:   }
577:   PetscSFSetGraph(sf,nroots,nleaves,ilocal,localmode,remote,PETSC_OWN_POINTER);
578:   return(0);
579: }