Date: 2016-07-24T17:17:23+00:00

Actual source code: petscimpl.h
petsc-3.7.3 2016-07-24
Report Typos and Errors

      2: /*
      3:     Defines the basic header of all PETSc objects.
      4: */

      6: #if !defined(_PETSCHEAD_H)
      7: #define _PETSCHEAD_H
      8: #include <petscsys.h>

     10: #if defined(PETSC_HAVE_CUDA)
     11: #include <cuda.h>
     12: #include <cublas_v2.h>
     13: #endif

     15: /*
     16:    All major PETSc data structures have a common core; this is defined
     17:    below by PETSCHEADER.

     19:    PetscHeaderCreate() should be used whenever creating a PETSc structure.
     20: */

     22: /*
     23:    PetscOps: structure of core operations that all PETSc objects support.

     25:       getcomm()         - Gets the object's communicator.
     26:       view()            - Is the routine for viewing the entire PETSc object; for
     27:                           example, MatView() is the general matrix viewing routine.
     28:                           This is used by PetscObjectView((PetscObject)obj) to allow
     29:                           viewing any PETSc object.
     30:       destroy()         - Is the routine for destroying the entire PETSc object;
     31:                           for example,MatDestroy() is the general matrix
     32:                           destruction routine.
     33:                           This is used by PetscObjectDestroy((PetscObject*)&obj) to allow
     34:                           destroying any PETSc object.
     35:       compose()         - Associates a PETSc object with another PETSc object with a name
     36:       query()           - Returns a different PETSc object that has been associated
     37:                           with the first object using a name.
     38:       composefunction() - Attaches an a function to a PETSc object with a name.
     39:       queryfunction()   - Requests a registered function that has been attached to a PETSc object.
     40: */

     42: typedef struct {
     43:    PetscErrorCode (*getcomm)(PetscObject,MPI_Comm *);
     44:    PetscErrorCode (*view)(PetscObject,PetscViewer);
     45:    PetscErrorCode (*destroy)(PetscObject*);
     46:    PetscErrorCode (*compose)(PetscObject,const char[],PetscObject);
     47:    PetscErrorCode (*query)(PetscObject,const char[],PetscObject *);
     48:    PetscErrorCode (*composefunction)(PetscObject,const char[],void (*)(void));
     49:    PetscErrorCode (*queryfunction)(PetscObject,const char[],void (**)(void));
     50: } PetscOps;

     52: typedef enum {PETSC_FORTRAN_CALLBACK_CLASS,PETSC_FORTRAN_CALLBACK_SUBTYPE,PETSC_FORTRAN_CALLBACK_MAXTYPE} PetscFortranCallbackType;
     53: typedef int PetscFortranCallbackId;
     54: #define PETSC_SMALLEST_FORTRAN_CALLBACK ((PetscFortranCallbackId)1000)
     55: PETSC_EXTERN PetscErrorCode PetscFortranCallbackRegister(PetscClassId,const char*,PetscFortranCallbackId*);
     56: PETSC_EXTERN PetscErrorCode PetscFortranCallbackGetSizes(PetscClassId,PetscInt*,PetscInt*);

     58: typedef struct {
     59:   void (*func)(void);
     60:   void *ctx;
     61: } PetscFortranCallback;

     63: /*
     64:    All PETSc objects begin with the fields defined in PETSCHEADER.
     65:    The PetscObject is a way of examining these fields regardless of
     66:    the specific object. In C++ this could be a base abstract class
     67:    from which all objects are derived.
     68: */
     69: #define PETSC_MAX_OPTIONS_HANDLER 5
     70: typedef struct _p_PetscObject {
     71:   PetscClassId         classid;
     72:   PetscOps             bops[1];
     73:   MPI_Comm             comm;
     74:   PetscInt             type;
     75:   PetscLogDouble       flops,time,mem,memchildren;
     76:   PetscObjectId        id;
     77:   PetscInt             refct;
     78:   PetscMPIInt          tag;
     79:   PetscFunctionList    qlist;
     80:   PetscObjectList      olist;
     81:   char                 *class_name;    /*  for example, "Vec" */
     82:   char                 *description;
     83:   char                 *mansec;
     84:   char                 *type_name;     /*  this is the subclass, for example VECSEQ which equals "seq" */
     85:   PetscObject          parent;
     86:   PetscObjectId        parentid;
     87:   char*                name;
     88:   char                 *prefix;
     89:   PetscInt             tablevel;
     90:   void                 *cpp;
     91:   PetscObjectState     state;
     92:   PetscInt             int_idmax,        intstar_idmax;
     93:   PetscObjectState     *intcomposedstate,*intstarcomposedstate;
     94:   PetscInt             *intcomposeddata, **intstarcomposeddata;
     95:   PetscInt             real_idmax,        realstar_idmax;
     96:   PetscObjectState     *realcomposedstate,*realstarcomposedstate;
     97:   PetscReal            *realcomposeddata, **realstarcomposeddata;
     98:   PetscInt             scalar_idmax,        scalarstar_idmax;
     99:   PetscObjectState     *scalarcomposedstate,*scalarstarcomposedstate;
    100:   PetscScalar          *scalarcomposeddata, **scalarstarcomposeddata;
    101:   void                 (**fortran_func_pointers)(void);                  /* used by Fortran interface functions to stash user provided Fortran functions */
    102:   PetscInt             num_fortran_func_pointers;                        /* number of Fortran function pointers allocated */
    103:   PetscFortranCallback *fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
    104:   PetscInt             num_fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
    105:   void                 *python_context;
    106:   PetscErrorCode       (*python_destroy)(void*);

    108:   PetscInt             noptionhandler;
    109:   PetscErrorCode       (*optionhandler[PETSC_MAX_OPTIONS_HANDLER])(PetscOptionItems*,PetscObject,void*);
    110:   PetscErrorCode       (*optiondestroy[PETSC_MAX_OPTIONS_HANDLER])(PetscObject,void*);
    111:   void                 *optionctx[PETSC_MAX_OPTIONS_HANDLER];
    112:   PetscPrecision       precision;
    113:   PetscBool            optionsprinted;
    114: #if defined(PETSC_HAVE_SAWS)
    115:   PetscBool            amsmem;          /* if PETSC_TRUE then this object is registered with SAWs and visible to clients */
    116:   PetscBool            amspublishblock; /* if PETSC_TRUE and publishing objects then will block at PetscObjectSAWsBlock() */
    117: #endif
    118:   PetscOptions         options;         /* options database used, NULL means default */
    119: } _p_PetscObject;

    121: #define PETSCHEADER(ObjectOps) \
    122:   _p_PetscObject hdr;          \
    123:   ObjectOps      ops[1]

    125: #define  PETSCFREEDHEADER -1

    127: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectDestroyFunction)(PetscObject*); /* force cast in next macro to NEVER use extern "C" style */
    128: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectViewFunction)(PetscObject,PetscViewer);

    130: /*@C
    131:     PetscHeaderCreate - Creates a PETSc object of a particular class

    133:     Input Parameters:
    134: +   classid - the classid associated with this object (for example VEC_CLASSID)
    135: .   class_name - string name of class; should be static (for example "Vec")
    136: .   descr - string containing short description; should be static (for example "Vector")
    137: .   mansec - string indicating section in manual pages; should be static (for example "Vec")
    138: .   comm - the MPI Communicator
    139: .   destroy - the destroy routine for this object (for example VecDestroy())
    140: -   view - the view routine for this object (for example VecView())

    142:     Output Parameter:
    143: .   h - the newly created object

    145:     Level: developer

    147: .seealso: PetscHeaderDestroy(), PetscClassIdRegister()

    149: @*/
    150: #define PetscHeaderCreate(h,classid,class_name,descr,mansec,comm,destroy,view) \
    151:   (PetscNew(&(h)) || \
    152:    PetscHeaderCreate_Private((PetscObject)h,classid,class_name,descr,mansec,comm,(PetscObjectDestroyFunction)destroy,(PetscObjectViewFunction)view) || \
    153:    PetscLogObjectCreate(h) || \
    154:    PetscLogObjectMemory((PetscObject)h,sizeof(*(h))))

    156: PETSC_EXTERN PetscErrorCode PetscComposedQuantitiesDestroy(PetscObject obj);
    157: PETSC_EXTERN PetscErrorCode PetscHeaderCreate_Private(PetscObject,PetscClassId,const char[],const char[],const char[],MPI_Comm,PetscObjectDestroyFunction,PetscObjectViewFunction);

    159: /*@C
    160:     PetscHeaderDestroy - Final step in destroying a PetscObject

    162:     Input Parameters:
    163: .   h - the header created with PetscHeaderCreate()

    165:     Level: developer

    167: .seealso: PetscHeaderCreate()
    168: @*/
    169: #define PetscHeaderDestroy(h) (PetscHeaderDestroy_Private((PetscObject)(*h)) || PetscFree(*h))

    171: PETSC_EXTERN PetscErrorCode PetscHeaderDestroy_Private(PetscObject);
    172: PETSC_EXTERN PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject,PetscObject);
    173: PETSC_EXTERN PetscErrorCode PetscObjectSetFortranCallback(PetscObject,PetscFortranCallbackType,PetscFortranCallbackId*,void(*)(void),void *ctx);
    174: PETSC_EXTERN PetscErrorCode PetscObjectGetFortranCallback(PetscObject,PetscFortranCallbackType,PetscFortranCallbackId,void(**)(void),void **ctx);

    176: PETSC_INTERN PetscErrorCode PetscCitationsInitialize(void);
    177: PETSC_INTERN PetscErrorCode PetscOptionsFindPair_Private(PetscOptions,const char[],const char[],char**,PetscBool*);

    181: /*
    182:     Macros to test if a PETSc object is valid and if pointers are valid
    183: */
    184: #if !defined(PETSC_USE_DEBUG)

    195: #else

    198:   do {                                                                  \
    199:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg); \
    201:     if (((PetscObject)(h))->classid != ck) {                            \
    202:       if (((PetscObject)(h))->classid == PETSCFREEDHEADER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
    203:       else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Wrong type of object: Parameter # %d",arg); \
    204:     }                                                                   \
    205:   } while (0)

    208:   do {                                                                  \
    209:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg); \
    211:     if (((PetscObject)(h))->classid == PETSCFREEDHEADER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
    212:     else if (((PetscObject)(h))->classid < PETSC_SMALLEST_CLASSID || ((PetscObject)(h))->classid > PETSC_LARGEST_CLASSID) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Invalid type of object: Parameter # %d",arg); \
    213:   } while (0)

    216:   do {                                                                  \
    217:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
    219:   } while (0)

    222:   do {                                                                  \
    223:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg);\
    225:   } while (0)

    228:   do {                                                                  \
    229:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Null Pointer: Parameter # %d",arg); \
    231:   } while (0)

    234:   do {                                                                  \
    235:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
    237:   } while (0)

    240:   do {                                                                  \
    241:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
    243:   } while (0)

    246:   do {                                                                  \
    247:     if (!f) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Function Pointer: Parameter # %d",arg); \
    248:   } while (0)

    250: #endif

    252: #if !defined(PETSC_USE_DEBUG)

    265: #else

    267: /*
    268:     For example, in the dot product between two vectors,
    269:   both vectors must be either Seq or MPI, not one of each
    270: */
    272:   if (((PetscObject)a)->type != ((PetscObject)b)->type) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMETYPE,"Objects not of same type: Argument # %d and %d",arga,argb);
    273: /*
    274:    Use this macro to check if the type is set
    275: */
    277:   if (!((PetscObject)a)->type_name) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"%s object's type is not set: Argument # %d",((PetscObject)a)->class_name,arg);
    278: /*
    279:    Sometimes object must live on same communicator to inter-operate
    280: */
    282:   do {                                                                  \
    283:     PetscErrorCode _6_ierr,__flag;                                      \
    284:     _6_MPI_Comm_compare(PetscObjectComm((PetscObject)a),PetscObjectComm((PetscObject)b),&__flag);CHKERRQ(_6_ierr);                                                   \
    285:     if (__flag != MPI_CONGRUENT && __flag != MPI_IDENT) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"Different communicators in the two objects: Argument # %d and %d flag %d",arga,argb,__flag); \
    286:   } while (0)

    289:   do {                                                  \
    292:   } while (0)

    295:   do {                                                                  \
    296:     PetscErrorCode _7_ierr;                                             \
    297:     PetscReal b1[6],b2[6];                                              \
    298:     if (PetscIsNanScalar(b)) {b1[4] = -1; b1[5] = 1;} else b1[4] = b1[5] = 0; \
    299:     b1[0] = -PetscRealPart(b); b1[1] = PetscRealPart(b);b1[2] = -PetscImaginaryPart(b); b1[3] = PetscImaginaryPart(b);         \
    300:     _7_MPI_Allreduce(b1,b2,6,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
    301:     if (!(b2[4] == -1 && b2[5] == 1) && (-b2[0] != b2[1] || -b2[2] != b2[3])) SETERRQ1(PetscObjectComm((PetscObject)a),PETSC_ERR_ARG_WRONG,"Scalar value must be same on all processes, argument # %d",c); \
    302:   } while (0)

    305:   do {                                                                  \
    306:     PetscErrorCode _7_ierr;                                             \
    307:     PetscReal b1[4],b2[4];                                              \
    308:     if (PetscIsNanReal(b)) {b1[2] = -1; b1[3] = 1;} else b1[2] = b1[3] = 0; \
    309:     b1[0] = -b; b1[1] = b;                                                  \
    310:     _7_MPI_Allreduce(b1,b2,4,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
    311:     if (!(b2[2] == -1 && b2[3] == 1) && -b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)a),PETSC_ERR_ARG_WRONG,"Real value must be same on all processes, argument # %d",c); \
    312:   } while (0)

    315:   do {                                                                  \
    316:     PetscErrorCode _7_ierr;                                             \
    317:     PetscInt b1[2],b2[2];                                               \
    318:     b1[0] = -b; b1[1] = b;                                              \
    319:     _7_MPIU_Allreduce(b1,b2,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
    320:     if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)a),PETSC_ERR_ARG_WRONG,"Int value must be same on all processes, argument # %d",c); \
    321:   } while (0)

    326:   do {                                                                  \
    327:     PetscErrorCode _7_ierr;                                             \
    328:     PetscMPIInt b1[2],b2[2];                                            \
    329:     b1[0] = -(PetscMPIInt)b; b1[1] = (PetscMPIInt)b;                    \
    330:     _7_MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
    331:     if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)a),PETSC_ERR_ARG_WRONG,"Bool value must be same on all processes, argument # %d",c); \
    332:   } while (0)

    335:   do {                                                                  \
    336:     PetscErrorCode _7_ierr;                                             \
    337:     PetscMPIInt b1[2],b2[2];                                            \
    338:     b1[0] = -(PetscMPIInt)b; b1[1] = (PetscMPIInt)b;                    \
    339:     _7_MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
    340:     if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)a),PETSC_ERR_ARG_WRONG,"Enum value must be same on all processes, argument # %d",c); \
    341:   } while (0)

    343: #endif

    345: /*
    346:    PetscTryMethod - Queries an object for a method, if it exists then calls it.
    347:               These are intended to be used only inside PETSc functions.

    349:    Level: developer

    351: .seealso: PetscUseMethod()
    352: */
    353: #define  PetscTryMethod(obj,A,B,C) \
    354:   0;{ PetscErrorCode (*f)B, __ierr; \
    355:     __PetscObjectQueryFunction((PetscObject)obj,A,&f);CHKERRQ(__ierr); \
    356:     if (f) {__(*f)C;CHKERRQ(__ierr);}\
    357:   }

    359: /*
    360:    PetscUseMethod - Queries an object for a method, if it exists then calls it, otherwise generates an error.
    361:               These are intended to be used only inside PETSc functions.

    363:    Level: developer

    365: .seealso: PetscTryMethod()
    366: */
    367: #define  PetscUseMethod(obj,A,B,C) \
    368:   0;{ PetscErrorCode (*f)B, __ierr; \
    369:     __PetscObjectQueryFunction((PetscObject)obj,A,&f);CHKERRQ(__ierr); \
    370:     if (f) {__(*f)C;CHKERRQ(__ierr);}\
    371:     else SETERRQ1(PetscObjectComm((PetscObject)obj),PETSC_ERR_SUP,"Cannot locate function %s in object",A); \
    372:   }

    374: /*MC
    375:    PetscObjectStateIncrease - Increases the state of any PetscObject

    377:    Synopsis:
    378:    #include "petsc/private/petscimpl.h"
    379:    PetscErrorCode PetscObjectStateIncrease(PetscObject obj)

    381:    Logically Collective

    383:    Input Parameter:
    384: .  obj - any PETSc object, for example a Vec, Mat or KSP. This must be
    385:          cast with a (PetscObject), for example,
    386:          PetscObjectStateIncrease((PetscObject)mat);

    388:    Notes: object state is an integer which gets increased every time
    389:    the object is changed internally. By saving and later querying the object state
    390:    one can determine whether information about the object is still current.
    391:    Currently, state is maintained for Vec and Mat objects.

    393:    This routine is mostly for internal use by PETSc; a developer need only
    394:    call it after explicit access to an object's internals. Routines such
    395:    as VecSet() or MatScale() already call this routine. It is also called, as a
    396:    precaution, in VecRestoreArray(), MatRestoreRow(), MatDenseRestoreArray().

    398:    This routine is logically collective because state equality comparison needs to be possible without communication.

    400:    Level: developer

    402:    seealso: PetscObjectStateGet()

    404:    Concepts: state

    406: M*/
    407: #define PetscObjectStateIncrease(obj) ((obj)->state++,0)

    409: PETSC_EXTERN PetscErrorCode PetscObjectStateGet(PetscObject,PetscObjectState*);
    410: PETSC_EXTERN PetscErrorCode PetscObjectStateSet(PetscObject,PetscObjectState);
    411: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataRegister(PetscInt*);
    412: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject);
    413: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject);
    414: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject);
    415: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject);
    416: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject);
    417: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject);
    418: PETSC_EXTERN PetscInt         PetscObjectComposedDataMax;
    419: /*MC
    420:    PetscObjectComposedDataSetInt - attach integer data to a PetscObject

    422:    Synopsis:
    423:    #include "petsc/private/petscimpl.h"
    424:    PetscErrorCode PetscObjectComposedDataSetInt(PetscObject obj,int id,int data)

    426:    Not collective

    428:    Input parameters:
    429: +  obj - the object to which data is to be attached
    430: .  id - the identifier for the data
    431: -  data - the data to  be attached

    433:    Notes
    434:    The data identifier can best be created through a call to  PetscObjectComposedDataRegister()

    436:    Level: developer
    437: M*/
    438: #define PetscObjectComposedDataSetInt(obj,id,data)                                      \
    439:   ((((obj)->int_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseInt(obj)) ||  \
    440:    ((obj)->intcomposeddata[id] = data,(obj)->intcomposedstate[id] = (obj)->state, 0))

    442: /*MC
    443:    PetscObjectComposedDataGetInt - retrieve integer data attached to an object

    445:    Synopsis:
    446:    #include "petsc/private/petscimpl.h"
    447:    PetscErrorCode PetscObjectComposedDataGetInt(PetscObject obj,int id,int data,PetscBool  flag)

    449:    Not collective

    451:    Input parameters:
    452: +  obj - the object from which data is to be retrieved
    453: -  id - the identifier for the data

    455:    Output parameters
    456: +  data - the data to be retrieved
    457: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

    459:    The 'data' and 'flag' variables are inlined, so they are not pointers.

    461:    Level: developer
    462: M*/
    463: #define PetscObjectComposedDataGetInt(obj,id,data,flag)                            \
    464:   ((((obj)->intcomposedstate && ((obj)->intcomposedstate[id] == (obj)->state)) ?   \
    465:    (data = (obj)->intcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

    467: /*MC
    468:    PetscObjectComposedDataSetIntstar - attach integer array data to a PetscObject

    470:    Synopsis:
    471:    #include "petsc/private/petscimpl.h"
    472:    PetscErrorCode PetscObjectComposedDataSetIntstar(PetscObject obj,int id,int *data)

    474:    Not collective

    476:    Input parameters:
    477: +  obj - the object to which data is to be attached
    478: .  id - the identifier for the data
    479: -  data - the data to  be attached

    481:    Notes
    482:    The data identifier can best be determined through a call to
    483:    PetscObjectComposedDataRegister()

    485:    Level: developer
    486: M*/
    487: #define PetscObjectComposedDataSetIntstar(obj,id,data)                                          \
    488:   ((((obj)->intstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseIntstar(obj)) ||  \
    489:    ((obj)->intstarcomposeddata[id] = data,(obj)->intstarcomposedstate[id] = (obj)->state, 0))

    491: /*MC
    492:    PetscObjectComposedDataGetIntstar - retrieve integer array data
    493:    attached to an object

    495:    Synopsis:
    496:    #include "petsc/private/petscimpl.h"
    497:    PetscErrorCode PetscObjectComposedDataGetIntstar(PetscObject obj,int id,int *data,PetscBool  flag)

    499:    Not collective

    501:    Input parameters:
    502: +  obj - the object from which data is to be retrieved
    503: -  id - the identifier for the data

    505:    Output parameters
    506: +  data - the data to be retrieved
    507: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

    509:    The 'data' and 'flag' variables are inlined, so they are not pointers.

    511:    Level: developer
    512: M*/
    513: #define PetscObjectComposedDataGetIntstar(obj,id,data,flag)                               \
    514:   ((((obj)->intstarcomposedstate && ((obj)->intstarcomposedstate[id] == (obj)->state)) ?  \
    515:    (data = (obj)->intstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

    517: /*MC
    518:    PetscObjectComposedDataSetReal - attach real data to a PetscObject

    520:    Synopsis:
    521:    #include "petsc/private/petscimpl.h"
    522:    PetscErrorCode PetscObjectComposedDataSetReal(PetscObject obj,int id,PetscReal data)

    524:    Not collective

    526:    Input parameters:
    527: +  obj - the object to which data is to be attached
    528: .  id - the identifier for the data
    529: -  data - the data to  be attached

    531:    Notes
    532:    The data identifier can best be determined through a call to
    533:    PetscObjectComposedDataRegister()

    535:    Level: developer
    536: M*/
    537: #define PetscObjectComposedDataSetReal(obj,id,data)                                       \
    538:   ((((obj)->real_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseReal(obj)) ||  \
    539:    ((obj)->realcomposeddata[id] = data,(obj)->realcomposedstate[id] = (obj)->state, 0))

    541: /*MC
    542:    PetscObjectComposedDataGetReal - retrieve real data attached to an object

    544:    Synopsis:
    545:    #include "petsc/private/petscimpl.h"
    546:    PetscErrorCode PetscObjectComposedDataGetReal(PetscObject obj,int id,PetscReal data,PetscBool  flag)

    548:    Not collective

    550:    Input parameters:
    551: +  obj - the object from which data is to be retrieved
    552: -  id - the identifier for the data

    554:    Output parameters
    555: +  data - the data to be retrieved
    556: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

    558:    The 'data' and 'flag' variables are inlined, so they are not pointers.

    560:    Level: developer
    561: M*/
    562: #define PetscObjectComposedDataGetReal(obj,id,data,flag)                            \
    563:   ((((obj)->realcomposedstate && ((obj)->realcomposedstate[id] == (obj)->state)) ?  \
    564:    (data = (obj)->realcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

    566: /*MC
    567:    PetscObjectComposedDataSetRealstar - attach real array data to a PetscObject

    569:    Synopsis:
    570:    #include "petsc/private/petscimpl.h"
    571:    PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *data)

    573:    Not collective

    575:    Input parameters:
    576: +  obj - the object to which data is to be attached
    577: .  id - the identifier for the data
    578: -  data - the data to  be attached

    580:    Notes
    581:    The data identifier can best be determined through a call to
    582:    PetscObjectComposedDataRegister()

    584:    Level: developer
    585: M*/
    586: #define PetscObjectComposedDataSetRealstar(obj,id,data)                                           \
    587:   ((((obj)->realstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseRealstar(obj)) ||  \
    588:    ((obj)->realstarcomposeddata[id] = data, (obj)->realstarcomposedstate[id] = (obj)->state, 0))

    590: /*MC
    591:    PetscObjectComposedDataGetRealstar - retrieve real array data
    592:    attached to an object

    594:    Synopsis:
    595:    #include "petsc/private/petscimpl.h"
    596:    PetscErrorCode PetscObjectComposedDataGetRealstar(PetscObject obj,int id,PetscReal *data,PetscBool  flag)

    598:    Not collective

    600:    Input parameters:
    601: +  obj - the object from which data is to be retrieved
    602: -  id - the identifier for the data

    604:    Output parameters
    605: +  data - the data to be retrieved
    606: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

    608:    The 'data' and 'flag' variables are inlined, so they are not pointers.

    610:    Level: developer
    611: M*/
    612: #define PetscObjectComposedDataGetRealstar(obj,id,data,flag)                                \
    613:   ((((obj)->realstarcomposedstate && ((obj)->realstarcomposedstate[id] == (obj)->state)) ?  \
    614:    (data = (obj)->realstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

    616: /*MC
    617:    PetscObjectComposedDataSetScalar - attach scalar data to a PetscObject

    619:    Synopsis:
    620:    #include "petsc/private/petscimpl.h"
    621:    PetscErrorCode PetscObjectComposedDataSetScalar(PetscObject obj,int id,PetscScalar data)

    623:    Not collective

    625:    Input parameters:
    626: +  obj - the object to which data is to be attached
    627: .  id - the identifier for the data
    628: -  data - the data to  be attached

    630:    Notes
    631:    The data identifier can best be determined through a call to
    632:    PetscObjectComposedDataRegister()

    634:    Level: developer
    635: M*/
    636: #if defined(PETSC_USE_COMPLEX)
    637: #define PetscObjectComposedDataSetScalar(obj,id,data)                                        \
    638:   ((((obj)->scalar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalar(obj)) || \
    639:    ((obj)->scalarcomposeddata[id] = data,(obj)->scalarcomposedstate[id] = (obj)->state, 0))
    640: #else
    641: #define PetscObjectComposedDataSetScalar(obj,id,data) \
    642:         PetscObjectComposedDataSetReal(obj,id,data)
    643: #endif
    644: /*MC
    645:    PetscObjectComposedDataGetScalar - retrieve scalar data attached to an object

    647:    Synopsis:
    648:    #include "petsc/private/petscimpl.h"
    649:    PetscErrorCode PetscObjectComposedDataGetScalar(PetscObject obj,int id,PetscScalar data,PetscBool  flag)

    651:    Not collective

    653:    Input parameters:
    654: +  obj - the object from which data is to be retrieved
    655: -  id - the identifier for the data

    657:    Output parameters
    658: +  data - the data to be retrieved
    659: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

    661:    The 'data' and 'flag' variables are inlined, so they are not pointers.

    663:    Level: developer
    664: M*/
    665: #if defined(PETSC_USE_COMPLEX)
    666: #define PetscObjectComposedDataGetScalar(obj,id,data,flag)                              \
    667:   ((((obj)->scalarcomposedstate && ((obj)->scalarcomposedstate[id] == (obj)->state) ) ? \
    668:    (data = (obj)->scalarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
    669: #else
    670: #define PetscObjectComposedDataGetScalar(obj,id,data,flag)                             \
    671:         PetscObjectComposedDataGetReal(obj,id,data,flag)
    672: #endif

    674: /*MC
    675:    PetscObjectComposedDataSetScalarstar - attach scalar array data to a PetscObject

    677:    Synopsis:
    678:    #include "petsc/private/petscimpl.h"
    679:    PetscErrorCode PetscObjectComposedDataSetScalarstar(PetscObject obj,int id,PetscScalar *data)

    681:    Not collective

    683:    Input parameters:
    684: +  obj - the object to which data is to be attached
    685: .  id - the identifier for the data
    686: -  data - the data to  be attached

    688:    Notes
    689:    The data identifier can best be determined through a call to
    690:    PetscObjectComposedDataRegister()

    692:    Level: developer
    693: M*/
    694: #if defined(PETSC_USE_COMPLEX)
    695: #define PetscObjectComposedDataSetScalarstar(obj,id,data)                                             \
    696:   ((((obj)->scalarstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalarstar(obj)) ||  \
    697:    ((obj)->scalarstarcomposeddata[id] = data,(obj)->scalarstarcomposedstate[id] = (obj)->state, 0))
    698: #else
    699: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
    700:         PetscObjectComposedDataSetRealstar(obj,id,data)
    701: #endif
    702: /*MC
    703:    PetscObjectComposedDataGetScalarstar - retrieve scalar array data
    704:    attached to an object

    706:    Synopsis:
    707:    #include "petsc/private/petscimpl.h"
    708:    PetscErrorCode PetscObjectComposedDataGetScalarstar(PetscObject obj,int id,PetscScalar *data,PetscBool  flag)

    710:    Not collective

    712:    Input parameters:
    713: +  obj - the object from which data is to be retrieved
    714: -  id - the identifier for the data

    716:    Output parameters
    717: +  data - the data to be retrieved
    718: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

    720:    The 'data' and 'flag' variables are inlined, so they are not pointers.

    722:    Level: developer
    723: M*/
    724: #if defined(PETSC_USE_COMPLEX)
    725: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag)                                 \
    726:   ((((obj)->scalarstarcomposedstate && ((obj)->scalarstarcomposedstate[id] == (obj)->state)) ? \
    727:        (data = (obj)->scalarstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
    728: #else
    729: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag)         \
    730:         PetscObjectComposedDataGetRealstar(obj,id,data,flag)
    731: #endif

    733: PETSC_EXTERN PetscErrorCode PetscObjectGetId(PetscObject,PetscObjectId*);

    735: PETSC_EXTERN PetscErrorCode PetscMonitorCompare(PetscErrorCode (*)(void),void *,PetscErrorCode (*)(void**),PetscErrorCode (*)(void),void *,PetscErrorCode (*)(void**),PetscBool *);

    737: PETSC_EXTERN PetscMPIInt Petsc_Counter_keyval;
    738: PETSC_EXTERN PetscMPIInt Petsc_InnerComm_keyval;
    739: PETSC_EXTERN PetscMPIInt Petsc_OuterComm_keyval;

    741: /*
    742:   PETSc communicators have this attribute, see
    743:   PetscCommDuplicate(), PetscCommDestroy(), PetscCommGetNewTag(), PetscObjectGetName()
    744: */
    745: typedef struct {
    746:   PetscMPIInt tag;              /* next free tag value */
    747:   PetscInt    refcount;         /* number of references, communicator can be freed when this reaches 0 */
    748:   PetscInt    namecount;        /* used to generate the next name, as in Vec_0, Mat_1, ... */
    749: } PetscCommCounter;

    751: #if defined(PETSC_HAVE_CUSP)
    752: /*E
    753:     PetscCUSPFlag - indicates which memory (CPU, GPU, or none contains valid vector

    755:    PETSC_CUSP_UNALLOCATED  - no memory contains valid matrix entries; NEVER used for vectors
    756:    PETSC_CUSP_GPU - GPU has valid vector/matrix entries
    757:    PETSC_CUSP_CPU - CPU has valid vector/matrix entries
    758:    PETSC_CUSP_BOTH - Both GPU and CPU have valid vector/matrix entries and they match

    760:    Level: developer
    761: E*/
    762: typedef enum {PETSC_CUSP_UNALLOCATED,PETSC_CUSP_GPU,PETSC_CUSP_CPU,PETSC_CUSP_BOTH} PetscCUSPFlag;
    763: #elif defined(PETSC_HAVE_VIENNACL)
    764: /*E
    765:     PetscViennaCLFlag - indicates which memory (CPU, GPU, or none contains valid vector

    767:    PETSC_VIENNACL_UNALLOCATED  - no memory contains valid matrix entries; NEVER used for vectors
    768:    PETSC_VIENNACL_GPU - GPU has valid vector/matrix entries
    769:    PETSC_VIENNACL_CPU - CPU has valid vector/matrix entries
    770:    PETSC_VIENNACL_BOTH - Both GPU and CPU have valid vector/matrix entries and they match

    772:    Level: developer
    773: E*/
    774: typedef enum {PETSC_VIENNACL_UNALLOCATED,PETSC_VIENNACL_GPU,PETSC_VIENNACL_CPU,PETSC_VIENNACL_BOTH} PetscViennaCLFlag;
    775: #elif defined(PETSC_HAVE_VECCUDA)
    776: /*E
    777:     PetscCUDAFlag - indicates which memory (CPU, GPU, or none contains valid vector

    779:    PETSC_CUDA_UNALLOCATED  - no memory contains valid matrix entries; NEVER used for vectors
    780:    PETSC_CUDA_GPU - GPU has valid vector/matrix entries
    781:    PETSC_CUDA_CPU - CPU has valid vector/matrix entries
    782:    PETSC_CUDA_BOTH - Both GPU and CPU have valid vector/matrix entries and they match

    784:    Level: developer
    785: E*/
    786: typedef enum {PETSC_CUDA_UNALLOCATED,PETSC_CUDA_GPU,PETSC_CUDA_CPU,PETSC_CUDA_BOTH} PetscCUDAFlag;
    787: #endif

    789: #if defined(PETSC_HAVE_CUSP) || defined(PETSC_HAVE_VECCUDA)
    790: PETSC_EXTERN cublasHandle_t cublasv2handle;
    791: #endif

    793: typedef enum {STATE_BEGIN, STATE_PENDING, STATE_END} SRState;

    795: #define REDUCE_SUM  0
    796: #define REDUCE_MAX  1
    797: #define REDUCE_MIN  2

    799: typedef struct {
    800:   MPI_Comm    comm;
    801:   MPI_Request request;
    802:   PetscBool   async;
    803:   PetscScalar *lvalues;     /* this are the reduced values before call to MPI_Allreduce() */
    804:   PetscScalar *gvalues;     /* values after call to MPI_Allreduce() */
    805:   void        **invecs;     /* for debugging only, vector/memory used with each op */
    806:   PetscInt    *reducetype;  /* is particular value to be summed or maxed? */
    807:   SRState     state;        /* are we calling xxxBegin() or xxxEnd()? */
    808:   PetscInt    maxops;       /* total amount of space we have for requests */
    809:   PetscInt    numopsbegin;  /* number of requests that have been queued in */
    810:   PetscInt    numopsend;    /* number of requests that have been gotten by user */
    811: } PetscSplitReduction;

    813: PETSC_EXTERN PetscErrorCode PetscSplitReductionGet(MPI_Comm,PetscSplitReduction**);
    814: PETSC_EXTERN PetscErrorCode PetscSplitReductionEnd(PetscSplitReduction*);
    815: PETSC_EXTERN PetscErrorCode PetscSplitReductionExtend(PetscSplitReduction*);

    817: #if !defined(PETSC_SKIP_SPINLOCK)
    818: #if defined(PETSC_HAVE_THREADSAFETY)
    819: #  if defined(PETSC_HAVE_CONCURRENCYKIT)
    820: #if defined(__cplusplus)
    821: /*  CK does not have extern "C" protection in their include files */
    822: extern "C" {
    823: #endif
    824: #include <ck_spinlock.h>
    825: #if defined(__cplusplus)
    826: }
    827: #endif
    828: typedef ck_spinlock_t PetscSpinlock;
    829: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockCreate(PetscSpinlock *ck_spinlock)
    830: {
    831:   ck_spinlock_init(ck_spinlock);
    832:   return 0;
    833: }
    834: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockLock(PetscSpinlock *ck_spinlock)
    835: {
    836:   ck_spinlock_lock(ck_spinlock);
    837:   return 0;
    838: }
    839: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *ck_spinlock)
    840: {
    841:   ck_spinlock_unlock(ck_spinlock);
    842:   return 0;
    843: }
    844: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *ck_spinlock)
    845: {
    846:   return 0;
    847: }
    848: #  elif defined(PETSC_HAVE_OPENMP)

    850: #include <omp.h>
    851: typedef omp_lock_t PetscSpinlock;
    852: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockCreate(PetscSpinlock *omp_lock)
    853: {
    854:   omp_init_lock(omp_lock);
    855:   return 0;
    856: }
    857: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockLock(PetscSpinlock *omp_lock)
    858: {
    859:   omp_set_lock(omp_lock);
    860:   return 0;
    861: }
    862: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *omp_lock)
    863: {
    864:   omp_unset_lock(omp_lock);
    865:   return 0;
    866: }
    867: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *omp_lock)
    868: {
    869:   omp_destroy_lock(omp_lock);
    870:   return 0;
    871: }
    872: #else
    873: Thread safety requires either --with-openmp or --download-concurrencykit
    874: #endif

    876: #else
    877: typedef int PetscSpinlock;
    878: #define PetscSpinlockCreate(a)  0
    879: #define PetscSpinlockLock(a)    0
    880: #define PetscSpinlockUnlock(a)  0
    881: #define PetscSpinlockDestroy(a) 0
    882: #endif

    884: #if defined(PETSC_HAVE_THREADSAFETY)
    885: extern PetscSpinlock PetscViewerASCIISpinLockOpen;
    886: extern PetscSpinlock PetscViewerASCIISpinLockStdout;
    887: extern PetscSpinlock PetscViewerASCIISpinLockStderr;
    888: extern PetscSpinlock PetscCommSpinLock;
    889: #endif
    890: #endif

    892: #endif /* _PETSCHEAD_H */