Date: 2013-07-02T14:40:46+00:00

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: }