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: /*@C
152: PetscHeaderCreate - Creates a PETSc object of a particular class
154: Input Parameters:
155: + classid - the classid associated with this object (for example VEC_CLASSID)
156: . class_name - string name of class; should be static (for example "Vec")
157: . descr - string containing short description; should be static (for example "Vector")
158: . mansec - string indicating section in manual pages; should be static (for example "Vec")
159: . comm - the MPI Communicator
160: . destroy - the destroy routine for this object (for example `VecDestroy()`)
161: - view - the view routine for this object (for example `VecView()`)
163: Output Parameter:
164: . h - the newly created object
166: Level: developer
168: .seealso: `PetscHeaderDestroy()`, `PetscClassIdRegister()`
170: @*/
171: #define PetscHeaderCreate(h, classid, class_name, descr, mansec, comm, destroy, view) \
172: (PetscNew(&(h)) || PetscHeaderCreate_Private((PetscObject)(h), classid, class_name, descr, mansec, comm, (PetscObjectDestroyFunction)(destroy), (PetscObjectViewFunction)(view)) || PetscLogObjectCreate(h))
174: PETSC_EXTERN PetscErrorCode PetscComposedQuantitiesDestroy(PetscObject obj);
175: PETSC_EXTERN PetscErrorCode PetscHeaderCreate_Private(PetscObject, PetscClassId, const char[], const char[], const char[], MPI_Comm, PetscObjectDestroyFunction, PetscObjectViewFunction);
176: PETSC_INTERN PetscObjectId PetscObjectNewId_Internal(void);
178: /*@C
179: PetscHeaderDestroy - Final step in destroying a PetscObject
181: Input Parameters:
182: . h - the header created with `PetscHeaderCreate()`
184: Level: developer
186: .seealso: `PetscHeaderCreate()`
187: @*/
188: #define PetscHeaderDestroy(h) (PetscHeaderDestroy_Private((PetscObject)(*(h)), PETSC_FALSE) || PetscFree(*(h)))
190: PETSC_EXTERN PetscErrorCode PetscHeaderDestroy_Private(PetscObject, PetscBool);
191: PETSC_SINGLE_LIBRARY_INTERN PetscErrorCode PetscHeaderReset_Internal(PetscObject);
192: PETSC_EXTERN PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject, PetscObject);
193: PETSC_EXTERN PetscErrorCode PetscObjectSetFortranCallback(PetscObject, PetscFortranCallbackType, PetscFortranCallbackId *, void (*)(void), void *ctx);
194: PETSC_EXTERN PetscErrorCode PetscObjectGetFortranCallback(PetscObject, PetscFortranCallbackType, PetscFortranCallbackId, void (**)(void), void **ctx);
196: PETSC_INTERN PetscErrorCode PetscCitationsInitialize(void);
197: PETSC_INTERN PetscErrorCode PetscFreeMPIResources(void);
198: PETSC_INTERN PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions, PetscBool *);
200: /* Code shared between C and Fortran */
201: PETSC_INTERN PetscErrorCode PetscInitialize_Common(const char *, const char *, const char *, PetscBool, PetscBool, PetscInt);
203: #if PetscDefined(HAVE_SETJMP_H)
205: #else
207: #endif
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)
215: do { \
216: (void)(h); \
217: } while (0)
219: do { \
220: (void)(h); \
221: } while (0)
223: do { \
224: (void)(h); \
225: } while (0)
227: do { \
228: (void)(h); \
229: } while (0)
231: do { \
232: (void)(h); \
233: } while (0)
235: do { \
236: (void)(h); \
237: } while (0)
239: do { \
240: (void)(h); \
241: } while (0)
243: do { \
244: (void)(h); \
245: } while (0)
247: do { \
248: (void)(h); \
249: } while (0)
251: do { \
252: (void)(h); \
253: } while (0)
255: do { \
256: (void)(h); \
257: } while (0)
259: do { \
260: (void)(h); \
261: } while (0)
263: #else
265: /* This check is for subtype methods such as DMDAGetCorners() that do not use the PetscTryMethod() or PetscUseMethod() paradigm */
267: do { \
268: PetscBool _7_same; \
270: PetscObjectTypeCompare((PetscObject)(h), t, &_7_same); \
272: } while (0)
275: do { \
278: } while (0)
281: do { \
283: if (((PetscObject)(h))->classid != ck) { \
285: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Wrong type of object: Parameter # %d", arg); \
286: } \
287: } while (0)
290: do { \
294: } while (0)
306: do { \
308: } while (0)
309: #endif
310: #else /* PETSC_CLANG_STATIC_ANALYZER */
311: template <typename T>
313: template <typename T>
315: template <typename T>
317: template <typename T>
319: template <typename T>
321: template <typename T>
323: template <typename T>
325: template <typename T>
327: template <typename T>
329: template <typename T>
331: template <typename T>
333: template <typename T>
335: template <typename T>
337: #endif /* PETSC_CLANG_STATIC_ANALYZER */
339: #define PetscSorted(n, idx, sorted) \
340: do { \
341: (sorted) = PETSC_TRUE; \
342: for (PetscInt _i_ = 1; _i_ < (n); ++_i_) { \
343: if ((idx)[_i_] < (idx)[_i_ - 1]) { \
344: (sorted) = PETSC_FALSE; \
345: break; \
346: } \
347: } \
348: } while (0)
350: #if !defined(PETSC_CLANG_STATIC_ANALYZER)
351: #if !defined(PETSC_USE_DEBUG)
354: do { \
355: (void)(a); \
356: (void)(b); \
357: } while (0)
359: do { \
360: (void)(a); \
361: } while (0)
363: do { \
364: (void)(a); \
365: } while (0)
367: do { \
368: (void)(a); \
369: } while (0)
371: do { \
372: (void)(a); \
373: (void)(b); \
374: } while (0)
376: do { \
377: (void)(a); \
378: (void)(b); \
379: } while (0)
381: do { \
382: (void)(a); \
383: (void)(b); \
384: } while (0)
386: do { \
387: (void)(a); \
388: (void)(b); \
389: } while (0)
391: do { \
392: (void)(a); \
393: (void)(b); \
394: } while (0)
396: do { \
397: (void)(a); \
398: (void)(b); \
399: } while (0)
401: do { \
402: (void)(a); \
403: (void)(b); \
404: } while (0)
406: do { \
407: (void)(a); \
408: (void)(b); \
409: } while (0)
411: do { \
412: (void)(n); \
413: (void)(idx); \
414: } while (0)
416: #else
418: /*
419: This macro currently does nothing, the plan is for each PetscObject to have a PetscInt "type"
420: member associated with the string type_name that can be quickly compared.
422: **Do not swap this macro to compare string type_name!**
424: This macro is used incorrectly in the code. Many places that do not need identity of the
425: types incorrectly call this check and would need to be fixed if this macro is enabled.
426: */
427: #if 0
429: do { \
430: PetscBool pcst_type_eq_ = PETSC_TRUE; \
431: PetscStrcmp(((PetscObject)(a))->type_name, (((PetscObject)(b)))->type_name, &pcst_type_eq_); \
433: } while (0)
434: #else
436: do { \
437: (void)(a); \
438: (void)(b); \
439: } while (0)
440: #endif
442: /*
443: Check type_name
444: */
446: do { \
447: PetscBool _7_match; \
448: PetscObjectTypeCompare(((PetscObject)(a)), (type), &_7_match); \
450: } while (0)
453: do { \
454: PetscBool _7_match; \
455: PetscObjectTypeCompareAny(((PetscObject)(a)), &_7_match, (type1), (type2), ""); \
457: } while (0)
459: /*
460: Use this macro to check if the type is set
461: */
464: /*
465: Sometimes object must live on same communicator to inter-operate
466: */
468: do { \
469: PetscMPIInt _7_flag; \
470: MPI_Comm_compare(PetscObjectComm((PetscObject)(a)), PetscObjectComm((PetscObject)(b)), &_7_flag); \
472: } while (0)
475: do { \
478: } while (0)
481: do { \
482: PetscScalar b0 = (b); \
483: PetscReal b1[5], b2[5]; \
484: if (PetscIsNanScalar(b0)) { \
485: b1[4] = 1; \
486: } else { \
487: b1[4] = 0; \
488: }; \
489: b1[0] = -PetscRealPart(b0); \
490: b1[1] = PetscRealPart(b0); \
491: b1[2] = -PetscImaginaryPart(b0); \
492: b1[3] = PetscImaginaryPart(b0); \
493: MPIU_Allreduce(b1, b2, 5, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)(a))); \
495: } while (0)
498: do { \
499: PetscReal b0 = (b), b1[3], b2[3]; \
500: if (PetscIsNanReal(b0)) { \
501: b1[2] = 1; \
502: } else { \
503: b1[2] = 0; \
504: }; \
505: b1[0] = -b0; \
506: b1[1] = b0; \
507: MPIU_Allreduce(b1, b2, 3, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)(a))); \
509: } while (0)
512: do { \
513: PetscInt b0 = (b), b1[2], b2[2]; \
514: b1[0] = -b0; \
515: b1[1] = b0; \
516: MPIU_Allreduce(b1, b2, 2, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)(a))); \
518: } while (0)
521: do { \
522: PetscMPIInt b0 = (b), b1[2], b2[2]; \
523: b1[0] = -b0; \
524: b1[1] = b0; \
525: MPIU_Allreduce(b1, b2, 2, MPI_INT, MPI_MAX, PetscObjectComm((PetscObject)(a))); \
527: } while (0)
530: do { \
531: PetscMPIInt b0 = (PetscMPIInt)(b), b1[2], b2[2]; \
532: b1[0] = -b0; \
533: b1[1] = b0; \
534: MPIU_Allreduce(b1, b2, 2, MPI_INT, MPI_MAX, PetscObjectComm((PetscObject)(a))); \
536: } while (0)
539: do { \
540: PetscMPIInt b0 = (PetscMPIInt)(b), b1[2], b2[2]; \
541: b1[0] = -b0; \
542: b1[1] = b0; \
543: MPIU_Allreduce(b1, b2, 2, MPI_INT, MPI_MAX, PetscObjectComm((PetscObject)(a))); \
545: } while (0)
548: do { \
549: PetscBool _1_flg; \
550: PetscSorted(n, idx, _1_flg); \
552: } while (0)
554: #endif
555: #else /* PETSC_CLANG_STATIC_ANALYZER */
556: template <typename Ta, typename Tb>
558: template <typename Ta, typename Tb>
560: template <typename Ta, typename Tb, typename Tc>
562: template <typename T>
564: template <typename Ta, typename Tb>
566: template <typename Ta, typename Tb>
568: template <typename Ta, typename Tb>
570: template <typename Ta, typename Tb>
572: template <typename Ta, typename Tb>
574: template <typename Ta, typename Tb>
576: template <typename Ta, typename Tb>
578: template <typename Ta, typename Tb>
580: template <typename T>
582: #endif /* PETSC_CLANG_STATIC_ANALYZER */
584: /*MC
585: PetscTryMethod - Queries an object for a method added with `PetscObjectComposeFunction()`, if it exists then calls it.
587: Synopsis:
588: #include "petsc/private/petscimpl.h"
589: PetscTryMethod(PetscObject obj,const char *name,(arg_types),(arg_value))
591: Input Parameters:
592: + obj - the object
593: . name - the name of the method, for example, "KSPGMRESSetRestart_C" for the function `KSPGMRESSetRestart()`
594: . arg_types - the argument types for the method, for example, (KSP,PetscInt)
595: - args - the arguements for the method, for example, (ksp,restart))
597: Level: developer
599: Notes:
600: The object is always the implicit first argument of the method and is not listed in arg_types or args
602: This does not return an error code, it is a macro that returns with an error code on error.
604: Use `PetscUseTypeMethod()` or `PetscTryTypeMethod()` to call functions that are included in the objects function table, the `ops` array
605: in the object.
608: M*/
609: #define PetscTryMethod(obj, A, B, C) \
610: do { \
611: PetscErrorCode(*_7_f) B; \
612: PetscObjectQueryFunction((PetscObject)(obj), A, &_7_f); \
613: if (_7_f) (*_7_f)C; \
614: } while (0)
616: /*MC
617: PetscUseMethod - Queries an object for a method added with `PetscObjectComposeFunction()`, if it exists then calls it, otherwise generates an error.
619: Synopsis:
620: #include "petsc/private/petscimpl.h"
621: PetscUseMethod(PetscObject obj,const char *name,(arg_types),(arg_value))
623: Input Parameters:
624: + obj - the object
625: . name - the name of the method, for example, "KSPGMRESSetRestart_C" for the function `KSPGMRESSetRestart()`
626: . arg_types - the argument types for the method, for example, (KSP,PetscInt)
627: - args - the arguements for the method, for example, (ksp,restart))
629: Level: developer
631: Notes:
632: The object is always the implicit first argument of the method and is not listed in arg_types or args
634: This does not return an error code, it is a macro that returns with an error code on error.
636: Use `PetscUseTypeMethod()` or `PetscTryTypeMethod()` to call functions that are included in the objects function table, the `ops` array
637: in the object.
640: M*/
641: #define PetscUseMethod(obj, A, B, C) \
642: do { \
643: PetscErrorCode(*_7_f) B; \
644: PetscObjectQueryFunction((PetscObject)(obj), A, &_7_f); \
646: (*_7_f)C; \
647: } while (0)
649: /*
650: Use Microsoft traditional preprocessor.
652: The Microsoft compiler option -Zc:preprocessor available in recent versions of the compiler
653: sets _MSVC_TRADITIONAL to zero so this code path is not used.
655: It appears the Intel Windows compiler icl does not have an equaivalent of -Zc:preprocessor
657: These macros use the trick that Windows compilers remove the , before the __VA_ARGS__ if __VA_ARGS__ does not exist
659: PetscCall() cannot be used in the macros because the remove the , trick does not work in a macro in a macro
660: */
661: #if (defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) || defined(__ICL)
663: #define PetscUseTypeMethod(obj, OP, ...) \
664: do { \
665: PetscErrorCode ierr_p_; \
666: PetscStackUpdateLine; \
668: ierr_p_ = (*(obj)->ops->OP)(obj, __VA_ARGS__); \
669: ierr_p_; \
670: } while (0)
672: #define PetscTryTypeMethod(obj, OP, ...) \
673: do { \
674: if ((obj)->ops->OP) { \
675: PetscErrorCode ierr_p_; \
676: PetscStackUpdateLine; \
677: ierr_p_ = (*(obj)->ops->OP)(obj, __VA_ARGS__); \
678: ierr_p_; \
679: } \
680: } while (0)
682: #else
684: /*MC
685: 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
687: Synopsis:
688: #include "petsc/private/petscimpl.h"
689: PetscUseTypeMethod(obj,method,other_args)
691: Input Parameters:
692: + obj - the object the method is called on
693: . method - the name of the method, for example, mult for the PETSc routine MatMult()
694: - other_args - the other arguments for the method, obj is the first argument
696: Level: developer
698: Note:
699: This does not return an error code, it is a macro that returns with an error code on error.
701: Use `PetscUseMethod()` or `PetscTryMethod()` to call functions that have been composed to an object with `PetscObjectComposeFunction()`
704: M*/
705: #define PetscUseTypeMethod(obj, ...) \
706: do { \
708: PetscStringize(PETSC_FIRST_ARG((__VA_ARGS__,unused))), ((PetscObject)obj)->class_name, ((PetscObject)obj)->type_name); \
709: (*(obj)->ops->PETSC_FIRST_ARG((__VA_ARGS__, unused)))(obj PETSC_REST_ARG(__VA_ARGS__)); \
710: } while (0)
712: /*MC
713: 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
715: Synopsis:
716: #include "petsc/private/petscimpl.h"
717: PetscTryTtype(obj,method,other_args)
719: Input Parameters:
720: + obj - the object the method is called on
721: . method - the name of the method, for example, mult for the PETSc routine MatMult()
722: - other_args - the other arguments for the method, obj is the first argument
724: Level: developer
726: Note:
727: This does not return an error code, it is a macro that returns with an error code on error.
729: Use `PetscUseMethod()` or `PetscTryMethod()` to call functions that have been composed to an object with `PetscObjectComposeFunction()`
732: M*/
733: #define PetscTryTypeMethod(obj, ...) \
734: do { \
735: if ((obj)->ops->PETSC_FIRST_ARG((__VA_ARGS__, unused))) (*(obj)->ops->PETSC_FIRST_ARG((__VA_ARGS__, unused)))(obj PETSC_REST_ARG(__VA_ARGS__)); \
736: } while (0)
738: #endif
740: /*MC
741: PetscObjectStateIncrease - Increases the state of any `PetscObject`
743: Synopsis:
744: #include "petsc/private/petscimpl.h"
745: PetscErrorCode PetscObjectStateIncrease(PetscObject obj)
747: Logically Collective
749: Input Parameter:
750: . obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`. This must be
751: cast with a (PetscObject), for example,
752: `PetscObjectStateIncrease`((`PetscObject`)mat);
754: Notes:
755: Object state is a 64 bit integer which gets increased every time
756: the object is changed internally. By saving and later querying the object state
757: one can determine whether information about the object is still current.
758: Currently, state is maintained for `Vec` and `Mat` objects.
760: This routine is mostly for internal use by PETSc; a developer need only
761: call it after explicit access to an object's internals. Routines such
762: as `VecSet()` or `MatScale()` already call this routine. It is also called, as a
763: precaution, in `VecRestoreArray()`, `MatRestoreRow()`, `MatDenseRestoreArray()`.
765: Routines such as `VecNorm()` can by-pass the computation if the norm has already been computed and the vector's state has not changed.
767: This routine is logically collective because state equality comparison needs to be possible without communication.
769: `Mat` also has `MatGetNonzeroState()` and `MatSetNonzeroState()` for tracking changes to the nonzero structure.
771: Level: developer
773: .seealso: `PetscObjectStateGet()`, `MatSetNonzeroState()`, `PetscObject`
775: M*/
776: #define PetscObjectStateIncrease(obj) ((obj)->state++, 0)
778: PETSC_EXTERN PetscErrorCode PetscObjectStateGet(PetscObject, PetscObjectState *);
779: PETSC_EXTERN PetscErrorCode PetscObjectStateSet(PetscObject, PetscObjectState);
780: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataRegister(PetscInt *);
781: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject);
782: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject);
783: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject);
784: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject);
785: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject);
786: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject);
787: PETSC_EXTERN PetscInt PetscObjectComposedDataMax;
789: /*MC
790: PetscObjectComposedDataSetInt - attach integer data to a `PetscObject` that may be accessed with `PetscObjectComposedDataGetInt()`
792: Synopsis:
793: #include "petsc/private/petscimpl.h"
794: PetscErrorCode PetscObjectComposedDataSetInt(PetscObject obj,int id,int data)
796: Not collective
798: Input parameters:
799: + obj - the object to which data is to be attached
800: . id - the identifier for the data
801: - data - the data to be attached
803: Notes:
804: The data identifier can be created through a call to `PetscObjectComposedDataRegister()`
806: This allows the efficient composition of a single integer value with a `PetscObject`. Complex data may be
807: attached with `PetscObjectCompose()`
809: Level: developer
811: .seealso: `PetscObjectComposedDataGetInt()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetReal()`,
812: `PetscObjectComposedDataGetIntstar()`, `PetscObjectComposedDataSetIntstar()`, `PetscObject`,
813: `PetscObjectCompose()`, `PetscObjectQuery()`
814: M*/
815: #define PetscObjectComposedDataSetInt(obj, id, data) ((((obj)->int_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseInt(obj)) || ((obj)->intcomposeddata[id] = data, (obj)->intcomposedstate[id] = (obj)->state, 0))
817: /*MC
818: PetscObjectComposedDataGetInt - retrieve integer data attached to an object with `PetscObjectComposedDataSetInt()`
820: Synopsis:
821: #include "petsc/private/petscimpl.h"
822: PetscErrorCode PetscObjectComposedDataGetInt(PetscObject obj,int id,int data,PetscBool flag)
824: Not collective
826: Input parameters:
827: + obj - the object from which data is to be retrieved
828: - id - the identifier for the data
830: Output parameters:
831: + data - the data to be retrieved
832: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
834: Level: developer
836: Notes:
837: The 'data' and 'flag' variables are inlined, so they are not pointers.
839: The length of the array accessed must be known.
841: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetReal()`,
842: `PetscObjectComposedDataGetIntstar()`, `PetscObjectComposedDataSetIntstar()`, `PetscObject`,
843: `PetscObjectCompose()`, `PetscObjectQuery()`
844: M*/
845: #define PetscObjectComposedDataGetInt(obj, id, data, flag) (((obj)->intcomposedstate ? (data = (obj)->intcomposeddata[id], flag = (PetscBool)((obj)->intcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
847: /*MC
848: PetscObjectComposedDataSetIntstar - attach an integer array data to a `PetscObject` that may be accessed with `PetscObjectComposedDataGetIntstar()`
850: Synopsis:
851: #include "petsc/private/petscimpl.h"
852: PetscErrorCode PetscObjectComposedDataSetIntstar(PetscObject obj,int id,int *data)
854: Not collective
856: Input parameters:
857: + obj - the object to which data is to be attached
858: . id - the identifier for the data
859: - data - the data to be attached
861: Notes:
862: The data identifier can be determined through a call to `PetscObjectComposedDataRegister()`
864: The length of the array accessed must be known, it is not available through this API.
866: Level: developer
868: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetReal()`,
869: `PetscObjectComposedDataGetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
870: `PetscObjectCompose()`, `PetscObjectQuery()`
871: M*/
872: #define PetscObjectComposedDataSetIntstar(obj, id, data) \
873: ((((obj)->intstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseIntstar(obj)) || ((obj)->intstarcomposeddata[id] = data, (obj)->intstarcomposedstate[id] = (obj)->state, 0))
875: /*MC
876: PetscObjectComposedDataGetIntstar - retrieve integer array data attached to an object with `PetscObjectComposedDataSetIntstar()`
878: Synopsis:
879: #include "petsc/private/petscimpl.h"
880: PetscErrorCode PetscObjectComposedDataGetIntstar(PetscObject obj,int id,int *data,PetscBool flag)
882: Not collective
884: Input parameters:
885: + obj - the object from which data is to be retrieved
886: - id - the identifier for the data
888: Output parameters:
889: + data - the data to be retrieved
890: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
892: Notes:
893: The 'data' and 'flag' variables are inlined, so they are not pointers.
895: The length of the array accessed must be known, it is not available through this API.
897: Level: developer
899: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetReal()`,
900: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
901: `PetscObjectCompose()`, `PetscObjectQuery()`
902: M*/
903: #define PetscObjectComposedDataGetIntstar(obj, id, data, flag) (((obj)->intstarcomposedstate ? (data = (obj)->intstarcomposeddata[id], flag = (PetscBool)((obj)->intstarcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
905: /*MC
906: PetscObjectComposedDataSetReal - attach real data to a `PetscObject` that may be accessed with `PetscObjectComposedDataGetReal()`
908: Synopsis:
909: #include "petsc/private/petscimpl.h"
910: PetscErrorCode PetscObjectComposedDataSetReal(PetscObject obj,int id,PetscReal data)
912: Not collective
914: Input parameters:
915: + obj - the object to which data is to be attached
916: . id - the identifier for the data
917: - data - the data to be attached
919: Note:
920: The data identifier can be determined through a call to `PetscObjectComposedDataRegister()`
922: Level: developer
924: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
925: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
926: `PetscObjectCompose()`, `PetscObjectQuery()`
927: M*/
928: #define PetscObjectComposedDataSetReal(obj, id, data) ((((obj)->real_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseReal(obj)) || ((obj)->realcomposeddata[id] = data, (obj)->realcomposedstate[id] = (obj)->state, 0))
930: /*MC
931: PetscObjectComposedDataGetReal - retrieve real data attached to an object set with `PetscObjectComposedDataSetReal()`
933: Synopsis:
934: #include "petsc/private/petscimpl.h"
935: PetscErrorCode PetscObjectComposedDataGetReal(PetscObject obj,int id,PetscReal data,PetscBool flag)
937: Not collective
939: Input parameters:
940: + obj - the object from which data is to be retrieved
941: - id - the identifier for the data
943: Output parameters:
944: + data - the data to be retrieved
945: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
947: Note:
948: The 'data' and 'flag' variables are inlined, so they are not pointers.
950: Level: developer
952: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataSetIntstar()`,
953: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
954: `PetscObjectCompose()`, `PetscObjectQuery()`
955: M*/
956: #define PetscObjectComposedDataGetReal(obj, id, data, flag) (((obj)->realcomposedstate ? (data = (obj)->realcomposeddata[id], flag = (PetscBool)((obj)->realcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
958: /*MC
959: PetscObjectComposedDataSetRealstar - attach real array data to a `PetscObject` that may be retrieved with `PetscObjectComposedDataGetRealstar()`
961: Synopsis:
962: #include "petsc/private/petscimpl.h"
963: PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *data)
965: Not collective
967: Input parameters:
968: + obj - the object to which data is to be attached
969: . id - the identifier for the data
970: - data - the data to be attached
972: Notes:
973: The data identifier can be determined through a call to `PetscObjectComposedDataRegister()`
975: The length of the array accessed must be known, it is not available through this API.
977: Level: developer
979: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
980: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
981: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataGetRealstar()`
982: M*/
983: #define PetscObjectComposedDataSetRealstar(obj, id, data) \
984: ((((obj)->realstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseRealstar(obj)) || ((obj)->realstarcomposeddata[id] = data, (obj)->realstarcomposedstate[id] = (obj)->state, 0))
986: /*MC
987: PetscObjectComposedDataGetRealstar - retrieve real array data attached to an object with `PetscObjectComposedDataSetRealstar()`
989: Synopsis:
990: #include "petsc/private/petscimpl.h"
991: PetscErrorCode PetscObjectComposedDataGetRealstar(PetscObject obj,int id,PetscReal *data,PetscBool flag)
993: Not collective
995: Input parameters:
996: + obj - the object from which data is to be retrieved
997: - id - the identifier for the data
999: Output parameters:
1000: + data - the data to be retrieved
1001: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
1003: Notes:
1004: The 'data' and 'flag' variables are inlined, so they are not pointers.
1006: The length of the array accessed must be known, it is not available through this API.
1008: Level: developer
1010: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
1011: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1012: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`
1013: M*/
1014: #define PetscObjectComposedDataGetRealstar(obj, id, data, flag) (((obj)->realstarcomposedstate ? (data = (obj)->realstarcomposeddata[id], flag = (PetscBool)((obj)->realstarcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
1016: /*MC
1017: PetscObjectComposedDataSetScalar - attach scalar data to a PetscObject that may be retrieved with `PetscObjectComposedDataGetScalar()`
1019: Synopsis:
1020: #include "petsc/private/petscimpl.h"
1021: PetscErrorCode PetscObjectComposedDataSetScalar(PetscObject obj,int id,PetscScalar data)
1023: Not collective
1025: Input parameters:
1026: + obj - the object to which data is to be attached
1027: . id - the identifier for the data
1028: - data - the data to be attached
1030: Note:
1031: The data identifier can be determined through a call to `PetscObjectComposedDataRegister()`
1033: Level: developer
1035: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
1036: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1037: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataGetScalar()`
1038: M*/
1039: #if defined(PETSC_USE_COMPLEX)
1040: #define PetscObjectComposedDataSetScalar(obj, id, data) ((((obj)->scalar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalar(obj)) || ((obj)->scalarcomposeddata[id] = data, (obj)->scalarcomposedstate[id] = (obj)->state, 0))
1041: #else
1042: #define PetscObjectComposedDataSetScalar(obj, id, data) PetscObjectComposedDataSetReal(obj, id, data)
1043: #endif
1044: /*MC
1045: PetscObjectComposedDataGetScalar - retrieve scalar data attached to an object that was set with `PetscObjectComposedDataSetScalar()`
1047: Synopsis:
1048: #include "petsc/private/petscimpl.h"
1049: PetscErrorCode PetscObjectComposedDataGetScalar(PetscObject obj,int id,PetscScalar data,PetscBool flag)
1051: Not collective
1053: Input parameters:
1054: + obj - the object from which data is to be retrieved
1055: - id - the identifier for the data
1057: Output parameters:
1058: + data - the data to be retrieved
1059: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
1061: Note:
1062: The 'data' and 'flag' variables are inlined, so they are not pointers.
1064: Level: developer
1066: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
1067: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1068: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataSetScalar()`
1069: M*/
1070: #if defined(PETSC_USE_COMPLEX)
1071: #define PetscObjectComposedDataGetScalar(obj, id, data, flag) (((obj)->scalarcomposedstate ? (data = (obj)->scalarcomposeddata[id], flag = (PetscBool)((obj)->scalarcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
1072: #else
1073: #define PetscObjectComposedDataGetScalar(obj, id, data, flag) PetscObjectComposedDataGetReal(obj, id, data, flag)
1074: #endif
1076: /*MC
1077: PetscObjectComposedDataSetScalarstar - attach scalar array data to a `PetscObject` that may be retrieved with `PetscObjectComposedDataSetScalarstar()`
1079: Synopsis:
1080: #include "petsc/private/petscimpl.h"
1081: PetscErrorCode PetscObjectComposedDataSetScalarstar(PetscObject obj,int id,PetscScalar *data)
1083: Not collective
1085: Input parameters:
1086: + obj - the object to which data is to be attached
1087: . id - the identifier for the data
1088: - data - the data to be attached
1090: Notes:
1091: The data identifier can be determined through a call to `PetscObjectComposedDataRegister()`
1093: The length of the array accessed must be known, it is not available through this API.
1095: Level: developer
1097: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
1098: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1099: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataGetScalarstar()`
1100: M*/
1101: #if defined(PETSC_USE_COMPLEX)
1102: #define PetscObjectComposedDataSetScalarstar(obj, id, data) \
1103: ((((obj)->scalarstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalarstar(obj)) || ((obj)->scalarstarcomposeddata[id] = data, (obj)->scalarstarcomposedstate[id] = (obj)->state, 0))
1104: #else
1105: #define PetscObjectComposedDataSetScalarstar(obj, id, data) PetscObjectComposedDataSetRealstar(obj, id, data)
1106: #endif
1107: /*MC
1108: PetscObjectComposedDataGetScalarstar - retrieve scalar array data set with `PetscObjectComposedDataSetScalarstar()`
1109: attached to an object
1111: Synopsis:
1112: #include "petsc/private/petscimpl.h"
1113: PetscErrorCode PetscObjectComposedDataGetScalarstar(PetscObject obj,int id,PetscScalar *data,PetscBool flag)
1115: Not collective
1117: Input parameters:
1118: + obj - the object from which data is to be retrieved
1119: - id - the identifier for the data
1121: Output parameters:
1122: + data - the data to be retrieved
1123: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
1125: Notes:
1126: The 'data' and 'flag' variables are inlined, so they are not pointers.
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()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataSetScalarstar()`
1135: M*/
1136: #if defined(PETSC_USE_COMPLEX)
1137: #define PetscObjectComposedDataGetScalarstar(obj, id, data, flag) (((obj)->scalarstarcomposedstate ? (data = (obj)->scalarstarcomposeddata[id], flag = (PetscBool)((obj)->scalarstarcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
1138: #else
1139: #define PetscObjectComposedDataGetScalarstar(obj, id, data, flag) PetscObjectComposedDataGetRealstar(obj, id, data, flag)
1140: #endif
1142: PETSC_EXTERN PetscMPIInt Petsc_Counter_keyval;
1143: PETSC_EXTERN PetscMPIInt Petsc_InnerComm_keyval;
1144: PETSC_EXTERN PetscMPIInt Petsc_OuterComm_keyval;
1145: PETSC_EXTERN PetscMPIInt Petsc_Seq_keyval;
1146: PETSC_EXTERN PetscMPIInt Petsc_ShmComm_keyval;
1147: PETSC_EXTERN PetscMPIInt Petsc_CreationIdx_keyval;
1148: PETSC_EXTERN PetscMPIInt Petsc_Garbage_HMap_keyval;
1150: struct PetscCommStash {
1151: struct PetscCommStash *next;
1152: MPI_Comm comm;
1153: };
1155: /*
1156: PETSc communicators have this attribute, see
1157: PetscCommDuplicate(), PetscCommDestroy(), PetscCommGetNewTag(), PetscObjectGetName()
1158: */
1159: typedef struct {
1160: PetscMPIInt tag; /* next free tag value */
1161: PetscInt refcount; /* number of references, communicator can be freed when this reaches 0 */
1162: PetscInt namecount; /* used to generate the next name, as in Vec_0, Mat_1, ... */
1163: PetscMPIInt *iflags; /* length of comm size, shared by all calls to PetscCommBuildTwoSided_Allreduce/RedScatter on this comm */
1164: struct PetscCommStash *comms; /* communicators available for PETSc to pass off to other packages */
1165: } PetscCommCounter;
1167: typedef enum {
1168: STATE_BEGIN,
1169: STATE_PENDING,
1170: STATE_END
1171: } SRState;
1173: typedef enum {
1174: PETSC_SR_REDUCE_SUM = 0,
1175: PETSC_SR_REDUCE_MAX = 1,
1176: PETSC_SR_REDUCE_MIN = 2
1177: } PetscSRReductionType;
1179: typedef struct {
1180: MPI_Comm comm;
1181: MPI_Request request;
1182: PetscBool mix;
1183: PetscBool async;
1184: PetscScalar *lvalues; /* this are the reduced values before call to MPI_Allreduce() */
1185: PetscScalar *gvalues; /* values after call to MPI_Allreduce() */
1186: void **invecs; /* for debugging only, vector/memory used with each op */
1187: PetscInt *reducetype; /* is particular value to be summed or maxed? */
1188: struct {
1189: PetscScalar v;
1190: PetscInt i;
1191: } *lvalues_mix, *gvalues_mix; /* used when mixing reduce operations */
1192: SRState state; /* are we calling xxxBegin() or xxxEnd()? */
1193: PetscInt maxops; /* total amount of space we have for requests */
1194: PetscInt numopsbegin; /* number of requests that have been queued in */
1195: PetscInt numopsend; /* number of requests that have been gotten by user */
1196: } PetscSplitReduction;
1198: PETSC_EXTERN PetscErrorCode PetscSplitReductionGet(MPI_Comm, PetscSplitReduction **);
1199: PETSC_EXTERN PetscErrorCode PetscSplitReductionEnd(PetscSplitReduction *);
1200: PETSC_EXTERN PetscErrorCode PetscSplitReductionExtend(PetscSplitReduction *);
1202: #if !defined(PETSC_SKIP_SPINLOCK)
1203: #if defined(PETSC_HAVE_THREADSAFETY)
1204: #if defined(PETSC_HAVE_CONCURRENCYKIT)
1205: #if defined(__cplusplus)
1206: /* CK does not have extern "C" protection in their include files */
1207: extern "C" {
1208: #endif
1209: #include <ck_spinlock.h>
1210: #if defined(__cplusplus)
1211: }
1212: #endif
1213: typedef ck_spinlock_t PetscSpinlock;
1214: static inline PetscErrorCode PetscSpinlockCreate(PetscSpinlock *ck_spinlock)
1215: {
1216: ck_spinlock_init(ck_spinlock);
1217: return 0;
1218: }
1219: static inline PetscErrorCode PetscSpinlockLock(PetscSpinlock *ck_spinlock)
1220: {
1221: ck_spinlock_lock(ck_spinlock);
1222: return 0;
1223: }
1224: static inline PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *ck_spinlock)
1225: {
1226: ck_spinlock_unlock(ck_spinlock);
1227: return 0;
1228: }
1229: static inline PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *ck_spinlock)
1230: {
1231: return 0;
1232: }
1233: #elif defined(PETSC_HAVE_OPENMP)
1235: #include <omp.h>
1236: typedef omp_lock_t PetscSpinlock;
1237: static inline PetscErrorCode PetscSpinlockCreate(PetscSpinlock *omp_lock)
1238: {
1239: omp_init_lock(omp_lock);
1240: return 0;
1241: }
1242: static inline PetscErrorCode PetscSpinlockLock(PetscSpinlock *omp_lock)
1243: {
1244: omp_set_lock(omp_lock);
1245: return 0;
1246: }
1247: static inline PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *omp_lock)
1248: {
1249: omp_unset_lock(omp_lock);
1250: return 0;
1251: }
1252: static inline PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *omp_lock)
1253: {
1254: omp_destroy_lock(omp_lock);
1255: return 0;
1256: }
1257: #else
1258: #error "Thread safety requires either --with-openmp or --download-concurrencykit"
1259: #endif
1261: #else
1262: typedef int PetscSpinlock;
1263: #define PetscSpinlockCreate(a) 0
1264: #define PetscSpinlockLock(a) 0
1265: #define PetscSpinlockUnlock(a) 0
1266: #define PetscSpinlockDestroy(a) 0
1267: #endif
1269: #if defined(PETSC_HAVE_THREADSAFETY)
1270: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockOpen;
1271: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStdout;
1272: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStderr;
1273: PETSC_INTERN PetscSpinlock PetscCommSpinLock;
1274: #endif
1275: #endif
1277: PETSC_EXTERN PetscLogEvent PETSC_Barrier;
1278: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSided;
1279: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSidedF;
1280: PETSC_EXTERN PetscBool use_gpu_aware_mpi;
1281: PETSC_EXTERN PetscBool PetscPrintFunctionList;
1283: #if defined(PETSC_HAVE_ADIOS)
1284: PETSC_EXTERN int64_t Petsc_adios_group;
1285: #endif
1287: #if defined(PETSC_HAVE_KOKKOS)
1288: PETSC_INTERN PetscBool PetscBeganKokkos;
1289: PETSC_EXTERN PetscBool PetscKokkosInitialized;
1290: PETSC_INTERN PetscErrorCode PetscKokkosIsInitialized_Private(PetscBool *);
1291: PETSC_INTERN PetscErrorCode PetscKokkosFinalize_Private(void);
1292: #endif
1294: #if defined(PETSC_HAVE_OPENMP)
1295: PETSC_EXTERN PetscInt PetscNumOMPThreads;
1296: #endif
1298: #endif /* PETSCIMPL_H */