Actual source code: petscimpl.h
2: /*
3: Defines the basic header of all PETSc objects.
4: */
5: #ifndef PETSCIMPL_H
6: #define PETSCIMPL_H
7: #include <petscsys.h>
9: /* SUBMANSEC = Sys */
11: #if defined(PETSC_CLANG_STATIC_ANALYZER)
12: #define PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(expr)
13: #else
14: #define PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(expr) 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: /*
36: All major PETSc data structures have a common core; this is defined
37: below by PETSCHEADER.
39: PetscHeaderCreate() should be used whenever creating a PETSc structure.
40: */
42: /*
43: PetscOps: structure of core operations that all PETSc objects support.
45: getcomm() - Gets the object's communicator.
46: view() - Is the routine for viewing the entire PETSc object; for
47: example, MatView() is the general matrix viewing routine.
48: This is used by PetscObjectView((PetscObject)obj) to allow
49: viewing any PETSc object.
50: destroy() - Is the routine for destroying the entire PETSc object;
51: for example,MatDestroy() is the general matrix
52: destruction routine.
53: This is used by PetscObjectDestroy((PetscObject*)&obj) to allow
54: destroying any PETSc object.
55: compose() - Associates a PETSc object with another PETSc object with a name
56: query() - Returns a different PETSc object that has been associated
57: with the first object using a name.
58: composefunction() - Attaches an a function to a PETSc object with a name.
59: queryfunction() - Requests a registered function that has been attached to a PETSc object.
60: */
62: typedef struct {
63: PetscErrorCode (*view)(PetscObject, PetscViewer);
64: PetscErrorCode (*destroy)(PetscObject *);
65: PetscErrorCode (*compose)(PetscObject, const char[], PetscObject);
66: PetscErrorCode (*query)(PetscObject, const char[], PetscObject *);
67: PetscErrorCode (*composefunction)(PetscObject, const char[], void (*)(void));
68: PetscErrorCode (*queryfunction)(PetscObject, const char[], void (**)(void));
69: } PetscOps;
71: typedef enum {
72: PETSC_FORTRAN_CALLBACK_CLASS,
73: PETSC_FORTRAN_CALLBACK_SUBTYPE,
74: PETSC_FORTRAN_CALLBACK_MAXTYPE
75: } PetscFortranCallbackType;
76: typedef size_t PetscFortranCallbackId;
77: #define PETSC_SMALLEST_FORTRAN_CALLBACK ((PetscFortranCallbackId)1000)
78: PETSC_EXTERN PetscErrorCode PetscFortranCallbackRegister(PetscClassId, const char *, PetscFortranCallbackId *);
79: PETSC_EXTERN PetscErrorCode PetscFortranCallbackGetSizes(PetscClassId, PetscFortranCallbackId *, PetscFortranCallbackId *);
81: typedef struct {
82: void (*func)(void);
83: void *ctx;
84: } PetscFortranCallback;
86: /*
87: All PETSc objects begin with the fields defined in PETSCHEADER.
88: The PetscObject is a way of examining these fields regardless of
89: the specific object. In C++ this could be a base abstract class
90: from which all objects are derived.
91: */
92: #define PETSC_MAX_OPTIONS_HANDLER 5
93: typedef struct _p_PetscObject {
94: PetscOps bops[1];
95: PetscClassId classid;
96: MPI_Comm comm;
97: PetscObjectId id; /* this is used to compare object for identity that may no longer exist since memory addresses get recycled for new objects */
98: PetscInt refct;
99: PetscErrorCode (*non_cyclic_references)(PetscObject, PetscInt *);
100: PetscInt64 cidx;
101: PetscMPIInt tag;
102: PetscFunctionList qlist;
103: PetscObjectList olist;
104: char *class_name; /* for example, "Vec" */
105: char *description;
106: char *mansec;
107: char *type_name; /* this is the subclass, for example VECSEQ which equals "seq" */
108: char *name;
109: char *prefix;
110: PetscInt tablevel;
111: void *cpp;
112: PetscObjectState state;
113: PetscInt int_idmax, intstar_idmax;
114: PetscObjectState *intcomposedstate, *intstarcomposedstate;
115: PetscInt *intcomposeddata, **intstarcomposeddata;
116: PetscInt real_idmax, realstar_idmax;
117: PetscObjectState *realcomposedstate, *realstarcomposedstate;
118: PetscReal *realcomposeddata, **realstarcomposeddata;
119: PetscInt scalar_idmax, scalarstar_idmax;
120: PetscObjectState *scalarcomposedstate, *scalarstarcomposedstate;
121: PetscScalar *scalarcomposeddata, **scalarstarcomposeddata;
122: void (**fortran_func_pointers)(void); /* used by Fortran interface functions to stash user provided Fortran functions */
123: PetscFortranCallbackId num_fortran_func_pointers; /* number of Fortran function pointers allocated */
124: PetscFortranCallback *fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
125: PetscFortranCallbackId num_fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
126: void *python_context;
127: PetscErrorCode (*python_destroy)(void *);
129: PetscInt noptionhandler;
130: PetscErrorCode (*optionhandler[PETSC_MAX_OPTIONS_HANDLER])(PetscObject, PetscOptionItems *, void *);
131: PetscErrorCode (*optiondestroy[PETSC_MAX_OPTIONS_HANDLER])(PetscObject, void *);
132: void *optionctx[PETSC_MAX_OPTIONS_HANDLER];
133: #if defined(PETSC_HAVE_SAWS)
134: PetscBool amsmem; /* if PETSC_TRUE then this object is registered with SAWs and visible to clients */
135: PetscBool amspublishblock; /* if PETSC_TRUE and publishing objects then will block at PetscObjectSAWsBlock() */
136: #endif
137: PetscOptions options; /* options database used, NULL means default */
138: PetscBool optionsprinted;
139: PetscBool donotPetscObjectPrintClassNamePrefixType;
140: } _p_PetscObject;
142: #define PETSCHEADER(ObjectOps) \
143: _p_PetscObject hdr; \
144: ObjectOps ops[1]
146: #define PETSCFREEDHEADER -1
148: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectDestroyFunction)(PetscObject *); /* force cast in next macro to NEVER use extern "C" style */
149: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectViewFunction)(PetscObject, PetscViewer);
151: /*MC
152: PetscHeaderCreate - Creates a PETSc object of a particular class
154: Synopsis:
155: #include <petsc/private/petscimpl.h>
156: PetscErrorCode PetscHeaderCreate(PetscObject h, PetscClassId classid, const char class_name[], const char descr[], const char mansec[], MPI_Comm comm, PetscObjectDestroyFunction destroy, PetscObjectViewFunction view)
158: Input Parameters:
159: + classid - The classid associated with this object (for example `VEC_CLASSID`)
160: . class_name - String name of class; should be static (for example "Vec"), may be
161: `PETSC_NULLPTR`
162: . descr - String containing short description; should be static (for example "Vector"),
163: may be `PETSC_NULLPTR`
164: . mansec - String indicating section in manual pages; should be static (for example "Vec"),
165: may be `PETSC_NULLPTR`
166: . comm - The MPI Communicator
167: . destroy - The destroy routine for this object (for example `VecDestroy()`)
168: - view - The view routine for this object (for example `VecView()`), may be
169: `PETSC_NULLPTR`
171: Output Parameter:
172: . h - The newly created `PetscObject`
174: Notes:
175: Can only be used to create a `PetscObject`. A `PetscObject` is defined as a pointer to a
176: C/C++ structure which satisfies all of the following\:
178: 1. The first member of the structure must be a `_p_PetscObject`.
179: 2. C++ structures must be "Standard Layout". Generally speaking a standard layout class\:
180: - Has no virtual functions or base classes.
181: - Has only standard layout non-static members (if any).
182: - Has only standard layout base classes (if any).
184: See https://en.cppreference.com/w/cpp/language/classes#Standard-layout_class for further
185: information.
187: Example Usage:
188: Existing `PetscObject`s may be easily created as shown. Unless otherwise stated, a particular
189: objects `destroy` and `view` functions are exactly `<OBJECT_TYPE>Destroy()` and
190: `<OBJECT_TYPE>View()`.
191: .vb
192: Vec v;
194: PetscHeaderCreate(v, VEC_CLASSID, "Vec", "A distributed vector class", "Vec", PETSC_COMM_WORLD, VecDestroy, VecView);
195: .ve
197: It is possible to create custom `PetscObject`s, note however that they must abide by the
198: restrictions set forth above.
199: .vb
200: // OK, first member of C structure is _p_PetscObject
201: struct MyCPetscObject_s
202: {
203: _p_PetscObject header;
204: int some_data;
205: };
206: typedef struct *MyCPetscObject_s MyCPetscObject;
208: PetscErrorCode MyObjectDestroy(MyObject *);
209: PetscErrorCode MyObjectView(MyObject);
211: MyCPetscObject obj;
213: // assume MY_PETSC_CLASSID is already registered
214: PetscHeaderCreate(obj, MY_PETSC_CLASSID, "MyObject", "A custom PetscObject", PETSC_NULLPTR, PETSC_COMM_SELF, MyObjectDestroy, MyObjectView);
216: // OK, only destroy function must be given, all others may be NULL
217: PetscHeaderCreate(obj, MY_PETSC_CLASSID, PETSC_NULLPTR, PETSC_NULLPTR, PETSC_NULLPTR, PETSC_COMM_SELF, MyObjectDestroy, PETSC_NULLPTR);
219: // ERROR must be a single-level pointer
220: PetscHeaderCreate(&obj, ...);
221: .ve
223: Illustrating proper construction from C++\:
224: .vb
225: // ERROR, class is not standard layout, first member must be publicly accessible
226: class BadCppPetscObject
227: {
228: _p_PetscObject header;
229: };
231: // ERROR, class is not standard layout, has a virtual function and virtual inheritance
232: class BadCppPetscObject2 : virtual BaseClass
233: {
234: public:
235: _p_PetscObject header;
237: virtual void foo();
238: };
240: // ERROR, class is not standard layout! Has non-standard layout member
241: class BadCppPetscObject2
242: {
243: public:
244: _p_PetscObject header;
245: BadCppPetscObject non_standard_layout;
246: };
248: // OK, class is standard layout!
249: class GoodCppPetscObject;
250: using MyCppObject = GoodCppPetscObject *;
252: // OK, non-virtual inheritance of other standard layout class does not affect layout
253: class GoodCppPetscObject : StandardLayoutClass
254: {
255: public:
256: // OK, non standard layout member is static, does not affect layout
257: static BadCppPetscObject non_standard_layout;
259: // OK, first non-static member is _p_PetscObject
260: _p_PetscObject header;
262: // OK, non-virtual member functions do not affect class layout
263: void foo();
265: // OK, may use "member" functions for destroy and view so long as they are static
266: static PetscErrorCode destroy(MyCppObject *);
267: static PetscErrorCode view(MyCppObject);
268: };
270: // OK, usage via pointer
271: MyObject obj;
273: PetscHeaderCreate(obj, MY_PETSC_CLASSID, "MyObject", "A custom C++ PetscObject", nullptr, PETSC_COMM_SELF, GoodCppPetscObject::destroy, GoodCppPetscObject::view);
274: .ve
276: Level: developer
278: .seealso: `PetscHeaderDestroy()`, `PetscClassIdRegister()`
279: M*/
280: #define PetscHeaderCreate(h, classid, class_name, descr, mansec, comm, destroy, view) \
281: (PetscNew(&(h)) || PetscHeaderCreate_Private((PetscObject)(h), classid, class_name, descr, mansec, comm, (PetscObjectDestroyFunction)(destroy), (PetscObjectViewFunction)(view)) || PetscLogObjectCreate(h))
283: PETSC_EXTERN PetscErrorCode PetscComposedQuantitiesDestroy(PetscObject obj);
284: PETSC_EXTERN PetscErrorCode PetscHeaderCreate_Private(PetscObject, PetscClassId, const char[], const char[], const char[], MPI_Comm, PetscObjectDestroyFunction, PetscObjectViewFunction);
285: PETSC_INTERN PetscObjectId PetscObjectNewId_Internal(void);
287: /*MC
288: PetscHeaderDestroy - Final step in destroying a `PetscObject`
290: Synopsis:
291: #include <petsc/private/petscimpl.h>
292: PetscErrorCode PetscHeaderDestroy(PetscObject *obj)
294: Input Parameters:
295: . h - A pointer to the header created with `PetscHeaderCreate()`
297: Notes:
298: `h` is freed and set to `PETSC_NULLPTR` when this routine returns.
300: Example Usage:
301: .vb
302: PetscObject obj;
304: PetscHeaderCreate(obj, ...);
305: // use obj...
307: // note pointer to obj is used
308: PetscHeaderDestroy(&obj);
309: .ve
311: Note that this routine is the _last_ step when destroying higher-level `PetscObject`s as it
312: deallocates the memory for the structure itself\:
313: .vb
314: typedef struct MyPetscObject_s *MyPetscObject;
315: struct MyPetscObject_s
316: {
317: _p_PetscObject hdr;
318: PetscInt *foo;
319: PetscScalar *bar;
320: };
322: // assume obj is created/initialized elsewhere...
323: MyPetscObject obj;
325: // OK, should dispose of all dynamically allocated resources before calling
326: // PetscHeaderDestroy()
327: PetscFree(obj->foo);
329: // OK, dispose of obj
330: PetscHeaderDestroy(&obj);
332: // ERROR, obj points to NULL here, accessing obj->bar may result in segmentation violation!
333: // obj->bar is potentially leaked!
334: PetscFree(obj->bar);
335: .ve
337: Level: developer
339: .seealso: `PetscHeaderCreate()`
340: M*/
341: #define PetscHeaderDestroy(h) (PetscHeaderDestroy_Private((PetscObject)(*(h)), PETSC_FALSE) || PetscFree(*(h)))
343: PETSC_EXTERN PetscErrorCode PetscHeaderDestroy_Private(PetscObject, PetscBool);
344: PETSC_SINGLE_LIBRARY_INTERN PetscErrorCode PetscHeaderReset_Internal(PetscObject);
345: PETSC_EXTERN PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject, PetscObject);
346: PETSC_EXTERN PetscErrorCode PetscObjectSetFortranCallback(PetscObject, PetscFortranCallbackType, PetscFortranCallbackId *, void (*)(void), void *ctx);
347: PETSC_EXTERN PetscErrorCode PetscObjectGetFortranCallback(PetscObject, PetscFortranCallbackType, PetscFortranCallbackId, void (**)(void), void **ctx);
349: PETSC_INTERN PetscErrorCode PetscCitationsInitialize(void);
350: PETSC_INTERN PetscErrorCode PetscFreeMPIResources(void);
351: PETSC_INTERN PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions, PetscBool *);
353: /* Code shared between C and Fortran */
354: PETSC_INTERN PetscErrorCode PetscInitialize_Common(const char *, const char *, const char *, PetscBool, PetscBool, PetscInt);
356: #if PetscDefined(HAVE_SETJMP_H)
358: #else
360: #endif
361: #if !defined(PETSC_CLANG_STATIC_ANALYZER)
362: /*
363: Macros to test if a PETSc object is valid and if pointers are valid
364: */
365: #if !defined(PETSC_USE_DEBUG)
368: do { \
369: (void)(h); \
370: } while (0)
372: do { \
373: (void)(h); \
374: } while (0)
376: do { \
377: (void)(h); \
378: } while (0)
380: do { \
381: (void)(h); \
382: } while (0)
384: do { \
385: (void)(h); \
386: } while (0)
388: do { \
389: (void)(h); \
390: } while (0)
392: do { \
393: (void)(h); \
394: } while (0)
396: do { \
397: (void)(h); \
398: } while (0)
400: do { \
401: (void)(h); \
402: } while (0)
404: do { \
405: (void)(h); \
406: } while (0)
408: do { \
409: (void)(h); \
410: } while (0)
412: do { \
413: (void)(h); \
414: } while (0)
416: #else
418: /* This check is for subtype methods such as DMDAGetCorners() that do not use the PetscTryMethod() or PetscUseMethod() paradigm */
420: do { \
421: PetscBool _7_same; \
423: PetscObjectTypeCompare((PetscObject)(h), t, &_7_same); \
425: } while (0)
428: do { \
431: } while (0)
434: do { \
436: if (((PetscObject)(h))->classid != ck) { \
438: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Wrong type of object: Parameter # %d", arg); \
439: } \
440: } while (0)
443: do { \
447: } while (0)
459: do { \
461: } while (0)
462: #endif
463: #else /* PETSC_CLANG_STATIC_ANALYZER */
464: template <typename T>
466: template <typename T>
468: template <typename T>
470: template <typename T>
472: template <typename T>
474: template <typename T>
476: template <typename T>
478: template <typename T>
480: template <typename T>
482: template <typename T>
484: template <typename T>
486: template <typename T>
488: template <typename T>
490: #endif /* PETSC_CLANG_STATIC_ANALYZER */
492: #define PetscSorted(n, idx, sorted) \
493: do { \
494: (sorted) = PETSC_TRUE; \
495: for (PetscInt _i_ = 1; _i_ < (n); ++_i_) { \
496: if ((idx)[_i_] < (idx)[_i_ - 1]) { \
497: (sorted) = PETSC_FALSE; \
498: break; \
499: } \
500: } \
501: } while (0)
503: #if !defined(PETSC_CLANG_STATIC_ANALYZER)
504: #if !defined(PETSC_USE_DEBUG)
507: do { \
508: (void)(a); \
509: (void)(b); \
510: } while (0)
512: do { \
513: (void)(a); \
514: } while (0)
516: do { \
517: (void)(a); \
518: } while (0)
520: do { \
521: (void)(a); \
522: } while (0)
524: do { \
525: (void)(a); \
526: (void)(b); \
527: } while (0)
529: do { \
530: (void)(a); \
531: (void)(b); \
532: } while (0)
534: do { \
535: (void)(a); \
536: (void)(b); \
537: } while (0)
539: do { \
540: (void)(a); \
541: (void)(b); \
542: } while (0)
544: do { \
545: (void)(a); \
546: (void)(b); \
547: } while (0)
549: do { \
550: (void)(a); \
551: (void)(b); \
552: } while (0)
554: do { \
555: (void)(a); \
556: (void)(b); \
557: } while (0)
559: do { \
560: (void)(a); \
561: (void)(b); \
562: } while (0)
564: do { \
565: (void)(n); \
566: (void)(idx); \
567: } while (0)
569: #else
571: /*
572: This macro currently does nothing, the plan is for each PetscObject to have a PetscInt "type"
573: member associated with the string type_name that can be quickly compared.
575: **Do not swap this macro to compare string type_name!**
577: This macro is used incorrectly in the code. Many places that do not need identity of the
578: types incorrectly call this check and would need to be fixed if this macro is enabled.
579: */
580: #if 0
582: do { \
583: PetscBool pcst_type_eq_ = PETSC_TRUE; \
584: PetscStrcmp(((PetscObject)(a))->type_name, (((PetscObject)(b)))->type_name, &pcst_type_eq_); \
586: } while (0)
587: #else
589: do { \
590: (void)(a); \
591: (void)(b); \
592: } while (0)
593: #endif
595: /*
596: Check type_name
597: */
599: do { \
600: PetscBool _7_match; \
601: PetscObjectTypeCompare(((PetscObject)(a)), (type), &_7_match); \
603: } while (0)
606: do { \
607: PetscBool _7_match; \
608: PetscObjectTypeCompareAny(((PetscObject)(a)), &_7_match, (type1), (type2), ""); \
610: } while (0)
612: /*
613: Use this macro to check if the type is set
614: */
617: /*
618: Sometimes object must live on same communicator to inter-operate
619: */
621: do { \
622: PetscMPIInt _7_flag; \
623: MPI_Comm_compare(PetscObjectComm((PetscObject)(a)), PetscObjectComm((PetscObject)(b)), &_7_flag); \
625: } while (0)
628: do { \
631: } while (0)
634: do { \
635: PetscScalar b0 = (b); \
636: PetscReal b1[5], b2[5]; \
637: if (PetscIsNanScalar(b0)) { \
638: b1[4] = 1; \
639: } else { \
640: b1[4] = 0; \
641: }; \
642: b1[0] = -PetscRealPart(b0); \
643: b1[1] = PetscRealPart(b0); \
644: b1[2] = -PetscImaginaryPart(b0); \
645: b1[3] = PetscImaginaryPart(b0); \
646: MPIU_Allreduce(b1, b2, 5, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)(a))); \
648: } while (0)
651: do { \
652: PetscReal b0 = (b), b1[3], b2[3]; \
653: if (PetscIsNanReal(b0)) { \
654: b1[2] = 1; \
655: } else { \
656: b1[2] = 0; \
657: }; \
658: b1[0] = -b0; \
659: b1[1] = b0; \
660: MPIU_Allreduce(b1, b2, 3, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)(a))); \
662: } while (0)
665: do { \
666: PetscInt b0 = (b), b1[2], b2[2]; \
667: b1[0] = -b0; \
668: b1[1] = b0; \
669: MPIU_Allreduce(b1, b2, 2, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)(a))); \
671: } while (0)
674: do { \
675: PetscMPIInt b0 = (b), b1[2], b2[2]; \
676: b1[0] = -b0; \
677: b1[1] = b0; \
678: MPIU_Allreduce(b1, b2, 2, MPI_INT, MPI_MAX, PetscObjectComm((PetscObject)(a))); \
680: } while (0)
683: do { \
684: PetscMPIInt b0 = (PetscMPIInt)(b), b1[2], b2[2]; \
685: b1[0] = -b0; \
686: b1[1] = b0; \
687: MPIU_Allreduce(b1, b2, 2, MPI_INT, MPI_MAX, PetscObjectComm((PetscObject)(a))); \
689: } while (0)
692: do { \
693: PetscMPIInt b0 = (PetscMPIInt)(b), b1[2], b2[2]; \
694: b1[0] = -b0; \
695: b1[1] = b0; \
696: MPIU_Allreduce(b1, b2, 2, MPI_INT, MPI_MAX, PetscObjectComm((PetscObject)(a))); \
698: } while (0)
701: do { \
702: PetscBool _1_flg; \
703: PetscSorted(n, idx, _1_flg); \
705: } while (0)
707: #endif
708: #else /* PETSC_CLANG_STATIC_ANALYZER */
709: template <typename Ta, typename Tb>
711: template <typename Ta, typename Tb>
713: template <typename Ta, typename Tb, typename Tc>
715: template <typename T>
717: template <typename Ta, typename Tb>
719: template <typename Ta, typename Tb>
721: template <typename Ta, typename Tb>
723: template <typename Ta, typename Tb>
725: template <typename Ta, typename Tb>
727: template <typename Ta, typename Tb>
729: template <typename Ta, typename Tb>
731: template <typename Ta, typename Tb>
733: template <typename T>
735: #endif /* PETSC_CLANG_STATIC_ANALYZER */
737: /*MC
738: PetscTryMethod - Queries an object for a method added with `PetscObjectComposeFunction()`, if it exists then calls it.
740: Synopsis:
741: #include "petsc/private/petscimpl.h"
742: PetscTryMethod(PetscObject obj,const char *name,(arg_types),(arg_value))
744: Input Parameters:
745: + obj - the object
746: . name - the name of the method, for example, "KSPGMRESSetRestart_C" for the function `KSPGMRESSetRestart()`
747: . arg_types - the argument types for the method, for example, (KSP,PetscInt)
748: - args - the arguments for the method, for example, (ksp,restart))
750: Level: developer
752: Notes:
753: The object is always the implicit first argument of the method and is not listed in arg_types or args
755: This does not return an error code, it is a macro that returns with an error code on error.
757: Use `PetscUseTypeMethod()` or `PetscTryTypeMethod()` to call functions that are included in the objects function table, the `ops` array
758: in the object.
761: M*/
762: #define PetscTryMethod(obj, A, B, C) \
763: do { \
764: PetscErrorCode(*_7_f) B; \
765: PetscObjectQueryFunction((PetscObject)(obj), A, &_7_f); \
766: if (_7_f) (*_7_f)C; \
767: } while (0)
769: /*MC
770: PetscUseMethod - Queries an object for a method added with `PetscObjectComposeFunction()`, if it exists then calls it, otherwise generates an error.
772: Synopsis:
773: #include "petsc/private/petscimpl.h"
774: PetscUseMethod(PetscObject obj,const char *name,(arg_types),(arg_value))
776: Input Parameters:
777: + obj - the object
778: . name - the name of the method, for example, "KSPGMRESSetRestart_C" for the function `KSPGMRESSetRestart()`
779: . arg_types - the argument types for the method, for example, (KSP,PetscInt)
780: - args - the arguments for the method, for example, (ksp,restart))
782: Level: developer
784: Notes:
785: The object is always the implicit first argument of the method and is not listed in arg_types or args
787: This does not return an error code, it is a macro that returns with an error code on error.
789: Use `PetscUseTypeMethod()` or `PetscTryTypeMethod()` to call functions that are included in the objects function table, the `ops` array
790: in the object.
793: M*/
794: #define PetscUseMethod(obj, A, B, C) \
795: do { \
796: PetscErrorCode(*_7_f) B; \
797: PetscObjectQueryFunction((PetscObject)(obj), A, &_7_f); \
799: (*_7_f)C; \
800: } while (0)
802: /*
803: Use Microsoft traditional preprocessor.
805: The Microsoft compiler option -Zc:preprocessor available in recent versions of the compiler
806: sets _MSVC_TRADITIONAL to zero so this code path is not used.
808: It appears the Intel Windows compiler icl does not have an equaivalent of -Zc:preprocessor
810: These macros use the trick that Windows compilers remove the , before the __VA_ARGS__ if __VA_ARGS__ does not exist
812: PetscCall() cannot be used in the macros because the remove the , trick does not work in a macro in a macro
813: */
814: #if (defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) || defined(__ICL)
816: #define PetscUseTypeMethod(obj, OP, ...) \
817: do { \
818: PetscErrorCode ierr_p_; \
819: PetscStackUpdateLine; \
821: ierr_p_ = (*(obj)->ops->OP)(obj, __VA_ARGS__); \
822: ierr_p_; \
823: } while (0)
825: #define PetscTryTypeMethod(obj, OP, ...) \
826: do { \
827: if ((obj)->ops->OP) { \
828: PetscErrorCode ierr_p_; \
829: PetscStackUpdateLine; \
830: ierr_p_ = (*(obj)->ops->OP)(obj, __VA_ARGS__); \
831: ierr_p_; \
832: } \
833: } while (0)
835: #else
837: /*MC
838: PetscUseTypeMethod - Call a method on a PETSc object, that is a function in the objects function table obj->ops, error if the method does not exist
840: Synopsis:
841: #include "petsc/private/petscimpl.h"
842: PetscUseTypeMethod(obj,method,other_args)
844: Input Parameters:
845: + obj - the object the method is called on
846: . method - the name of the method, for example, mult for the PETSc routine MatMult()
847: - other_args - the other arguments for the method, obj is the first argument
849: Level: developer
851: Note:
852: This does not return an error code, it is a macro that returns with an error code on error.
854: Use `PetscUseMethod()` or `PetscTryMethod()` to call functions that have been composed to an object with `PetscObjectComposeFunction()`
857: M*/
858: #define PetscUseTypeMethod(obj, ...) \
859: do { \
861: PetscStringize(PETSC_FIRST_ARG((__VA_ARGS__,unused))), ((PetscObject)obj)->class_name, ((PetscObject)obj)->type_name); \
862: (*(obj)->ops->PETSC_FIRST_ARG((__VA_ARGS__, unused)))(obj PETSC_REST_ARG(__VA_ARGS__)); \
863: } while (0)
865: /*MC
866: PetscTryTypeMethod - Call a method on a PETSc object, that is a function in the objects function table obj->ops, skip if the method does not exist
868: Synopsis:
869: #include "petsc/private/petscimpl.h"
870: PetscTryTtype(obj,method,other_args)
872: Input Parameters:
873: + obj - the object the method is called on
874: . method - the name of the method, for example, mult for the PETSc routine MatMult()
875: - other_args - the other arguments for the method, obj is the first argument
877: Level: developer
879: Note:
880: This does not return an error code, it is a macro that returns with an error code on error.
882: Use `PetscUseMethod()` or `PetscTryMethod()` to call functions that have been composed to an object with `PetscObjectComposeFunction()`
885: M*/
886: #define PetscTryTypeMethod(obj, ...) \
887: do { \
888: if ((obj)->ops->PETSC_FIRST_ARG((__VA_ARGS__, unused))) (*(obj)->ops->PETSC_FIRST_ARG((__VA_ARGS__, unused)))(obj PETSC_REST_ARG(__VA_ARGS__)); \
889: } while (0)
891: #endif
893: /*MC
894: PetscObjectStateIncrease - Increases the state of any `PetscObject`
896: Synopsis:
897: #include "petsc/private/petscimpl.h"
898: PetscErrorCode PetscObjectStateIncrease(PetscObject obj)
900: Logically Collective
902: Input Parameter:
903: . obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`. This must be
904: cast with a (PetscObject), for example,
905: `PetscObjectStateIncrease`((`PetscObject`)mat);
907: Notes:
908: Object state is a 64 bit integer which gets increased every time
909: the object is changed internally. By saving and later querying the object state
910: one can determine whether information about the object is still current.
911: Currently, state is maintained for `Vec` and `Mat` objects.
913: This routine is mostly for internal use by PETSc; a developer need only
914: call it after explicit access to an object's internals. Routines such
915: as `VecSet()` or `MatScale()` already call this routine. It is also called, as a
916: precaution, in `VecRestoreArray()`, `MatRestoreRow()`, `MatDenseRestoreArray()`.
918: Routines such as `VecNorm()` can by-pass the computation if the norm has already been computed and the vector's state has not changed.
920: This routine is logically collective because state equality comparison needs to be possible without communication.
922: `Mat` also has `MatGetNonzeroState()` for tracking changes to the nonzero structure.
924: Level: developer
926: .seealso: `PetscObjectStateGet()`, `PetscObject`
928: M*/
929: #define PetscObjectStateIncrease(obj) ((obj)->state++, 0)
931: PETSC_EXTERN PetscErrorCode PetscObjectStateGet(PetscObject, PetscObjectState *);
932: PETSC_EXTERN PetscErrorCode PetscObjectStateSet(PetscObject, PetscObjectState);
933: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataRegister(PetscInt *);
934: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject);
935: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject);
936: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject);
937: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject);
938: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject);
939: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject);
940: PETSC_EXTERN PetscInt PetscObjectComposedDataMax;
942: /*MC
943: PetscObjectComposedDataSetInt - attach integer data to a `PetscObject` that may be accessed with `PetscObjectComposedDataGetInt()`
945: Synopsis:
946: #include "petsc/private/petscimpl.h"
947: PetscErrorCode PetscObjectComposedDataSetInt(PetscObject obj,int id,int data)
949: Not collective
951: Input parameters:
952: + obj - the object to which data is to be attached
953: . id - the identifier for the data
954: - data - the data to be attached
956: Notes:
957: The data identifier can be created through a call to `PetscObjectComposedDataRegister()`
959: This allows the efficient composition of a single integer value with a `PetscObject`. Complex data may be
960: attached with `PetscObjectCompose()`
962: Level: developer
964: .seealso: `PetscObjectComposedDataGetInt()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetReal()`,
965: `PetscObjectComposedDataGetIntstar()`, `PetscObjectComposedDataSetIntstar()`, `PetscObject`,
966: `PetscObjectCompose()`, `PetscObjectQuery()`
967: M*/
968: #define PetscObjectComposedDataSetInt(obj, id, data) ((((obj)->int_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseInt(obj)) || ((obj)->intcomposeddata[id] = data, (obj)->intcomposedstate[id] = (obj)->state, 0))
970: /*MC
971: PetscObjectComposedDataGetInt - retrieve integer data attached to an object with `PetscObjectComposedDataSetInt()`
973: Synopsis:
974: #include "petsc/private/petscimpl.h"
975: PetscErrorCode PetscObjectComposedDataGetInt(PetscObject obj,int id,int data,PetscBool flag)
977: Not collective
979: Input parameters:
980: + obj - the object from which data is to be retrieved
981: - id - the identifier for the data
983: Output parameters:
984: + data - the data to be retrieved
985: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
987: Level: developer
989: Notes:
990: The 'data' and 'flag' variables are inlined, so they are not pointers.
992: The length of the array accessed must be known.
994: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetReal()`,
995: `PetscObjectComposedDataGetIntstar()`, `PetscObjectComposedDataSetIntstar()`, `PetscObject`,
996: `PetscObjectCompose()`, `PetscObjectQuery()`
997: M*/
998: #define PetscObjectComposedDataGetInt(obj, id, data, flag) (((obj)->intcomposedstate ? (data = (obj)->intcomposeddata[id], flag = (PetscBool)((obj)->intcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
1000: /*MC
1001: PetscObjectComposedDataSetIntstar - attach an integer array data to a `PetscObject` that may be accessed with `PetscObjectComposedDataGetIntstar()`
1003: Synopsis:
1004: #include "petsc/private/petscimpl.h"
1005: PetscErrorCode PetscObjectComposedDataSetIntstar(PetscObject obj,int id,int *data)
1007: Not collective
1009: Input parameters:
1010: + obj - the object to which data is to be attached
1011: . id - the identifier for the data
1012: - data - the data to be attached
1014: Notes:
1015: The data identifier can be determined through a call to `PetscObjectComposedDataRegister()`
1017: The length of the array accessed must be known, it is not available through this API.
1019: Level: developer
1021: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetReal()`,
1022: `PetscObjectComposedDataGetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1023: `PetscObjectCompose()`, `PetscObjectQuery()`
1024: M*/
1025: #define PetscObjectComposedDataSetIntstar(obj, id, data) \
1026: ((((obj)->intstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseIntstar(obj)) || ((obj)->intstarcomposeddata[id] = data, (obj)->intstarcomposedstate[id] = (obj)->state, 0))
1028: /*MC
1029: PetscObjectComposedDataGetIntstar - retrieve integer array data attached to an object with `PetscObjectComposedDataSetIntstar()`
1031: Synopsis:
1032: #include "petsc/private/petscimpl.h"
1033: PetscErrorCode PetscObjectComposedDataGetIntstar(PetscObject obj,int id,int *data,PetscBool flag)
1035: Not collective
1037: Input parameters:
1038: + obj - the object from which data is to be retrieved
1039: - id - the identifier for the data
1041: Output parameters:
1042: + data - the data to be retrieved
1043: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
1045: Notes:
1046: The 'data' and 'flag' variables are inlined, so they are not pointers.
1048: The length of the array accessed must be known, it is not available through this API.
1050: Level: developer
1052: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetReal()`,
1053: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1054: `PetscObjectCompose()`, `PetscObjectQuery()`
1055: M*/
1056: #define PetscObjectComposedDataGetIntstar(obj, id, data, flag) (((obj)->intstarcomposedstate ? (data = (obj)->intstarcomposeddata[id], flag = (PetscBool)((obj)->intstarcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
1058: /*MC
1059: PetscObjectComposedDataSetReal - attach real data to a `PetscObject` that may be accessed with `PetscObjectComposedDataGetReal()`
1061: Synopsis:
1062: #include "petsc/private/petscimpl.h"
1063: PetscErrorCode PetscObjectComposedDataSetReal(PetscObject obj,int id,PetscReal data)
1065: Not collective
1067: Input parameters:
1068: + obj - the object to which data is to be attached
1069: . id - the identifier for the data
1070: - data - the data to be attached
1072: Note:
1073: The data identifier can be determined through a call to `PetscObjectComposedDataRegister()`
1075: Level: developer
1077: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
1078: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1079: `PetscObjectCompose()`, `PetscObjectQuery()`
1080: M*/
1081: #define PetscObjectComposedDataSetReal(obj, id, data) ((((obj)->real_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseReal(obj)) || ((obj)->realcomposeddata[id] = data, (obj)->realcomposedstate[id] = (obj)->state, 0))
1083: /*MC
1084: PetscObjectComposedDataGetReal - retrieve real data attached to an object set with `PetscObjectComposedDataSetReal()`
1086: Synopsis:
1087: #include "petsc/private/petscimpl.h"
1088: PetscErrorCode PetscObjectComposedDataGetReal(PetscObject obj,int id,PetscReal data,PetscBool flag)
1090: Not collective
1092: Input parameters:
1093: + obj - the object from which data is to be retrieved
1094: - id - the identifier for the data
1096: Output parameters:
1097: + data - the data to be retrieved
1098: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
1100: Note:
1101: The 'data' and 'flag' variables are inlined, so they are not pointers.
1103: Level: developer
1105: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataSetIntstar()`,
1106: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1107: `PetscObjectCompose()`, `PetscObjectQuery()`
1108: M*/
1109: #define PetscObjectComposedDataGetReal(obj, id, data, flag) (((obj)->realcomposedstate ? (data = (obj)->realcomposeddata[id], flag = (PetscBool)((obj)->realcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
1111: /*MC
1112: PetscObjectComposedDataSetRealstar - attach real array data to a `PetscObject` that may be retrieved with `PetscObjectComposedDataGetRealstar()`
1114: Synopsis:
1115: #include "petsc/private/petscimpl.h"
1116: PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *data)
1118: Not collective
1120: Input parameters:
1121: + obj - the object to which data is to be attached
1122: . id - the identifier for the data
1123: - data - the data to be attached
1125: Notes:
1126: The data identifier can be determined through a call to `PetscObjectComposedDataRegister()`
1128: The length of the array accessed must be known, it is not available through this API.
1130: Level: developer
1132: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
1133: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1134: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataGetRealstar()`
1135: M*/
1136: #define PetscObjectComposedDataSetRealstar(obj, id, data) \
1137: ((((obj)->realstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseRealstar(obj)) || ((obj)->realstarcomposeddata[id] = data, (obj)->realstarcomposedstate[id] = (obj)->state, 0))
1139: /*MC
1140: PetscObjectComposedDataGetRealstar - retrieve real array data attached to an object with `PetscObjectComposedDataSetRealstar()`
1142: Synopsis:
1143: #include "petsc/private/petscimpl.h"
1144: PetscErrorCode PetscObjectComposedDataGetRealstar(PetscObject obj,int id,PetscReal *data,PetscBool flag)
1146: Not collective
1148: Input parameters:
1149: + obj - the object from which data is to be retrieved
1150: - id - the identifier for the data
1152: Output parameters:
1153: + data - the data to be retrieved
1154: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
1156: Notes:
1157: The 'data' and 'flag' variables are inlined, so they are not pointers.
1159: The length of the array accessed must be known, it is not available through this API.
1161: Level: developer
1163: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
1164: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1165: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`
1166: M*/
1167: #define PetscObjectComposedDataGetRealstar(obj, id, data, flag) (((obj)->realstarcomposedstate ? (data = (obj)->realstarcomposeddata[id], flag = (PetscBool)((obj)->realstarcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
1169: /*MC
1170: PetscObjectComposedDataSetScalar - attach scalar data to a PetscObject that may be retrieved with `PetscObjectComposedDataGetScalar()`
1172: Synopsis:
1173: #include "petsc/private/petscimpl.h"
1174: PetscErrorCode PetscObjectComposedDataSetScalar(PetscObject obj,int id,PetscScalar data)
1176: Not collective
1178: Input parameters:
1179: + obj - the object to which data is to be attached
1180: . id - the identifier for the data
1181: - data - the data to be attached
1183: Note:
1184: The data identifier can be determined through a call to `PetscObjectComposedDataRegister()`
1186: Level: developer
1188: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
1189: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1190: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataGetScalar()`
1191: M*/
1192: #if defined(PETSC_USE_COMPLEX)
1193: #define PetscObjectComposedDataSetScalar(obj, id, data) ((((obj)->scalar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalar(obj)) || ((obj)->scalarcomposeddata[id] = data, (obj)->scalarcomposedstate[id] = (obj)->state, 0))
1194: #else
1195: #define PetscObjectComposedDataSetScalar(obj, id, data) PetscObjectComposedDataSetReal(obj, id, data)
1196: #endif
1197: /*MC
1198: PetscObjectComposedDataGetScalar - retrieve scalar data attached to an object that was set with `PetscObjectComposedDataSetScalar()`
1200: Synopsis:
1201: #include "petsc/private/petscimpl.h"
1202: PetscErrorCode PetscObjectComposedDataGetScalar(PetscObject obj,int id,PetscScalar data,PetscBool flag)
1204: Not collective
1206: Input parameters:
1207: + obj - the object from which data is to be retrieved
1208: - id - the identifier for the data
1210: Output parameters:
1211: + data - the data to be retrieved
1212: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
1214: Note:
1215: The 'data' and 'flag' variables are inlined, so they are not pointers.
1217: Level: developer
1219: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
1220: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1221: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataSetScalar()`
1222: M*/
1223: #if defined(PETSC_USE_COMPLEX)
1224: #define PetscObjectComposedDataGetScalar(obj, id, data, flag) (((obj)->scalarcomposedstate ? (data = (obj)->scalarcomposeddata[id], flag = (PetscBool)((obj)->scalarcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
1225: #else
1226: #define PetscObjectComposedDataGetScalar(obj, id, data, flag) PetscObjectComposedDataGetReal(obj, id, data, flag)
1227: #endif
1229: /*MC
1230: PetscObjectComposedDataSetScalarstar - attach scalar array data to a `PetscObject` that may be retrieved with `PetscObjectComposedDataSetScalarstar()`
1232: Synopsis:
1233: #include "petsc/private/petscimpl.h"
1234: PetscErrorCode PetscObjectComposedDataSetScalarstar(PetscObject obj,int id,PetscScalar *data)
1236: Not collective
1238: Input parameters:
1239: + obj - the object to which data is to be attached
1240: . id - the identifier for the data
1241: - data - the data to be attached
1243: Notes:
1244: The data identifier can be determined through a call to `PetscObjectComposedDataRegister()`
1246: The length of the array accessed must be known, it is not available through this API.
1248: Level: developer
1250: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
1251: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1252: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataGetScalarstar()`
1253: M*/
1254: #if defined(PETSC_USE_COMPLEX)
1255: #define PetscObjectComposedDataSetScalarstar(obj, id, data) \
1256: ((((obj)->scalarstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalarstar(obj)) || ((obj)->scalarstarcomposeddata[id] = data, (obj)->scalarstarcomposedstate[id] = (obj)->state, 0))
1257: #else
1258: #define PetscObjectComposedDataSetScalarstar(obj, id, data) PetscObjectComposedDataSetRealstar(obj, id, data)
1259: #endif
1260: /*MC
1261: PetscObjectComposedDataGetScalarstar - retrieve scalar array data set with `PetscObjectComposedDataSetScalarstar()`
1262: attached to an object
1264: Synopsis:
1265: #include "petsc/private/petscimpl.h"
1266: PetscErrorCode PetscObjectComposedDataGetScalarstar(PetscObject obj,int id,PetscScalar *data,PetscBool flag)
1268: Not collective
1270: Input parameters:
1271: + obj - the object from which data is to be retrieved
1272: - id - the identifier for the data
1274: Output parameters:
1275: + data - the data to be retrieved
1276: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
1278: Notes:
1279: The 'data' and 'flag' variables are inlined, so they are not pointers.
1281: The length of the array accessed must be known, it is not available through this API.
1283: Level: developer
1285: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
1286: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1287: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataSetScalarstar()`
1288: M*/
1289: #if defined(PETSC_USE_COMPLEX)
1290: #define PetscObjectComposedDataGetScalarstar(obj, id, data, flag) (((obj)->scalarstarcomposedstate ? (data = (obj)->scalarstarcomposeddata[id], flag = (PetscBool)((obj)->scalarstarcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
1291: #else
1292: #define PetscObjectComposedDataGetScalarstar(obj, id, data, flag) PetscObjectComposedDataGetRealstar(obj, id, data, flag)
1293: #endif
1295: PETSC_EXTERN PetscMPIInt Petsc_Counter_keyval;
1296: PETSC_EXTERN PetscMPIInt Petsc_InnerComm_keyval;
1297: PETSC_EXTERN PetscMPIInt Petsc_OuterComm_keyval;
1298: PETSC_EXTERN PetscMPIInt Petsc_Seq_keyval;
1299: PETSC_EXTERN PetscMPIInt Petsc_ShmComm_keyval;
1300: PETSC_EXTERN PetscMPIInt Petsc_CreationIdx_keyval;
1301: PETSC_EXTERN PetscMPIInt Petsc_Garbage_HMap_keyval;
1303: struct PetscCommStash {
1304: struct PetscCommStash *next;
1305: MPI_Comm comm;
1306: };
1308: /*
1309: PETSc communicators have this attribute, see
1310: PetscCommDuplicate(), PetscCommDestroy(), PetscCommGetNewTag(), PetscObjectGetName()
1311: */
1312: typedef struct {
1313: PetscMPIInt tag; /* next free tag value */
1314: PetscInt refcount; /* number of references, communicator can be freed when this reaches 0 */
1315: PetscInt namecount; /* used to generate the next name, as in Vec_0, Mat_1, ... */
1316: PetscMPIInt *iflags; /* length of comm size, shared by all calls to PetscCommBuildTwoSided_Allreduce/RedScatter on this comm */
1317: struct PetscCommStash *comms; /* communicators available for PETSc to pass off to other packages */
1318: } PetscCommCounter;
1320: typedef enum {
1321: STATE_BEGIN,
1322: STATE_PENDING,
1323: STATE_END
1324: } SRState;
1326: typedef enum {
1327: PETSC_SR_REDUCE_SUM = 0,
1328: PETSC_SR_REDUCE_MAX = 1,
1329: PETSC_SR_REDUCE_MIN = 2
1330: } PetscSRReductionType;
1332: typedef struct {
1333: MPI_Comm comm;
1334: MPI_Request request;
1335: PetscBool mix;
1336: PetscBool async;
1337: PetscScalar *lvalues; /* this are the reduced values before call to MPI_Allreduce() */
1338: PetscScalar *gvalues; /* values after call to MPI_Allreduce() */
1339: void **invecs; /* for debugging only, vector/memory used with each op */
1340: PetscInt *reducetype; /* is particular value to be summed or maxed? */
1341: struct {
1342: PetscScalar v;
1343: PetscInt i;
1344: } *lvalues_mix, *gvalues_mix; /* used when mixing reduce operations */
1345: SRState state; /* are we calling xxxBegin() or xxxEnd()? */
1346: PetscInt maxops; /* total amount of space we have for requests */
1347: PetscInt numopsbegin; /* number of requests that have been queued in */
1348: PetscInt numopsend; /* number of requests that have been gotten by user */
1349: } PetscSplitReduction;
1351: PETSC_EXTERN PetscErrorCode PetscSplitReductionGet(MPI_Comm, PetscSplitReduction **);
1352: PETSC_EXTERN PetscErrorCode PetscSplitReductionEnd(PetscSplitReduction *);
1353: PETSC_EXTERN PetscErrorCode PetscSplitReductionExtend(PetscSplitReduction *);
1355: #if !defined(PETSC_SKIP_SPINLOCK)
1356: #if defined(PETSC_HAVE_THREADSAFETY)
1357: #if defined(PETSC_HAVE_CONCURRENCYKIT)
1358: #if defined(__cplusplus)
1359: /* CK does not have extern "C" protection in their include files */
1360: extern "C" {
1361: #endif
1362: #include <ck_spinlock.h>
1363: #if defined(__cplusplus)
1364: }
1365: #endif
1366: typedef ck_spinlock_t PetscSpinlock;
1367: static inline PetscErrorCode PetscSpinlockCreate(PetscSpinlock *ck_spinlock)
1368: {
1369: ck_spinlock_init(ck_spinlock);
1370: return 0;
1371: }
1372: static inline PetscErrorCode PetscSpinlockLock(PetscSpinlock *ck_spinlock)
1373: {
1374: ck_spinlock_lock(ck_spinlock);
1375: return 0;
1376: }
1377: static inline PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *ck_spinlock)
1378: {
1379: ck_spinlock_unlock(ck_spinlock);
1380: return 0;
1381: }
1382: static inline PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *ck_spinlock)
1383: {
1384: return 0;
1385: }
1386: #elif defined(PETSC_HAVE_OPENMP)
1388: #include <omp.h>
1389: typedef omp_lock_t PetscSpinlock;
1390: static inline PetscErrorCode PetscSpinlockCreate(PetscSpinlock *omp_lock)
1391: {
1392: omp_init_lock(omp_lock);
1393: return 0;
1394: }
1395: static inline PetscErrorCode PetscSpinlockLock(PetscSpinlock *omp_lock)
1396: {
1397: omp_set_lock(omp_lock);
1398: return 0;
1399: }
1400: static inline PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *omp_lock)
1401: {
1402: omp_unset_lock(omp_lock);
1403: return 0;
1404: }
1405: static inline PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *omp_lock)
1406: {
1407: omp_destroy_lock(omp_lock);
1408: return 0;
1409: }
1410: #else
1411: #error "Thread safety requires either --with-openmp or --download-concurrencykit"
1412: #endif
1414: #else
1415: typedef int PetscSpinlock;
1416: #define PetscSpinlockCreate(a) 0
1417: #define PetscSpinlockLock(a) 0
1418: #define PetscSpinlockUnlock(a) 0
1419: #define PetscSpinlockDestroy(a) 0
1420: #endif
1422: #if defined(PETSC_HAVE_THREADSAFETY)
1423: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockOpen;
1424: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStdout;
1425: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStderr;
1426: PETSC_INTERN PetscSpinlock PetscCommSpinLock;
1427: #endif
1428: #endif
1430: PETSC_EXTERN PetscLogEvent PETSC_Barrier;
1431: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSided;
1432: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSidedF;
1433: PETSC_EXTERN PetscBool use_gpu_aware_mpi;
1434: PETSC_EXTERN PetscBool PetscPrintFunctionList;
1436: #if defined(PETSC_HAVE_ADIOS)
1437: PETSC_EXTERN int64_t Petsc_adios_group;
1438: #endif
1440: #if defined(PETSC_HAVE_KOKKOS)
1441: PETSC_INTERN PetscBool PetscBeganKokkos;
1442: PETSC_EXTERN PetscBool PetscKokkosInitialized;
1443: PETSC_INTERN PetscErrorCode PetscKokkosIsInitialized_Private(PetscBool *);
1444: PETSC_INTERN PetscErrorCode PetscKokkosFinalize_Private(void);
1445: #endif
1447: #if defined(PETSC_HAVE_OPENMP)
1448: PETSC_EXTERN PetscInt PetscNumOMPThreads;
1449: #endif
1451: #endif /* PETSCIMPL_H */