Actual source code: petscimpl.h
2: /*
3: Defines the basic header of all PETSc objects.
4: */
6: #if !defined(PETSCIMPL_H)
7: #define PETSCIMPL_H
8: #include <petscsys.h>
10: #if defined(PETSC_CLANG_STATIC_ANALYZER)
11: #define PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(expr)
12: #else
13: #define PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(expr) \
14: expr
15: #endif
17: #if PetscDefined(USE_DEBUG)
18: PETSC_INTERN PetscErrorCode PetscStackSetCheck(PetscBool);
19: PETSC_INTERN PetscErrorCode PetscStackView(FILE*);
20: PETSC_INTERN PetscErrorCode PetscStackReset(void);
21: PETSC_INTERN PetscErrorCode PetscStackCopy(PetscStack*,PetscStack*);
22: PETSC_INTERN PetscErrorCode PetscStackPrint(PetscStack *,FILE*);
23: #else
24: #define PetscStackSetCheck(check) 0
25: #define PetscStackView(file) 0
26: #define PetscStackReset() 0
27: #define PetscStackCopy(stackin,stackout) 0
28: #define PetscStackPrint(stack,file) 0
29: #endif /* PetscDefined(USE_DEBUG) */
31: /* These are used internally by PETSc ASCII IO routines*/
32: #include <stdarg.h>
33: PETSC_EXTERN PetscErrorCode PetscVFPrintfDefault(FILE*,const char[],va_list);
35: #if defined(PETSC_HAVE_CLOSURE)
36: PETSC_EXTERN PetscErrorCode PetscVFPrintfSetClosure(int (^)(const char*));
37: #endif
39: /*
40: All major PETSc data structures have a common core; this is defined
41: below by PETSCHEADER.
43: PetscHeaderCreate() should be used whenever creating a PETSc structure.
44: */
46: /*
47: PetscOps: structure of core operations that all PETSc objects support.
49: getcomm() - Gets the object's communicator.
50: view() - Is the routine for viewing the entire PETSc object; for
51: example, MatView() is the general matrix viewing routine.
52: This is used by PetscObjectView((PetscObject)obj) to allow
53: viewing any PETSc object.
54: destroy() - Is the routine for destroying the entire PETSc object;
55: for example,MatDestroy() is the general matrix
56: destruction routine.
57: This is used by PetscObjectDestroy((PetscObject*)&obj) to allow
58: destroying any PETSc object.
59: compose() - Associates a PETSc object with another PETSc object with a name
60: query() - Returns a different PETSc object that has been associated
61: with the first object using a name.
62: composefunction() - Attaches an a function to a PETSc object with a name.
63: queryfunction() - Requests a registered function that has been attached to a PETSc object.
64: */
66: typedef struct {
67: PetscErrorCode (*getcomm)(PetscObject,MPI_Comm *);
68: PetscErrorCode (*view)(PetscObject,PetscViewer);
69: PetscErrorCode (*destroy)(PetscObject*);
70: PetscErrorCode (*compose)(PetscObject,const char[],PetscObject);
71: PetscErrorCode (*query)(PetscObject,const char[],PetscObject *);
72: PetscErrorCode (*composefunction)(PetscObject,const char[],void (*)(void));
73: PetscErrorCode (*queryfunction)(PetscObject,const char[],void (**)(void));
74: } PetscOps;
76: typedef enum {PETSC_FORTRAN_CALLBACK_CLASS,PETSC_FORTRAN_CALLBACK_SUBTYPE,PETSC_FORTRAN_CALLBACK_MAXTYPE} PetscFortranCallbackType;
77: typedef size_t PetscFortranCallbackId;
78: #define PETSC_SMALLEST_FORTRAN_CALLBACK ((PetscFortranCallbackId)1000)
79: PETSC_EXTERN PetscErrorCode PetscFortranCallbackRegister(PetscClassId,const char*,PetscFortranCallbackId*);
80: PETSC_EXTERN PetscErrorCode PetscFortranCallbackGetSizes(PetscClassId,PetscFortranCallbackId*,PetscFortranCallbackId*);
82: typedef struct {
83: void (*func)(void);
84: void *ctx;
85: } PetscFortranCallback;
87: /*
88: All PETSc objects begin with the fields defined in PETSCHEADER.
89: The PetscObject is a way of examining these fields regardless of
90: the specific object. In C++ this could be a base abstract class
91: from which all objects are derived.
92: */
93: #define PETSC_MAX_OPTIONS_HANDLER 5
94: typedef struct _p_PetscObject {
95: PetscClassId classid;
96: PetscOps bops[1];
97: MPI_Comm comm;
98: PetscInt type;
99: PetscLogDouble flops,time,mem,memchildren;
100: PetscObjectId id;
101: PetscInt refct;
102: PetscMPIInt tag;
103: PetscFunctionList qlist;
104: PetscObjectList olist;
105: char *class_name; /* for example, "Vec" */
106: char *description;
107: char *mansec;
108: char *type_name; /* this is the subclass, for example VECSEQ which equals "seq" */
109: PetscObject parent;
110: PetscObjectId parentid;
111: char* name;
112: char *prefix;
113: PetscInt tablevel;
114: void *cpp;
115: PetscObjectState state;
116: PetscInt int_idmax, intstar_idmax;
117: PetscObjectState *intcomposedstate,*intstarcomposedstate;
118: PetscInt *intcomposeddata, **intstarcomposeddata;
119: PetscInt real_idmax, realstar_idmax;
120: PetscObjectState *realcomposedstate,*realstarcomposedstate;
121: PetscReal *realcomposeddata, **realstarcomposeddata;
122: PetscInt scalar_idmax, scalarstar_idmax;
123: PetscObjectState *scalarcomposedstate,*scalarstarcomposedstate;
124: PetscScalar *scalarcomposeddata, **scalarstarcomposeddata;
125: void (**fortran_func_pointers)(void); /* used by Fortran interface functions to stash user provided Fortran functions */
126: PetscFortranCallbackId num_fortran_func_pointers; /* number of Fortran function pointers allocated */
127: PetscFortranCallback *fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
128: PetscFortranCallbackId num_fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
129: void *python_context;
130: PetscErrorCode (*python_destroy)(void*);
132: PetscInt noptionhandler;
133: PetscErrorCode (*optionhandler[PETSC_MAX_OPTIONS_HANDLER])(PetscOptionItems*,PetscObject,void*);
134: PetscErrorCode (*optiondestroy[PETSC_MAX_OPTIONS_HANDLER])(PetscObject,void*);
135: void *optionctx[PETSC_MAX_OPTIONS_HANDLER];
136: PetscBool optionsprinted;
137: #if defined(PETSC_HAVE_SAWS)
138: PetscBool amsmem; /* if PETSC_TRUE then this object is registered with SAWs and visible to clients */
139: PetscBool amspublishblock; /* if PETSC_TRUE and publishing objects then will block at PetscObjectSAWsBlock() */
140: #endif
141: PetscOptions options; /* options database used, NULL means default */
142: PetscBool donotPetscObjectPrintClassNamePrefixType;
143: } _p_PetscObject;
145: #define PETSCHEADER(ObjectOps) \
146: _p_PetscObject hdr; \
147: ObjectOps ops[1]
149: #define PETSCFREEDHEADER -1
151: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectDestroyFunction)(PetscObject*); /* force cast in next macro to NEVER use extern "C" style */
152: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectViewFunction)(PetscObject,PetscViewer);
154: /*@C
155: PetscHeaderCreate - Creates a PETSc object of a particular class
157: Input Parameters:
158: + classid - the classid associated with this object (for example VEC_CLASSID)
159: . class_name - string name of class; should be static (for example "Vec")
160: . descr - string containing short description; should be static (for example "Vector")
161: . mansec - string indicating section in manual pages; should be static (for example "Vec")
162: . comm - the MPI Communicator
163: . destroy - the destroy routine for this object (for example VecDestroy())
164: - view - the view routine for this object (for example VecView())
166: Output Parameter:
167: . h - the newly created object
169: Level: developer
171: .seealso: PetscHeaderDestroy(), PetscClassIdRegister()
173: @*/
174: #define PetscHeaderCreate(h,classid,class_name,descr,mansec,comm,destroy,view) \
175: (PetscNew(&(h)) || \
176: PetscHeaderCreate_Private((PetscObject)(h),classid,class_name,descr,mansec,comm,(PetscObjectDestroyFunction)(destroy),(PetscObjectViewFunction)(view)) || \
177: PetscLogObjectCreate(h) || \
178: PetscLogObjectMemory((PetscObject)(h),sizeof(*(h))))
180: PETSC_EXTERN PetscErrorCode PetscComposedQuantitiesDestroy(PetscObject obj);
181: PETSC_EXTERN PetscErrorCode PetscHeaderCreate_Private(PetscObject,PetscClassId,const char[],const char[],const char[],MPI_Comm,PetscObjectDestroyFunction,PetscObjectViewFunction);
183: /*@C
184: PetscHeaderDestroy - Final step in destroying a PetscObject
186: Input Parameters:
187: . h - the header created with PetscHeaderCreate()
189: Level: developer
191: .seealso: PetscHeaderCreate()
192: @*/
193: #define PetscHeaderDestroy(h) (PetscHeaderDestroy_Private((PetscObject)(*(h))) || PetscFree(*(h)))
195: PETSC_EXTERN PetscErrorCode PetscHeaderDestroy_Private(PetscObject);
196: PETSC_EXTERN PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject,PetscObject);
197: PETSC_EXTERN PetscErrorCode PetscObjectSetFortranCallback(PetscObject,PetscFortranCallbackType,PetscFortranCallbackId*,void(*)(void),void *ctx);
198: PETSC_EXTERN PetscErrorCode PetscObjectGetFortranCallback(PetscObject,PetscFortranCallbackType,PetscFortranCallbackId,void(**)(void),void **ctx);
200: PETSC_INTERN PetscErrorCode PetscCitationsInitialize(void);
201: PETSC_INTERN PetscErrorCode PetscFreeMPIResources(void);
202: PETSC_INTERN PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions,PetscBool*);
204: /* Code shared between C and Fortran */
205: PETSC_INTERN PetscErrorCode PetscInitialize_Common(const char*,const char*,const char*,PetscBool,PetscBool,PetscInt);
208: #if !defined(PETSC_CLANG_STATIC_ANALYZER)
209: /*
210: Macros to test if a PETSc object is valid and if pointers are valid
211: */
212: #if !defined(PETSC_USE_DEBUG)
225: #else
227: /* This check is for subtype methods such as DMDAGetCorners() that do not use the PetscTryMethod() or PetscUseMethod() paradigm */
229: do { \
230: PetscBool _7_same; \
232: PetscObjectTypeCompare((PetscObject)(h),t,&_7_same); \
234: } while (0)
239: } while (0)
245: if (((PetscObject)(h))->classid != ck) { \
247: else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Wrong type of object: Parameter # %d",arg); \
248: } \
249: } while (0)
255: } while (0)
265: do { \
267: } while (0)
268: #endif
269: #else /* PETSC_CLANG_STATIC_ANALYZER */
270: template <typename T>
272: template <typename T>
274: template <typename T>
276: template <typename T>
278: template <typename T>
280: template <typename T>
282: template <typename T>
284: template <typename T>
286: template <typename T>
288: template <typename T>
291: #endif /* PETSC_CLANG_STATIC_ANALYZER */
293: #define PetscSorted(n,idx,sorted) \
294: do { \
295: (sorted) = PETSC_TRUE; \
296: for (PetscInt _i_ = 1; _i_ < (n); ++_i_) { \
297: if ((idx)[_i_] < (idx)[_i_ - 1]) { (sorted) = PETSC_FALSE; break; } \
298: } \
299: } while (0)
301: #if !defined(PETSC_CLANG_STATIC_ANALYZER)
302: #if !defined(PETSC_USE_DEBUG)
318: #else
320: /*
321: For example, in the dot product between two vectors,
322: both vectors must be either Seq or MPI, not one of each
323: */
325: do { \
327: } while (0)
329: /*
330: Check type_name
331: */
333: do { \
334: PetscBool _7_match; \
335: PetscObjectTypeCompare(((PetscObject)(a)),(type),&_7_match); \
337: } while (0)
340: do { \
341: PetscBool _7_match; \
342: PetscObjectTypeCompareAny(((PetscObject)(a)),&_7_match,(type1),(type2),""); \
344: } while (0)
345: /*
346: Use this macro to check if the type is set
347: */
350: do { \
352: } while (0)
353: /*
354: Sometimes object must live on same communicator to inter-operate
355: */
357: do { \
358: PetscMPIInt _7_flag; \
359: MPI_Comm_compare(PetscObjectComm((PetscObject)(a)),PetscObjectComm((PetscObject)(b)),&_7_flag); \
361: } while (0)
364: do { \
367: } while (0)
370: do { \
371: PetscScalar b0=(b); \
372: PetscReal b1[5],b2[5]; \
373: if (PetscIsNanScalar(b0)) {b1[4] = 1;} else {b1[4] = 0;}; \
374: b1[0] = -PetscRealPart(b0); b1[1] = PetscRealPart(b0); b1[2] = -PetscImaginaryPart(b0); b1[3] = PetscImaginaryPart(b0); \
375: MPIU_Allreduce(b1,b2,5,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)(a)));\
377: } while (0)
380: do { \
381: PetscReal b0=(b),b1[3],b2[3]; \
382: if (PetscIsNanReal(b0)) {b1[2] = 1;} else {b1[2] = 0;}; \
383: b1[0] = -b0; b1[1] = b0; \
384: MPIU_Allreduce(b1,b2,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)(a)));\
386: } while (0)
389: do { \
390: PetscInt b0=(b),b1[2],b2[2]; \
391: b1[0] = -b0; b1[1] = b0; \
392: MPIU_Allreduce(b1,b2,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));\
394: } while (0)
397: do { \
398: PetscMPIInt b0=(b),b1[2],b2[2]; \
399: b1[0] = -b0; b1[1] = b0; \
400: MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));\
402: } while (0)
405: do { \
406: PetscMPIInt b0=(PetscMPIInt)(b),b1[2],b2[2]; \
407: b1[0] = -b0; b1[1] = b0; \
408: MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));\
410: } while (0)
413: do { \
414: PetscMPIInt b0=(PetscMPIInt)(b),b1[2],b2[2]; \
415: b1[0] = -b0; b1[1] = b0; \
416: MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));\
418: } while (0)
421: do { \
422: PetscBool _1_flg; \
423: PetscSorted(n,idx,_1_flg); \
425: } while (0)
427: #endif
428: #else /* PETSC_CLANG_STATIC_ANALYZER */
429: template <typename Ta,typename Tb>
433: template <typename T>
435: template <typename Ta,typename Tb>
437: template <typename Ta,typename Tb>
439: template <typename Ta,typename Tb>
441: template <typename Ta,typename Tb>
443: template <typename Ta,typename Tb>
445: template <typename Ta,typename Tb>
447: template <typename Ta,typename Tb>
449: template <typename Ta,typename Tb>
452: #endif /* PETSC_CLANG_STATIC_ANALYZER */
454: /*
455: PetscTryMethod - Queries an object for a method, if it exists then calls it.
456: These are intended to be used only inside PETSc functions.
458: Level: developer
460: .seealso: PetscUseMethod()
461: */
462: #define PetscTryMethod(obj,A,B,C) do { \
463: PetscErrorCode (*_7_f)B; \
464: PetscObjectQueryFunction((PetscObject)(obj),A,&_7_f); \
465: if (_7_f) (*_7_f)C; \
466: } while (0)
468: /*
469: PetscUseMethod - Queries an object for a method, if it exists then calls it, otherwise generates an error.
470: These are intended to be used only inside PETSc functions.
472: Level: developer
474: .seealso: PetscTryMethod()
475: */
476: #define PetscUseMethod(obj,A,B,C) do { \
477: PetscErrorCode (*_7_f)B; \
478: PetscObjectQueryFunction((PetscObject)(obj),A,&_7_f); \
480: (*_7_f)C; \
481: } while (0)
483: /*MC
484: PetscObjectStateIncrease - Increases the state of any PetscObject
486: Synopsis:
487: #include "petsc/private/petscimpl.h"
488: PetscErrorCode PetscObjectStateIncrease(PetscObject obj)
490: Logically Collective
492: Input Parameter:
493: . obj - any PETSc object, for example a Vec, Mat or KSP. This must be
494: cast with a (PetscObject), for example,
495: PetscObjectStateIncrease((PetscObject)mat);
497: Notes:
498: object state is an integer which gets increased every time
499: the object is changed internally. By saving and later querying the object state
500: one can determine whether information about the object is still current.
501: Currently, state is maintained for Vec and Mat objects.
503: This routine is mostly for internal use by PETSc; a developer need only
504: call it after explicit access to an object's internals. Routines such
505: as VecSet() or MatScale() already call this routine. It is also called, as a
506: precaution, in VecRestoreArray(), MatRestoreRow(), MatDenseRestoreArray().
508: This routine is logically collective because state equality comparison needs to be possible without communication.
510: Level: developer
512: seealso: PetscObjectStateGet()
514: M*/
515: #define PetscObjectStateIncrease(obj) ((obj)->state++,0)
517: PETSC_EXTERN PetscErrorCode PetscObjectStateGet(PetscObject,PetscObjectState*);
518: PETSC_EXTERN PetscErrorCode PetscObjectStateSet(PetscObject,PetscObjectState);
519: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataRegister(PetscInt*);
520: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject);
521: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject);
522: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject);
523: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject);
524: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject);
525: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject);
526: PETSC_EXTERN PetscInt PetscObjectComposedDataMax;
527: /*MC
528: PetscObjectComposedDataSetInt - attach integer data to a PetscObject
530: Synopsis:
531: #include "petsc/private/petscimpl.h"
532: PetscErrorCode PetscObjectComposedDataSetInt(PetscObject obj,int id,int data)
534: Not collective
536: Input parameters:
537: + obj - the object to which data is to be attached
538: . id - the identifier for the data
539: - data - the data to be attached
541: Notes
542: The data identifier can best be created through a call to PetscObjectComposedDataRegister()
544: Level: developer
545: M*/
546: #define PetscObjectComposedDataSetInt(obj,id,data) \
547: ((((obj)->int_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseInt(obj)) || \
548: ((obj)->intcomposeddata[id] = data,(obj)->intcomposedstate[id] = (obj)->state, 0))
550: /*MC
551: PetscObjectComposedDataGetInt - retrieve integer data attached to an object
553: Synopsis:
554: #include "petsc/private/petscimpl.h"
555: PetscErrorCode PetscObjectComposedDataGetInt(PetscObject obj,int id,int data,PetscBool flag)
557: Not collective
559: Input parameters:
560: + obj - the object from which data is to be retrieved
561: - id - the identifier for the data
563: Output parameters:
564: + data - the data to be retrieved
565: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
567: The 'data' and 'flag' variables are inlined, so they are not pointers.
569: Level: developer
570: M*/
571: #define PetscObjectComposedDataGetInt(obj,id,data,flag) \
572: ((((obj)->intcomposedstate && ((obj)->intcomposedstate[id] == (obj)->state)) ? \
573: (data = (obj)->intcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
575: /*MC
576: PetscObjectComposedDataSetIntstar - attach integer array data to a PetscObject
578: Synopsis:
579: #include "petsc/private/petscimpl.h"
580: PetscErrorCode PetscObjectComposedDataSetIntstar(PetscObject obj,int id,int *data)
582: Not collective
584: Input parameters:
585: + obj - the object to which data is to be attached
586: . id - the identifier for the data
587: - data - the data to be attached
589: Notes
590: The data identifier can best be determined through a call to
591: PetscObjectComposedDataRegister()
593: Level: developer
594: M*/
595: #define PetscObjectComposedDataSetIntstar(obj,id,data) \
596: ((((obj)->intstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseIntstar(obj)) || \
597: ((obj)->intstarcomposeddata[id] = data,(obj)->intstarcomposedstate[id] = (obj)->state, 0))
599: /*MC
600: PetscObjectComposedDataGetIntstar - retrieve integer array data
601: attached to an object
603: Synopsis:
604: #include "petsc/private/petscimpl.h"
605: PetscErrorCode PetscObjectComposedDataGetIntstar(PetscObject obj,int id,int *data,PetscBool flag)
607: Not collective
609: Input parameters:
610: + obj - the object from which data is to be retrieved
611: - id - the identifier for the data
613: Output parameters:
614: + data - the data to be retrieved
615: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
617: The 'data' and 'flag' variables are inlined, so they are not pointers.
619: Level: developer
620: M*/
621: #define PetscObjectComposedDataGetIntstar(obj,id,data,flag) \
622: ((((obj)->intstarcomposedstate && ((obj)->intstarcomposedstate[id] == (obj)->state)) ? \
623: (data = (obj)->intstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
625: /*MC
626: PetscObjectComposedDataSetReal - attach real data to a PetscObject
628: Synopsis:
629: #include "petsc/private/petscimpl.h"
630: PetscErrorCode PetscObjectComposedDataSetReal(PetscObject obj,int id,PetscReal data)
632: Not collective
634: Input parameters:
635: + obj - the object to which data is to be attached
636: . id - the identifier for the data
637: - data - the data to be attached
639: Notes
640: The data identifier can best be determined through a call to
641: PetscObjectComposedDataRegister()
643: Level: developer
644: M*/
645: #define PetscObjectComposedDataSetReal(obj,id,data) \
646: ((((obj)->real_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseReal(obj)) || \
647: ((obj)->realcomposeddata[id] = data,(obj)->realcomposedstate[id] = (obj)->state, 0))
649: /*MC
650: PetscObjectComposedDataGetReal - retrieve real data attached to an object
652: Synopsis:
653: #include "petsc/private/petscimpl.h"
654: PetscErrorCode PetscObjectComposedDataGetReal(PetscObject obj,int id,PetscReal data,PetscBool flag)
656: Not collective
658: Input parameters:
659: + obj - the object from which data is to be retrieved
660: - id - the identifier for the data
662: Output parameters:
663: + data - the data to be retrieved
664: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
666: The 'data' and 'flag' variables are inlined, so they are not pointers.
668: Level: developer
669: M*/
670: #define PetscObjectComposedDataGetReal(obj,id,data,flag) \
671: ((((obj)->realcomposedstate && ((obj)->realcomposedstate[id] == (obj)->state)) ? \
672: (data = (obj)->realcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
674: /*MC
675: PetscObjectComposedDataSetRealstar - attach real array data to a PetscObject
677: Synopsis:
678: #include "petsc/private/petscimpl.h"
679: PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *data)
681: Not collective
683: Input parameters:
684: + obj - the object to which data is to be attached
685: . id - the identifier for the data
686: - data - the data to be attached
688: Notes
689: The data identifier can best be determined through a call to
690: PetscObjectComposedDataRegister()
692: Level: developer
693: M*/
694: #define PetscObjectComposedDataSetRealstar(obj,id,data) \
695: ((((obj)->realstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseRealstar(obj)) || \
696: ((obj)->realstarcomposeddata[id] = data, (obj)->realstarcomposedstate[id] = (obj)->state, 0))
698: /*MC
699: PetscObjectComposedDataGetRealstar - retrieve real array data
700: attached to an object
702: Synopsis:
703: #include "petsc/private/petscimpl.h"
704: PetscErrorCode PetscObjectComposedDataGetRealstar(PetscObject obj,int id,PetscReal *data,PetscBool flag)
706: Not collective
708: Input parameters:
709: + obj - the object from which data is to be retrieved
710: - id - the identifier for the data
712: Output parameters:
713: + data - the data to be retrieved
714: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
716: The 'data' and 'flag' variables are inlined, so they are not pointers.
718: Level: developer
719: M*/
720: #define PetscObjectComposedDataGetRealstar(obj,id,data,flag) \
721: ((((obj)->realstarcomposedstate && ((obj)->realstarcomposedstate[id] == (obj)->state)) ? \
722: (data = (obj)->realstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
724: /*MC
725: PetscObjectComposedDataSetScalar - attach scalar data to a PetscObject
727: Synopsis:
728: #include "petsc/private/petscimpl.h"
729: PetscErrorCode PetscObjectComposedDataSetScalar(PetscObject obj,int id,PetscScalar data)
731: Not collective
733: Input parameters:
734: + obj - the object to which data is to be attached
735: . id - the identifier for the data
736: - data - the data to be attached
738: Notes
739: The data identifier can best be determined through a call to
740: PetscObjectComposedDataRegister()
742: Level: developer
743: M*/
744: #if defined(PETSC_USE_COMPLEX)
745: #define PetscObjectComposedDataSetScalar(obj,id,data) \
746: ((((obj)->scalar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalar(obj)) || \
747: ((obj)->scalarcomposeddata[id] = data,(obj)->scalarcomposedstate[id] = (obj)->state, 0))
748: #else
749: #define PetscObjectComposedDataSetScalar(obj,id,data) \
750: PetscObjectComposedDataSetReal(obj,id,data)
751: #endif
752: /*MC
753: PetscObjectComposedDataGetScalar - retrieve scalar data attached to an object
755: Synopsis:
756: #include "petsc/private/petscimpl.h"
757: PetscErrorCode PetscObjectComposedDataGetScalar(PetscObject obj,int id,PetscScalar data,PetscBool flag)
759: Not collective
761: Input parameters:
762: + obj - the object from which data is to be retrieved
763: - id - the identifier for the data
765: Output parameters:
766: + data - the data to be retrieved
767: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
769: The 'data' and 'flag' variables are inlined, so they are not pointers.
771: Level: developer
772: M*/
773: #if defined(PETSC_USE_COMPLEX)
774: #define PetscObjectComposedDataGetScalar(obj,id,data,flag) \
775: ((((obj)->scalarcomposedstate && ((obj)->scalarcomposedstate[id] == (obj)->state)) ? \
776: (data = (obj)->scalarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
777: #else
778: #define PetscObjectComposedDataGetScalar(obj,id,data,flag) \
779: PetscObjectComposedDataGetReal(obj,id,data,flag)
780: #endif
782: /*MC
783: PetscObjectComposedDataSetScalarstar - attach scalar array data to a PetscObject
785: Synopsis:
786: #include "petsc/private/petscimpl.h"
787: PetscErrorCode PetscObjectComposedDataSetScalarstar(PetscObject obj,int id,PetscScalar *data)
789: Not collective
791: Input parameters:
792: + obj - the object to which data is to be attached
793: . id - the identifier for the data
794: - data - the data to be attached
796: Notes
797: The data identifier can best be determined through a call to
798: PetscObjectComposedDataRegister()
800: Level: developer
801: M*/
802: #if defined(PETSC_USE_COMPLEX)
803: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
804: ((((obj)->scalarstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalarstar(obj)) || \
805: ((obj)->scalarstarcomposeddata[id] = data,(obj)->scalarstarcomposedstate[id] = (obj)->state, 0))
806: #else
807: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
808: PetscObjectComposedDataSetRealstar(obj,id,data)
809: #endif
810: /*MC
811: PetscObjectComposedDataGetScalarstar - retrieve scalar array data
812: attached to an object
814: Synopsis:
815: #include "petsc/private/petscimpl.h"
816: PetscErrorCode PetscObjectComposedDataGetScalarstar(PetscObject obj,int id,PetscScalar *data,PetscBool flag)
818: Not collective
820: Input parameters:
821: + obj - the object from which data is to be retrieved
822: - id - the identifier for the data
824: Output parameters:
825: + data - the data to be retrieved
826: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
828: The 'data' and 'flag' variables are inlined, so they are not pointers.
830: Level: developer
831: M*/
832: #if defined(PETSC_USE_COMPLEX)
833: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag) \
834: ((((obj)->scalarstarcomposedstate && ((obj)->scalarstarcomposedstate[id] == (obj)->state)) ? \
835: (data = (obj)->scalarstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
836: #else
837: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag) \
838: PetscObjectComposedDataGetRealstar(obj,id,data,flag)
839: #endif
841: PETSC_EXTERN PetscMPIInt Petsc_Counter_keyval;
842: PETSC_EXTERN PetscMPIInt Petsc_InnerComm_keyval;
843: PETSC_EXTERN PetscMPIInt Petsc_OuterComm_keyval;
844: PETSC_EXTERN PetscMPIInt Petsc_Seq_keyval;
845: PETSC_EXTERN PetscMPIInt Petsc_ShmComm_keyval;
847: struct PetscCommStash {
848: struct PetscCommStash *next;
849: MPI_Comm comm;
850: };
852: /*
853: PETSc communicators have this attribute, see
854: PetscCommDuplicate(), PetscCommDestroy(), PetscCommGetNewTag(), PetscObjectGetName()
855: */
856: typedef struct {
857: PetscMPIInt tag; /* next free tag value */
858: PetscInt refcount; /* number of references, communicator can be freed when this reaches 0 */
859: PetscInt namecount; /* used to generate the next name, as in Vec_0, Mat_1, ... */
860: PetscMPIInt *iflags; /* length of comm size, shared by all calls to PetscCommBuildTwoSided_Allreduce/RedScatter on this comm */
861: struct PetscCommStash *comms; /* communicators available for PETSc to pass off to other packages */
862: } PetscCommCounter;
864: typedef enum {STATE_BEGIN, STATE_PENDING, STATE_END} SRState;
866: typedef enum {PETSC_SR_REDUCE_SUM=0,PETSC_SR_REDUCE_MAX=1,PETSC_SR_REDUCE_MIN=2} PetscSRReductionType;
868: typedef struct {
869: MPI_Comm comm;
870: MPI_Request request;
871: PetscBool mix;
872: PetscBool async;
873: PetscScalar *lvalues; /* this are the reduced values before call to MPI_Allreduce() */
874: PetscScalar *gvalues; /* values after call to MPI_Allreduce() */
875: void **invecs; /* for debugging only, vector/memory used with each op */
876: PetscInt *reducetype; /* is particular value to be summed or maxed? */
877: struct { PetscScalar v; PetscInt i; } *lvalues_mix,*gvalues_mix; /* used when mixing reduce operations */
878: SRState state; /* are we calling xxxBegin() or xxxEnd()? */
879: PetscInt maxops; /* total amount of space we have for requests */
880: PetscInt numopsbegin; /* number of requests that have been queued in */
881: PetscInt numopsend; /* number of requests that have been gotten by user */
882: } PetscSplitReduction;
884: PETSC_EXTERN PetscErrorCode PetscSplitReductionGet(MPI_Comm,PetscSplitReduction**);
885: PETSC_EXTERN PetscErrorCode PetscSplitReductionEnd(PetscSplitReduction*);
886: PETSC_EXTERN PetscErrorCode PetscSplitReductionExtend(PetscSplitReduction*);
888: #if !defined(PETSC_SKIP_SPINLOCK)
889: #if defined(PETSC_HAVE_THREADSAFETY)
890: # if defined(PETSC_HAVE_CONCURRENCYKIT)
891: #if defined(__cplusplus)
892: /* CK does not have extern "C" protection in their include files */
893: extern "C" {
894: #endif
895: #include <ck_spinlock.h>
896: #if defined(__cplusplus)
897: }
898: #endif
899: typedef ck_spinlock_t PetscSpinlock;
900: static inline PetscErrorCode PetscSpinlockCreate(PetscSpinlock *ck_spinlock)
901: {
902: ck_spinlock_init(ck_spinlock);
903: return 0;
904: }
905: static inline PetscErrorCode PetscSpinlockLock(PetscSpinlock *ck_spinlock)
906: {
907: ck_spinlock_lock(ck_spinlock);
908: return 0;
909: }
910: static inline PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *ck_spinlock)
911: {
912: ck_spinlock_unlock(ck_spinlock);
913: return 0;
914: }
915: static inline PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *ck_spinlock)
916: {
917: return 0;
918: }
919: # elif defined(PETSC_HAVE_OPENMP)
921: #include <omp.h>
922: typedef omp_lock_t PetscSpinlock;
923: static inline PetscErrorCode PetscSpinlockCreate(PetscSpinlock *omp_lock)
924: {
925: omp_init_lock(omp_lock);
926: return 0;
927: }
928: static inline PetscErrorCode PetscSpinlockLock(PetscSpinlock *omp_lock)
929: {
930: omp_set_lock(omp_lock);
931: return 0;
932: }
933: static inline PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *omp_lock)
934: {
935: omp_unset_lock(omp_lock);
936: return 0;
937: }
938: static inline PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *omp_lock)
939: {
940: omp_destroy_lock(omp_lock);
941: return 0;
942: }
943: #else
944: Thread safety requires either --with-openmp or --download-concurrencykit
945: #endif
947: #else
948: typedef int PetscSpinlock;
949: #define PetscSpinlockCreate(a) 0
950: #define PetscSpinlockLock(a) 0
951: #define PetscSpinlockUnlock(a) 0
952: #define PetscSpinlockDestroy(a) 0
953: #endif
955: #if defined(PETSC_HAVE_THREADSAFETY)
956: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockOpen;
957: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStdout;
958: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStderr;
959: PETSC_INTERN PetscSpinlock PetscCommSpinLock;
960: #endif
961: #endif
963: PETSC_EXTERN PetscLogEvent PETSC_Barrier;
964: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSided;
965: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSidedF;
966: PETSC_EXTERN PetscBool use_gpu_aware_mpi;
968: #if defined(PETSC_HAVE_ADIOS)
969: PETSC_EXTERN int64_t Petsc_adios_group;
970: #endif
972: #if defined(PETSC_HAVE_KOKKOS)
973: PETSC_INTERN PetscBool PetscBeganKokkos;
974: PETSC_EXTERN PetscBool PetscKokkosInitialized;
975: PETSC_INTERN PetscErrorCode PetscKokkosIsInitialized_Private(PetscBool*);
976: PETSC_INTERN PetscErrorCode PetscKokkosFinalize_Private(void);
977: #endif
979: #if defined(PETSC_HAVE_OPENMP)
980: PETSC_EXTERN PetscInt PetscNumOMPThreads;
981: #endif
983: #endif /* PETSCIMPL_H */