Actual source code: vscreate.c
petsc-3.10.5 2019-03-28
Report Typos and Errors

      1: /*
      2:     The VECSCATTER (vec scatter) interface routines, callable by users.
      3: */

      5:  #include <petsc/private/vecscatterimpl.h>

      7: /* Logging support */
      8: PetscClassId VEC_SCATTER_CLASSID;

     10: PetscFunctionList VecScatterList              = NULL;
     11: PetscBool         VecScatterRegisterAllCalled = PETSC_FALSE;

     13: /*@C
     14:   VecScatterSetType - Builds a vector scatter, for a particular vector scatter implementation.

     16:   Collective on VecScatter

     18:   Input Parameters:
     19: + vscat - The vector scatter object
     20: - type - The name of the vector scatter type

     22:   Options Database Key:
     23: . -vecscatter_type <type> - Sets the vector scatter type; use -help for a list
     24:                      of available types

     26:   Notes:
     27:   See "petsc/include/petscvec.h" for available vector scatter types (for instance, VECSCATTERMPI1, or VECSCATTERMPI3NODE).

     29:   Use VecScatterDuplicate() to form additional vectors scatter of the same type as an existing vector scatter.

     31:   Level: intermediate

     33: .keywords: vector scatter, set, type
     34: .seealso: VecScatterGetType(), VecScatterCreate()
     35: @*/
     36: PetscErrorCode VecScatterSetType(VecScatter vscat, VecScatterType type)
     37: {
     38:   PetscBool      match;
     40:   PetscErrorCode (*r)(VecScatter);

     44:   PetscObjectTypeCompare((PetscObject)vscat, type, &match);
     45:   if (match) return(0);

     47:   PetscFunctionListFind(VecScatterList,type,&r);
     48:   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown vector scatter type: %s",type);

     50:   if (vscat->ops->destroy) {
     51:     (*vscat->ops->destroy)(vscat);
     52:     vscat->ops->destroy = NULL;
     53:   }

     55:   (*r)(vscat);
     56:   return(0);
     57: }

     59: /*@C
     60:   VecScatterGetType - Gets the vector scatter type name (as a string) from the VecScatter.

     62:   Not Collective

     64:   Input Parameter:
     65: . vscat  - The vector scatter

     67:   Output Parameter:
     68: . type - The vector scatter type name

     70:   Level: intermediate

     72: .keywords: vector scatter, get, type, name
     73: .seealso: VecScatterSetType(), VecScatterCreate()
     74: @*/
     75: PetscErrorCode VecScatterGetType(VecScatter vscat, VecScatterType *type)
     76: {

     82:   VecScatterRegisterAll();
     83:   *type = ((PetscObject)vscat)->type_name;
     84:   return(0);
     85: }

     87: /*@
     88:   VecScatterSetFromOptions - Configures the vector scatter from the options database.

     90:   Collective on VecScatter

     92:   Input Parameter:
     93: . vscat - The vector scatter

     95:   Notes:
     96:     To see all options, run your program with the -help option, or consult the users manual.
     97:           Must be called after VecScatterCreate() but before the vector scatter is used.

     99:   Level: beginner

    101:   Concepts: vectorscatter^setting options
    102:   Concepts: vectorscatter^setting type

    104: .keywords: VecScatter, set, options, database
    105: .seealso: VecScatterCreate()
    106: @*/
    107: PetscErrorCode VecScatterSetFromOptions(VecScatter vscat)
    108: {
    110:   PetscBool      opt;
    111:   VecScatterType defaultType;
    112:   char           typeName[256];
    113:   PetscMPIInt    size;

    118:   PetscObjectOptionsBegin((PetscObject)vscat);
    119:   MPI_Comm_size(PetscObjectComm((PetscObject)vscat), &size);

    121:   /* Handle vector type options */
    122:   if (((PetscObject)vscat)->type_name) {
    123:     defaultType = ((PetscObject)vscat)->type_name;
    124:   } else {
    125:     if (size > 1) defaultType = VECSCATTERMPI1;
    126:     else defaultType = VECSCATTERSEQ;
    127:   }

    129:   VecScatterRegisterAll();
    130:   PetscOptionsFList("-vecscatter_type","Vector Scatter type","VecScatterSetType",VecScatterList,defaultType,typeName,256,&opt);
    131:   if (size > 1 && opt) {
    132:     VecScatterSetType(vscat,typeName);
    133:   } else {
    134:     VecScatterSetType(vscat,defaultType);
    135:   }

    137:   vscat->beginandendtogether = PETSC_FALSE;
    138:   PetscOptionsBool("-vecscatter_merge","Use combined (merged) vector scatter begin and end","VecScatterCreate",vscat->beginandendtogether,&vscat->beginandendtogether,NULL);
    139:   if (vscat->beginandendtogether) {
    140:     PetscInfo(vscat,"Using combined (merged) vector scatter begin and end\n");
    141:   }

    143:   PetscOptionsEnd();
    144:   return(0);
    145: }

    147: /*@C
    148:   VecScatterRegister -  Adds a new vector scatter component implementation

    150:   Not Collective

    152:   Input Parameters:
    153: + name        - The name of a new user-defined creation routine
    154: - create_func - The creation routine itself

    156:   Notes:
    157:   VecScatterRegister() may be called multiple times to add several user-defined vectors

    159:   Sample usage:
    160: .vb
    161:     VecScatterRegister("my_vecscatter",MyVecScatterCreate);
    162: .ve

    164:   Then, your vector scatter type can be chosen with the procedural interface via
    165: .vb
    166:     VecScatterCreate(MPI_Comm, VecScatter *);
    167:     VecScatterSetType(VecScatter,"my_vectorscatter_name");
    168: .ve
    169:    or at runtime via the option
    170: .vb
    171:     -vecscatter_type my_vectorscatter_name
    172: .ve

    174:   Level: advanced

    176: .keywords: VecScatter, Register

    178: .seealso: VecScatterRegisterAll(), VecScatterRegisterDestroy()
    179: @*/
    180: PetscErrorCode VecScatterRegister(const char sname[], PetscErrorCode (*function)(VecScatter))
    181: {

    185:   VecInitializePackage();
    186:   PetscFunctionListAdd(&VecScatterList,sname,function);
    187:   return(0);
    188: }

    190: /* VecScatterCreate() will be renamed as VecScatterCreateWithVecs() */
    191: /* ---------------------------------------------------------------- */
    192: /*@
    193:    VecScatterCreate - Creates a vector scatter context.

    195:    Collective on Vec

    197:    Input Parameters:
    198: +  xin - a vector that defines the shape (parallel data layout of the vector)
    199:          of vectors from which we scatter
    200: .  yin - a vector that defines the shape (parallel data layout of the vector)
    201:          of vectors to which we scatter
    202: .  ix - the indices of xin to scatter (if NULL scatters all values)
    203: -  iy - the indices of yin to hold results (if NULL fills entire vector yin)

    205:    Output Parameter:
    206: .  newctx - location to store the new scatter context

    208:    Options Database Keys: (uses regular MPI_Sends by default)
    209: .  -vecscatter_view         - Prints detail of communications
    210: .  -vecscatter_view ::ascii_info    - Print less details about communication
    211: .  -vecscatter_merge        - VecScatterBegin() handles all of the communication, VecScatterEnd() is a nop
    212:                               eliminates the chance for overlap of computation and communication
    213: .  -vecscatter_packtogether - Pack all messages before sending, receive all messages before unpacking
    214:                               will make the results of scatters deterministic when otherwise they are not (it may be slower also).

    216:     Level: intermediate

    218:   Notes:
    219:    In calls to VecScatter() you can use different vectors than the xin and
    220:    yin you used above; BUT they must have the same parallel data layout, for example,
    221:    they could be obtained from VecDuplicate().
    222:    A VecScatter context CANNOT be used in two or more simultaneous scatters;
    223:    that is you cannot call a second VecScatterBegin() with the same scatter
    224:    context until the VecScatterEnd() has been called on the first VecScatterBegin().
    225:    In this case a separate VecScatter is needed for each concurrent scatter.

    227:    Currently the MPI_Send() use PERSISTENT versions.
    228:    (this unfortunately requires that the same in and out arrays be used for each use, this
    229:     is why  we always need to pack the input into the work array before sending
    230:     and unpack upon receiving instead of using MPI datatypes to avoid the packing/unpacking).

    232:    Both ix and iy cannot be NULL at the same time.

    234:    Concepts: scatter^between vectors
    235:    Concepts: gather^between vectors

    237: .seealso: VecScatterDestroy(), VecScatterCreateToAll(), VecScatterCreateToZero()
    238: @*/
    239: PetscErrorCode VecScatterCreate(Vec xin,IS ix,Vec yin,IS iy,VecScatter *newctx)
    240: {
    241:   VecScatter        ctx;
    242:   PetscErrorCode    ierr;
    243:   PetscMPIInt       size;
    244:   MPI_Comm          comm,ycomm;

    247:   if (!ix && !iy) SETERRQ(PetscObjectComm((PetscObject)xin),PETSC_ERR_SUP,"Cannot pass default in for both input and output indices");
    249:   *newctx = NULL;
    250:   VecScatterInitializePackage();

    252:   /* Get comm from xin and yin */
    253:   PetscObjectGetComm((PetscObject)xin,&comm);
    254:   MPI_Comm_size(comm,&size);

    256:   PetscObjectGetComm((PetscObject)yin,&ycomm);
    257:   MPI_Comm_size(ycomm,&size);
    258:   if (size > 1) comm = ycomm;

    260:   PetscHeaderCreate(ctx,VEC_SCATTER_CLASSID,"VecScatter","Vector Scatter","VecScatter",comm,VecScatterDestroy,VecScatterView);

    262:   ctx->from_v = xin; ctx->to_v = yin;
    263:   ctx->from_is = ix; ctx->to_is = iy;
    264:   ctx->inuse        = PETSC_FALSE;
    265:   ctx->is_duplicate = PETSC_FALSE;

    267:   VecGetLocalSize(xin,&ctx->from_n);
    268:   VecGetLocalSize(yin,&ctx->to_n);
    269:   *newctx = ctx;

    271:   /* Set default scatter type */
    272:   MPI_Comm_size(comm,&size);
    273:   if (size == 1) {
    274:     VecScatterSetType(ctx,VECSCATTERSEQ);
    275:   } else {
    276:     VecScatterSetType(ctx,VECSCATTERMPI1);
    277:   }
    278:   VecScatterSetFromOptions(ctx);
    279:   return(0);
    280: }