Actual source code: petscimpl.h
petsc-3.13.2 2020-06-02
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);
191: #if defined(PETSC_HAVE_CUDA)
193: #endif
194: /*
195: Macros to test if a PETSc object is valid and if pointers are valid
196: */
197: #if !defined(PETSC_USE_DEBUG)
210: #else
212: /* This check is for subtype methods such as DMDAGetCorners() that do not use the PetscTryMethod() or PetscUseMethod() paradigm */
214: do { \
215: PetscErrorCode _7_ierr; \
216: PetscBool _7_same; \
218: _7_PetscObjectTypeCompare((PetscObject)(h),t,&_7_same);CHKERRQ(_7_ierr); \
219: 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); \
220: } while (0)
223: do { \
224: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg); \
226: if (((PetscObject)(h))->classid != ck) { \
227: if (((PetscObject)(h))->classid == PETSCFREEDHEADER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
228: else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Wrong type of object: Parameter # %d",arg); \
229: } \
230: } while (0)
233: do { \
234: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg); \
236: if (((PetscObject)(h))->classid == PETSCFREEDHEADER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
237: 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); \
238: } while (0)
241: do { \
242: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
244: } while (0)
247: do { \
248: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg);\
250: } while (0)
253: do { \
254: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Null Pointer: Parameter # %d",arg); \
256: } while (0)
259: do { \
260: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Null Pointer: Parameter # %d",arg); \
262: } while (0)
265: do { \
266: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
268: } while (0)
271: do { \
272: if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
274: } while (0)
277: do { \
278: if (!(f)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Function Pointer: Parameter # %d",arg); \
279: } while (0)
281: #endif
283: #define PetscSorted(n,idx,sorted) \
284: do { \
285: PetscInt _i_; \
286: (sorted) = PETSC_TRUE; \
287: for (_i_ = 1; _i_ < (n); _i_++) \
288: if ((idx)[_i_] < (idx)[_i_ - 1]) \
289: { (sorted) = PETSC_FALSE; break; } \
290: } while(0)
292: #if !defined(PETSC_USE_DEBUG)
308: #else
310: /*
311: For example, in the dot product between two vectors,
312: both vectors must be either Seq or MPI, not one of each
313: */
315: do { \
316: 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); \
317: } while (0)
318: /*
319: Check type_name
320: */
322: do { \
323: PetscBool _7_match; \
324: PetscErrorCode _7_ierr; \
325: _7_PetscObjectTypeCompare(((PetscObject)(a)),(type),&_7_match);CHKERRQ(_7_ierr); \
326: if (!_7_match) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Object (%s) is not %s",(char*)(((PetscObject)(a))->type_name),type); \
327: } while (0)
330: do { \
331: PetscBool _7_match; \
332: PetscErrorCode _7_ierr; \
333: _7_PetscObjectTypeCompareAny(((PetscObject)(a)),&_7_match,(type1),(type2),"");CHKERRQ(_7_ierr); \
334: 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); \
335: } while (0)
336: /*
337: Use this macro to check if the type is set
338: */
340: do { \
341: 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); \
342: } while (0)
343: /*
344: Sometimes object must live on same communicator to inter-operate
345: */
347: do { \
348: PetscErrorCode _7_ierr; \
349: PetscMPIInt _7_flag; \
350: _7_MPI_Comm_compare(PetscObjectComm((PetscObject)(a)),PetscObjectComm((PetscObject)(b)),&_7_flag);CHKERRQ(_7_ierr); \
351: 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); \
352: } while (0)
355: do { \
358: } while (0)
361: do { \
362: PetscErrorCode _7_ierr; \
363: PetscScalar b0=(b); \
364: PetscReal b1[5],b2[5]; \
365: if (PetscIsNanScalar(b0)) {b1[4] = 1;} else {b1[4] = 0;}; \
366: b1[0] = -PetscRealPart(b0); b1[1] = PetscRealPart(b0); b1[2] = -PetscImaginaryPart(b0); b1[3] = PetscImaginaryPart(b0); \
367: _7_MPI_Allreduce(b1,b2,5,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)(a)));CHKERRQ(_7_ierr); \
368: 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); \
369: } while (0)
372: do { \
373: PetscErrorCode _7_ierr; \
374: PetscReal b0=(b),b1[3],b2[3]; \
375: if (PetscIsNanReal(b0)) {b1[2] = 1;} else {b1[2] = 0;}; \
376: b1[0] = -b0; b1[1] = b0; \
377: _7_MPI_Allreduce(b1,b2,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)(a)));CHKERRQ(_7_ierr); \
378: 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); \
379: } while (0)
382: do { \
383: PetscErrorCode _7_ierr; \
384: PetscInt b0=(b),b1[2],b2[2]; \
385: b1[0] = -b0; b1[1] = b0; \
386: _7_MPIU_Allreduce(b1,b2,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));CHKERRQ(_7_ierr); \
387: if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)(a)),PETSC_ERR_ARG_WRONG,"Int value must be same on all processes, argument # %d",arg); \
388: } while (0)
391: do { \
392: PetscErrorCode _7_ierr; \
393: PetscMPIInt b0=(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,"PetscMPIInt 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,"Bool value must be same on all processes, argument # %d",arg); \
406: } while (0)
409: do { \
410: PetscErrorCode _7_ierr; \
411: PetscMPIInt b0=(PetscMPIInt)(b),b1[2],b2[2]; \
412: b1[0] = -b0; b1[1] = b0; \
413: _7_MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));CHKERRQ(_7_ierr); \
414: if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)(a)),PETSC_ERR_ARG_WRONG,"Enum value must be same on all processes, argument # %d",arg); \
415: } while (0)
418: do { \
419: PetscBool _1_flg; \
420: PetscSorted(n,idx,_1_flg); \
421: if (!_1_flg) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Input array needs to be sorted"); \
422: } while (0)
424: #endif
426: /*
427: PetscTryMethod - Queries an object for a method, if it exists then calls it.
428: These are intended to be used only inside PETSc functions.
430: Level: developer
432: .seealso: PetscUseMethod()
433: */
434: #define PetscTryMethod(obj,A,B,C) \
435: 0; do { PetscErrorCode (*_7_f)B, _7_ierr; \
436: _7_PetscObjectQueryFunction((PetscObject)(obj),A,&_7_f);CHKERRQ(_7_ierr); \
437: if (_7_f) {_7_(*_7_f)C;CHKERRQ(_7_ierr);} \
438: } while(0)
440: /*
441: PetscUseMethod - Queries an object for a method, if it exists then calls it, otherwise generates an error.
442: These are intended to be used only inside PETSc functions.
444: Level: developer
446: .seealso: PetscTryMethod()
447: */
448: #define PetscUseMethod(obj,A,B,C) \
449: 0; do { PetscErrorCode (*_7_f)B, _7_ierr; \
450: _7_PetscObjectQueryFunction((PetscObject)(obj),A,&_7_f);CHKERRQ(_7_ierr); \
451: if (_7_f) {_7_(*_7_f)C;CHKERRQ(_7_ierr);} \
452: else SETERRQ1(PetscObjectComm((PetscObject)(obj)),PETSC_ERR_SUP,"Cannot locate function %s in object",A); \
453: } while(0)
455: /*MC
456: PetscObjectStateIncrease - Increases the state of any PetscObject
458: Synopsis:
459: #include "petsc/private/petscimpl.h"
460: PetscErrorCode PetscObjectStateIncrease(PetscObject obj)
462: Logically Collective
464: Input Parameter:
465: . obj - any PETSc object, for example a Vec, Mat or KSP. This must be
466: cast with a (PetscObject), for example,
467: PetscObjectStateIncrease((PetscObject)mat);
469: Notes:
470: object state is an integer which gets increased every time
471: the object is changed internally. By saving and later querying the object state
472: one can determine whether information about the object is still current.
473: Currently, state is maintained for Vec and Mat objects.
475: This routine is mostly for internal use by PETSc; a developer need only
476: call it after explicit access to an object's internals. Routines such
477: as VecSet() or MatScale() already call this routine. It is also called, as a
478: precaution, in VecRestoreArray(), MatRestoreRow(), MatDenseRestoreArray().
480: This routine is logically collective because state equality comparison needs to be possible without communication.
482: Level: developer
484: seealso: PetscObjectStateGet()
486: M*/
487: #define PetscObjectStateIncrease(obj) ((obj)->state++,0)
489: PETSC_EXTERN PetscErrorCode PetscObjectStateGet(PetscObject,PetscObjectState*);
490: PETSC_EXTERN PetscErrorCode PetscObjectStateSet(PetscObject,PetscObjectState);
491: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataRegister(PetscInt*);
492: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject);
493: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject);
494: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject);
495: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject);
496: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject);
497: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject);
498: PETSC_EXTERN PetscInt PetscObjectComposedDataMax;
499: /*MC
500: PetscObjectComposedDataSetInt - attach integer data to a PetscObject
502: Synopsis:
503: #include "petsc/private/petscimpl.h"
504: PetscErrorCode PetscObjectComposedDataSetInt(PetscObject obj,int id,int data)
506: Not collective
508: Input parameters:
509: + obj - the object to which data is to be attached
510: . id - the identifier for the data
511: - data - the data to be attached
513: Notes
514: The data identifier can best be created through a call to PetscObjectComposedDataRegister()
516: Level: developer
517: M*/
518: #define PetscObjectComposedDataSetInt(obj,id,data) \
519: ((((obj)->int_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseInt(obj)) || \
520: ((obj)->intcomposeddata[id] = data,(obj)->intcomposedstate[id] = (obj)->state, 0))
522: /*MC
523: PetscObjectComposedDataGetInt - retrieve integer data attached to an object
525: Synopsis:
526: #include "petsc/private/petscimpl.h"
527: PetscErrorCode PetscObjectComposedDataGetInt(PetscObject obj,int id,int data,PetscBool flag)
529: Not collective
531: Input parameters:
532: + obj - the object from which data is to be retrieved
533: - id - the identifier for the data
535: Output parameters:
536: + data - the data to be retrieved
537: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
539: The 'data' and 'flag' variables are inlined, so they are not pointers.
541: Level: developer
542: M*/
543: #define PetscObjectComposedDataGetInt(obj,id,data,flag) \
544: ((((obj)->intcomposedstate && ((obj)->intcomposedstate[id] == (obj)->state)) ? \
545: (data = (obj)->intcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
547: /*MC
548: PetscObjectComposedDataSetIntstar - attach integer array data to a PetscObject
550: Synopsis:
551: #include "petsc/private/petscimpl.h"
552: PetscErrorCode PetscObjectComposedDataSetIntstar(PetscObject obj,int id,int *data)
554: Not collective
556: Input parameters:
557: + obj - the object to which data is to be attached
558: . id - the identifier for the data
559: - data - the data to be attached
561: Notes
562: The data identifier can best be determined through a call to
563: PetscObjectComposedDataRegister()
565: Level: developer
566: M*/
567: #define PetscObjectComposedDataSetIntstar(obj,id,data) \
568: ((((obj)->intstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseIntstar(obj)) || \
569: ((obj)->intstarcomposeddata[id] = data,(obj)->intstarcomposedstate[id] = (obj)->state, 0))
571: /*MC
572: PetscObjectComposedDataGetIntstar - retrieve integer array data
573: attached to an object
575: Synopsis:
576: #include "petsc/private/petscimpl.h"
577: PetscErrorCode PetscObjectComposedDataGetIntstar(PetscObject obj,int id,int *data,PetscBool flag)
579: Not collective
581: Input parameters:
582: + obj - the object from which data is to be retrieved
583: - id - the identifier for the data
585: Output parameters:
586: + data - the data to be retrieved
587: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
589: The 'data' and 'flag' variables are inlined, so they are not pointers.
591: Level: developer
592: M*/
593: #define PetscObjectComposedDataGetIntstar(obj,id,data,flag) \
594: ((((obj)->intstarcomposedstate && ((obj)->intstarcomposedstate[id] == (obj)->state)) ? \
595: (data = (obj)->intstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
597: /*MC
598: PetscObjectComposedDataSetReal - attach real data to a PetscObject
600: Synopsis:
601: #include "petsc/private/petscimpl.h"
602: PetscErrorCode PetscObjectComposedDataSetReal(PetscObject obj,int id,PetscReal data)
604: Not collective
606: Input parameters:
607: + obj - the object to which data is to be attached
608: . id - the identifier for the data
609: - data - the data to be attached
611: Notes
612: The data identifier can best be determined through a call to
613: PetscObjectComposedDataRegister()
615: Level: developer
616: M*/
617: #define PetscObjectComposedDataSetReal(obj,id,data) \
618: ((((obj)->real_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseReal(obj)) || \
619: ((obj)->realcomposeddata[id] = data,(obj)->realcomposedstate[id] = (obj)->state, 0))
621: /*MC
622: PetscObjectComposedDataGetReal - retrieve real data attached to an object
624: Synopsis:
625: #include "petsc/private/petscimpl.h"
626: PetscErrorCode PetscObjectComposedDataGetReal(PetscObject obj,int id,PetscReal data,PetscBool flag)
628: Not collective
630: Input parameters:
631: + obj - the object from which data is to be retrieved
632: - id - the identifier for the data
634: Output parameters:
635: + data - the data to be retrieved
636: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
638: The 'data' and 'flag' variables are inlined, so they are not pointers.
640: Level: developer
641: M*/
642: #define PetscObjectComposedDataGetReal(obj,id,data,flag) \
643: ((((obj)->realcomposedstate && ((obj)->realcomposedstate[id] == (obj)->state)) ? \
644: (data = (obj)->realcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
646: /*MC
647: PetscObjectComposedDataSetRealstar - attach real array data to a PetscObject
649: Synopsis:
650: #include "petsc/private/petscimpl.h"
651: PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *data)
653: Not collective
655: Input parameters:
656: + obj - the object to which data is to be attached
657: . id - the identifier for the data
658: - data - the data to be attached
660: Notes
661: The data identifier can best be determined through a call to
662: PetscObjectComposedDataRegister()
664: Level: developer
665: M*/
666: #define PetscObjectComposedDataSetRealstar(obj,id,data) \
667: ((((obj)->realstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseRealstar(obj)) || \
668: ((obj)->realstarcomposeddata[id] = data, (obj)->realstarcomposedstate[id] = (obj)->state, 0))
670: /*MC
671: PetscObjectComposedDataGetRealstar - retrieve real array data
672: attached to an object
674: Synopsis:
675: #include "petsc/private/petscimpl.h"
676: PetscErrorCode PetscObjectComposedDataGetRealstar(PetscObject obj,int id,PetscReal *data,PetscBool flag)
678: Not collective
680: Input parameters:
681: + obj - the object from which data is to be retrieved
682: - id - the identifier for the data
684: Output parameters:
685: + data - the data to be retrieved
686: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
688: The 'data' and 'flag' variables are inlined, so they are not pointers.
690: Level: developer
691: M*/
692: #define PetscObjectComposedDataGetRealstar(obj,id,data,flag) \
693: ((((obj)->realstarcomposedstate && ((obj)->realstarcomposedstate[id] == (obj)->state)) ? \
694: (data = (obj)->realstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
696: /*MC
697: PetscObjectComposedDataSetScalar - attach scalar data to a PetscObject
699: Synopsis:
700: #include "petsc/private/petscimpl.h"
701: PetscErrorCode PetscObjectComposedDataSetScalar(PetscObject obj,int id,PetscScalar data)
703: Not collective
705: Input parameters:
706: + obj - the object to which data is to be attached
707: . id - the identifier for the data
708: - data - the data to be attached
710: Notes
711: The data identifier can best be determined through a call to
712: PetscObjectComposedDataRegister()
714: Level: developer
715: M*/
716: #if defined(PETSC_USE_COMPLEX)
717: #define PetscObjectComposedDataSetScalar(obj,id,data) \
718: ((((obj)->scalar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalar(obj)) || \
719: ((obj)->scalarcomposeddata[id] = data,(obj)->scalarcomposedstate[id] = (obj)->state, 0))
720: #else
721: #define PetscObjectComposedDataSetScalar(obj,id,data) \
722: PetscObjectComposedDataSetReal(obj,id,data)
723: #endif
724: /*MC
725: PetscObjectComposedDataGetScalar - retrieve scalar data attached to an object
727: Synopsis:
728: #include "petsc/private/petscimpl.h"
729: PetscErrorCode PetscObjectComposedDataGetScalar(PetscObject obj,int id,PetscScalar data,PetscBool flag)
731: Not collective
733: Input parameters:
734: + obj - the object from which data is to be retrieved
735: - id - the identifier for the data
737: Output parameters:
738: + data - the data to be retrieved
739: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
741: The 'data' and 'flag' variables are inlined, so they are not pointers.
743: Level: developer
744: M*/
745: #if defined(PETSC_USE_COMPLEX)
746: #define PetscObjectComposedDataGetScalar(obj,id,data,flag) \
747: ((((obj)->scalarcomposedstate && ((obj)->scalarcomposedstate[id] == (obj)->state) ) ? \
748: (data = (obj)->scalarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
749: #else
750: #define PetscObjectComposedDataGetScalar(obj,id,data,flag) \
751: PetscObjectComposedDataGetReal(obj,id,data,flag)
752: #endif
754: /*MC
755: PetscObjectComposedDataSetScalarstar - attach scalar array data to a PetscObject
757: Synopsis:
758: #include "petsc/private/petscimpl.h"
759: PetscErrorCode PetscObjectComposedDataSetScalarstar(PetscObject obj,int id,PetscScalar *data)
761: Not collective
763: Input parameters:
764: + obj - the object to which data is to be attached
765: . id - the identifier for the data
766: - data - the data to be attached
768: Notes
769: The data identifier can best be determined through a call to
770: PetscObjectComposedDataRegister()
772: Level: developer
773: M*/
774: #if defined(PETSC_USE_COMPLEX)
775: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
776: ((((obj)->scalarstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalarstar(obj)) || \
777: ((obj)->scalarstarcomposeddata[id] = data,(obj)->scalarstarcomposedstate[id] = (obj)->state, 0))
778: #else
779: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
780: PetscObjectComposedDataSetRealstar(obj,id,data)
781: #endif
782: /*MC
783: PetscObjectComposedDataGetScalarstar - retrieve scalar array data
784: attached to an object
786: Synopsis:
787: #include "petsc/private/petscimpl.h"
788: PetscErrorCode PetscObjectComposedDataGetScalarstar(PetscObject obj,int id,PetscScalar *data,PetscBool flag)
790: Not collective
792: Input parameters:
793: + obj - the object from which data is to be retrieved
794: - id - the identifier for the data
796: Output parameters:
797: + data - the data to be retrieved
798: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
800: The 'data' and 'flag' variables are inlined, so they are not pointers.
802: Level: developer
803: M*/
804: #if defined(PETSC_USE_COMPLEX)
805: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag) \
806: ((((obj)->scalarstarcomposedstate && ((obj)->scalarstarcomposedstate[id] == (obj)->state)) ? \
807: (data = (obj)->scalarstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
808: #else
809: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag) \
810: PetscObjectComposedDataGetRealstar(obj,id,data,flag)
811: #endif
813: PETSC_EXTERN PetscMPIInt Petsc_Counter_keyval;
814: PETSC_EXTERN PetscMPIInt Petsc_InnerComm_keyval;
815: PETSC_EXTERN PetscMPIInt Petsc_OuterComm_keyval;
816: PETSC_EXTERN PetscMPIInt Petsc_Seq_keyval;
817: PETSC_EXTERN PetscMPIInt Petsc_ShmComm_keyval;
819: /*
820: PETSc communicators have this attribute, see
821: PetscCommDuplicate(), PetscCommDestroy(), PetscCommGetNewTag(), PetscObjectGetName()
822: */
823: typedef struct {
824: PetscMPIInt tag; /* next free tag value */
825: PetscInt refcount; /* number of references, communicator can be freed when this reaches 0 */
826: PetscInt namecount; /* used to generate the next name, as in Vec_0, Mat_1, ... */
827: PetscMPIInt *iflags; /* length of comm size, shared by all calls to PetscCommBuildTwoSided_Allreduce/RedScatter on this comm */
828: } PetscCommCounter;
830: /*E
831: PetscOffloadMask - indicates which memory (CPU, GPU, or none) contains valid data
833: PETSC_OFFLOAD_UNALLOCATED - no memory contains valid matrix entries; NEVER used for vectors
834: PETSC_OFFLOAD_GPU - GPU has valid vector/matrix entries
835: PETSC_OFFLOAD_CPU - CPU has valid vector/matrix entries
836: PETSC_OFFLOAD_BOTH - Both GPU and CPU have valid vector/matrix entries and they match
838: Level: developer
839: E*/
840: typedef enum {PETSC_OFFLOAD_UNALLOCATED=0x0,PETSC_OFFLOAD_CPU=0x1,PETSC_OFFLOAD_GPU=0x2,PETSC_OFFLOAD_BOTH=0x3} PetscOffloadMask;
842: typedef enum {STATE_BEGIN, STATE_PENDING, STATE_END} SRState;
844: typedef enum {PETSC_SR_REDUCE_SUM=0,PETSC_SR_REDUCE_MAX=1,PETSC_SR_REDUCE_MIN=2} PetscSRReductionType;
846: typedef struct {
847: MPI_Comm comm;
848: MPI_Request request;
849: PetscBool async;
850: PetscScalar *lvalues; /* this are the reduced values before call to MPI_Allreduce() */
851: PetscScalar *gvalues; /* values after call to MPI_Allreduce() */
852: void **invecs; /* for debugging only, vector/memory used with each op */
853: PetscInt *reducetype; /* is particular value to be summed or maxed? */
854: SRState state; /* are we calling xxxBegin() or xxxEnd()? */
855: PetscInt maxops; /* total amount of space we have for requests */
856: PetscInt numopsbegin; /* number of requests that have been queued in */
857: PetscInt numopsend; /* number of requests that have been gotten by user */
858: } PetscSplitReduction;
860: PETSC_EXTERN PetscErrorCode PetscSplitReductionGet(MPI_Comm,PetscSplitReduction**);
861: PETSC_EXTERN PetscErrorCode PetscSplitReductionEnd(PetscSplitReduction*);
862: PETSC_EXTERN PetscErrorCode PetscSplitReductionExtend(PetscSplitReduction*);
864: #if !defined(PETSC_SKIP_SPINLOCK)
865: #if defined(PETSC_HAVE_THREADSAFETY)
866: # if defined(PETSC_HAVE_CONCURRENCYKIT)
867: #if defined(__cplusplus)
868: /* CK does not have extern "C" protection in their include files */
869: extern "C" {
870: #endif
871: #include <ck_spinlock.h>
872: #if defined(__cplusplus)
873: }
874: #endif
875: typedef ck_spinlock_t PetscSpinlock;
876: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockCreate(PetscSpinlock *ck_spinlock)
877: {
878: ck_spinlock_init(ck_spinlock);
879: return 0;
880: }
881: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockLock(PetscSpinlock *ck_spinlock)
882: {
883: ck_spinlock_lock(ck_spinlock);
884: return 0;
885: }
886: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *ck_spinlock)
887: {
888: ck_spinlock_unlock(ck_spinlock);
889: return 0;
890: }
891: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *ck_spinlock)
892: {
893: return 0;
894: }
895: # elif defined(PETSC_HAVE_OPENMP)
897: #include <omp.h>
898: typedef omp_lock_t PetscSpinlock;
899: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockCreate(PetscSpinlock *omp_lock)
900: {
901: omp_init_lock(omp_lock);
902: return 0;
903: }
904: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockLock(PetscSpinlock *omp_lock)
905: {
906: omp_set_lock(omp_lock);
907: return 0;
908: }
909: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *omp_lock)
910: {
911: omp_unset_lock(omp_lock);
912: return 0;
913: }
914: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *omp_lock)
915: {
916: omp_destroy_lock(omp_lock);
917: return 0;
918: }
919: #else
920: Thread safety requires either --with-openmp or --download-concurrencykit
921: #endif
923: #else
924: typedef int PetscSpinlock;
925: #define PetscSpinlockCreate(a) 0
926: #define PetscSpinlockLock(a) 0
927: #define PetscSpinlockUnlock(a) 0
928: #define PetscSpinlockDestroy(a) 0
929: #endif
931: #if defined(PETSC_HAVE_THREADSAFETY)
932: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockOpen;
933: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStdout;
934: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStderr;
935: PETSC_INTERN PetscSpinlock PetscCommSpinLock;
936: #endif
937: #endif
939: PETSC_EXTERN PetscLogEvent PETSC_Barrier;
940: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSided;
941: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSidedF;
942: PETSC_EXTERN PetscBool use_gpu_aware_mpi;
944: #if defined(PETSC_HAVE_ADIOS)
945: PETSC_EXTERN int64_t Petsc_adios_group;
946: #endif
948: #endif /* PETSCIMPL_H */