Actual source code: petscimpl.h
petsc-3.15.0 2021-03-30
2: /*
3: Defines the basic header of all PETSc objects.
4: */
6: #if !defined(PETSCIMPL_H)
7: #define PETSCIMPL_H
8: #include <petscsys.h>
10: /* These are used internally by PETSc ASCII IO routines*/
11: #include <stdarg.h>
12: PETSC_EXTERN PetscErrorCode PetscVFPrintfDefault(FILE*,const char[],va_list);
14: #if defined(PETSC_HAVE_CLOSURE)
15: PETSC_EXTERN PetscErrorCode PetscVFPrintfSetClosure(int (^)(const char*));
16: #endif
18: /*
19: All major PETSc data structures have a common core; this is defined
20: below by PETSCHEADER.
22: PetscHeaderCreate() should be used whenever creating a PETSc structure.
23: */
25: /*
26: PetscOps: structure of core operations that all PETSc objects support.
28: getcomm() - Gets the object's communicator.
29: view() - Is the routine for viewing the entire PETSc object; for
30: example, MatView() is the general matrix viewing routine.
31: This is used by PetscObjectView((PetscObject)obj) to allow
32: viewing any PETSc object.
33: destroy() - Is the routine for destroying the entire PETSc object;
34: for example,MatDestroy() is the general matrix
35: destruction routine.
36: This is used by PetscObjectDestroy((PetscObject*)&obj) to allow
37: destroying any PETSc object.
38: compose() - Associates a PETSc object with another PETSc object with a name
39: query() - Returns a different PETSc object that has been associated
40: with the first object using a name.
41: composefunction() - Attaches an a function to a PETSc object with a name.
42: queryfunction() - Requests a registered function that has been attached to a PETSc object.
43: */
45: typedef struct {
46: PetscErrorCode (*getcomm)(PetscObject,MPI_Comm *);
47: PetscErrorCode (*view)(PetscObject,PetscViewer);
48: PetscErrorCode (*destroy)(PetscObject*);
49: PetscErrorCode (*compose)(PetscObject,const char[],PetscObject);
50: PetscErrorCode (*query)(PetscObject,const char[],PetscObject *);
51: PetscErrorCode (*composefunction)(PetscObject,const char[],void (*)(void));
52: PetscErrorCode (*queryfunction)(PetscObject,const char[],void (**)(void));
53: } PetscOps;
55: typedef enum {PETSC_FORTRAN_CALLBACK_CLASS,PETSC_FORTRAN_CALLBACK_SUBTYPE,PETSC_FORTRAN_CALLBACK_MAXTYPE} PetscFortranCallbackType;
56: typedef int PetscFortranCallbackId;
57: #define PETSC_SMALLEST_FORTRAN_CALLBACK ((PetscFortranCallbackId)1000)
58: PETSC_EXTERN PetscErrorCode PetscFortranCallbackRegister(PetscClassId,const char*,PetscFortranCallbackId*);
59: PETSC_EXTERN PetscErrorCode PetscFortranCallbackGetSizes(PetscClassId,PetscInt*,PetscInt*);
61: typedef struct {
62: void (*func)(void);
63: void *ctx;
64: } PetscFortranCallback;
66: /*
67: All PETSc objects begin with the fields defined in PETSCHEADER.
68: The PetscObject is a way of examining these fields regardless of
69: the specific object. In C++ this could be a base abstract class
70: from which all objects are derived.
71: */
72: #define PETSC_MAX_OPTIONS_HANDLER 5
73: typedef struct _p_PetscObject {
74: PetscClassId classid;
75: PetscOps bops[1];
76: MPI_Comm comm;
77: PetscInt type;
78: PetscLogDouble flops,time,mem,memchildren;
79: PetscObjectId id;
80: PetscInt refct;
81: PetscMPIInt tag;
82: PetscFunctionList qlist;
83: PetscObjectList olist;
84: char *class_name; /* for example, "Vec" */
85: char *description;
86: char *mansec;
87: char *type_name; /* this is the subclass, for example VECSEQ which equals "seq" */
88: PetscObject parent;
89: PetscObjectId parentid;
90: char* name;
91: char *prefix;
92: PetscInt tablevel;
93: void *cpp;
94: PetscObjectState state;
95: PetscInt int_idmax, intstar_idmax;
96: PetscObjectState *intcomposedstate,*intstarcomposedstate;
97: PetscInt *intcomposeddata, **intstarcomposeddata;
98: PetscInt real_idmax, realstar_idmax;
99: PetscObjectState *realcomposedstate,*realstarcomposedstate;
100: PetscReal *realcomposeddata, **realstarcomposeddata;
101: PetscInt scalar_idmax, scalarstar_idmax;
102: PetscObjectState *scalarcomposedstate,*scalarstarcomposedstate;
103: PetscScalar *scalarcomposeddata, **scalarstarcomposeddata;
104: void (**fortran_func_pointers)(void); /* used by Fortran interface functions to stash user provided Fortran functions */
105: PetscInt num_fortran_func_pointers; /* number of Fortran function pointers allocated */
106: PetscFortranCallback *fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
107: PetscInt num_fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
108: void *python_context;
109: PetscErrorCode (*python_destroy)(void*);
111: PetscInt noptionhandler;
112: PetscErrorCode (*optionhandler[PETSC_MAX_OPTIONS_HANDLER])(PetscOptionItems*,PetscObject,void*);
113: PetscErrorCode (*optiondestroy[PETSC_MAX_OPTIONS_HANDLER])(PetscObject,void*);
114: void *optionctx[PETSC_MAX_OPTIONS_HANDLER];
115: PetscBool optionsprinted;
116: #if defined(PETSC_HAVE_SAWS)
117: PetscBool amsmem; /* if PETSC_TRUE then this object is registered with SAWs and visible to clients */
118: PetscBool amspublishblock; /* if PETSC_TRUE and publishing objects then will block at PetscObjectSAWsBlock() */
119: #endif
120: PetscOptions options; /* options database used, NULL means default */
121: PetscBool donotPetscObjectPrintClassNamePrefixType;
122: } _p_PetscObject;
124: #define PETSCHEADER(ObjectOps) \
125: _p_PetscObject hdr; \
126: ObjectOps ops[1]
128: #define PETSCFREEDHEADER -1
130: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectDestroyFunction)(PetscObject*); /* force cast in next macro to NEVER use extern "C" style */
131: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectViewFunction)(PetscObject,PetscViewer);
133: /*@C
134: PetscHeaderCreate - Creates a PETSc object of a particular class
136: Input Parameters:
137: + classid - the classid associated with this object (for example VEC_CLASSID)
138: . class_name - string name of class; should be static (for example "Vec")
139: . descr - string containing short description; should be static (for example "Vector")
140: . mansec - string indicating section in manual pages; should be static (for example "Vec")
141: . comm - the MPI Communicator
142: . destroy - the destroy routine for this object (for example VecDestroy())
143: - view - the view routine for this object (for example VecView())
145: Output Parameter:
146: . h - the newly created object
148: Level: developer
150: .seealso: PetscHeaderDestroy(), PetscClassIdRegister()
152: @*/
153: #define PetscHeaderCreate(h,classid,class_name,descr,mansec,comm,destroy,view) \
154: (PetscNew(&(h)) || \
155: PetscHeaderCreate_Private((PetscObject)(h),classid,class_name,descr,mansec,comm,(PetscObjectDestroyFunction)(destroy),(PetscObjectViewFunction)(view)) || \
156: PetscLogObjectCreate(h) || \
157: PetscLogObjectMemory((PetscObject)(h),sizeof(*(h))))
159: PETSC_EXTERN PetscErrorCode PetscComposedQuantitiesDestroy(PetscObject obj);
160: PETSC_EXTERN PetscErrorCode PetscHeaderCreate_Private(PetscObject,PetscClassId,const char[],const char[],const char[],MPI_Comm,PetscObjectDestroyFunction,PetscObjectViewFunction);
162: /*@C
163: PetscHeaderDestroy - Final step in destroying a PetscObject
165: Input Parameters:
166: . h - the header created with PetscHeaderCreate()
168: Level: developer
170: .seealso: PetscHeaderCreate()
171: @*/
172: #define PetscHeaderDestroy(h) (PetscHeaderDestroy_Private((PetscObject)(*(h))) || PetscFree(*(h)))
174: PETSC_EXTERN PetscErrorCode PetscHeaderDestroy_Private(PetscObject);
175: PETSC_EXTERN PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject,PetscObject);
176: PETSC_EXTERN PetscErrorCode PetscObjectSetFortranCallback(PetscObject,PetscFortranCallbackType,PetscFortranCallbackId*,void(*)(void),void *ctx);
177: PETSC_EXTERN PetscErrorCode PetscObjectGetFortranCallback(PetscObject,PetscFortranCallbackType,PetscFortranCallbackId,void(**)(void),void **ctx);
179: PETSC_INTERN PetscErrorCode PetscCitationsInitialize(void);
180: PETSC_INTERN PetscErrorCode PetscFreeMPIResources(void);
181: PETSC_INTERN PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions,PetscBool*);
185: /*
186: Macros to test if a PETSc object is valid and if pointers are valid
187: */
188: #if !defined(PETSC_USE_DEBUG)
201: #else
203: /* This check is for subtype methods such as DMDAGetCorners() that do not use the PetscTryMethod() or PetscUseMethod() paradigm */
205: do { \
206: PetscErrorCode _7_ierr; \
207: PetscBool _7_same; \
209: _7_PetscObjectTypeCompare((PetscObject)(h),t,&_7_same);CHKERRQ(_7_ierr); \
210: 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); \
211: } while (0)
214: do { \
215: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg); \
217: if (((PetscObject)(h))->classid != ck) { \
218: if (((PetscObject)(h))->classid == PETSCFREEDHEADER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
219: else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Wrong type of object: Parameter # %d",arg); \
220: } \
221: } while (0)
224: do { \
225: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg); \
227: if (((PetscObject)(h))->classid == PETSCFREEDHEADER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
228: 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); \
229: } while (0)
232: do { \
233: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
235: } while (0)
238: do { \
239: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg);\
241: } while (0)
244: do { \
245: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Null Pointer: Parameter # %d",arg); \
247: } while (0)
250: do { \
251: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Null Pointer: 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 (!(f)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Function Pointer: Parameter # %d",arg); \
270: } while (0)
272: #endif
274: #define PetscSorted(n,idx,sorted) \
275: do { \
276: PetscInt _i_; \
277: (sorted) = PETSC_TRUE; \
278: for (_i_ = 1; _i_ < (n); _i_++) \
279: if ((idx)[_i_] < (idx)[_i_ - 1]) \
280: { (sorted) = PETSC_FALSE; break; } \
281: } while (0)
283: #if !defined(PETSC_USE_DEBUG)
299: #else
301: /*
302: For example, in the dot product between two vectors,
303: both vectors must be either Seq or MPI, not one of each
304: */
306: do { \
307: 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); \
308: } while (0)
309: /*
310: Check type_name
311: */
313: do { \
314: PetscBool _7_match; \
315: PetscErrorCode _7_ierr; \
316: _7_PetscObjectTypeCompare(((PetscObject)(a)),(type),&_7_match);CHKERRQ(_7_ierr); \
317: if (!_7_match) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Object (%s) is not %s",(char*)(((PetscObject)(a))->type_name),type); \
318: } while (0)
321: do { \
322: PetscBool _7_match; \
323: PetscErrorCode _7_ierr; \
324: _7_PetscObjectTypeCompareAny(((PetscObject)(a)),&_7_match,(type1),(type2),"");CHKERRQ(_7_ierr); \
325: 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); \
326: } while (0)
327: /*
328: Use this macro to check if the type is set
329: */
331: do { \
332: 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); \
333: } while (0)
334: /*
335: Sometimes object must live on same communicator to inter-operate
336: */
338: do { \
339: PetscErrorCode _7_ierr; \
340: PetscMPIInt _7_flag; \
341: _7_MPI_Comm_compare(PetscObjectComm((PetscObject)(a)),PetscObjectComm((PetscObject)(b)),&_7_flag);CHKERRMPI(_7_ierr); \
342: 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); \
343: } while (0)
346: do { \
349: } while (0)
352: do { \
353: PetscErrorCode _7_ierr; \
354: PetscScalar b0=(b); \
355: PetscReal b1[5],b2[5]; \
356: if (PetscIsNanScalar(b0)) {b1[4] = 1;} else {b1[4] = 0;}; \
357: b1[0] = -PetscRealPart(b0); b1[1] = PetscRealPart(b0); b1[2] = -PetscImaginaryPart(b0); b1[3] = PetscImaginaryPart(b0); \
358: _7_MPI_Allreduce(b1,b2,5,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)(a)));CHKERRMPI(_7_ierr); \
359: 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); \
360: } while (0)
363: do { \
364: PetscErrorCode _7_ierr; \
365: PetscReal b0=(b),b1[3],b2[3]; \
366: if (PetscIsNanReal(b0)) {b1[2] = 1;} else {b1[2] = 0;}; \
367: b1[0] = -b0; b1[1] = b0; \
368: _7_MPI_Allreduce(b1,b2,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)(a)));CHKERRMPI(_7_ierr); \
369: 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); \
370: } while (0)
373: do { \
374: PetscErrorCode _7_ierr; \
375: PetscInt b0=(b),b1[2],b2[2]; \
376: b1[0] = -b0; b1[1] = b0; \
377: _7_MPIU_Allreduce(b1,b2,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));CHKERRQ(_7_ierr); \
378: if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)(a)),PETSC_ERR_ARG_WRONG,"Int value must be same on all processes, argument # %d",arg); \
379: } while (0)
382: do { \
383: PetscErrorCode _7_ierr; \
384: PetscMPIInt b0=(b),b1[2],b2[2]; \
385: b1[0] = -b0; b1[1] = b0; \
386: _7_MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));CHKERRQ(_7_ierr); \
387: if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)(a)),PETSC_ERR_ARG_WRONG,"PetscMPIInt value must be same on all processes, argument # %d",arg); \
388: } while (0)
391: do { \
392: PetscErrorCode _7_ierr; \
393: PetscMPIInt b0=(PetscMPIInt)(b),b1[2],b2[2]; \
394: b1[0] = -b0; b1[1] = b0; \
395: _7_MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));CHKERRQ(_7_ierr); \
396: if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)(a)),PETSC_ERR_ARG_WRONG,"Bool value must be same on all processes, argument # %d",arg); \
397: } while (0)
400: do { \
401: PetscErrorCode _7_ierr; \
402: PetscMPIInt b0=(PetscMPIInt)(b),b1[2],b2[2]; \
403: b1[0] = -b0; b1[1] = b0; \
404: _7_MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));CHKERRQ(_7_ierr); \
405: if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)(a)),PETSC_ERR_ARG_WRONG,"Enum value must be same on all processes, argument # %d",arg); \
406: } while (0)
409: do { \
410: PetscBool _1_flg; \
411: PetscSorted(n,idx,_1_flg); \
412: if (!_1_flg) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Input array needs to be sorted"); \
413: } while (0)
415: #endif
417: /*
418: PetscTryMethod - Queries an object for a method, if it exists then calls it.
419: These are intended to be used only inside PETSc functions.
421: Level: developer
423: .seealso: PetscUseMethod()
424: */
425: #define PetscTryMethod(obj,A,B,C) \
426: 0; do { PetscErrorCode (*_7_f)B, _7_ierr; \
427: _7_PetscObjectQueryFunction((PetscObject)(obj),A,&_7_f);CHKERRQ(_7_ierr); \
428: if (_7_f) {_7_(*_7_f)C;CHKERRQ(_7_ierr);} \
429: } while (0)
431: /*
432: PetscUseMethod - Queries an object for a method, if it exists then calls it, otherwise generates an error.
433: These are intended to be used only inside PETSc functions.
435: Level: developer
437: .seealso: PetscTryMethod()
438: */
439: #define PetscUseMethod(obj,A,B,C) \
440: 0; do { PetscErrorCode (*_7_f)B, _7_ierr; \
441: _7_PetscObjectQueryFunction((PetscObject)(obj),A,&_7_f);CHKERRQ(_7_ierr); \
442: if (_7_f) {_7_(*_7_f)C;CHKERRQ(_7_ierr);} \
443: else SETERRQ1(PetscObjectComm((PetscObject)(obj)),PETSC_ERR_SUP,"Cannot locate function %s in object",A); \
444: } while (0)
446: /*MC
447: PetscObjectStateIncrease - Increases the state of any PetscObject
449: Synopsis:
450: #include "petsc/private/petscimpl.h"
451: PetscErrorCode PetscObjectStateIncrease(PetscObject obj)
453: Logically Collective
455: Input Parameter:
456: . obj - any PETSc object, for example a Vec, Mat or KSP. This must be
457: cast with a (PetscObject), for example,
458: PetscObjectStateIncrease((PetscObject)mat);
460: Notes:
461: object state is an integer which gets increased every time
462: the object is changed internally. By saving and later querying the object state
463: one can determine whether information about the object is still current.
464: Currently, state is maintained for Vec and Mat objects.
466: This routine is mostly for internal use by PETSc; a developer need only
467: call it after explicit access to an object's internals. Routines such
468: as VecSet() or MatScale() already call this routine. It is also called, as a
469: precaution, in VecRestoreArray(), MatRestoreRow(), MatDenseRestoreArray().
471: This routine is logically collective because state equality comparison needs to be possible without communication.
473: Level: developer
475: seealso: PetscObjectStateGet()
477: M*/
478: #define PetscObjectStateIncrease(obj) ((obj)->state++,0)
480: PETSC_EXTERN PetscErrorCode PetscObjectStateGet(PetscObject,PetscObjectState*);
481: PETSC_EXTERN PetscErrorCode PetscObjectStateSet(PetscObject,PetscObjectState);
482: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataRegister(PetscInt*);
483: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject);
484: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject);
485: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject);
486: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject);
487: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject);
488: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject);
489: PETSC_EXTERN PetscInt PetscObjectComposedDataMax;
490: /*MC
491: PetscObjectComposedDataSetInt - attach integer data to a PetscObject
493: Synopsis:
494: #include "petsc/private/petscimpl.h"
495: PetscErrorCode PetscObjectComposedDataSetInt(PetscObject obj,int id,int data)
497: Not collective
499: Input parameters:
500: + obj - the object to which data is to be attached
501: . id - the identifier for the data
502: - data - the data to be attached
504: Notes
505: The data identifier can best be created through a call to PetscObjectComposedDataRegister()
507: Level: developer
508: M*/
509: #define PetscObjectComposedDataSetInt(obj,id,data) \
510: ((((obj)->int_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseInt(obj)) || \
511: ((obj)->intcomposeddata[id] = data,(obj)->intcomposedstate[id] = (obj)->state, 0))
513: /*MC
514: PetscObjectComposedDataGetInt - retrieve integer data attached to an object
516: Synopsis:
517: #include "petsc/private/petscimpl.h"
518: PetscErrorCode PetscObjectComposedDataGetInt(PetscObject obj,int id,int data,PetscBool flag)
520: Not collective
522: Input parameters:
523: + obj - the object from which data is to be retrieved
524: - id - the identifier for the data
526: Output parameters:
527: + data - the data to be retrieved
528: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
530: The 'data' and 'flag' variables are inlined, so they are not pointers.
532: Level: developer
533: M*/
534: #define PetscObjectComposedDataGetInt(obj,id,data,flag) \
535: ((((obj)->intcomposedstate && ((obj)->intcomposedstate[id] == (obj)->state)) ? \
536: (data = (obj)->intcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
538: /*MC
539: PetscObjectComposedDataSetIntstar - attach integer array data to a PetscObject
541: Synopsis:
542: #include "petsc/private/petscimpl.h"
543: PetscErrorCode PetscObjectComposedDataSetIntstar(PetscObject obj,int id,int *data)
545: Not collective
547: Input parameters:
548: + obj - the object to which data is to be attached
549: . id - the identifier for the data
550: - data - the data to be attached
552: Notes
553: The data identifier can best be determined through a call to
554: PetscObjectComposedDataRegister()
556: Level: developer
557: M*/
558: #define PetscObjectComposedDataSetIntstar(obj,id,data) \
559: ((((obj)->intstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseIntstar(obj)) || \
560: ((obj)->intstarcomposeddata[id] = data,(obj)->intstarcomposedstate[id] = (obj)->state, 0))
562: /*MC
563: PetscObjectComposedDataGetIntstar - retrieve integer array data
564: attached to an object
566: Synopsis:
567: #include "petsc/private/petscimpl.h"
568: PetscErrorCode PetscObjectComposedDataGetIntstar(PetscObject obj,int id,int *data,PetscBool flag)
570: Not collective
572: Input parameters:
573: + obj - the object from which data is to be retrieved
574: - id - the identifier for the data
576: Output parameters:
577: + data - the data to be retrieved
578: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
580: The 'data' and 'flag' variables are inlined, so they are not pointers.
582: Level: developer
583: M*/
584: #define PetscObjectComposedDataGetIntstar(obj,id,data,flag) \
585: ((((obj)->intstarcomposedstate && ((obj)->intstarcomposedstate[id] == (obj)->state)) ? \
586: (data = (obj)->intstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
588: /*MC
589: PetscObjectComposedDataSetReal - attach real data to a PetscObject
591: Synopsis:
592: #include "petsc/private/petscimpl.h"
593: PetscErrorCode PetscObjectComposedDataSetReal(PetscObject obj,int id,PetscReal data)
595: Not collective
597: Input parameters:
598: + obj - the object to which data is to be attached
599: . id - the identifier for the data
600: - data - the data to be attached
602: Notes
603: The data identifier can best be determined through a call to
604: PetscObjectComposedDataRegister()
606: Level: developer
607: M*/
608: #define PetscObjectComposedDataSetReal(obj,id,data) \
609: ((((obj)->real_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseReal(obj)) || \
610: ((obj)->realcomposeddata[id] = data,(obj)->realcomposedstate[id] = (obj)->state, 0))
612: /*MC
613: PetscObjectComposedDataGetReal - retrieve real data attached to an object
615: Synopsis:
616: #include "petsc/private/petscimpl.h"
617: PetscErrorCode PetscObjectComposedDataGetReal(PetscObject obj,int id,PetscReal data,PetscBool flag)
619: Not collective
621: Input parameters:
622: + obj - the object from which data is to be retrieved
623: - id - the identifier for the data
625: Output parameters:
626: + data - the data to be retrieved
627: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
629: The 'data' and 'flag' variables are inlined, so they are not pointers.
631: Level: developer
632: M*/
633: #define PetscObjectComposedDataGetReal(obj,id,data,flag) \
634: ((((obj)->realcomposedstate && ((obj)->realcomposedstate[id] == (obj)->state)) ? \
635: (data = (obj)->realcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
637: /*MC
638: PetscObjectComposedDataSetRealstar - attach real array data to a PetscObject
640: Synopsis:
641: #include "petsc/private/petscimpl.h"
642: PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *data)
644: Not collective
646: Input parameters:
647: + obj - the object to which data is to be attached
648: . id - the identifier for the data
649: - data - the data to be attached
651: Notes
652: The data identifier can best be determined through a call to
653: PetscObjectComposedDataRegister()
655: Level: developer
656: M*/
657: #define PetscObjectComposedDataSetRealstar(obj,id,data) \
658: ((((obj)->realstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseRealstar(obj)) || \
659: ((obj)->realstarcomposeddata[id] = data, (obj)->realstarcomposedstate[id] = (obj)->state, 0))
661: /*MC
662: PetscObjectComposedDataGetRealstar - retrieve real array data
663: attached to an object
665: Synopsis:
666: #include "petsc/private/petscimpl.h"
667: PetscErrorCode PetscObjectComposedDataGetRealstar(PetscObject obj,int id,PetscReal *data,PetscBool flag)
669: Not collective
671: Input parameters:
672: + obj - the object from which data is to be retrieved
673: - id - the identifier for the data
675: Output parameters:
676: + data - the data to be retrieved
677: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
679: The 'data' and 'flag' variables are inlined, so they are not pointers.
681: Level: developer
682: M*/
683: #define PetscObjectComposedDataGetRealstar(obj,id,data,flag) \
684: ((((obj)->realstarcomposedstate && ((obj)->realstarcomposedstate[id] == (obj)->state)) ? \
685: (data = (obj)->realstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
687: /*MC
688: PetscObjectComposedDataSetScalar - attach scalar data to a PetscObject
690: Synopsis:
691: #include "petsc/private/petscimpl.h"
692: PetscErrorCode PetscObjectComposedDataSetScalar(PetscObject obj,int id,PetscScalar data)
694: Not collective
696: Input parameters:
697: + obj - the object to which data is to be attached
698: . id - the identifier for the data
699: - data - the data to be attached
701: Notes
702: The data identifier can best be determined through a call to
703: PetscObjectComposedDataRegister()
705: Level: developer
706: M*/
707: #if defined(PETSC_USE_COMPLEX)
708: #define PetscObjectComposedDataSetScalar(obj,id,data) \
709: ((((obj)->scalar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalar(obj)) || \
710: ((obj)->scalarcomposeddata[id] = data,(obj)->scalarcomposedstate[id] = (obj)->state, 0))
711: #else
712: #define PetscObjectComposedDataSetScalar(obj,id,data) \
713: PetscObjectComposedDataSetReal(obj,id,data)
714: #endif
715: /*MC
716: PetscObjectComposedDataGetScalar - retrieve scalar data attached to an object
718: Synopsis:
719: #include "petsc/private/petscimpl.h"
720: PetscErrorCode PetscObjectComposedDataGetScalar(PetscObject obj,int id,PetscScalar data,PetscBool flag)
722: Not collective
724: Input parameters:
725: + obj - the object from which data is to be retrieved
726: - id - the identifier for the data
728: Output parameters:
729: + data - the data to be retrieved
730: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
732: The 'data' and 'flag' variables are inlined, so they are not pointers.
734: Level: developer
735: M*/
736: #if defined(PETSC_USE_COMPLEX)
737: #define PetscObjectComposedDataGetScalar(obj,id,data,flag) \
738: ((((obj)->scalarcomposedstate && ((obj)->scalarcomposedstate[id] == (obj)->state)) ? \
739: (data = (obj)->scalarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
740: #else
741: #define PetscObjectComposedDataGetScalar(obj,id,data,flag) \
742: PetscObjectComposedDataGetReal(obj,id,data,flag)
743: #endif
745: /*MC
746: PetscObjectComposedDataSetScalarstar - attach scalar array data to a PetscObject
748: Synopsis:
749: #include "petsc/private/petscimpl.h"
750: PetscErrorCode PetscObjectComposedDataSetScalarstar(PetscObject obj,int id,PetscScalar *data)
752: Not collective
754: Input parameters:
755: + obj - the object to which data is to be attached
756: . id - the identifier for the data
757: - data - the data to be attached
759: Notes
760: The data identifier can best be determined through a call to
761: PetscObjectComposedDataRegister()
763: Level: developer
764: M*/
765: #if defined(PETSC_USE_COMPLEX)
766: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
767: ((((obj)->scalarstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalarstar(obj)) || \
768: ((obj)->scalarstarcomposeddata[id] = data,(obj)->scalarstarcomposedstate[id] = (obj)->state, 0))
769: #else
770: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
771: PetscObjectComposedDataSetRealstar(obj,id,data)
772: #endif
773: /*MC
774: PetscObjectComposedDataGetScalarstar - retrieve scalar array data
775: attached to an object
777: Synopsis:
778: #include "petsc/private/petscimpl.h"
779: PetscErrorCode PetscObjectComposedDataGetScalarstar(PetscObject obj,int id,PetscScalar *data,PetscBool flag)
781: Not collective
783: Input parameters:
784: + obj - the object from which data is to be retrieved
785: - id - the identifier for the data
787: Output parameters:
788: + data - the data to be retrieved
789: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
791: The 'data' and 'flag' variables are inlined, so they are not pointers.
793: Level: developer
794: M*/
795: #if defined(PETSC_USE_COMPLEX)
796: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag) \
797: ((((obj)->scalarstarcomposedstate && ((obj)->scalarstarcomposedstate[id] == (obj)->state)) ? \
798: (data = (obj)->scalarstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
799: #else
800: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag) \
801: PetscObjectComposedDataGetRealstar(obj,id,data,flag)
802: #endif
804: PETSC_EXTERN PetscMPIInt Petsc_Counter_keyval;
805: PETSC_EXTERN PetscMPIInt Petsc_InnerComm_keyval;
806: PETSC_EXTERN PetscMPIInt Petsc_OuterComm_keyval;
807: PETSC_EXTERN PetscMPIInt Petsc_Seq_keyval;
808: PETSC_EXTERN PetscMPIInt Petsc_ShmComm_keyval;
810: /*
811: PETSc communicators have this attribute, see
812: PetscCommDuplicate(), PetscCommDestroy(), PetscCommGetNewTag(), PetscObjectGetName()
813: */
814: typedef struct {
815: PetscMPIInt tag; /* next free tag value */
816: PetscInt refcount; /* number of references, communicator can be freed when this reaches 0 */
817: PetscInt namecount; /* used to generate the next name, as in Vec_0, Mat_1, ... */
818: PetscMPIInt *iflags; /* length of comm size, shared by all calls to PetscCommBuildTwoSided_Allreduce/RedScatter on this comm */
819: } PetscCommCounter;
821: typedef enum {STATE_BEGIN, STATE_PENDING, STATE_END} SRState;
823: typedef enum {PETSC_SR_REDUCE_SUM=0,PETSC_SR_REDUCE_MAX=1,PETSC_SR_REDUCE_MIN=2} PetscSRReductionType;
825: typedef struct {
826: MPI_Comm comm;
827: MPI_Request request;
828: PetscBool async;
829: PetscScalar *lvalues; /* this are the reduced values before call to MPI_Allreduce() */
830: PetscScalar *gvalues; /* values after call to MPI_Allreduce() */
831: void **invecs; /* for debugging only, vector/memory used with each op */
832: PetscInt *reducetype; /* is particular value to be summed or maxed? */
833: SRState state; /* are we calling xxxBegin() or xxxEnd()? */
834: PetscInt maxops; /* total amount of space we have for requests */
835: PetscInt numopsbegin; /* number of requests that have been queued in */
836: PetscInt numopsend; /* number of requests that have been gotten by user */
837: } PetscSplitReduction;
839: PETSC_EXTERN PetscErrorCode PetscSplitReductionGet(MPI_Comm,PetscSplitReduction**);
840: PETSC_EXTERN PetscErrorCode PetscSplitReductionEnd(PetscSplitReduction*);
841: PETSC_EXTERN PetscErrorCode PetscSplitReductionExtend(PetscSplitReduction*);
843: #if !defined(PETSC_SKIP_SPINLOCK)
844: #if defined(PETSC_HAVE_THREADSAFETY)
845: # if defined(PETSC_HAVE_CONCURRENCYKIT)
846: #if defined(__cplusplus)
847: /* CK does not have extern "C" protection in their include files */
848: extern "C" {
849: #endif
850: #include <ck_spinlock.h>
851: #if defined(__cplusplus)
852: }
853: #endif
854: typedef ck_spinlock_t PetscSpinlock;
855: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockCreate(PetscSpinlock *ck_spinlock)
856: {
857: ck_spinlock_init(ck_spinlock);
858: return 0;
859: }
860: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockLock(PetscSpinlock *ck_spinlock)
861: {
862: ck_spinlock_lock(ck_spinlock);
863: return 0;
864: }
865: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *ck_spinlock)
866: {
867: ck_spinlock_unlock(ck_spinlock);
868: return 0;
869: }
870: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *ck_spinlock)
871: {
872: return 0;
873: }
874: # elif defined(PETSC_HAVE_OPENMP)
876: #include <omp.h>
877: typedef omp_lock_t PetscSpinlock;
878: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockCreate(PetscSpinlock *omp_lock)
879: {
880: omp_init_lock(omp_lock);
881: return 0;
882: }
883: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockLock(PetscSpinlock *omp_lock)
884: {
885: omp_set_lock(omp_lock);
886: return 0;
887: }
888: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *omp_lock)
889: {
890: omp_unset_lock(omp_lock);
891: return 0;
892: }
893: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *omp_lock)
894: {
895: omp_destroy_lock(omp_lock);
896: return 0;
897: }
898: #else
899: Thread safety requires either --with-openmp or --download-concurrencykit
900: #endif
902: #else
903: typedef int PetscSpinlock;
904: #define PetscSpinlockCreate(a) 0
905: #define PetscSpinlockLock(a) 0
906: #define PetscSpinlockUnlock(a) 0
907: #define PetscSpinlockDestroy(a) 0
908: #endif
910: #if defined(PETSC_HAVE_THREADSAFETY)
911: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockOpen;
912: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStdout;
913: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStderr;
914: PETSC_INTERN PetscSpinlock PetscCommSpinLock;
915: #endif
916: #endif
918: PETSC_EXTERN PetscLogEvent PETSC_Barrier;
919: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSided;
920: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSidedF;
921: PETSC_EXTERN PetscBool use_gpu_aware_mpi;
923: #if defined(PETSC_HAVE_ADIOS)
924: PETSC_EXTERN int64_t Petsc_adios_group;
925: #endif
927: #if defined(PETSC_HAVE_KOKKOS)
928: PETSC_INTERN PetscBool PetscBeganKokkos;
929: PETSC_EXTERN PetscBool PetscKokkosInitialized;
930: PETSC_INTERN PetscErrorCode PetscKokkosIsInitialized_Private(PetscBool*);
931: PETSC_INTERN PetscErrorCode PetscKokkosFinalize_Private(void);
932: #endif
934: #if defined(PETSC_HAVE_CUDA)
935: PETSC_EXTERN PetscBool PetscCUDAInitialized; /* Is CUDA initialized? One can use this flag to guard CUDA calls. */
936: PETSC_EXTERN PetscBool PetscMPICUDAAwarenessCheck(void);
937: #endif
939: #if defined(PETSC_HAVE_HIP)
940: PETSC_EXTERN PetscBool PetscHIPInitialized;
941: PETSC_EXTERN PetscBool PetscMPIHIPAwarenessCheck(void);
942: #endif
944: PETSC_EXTERN PetscBool PetscCreatedGpuObjects;
945: #endif /* PETSCIMPL_H */