Date: 2015-10-02T22:04:08+00:00

Actual source code: pmap.c
petsc-3.6.2 2015-10-02
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: }