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)


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

255: } while (0)


265:   do {                                                                  \
267:   } while (0)
268: #endif
269: #else /* PETSC_CLANG_STATIC_ANALYZER */
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>
288: template <typename T>
291: #endif /* PETSC_CLANG_STATIC_ANALYZER */

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

301: #if !defined(PETSC_CLANG_STATIC_ANALYZER)
302: #if !defined(PETSC_USE_DEBUG)


318: #else

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

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

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

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

364:   do {                                                  \
367:   } while (0)

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

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

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

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

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

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

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

427: #endif
428: #else /* PETSC_CLANG_STATIC_ANALYZER */
429: template <typename Ta,typename Tb>
433: template <typename T>
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>
449: template <typename Ta,typename Tb>
452: #endif /* PETSC_CLANG_STATIC_ANALYZER */

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

458:    Level: developer

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

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

472:    Level: developer

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

483: /*MC
484:    PetscObjectStateIncrease - Increases the state of any PetscObject

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

490:    Logically Collective

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

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

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

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

510:    Level: developer

512:    seealso: PetscObjectStateGet()

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

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

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

534:    Not collective

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

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

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

550: /*MC
551:    PetscObjectComposedDataGetInt - retrieve integer data attached to an object

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

557:    Not collective

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

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

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

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

575: /*MC
576:    PetscObjectComposedDataSetIntstar - attach integer array data to a PetscObject

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

582:    Not collective

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

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

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

599: /*MC
600:    PetscObjectComposedDataGetIntstar - retrieve integer array data
601:    attached to an object

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

607:    Not collective

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

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

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

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

625: /*MC
626:    PetscObjectComposedDataSetReal - attach real data to a PetscObject

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

632:    Not collective

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

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

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

649: /*MC
650:    PetscObjectComposedDataGetReal - retrieve real data attached to an object

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

656:    Not collective

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

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

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

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

674: /*MC
675:    PetscObjectComposedDataSetRealstar - attach real array data to a PetscObject

677:    Synopsis:
678:    #include "petsc/private/petscimpl.h"
679:    PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *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: #define PetscObjectComposedDataSetRealstar(obj,id,data)                                           \
695:   ((((obj)->realstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseRealstar(obj)) ||  \
696:    ((obj)->realstarcomposeddata[id] = data, (obj)->realstarcomposedstate[id] = (obj)->state, 0))

698: /*MC
699:    PetscObjectComposedDataGetRealstar - retrieve real array data
700:    attached to an object

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

706:    Not collective

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

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

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

718:    Level: developer
719: M*/
720: #define PetscObjectComposedDataGetRealstar(obj,id,data,flag)                                \
721:   ((((obj)->realstarcomposedstate && ((obj)->realstarcomposedstate[id] == (obj)->state)) ?  \
722:    (data = (obj)->realstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

724: /*MC
725:    PetscObjectComposedDataSetScalar - attach scalar data to a PetscObject

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

731:    Not collective

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

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

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

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

759:    Not collective

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

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

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

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

782: /*MC
783:    PetscObjectComposedDataSetScalarstar - attach scalar array data to a PetscObject

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

789:    Not collective

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

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

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

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

818:    Not collective

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

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

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

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

841: PETSC_EXTERN PetscMPIInt Petsc_Counter_keyval;
842: PETSC_EXTERN PetscMPIInt Petsc_InnerComm_keyval;
843: PETSC_EXTERN PetscMPIInt Petsc_OuterComm_keyval;
844: PETSC_EXTERN PetscMPIInt Petsc_Seq_keyval;
845: PETSC_EXTERN PetscMPIInt Petsc_ShmComm_keyval;

847: struct PetscCommStash {
848:   struct PetscCommStash *next;
849:   MPI_Comm              comm;
850: };

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

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

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

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

884: PETSC_EXTERN PetscErrorCode PetscSplitReductionGet(MPI_Comm,PetscSplitReduction**);
885: PETSC_EXTERN PetscErrorCode PetscSplitReductionEnd(PetscSplitReduction*);
886: PETSC_EXTERN PetscErrorCode PetscSplitReductionExtend(PetscSplitReduction*);

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

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

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

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

963: PETSC_EXTERN PetscLogEvent PETSC_Barrier;
964: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSided;
965: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSidedF;
966: PETSC_EXTERN PetscBool     use_gpu_aware_mpi;

968: #if defined(PETSC_HAVE_ADIOS)
969: PETSC_EXTERN int64_t Petsc_adios_group;
970: #endif

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

979: #if defined(PETSC_HAVE_OPENMP)
980: PETSC_EXTERN PetscInt PetscNumOMPThreads;
981: #endif

983: #endif /* PETSCIMPL_H */