Actual source code: petscimpl.h
petsc-3.12.4 2020-02-04
Report Typos and Errors

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

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

     10: /* These are used internally by PETSc ASCII IO routines*/
     11: #include <stdarg.h>
     12: PETSC_EXTERN PetscErrorCode PetscVFPrintfDefault(FILE*,const char[],va_list);

     14: #if defined(PETSC_HAVE_CLOSURE)
     15: PETSC_EXTERN PetscErrorCode PetscVFPrintfSetClosure(int (^)(const char*));
     16: #endif

     19: #if defined(PETSC_HAVE_CUDA)
     20: #include <cuda.h>
     21: #include <cublas_v2.h>
     22: #endif

     24: /*
     25:    All major PETSc data structures have a common core; this is defined
     26:    below by PETSCHEADER.

     28:    PetscHeaderCreate() should be used whenever creating a PETSc structure.
     29: */

     31: /*
     32:    PetscOps: structure of core operations that all PETSc objects support.

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

     51: typedef struct {
     52:    PetscErrorCode (*getcomm)(PetscObject,MPI_Comm *);
     53:    PetscErrorCode (*view)(PetscObject,PetscViewer);
     54:    PetscErrorCode (*destroy)(PetscObject*);
     55:    PetscErrorCode (*compose)(PetscObject,const char[],PetscObject);
     56:    PetscErrorCode (*query)(PetscObject,const char[],PetscObject *);
     57:    PetscErrorCode (*composefunction)(PetscObject,const char[],void (*)(void));
     58:    PetscErrorCode (*queryfunction)(PetscObject,const char[],void (**)(void));
     59: } PetscOps;

     61: typedef enum {PETSC_FORTRAN_CALLBACK_CLASS,PETSC_FORTRAN_CALLBACK_SUBTYPE,PETSC_FORTRAN_CALLBACK_MAXTYPE} PetscFortranCallbackType;
     62: typedef int PetscFortranCallbackId;
     63: #define PETSC_SMALLEST_FORTRAN_CALLBACK ((PetscFortranCallbackId)1000)
     64: PETSC_EXTERN PetscErrorCode PetscFortranCallbackRegister(PetscClassId,const char*,PetscFortranCallbackId*);
     65: PETSC_EXTERN PetscErrorCode PetscFortranCallbackGetSizes(PetscClassId,PetscInt*,PetscInt*);

     67: typedef struct {
     68:   void (*func)(void);
     69:   void *ctx;
     70: } PetscFortranCallback;

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

    117:   PetscInt             noptionhandler;
    118:   PetscErrorCode       (*optionhandler[PETSC_MAX_OPTIONS_HANDLER])(PetscOptionItems*,PetscObject,void*);
    119:   PetscErrorCode       (*optiondestroy[PETSC_MAX_OPTIONS_HANDLER])(PetscObject,void*);
    120:   void                 *optionctx[PETSC_MAX_OPTIONS_HANDLER];
    121:   PetscBool            optionsprinted;
    122: #if defined(PETSC_HAVE_SAWS)
    123:   PetscBool            amsmem;          /* if PETSC_TRUE then this object is registered with SAWs and visible to clients */
    124:   PetscBool            amspublishblock; /* if PETSC_TRUE and publishing objects then will block at PetscObjectSAWsBlock() */
    125: #endif
    126:   PetscOptions         options;         /* options database used, NULL means default */
    127:   PetscBool            donotPetscObjectPrintClassNamePrefixType;
    128: } _p_PetscObject;

    130: #define PETSCHEADER(ObjectOps) \
    131:   _p_PetscObject hdr;          \
    132:   ObjectOps      ops[1]

    134: #define  PETSCFREEDHEADER -1

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

    139: /*@C
    140:     PetscHeaderCreate - Creates a PETSc object of a particular class

    142:     Input Parameters:
    143: +   classid - the classid associated with this object (for example VEC_CLASSID)
    144: .   class_name - string name of class; should be static (for example "Vec")
    145: .   descr - string containing short description; should be static (for example "Vector")
    146: .   mansec - string indicating section in manual pages; should be static (for example "Vec")
    147: .   comm - the MPI Communicator
    148: .   destroy - the destroy routine for this object (for example VecDestroy())
    149: -   view - the view routine for this object (for example VecView())

    151:     Output Parameter:
    152: .   h - the newly created object

    154:     Level: developer

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

    158: @*/
    159: #define PetscHeaderCreate(h,classid,class_name,descr,mansec,comm,destroy,view) \
    160:   (PetscNew(&(h)) || \
    161:    PetscHeaderCreate_Private((PetscObject)h,classid,class_name,descr,mansec,comm,(PetscObjectDestroyFunction)destroy,(PetscObjectViewFunction)view) || \
    162:    PetscLogObjectCreate(h) || \
    163:    PetscLogObjectMemory((PetscObject)h,sizeof(*(h))))

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

    168: /*@C
    169:     PetscHeaderDestroy - Final step in destroying a PetscObject

    171:     Input Parameters:
    172: .   h - the header created with PetscHeaderCreate()

    174:     Level: developer

    176: .seealso: PetscHeaderCreate()
    177: @*/
    178: #define PetscHeaderDestroy(h) (PetscHeaderDestroy_Private((PetscObject)(*h)) || PetscFree(*h))

    180: PETSC_EXTERN PetscErrorCode PetscHeaderDestroy_Private(PetscObject);
    181: PETSC_EXTERN PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject,PetscObject);
    182: PETSC_EXTERN PetscErrorCode PetscObjectSetFortranCallback(PetscObject,PetscFortranCallbackType,PetscFortranCallbackId*,void(*)(void),void *ctx);
    183: PETSC_EXTERN PetscErrorCode PetscObjectGetFortranCallback(PetscObject,PetscFortranCallbackType,PetscFortranCallbackId,void(**)(void),void **ctx);

    185: PETSC_INTERN PetscErrorCode PetscCitationsInitialize(void);
    186: PETSC_INTERN PetscErrorCode PetscFreeMPIResources(void);

    192: /*
    193:     Macros to test if a PETSc object is valid and if pointers are valid
    194: */
    195: #if !defined(PETSC_USE_DEBUG)

    208: #else

    210: /*  This check is for subtype methods such as DMDAGetCorners() that do not use the PetscTryMethod() or PetscUseMethod() paradigm */
    212:   do {   \
    213:     PetscErrorCode _7_ierr; \
    214:     PetscBool      _7_same; \
    216:     _7_PetscObjectTypeCompare((PetscObject)h,t,&_7_same);CHKERRQ(_7_ierr);      \
    217:     if (!_7_same) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Wrong subtype object:Parameter # %d must have implementation %s it is %s",arg,t,((PetscObject)h)->type_name); \
    218:   } while (0)

    221:   do {                                                                  \
    222:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg); \
    224:     if (((PetscObject)(h))->classid != ck) {                            \
    225:       if (((PetscObject)(h))->classid == PETSCFREEDHEADER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
    226:       else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Wrong type of object: Parameter # %d",arg); \
    227:     }                                                                   \
    228:   } while (0)

    231:   do {                                                                  \
    232:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg); \
    234:     if (((PetscObject)(h))->classid == PETSCFREEDHEADER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
    235:     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); \
    236:   } while (0)

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

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

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

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

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

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

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

    279: #endif

    281: #if !defined(PETSC_USE_DEBUG)

    296: #else

    298: /*
    299:     For example, in the dot product between two vectors,
    300:   both vectors must be either Seq or MPI, not one of each
    301: */
    303:   do {                                                                  \
    304:     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); \
    305:   } while (0)
    306: /*
    307:     Check type_name
    308: */
    310:   do {                                                                  \
    311:     PetscBool      _7_match;                                             \
    312:     PetscErrorCode _7_ierr;                                             \
    313:     _7_PetscObjectTypeCompare(((PetscObject)a),(type),&_7_match);CHKERRQ(_7_ierr); \
    314:     if (!_7_match) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Object (%s) is not %s",(char*)(((PetscObject)a)->type_name),type); \
    315:   } while (0)

    318:   do {                                                                  \
    319:     PetscBool      _7_match;                                            \
    320:     PetscErrorCode _7_ierr;                                             \
    321:     _7_PetscObjectTypeCompareAny(((PetscObject)a),&_7_match,(type1),(type2),"");CHKERRQ(_7_ierr); \
    322:     if (!_7_match) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Object (%s) is not %s or %s",(char*)(((PetscObject)a)->type_name),type1,type2); \
    323:   } while (0)
    324: /*
    325:    Use this macro to check if the type is set
    326: */
    328:   do {                                                                  \
    329:     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); \
    330:   } while (0)
    331: /*
    332:    Sometimes object must live on same communicator to inter-operate
    333: */
    335:   do {                                                                  \
    336:     PetscErrorCode _7_ierr;                                             \
    337:     PetscMPIInt    _7_flag;                                             \
    338:     _7_MPI_Comm_compare(PetscObjectComm((PetscObject)a),PetscObjectComm((PetscObject)b),&_7_flag);CHKERRQ(_7_ierr);                                                   \
    339:     if (_7_flag != MPI_CONGRUENT && _7_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,_7_flag); \
    340:   } while (0)

    343:   do {                                                  \
    346:   } while (0)

    349:   do {                                                                  \
    350:     PetscErrorCode _7_ierr;                                             \
    351:     PetscReal b1[5],b2[5];                                              \
    352:     if (PetscIsNanScalar(b)) {b1[4] = 1;} else {b1[4] = 0;};            \
    353:     b1[0] = -PetscRealPart(b); b1[1] = PetscRealPart(b); b1[2] = -PetscImaginaryPart(b); b1[3] = PetscImaginaryPart(b); \
    354:     _7_MPI_Allreduce(b1,b2,5,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
    355:     if (!(b2[4] > 0) && !(PetscEqualReal(-b2[0],b2[1]) && PetscEqualReal(-b2[2],b2[3]))) SETERRQ1(PetscObjectComm((PetscObject)a),PETSC_ERR_ARG_WRONG,"Scalar value must be same on all processes, argument # %d",c); \
    356:   } while (0)

    359:   do {                                                                  \
    360:     PetscErrorCode _7_ierr;                                             \
    361:     PetscReal b1[3],b2[3];                                              \
    362:     if (PetscIsNanReal(b)) {b1[2] = 1;} else {b1[2] = 0;};              \
    363:     b1[0] = -b; b1[1] = b;                                              \
    364:     _7_MPI_Allreduce(b1,b2,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
    365:     if (!(b2[2] > 0) && !PetscEqualReal(-b2[0],b2[1])) SETERRQ1(PetscObjectComm((PetscObject)a),PETSC_ERR_ARG_WRONG,"Real value must be same on all processes, argument # %d",c); \
    366:   } while (0)

    369:   do {                                                                  \
    370:     PetscErrorCode _7_ierr;                                             \
    371:     PetscInt b1[2],b2[2];                                               \
    372:     b1[0] = -b; b1[1] = b;                                              \
    373:     _7_MPIU_Allreduce(b1,b2,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
    374:     if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)a),PETSC_ERR_ARG_WRONG,"Int value must be same on all processes, argument # %d",c); \
    375:   } while (0)

    380:   do {                                                                  \
    381:     PetscErrorCode _7_ierr;                                             \
    382:     PetscMPIInt b1[2],b2[2];                                            \
    383:     b1[0] = -(PetscMPIInt)b; b1[1] = (PetscMPIInt)b;                    \
    384:     _7_MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
    385:     if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)a),PETSC_ERR_ARG_WRONG,"Bool value must be same on all processes, argument # %d",c); \
    386:   } while (0)

    389:   do {                                                                  \
    390:     PetscErrorCode _7_ierr;                                             \
    391:     PetscMPIInt b1[2],b2[2];                                            \
    392:     b1[0] = -(PetscMPIInt)b; b1[1] = (PetscMPIInt)b;                    \
    393:     _7_MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
    394:     if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)a),PETSC_ERR_ARG_WRONG,"Enum value must be same on all processes, argument # %d",c); \
    395:   } while (0)

    397: #endif

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

    403:    Level: developer

    405: .seealso: PetscUseMethod()
    406: */
    407: #define  PetscTryMethod(obj,A,B,C) \
    408:   0; do { PetscErrorCode (*_7_f)B, _7_ierr; \
    409:     _7_PetscObjectQueryFunction((PetscObject)(obj),A,&_7_f);CHKERRQ(_7_ierr); \
    410:     if (_7_f) {_7_(*_7_f)C;CHKERRQ(_7_ierr);} \
    411:   } while(0)

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

    417:    Level: developer

    419: .seealso: PetscTryMethod()
    420: */
    421: #define  PetscUseMethod(obj,A,B,C) \
    422:   0; do { PetscErrorCode (*_7_f)B, _7_ierr; \
    423:     _7_PetscObjectQueryFunction((PetscObject)(obj),A,&_7_f);CHKERRQ(_7_ierr); \
    424:     if (_7_f) {_7_(*_7_f)C;CHKERRQ(_7_ierr);} \
    425:     else SETERRQ1(PetscObjectComm((PetscObject)(obj)),PETSC_ERR_SUP,"Cannot locate function %s in object",A); \
    426:   } while(0)

    428: /*MC
    429:    PetscObjectStateIncrease - Increases the state of any PetscObject

    431:    Synopsis:
    432:    #include "petsc/private/petscimpl.h"
    433:    PetscErrorCode PetscObjectStateIncrease(PetscObject obj)

    435:    Logically Collective

    437:    Input Parameter:
    438: .  obj - any PETSc object, for example a Vec, Mat or KSP. This must be
    439:          cast with a (PetscObject), for example,
    440:          PetscObjectStateIncrease((PetscObject)mat);

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

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

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

    455:    Level: developer

    457:    seealso: PetscObjectStateGet()

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

    462: PETSC_EXTERN PetscErrorCode PetscObjectStateGet(PetscObject,PetscObjectState*);
    463: PETSC_EXTERN PetscErrorCode PetscObjectStateSet(PetscObject,PetscObjectState);
    464: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataRegister(PetscInt*);
    465: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject);
    466: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject);
    467: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject);
    468: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject);
    469: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject);
    470: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject);
    471: PETSC_EXTERN PetscInt       PetscObjectComposedDataMax;
    472: /*MC
    473:    PetscObjectComposedDataSetInt - attach integer data to a PetscObject

    475:    Synopsis:
    476:    #include "petsc/private/petscimpl.h"
    477:    PetscErrorCode PetscObjectComposedDataSetInt(PetscObject obj,int id,int data)

    479:    Not collective

    481:    Input parameters:
    482: +  obj - the object to which data is to be attached
    483: .  id - the identifier for the data
    484: -  data - the data to  be attached

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

    489:    Level: developer
    490: M*/
    491: #define PetscObjectComposedDataSetInt(obj,id,data)                                      \
    492:   ((((obj)->int_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseInt(obj)) ||  \
    493:    ((obj)->intcomposeddata[id] = data,(obj)->intcomposedstate[id] = (obj)->state, 0))

    495: /*MC
    496:    PetscObjectComposedDataGetInt - retrieve integer data attached to an object

    498:    Synopsis:
    499:    #include "petsc/private/petscimpl.h"
    500:    PetscErrorCode PetscObjectComposedDataGetInt(PetscObject obj,int id,int data,PetscBool  flag)

    502:    Not collective

    504:    Input parameters:
    505: +  obj - the object from which data is to be retrieved
    506: -  id - the identifier for the data

    508:    Output parameters
    509: +  data - the data to be retrieved
    510: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

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

    514:    Level: developer
    515: M*/
    516: #define PetscObjectComposedDataGetInt(obj,id,data,flag)                            \
    517:   ((((obj)->intcomposedstate && ((obj)->intcomposedstate[id] == (obj)->state)) ?   \
    518:    (data = (obj)->intcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

    520: /*MC
    521:    PetscObjectComposedDataSetIntstar - attach integer array data to a PetscObject

    523:    Synopsis:
    524:    #include "petsc/private/petscimpl.h"
    525:    PetscErrorCode PetscObjectComposedDataSetIntstar(PetscObject obj,int id,int *data)

    527:    Not collective

    529:    Input parameters:
    530: +  obj - the object to which data is to be attached
    531: .  id - the identifier for the data
    532: -  data - the data to  be attached

    534:    Notes
    535:    The data identifier can best be determined through a call to
    536:    PetscObjectComposedDataRegister()

    538:    Level: developer
    539: M*/
    540: #define PetscObjectComposedDataSetIntstar(obj,id,data)                                          \
    541:   ((((obj)->intstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseIntstar(obj)) ||  \
    542:    ((obj)->intstarcomposeddata[id] = data,(obj)->intstarcomposedstate[id] = (obj)->state, 0))

    544: /*MC
    545:    PetscObjectComposedDataGetIntstar - retrieve integer array data
    546:    attached to an object

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

    552:    Not collective

    554:    Input parameters:
    555: +  obj - the object from which data is to be retrieved
    556: -  id - the identifier for the data

    558:    Output parameters
    559: +  data - the data to be retrieved
    560: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

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

    564:    Level: developer
    565: M*/
    566: #define PetscObjectComposedDataGetIntstar(obj,id,data,flag)                               \
    567:   ((((obj)->intstarcomposedstate && ((obj)->intstarcomposedstate[id] == (obj)->state)) ?  \
    568:    (data = (obj)->intstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

    570: /*MC
    571:    PetscObjectComposedDataSetReal - attach real data to a PetscObject

    573:    Synopsis:
    574:    #include "petsc/private/petscimpl.h"
    575:    PetscErrorCode PetscObjectComposedDataSetReal(PetscObject obj,int id,PetscReal data)

    577:    Not collective

    579:    Input parameters:
    580: +  obj - the object to which data is to be attached
    581: .  id - the identifier for the data
    582: -  data - the data to  be attached

    584:    Notes
    585:    The data identifier can best be determined through a call to
    586:    PetscObjectComposedDataRegister()

    588:    Level: developer
    589: M*/
    590: #define PetscObjectComposedDataSetReal(obj,id,data)                                       \
    591:   ((((obj)->real_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseReal(obj)) ||  \
    592:    ((obj)->realcomposeddata[id] = data,(obj)->realcomposedstate[id] = (obj)->state, 0))

    594: /*MC
    595:    PetscObjectComposedDataGetReal - retrieve real data attached to an object

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

    601:    Not collective

    603:    Input parameters:
    604: +  obj - the object from which data is to be retrieved
    605: -  id - the identifier for the data

    607:    Output parameters
    608: +  data - the data to be retrieved
    609: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

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

    613:    Level: developer
    614: M*/
    615: #define PetscObjectComposedDataGetReal(obj,id,data,flag)                            \
    616:   ((((obj)->realcomposedstate && ((obj)->realcomposedstate[id] == (obj)->state)) ?  \
    617:    (data = (obj)->realcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

    619: /*MC
    620:    PetscObjectComposedDataSetRealstar - attach real array data to a PetscObject

    622:    Synopsis:
    623:    #include "petsc/private/petscimpl.h"
    624:    PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *data)

    626:    Not collective

    628:    Input parameters:
    629: +  obj - the object to which data is to be attached
    630: .  id - the identifier for the data
    631: -  data - the data to  be attached

    633:    Notes
    634:    The data identifier can best be determined through a call to
    635:    PetscObjectComposedDataRegister()

    637:    Level: developer
    638: M*/
    639: #define PetscObjectComposedDataSetRealstar(obj,id,data)                                           \
    640:   ((((obj)->realstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseRealstar(obj)) ||  \
    641:    ((obj)->realstarcomposeddata[id] = data, (obj)->realstarcomposedstate[id] = (obj)->state, 0))

    643: /*MC
    644:    PetscObjectComposedDataGetRealstar - retrieve real array data
    645:    attached to an object

    647:    Synopsis:
    648:    #include "petsc/private/petscimpl.h"
    649:    PetscErrorCode PetscObjectComposedDataGetRealstar(PetscObject obj,int id,PetscReal *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: #define PetscObjectComposedDataGetRealstar(obj,id,data,flag)                                \
    666:   ((((obj)->realstarcomposedstate && ((obj)->realstarcomposedstate[id] == (obj)->state)) ?  \
    667:    (data = (obj)->realstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

    669: /*MC
    670:    PetscObjectComposedDataSetScalar - attach scalar data to a PetscObject

    672:    Synopsis:
    673:    #include "petsc/private/petscimpl.h"
    674:    PetscErrorCode PetscObjectComposedDataSetScalar(PetscObject obj,int id,PetscScalar data)

    676:    Not collective

    678:    Input parameters:
    679: +  obj - the object to which data is to be attached
    680: .  id - the identifier for the data
    681: -  data - the data to  be attached

    683:    Notes
    684:    The data identifier can best be determined through a call to
    685:    PetscObjectComposedDataRegister()

    687:    Level: developer
    688: M*/
    689: #if defined(PETSC_USE_COMPLEX)
    690: #define PetscObjectComposedDataSetScalar(obj,id,data)                                        \
    691:   ((((obj)->scalar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalar(obj)) || \
    692:    ((obj)->scalarcomposeddata[id] = data,(obj)->scalarcomposedstate[id] = (obj)->state, 0))
    693: #else
    694: #define PetscObjectComposedDataSetScalar(obj,id,data) \
    695:         PetscObjectComposedDataSetReal(obj,id,data)
    696: #endif
    697: /*MC
    698:    PetscObjectComposedDataGetScalar - retrieve scalar data attached to an object

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

    704:    Not collective

    706:    Input parameters:
    707: +  obj - the object from which data is to be retrieved
    708: -  id - the identifier for the data

    710:    Output parameters
    711: +  data - the data to be retrieved
    712: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

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

    716:    Level: developer
    717: M*/
    718: #if defined(PETSC_USE_COMPLEX)
    719: #define PetscObjectComposedDataGetScalar(obj,id,data,flag)                              \
    720:   ((((obj)->scalarcomposedstate && ((obj)->scalarcomposedstate[id] == (obj)->state) ) ? \
    721:    (data = (obj)->scalarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
    722: #else
    723: #define PetscObjectComposedDataGetScalar(obj,id,data,flag)                             \
    724:         PetscObjectComposedDataGetReal(obj,id,data,flag)
    725: #endif

    727: /*MC
    728:    PetscObjectComposedDataSetScalarstar - attach scalar array data to a PetscObject

    730:    Synopsis:
    731:    #include "petsc/private/petscimpl.h"
    732:    PetscErrorCode PetscObjectComposedDataSetScalarstar(PetscObject obj,int id,PetscScalar *data)

    734:    Not collective

    736:    Input parameters:
    737: +  obj - the object to which data is to be attached
    738: .  id - the identifier for the data
    739: -  data - the data to  be attached

    741:    Notes
    742:    The data identifier can best be determined through a call to
    743:    PetscObjectComposedDataRegister()

    745:    Level: developer
    746: M*/
    747: #if defined(PETSC_USE_COMPLEX)
    748: #define PetscObjectComposedDataSetScalarstar(obj,id,data)                                             \
    749:   ((((obj)->scalarstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalarstar(obj)) ||  \
    750:    ((obj)->scalarstarcomposeddata[id] = data,(obj)->scalarstarcomposedstate[id] = (obj)->state, 0))
    751: #else
    752: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
    753:         PetscObjectComposedDataSetRealstar(obj,id,data)
    754: #endif
    755: /*MC
    756:    PetscObjectComposedDataGetScalarstar - retrieve scalar array data
    757:    attached to an object

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

    763:    Not collective

    765:    Input parameters:
    766: +  obj - the object from which data is to be retrieved
    767: -  id - the identifier for the data

    769:    Output parameters
    770: +  data - the data to be retrieved
    771: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

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

    775:    Level: developer
    776: M*/
    777: #if defined(PETSC_USE_COMPLEX)
    778: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag)                                 \
    779:   ((((obj)->scalarstarcomposedstate && ((obj)->scalarstarcomposedstate[id] == (obj)->state)) ? \
    780:        (data = (obj)->scalarstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
    781: #else
    782: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag)         \
    783:         PetscObjectComposedDataGetRealstar(obj,id,data,flag)
    784: #endif

    786: PETSC_EXTERN PetscErrorCode PetscObjectGetId(PetscObject,PetscObjectId*);
    787: PETSC_EXTERN PetscErrorCode PetscObjectCompareId(PetscObject,PetscObjectId,PetscBool*);

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

    791: PETSC_EXTERN PetscMPIInt Petsc_Counter_keyval;
    792: PETSC_EXTERN PetscMPIInt Petsc_InnerComm_keyval;
    793: PETSC_EXTERN PetscMPIInt Petsc_OuterComm_keyval;
    794: PETSC_EXTERN PetscMPIInt Petsc_Seq_keyval;
    795: PETSC_EXTERN PetscMPIInt Petsc_ShmComm_keyval;

    797: /*
    798:   PETSc communicators have this attribute, see
    799:   PetscCommDuplicate(), PetscCommDestroy(), PetscCommGetNewTag(), PetscObjectGetName()
    800: */
    801: typedef struct {
    802:   PetscMPIInt tag;              /* next free tag value */
    803:   PetscInt    refcount;         /* number of references, communicator can be freed when this reaches 0 */
    804:   PetscInt    namecount;        /* used to generate the next name, as in Vec_0, Mat_1, ... */
    805: } PetscCommCounter;

    807: /*E
    808:     PetscOffloadMask - indicates which memory (CPU, GPU, or none) contains valid data

    810:    PETSC_OFFLOAD_UNALLOCATED  - no memory contains valid matrix entries; NEVER used for vectors
    811:    PETSC_OFFLOAD_GPU - GPU has valid vector/matrix entries
    812:    PETSC_OFFLOAD_CPU - CPU has valid vector/matrix entries
    813:    PETSC_OFFLOAD_BOTH - Both GPU and CPU have valid vector/matrix entries and they match

    815:    Level: developer
    816: E*/
    817: typedef enum {PETSC_OFFLOAD_UNALLOCATED=0x0,PETSC_OFFLOAD_CPU=0x1,PETSC_OFFLOAD_GPU=0x2,PETSC_OFFLOAD_BOTH=0x3} PetscOffloadMask;

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

    821: typedef enum {PETSC_SR_REDUCE_SUM=0,PETSC_SR_REDUCE_MAX=1,PETSC_SR_REDUCE_MIN=2} PetscSRReductionType;

    823: typedef struct {
    824:   MPI_Comm    comm;
    825:   MPI_Request request;
    826:   PetscBool   async;
    827:   PetscScalar *lvalues;     /* this are the reduced values before call to MPI_Allreduce() */
    828:   PetscScalar *gvalues;     /* values after call to MPI_Allreduce() */
    829:   void        **invecs;     /* for debugging only, vector/memory used with each op */
    830:   PetscInt    *reducetype;  /* is particular value to be summed or maxed? */
    831:   SRState     state;        /* are we calling xxxBegin() or xxxEnd()? */
    832:   PetscInt    maxops;       /* total amount of space we have for requests */
    833:   PetscInt    numopsbegin;  /* number of requests that have been queued in */
    834:   PetscInt    numopsend;    /* number of requests that have been gotten by user */
    835: } PetscSplitReduction;

    837: PETSC_EXTERN PetscErrorCode PetscSplitReductionGet(MPI_Comm,PetscSplitReduction**);
    838: PETSC_EXTERN PetscErrorCode PetscSplitReductionEnd(PetscSplitReduction*);
    839: PETSC_EXTERN PetscErrorCode PetscSplitReductionExtend(PetscSplitReduction*);

    841: #if !defined(PETSC_SKIP_SPINLOCK)
    842: #if defined(PETSC_HAVE_THREADSAFETY)
    843: #  if defined(PETSC_HAVE_CONCURRENCYKIT)
    844: #if defined(__cplusplus)
    845: /*  CK does not have extern "C" protection in their include files */
    846: extern "C" {
    847: #endif
    848: #include <ck_spinlock.h>
    849: #if defined(__cplusplus)
    850: }
    851: #endif
    852: typedef ck_spinlock_t PetscSpinlock;
    853: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockCreate(PetscSpinlock *ck_spinlock)
    854: {
    855:   ck_spinlock_init(ck_spinlock);
    856:   return 0;
    857: }
    858: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockLock(PetscSpinlock *ck_spinlock)
    859: {
    860:   ck_spinlock_lock(ck_spinlock);
    861:   return 0;
    862: }
    863: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *ck_spinlock)
    864: {
    865:   ck_spinlock_unlock(ck_spinlock);
    866:   return 0;
    867: }
    868: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *ck_spinlock)
    869: {
    870:   return 0;
    871: }
    872: #  elif defined(PETSC_HAVE_OPENMP)

    874: #include <omp.h>
    875: typedef omp_lock_t PetscSpinlock;
    876: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockCreate(PetscSpinlock *omp_lock)
    877: {
    878:   omp_init_lock(omp_lock);
    879:   return 0;
    880: }
    881: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockLock(PetscSpinlock *omp_lock)
    882: {
    883:   omp_set_lock(omp_lock);
    884:   return 0;
    885: }
    886: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *omp_lock)
    887: {
    888:   omp_unset_lock(omp_lock);
    889:   return 0;
    890: }
    891: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *omp_lock)
    892: {
    893:   omp_destroy_lock(omp_lock);
    894:   return 0;
    895: }
    896: #else
    897: Thread safety requires either --with-openmp or --download-concurrencykit
    898: #endif

    900: #else
    901: typedef int PetscSpinlock;
    902: #define PetscSpinlockCreate(a)  0
    903: #define PetscSpinlockLock(a)    0
    904: #define PetscSpinlockUnlock(a)  0
    905: #define PetscSpinlockDestroy(a) 0
    906: #endif

    908: #if defined(PETSC_HAVE_THREADSAFETY)
    909: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockOpen;
    910: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStdout;
    911: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStderr;
    912: PETSC_INTERN PetscSpinlock PetscCommSpinLock;
    913: #endif
    914: #endif

    916: PETSC_EXTERN PetscLogEvent PETSC_Barrier;
    917: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSided;
    918: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSidedF;

    920: #if defined(PETSC_HAVE_ADIOS)
    921: PETSC_EXTERN int64_t Petsc_adios_group;
    922: #endif

    924: PETSC_EXTERN PetscBool use_gpu_aware_mpi;
    925: #if defined(PETSC_HAVE_CUDA)
    926: PETSC_EXTERN PetscBool sf_use_default_cuda_stream;
    927: #endif

    929: #endif /* PETSCIMPL_H */