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 int PetscFortranCallbackId;
78: #define PETSC_SMALLEST_FORTRAN_CALLBACK ((PetscFortranCallbackId)1000)
79: PETSC_EXTERN PetscErrorCode PetscFortranCallbackRegister(PetscClassId,const char*,PetscFortranCallbackId*);
80: PETSC_EXTERN PetscErrorCode PetscFortranCallbackGetSizes(PetscClassId,PetscInt*,PetscInt*);
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: PetscInt num_fortran_func_pointers; /* number of Fortran function pointers allocated */
127: PetscFortranCallback *fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
128: PetscInt 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: PetscErrorCode _7_ierr; \
231: PetscBool _7_same; \
233: _7_PetscObjectTypeCompare((PetscObject)(h),t,&_7_same);CHKERRQ(_7_ierr); \
234: 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); \
235: } while (0)
238: do { \
239: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg); \
241: if (((PetscObject)(h))->classid != ck) { \
242: if (((PetscObject)(h))->classid == PETSCFREEDHEADER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
243: else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Wrong type of object: Parameter # %d",arg); \
244: } \
245: } while (0)
248: do { \
249: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg); \
251: if (((PetscObject)(h))->classid == PETSCFREEDHEADER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
252: 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); \
253: } while (0)
256: do { \
257: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
259: } while (0)
262: do { \
263: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg);\
265: } while (0)
268: do { \
269: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Null Pointer: Parameter # %d",arg); \
271: } while (0)
274: do { \
275: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Null Pointer: Parameter # %d",arg); \
277: } while (0)
280: do { \
281: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
283: } while (0)
286: do { \
287: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
289: } while (0)
292: do { \
293: if (!(f)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Function Pointer: Parameter # %d",arg); \
294: } while (0)
295: #endif
296: #else /* PETSC_CLANG_STATIC_ANALYZER */
297: template <typename T>
299: template <typename T>
301: template <typename T>
303: template <typename T>
305: template <typename T>
307: template <typename T>
309: template <typename T>
311: template <typename T>
313: template <typename T>
315: template <typename T>
318: #endif /* PETSC_CLANG_STATIC_ANALYZER */
320: #define PetscSorted(n,idx,sorted) \
321: do { \
322: PetscInt _i_; \
323: (sorted) = PETSC_TRUE; \
324: for (_i_ = 1; _i_ < (n); _i_++) \
325: if ((idx)[_i_] < (idx)[_i_ - 1]) \
326: { (sorted) = PETSC_FALSE; break; } \
327: } while (0)
329: #if !defined(PETSC_CLANG_STATIC_ANALYZER)
330: #if !defined(PETSC_USE_DEBUG)
346: #else
348: /*
349: For example, in the dot product between two vectors,
350: both vectors must be either Seq or MPI, not one of each
351: */
353: do { \
354: 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); \
355: } while (0)
357: /*
358: Check type_name
359: */
361: do { \
362: PetscBool _7_match; \
363: PetscErrorCode _7_ierr; \
364: _7_PetscObjectTypeCompare(((PetscObject)(a)),(type),&_7_match);CHKERRQ(_7_ierr); \
365: if (!_7_match) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Object (%s) is not %s",(char*)(((PetscObject)(a))->type_name),type); \
366: } while (0)
369: do { \
370: PetscBool _7_match; \
371: PetscErrorCode _7_ierr; \
372: _7_PetscObjectTypeCompareAny(((PetscObject)(a)),&_7_match,(type1),(type2),"");CHKERRQ(_7_ierr); \
373: 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); \
374: } while (0)
375: /*
376: Use this macro to check if the type is set
377: */
380: do { \
381: 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); \
382: } while (0)
383: /*
384: Sometimes object must live on same communicator to inter-operate
385: */
387: do { \
388: PetscErrorCode _7_ierr; \
389: PetscMPIInt _7_flag; \
390: _7_MPI_Comm_compare(PetscObjectComm((PetscObject)(a)),PetscObjectComm((PetscObject)(b)),&_7_flag);CHKERRMPI(_7_ierr); \
391: 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); \
392: } while (0)
395: do { \
398: } while (0)
401: do { \
402: PetscErrorCode _7_ierr; \
403: PetscScalar b0=(b); \
404: PetscReal b1[5],b2[5]; \
405: if (PetscIsNanScalar(b0)) {b1[4] = 1;} else {b1[4] = 0;}; \
406: b1[0] = -PetscRealPart(b0); b1[1] = PetscRealPart(b0); b1[2] = -PetscImaginaryPart(b0); b1[3] = PetscImaginaryPart(b0); \
407: _7_MPIU_Allreduce(b1,b2,5,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)(a)));CHKERRMPI(_7_ierr); \
408: 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",arg); \
409: } while (0)
412: do { \
413: PetscErrorCode _7_ierr; \
414: PetscReal b0=(b),b1[3],b2[3]; \
415: if (PetscIsNanReal(b0)) {b1[2] = 1;} else {b1[2] = 0;}; \
416: b1[0] = -b0; b1[1] = b0; \
417: _7_MPIU_Allreduce(b1,b2,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)(a)));CHKERRMPI(_7_ierr); \
418: 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",arg); \
419: } while (0)
422: do { \
423: PetscErrorCode _7_ierr; \
424: PetscInt b0=(b),b1[2],b2[2]; \
425: b1[0] = -b0; b1[1] = b0; \
426: _7_MPIU_Allreduce(b1,b2,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));CHKERRMPI(_7_ierr); \
427: if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)(a)),PETSC_ERR_ARG_WRONG,"Int value must be same on all processes, argument # %d",arg); \
428: } while (0)
431: do { \
432: PetscErrorCode _7_ierr; \
433: PetscMPIInt b0=(b),b1[2],b2[2]; \
434: b1[0] = -b0; b1[1] = b0; \
435: _7_MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));CHKERRMPI(_7_ierr); \
436: if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)(a)),PETSC_ERR_ARG_WRONG,"PetscMPIInt value must be same on all processes, argument # %d",arg); \
437: } while (0)
440: do { \
441: PetscErrorCode _7_ierr; \
442: PetscMPIInt b0=(PetscMPIInt)(b),b1[2],b2[2]; \
443: b1[0] = -b0; b1[1] = b0; \
444: _7_MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));CHKERRMPI(_7_ierr); \
445: if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)(a)),PETSC_ERR_ARG_WRONG,"Bool value must be same on all processes, argument # %d",arg); \
446: } while (0)
449: do { \
450: PetscErrorCode _7_ierr; \
451: PetscMPIInt b0=(PetscMPIInt)(b),b1[2],b2[2]; \
452: b1[0] = -b0; b1[1] = b0; \
453: _7_MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));CHKERRMPI(_7_ierr); \
454: if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)(a)),PETSC_ERR_ARG_WRONG,"Enum value must be same on all processes, argument # %d",arg); \
455: } while (0)
458: do { \
459: PetscBool _1_flg; \
460: PetscSorted(n,idx,_1_flg); \
461: if (!_1_flg) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Input array needs to be sorted"); \
462: } while (0)
464: #endif
465: #else /* PETSC_CLANG_STATIC_ANALYZER */
466: template <typename Ta,typename Tb>
470: template <typename T>
472: template <typename Ta,typename Tb>
474: template <typename Ta,typename Tb>
476: template <typename Ta,typename Tb>
478: template <typename Ta,typename Tb>
480: template <typename Ta,typename Tb>
482: template <typename Ta,typename Tb>
484: template <typename Ta,typename Tb>
486: template <typename Ta,typename Tb>
489: #endif /* PETSC_CLANG_STATIC_ANALYZER */
491: /*
492: PetscTryMethod - Queries an object for a method, if it exists then calls it.
493: These are intended to be used only inside PETSc functions.
495: Level: developer
497: .seealso: PetscUseMethod()
498: */
499: #define PetscTryMethod(obj,A,B,C) \
500: 0; do { PetscErrorCode (*_7_f)B, _7_ierr; \
501: _7_PetscObjectQueryFunction((PetscObject)(obj),A,&_7_f);CHKERRQ(_7_ierr); \
502: if (_7_f) {_7_(*_7_f)C;CHKERRQ(_7_ierr);} \
503: } while (0)
505: /*
506: PetscUseMethod - Queries an object for a method, if it exists then calls it, otherwise generates an error.
507: These are intended to be used only inside PETSc functions.
509: Level: developer
511: .seealso: PetscTryMethod()
512: */
513: #define PetscUseMethod(obj,A,B,C) \
514: 0; do { PetscErrorCode (*_7_f)B, _7_ierr; \
515: _7_PetscObjectQueryFunction((PetscObject)(obj),A,&_7_f);CHKERRQ(_7_ierr); \
516: if (_7_f) {_7_(*_7_f)C;CHKERRQ(_7_ierr);} \
517: else SETERRQ1(PetscObjectComm((PetscObject)(obj)),PETSC_ERR_SUP,"Cannot locate function %s in object",A); \
518: } while (0)
520: /*MC
521: PetscObjectStateIncrease - Increases the state of any PetscObject
523: Synopsis:
524: #include "petsc/private/petscimpl.h"
525: PetscErrorCode PetscObjectStateIncrease(PetscObject obj)
527: Logically Collective
529: Input Parameter:
530: . obj - any PETSc object, for example a Vec, Mat or KSP. This must be
531: cast with a (PetscObject), for example,
532: PetscObjectStateIncrease((PetscObject)mat);
534: Notes:
535: object state is an integer which gets increased every time
536: the object is changed internally. By saving and later querying the object state
537: one can determine whether information about the object is still current.
538: Currently, state is maintained for Vec and Mat objects.
540: This routine is mostly for internal use by PETSc; a developer need only
541: call it after explicit access to an object's internals. Routines such
542: as VecSet() or MatScale() already call this routine. It is also called, as a
543: precaution, in VecRestoreArray(), MatRestoreRow(), MatDenseRestoreArray().
545: This routine is logically collective because state equality comparison needs to be possible without communication.
547: Level: developer
549: seealso: PetscObjectStateGet()
551: M*/
552: #define PetscObjectStateIncrease(obj) ((obj)->state++,0)
554: PETSC_EXTERN PetscErrorCode PetscObjectStateGet(PetscObject,PetscObjectState*);
555: PETSC_EXTERN PetscErrorCode PetscObjectStateSet(PetscObject,PetscObjectState);
556: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataRegister(PetscInt*);
557: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject);
558: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject);
559: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject);
560: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject);
561: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject);
562: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject);
563: PETSC_EXTERN PetscInt PetscObjectComposedDataMax;
564: /*MC
565: PetscObjectComposedDataSetInt - attach integer data to a PetscObject
567: Synopsis:
568: #include "petsc/private/petscimpl.h"
569: PetscErrorCode PetscObjectComposedDataSetInt(PetscObject obj,int id,int data)
571: Not collective
573: Input parameters:
574: + obj - the object to which data is to be attached
575: . id - the identifier for the data
576: - data - the data to be attached
578: Notes
579: The data identifier can best be created through a call to PetscObjectComposedDataRegister()
581: Level: developer
582: M*/
583: #define PetscObjectComposedDataSetInt(obj,id,data) \
584: ((((obj)->int_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseInt(obj)) || \
585: ((obj)->intcomposeddata[id] = data,(obj)->intcomposedstate[id] = (obj)->state, 0))
587: /*MC
588: PetscObjectComposedDataGetInt - retrieve integer data attached to an object
590: Synopsis:
591: #include "petsc/private/petscimpl.h"
592: PetscErrorCode PetscObjectComposedDataGetInt(PetscObject obj,int id,int data,PetscBool flag)
594: Not collective
596: Input parameters:
597: + obj - the object from which data is to be retrieved
598: - id - the identifier for the data
600: Output parameters:
601: + data - the data to be retrieved
602: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
604: The 'data' and 'flag' variables are inlined, so they are not pointers.
606: Level: developer
607: M*/
608: #define PetscObjectComposedDataGetInt(obj,id,data,flag) \
609: ((((obj)->intcomposedstate && ((obj)->intcomposedstate[id] == (obj)->state)) ? \
610: (data = (obj)->intcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
612: /*MC
613: PetscObjectComposedDataSetIntstar - attach integer array data to a PetscObject
615: Synopsis:
616: #include "petsc/private/petscimpl.h"
617: PetscErrorCode PetscObjectComposedDataSetIntstar(PetscObject obj,int id,int *data)
619: Not collective
621: Input parameters:
622: + obj - the object to which data is to be attached
623: . id - the identifier for the data
624: - data - the data to be attached
626: Notes
627: The data identifier can best be determined through a call to
628: PetscObjectComposedDataRegister()
630: Level: developer
631: M*/
632: #define PetscObjectComposedDataSetIntstar(obj,id,data) \
633: ((((obj)->intstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseIntstar(obj)) || \
634: ((obj)->intstarcomposeddata[id] = data,(obj)->intstarcomposedstate[id] = (obj)->state, 0))
636: /*MC
637: PetscObjectComposedDataGetIntstar - retrieve integer array data
638: attached to an object
640: Synopsis:
641: #include "petsc/private/petscimpl.h"
642: PetscErrorCode PetscObjectComposedDataGetIntstar(PetscObject obj,int id,int *data,PetscBool flag)
644: Not collective
646: Input parameters:
647: + obj - the object from which data is to be retrieved
648: - id - the identifier for the data
650: Output parameters:
651: + data - the data to be retrieved
652: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
654: The 'data' and 'flag' variables are inlined, so they are not pointers.
656: Level: developer
657: M*/
658: #define PetscObjectComposedDataGetIntstar(obj,id,data,flag) \
659: ((((obj)->intstarcomposedstate && ((obj)->intstarcomposedstate[id] == (obj)->state)) ? \
660: (data = (obj)->intstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
662: /*MC
663: PetscObjectComposedDataSetReal - attach real data to a PetscObject
665: Synopsis:
666: #include "petsc/private/petscimpl.h"
667: PetscErrorCode PetscObjectComposedDataSetReal(PetscObject obj,int id,PetscReal data)
669: Not collective
671: Input parameters:
672: + obj - the object to which data is to be attached
673: . id - the identifier for the data
674: - data - the data to be attached
676: Notes
677: The data identifier can best be determined through a call to
678: PetscObjectComposedDataRegister()
680: Level: developer
681: M*/
682: #define PetscObjectComposedDataSetReal(obj,id,data) \
683: ((((obj)->real_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseReal(obj)) || \
684: ((obj)->realcomposeddata[id] = data,(obj)->realcomposedstate[id] = (obj)->state, 0))
686: /*MC
687: PetscObjectComposedDataGetReal - retrieve real data attached to an object
689: Synopsis:
690: #include "petsc/private/petscimpl.h"
691: PetscErrorCode PetscObjectComposedDataGetReal(PetscObject obj,int id,PetscReal data,PetscBool flag)
693: Not collective
695: Input parameters:
696: + obj - the object from which data is to be retrieved
697: - id - the identifier for the data
699: Output parameters:
700: + data - the data to be retrieved
701: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
703: The 'data' and 'flag' variables are inlined, so they are not pointers.
705: Level: developer
706: M*/
707: #define PetscObjectComposedDataGetReal(obj,id,data,flag) \
708: ((((obj)->realcomposedstate && ((obj)->realcomposedstate[id] == (obj)->state)) ? \
709: (data = (obj)->realcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
711: /*MC
712: PetscObjectComposedDataSetRealstar - attach real array data to a PetscObject
714: Synopsis:
715: #include "petsc/private/petscimpl.h"
716: PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *data)
718: Not collective
720: Input parameters:
721: + obj - the object to which data is to be attached
722: . id - the identifier for the data
723: - data - the data to be attached
725: Notes
726: The data identifier can best be determined through a call to
727: PetscObjectComposedDataRegister()
729: Level: developer
730: M*/
731: #define PetscObjectComposedDataSetRealstar(obj,id,data) \
732: ((((obj)->realstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseRealstar(obj)) || \
733: ((obj)->realstarcomposeddata[id] = data, (obj)->realstarcomposedstate[id] = (obj)->state, 0))
735: /*MC
736: PetscObjectComposedDataGetRealstar - retrieve real array data
737: attached to an object
739: Synopsis:
740: #include "petsc/private/petscimpl.h"
741: PetscErrorCode PetscObjectComposedDataGetRealstar(PetscObject obj,int id,PetscReal *data,PetscBool flag)
743: Not collective
745: Input parameters:
746: + obj - the object from which data is to be retrieved
747: - id - the identifier for the data
749: Output parameters:
750: + data - the data to be retrieved
751: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
753: The 'data' and 'flag' variables are inlined, so they are not pointers.
755: Level: developer
756: M*/
757: #define PetscObjectComposedDataGetRealstar(obj,id,data,flag) \
758: ((((obj)->realstarcomposedstate && ((obj)->realstarcomposedstate[id] == (obj)->state)) ? \
759: (data = (obj)->realstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
761: /*MC
762: PetscObjectComposedDataSetScalar - attach scalar data to a PetscObject
764: Synopsis:
765: #include "petsc/private/petscimpl.h"
766: PetscErrorCode PetscObjectComposedDataSetScalar(PetscObject obj,int id,PetscScalar data)
768: Not collective
770: Input parameters:
771: + obj - the object to which data is to be attached
772: . id - the identifier for the data
773: - data - the data to be attached
775: Notes
776: The data identifier can best be determined through a call to
777: PetscObjectComposedDataRegister()
779: Level: developer
780: M*/
781: #if defined(PETSC_USE_COMPLEX)
782: #define PetscObjectComposedDataSetScalar(obj,id,data) \
783: ((((obj)->scalar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalar(obj)) || \
784: ((obj)->scalarcomposeddata[id] = data,(obj)->scalarcomposedstate[id] = (obj)->state, 0))
785: #else
786: #define PetscObjectComposedDataSetScalar(obj,id,data) \
787: PetscObjectComposedDataSetReal(obj,id,data)
788: #endif
789: /*MC
790: PetscObjectComposedDataGetScalar - retrieve scalar data attached to an object
792: Synopsis:
793: #include "petsc/private/petscimpl.h"
794: PetscErrorCode PetscObjectComposedDataGetScalar(PetscObject obj,int id,PetscScalar data,PetscBool flag)
796: Not collective
798: Input parameters:
799: + obj - the object from which data is to be retrieved
800: - id - the identifier for the data
802: Output parameters:
803: + data - the data to be retrieved
804: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
806: The 'data' and 'flag' variables are inlined, so they are not pointers.
808: Level: developer
809: M*/
810: #if defined(PETSC_USE_COMPLEX)
811: #define PetscObjectComposedDataGetScalar(obj,id,data,flag) \
812: ((((obj)->scalarcomposedstate && ((obj)->scalarcomposedstate[id] == (obj)->state)) ? \
813: (data = (obj)->scalarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
814: #else
815: #define PetscObjectComposedDataGetScalar(obj,id,data,flag) \
816: PetscObjectComposedDataGetReal(obj,id,data,flag)
817: #endif
819: /*MC
820: PetscObjectComposedDataSetScalarstar - attach scalar array data to a PetscObject
822: Synopsis:
823: #include "petsc/private/petscimpl.h"
824: PetscErrorCode PetscObjectComposedDataSetScalarstar(PetscObject obj,int id,PetscScalar *data)
826: Not collective
828: Input parameters:
829: + obj - the object to which data is to be attached
830: . id - the identifier for the data
831: - data - the data to be attached
833: Notes
834: The data identifier can best be determined through a call to
835: PetscObjectComposedDataRegister()
837: Level: developer
838: M*/
839: #if defined(PETSC_USE_COMPLEX)
840: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
841: ((((obj)->scalarstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalarstar(obj)) || \
842: ((obj)->scalarstarcomposeddata[id] = data,(obj)->scalarstarcomposedstate[id] = (obj)->state, 0))
843: #else
844: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
845: PetscObjectComposedDataSetRealstar(obj,id,data)
846: #endif
847: /*MC
848: PetscObjectComposedDataGetScalarstar - retrieve scalar array data
849: attached to an object
851: Synopsis:
852: #include "petsc/private/petscimpl.h"
853: PetscErrorCode PetscObjectComposedDataGetScalarstar(PetscObject obj,int id,PetscScalar *data,PetscBool flag)
855: Not collective
857: Input parameters:
858: + obj - the object from which data is to be retrieved
859: - id - the identifier for the data
861: Output parameters:
862: + data - the data to be retrieved
863: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
865: The 'data' and 'flag' variables are inlined, so they are not pointers.
867: Level: developer
868: M*/
869: #if defined(PETSC_USE_COMPLEX)
870: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag) \
871: ((((obj)->scalarstarcomposedstate && ((obj)->scalarstarcomposedstate[id] == (obj)->state)) ? \
872: (data = (obj)->scalarstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
873: #else
874: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag) \
875: PetscObjectComposedDataGetRealstar(obj,id,data,flag)
876: #endif
878: PETSC_EXTERN PetscMPIInt Petsc_Counter_keyval;
879: PETSC_EXTERN PetscMPIInt Petsc_InnerComm_keyval;
880: PETSC_EXTERN PetscMPIInt Petsc_OuterComm_keyval;
881: PETSC_EXTERN PetscMPIInt Petsc_Seq_keyval;
882: PETSC_EXTERN PetscMPIInt Petsc_ShmComm_keyval;
884: /*
885: PETSc communicators have this attribute, see
886: PetscCommDuplicate(), PetscCommDestroy(), PetscCommGetNewTag(), PetscObjectGetName()
887: */
888: typedef struct {
889: PetscMPIInt tag; /* next free tag value */
890: PetscInt refcount; /* number of references, communicator can be freed when this reaches 0 */
891: PetscInt namecount; /* used to generate the next name, as in Vec_0, Mat_1, ... */
892: PetscMPIInt *iflags; /* length of comm size, shared by all calls to PetscCommBuildTwoSided_Allreduce/RedScatter on this comm */
893: } PetscCommCounter;
895: typedef enum {STATE_BEGIN, STATE_PENDING, STATE_END} SRState;
897: typedef enum {PETSC_SR_REDUCE_SUM=0,PETSC_SR_REDUCE_MAX=1,PETSC_SR_REDUCE_MIN=2} PetscSRReductionType;
899: typedef struct {
900: MPI_Comm comm;
901: MPI_Request request;
902: PetscBool mix;
903: PetscBool async;
904: PetscScalar *lvalues; /* this are the reduced values before call to MPI_Allreduce() */
905: PetscScalar *gvalues; /* values after call to MPI_Allreduce() */
906: void **invecs; /* for debugging only, vector/memory used with each op */
907: PetscInt *reducetype; /* is particular value to be summed or maxed? */
908: struct { PetscScalar v; PetscInt i; } *lvalues_mix,*gvalues_mix; /* used when mixing reduce operations */
909: SRState state; /* are we calling xxxBegin() or xxxEnd()? */
910: PetscInt maxops; /* total amount of space we have for requests */
911: PetscInt numopsbegin; /* number of requests that have been queued in */
912: PetscInt numopsend; /* number of requests that have been gotten by user */
913: } PetscSplitReduction;
915: PETSC_EXTERN PetscErrorCode PetscSplitReductionGet(MPI_Comm,PetscSplitReduction**);
916: PETSC_EXTERN PetscErrorCode PetscSplitReductionEnd(PetscSplitReduction*);
917: PETSC_EXTERN PetscErrorCode PetscSplitReductionExtend(PetscSplitReduction*);
919: #if !defined(PETSC_SKIP_SPINLOCK)
920: #if defined(PETSC_HAVE_THREADSAFETY)
921: # if defined(PETSC_HAVE_CONCURRENCYKIT)
922: #if defined(__cplusplus)
923: /* CK does not have extern "C" protection in their include files */
924: extern "C" {
925: #endif
926: #include <ck_spinlock.h>
927: #if defined(__cplusplus)
928: }
929: #endif
930: typedef ck_spinlock_t PetscSpinlock;
931: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockCreate(PetscSpinlock *ck_spinlock)
932: {
933: ck_spinlock_init(ck_spinlock);
934: return 0;
935: }
936: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockLock(PetscSpinlock *ck_spinlock)
937: {
938: ck_spinlock_lock(ck_spinlock);
939: return 0;
940: }
941: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *ck_spinlock)
942: {
943: ck_spinlock_unlock(ck_spinlock);
944: return 0;
945: }
946: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *ck_spinlock)
947: {
948: return 0;
949: }
950: # elif defined(PETSC_HAVE_OPENMP)
952: #include <omp.h>
953: typedef omp_lock_t PetscSpinlock;
954: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockCreate(PetscSpinlock *omp_lock)
955: {
956: omp_init_lock(omp_lock);
957: return 0;
958: }
959: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockLock(PetscSpinlock *omp_lock)
960: {
961: omp_set_lock(omp_lock);
962: return 0;
963: }
964: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *omp_lock)
965: {
966: omp_unset_lock(omp_lock);
967: return 0;
968: }
969: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *omp_lock)
970: {
971: omp_destroy_lock(omp_lock);
972: return 0;
973: }
974: #else
975: Thread safety requires either --with-openmp or --download-concurrencykit
976: #endif
978: #else
979: typedef int PetscSpinlock;
980: #define PetscSpinlockCreate(a) 0
981: #define PetscSpinlockLock(a) 0
982: #define PetscSpinlockUnlock(a) 0
983: #define PetscSpinlockDestroy(a) 0
984: #endif
986: #if defined(PETSC_HAVE_THREADSAFETY)
987: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockOpen;
988: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStdout;
989: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStderr;
990: PETSC_INTERN PetscSpinlock PetscCommSpinLock;
991: #endif
992: #endif
994: PETSC_EXTERN PetscLogEvent PETSC_Barrier;
995: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSided;
996: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSidedF;
997: PETSC_EXTERN PetscBool use_gpu_aware_mpi;
999: #if defined(PETSC_HAVE_ADIOS)
1000: PETSC_EXTERN int64_t Petsc_adios_group;
1001: #endif
1003: #if defined(PETSC_HAVE_KOKKOS)
1004: PETSC_INTERN PetscBool PetscBeganKokkos;
1005: PETSC_EXTERN PetscBool PetscKokkosInitialized;
1006: PETSC_INTERN PetscErrorCode PetscKokkosIsInitialized_Private(PetscBool*);
1007: PETSC_INTERN PetscErrorCode PetscKokkosFinalize_Private(void);
1008: #endif
1010: #if defined(PETSC_HAVE_CUDA)
1011: PETSC_EXTERN PetscBool PetscCUDAInitialized; /* Is CUDA initialized? One can use this flag to guard CUDA calls. */
1012: PETSC_EXTERN PetscBool PetscMPICUDAAwarenessCheck(void);
1013: #endif
1015: #if defined(PETSC_HAVE_HIP)
1016: PETSC_EXTERN PetscBool PetscHIPInitialized;
1017: PETSC_EXTERN PetscBool PetscMPIHIPAwarenessCheck(void);
1018: #endif
1020: #if defined(PETSC_HAVE_OPENMP)
1021: PETSC_EXTERN PetscInt PetscNumOMPThreads;
1022: #endif
1024: PETSC_EXTERN PetscBool PetscCreatedGpuObjects;
1025: #endif /* PETSCIMPL_H */