Actual source code: petscimpl.h
petsc-3.12.0 2019-09-29
2: /*
3: Defines the basic header of all PETSc objects.
4: */
6: #if !defined(PETSCIMPL_H)
7: #define PETSCIMPL_H
8: #include <petscsys.h>
10: /* These are used internally by PETSc ASCII IO routines*/
11: #include <stdarg.h>
12: PETSC_EXTERN PetscErrorCode PetscVFPrintfDefault(FILE*,const char[],va_list);
14: #if defined(PETSC_HAVE_CLOSURE)
15: PETSC_EXTERN PetscErrorCode PetscVFPrintfSetClosure(int (^)(const char*));
16: #endif
19: #if defined(PETSC_HAVE_CUDA)
20: #include <cuda.h>
21: #include <cublas_v2.h>
22: #endif
24: /*
25: All major PETSc data structures have a common core; this is defined
26: below by PETSCHEADER.
28: PetscHeaderCreate() should be used whenever creating a PETSc structure.
29: */
31: /*
32: PetscOps: structure of core operations that all PETSc objects support.
34: getcomm() - Gets the object's communicator.
35: view() - Is the routine for viewing the entire PETSc object; for
36: example, MatView() is the general matrix viewing routine.
37: This is used by PetscObjectView((PetscObject)obj) to allow
38: viewing any PETSc object.
39: destroy() - Is the routine for destroying the entire PETSc object;
40: for example,MatDestroy() is the general matrix
41: destruction routine.
42: This is used by PetscObjectDestroy((PetscObject*)&obj) to allow
43: destroying any PETSc object.
44: compose() - Associates a PETSc object with another PETSc object with a name
45: query() - Returns a different PETSc object that has been associated
46: with the first object using a name.
47: composefunction() - Attaches an a function to a PETSc object with a name.
48: queryfunction() - Requests a registered function that has been attached to a PETSc object.
49: */
51: typedef struct {
52: PetscErrorCode (*getcomm)(PetscObject,MPI_Comm *);
53: PetscErrorCode (*view)(PetscObject,PetscViewer);
54: PetscErrorCode (*destroy)(PetscObject*);
55: PetscErrorCode (*compose)(PetscObject,const char[],PetscObject);
56: PetscErrorCode (*query)(PetscObject,const char[],PetscObject *);
57: PetscErrorCode (*composefunction)(PetscObject,const char[],void (*)(void));
58: PetscErrorCode (*queryfunction)(PetscObject,const char[],void (**)(void));
59: } PetscOps;
61: typedef enum {PETSC_FORTRAN_CALLBACK_CLASS,PETSC_FORTRAN_CALLBACK_SUBTYPE,PETSC_FORTRAN_CALLBACK_MAXTYPE} PetscFortranCallbackType;
62: typedef int PetscFortranCallbackId;
63: #define PETSC_SMALLEST_FORTRAN_CALLBACK ((PetscFortranCallbackId)1000)
64: PETSC_EXTERN PetscErrorCode PetscFortranCallbackRegister(PetscClassId,const char*,PetscFortranCallbackId*);
65: PETSC_EXTERN PetscErrorCode PetscFortranCallbackGetSizes(PetscClassId,PetscInt*,PetscInt*);
67: typedef struct {
68: void (*func)(void);
69: void *ctx;
70: } PetscFortranCallback;
72: /*
73: All PETSc objects begin with the fields defined in PETSCHEADER.
74: The PetscObject is a way of examining these fields regardless of
75: the specific object. In C++ this could be a base abstract class
76: from which all objects are derived.
77: */
78: #define PETSC_MAX_OPTIONS_HANDLER 5
79: typedef struct _p_PetscObject {
80: PetscClassId classid;
81: PetscOps bops[1];
82: MPI_Comm comm;
83: PetscInt type;
84: PetscLogDouble flops,time,mem,memchildren;
85: PetscObjectId id;
86: PetscInt refct;
87: PetscMPIInt tag;
88: PetscFunctionList qlist;
89: PetscObjectList olist;
90: char *class_name; /* for example, "Vec" */
91: char *description;
92: char *mansec;
93: char *type_name; /* this is the subclass, for example VECSEQ which equals "seq" */
94: PetscObject parent;
95: PetscObjectId parentid;
96: char* name;
97: char *prefix;
98: PetscInt tablevel;
99: void *cpp;
100: PetscObjectState state;
101: PetscInt int_idmax, intstar_idmax;
102: PetscObjectState *intcomposedstate,*intstarcomposedstate;
103: PetscInt *intcomposeddata, **intstarcomposeddata;
104: PetscInt real_idmax, realstar_idmax;
105: PetscObjectState *realcomposedstate,*realstarcomposedstate;
106: PetscReal *realcomposeddata, **realstarcomposeddata;
107: PetscInt scalar_idmax, scalarstar_idmax;
108: PetscObjectState *scalarcomposedstate,*scalarstarcomposedstate;
109: PetscScalar *scalarcomposeddata, **scalarstarcomposeddata;
110: void (**fortran_func_pointers)(void); /* used by Fortran interface functions to stash user provided Fortran functions */
111: PetscInt num_fortran_func_pointers; /* number of Fortran function pointers allocated */
112: PetscFortranCallback *fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
113: PetscInt num_fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
114: void *python_context;
115: PetscErrorCode (*python_destroy)(void*);
117: PetscInt noptionhandler;
118: PetscErrorCode (*optionhandler[PETSC_MAX_OPTIONS_HANDLER])(PetscOptionItems*,PetscObject,void*);
119: PetscErrorCode (*optiondestroy[PETSC_MAX_OPTIONS_HANDLER])(PetscObject,void*);
120: void *optionctx[PETSC_MAX_OPTIONS_HANDLER];
121: PetscBool optionsprinted;
122: #if defined(PETSC_HAVE_SAWS)
123: PetscBool amsmem; /* if PETSC_TRUE then this object is registered with SAWs and visible to clients */
124: PetscBool amspublishblock; /* if PETSC_TRUE and publishing objects then will block at PetscObjectSAWsBlock() */
125: #endif
126: PetscOptions options; /* options database used, NULL means default */
127: PetscBool donotPetscObjectPrintClassNamePrefixType;
128: } _p_PetscObject;
130: #define PETSCHEADER(ObjectOps) \
131: _p_PetscObject hdr; \
132: ObjectOps ops[1]
134: #define PETSCFREEDHEADER -1
136: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectDestroyFunction)(PetscObject*); /* force cast in next macro to NEVER use extern "C" style */
137: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectViewFunction)(PetscObject,PetscViewer);
139: /*@C
140: PetscHeaderCreate - Creates a PETSc object of a particular class
142: Input Parameters:
143: + classid - the classid associated with this object (for example VEC_CLASSID)
144: . class_name - string name of class; should be static (for example "Vec")
145: . descr - string containing short description; should be static (for example "Vector")
146: . mansec - string indicating section in manual pages; should be static (for example "Vec")
147: . comm - the MPI Communicator
148: . destroy - the destroy routine for this object (for example VecDestroy())
149: - view - the view routine for this object (for example VecView())
151: Output Parameter:
152: . h - the newly created object
154: Level: developer
156: .seealso: PetscHeaderDestroy(), PetscClassIdRegister()
158: @*/
159: #define PetscHeaderCreate(h,classid,class_name,descr,mansec,comm,destroy,view) \
160: (PetscNew(&(h)) || \
161: PetscHeaderCreate_Private((PetscObject)h,classid,class_name,descr,mansec,comm,(PetscObjectDestroyFunction)destroy,(PetscObjectViewFunction)view) || \
162: PetscLogObjectCreate(h) || \
163: PetscLogObjectMemory((PetscObject)h,sizeof(*(h))))
165: PETSC_EXTERN PetscErrorCode PetscComposedQuantitiesDestroy(PetscObject obj);
166: PETSC_EXTERN PetscErrorCode PetscHeaderCreate_Private(PetscObject,PetscClassId,const char[],const char[],const char[],MPI_Comm,PetscObjectDestroyFunction,PetscObjectViewFunction);
168: /*@C
169: PetscHeaderDestroy - Final step in destroying a PetscObject
171: Input Parameters:
172: . h - the header created with PetscHeaderCreate()
174: Level: developer
176: .seealso: PetscHeaderCreate()
177: @*/
178: #define PetscHeaderDestroy(h) (PetscHeaderDestroy_Private((PetscObject)(*h)) || PetscFree(*h))
180: PETSC_EXTERN PetscErrorCode PetscHeaderDestroy_Private(PetscObject);
181: PETSC_EXTERN PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject,PetscObject);
182: PETSC_EXTERN PetscErrorCode PetscObjectSetFortranCallback(PetscObject,PetscFortranCallbackType,PetscFortranCallbackId*,void(*)(void),void *ctx);
183: PETSC_EXTERN PetscErrorCode PetscObjectGetFortranCallback(PetscObject,PetscFortranCallbackType,PetscFortranCallbackId,void(**)(void),void **ctx);
185: PETSC_INTERN PetscErrorCode PetscCitationsInitialize(void);
186: PETSC_INTERN PetscErrorCode PetscFreeMPIResources(void);
192: /*
193: Macros to test if a PETSc object is valid and if pointers are valid
194: */
195: #if !defined(PETSC_USE_DEBUG)
208: #else
210: /* This check is for subtype methods such as DMDAGetCorners() that do not use the PetscTryMethod() or PetscUseMethod() paradigm */
212: do { \
213: PetscErrorCode _7_ierr; \
214: PetscBool _7_same; \
216: _7_PetscObjectTypeCompare((PetscObject)h,t,&_7_same);CHKERRQ(_7_ierr); \
217: if (!_7_same) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Wrong subtype object:Parameter # %d must have implementation %s it is %s",arg,t,((PetscObject)h)->type_name); \
218: } while (0)
221: do { \
222: if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg); \
224: if (((PetscObject)(h))->classid != ck) { \
225: if (((PetscObject)(h))->classid == PETSCFREEDHEADER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
226: else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Wrong type of object: Parameter # %d",arg); \
227: } \
228: } while (0)
231: do { \
232: if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg); \
234: if (((PetscObject)(h))->classid == PETSCFREEDHEADER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
235: else if (((PetscObject)(h))->classid < PETSC_SMALLEST_CLASSID || ((PetscObject)(h))->classid > PETSC_LARGEST_CLASSID) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Invalid type of object: Parameter # %d",arg); \
236: } while (0)
239: do { \
240: if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
242: } while (0)
245: do { \
246: if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg);\
248: } while (0)
251: do { \
252: if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Null Pointer: Parameter # %d",arg); \
254: } while (0)
257: do { \
258: if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Null Pointer: Parameter # %d",arg); \
260: } while (0)
263: do { \
264: if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
266: } while (0)
269: do { \
270: if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
272: } while (0)
275: do { \
276: if (!f) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Function Pointer: Parameter # %d",arg); \
277: } while (0)
279: #endif
281: #if !defined(PETSC_USE_DEBUG)
296: #else
298: /*
299: For example, in the dot product between two vectors,
300: both vectors must be either Seq or MPI, not one of each
301: */
303: do { \
304: if (((PetscObject)a)->type != ((PetscObject)b)->type) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMETYPE,"Objects not of same type: Argument # %d and %d",arga,argb); \
305: } while (0)
306: /*
307: Check type_name
308: */
310: do { \
311: PetscBool _7_match; \
312: PetscErrorCode _7_ierr; \
313: _7_PetscObjectTypeCompare(((PetscObject)a),(type),&_7_match);CHKERRQ(_7_ierr); \
314: if (!_7_match) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Object (%s) is not %s",(char*)(((PetscObject)a)->type_name),type); \
315: } while (0)
318: do { \
319: PetscBool _7_match; \
320: PetscErrorCode _7_ierr; \
321: _7_PetscObjectTypeCompareAny(((PetscObject)a),&_7_match,(type1),(type2),"");CHKERRQ(_7_ierr); \
322: if (!_7_match) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Object (%s) is not %s or %s",(char*)(((PetscObject)a)->type_name),type1,type2); \
323: } while (0)
324: /*
325: Use this macro to check if the type is set
326: */
328: do { \
329: if (!((PetscObject)a)->type_name) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"%s object's type is not set: Argument # %d",((PetscObject)a)->class_name,arg); \
330: } while (0)
331: /*
332: Sometimes object must live on same communicator to inter-operate
333: */
335: do { \
336: PetscErrorCode _7_ierr; \
337: PetscMPIInt _7_flag; \
338: _7_MPI_Comm_compare(PetscObjectComm((PetscObject)a),PetscObjectComm((PetscObject)b),&_7_flag);CHKERRQ(_7_ierr); \
339: if (_7_flag != MPI_CONGRUENT && _7_flag != MPI_IDENT) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"Different communicators in the two objects: Argument # %d and %d flag %d",arga,argb,_7_flag); \
340: } while (0)
343: do { \
346: } while (0)
349: do { \
350: PetscErrorCode _7_ierr; \
351: PetscReal b1[5],b2[5]; \
352: if (PetscIsNanScalar(b)) {b1[4] = 1;} else {b1[4] = 0;}; \
353: b1[0] = -PetscRealPart(b); b1[1] = PetscRealPart(b); b1[2] = -PetscImaginaryPart(b); b1[3] = PetscImaginaryPart(b); \
354: _7_MPI_Allreduce(b1,b2,5,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
355: if (!(b2[4] > 0) && !(PetscEqualReal(-b2[0],b2[1]) && PetscEqualReal(-b2[2],b2[3]))) SETERRQ1(PetscObjectComm((PetscObject)a),PETSC_ERR_ARG_WRONG,"Scalar value must be same on all processes, argument # %d",c); \
356: } while (0)
359: do { \
360: PetscErrorCode _7_ierr; \
361: PetscReal b1[3],b2[3]; \
362: if (PetscIsNanReal(b)) {b1[2] = 1;} else {b1[2] = 0;}; \
363: b1[0] = -b; b1[1] = b; \
364: _7_MPI_Allreduce(b1,b2,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
365: if (!(b2[2] > 0) && !PetscEqualReal(-b2[0],b2[1])) SETERRQ1(PetscObjectComm((PetscObject)a),PETSC_ERR_ARG_WRONG,"Real value must be same on all processes, argument # %d",c); \
366: } while (0)
369: do { \
370: PetscErrorCode _7_ierr; \
371: PetscInt b1[2],b2[2]; \
372: b1[0] = -b; b1[1] = b; \
373: _7_MPIU_Allreduce(b1,b2,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
374: if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)a),PETSC_ERR_ARG_WRONG,"Int value must be same on all processes, argument # %d",c); \
375: } while (0)
380: do { \
381: PetscErrorCode _7_ierr; \
382: PetscMPIInt b1[2],b2[2]; \
383: b1[0] = -(PetscMPIInt)b; b1[1] = (PetscMPIInt)b; \
384: _7_MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
385: if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)a),PETSC_ERR_ARG_WRONG,"Bool value must be same on all processes, argument # %d",c); \
386: } while (0)
389: do { \
390: PetscErrorCode _7_ierr; \
391: PetscMPIInt b1[2],b2[2]; \
392: b1[0] = -(PetscMPIInt)b; b1[1] = (PetscMPIInt)b; \
393: _7_MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
394: if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)a),PETSC_ERR_ARG_WRONG,"Enum value must be same on all processes, argument # %d",c); \
395: } while (0)
397: #endif
399: /*
400: PetscTryMethod - Queries an object for a method, if it exists then calls it.
401: These are intended to be used only inside PETSc functions.
403: Level: developer
405: .seealso: PetscUseMethod()
406: */
407: #define PetscTryMethod(obj,A,B,C) \
408: 0; do { PetscErrorCode (*_7_f)B, _7_ierr; \
409: _7_PetscObjectQueryFunction((PetscObject)(obj),A,&_7_f);CHKERRQ(_7_ierr); \
410: if (_7_f) {_7_(*_7_f)C;CHKERRQ(_7_ierr);} \
411: } while(0)
413: /*
414: PetscUseMethod - Queries an object for a method, if it exists then calls it, otherwise generates an error.
415: These are intended to be used only inside PETSc functions.
417: Level: developer
419: .seealso: PetscTryMethod()
420: */
421: #define PetscUseMethod(obj,A,B,C) \
422: 0; do { PetscErrorCode (*_7_f)B, _7_ierr; \
423: _7_PetscObjectQueryFunction((PetscObject)(obj),A,&_7_f);CHKERRQ(_7_ierr); \
424: if (_7_f) {_7_(*_7_f)C;CHKERRQ(_7_ierr);} \
425: else SETERRQ1(PetscObjectComm((PetscObject)(obj)),PETSC_ERR_SUP,"Cannot locate function %s in object",A); \
426: } while(0)
428: /*MC
429: PetscObjectStateIncrease - Increases the state of any PetscObject
431: Synopsis:
432: #include "petsc/private/petscimpl.h"
433: PetscErrorCode PetscObjectStateIncrease(PetscObject obj)
435: Logically Collective
437: Input Parameter:
438: . obj - any PETSc object, for example a Vec, Mat or KSP. This must be
439: cast with a (PetscObject), for example,
440: PetscObjectStateIncrease((PetscObject)mat);
442: Notes:
443: object state is an integer which gets increased every time
444: the object is changed internally. By saving and later querying the object state
445: one can determine whether information about the object is still current.
446: Currently, state is maintained for Vec and Mat objects.
448: This routine is mostly for internal use by PETSc; a developer need only
449: call it after explicit access to an object's internals. Routines such
450: as VecSet() or MatScale() already call this routine. It is also called, as a
451: precaution, in VecRestoreArray(), MatRestoreRow(), MatDenseRestoreArray().
453: This routine is logically collective because state equality comparison needs to be possible without communication.
455: Level: developer
457: seealso: PetscObjectStateGet()
459: M*/
460: #define PetscObjectStateIncrease(obj) ((obj)->state++,0)
462: PETSC_EXTERN PetscErrorCode PetscObjectStateGet(PetscObject,PetscObjectState*);
463: PETSC_EXTERN PetscErrorCode PetscObjectStateSet(PetscObject,PetscObjectState);
464: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataRegister(PetscInt*);
465: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject);
466: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject);
467: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject);
468: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject);
469: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject);
470: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject);
471: PETSC_EXTERN PetscInt PetscObjectComposedDataMax;
472: /*MC
473: PetscObjectComposedDataSetInt - attach integer data to a PetscObject
475: Synopsis:
476: #include "petsc/private/petscimpl.h"
477: PetscErrorCode PetscObjectComposedDataSetInt(PetscObject obj,int id,int data)
479: Not collective
481: Input parameters:
482: + obj - the object to which data is to be attached
483: . id - the identifier for the data
484: - data - the data to be attached
486: Notes
487: The data identifier can best be created through a call to PetscObjectComposedDataRegister()
489: Level: developer
490: M*/
491: #define PetscObjectComposedDataSetInt(obj,id,data) \
492: ((((obj)->int_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseInt(obj)) || \
493: ((obj)->intcomposeddata[id] = data,(obj)->intcomposedstate[id] = (obj)->state, 0))
495: /*MC
496: PetscObjectComposedDataGetInt - retrieve integer data attached to an object
498: Synopsis:
499: #include "petsc/private/petscimpl.h"
500: PetscErrorCode PetscObjectComposedDataGetInt(PetscObject obj,int id,int data,PetscBool flag)
502: Not collective
504: Input parameters:
505: + obj - the object from which data is to be retrieved
506: - id - the identifier for the data
508: Output parameters
509: + data - the data to be retrieved
510: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
512: The 'data' and 'flag' variables are inlined, so they are not pointers.
514: Level: developer
515: M*/
516: #define PetscObjectComposedDataGetInt(obj,id,data,flag) \
517: ((((obj)->intcomposedstate && ((obj)->intcomposedstate[id] == (obj)->state)) ? \
518: (data = (obj)->intcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
520: /*MC
521: PetscObjectComposedDataSetIntstar - attach integer array data to a PetscObject
523: Synopsis:
524: #include "petsc/private/petscimpl.h"
525: PetscErrorCode PetscObjectComposedDataSetIntstar(PetscObject obj,int id,int *data)
527: Not collective
529: Input parameters:
530: + obj - the object to which data is to be attached
531: . id - the identifier for the data
532: - data - the data to be attached
534: Notes
535: The data identifier can best be determined through a call to
536: PetscObjectComposedDataRegister()
538: Level: developer
539: M*/
540: #define PetscObjectComposedDataSetIntstar(obj,id,data) \
541: ((((obj)->intstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseIntstar(obj)) || \
542: ((obj)->intstarcomposeddata[id] = data,(obj)->intstarcomposedstate[id] = (obj)->state, 0))
544: /*MC
545: PetscObjectComposedDataGetIntstar - retrieve integer array data
546: attached to an object
548: Synopsis:
549: #include "petsc/private/petscimpl.h"
550: PetscErrorCode PetscObjectComposedDataGetIntstar(PetscObject obj,int id,int *data,PetscBool flag)
552: Not collective
554: Input parameters:
555: + obj - the object from which data is to be retrieved
556: - id - the identifier for the data
558: Output parameters
559: + data - the data to be retrieved
560: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
562: The 'data' and 'flag' variables are inlined, so they are not pointers.
564: Level: developer
565: M*/
566: #define PetscObjectComposedDataGetIntstar(obj,id,data,flag) \
567: ((((obj)->intstarcomposedstate && ((obj)->intstarcomposedstate[id] == (obj)->state)) ? \
568: (data = (obj)->intstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
570: /*MC
571: PetscObjectComposedDataSetReal - attach real data to a PetscObject
573: Synopsis:
574: #include "petsc/private/petscimpl.h"
575: PetscErrorCode PetscObjectComposedDataSetReal(PetscObject obj,int id,PetscReal data)
577: Not collective
579: Input parameters:
580: + obj - the object to which data is to be attached
581: . id - the identifier for the data
582: - data - the data to be attached
584: Notes
585: The data identifier can best be determined through a call to
586: PetscObjectComposedDataRegister()
588: Level: developer
589: M*/
590: #define PetscObjectComposedDataSetReal(obj,id,data) \
591: ((((obj)->real_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseReal(obj)) || \
592: ((obj)->realcomposeddata[id] = data,(obj)->realcomposedstate[id] = (obj)->state, 0))
594: /*MC
595: PetscObjectComposedDataGetReal - retrieve real data attached to an object
597: Synopsis:
598: #include "petsc/private/petscimpl.h"
599: PetscErrorCode PetscObjectComposedDataGetReal(PetscObject obj,int id,PetscReal data,PetscBool flag)
601: Not collective
603: Input parameters:
604: + obj - the object from which data is to be retrieved
605: - id - the identifier for the data
607: Output parameters
608: + data - the data to be retrieved
609: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
611: The 'data' and 'flag' variables are inlined, so they are not pointers.
613: Level: developer
614: M*/
615: #define PetscObjectComposedDataGetReal(obj,id,data,flag) \
616: ((((obj)->realcomposedstate && ((obj)->realcomposedstate[id] == (obj)->state)) ? \
617: (data = (obj)->realcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
619: /*MC
620: PetscObjectComposedDataSetRealstar - attach real array data to a PetscObject
622: Synopsis:
623: #include "petsc/private/petscimpl.h"
624: PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *data)
626: Not collective
628: Input parameters:
629: + obj - the object to which data is to be attached
630: . id - the identifier for the data
631: - data - the data to be attached
633: Notes
634: The data identifier can best be determined through a call to
635: PetscObjectComposedDataRegister()
637: Level: developer
638: M*/
639: #define PetscObjectComposedDataSetRealstar(obj,id,data) \
640: ((((obj)->realstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseRealstar(obj)) || \
641: ((obj)->realstarcomposeddata[id] = data, (obj)->realstarcomposedstate[id] = (obj)->state, 0))
643: /*MC
644: PetscObjectComposedDataGetRealstar - retrieve real array data
645: attached to an object
647: Synopsis:
648: #include "petsc/private/petscimpl.h"
649: PetscErrorCode PetscObjectComposedDataGetRealstar(PetscObject obj,int id,PetscReal *data,PetscBool flag)
651: Not collective
653: Input parameters:
654: + obj - the object from which data is to be retrieved
655: - id - the identifier for the data
657: Output parameters
658: + data - the data to be retrieved
659: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
661: The 'data' and 'flag' variables are inlined, so they are not pointers.
663: Level: developer
664: M*/
665: #define PetscObjectComposedDataGetRealstar(obj,id,data,flag) \
666: ((((obj)->realstarcomposedstate && ((obj)->realstarcomposedstate[id] == (obj)->state)) ? \
667: (data = (obj)->realstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
669: /*MC
670: PetscObjectComposedDataSetScalar - attach scalar data to a PetscObject
672: Synopsis:
673: #include "petsc/private/petscimpl.h"
674: PetscErrorCode PetscObjectComposedDataSetScalar(PetscObject obj,int id,PetscScalar data)
676: Not collective
678: Input parameters:
679: + obj - the object to which data is to be attached
680: . id - the identifier for the data
681: - data - the data to be attached
683: Notes
684: The data identifier can best be determined through a call to
685: PetscObjectComposedDataRegister()
687: Level: developer
688: M*/
689: #if defined(PETSC_USE_COMPLEX)
690: #define PetscObjectComposedDataSetScalar(obj,id,data) \
691: ((((obj)->scalar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalar(obj)) || \
692: ((obj)->scalarcomposeddata[id] = data,(obj)->scalarcomposedstate[id] = (obj)->state, 0))
693: #else
694: #define PetscObjectComposedDataSetScalar(obj,id,data) \
695: PetscObjectComposedDataSetReal(obj,id,data)
696: #endif
697: /*MC
698: PetscObjectComposedDataGetScalar - retrieve scalar data attached to an object
700: Synopsis:
701: #include "petsc/private/petscimpl.h"
702: PetscErrorCode PetscObjectComposedDataGetScalar(PetscObject obj,int id,PetscScalar data,PetscBool flag)
704: Not collective
706: Input parameters:
707: + obj - the object from which data is to be retrieved
708: - id - the identifier for the data
710: Output parameters
711: + data - the data to be retrieved
712: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
714: The 'data' and 'flag' variables are inlined, so they are not pointers.
716: Level: developer
717: M*/
718: #if defined(PETSC_USE_COMPLEX)
719: #define PetscObjectComposedDataGetScalar(obj,id,data,flag) \
720: ((((obj)->scalarcomposedstate && ((obj)->scalarcomposedstate[id] == (obj)->state) ) ? \
721: (data = (obj)->scalarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
722: #else
723: #define PetscObjectComposedDataGetScalar(obj,id,data,flag) \
724: PetscObjectComposedDataGetReal(obj,id,data,flag)
725: #endif
727: /*MC
728: PetscObjectComposedDataSetScalarstar - attach scalar array data to a PetscObject
730: Synopsis:
731: #include "petsc/private/petscimpl.h"
732: PetscErrorCode PetscObjectComposedDataSetScalarstar(PetscObject obj,int id,PetscScalar *data)
734: Not collective
736: Input parameters:
737: + obj - the object to which data is to be attached
738: . id - the identifier for the data
739: - data - the data to be attached
741: Notes
742: The data identifier can best be determined through a call to
743: PetscObjectComposedDataRegister()
745: Level: developer
746: M*/
747: #if defined(PETSC_USE_COMPLEX)
748: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
749: ((((obj)->scalarstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalarstar(obj)) || \
750: ((obj)->scalarstarcomposeddata[id] = data,(obj)->scalarstarcomposedstate[id] = (obj)->state, 0))
751: #else
752: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
753: PetscObjectComposedDataSetRealstar(obj,id,data)
754: #endif
755: /*MC
756: PetscObjectComposedDataGetScalarstar - retrieve scalar array data
757: attached to an object
759: Synopsis:
760: #include "petsc/private/petscimpl.h"
761: PetscErrorCode PetscObjectComposedDataGetScalarstar(PetscObject obj,int id,PetscScalar *data,PetscBool flag)
763: Not collective
765: Input parameters:
766: + obj - the object from which data is to be retrieved
767: - id - the identifier for the data
769: Output parameters
770: + data - the data to be retrieved
771: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
773: The 'data' and 'flag' variables are inlined, so they are not pointers.
775: Level: developer
776: M*/
777: #if defined(PETSC_USE_COMPLEX)
778: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag) \
779: ((((obj)->scalarstarcomposedstate && ((obj)->scalarstarcomposedstate[id] == (obj)->state)) ? \
780: (data = (obj)->scalarstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
781: #else
782: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag) \
783: PetscObjectComposedDataGetRealstar(obj,id,data,flag)
784: #endif
786: PETSC_EXTERN PetscErrorCode PetscObjectGetId(PetscObject,PetscObjectId*);
787: PETSC_EXTERN PetscErrorCode PetscObjectCompareId(PetscObject,PetscObjectId,PetscBool*);
789: PETSC_EXTERN PetscErrorCode PetscMonitorCompare(PetscErrorCode (*)(void),void *,PetscErrorCode (*)(void**),PetscErrorCode (*)(void),void *,PetscErrorCode (*)(void**),PetscBool *);
791: PETSC_EXTERN PetscMPIInt Petsc_Counter_keyval;
792: PETSC_EXTERN PetscMPIInt Petsc_InnerComm_keyval;
793: PETSC_EXTERN PetscMPIInt Petsc_OuterComm_keyval;
794: PETSC_EXTERN PetscMPIInt Petsc_Seq_keyval;
795: PETSC_EXTERN PetscMPIInt Petsc_ShmComm_keyval;
797: /*
798: PETSc communicators have this attribute, see
799: PetscCommDuplicate(), PetscCommDestroy(), PetscCommGetNewTag(), PetscObjectGetName()
800: */
801: typedef struct {
802: PetscMPIInt tag; /* next free tag value */
803: PetscInt refcount; /* number of references, communicator can be freed when this reaches 0 */
804: PetscInt namecount; /* used to generate the next name, as in Vec_0, Mat_1, ... */
805: } PetscCommCounter;
807: /*E
808: PetscOffloadFlag - indicates which memory (CPU, GPU, or none contains valid vector
810: PETSC_OFFLOAD_UNALLOCATED - no memory contains valid matrix entries; NEVER used for vectors
811: PETSC_OFFLOAD_GPU - GPU has valid vector/matrix entries
812: PETSC_OFFLOAD_CPU - CPU has valid vector/matrix entries
813: PETSC_OFFLOAD_BOTH - Both GPU and CPU have valid vector/matrix entries and they match
815: Level: developer
816: E*/
817: typedef enum {PETSC_OFFLOAD_UNALLOCATED,PETSC_OFFLOAD_GPU,PETSC_OFFLOAD_CPU,PETSC_OFFLOAD_BOTH} PetscOffloadFlag;
819: typedef enum {STATE_BEGIN, STATE_PENDING, STATE_END} SRState;
821: typedef enum {PETSC_SR_REDUCE_SUM=0,PETSC_SR_REDUCE_MAX=1,PETSC_SR_REDUCE_MIN=2} PetscSRReductionType;
823: typedef struct {
824: MPI_Comm comm;
825: MPI_Request request;
826: PetscBool async;
827: PetscScalar *lvalues; /* this are the reduced values before call to MPI_Allreduce() */
828: PetscScalar *gvalues; /* values after call to MPI_Allreduce() */
829: void **invecs; /* for debugging only, vector/memory used with each op */
830: PetscInt *reducetype; /* is particular value to be summed or maxed? */
831: SRState state; /* are we calling xxxBegin() or xxxEnd()? */
832: PetscInt maxops; /* total amount of space we have for requests */
833: PetscInt numopsbegin; /* number of requests that have been queued in */
834: PetscInt numopsend; /* number of requests that have been gotten by user */
835: } PetscSplitReduction;
837: PETSC_EXTERN PetscErrorCode PetscSplitReductionGet(MPI_Comm,PetscSplitReduction**);
838: PETSC_EXTERN PetscErrorCode PetscSplitReductionEnd(PetscSplitReduction*);
839: PETSC_EXTERN PetscErrorCode PetscSplitReductionExtend(PetscSplitReduction*);
841: #if !defined(PETSC_SKIP_SPINLOCK)
842: #if defined(PETSC_HAVE_THREADSAFETY)
843: # if defined(PETSC_HAVE_CONCURRENCYKIT)
844: #if defined(__cplusplus)
845: /* CK does not have extern "C" protection in their include files */
846: extern "C" {
847: #endif
848: #include <ck_spinlock.h>
849: #if defined(__cplusplus)
850: }
851: #endif
852: typedef ck_spinlock_t PetscSpinlock;
853: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockCreate(PetscSpinlock *ck_spinlock)
854: {
855: ck_spinlock_init(ck_spinlock);
856: return 0;
857: }
858: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockLock(PetscSpinlock *ck_spinlock)
859: {
860: ck_spinlock_lock(ck_spinlock);
861: return 0;
862: }
863: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *ck_spinlock)
864: {
865: ck_spinlock_unlock(ck_spinlock);
866: return 0;
867: }
868: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *ck_spinlock)
869: {
870: return 0;
871: }
872: # elif defined(PETSC_HAVE_OPENMP)
874: #include <omp.h>
875: typedef omp_lock_t PetscSpinlock;
876: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockCreate(PetscSpinlock *omp_lock)
877: {
878: omp_init_lock(omp_lock);
879: return 0;
880: }
881: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockLock(PetscSpinlock *omp_lock)
882: {
883: omp_set_lock(omp_lock);
884: return 0;
885: }
886: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *omp_lock)
887: {
888: omp_unset_lock(omp_lock);
889: return 0;
890: }
891: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *omp_lock)
892: {
893: omp_destroy_lock(omp_lock);
894: return 0;
895: }
896: #else
897: Thread safety requires either --with-openmp or --download-concurrencykit
898: #endif
900: #else
901: typedef int PetscSpinlock;
902: #define PetscSpinlockCreate(a) 0
903: #define PetscSpinlockLock(a) 0
904: #define PetscSpinlockUnlock(a) 0
905: #define PetscSpinlockDestroy(a) 0
906: #endif
908: #if defined(PETSC_HAVE_THREADSAFETY)
909: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockOpen;
910: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStdout;
911: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStderr;
912: PETSC_INTERN PetscSpinlock PetscCommSpinLock;
913: #endif
914: #endif
916: PETSC_EXTERN PetscLogEvent PETSC_Barrier;
917: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSided;
918: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSidedF;
920: #if defined(PETSC_HAVE_ADIOS)
921: PETSC_EXTERN int64_t Petsc_adios_group;
922: #endif
924: PETSC_EXTERN PetscBool use_gpu_aware_mpi;
925: #if defined(PETSC_HAVE_CUDA)
926: PETSC_EXTERN PetscBool sf_use_default_cuda_stream;
927: #endif
929: #endif /* PETSCIMPL_H */