Date: 2022-08-02T03:15:20+00:00

Actual source code: petscimpl.h

      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: #if defined(PETSC_CLANG_STATIC_ANALYZER)
     11: #define PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(expr)
     12: #else
     13: #define PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(expr) \
     14:   expr
     15: #endif

     17: #if PetscDefined(USE_DEBUG)
     18: PETSC_INTERN PetscErrorCode PetscStackSetCheck(PetscBool);
     19: PETSC_INTERN PetscErrorCode PetscStackView(FILE*);
     20: PETSC_INTERN PetscErrorCode PetscStackReset(void);
     21: PETSC_INTERN PetscErrorCode PetscStackCopy(PetscStack*,PetscStack*);
     22: PETSC_INTERN PetscErrorCode PetscStackPrint(PetscStack *,FILE*);
     23: #else
     24: #define PetscStackSetCheck(check)        0
     25: #define PetscStackView(file)             0
     26: #define PetscStackReset()                0
     27: #define PetscStackCopy(stackin,stackout) 0
     28: #define PetscStackPrint(stack,file)      0
     29: #endif /* PetscDefined(USE_DEBUG) */

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

     35: #if defined(PETSC_HAVE_CLOSURE)
     36: PETSC_EXTERN PetscErrorCode PetscVFPrintfSetClosure(int (^)(const char*));
     37: #endif

     39: /*
     40:    All major PETSc data structures have a common core; this is defined
     41:    below by PETSCHEADER.

     43:    PetscHeaderCreate() should be used whenever creating a PETSc structure.
     44: */

     46: /*
     47:    PetscOps: structure of core operations that all PETSc objects support.

     49:       getcomm()         - Gets the object's communicator.
     50:       view()            - Is the routine for viewing the entire PETSc object; for
     51:                           example, MatView() is the general matrix viewing routine.
     52:                           This is used by PetscObjectView((PetscObject)obj) to allow
     53:                           viewing any PETSc object.
     54:       destroy()         - Is the routine for destroying the entire PETSc object;
     55:                           for example,MatDestroy() is the general matrix
     56:                           destruction routine.
     57:                           This is used by PetscObjectDestroy((PetscObject*)&obj) to allow
     58:                           destroying any PETSc object.
     59:       compose()         - Associates a PETSc object with another PETSc object with a name
     60:       query()           - Returns a different PETSc object that has been associated
     61:                           with the first object using a name.
     62:       composefunction() - Attaches an a function to a PETSc object with a name.
     63:       queryfunction()   - Requests a registered function that has been attached to a PETSc object.
     64: */

     66: typedef struct {
     67:    PetscErrorCode (*getcomm)(PetscObject,MPI_Comm *);
     68:    PetscErrorCode (*view)(PetscObject,PetscViewer);
     69:    PetscErrorCode (*destroy)(PetscObject*);
     70:    PetscErrorCode (*compose)(PetscObject,const char[],PetscObject);
     71:    PetscErrorCode (*query)(PetscObject,const char[],PetscObject *);
     72:    PetscErrorCode (*composefunction)(PetscObject,const char[],void (*)(void));
     73:    PetscErrorCode (*queryfunction)(PetscObject,const char[],void (**)(void));
     74: } PetscOps;

     76: typedef enum {PETSC_FORTRAN_CALLBACK_CLASS,PETSC_FORTRAN_CALLBACK_SUBTYPE,PETSC_FORTRAN_CALLBACK_MAXTYPE} PetscFortranCallbackType;
     77: typedef size_t PetscFortranCallbackId;
     78: #define PETSC_SMALLEST_FORTRAN_CALLBACK ((PetscFortranCallbackId)1000)
     79: PETSC_EXTERN PetscErrorCode PetscFortranCallbackRegister(PetscClassId,const char*,PetscFortranCallbackId*);
     80: PETSC_EXTERN PetscErrorCode PetscFortranCallbackGetSizes(PetscClassId,PetscFortranCallbackId*,PetscFortranCallbackId*);

     82: typedef struct {
     83:   void (*func)(void);
     84:   void *ctx;
     85: } PetscFortranCallback;

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

    132:   PetscInt             noptionhandler;
    133:   PetscErrorCode       (*optionhandler[PETSC_MAX_OPTIONS_HANDLER])(PetscOptionItems*,PetscObject,void*);
    134:   PetscErrorCode       (*optiondestroy[PETSC_MAX_OPTIONS_HANDLER])(PetscObject,void*);
    135:   void                 *optionctx[PETSC_MAX_OPTIONS_HANDLER];
    136:   PetscBool            optionsprinted;
    137: #if defined(PETSC_HAVE_SAWS)
    138:   PetscBool            amsmem;          /* if PETSC_TRUE then this object is registered with SAWs and visible to clients */
    139:   PetscBool            amspublishblock; /* if PETSC_TRUE and publishing objects then will block at PetscObjectSAWsBlock() */
    140: #endif
    141:   PetscOptions         options;         /* options database used, NULL means default */
    142:   PetscBool            donotPetscObjectPrintClassNamePrefixType;
    143: } _p_PetscObject;

    145: #define PETSCHEADER(ObjectOps) \
    146:   _p_PetscObject hdr;          \
    147:   ObjectOps      ops[1]

    149: #define  PETSCFREEDHEADER -1

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

    154: /*@C
    155:     PetscHeaderCreate - Creates a PETSc object of a particular class

    157:     Input Parameters:
    158: +   classid - the classid associated with this object (for example VEC_CLASSID)
    159: .   class_name - string name of class; should be static (for example "Vec")
    160: .   descr - string containing short description; should be static (for example "Vector")
    161: .   mansec - string indicating section in manual pages; should be static (for example "Vec")
    162: .   comm - the MPI Communicator
    163: .   destroy - the destroy routine for this object (for example VecDestroy())
    164: -   view - the view routine for this object (for example VecView())

    166:     Output Parameter:
    167: .   h - the newly created object

    169:     Level: developer

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

    173: @*/
    174: #define PetscHeaderCreate(h,classid,class_name,descr,mansec,comm,destroy,view) \
    175:   (PetscNew(&(h)) || \
    176:    PetscHeaderCreate_Private((PetscObject)(h),classid,class_name,descr,mansec,comm,(PetscObjectDestroyFunction)(destroy),(PetscObjectViewFunction)(view)) || \
    177:    PetscLogObjectCreate(h) || \
    178:    PetscLogObjectMemory((PetscObject)(h),sizeof(*(h))))

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

    183: /*@C
    184:     PetscHeaderDestroy - Final step in destroying a PetscObject

    186:     Input Parameters:
    187: .   h - the header created with PetscHeaderCreate()

    189:     Level: developer

    191: .seealso: PetscHeaderCreate()
    192: @*/
    193: #define PetscHeaderDestroy(h) (PetscHeaderDestroy_Private((PetscObject)(*(h))) || PetscFree(*(h)))

    195: PETSC_EXTERN PetscErrorCode PetscHeaderDestroy_Private(PetscObject);
    196: PETSC_EXTERN PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject,PetscObject);
    197: PETSC_EXTERN PetscErrorCode PetscObjectSetFortranCallback(PetscObject,PetscFortranCallbackType,PetscFortranCallbackId*,void(*)(void),void *ctx);
    198: PETSC_EXTERN PetscErrorCode PetscObjectGetFortranCallback(PetscObject,PetscFortranCallbackType,PetscFortranCallbackId,void(**)(void),void **ctx);

    200: PETSC_INTERN PetscErrorCode PetscCitationsInitialize(void);
    201: PETSC_INTERN PetscErrorCode PetscFreeMPIResources(void);
    202: PETSC_INTERN PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions,PetscBool*);

    204: /* Code shared between C and Fortran */
    205: PETSC_INTERN PetscErrorCode PetscInitialize_Common(const char*,const char*,const char*,PetscBool,PetscBool,PetscInt);

    208: #if !defined(PETSC_CLANG_STATIC_ANALYZER)
    209: /*
    210:     Macros to test if a PETSc object is valid and if pointers are valid
    211: */
    212: #if !defined(PETSC_USE_DEBUG)

    225: #else

    227: /*  This check is for subtype methods such as DMDAGetCorners() that do not use the PetscTryMethod() or PetscUseMethod() paradigm */
    229:   do {   \
    230:     PetscBool _7_same; \
    232:     PetscObjectTypeCompare((PetscObject)(h),t,&_7_same); \
    234:   } while (0)

    239:   } while (0)

    243:     if (((PetscObject)(h))->classid != ck) {                                                   \
    245:       else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Wrong type of object: Parameter # %d",arg); \
    246:     }                                                                                          \
    247:   } while (0)

    253:   } while (0)

    263:   do {                                                                  \
    265:   } while (0)
    266: #endif
    267: #else /* PETSC_CLANG_STATIC_ANALYZER */
    268: template <typename T>
    270: template <typename T>
    272: template <typename T>
    274: template <typename T>
    276: template <typename T>
    278: template <typename T>
    280: template <typename T>
    282: template <typename T>
    284: template <typename T>
    286: template <typename T>
    289: #endif /* PETSC_CLANG_STATIC_ANALYZER */

    291: #define PetscSorted(n,idx,sorted)                                               \
    292:   do {                                                                          \
    293:     (sorted) = PETSC_TRUE;                                                      \
    294:     for (PetscInt _i_ = 1; _i_ < (n); ++_i_) {                                  \
    295:       if ((idx)[_i_] < (idx)[_i_ - 1]) { (sorted) = PETSC_FALSE; break; }       \
    296:     }                                                                           \
    297:   } while (0)

    299: #if !defined(PETSC_CLANG_STATIC_ANALYZER)
    300: #if !defined(PETSC_USE_DEBUG)

    316: #else

    318: /*
    319:     For example, in the dot product between two vectors,
    320:   both vectors must be either Seq or MPI, not one of each
    321: */
    323:   do {                                                                  \
    325:   } while (0)

    327: /*
    328:     Check type_name
    329: */
    331:   do {                                                                                         \
    332:     PetscBool _7_match;                                                                        \
    333:     PetscObjectTypeCompare(((PetscObject)(a)),(type),&_7_match);                      \
    335:   } while (0)

    338:   do {                                                                                         \
    339:     PetscBool _7_match;                                                                        \
    340:     PetscObjectTypeCompareAny(((PetscObject)(a)),&_7_match,(type1),(type2),"");       \
    342:   } while (0)
    343: /*
    344:    Use this macro to check if the type is set
    345: */

    348:   do {                                                                                         \
    350:   } while (0)
    351: /*
    352:    Sometimes object must live on same communicator to inter-operate
    353: */
    355:   do {                                                                  \
    356:     PetscMPIInt    _7_flag;                                             \
    357:     MPI_Comm_compare(PetscObjectComm((PetscObject)(a)),PetscObjectComm((PetscObject)(b)),&_7_flag); \
    359:   } while (0)

    362:   do {                                                  \
    365:   } while (0)

    368:   do {                                                                  \
    369:     PetscScalar b0=(b);                                                 \
    370:     PetscReal b1[5],b2[5];                                              \
    371:     if (PetscIsNanScalar(b0)) {b1[4] = 1;} else {b1[4] = 0;};           \
    372:     b1[0] = -PetscRealPart(b0); b1[1] = PetscRealPart(b0); b1[2] = -PetscImaginaryPart(b0); b1[3] = PetscImaginaryPart(b0); \
    373:     MPIU_Allreduce(b1,b2,5,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)(a)));\
    375:   } while (0)

    378:   do {                                                                  \
    379:     PetscReal b0=(b),b1[3],b2[3];                                       \
    380:     if (PetscIsNanReal(b0)) {b1[2] = 1;} else {b1[2] = 0;};             \
    381:     b1[0] = -b0; b1[1] = b0;                                            \
    382:     MPIU_Allreduce(b1,b2,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)(a)));\
    384:   } while (0)

    387:   do {                                                                  \
    388:     PetscInt b0=(b),b1[2],b2[2];                                        \
    389:     b1[0] = -b0; b1[1] = b0;                                            \
    390:     MPIU_Allreduce(b1,b2,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));\
    392:   } while (0)

    395:   do {                                                                  \
    396:     PetscMPIInt b0=(b),b1[2],b2[2];                                     \
    397:     b1[0] = -b0; b1[1] = b0;                                            \
    398:     MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));\
    400:   } while (0)

    403:   do {                                                                  \
    404:     PetscMPIInt b0=(PetscMPIInt)(b),b1[2],b2[2];                        \
    405:     b1[0] = -b0; b1[1] = b0;                                            \
    406:     MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));\
    408:   } while (0)

    411:   do {                                                                  \
    412:     PetscMPIInt b0=(PetscMPIInt)(b),b1[2],b2[2];                        \
    413:     b1[0] = -b0; b1[1] = b0;                                            \
    414:     MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));\
    416:   } while (0)

    419:   do {                                                                                            \
    420:     PetscBool _1_flg;                                                                             \
    421:     PetscSorted(n,idx,_1_flg);                                                                    \
    423:   } while (0)

    425: #endif
    426: #else /* PETSC_CLANG_STATIC_ANALYZER */
    427: template <typename Ta,typename Tb>
    431: template <typename T>
    433: template <typename Ta,typename Tb>
    435: template <typename Ta,typename Tb>
    437: template <typename Ta,typename Tb>
    439: template <typename Ta,typename Tb>
    441: template <typename Ta,typename Tb>
    443: template <typename Ta,typename Tb>
    445: template <typename Ta,typename Tb>
    447: template <typename Ta,typename Tb>
    450: #endif /* PETSC_CLANG_STATIC_ANALYZER */

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

    456:    Level: developer

    458: .seealso: PetscUseMethod()
    459: */
    460: #define PetscTryMethod(obj,A,B,C) do {                             \
    461:     PetscErrorCode (*_7_f)B;                                       \
    462:     PetscObjectQueryFunction((PetscObject)(obj),A,&_7_f); \
    463:     if (_7_f) (*_7_f)C;                                   \
    464:   } while (0)

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

    470:    Level: developer

    472: .seealso: PetscTryMethod()
    473: */
    474: #define PetscUseMethod(obj,A,B,C) do {                                                         \
    475:     PetscErrorCode (*_7_f)B;                                                                   \
    476:     PetscObjectQueryFunction((PetscObject)(obj),A,&_7_f);                             \
    478:     (*_7_f)C;                                                                         \
    479:   } while (0)

    481: /*MC
    482:    PetscObjectStateIncrease - Increases the state of any PetscObject

    484:    Synopsis:
    485:    #include "petsc/private/petscimpl.h"
    486:    PetscErrorCode PetscObjectStateIncrease(PetscObject obj)

    488:    Logically Collective

    490:    Input Parameter:
    491: .  obj - any PETSc object, for example a Vec, Mat or KSP. This must be
    492:          cast with a (PetscObject), for example,
    493:          PetscObjectStateIncrease((PetscObject)mat);

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

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

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

    508:    Level: developer

    510:    seealso: PetscObjectStateGet()

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

    515: PETSC_EXTERN PetscErrorCode PetscObjectStateGet(PetscObject,PetscObjectState*);
    516: PETSC_EXTERN PetscErrorCode PetscObjectStateSet(PetscObject,PetscObjectState);
    517: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataRegister(PetscInt*);
    518: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject);
    519: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject);
    520: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject);
    521: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject);
    522: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject);
    523: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject);
    524: PETSC_EXTERN PetscInt       PetscObjectComposedDataMax;
    525: /*MC
    526:    PetscObjectComposedDataSetInt - attach integer data to a PetscObject

    528:    Synopsis:
    529:    #include "petsc/private/petscimpl.h"
    530:    PetscErrorCode PetscObjectComposedDataSetInt(PetscObject obj,int id,int data)

    532:    Not collective

    534:    Input parameters:
    535: +  obj - the object to which data is to be attached
    536: .  id - the identifier for the data
    537: -  data - the data to  be attached

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

    542:    Level: developer
    543: M*/
    544: #define PetscObjectComposedDataSetInt(obj,id,data)                                      \
    545:   ((((obj)->int_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseInt(obj)) ||  \
    546:    ((obj)->intcomposeddata[id] = data,(obj)->intcomposedstate[id] = (obj)->state, 0))

    548: /*MC
    549:    PetscObjectComposedDataGetInt - retrieve integer data attached to an object

    551:    Synopsis:
    552:    #include "petsc/private/petscimpl.h"
    553:    PetscErrorCode PetscObjectComposedDataGetInt(PetscObject obj,int id,int data,PetscBool  flag)

    555:    Not collective

    557:    Input parameters:
    558: +  obj - the object from which data is to be retrieved
    559: -  id - the identifier for the data

    561:    Output parameters:
    562: +  data - the data to be retrieved
    563: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

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

    567:    Level: developer
    568: M*/
    569: #define PetscObjectComposedDataGetInt(obj,id,data,flag)                            \
    570:   ((((obj)->intcomposedstate && ((obj)->intcomposedstate[id] == (obj)->state)) ?   \
    571:    (data = (obj)->intcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

    573: /*MC
    574:    PetscObjectComposedDataSetIntstar - attach integer array data to a PetscObject

    576:    Synopsis:
    577:    #include "petsc/private/petscimpl.h"
    578:    PetscErrorCode PetscObjectComposedDataSetIntstar(PetscObject obj,int id,int *data)

    580:    Not collective

    582:    Input parameters:
    583: +  obj - the object to which data is to be attached
    584: .  id - the identifier for the data
    585: -  data - the data to  be attached

    587:    Notes
    588:    The data identifier can best be determined through a call to
    589:    PetscObjectComposedDataRegister()

    591:    Level: developer
    592: M*/
    593: #define PetscObjectComposedDataSetIntstar(obj,id,data)                                          \
    594:   ((((obj)->intstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseIntstar(obj)) ||  \
    595:    ((obj)->intstarcomposeddata[id] = data,(obj)->intstarcomposedstate[id] = (obj)->state, 0))

    597: /*MC
    598:    PetscObjectComposedDataGetIntstar - retrieve integer array data
    599:    attached to an object

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

    605:    Not collective

    607:    Input parameters:
    608: +  obj - the object from which data is to be retrieved
    609: -  id - the identifier for the data

    611:    Output parameters:
    612: +  data - the data to be retrieved
    613: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

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

    617:    Level: developer
    618: M*/
    619: #define PetscObjectComposedDataGetIntstar(obj,id,data,flag)                               \
    620:   ((((obj)->intstarcomposedstate && ((obj)->intstarcomposedstate[id] == (obj)->state)) ?  \
    621:    (data = (obj)->intstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

    623: /*MC
    624:    PetscObjectComposedDataSetReal - attach real data to a PetscObject

    626:    Synopsis:
    627:    #include "petsc/private/petscimpl.h"
    628:    PetscErrorCode PetscObjectComposedDataSetReal(PetscObject obj,int id,PetscReal data)

    630:    Not collective

    632:    Input parameters:
    633: +  obj - the object to which data is to be attached
    634: .  id - the identifier for the data
    635: -  data - the data to  be attached

    637:    Notes
    638:    The data identifier can best be determined through a call to
    639:    PetscObjectComposedDataRegister()

    641:    Level: developer
    642: M*/
    643: #define PetscObjectComposedDataSetReal(obj,id,data)                                       \
    644:   ((((obj)->real_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseReal(obj)) ||  \
    645:    ((obj)->realcomposeddata[id] = data,(obj)->realcomposedstate[id] = (obj)->state, 0))

    647: /*MC
    648:    PetscObjectComposedDataGetReal - retrieve real data attached to an object

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

    654:    Not collective

    656:    Input parameters:
    657: +  obj - the object from which data is to be retrieved
    658: -  id - the identifier for the data

    660:    Output parameters:
    661: +  data - the data to be retrieved
    662: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

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

    666:    Level: developer
    667: M*/
    668: #define PetscObjectComposedDataGetReal(obj,id,data,flag)                            \
    669:   ((((obj)->realcomposedstate && ((obj)->realcomposedstate[id] == (obj)->state)) ?  \
    670:    (data = (obj)->realcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

    672: /*MC
    673:    PetscObjectComposedDataSetRealstar - attach real array data to a PetscObject

    675:    Synopsis:
    676:    #include "petsc/private/petscimpl.h"
    677:    PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *data)

    679:    Not collective

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

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

    690:    Level: developer
    691: M*/
    692: #define PetscObjectComposedDataSetRealstar(obj,id,data)                                           \
    693:   ((((obj)->realstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseRealstar(obj)) ||  \
    694:    ((obj)->realstarcomposeddata[id] = data, (obj)->realstarcomposedstate[id] = (obj)->state, 0))

    696: /*MC
    697:    PetscObjectComposedDataGetRealstar - retrieve real array data
    698:    attached to an object

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

    722: /*MC
    723:    PetscObjectComposedDataSetScalar - attach scalar data to a PetscObject

    725:    Synopsis:
    726:    #include "petsc/private/petscimpl.h"
    727:    PetscErrorCode PetscObjectComposedDataSetScalar(PetscObject obj,int id,PetscScalar data)

    729:    Not collective

    731:    Input parameters:
    732: +  obj - the object to which data is to be attached
    733: .  id - the identifier for the data
    734: -  data - the data to  be attached

    736:    Notes
    737:    The data identifier can best be determined through a call to
    738:    PetscObjectComposedDataRegister()

    740:    Level: developer
    741: M*/
    742: #if defined(PETSC_USE_COMPLEX)
    743: #define PetscObjectComposedDataSetScalar(obj,id,data)                                        \
    744:   ((((obj)->scalar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalar(obj)) || \
    745:    ((obj)->scalarcomposeddata[id] = data,(obj)->scalarcomposedstate[id] = (obj)->state, 0))
    746: #else
    747: #define PetscObjectComposedDataSetScalar(obj,id,data) \
    748:         PetscObjectComposedDataSetReal(obj,id,data)
    749: #endif
    750: /*MC
    751:    PetscObjectComposedDataGetScalar - retrieve scalar data attached to an object

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

    757:    Not collective

    759:    Input parameters:
    760: +  obj - the object from which data is to be retrieved
    761: -  id - the identifier for the data

    763:    Output parameters:
    764: +  data - the data to be retrieved
    765: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

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

    769:    Level: developer
    770: M*/
    771: #if defined(PETSC_USE_COMPLEX)
    772: #define PetscObjectComposedDataGetScalar(obj,id,data,flag)                              \
    773:   ((((obj)->scalarcomposedstate && ((obj)->scalarcomposedstate[id] == (obj)->state)) ? \
    774:    (data = (obj)->scalarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
    775: #else
    776: #define PetscObjectComposedDataGetScalar(obj,id,data,flag)                             \
    777:         PetscObjectComposedDataGetReal(obj,id,data,flag)
    778: #endif

    780: /*MC
    781:    PetscObjectComposedDataSetScalarstar - attach scalar array data to a PetscObject

    783:    Synopsis:
    784:    #include "petsc/private/petscimpl.h"
    785:    PetscErrorCode PetscObjectComposedDataSetScalarstar(PetscObject obj,int id,PetscScalar *data)

    787:    Not collective

    789:    Input parameters:
    790: +  obj - the object to which data is to be attached
    791: .  id - the identifier for the data
    792: -  data - the data to  be attached

    794:    Notes
    795:    The data identifier can best be determined through a call to
    796:    PetscObjectComposedDataRegister()

    798:    Level: developer
    799: M*/
    800: #if defined(PETSC_USE_COMPLEX)
    801: #define PetscObjectComposedDataSetScalarstar(obj,id,data)                                             \
    802:   ((((obj)->scalarstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalarstar(obj)) ||  \
    803:    ((obj)->scalarstarcomposeddata[id] = data,(obj)->scalarstarcomposedstate[id] = (obj)->state, 0))
    804: #else
    805: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
    806:         PetscObjectComposedDataSetRealstar(obj,id,data)
    807: #endif
    808: /*MC
    809:    PetscObjectComposedDataGetScalarstar - retrieve scalar array data
    810:    attached to an object

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

    816:    Not collective

    818:    Input parameters:
    819: +  obj - the object from which data is to be retrieved
    820: -  id - the identifier for the data

    822:    Output parameters:
    823: +  data - the data to be retrieved
    824: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

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

    828:    Level: developer
    829: M*/
    830: #if defined(PETSC_USE_COMPLEX)
    831: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag)                                 \
    832:   ((((obj)->scalarstarcomposedstate && ((obj)->scalarstarcomposedstate[id] == (obj)->state)) ? \
    833:        (data = (obj)->scalarstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
    834: #else
    835: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag)         \
    836:         PetscObjectComposedDataGetRealstar(obj,id,data,flag)
    837: #endif

    839: PETSC_EXTERN PetscMPIInt Petsc_Counter_keyval;
    840: PETSC_EXTERN PetscMPIInt Petsc_InnerComm_keyval;
    841: PETSC_EXTERN PetscMPIInt Petsc_OuterComm_keyval;
    842: PETSC_EXTERN PetscMPIInt Petsc_Seq_keyval;
    843: PETSC_EXTERN PetscMPIInt Petsc_ShmComm_keyval;

    845: struct PetscCommStash {
    846:   struct PetscCommStash *next;
    847:   MPI_Comm              comm;
    848: };

    850: /*
    851:   PETSc communicators have this attribute, see
    852:   PetscCommDuplicate(), PetscCommDestroy(), PetscCommGetNewTag(), PetscObjectGetName()
    853: */
    854: typedef struct {
    855:   PetscMPIInt           tag;              /* next free tag value */
    856:   PetscInt              refcount;         /* number of references, communicator can be freed when this reaches 0 */
    857:   PetscInt              namecount;        /* used to generate the next name, as in Vec_0, Mat_1, ... */
    858:   PetscMPIInt           *iflags;          /* length of comm size, shared by all calls to PetscCommBuildTwoSided_Allreduce/RedScatter on this comm */
    859:   struct PetscCommStash *comms;           /* communicators available for PETSc to pass off to other packages */
    860: } PetscCommCounter;

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

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

    866: typedef struct {
    867:   MPI_Comm       comm;
    868:   MPI_Request    request;
    869:   PetscBool      mix;
    870:   PetscBool      async;
    871:   PetscScalar    *lvalues;     /* this are the reduced values before call to MPI_Allreduce() */
    872:   PetscScalar    *gvalues;     /* values after call to MPI_Allreduce() */
    873:   void           **invecs;     /* for debugging only, vector/memory used with each op */
    874:   PetscInt       *reducetype;  /* is particular value to be summed or maxed? */
    875:   struct { PetscScalar v; PetscInt i; } *lvalues_mix,*gvalues_mix; /* used when mixing reduce operations */
    876:   SRState        state;        /* are we calling xxxBegin() or xxxEnd()? */
    877:   PetscInt       maxops;       /* total amount of space we have for requests */
    878:   PetscInt       numopsbegin;  /* number of requests that have been queued in */
    879:   PetscInt       numopsend;    /* number of requests that have been gotten by user */
    880: } PetscSplitReduction;

    882: PETSC_EXTERN PetscErrorCode PetscSplitReductionGet(MPI_Comm,PetscSplitReduction**);
    883: PETSC_EXTERN PetscErrorCode PetscSplitReductionEnd(PetscSplitReduction*);
    884: PETSC_EXTERN PetscErrorCode PetscSplitReductionExtend(PetscSplitReduction*);

    886: #if !defined(PETSC_SKIP_SPINLOCK)
    887: #if defined(PETSC_HAVE_THREADSAFETY)
    888: #  if defined(PETSC_HAVE_CONCURRENCYKIT)
    889: #if defined(__cplusplus)
    890: /*  CK does not have extern "C" protection in their include files */
    891: extern "C" {
    892: #endif
    893: #include <ck_spinlock.h>
    894: #if defined(__cplusplus)
    895: }
    896: #endif
    897: typedef ck_spinlock_t PetscSpinlock;
    898: static inline PetscErrorCode PetscSpinlockCreate(PetscSpinlock *ck_spinlock)
    899: {
    900:   ck_spinlock_init(ck_spinlock);
    901:   return 0;
    902: }
    903: static inline PetscErrorCode PetscSpinlockLock(PetscSpinlock *ck_spinlock)
    904: {
    905:   ck_spinlock_lock(ck_spinlock);
    906:   return 0;
    907: }
    908: static inline PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *ck_spinlock)
    909: {
    910:   ck_spinlock_unlock(ck_spinlock);
    911:   return 0;
    912: }
    913: static inline PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *ck_spinlock)
    914: {
    915:   return 0;
    916: }
    917: #  elif defined(PETSC_HAVE_OPENMP)

    919: #include <omp.h>
    920: typedef omp_lock_t PetscSpinlock;
    921: static inline PetscErrorCode PetscSpinlockCreate(PetscSpinlock *omp_lock)
    922: {
    923:   omp_init_lock(omp_lock);
    924:   return 0;
    925: }
    926: static inline PetscErrorCode PetscSpinlockLock(PetscSpinlock *omp_lock)
    927: {
    928:   omp_set_lock(omp_lock);
    929:   return 0;
    930: }
    931: static inline PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *omp_lock)
    932: {
    933:   omp_unset_lock(omp_lock);
    934:   return 0;
    935: }
    936: static inline PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *omp_lock)
    937: {
    938:   omp_destroy_lock(omp_lock);
    939:   return 0;
    940: }
    941: #else
    942: #error "Thread safety requires either --with-openmp or --download-concurrencykit"
    943: #endif

    945: #else
    946: typedef int PetscSpinlock;
    947: #define PetscSpinlockCreate(a)  0
    948: #define PetscSpinlockLock(a)    0
    949: #define PetscSpinlockUnlock(a)  0
    950: #define PetscSpinlockDestroy(a) 0
    951: #endif

    953: #if defined(PETSC_HAVE_THREADSAFETY)
    954: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockOpen;
    955: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStdout;
    956: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStderr;
    957: PETSC_INTERN PetscSpinlock PetscCommSpinLock;
    958: #endif
    959: #endif

    961: PETSC_EXTERN PetscLogEvent PETSC_Barrier;
    962: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSided;
    963: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSidedF;
    964: PETSC_EXTERN PetscBool     use_gpu_aware_mpi;

    966: #if defined(PETSC_HAVE_ADIOS)
    967: PETSC_EXTERN int64_t Petsc_adios_group;
    968: #endif

    970: #if defined(PETSC_HAVE_KOKKOS)
    971: PETSC_INTERN PetscBool      PetscBeganKokkos;
    972: PETSC_EXTERN PetscBool      PetscKokkosInitialized;
    973: PETSC_INTERN PetscErrorCode PetscKokkosIsInitialized_Private(PetscBool*);
    974: PETSC_INTERN PetscErrorCode PetscKokkosFinalize_Private(void);
    975: #endif

    977: #if defined(PETSC_HAVE_OPENMP)
    978: PETSC_EXTERN PetscInt PetscNumOMPThreads;
    979: #endif

    981: #endif /* PETSCIMPL_H */