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: #if defined(PETSC_HAVE_CLOSURE)
36: PETSC_EXTERN PetscErrorCode PetscVFPrintfSetClosure(int (^)(const char *));
37: #endif
39: /*
40: All major PETSc data structures have a common core; this is defined
41: below by PETSCHEADER.
43: PetscHeaderCreate() should be used whenever creating a PETSc structure.
44: */
46: /*
47: PetscOps: structure of core operations that all PETSc objects support.
49: getcomm() - Gets the object's communicator.
50: view() - Is the routine for viewing the entire PETSc object; for
51: example, MatView() is the general matrix viewing routine.
52: This is used by PetscObjectView((PetscObject)obj) to allow
53: viewing any PETSc object.
54: destroy() - Is the routine for destroying the entire PETSc object;
55: for example,MatDestroy() is the general matrix
56: destruction routine.
57: This is used by PetscObjectDestroy((PetscObject*)&obj) to allow
58: destroying any PETSc object.
59: compose() - Associates a PETSc object with another PETSc object with a name
60: query() - Returns a different PETSc object that has been associated
61: with the first object using a name.
62: composefunction() - Attaches an a function to a PETSc object with a name.
63: queryfunction() - Requests a registered function that has been attached to a PETSc object.
64: */
66: typedef struct {
67: PetscErrorCode (*view)(PetscObject, PetscViewer);
68: PetscErrorCode (*destroy)(PetscObject *);
69: PetscErrorCode (*compose)(PetscObject, const char[], PetscObject);
70: PetscErrorCode (*query)(PetscObject, const char[], PetscObject *);
71: PetscErrorCode (*composefunction)(PetscObject, const char[], void (*)(void));
72: PetscErrorCode (*queryfunction)(PetscObject, const char[], void (**)(void));
73: } PetscOps;
75: typedef enum {
76: PETSC_FORTRAN_CALLBACK_CLASS,
77: PETSC_FORTRAN_CALLBACK_SUBTYPE,
78: PETSC_FORTRAN_CALLBACK_MAXTYPE
79: } PetscFortranCallbackType;
80: typedef size_t PetscFortranCallbackId;
81: #define PETSC_SMALLEST_FORTRAN_CALLBACK ((PetscFortranCallbackId)1000)
82: PETSC_EXTERN PetscErrorCode PetscFortranCallbackRegister(PetscClassId, const char *, PetscFortranCallbackId *);
83: PETSC_EXTERN PetscErrorCode PetscFortranCallbackGetSizes(PetscClassId, PetscFortranCallbackId *, PetscFortranCallbackId *);
85: typedef struct {
86: void (*func)(void);
87: void *ctx;
88: } PetscFortranCallback;
90: /*
91: All PETSc objects begin with the fields defined in PETSCHEADER.
92: The PetscObject is a way of examining these fields regardless of
93: the specific object. In C++ this could be a base abstract class
94: from which all objects are derived.
95: */
96: #define PETSC_MAX_OPTIONS_HANDLER 5
97: typedef struct _p_PetscObject {
98: PetscOps bops[1];
99: PetscClassId classid;
100: MPI_Comm comm;
101: PetscObjectId id; /* this is used to compare object for identity that may no longer exist since memory addresses get recycled for new objects */
102: PetscInt refct;
103: PetscMPIInt tag;
104: PetscFunctionList qlist;
105: PetscObjectList olist;
106: char *class_name; /* for example, "Vec" */
107: char *description;
108: char *mansec;
109: char *type_name; /* this is the subclass, for example VECSEQ which equals "seq" */
110: char *name;
111: char *prefix;
112: PetscInt tablevel;
113: void *cpp;
114: PetscObjectState state;
115: PetscInt int_idmax, intstar_idmax;
116: PetscObjectState *intcomposedstate, *intstarcomposedstate;
117: PetscInt *intcomposeddata, **intstarcomposeddata;
118: PetscInt real_idmax, realstar_idmax;
119: PetscObjectState *realcomposedstate, *realstarcomposedstate;
120: PetscReal *realcomposeddata, **realstarcomposeddata;
121: PetscInt scalar_idmax, scalarstar_idmax;
122: PetscObjectState *scalarcomposedstate, *scalarstarcomposedstate;
123: PetscScalar *scalarcomposeddata, **scalarstarcomposeddata;
124: void (**fortran_func_pointers)(void); /* used by Fortran interface functions to stash user provided Fortran functions */
125: PetscFortranCallbackId num_fortran_func_pointers; /* number of Fortran function pointers allocated */
126: PetscFortranCallback *fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
127: PetscFortranCallbackId num_fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
128: void *python_context;
129: PetscErrorCode (*python_destroy)(void *);
131: PetscInt noptionhandler;
132: PetscErrorCode (*optionhandler[PETSC_MAX_OPTIONS_HANDLER])(PetscObject, PetscOptionItems *, void *);
133: PetscErrorCode (*optiondestroy[PETSC_MAX_OPTIONS_HANDLER])(PetscObject, void *);
134: void *optionctx[PETSC_MAX_OPTIONS_HANDLER];
135: #if defined(PETSC_HAVE_SAWS)
136: PetscBool amsmem; /* if PETSC_TRUE then this object is registered with SAWs and visible to clients */
137: PetscBool amspublishblock; /* if PETSC_TRUE and publishing objects then will block at PetscObjectSAWsBlock() */
138: #endif
139: PetscOptions options; /* options database used, NULL means default */
140: PetscBool optionsprinted;
141: PetscBool donotPetscObjectPrintClassNamePrefixType;
142: } _p_PetscObject;
144: #define PETSCHEADER(ObjectOps) \
145: _p_PetscObject hdr; \
146: ObjectOps ops[1]
148: #define PETSCFREEDHEADER -1
150: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectDestroyFunction)(PetscObject *); /* force cast in next macro to NEVER use extern "C" style */
151: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectViewFunction)(PetscObject, PetscViewer);
153: /*@C
154: PetscHeaderCreate - Creates a PETSc object of a particular class
156: Input Parameters:
157: + classid - the classid associated with this object (for example VEC_CLASSID)
158: . class_name - string name of class; should be static (for example "Vec")
159: . descr - string containing short description; should be static (for example "Vector")
160: . mansec - string indicating section in manual pages; should be static (for example "Vec")
161: . comm - the MPI Communicator
162: . destroy - the destroy routine for this object (for example `VecDestroy()`)
163: - view - the view routine for this object (for example `VecView()`)
165: Output Parameter:
166: . h - the newly created object
168: Level: developer
170: .seealso: `PetscHeaderDestroy()`, `PetscClassIdRegister()`
172: @*/
173: #define PetscHeaderCreate(h, classid, class_name, descr, mansec, comm, destroy, view) \
174: (PetscNew(&(h)) || PetscHeaderCreate_Private((PetscObject)(h), classid, class_name, descr, mansec, comm, (PetscObjectDestroyFunction)(destroy), (PetscObjectViewFunction)(view)) || PetscLogObjectCreate(h))
176: PETSC_EXTERN PetscErrorCode PetscComposedQuantitiesDestroy(PetscObject obj);
177: PETSC_EXTERN PetscErrorCode PetscHeaderCreate_Private(PetscObject, PetscClassId, const char[], const char[], const char[], MPI_Comm, PetscObjectDestroyFunction, PetscObjectViewFunction);
178: PETSC_INTERN PetscObjectId PetscObjectNewId_Internal(void);
180: /*@C
181: PetscHeaderDestroy - Final step in destroying a PetscObject
183: Input Parameters:
184: . h - the header created with `PetscHeaderCreate()`
186: Level: developer
188: .seealso: `PetscHeaderCreate()`
189: @*/
190: #define PetscHeaderDestroy(h) (PetscHeaderDestroy_Private((PetscObject)(*(h)), PETSC_FALSE) || PetscFree(*(h)))
192: PETSC_EXTERN PetscErrorCode PetscHeaderDestroy_Private(PetscObject, PetscBool);
193: PETSC_SINGLE_LIBRARY_INTERN PetscErrorCode PetscHeaderReset_Internal(PetscObject);
194: PETSC_EXTERN PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject, PetscObject);
195: PETSC_EXTERN PetscErrorCode PetscObjectSetFortranCallback(PetscObject, PetscFortranCallbackType, PetscFortranCallbackId *, void (*)(void), void *ctx);
196: PETSC_EXTERN PetscErrorCode PetscObjectGetFortranCallback(PetscObject, PetscFortranCallbackType, PetscFortranCallbackId, void (**)(void), void **ctx);
198: PETSC_INTERN PetscErrorCode PetscCitationsInitialize(void);
199: PETSC_INTERN PetscErrorCode PetscFreeMPIResources(void);
200: PETSC_INTERN PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions, PetscBool *);
202: /* Code shared between C and Fortran */
203: PETSC_INTERN PetscErrorCode PetscInitialize_Common(const char *, const char *, const char *, PetscBool, PetscBool, PetscInt);
205: #if PetscDefined(HAVE_SETJMP_H)
207: #else
209: #endif
210: #if !defined(PETSC_CLANG_STATIC_ANALYZER)
211: /*
212: Macros to test if a PETSc object is valid and if pointers are valid
213: */
214: #if !defined(PETSC_USE_DEBUG)
217: do { \
218: (void)(h); \
219: } while (0)
221: do { \
222: (void)(h); \
223: } while (0)
225: do { \
226: (void)(h); \
227: } while (0)
229: do { \
230: (void)(h); \
231: } while (0)
233: do { \
234: (void)(h); \
235: } while (0)
237: do { \
238: (void)(h); \
239: } while (0)
241: do { \
242: (void)(h); \
243: } while (0)
245: do { \
246: (void)(h); \
247: } while (0)
249: do { \
250: (void)(h); \
251: } while (0)
253: do { \
254: (void)(h); \
255: } while (0)
257: #else
259: /* This check is for subtype methods such as DMDAGetCorners() that do not use the PetscTryMethod() or PetscUseMethod() paradigm */
261: do { \
262: PetscBool _7_same; \
264: PetscObjectTypeCompare((PetscObject)(h), t, &_7_same); \
266: } while (0)
269: do { \
272: } while (0)
275: do { \
277: if (((PetscObject)(h))->classid != ck) { \
279: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Wrong type of object: Parameter # %d", arg); \
280: } \
281: } while (0)
284: do { \
288: } while (0)
298: do { \
300: } while (0)
301: #endif
302: #else /* PETSC_CLANG_STATIC_ANALYZER */
303: template <typename T>
305: template <typename T>
307: template <typename T>
309: template <typename T>
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: #endif /* PETSC_CLANG_STATIC_ANALYZER */
327: #define PetscSorted(n, idx, sorted) \
328: do { \
329: (sorted) = PETSC_TRUE; \
330: for (PetscInt _i_ = 1; _i_ < (n); ++_i_) { \
331: if ((idx)[_i_] < (idx)[_i_ - 1]) { \
332: (sorted) = PETSC_FALSE; \
333: break; \
334: } \
335: } \
336: } while (0)
338: #if !defined(PETSC_CLANG_STATIC_ANALYZER)
339: #if !defined(PETSC_USE_DEBUG)
342: do { \
343: (void)(a); \
344: (void)(b); \
345: } while (0)
347: do { \
348: (void)(a); \
349: } while (0)
351: do { \
352: (void)(a); \
353: } while (0)
355: do { \
356: (void)(a); \
357: } while (0)
359: do { \
360: (void)(a); \
361: (void)(b); \
362: } while (0)
364: do { \
365: (void)(a); \
366: (void)(b); \
367: } while (0)
369: do { \
370: (void)(a); \
371: (void)(b); \
372: } while (0)
374: do { \
375: (void)(a); \
376: (void)(b); \
377: } while (0)
379: do { \
380: (void)(a); \
381: (void)(b); \
382: } while (0)
384: do { \
385: (void)(a); \
386: (void)(b); \
387: } while (0)
389: do { \
390: (void)(a); \
391: (void)(b); \
392: } while (0)
394: do { \
395: (void)(a); \
396: (void)(b); \
397: } while (0)
399: do { \
400: (void)(n); \
401: (void)(idx); \
402: } while (0)
404: #else
406: /*
407: This macro currently does nothing, the plan is for each PetscObject to have a PetscInt "type"
408: member associated with the string type_name that can be quickly compared.
410: **Do not swap this macro to compare string type_name!**
412: This macro is used incorrectly in the code. Many places that do not need identity of the
413: types incorrectly call this check and would need to be fixed if this macro is enabled.
414: */
415: #if 0
417: do { \
418: PetscBool pcst_type_eq_ = PETSC_TRUE; \
419: PetscStrcmp(((PetscObject)(a))->type_name, (((PetscObject)(b)))->type_name, &pcst_type_eq_); \
421: } while (0)
422: #else
424: do { \
425: (void)(a); \
426: (void)(b); \
427: } while (0)
428: #endif
430: /*
431: Check type_name
432: */
434: do { \
435: PetscBool _7_match; \
436: PetscObjectTypeCompare(((PetscObject)(a)), (type), &_7_match); \
438: } while (0)
441: do { \
442: PetscBool _7_match; \
443: PetscObjectTypeCompareAny(((PetscObject)(a)), &_7_match, (type1), (type2), ""); \
445: } while (0)
447: /*
448: Use this macro to check if the type is set
449: */
452: /*
453: Sometimes object must live on same communicator to inter-operate
454: */
456: do { \
457: PetscMPIInt _7_flag; \
458: MPI_Comm_compare(PetscObjectComm((PetscObject)(a)), PetscObjectComm((PetscObject)(b)), &_7_flag); \
460: } while (0)
463: do { \
466: } while (0)
469: do { \
470: PetscScalar b0 = (b); \
471: PetscReal b1[5], b2[5]; \
472: if (PetscIsNanScalar(b0)) { \
473: b1[4] = 1; \
474: } else { \
475: b1[4] = 0; \
476: }; \
477: b1[0] = -PetscRealPart(b0); \
478: b1[1] = PetscRealPart(b0); \
479: b1[2] = -PetscImaginaryPart(b0); \
480: b1[3] = PetscImaginaryPart(b0); \
481: MPIU_Allreduce(b1, b2, 5, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)(a))); \
483: } while (0)
486: do { \
487: PetscReal b0 = (b), b1[3], b2[3]; \
488: if (PetscIsNanReal(b0)) { \
489: b1[2] = 1; \
490: } else { \
491: b1[2] = 0; \
492: }; \
493: b1[0] = -b0; \
494: b1[1] = b0; \
495: MPIU_Allreduce(b1, b2, 3, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)(a))); \
497: } while (0)
500: do { \
501: PetscInt b0 = (b), b1[2], b2[2]; \
502: b1[0] = -b0; \
503: b1[1] = b0; \
504: MPIU_Allreduce(b1, b2, 2, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)(a))); \
506: } while (0)
509: do { \
510: PetscMPIInt b0 = (b), b1[2], b2[2]; \
511: b1[0] = -b0; \
512: b1[1] = b0; \
513: MPIU_Allreduce(b1, b2, 2, MPI_INT, MPI_MAX, PetscObjectComm((PetscObject)(a))); \
515: } while (0)
518: do { \
519: PetscMPIInt b0 = (PetscMPIInt)(b), b1[2], b2[2]; \
520: b1[0] = -b0; \
521: b1[1] = b0; \
522: MPIU_Allreduce(b1, b2, 2, MPI_INT, MPI_MAX, PetscObjectComm((PetscObject)(a))); \
524: } while (0)
527: do { \
528: PetscMPIInt b0 = (PetscMPIInt)(b), b1[2], b2[2]; \
529: b1[0] = -b0; \
530: b1[1] = b0; \
531: MPIU_Allreduce(b1, b2, 2, MPI_INT, MPI_MAX, PetscObjectComm((PetscObject)(a))); \
533: } while (0)
536: do { \
537: PetscBool _1_flg; \
538: PetscSorted(n, idx, _1_flg); \
540: } while (0)
542: #endif
543: #else /* PETSC_CLANG_STATIC_ANALYZER */
544: template <typename Ta, typename Tb>
546: template <typename Ta, typename Tb>
548: template <typename Ta, typename Tb, typename Tc>
550: template <typename T>
552: template <typename Ta, typename Tb>
554: template <typename Ta, typename Tb>
556: template <typename Ta, typename Tb>
558: template <typename Ta, typename Tb>
560: template <typename Ta, typename Tb>
562: template <typename Ta, typename Tb>
564: template <typename Ta, typename Tb>
566: template <typename Ta, typename Tb>
568: template <typename T>
570: #endif /* PETSC_CLANG_STATIC_ANALYZER */
572: /*MC
573: PetscTryMethod - Queries an object for a method added with `PetscObjectComposeFunction()`, if it exists then calls it.
575: Synopsis:
576: #include "petsc/private/petscimpl.h"
577: PetscTryMethod(PetscObject obj,const char *name,(arg_types),(arg_value))
579: Input Parameters:
580: + obj - the object
581: . name - the name of the method, for example, "KSPGMRESSetRestart_C" for the function `KSPGMRESSetRestart()`
582: . arg_types - the argument types for the method, for example, (KSP,PetscInt)
583: - args - the arguements for the method, for example, (ksp,restart))
585: Level: developer
587: Notes:
588: The object is always the implicit first argument of the method and is not listed in arg_types or args
590: This does not return an error code, it is a macro that returns with an erorr code on error.
592: Use `PetscUseTypeMethod()` or `PetscTryTypeMethod()` to call functions that are included in the objects function table, the `ops` array
593: in the object.
596: M*/
597: #define PetscTryMethod(obj, A, B, C) \
598: do { \
599: PetscErrorCode(*_7_f) B; \
600: PetscObjectQueryFunction((PetscObject)(obj), A, &_7_f); \
601: if (_7_f) (*_7_f)C; \
602: } while (0)
604: /*MC
605: PetscUseMethod - Queries an object for a method added with `PetscObjectComposeFunction()`, if it exists then calls it, otherwise generates an error.
607: Synopsis:
608: #include "petsc/private/petscimpl.h"
609: PetscUseMethod(PetscObject obj,const char *name,(arg_types),(arg_value))
611: Input Parameters:
612: + obj - the object
613: . name - the name of the method, for example, "KSPGMRESSetRestart_C" for the function `KSPGMRESSetRestart()`
614: . arg_types - the argument types for the method, for example, (KSP,PetscInt)
615: - args - the arguements for the method, for example, (ksp,restart))
617: Level: developer
619: Notes:
620: The object is always the implicit first argument of the method and is not listed in arg_types or args
622: This does not return an error code, it is a macro that returns with an erorr code on error.
624: Use `PetscUseTypeMethod()` or `PetscTryTypeMethod()` to call functions that are included in the objects function table, the `ops` array
625: in the object.
628: M*/
629: #define PetscUseMethod(obj, A, B, C) \
630: do { \
631: PetscErrorCode(*_7_f) B; \
632: PetscObjectQueryFunction((PetscObject)(obj), A, &_7_f); \
634: (*_7_f)C; \
635: } while (0)
637: /*
638: Use Microsoft traditional preprocessor.
640: The Microsoft compiler option -Zc:preprocessor available in recent versions of the compiler
641: sets _MSVC_TRADITIONAL to zero so this code path is not used.
643: It appears the Intel Windows compiler icl does not have an equaivalent of -Zc:preprocessor
645: These macros use the trick that Windows compilers remove the , before the __VA_ARGS__ if __VA_ARGS__ does not exist
647: PetscCall() cannot be used in the macros because the remove the , trick does not work in a macro in a macro
648: */
649: #if (defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) || defined(__ICL)
651: #define PetscUseTypeMethod(obj, OP, ...) \
652: do { \
653: PetscErrorCode ierr_p_; \
654: PetscStackUpdateLine; \
656: ierr_p_ = (*(obj)->ops->OP)(obj, __VA_ARGS__); \
657: ierr_p_; \
658: } while (0)
660: #define PetscTryTypeMethod(obj, OP, ...) \
661: do { \
662: if ((obj)->ops->OP) { \
663: PetscErrorCode ierr_p_; \
664: PetscStackUpdateLine; \
665: ierr_p_ = (*(obj)->ops->OP)(obj, __VA_ARGS__); \
666: ierr_p_; \
667: } \
668: } while (0)
670: #else
672: /*MC
673: 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
675: Synopsis:
676: #include "petsc/private/petscimpl.h"
677: PetscUseTypeMethod(obj,method,other_args)
679: Input Parameters:
680: + obj - the object the method is called on
681: . method - the name of the method, for example, mult for the PETSc routine MatMult()
682: - other_args - the other arguments for the method, obj is the first argument
684: Level: developer
686: Note:
687: This does not return an error code, it is a macro that returns with an erorr code on error.
689: Use `PetscUseMethod()` or `PetscTryMethod()` to call functions that have been composed to an object with `PetscObjectComposeFunction()`
692: M*/
693: #define PetscUseTypeMethod(obj, ...) \
694: do { \
696: PetscStringize(PETSC_FIRST_ARG((__VA_ARGS__,unused))), ((PetscObject)obj)->class_name, ((PetscObject)obj)->type_name); \
697: (*(obj)->ops->PETSC_FIRST_ARG((__VA_ARGS__, unused)))(obj PETSC_REST_ARG(__VA_ARGS__)); \
698: } while (0)
700: /*MC
701: 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
703: Synopsis:
704: #include "petsc/private/petscimpl.h"
705: PetscTryTtype(obj,method,other_args)
707: Input Parameters:
708: + obj - the object the method is called on
709: . method - the name of the method, for example, mult for the PETSc routine MatMult()
710: - other_args - the other arguments for the method, obj is the first argument
712: Level: developer
714: Note:
715: This does not return an error code, it is a macro that returns with an erorr code on error.
717: Use `PetscUseMethod()` or `PetscTryMethod()` to call functions that have been composed to an object with `PetscObjectComposeFunction()`
720: M*/
721: #define PetscTryTypeMethod(obj, ...) \
722: do { \
723: if ((obj)->ops->PETSC_FIRST_ARG((__VA_ARGS__, unused))) (*(obj)->ops->PETSC_FIRST_ARG((__VA_ARGS__, unused)))(obj PETSC_REST_ARG(__VA_ARGS__)); \
724: } while (0)
726: #endif
728: /*MC
729: PetscObjectStateIncrease - Increases the state of any `PetscObject`
731: Synopsis:
732: #include "petsc/private/petscimpl.h"
733: PetscErrorCode PetscObjectStateIncrease(PetscObject obj)
735: Logically Collective
737: Input Parameter:
738: . obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`. This must be
739: cast with a (PetscObject), for example,
740: `PetscObjectStateIncrease`((`PetscObject`)mat);
742: Notes:
743: Object state is a 64 bit integer which gets increased every time
744: the object is changed internally. By saving and later querying the object state
745: one can determine whether information about the object is still current.
746: Currently, state is maintained for `Vec` and `Mat` objects.
748: This routine is mostly for internal use by PETSc; a developer need only
749: call it after explicit access to an object's internals. Routines such
750: as `VecSet()` or `MatScale()` already call this routine. It is also called, as a
751: precaution, in `VecRestoreArray()`, `MatRestoreRow()`, `MatDenseRestoreArray()`.
753: Routines such as `VecNorm()` can by-pass the computation if the norm has already been computed and the vector's state has not changed.
755: This routine is logically collective because state equality comparison needs to be possible without communication.
757: `Mat` also has `MatGetNonzeroState()` and `MatSetNonzeroState()` for tracking changes to the nonzero structure.
759: Level: developer
761: .seealso: `PetscObjectStateGet()`, `MatSetNonzeroState()`, `PetscObject`
763: M*/
764: #define PetscObjectStateIncrease(obj) ((obj)->state++, 0)
766: PETSC_EXTERN PetscErrorCode PetscObjectStateGet(PetscObject, PetscObjectState *);
767: PETSC_EXTERN PetscErrorCode PetscObjectStateSet(PetscObject, PetscObjectState);
768: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataRegister(PetscInt *);
769: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject);
770: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject);
771: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject);
772: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject);
773: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject);
774: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject);
775: PETSC_EXTERN PetscInt PetscObjectComposedDataMax;
777: /*MC
778: PetscObjectComposedDataSetInt - attach integer data to a `PetscObject` that may be accessed with `PetscObjectComposedDataGetInt()`
780: Synopsis:
781: #include "petsc/private/petscimpl.h"
782: PetscErrorCode PetscObjectComposedDataSetInt(PetscObject obj,int id,int data)
784: Not collective
786: Input parameters:
787: + obj - the object to which data is to be attached
788: . id - the identifier for the data
789: - data - the data to be attached
791: Notes:
792: The data identifier can be created through a call to `PetscObjectComposedDataRegister()`
794: This allows the efficient composition of a single integer value with a `PetscObject`. Complex data may be
795: attached with `PetscObjectCompose()`
797: Level: developer
799: .seealso: `PetscObjectComposedDataGetInt()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetReal()`,
800: `PetscObjectComposedDataGetIntstar()`, `PetscObjectComposedDataSetIntstar()`, `PetscObject`,
801: `PetscObjectCompose()`, `PetscObjectQuery()`
802: M*/
803: #define PetscObjectComposedDataSetInt(obj, id, data) ((((obj)->int_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseInt(obj)) || ((obj)->intcomposeddata[id] = data, (obj)->intcomposedstate[id] = (obj)->state, 0))
805: /*MC
806: PetscObjectComposedDataGetInt - retrieve integer data attached to an object with `PetscObjectComposedDataSetInt()`
808: Synopsis:
809: #include "petsc/private/petscimpl.h"
810: PetscErrorCode PetscObjectComposedDataGetInt(PetscObject obj,int id,int data,PetscBool flag)
812: Not collective
814: Input parameters:
815: + obj - the object from which data is to be retrieved
816: - id - the identifier for the data
818: Output parameters:
819: + data - the data to be retrieved
820: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
822: Level: developer
824: Notes:
825: The 'data' and 'flag' variables are inlined, so they are not pointers.
827: The length of the array accessed must be known.
829: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetReal()`,
830: `PetscObjectComposedDataGetIntstar()`, `PetscObjectComposedDataSetIntstar()`, `PetscObject`,
831: `PetscObjectCompose()`, `PetscObjectQuery()`
832: M*/
833: #define PetscObjectComposedDataGetInt(obj, id, data, flag) (((obj)->intcomposedstate ? (data = (obj)->intcomposeddata[id], flag = (PetscBool)((obj)->intcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
835: /*MC
836: PetscObjectComposedDataSetIntstar - attach an integer array data to a `PetscObject` that may be accessed with `PetscObjectComposedDataGetIntstar()`
838: Synopsis:
839: #include "petsc/private/petscimpl.h"
840: PetscErrorCode PetscObjectComposedDataSetIntstar(PetscObject obj,int id,int *data)
842: Not collective
844: Input parameters:
845: + obj - the object to which data is to be attached
846: . id - the identifier for the data
847: - data - the data to be attached
849: Notes:
850: The data identifier can be determined through a call to `PetscObjectComposedDataRegister()`
852: The length of the array accessed must be known, it is not available through this API.
854: Level: developer
856: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetReal()`,
857: `PetscObjectComposedDataGetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
858: `PetscObjectCompose()`, `PetscObjectQuery()`
859: M*/
860: #define PetscObjectComposedDataSetIntstar(obj, id, data) \
861: ((((obj)->intstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseIntstar(obj)) || ((obj)->intstarcomposeddata[id] = data, (obj)->intstarcomposedstate[id] = (obj)->state, 0))
863: /*MC
864: PetscObjectComposedDataGetIntstar - retrieve integer array data attached to an object with `PetscObjectComposedDataSetIntstar()`
866: Synopsis:
867: #include "petsc/private/petscimpl.h"
868: PetscErrorCode PetscObjectComposedDataGetIntstar(PetscObject obj,int id,int *data,PetscBool flag)
870: Not collective
872: Input parameters:
873: + obj - the object from which data is to be retrieved
874: - id - the identifier for the data
876: Output parameters:
877: + data - the data to be retrieved
878: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
880: Notes:
881: The 'data' and 'flag' variables are inlined, so they are not pointers.
883: The length of the array accessed must be known, it is not available through this API.
885: Level: developer
887: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetReal()`,
888: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
889: `PetscObjectCompose()`, `PetscObjectQuery()`
890: M*/
891: #define PetscObjectComposedDataGetIntstar(obj, id, data, flag) (((obj)->intstarcomposedstate ? (data = (obj)->intstarcomposeddata[id], flag = (PetscBool)((obj)->intstarcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
893: /*MC
894: PetscObjectComposedDataSetReal - attach real data to a `PetscObject` that may be accessed with `PetscObjectComposedDataGetReal()`
896: Synopsis:
897: #include "petsc/private/petscimpl.h"
898: PetscErrorCode PetscObjectComposedDataSetReal(PetscObject obj,int id,PetscReal data)
900: Not collective
902: Input parameters:
903: + obj - the object to which data is to be attached
904: . id - the identifier for the data
905: - data - the data to be attached
907: Note:
908: The data identifier can be determined through a call to `PetscObjectComposedDataRegister()`
910: Level: developer
912: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
913: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
914: `PetscObjectCompose()`, `PetscObjectQuery()`
915: M*/
916: #define PetscObjectComposedDataSetReal(obj, id, data) ((((obj)->real_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseReal(obj)) || ((obj)->realcomposeddata[id] = data, (obj)->realcomposedstate[id] = (obj)->state, 0))
918: /*MC
919: PetscObjectComposedDataGetReal - retrieve real data attached to an object set with `PetscObjectComposedDataSetReal()`
921: Synopsis:
922: #include "petsc/private/petscimpl.h"
923: PetscErrorCode PetscObjectComposedDataGetReal(PetscObject obj,int id,PetscReal data,PetscBool flag)
925: Not collective
927: Input parameters:
928: + obj - the object from which data is to be retrieved
929: - id - the identifier for the data
931: Output parameters:
932: + data - the data to be retrieved
933: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
935: Note:
936: The 'data' and 'flag' variables are inlined, so they are not pointers.
938: Level: developer
940: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataSetIntstar()`,
941: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
942: `PetscObjectCompose()`, `PetscObjectQuery()`
943: M*/
944: #define PetscObjectComposedDataGetReal(obj, id, data, flag) (((obj)->realcomposedstate ? (data = (obj)->realcomposeddata[id], flag = (PetscBool)((obj)->realcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
946: /*MC
947: PetscObjectComposedDataSetRealstar - attach real array data to a `PetscObject` that may be retrieved with `PetscObjectComposedDataGetRealstar()`
949: Synopsis:
950: #include "petsc/private/petscimpl.h"
951: PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *data)
953: Not collective
955: Input parameters:
956: + obj - the object to which data is to be attached
957: . id - the identifier for the data
958: - data - the data to be attached
960: Notes:
961: The data identifier can be determined through a call to `PetscObjectComposedDataRegister()`
963: The length of the array accessed must be known, it is not available through this API.
965: Level: developer
967: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
968: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
969: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataGetRealstar()`
970: M*/
971: #define PetscObjectComposedDataSetRealstar(obj, id, data) \
972: ((((obj)->realstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseRealstar(obj)) || ((obj)->realstarcomposeddata[id] = data, (obj)->realstarcomposedstate[id] = (obj)->state, 0))
974: /*MC
975: PetscObjectComposedDataGetRealstar - retrieve real array data attached to an object with `PetscObjectComposedDataSetRealstar()`
977: Synopsis:
978: #include "petsc/private/petscimpl.h"
979: PetscErrorCode PetscObjectComposedDataGetRealstar(PetscObject obj,int id,PetscReal *data,PetscBool flag)
981: Not collective
983: Input parameters:
984: + obj - the object from which data is to be retrieved
985: - id - the identifier for the data
987: Output parameters:
988: + data - the data to be retrieved
989: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
991: Notes:
992: The 'data' and 'flag' variables are inlined, so they are not pointers.
994: The length of the array accessed must be known, it is not available through this API.
996: Level: developer
998: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
999: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1000: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`
1001: M*/
1002: #define PetscObjectComposedDataGetRealstar(obj, id, data, flag) (((obj)->realstarcomposedstate ? (data = (obj)->realstarcomposeddata[id], flag = (PetscBool)((obj)->realstarcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
1004: /*MC
1005: PetscObjectComposedDataSetScalar - attach scalar data to a PetscObject that may be retrieved with `PetscObjectComposedDataGetScalar()`
1007: Synopsis:
1008: #include "petsc/private/petscimpl.h"
1009: PetscErrorCode PetscObjectComposedDataSetScalar(PetscObject obj,int id,PetscScalar data)
1011: Not collective
1013: Input parameters:
1014: + obj - the object to which data is to be attached
1015: . id - the identifier for the data
1016: - data - the data to be attached
1018: Note:
1019: The data identifier can be determined through a call to `PetscObjectComposedDataRegister()`
1021: Level: developer
1023: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
1024: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1025: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataGetScalar()`
1026: M*/
1027: #if defined(PETSC_USE_COMPLEX)
1028: #define PetscObjectComposedDataSetScalar(obj, id, data) ((((obj)->scalar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalar(obj)) || ((obj)->scalarcomposeddata[id] = data, (obj)->scalarcomposedstate[id] = (obj)->state, 0))
1029: #else
1030: #define PetscObjectComposedDataSetScalar(obj, id, data) PetscObjectComposedDataSetReal(obj, id, data)
1031: #endif
1032: /*MC
1033: PetscObjectComposedDataGetScalar - retrieve scalar data attached to an object that was set with `PetscObjectComposedDataSetScalar()`
1035: Synopsis:
1036: #include "petsc/private/petscimpl.h"
1037: PetscErrorCode PetscObjectComposedDataGetScalar(PetscObject obj,int id,PetscScalar data,PetscBool flag)
1039: Not collective
1041: Input parameters:
1042: + obj - the object from which data is to be retrieved
1043: - id - the identifier for the data
1045: Output parameters:
1046: + data - the data to be retrieved
1047: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
1049: Note:
1050: The 'data' and 'flag' variables are inlined, so they are not pointers.
1052: Level: developer
1054: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
1055: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1056: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataSetScalar()`
1057: M*/
1058: #if defined(PETSC_USE_COMPLEX)
1059: #define PetscObjectComposedDataGetScalar(obj, id, data, flag) (((obj)->scalarcomposedstate ? (data = (obj)->scalarcomposeddata[id], flag = (PetscBool)((obj)->scalarcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
1060: #else
1061: #define PetscObjectComposedDataGetScalar(obj, id, data, flag) PetscObjectComposedDataGetReal(obj, id, data, flag)
1062: #endif
1064: /*MC
1065: PetscObjectComposedDataSetScalarstar - attach scalar array data to a `PetscObject` that may be retrieved with `PetscObjectComposedDataSetScalarstar()`
1067: Synopsis:
1068: #include "petsc/private/petscimpl.h"
1069: PetscErrorCode PetscObjectComposedDataSetScalarstar(PetscObject obj,int id,PetscScalar *data)
1071: Not collective
1073: Input parameters:
1074: + obj - the object to which data is to be attached
1075: . id - the identifier for the data
1076: - data - the data to be attached
1078: Notes:
1079: The data identifier can be determined through a call to `PetscObjectComposedDataRegister()`
1081: The length of the array accessed must be known, it is not available through this API.
1083: Level: developer
1085: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
1086: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1087: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataGetScalarstar()`
1088: M*/
1089: #if defined(PETSC_USE_COMPLEX)
1090: #define PetscObjectComposedDataSetScalarstar(obj, id, data) \
1091: ((((obj)->scalarstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalarstar(obj)) || ((obj)->scalarstarcomposeddata[id] = data, (obj)->scalarstarcomposedstate[id] = (obj)->state, 0))
1092: #else
1093: #define PetscObjectComposedDataSetScalarstar(obj, id, data) PetscObjectComposedDataSetRealstar(obj, id, data)
1094: #endif
1095: /*MC
1096: PetscObjectComposedDataGetScalarstar - retrieve scalar array data set with `PetscObjectComposedDataSetScalarstar()`
1097: attached to an object
1099: Synopsis:
1100: #include "petsc/private/petscimpl.h"
1101: PetscErrorCode PetscObjectComposedDataGetScalarstar(PetscObject obj,int id,PetscScalar *data,PetscBool flag)
1103: Not collective
1105: Input parameters:
1106: + obj - the object from which data is to be retrieved
1107: - id - the identifier for the data
1109: Output parameters:
1110: + data - the data to be retrieved
1111: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
1113: Notes:
1114: The 'data' and 'flag' variables are inlined, so they are not pointers.
1116: The length of the array accessed must be known, it is not available through this API.
1118: Level: developer
1120: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
1121: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1122: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataSetScalarstar()`
1123: M*/
1124: #if defined(PETSC_USE_COMPLEX)
1125: #define PetscObjectComposedDataGetScalarstar(obj, id, data, flag) (((obj)->scalarstarcomposedstate ? (data = (obj)->scalarstarcomposeddata[id], flag = (PetscBool)((obj)->scalarstarcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
1126: #else
1127: #define PetscObjectComposedDataGetScalarstar(obj, id, data, flag) PetscObjectComposedDataGetRealstar(obj, id, data, flag)
1128: #endif
1130: PETSC_EXTERN PetscMPIInt Petsc_Counter_keyval;
1131: PETSC_EXTERN PetscMPIInt Petsc_InnerComm_keyval;
1132: PETSC_EXTERN PetscMPIInt Petsc_OuterComm_keyval;
1133: PETSC_EXTERN PetscMPIInt Petsc_Seq_keyval;
1134: PETSC_EXTERN PetscMPIInt Petsc_ShmComm_keyval;
1136: struct PetscCommStash {
1137: struct PetscCommStash *next;
1138: MPI_Comm comm;
1139: };
1141: /*
1142: PETSc communicators have this attribute, see
1143: PetscCommDuplicate(), PetscCommDestroy(), PetscCommGetNewTag(), PetscObjectGetName()
1144: */
1145: typedef struct {
1146: PetscMPIInt tag; /* next free tag value */
1147: PetscInt refcount; /* number of references, communicator can be freed when this reaches 0 */
1148: PetscInt namecount; /* used to generate the next name, as in Vec_0, Mat_1, ... */
1149: PetscMPIInt *iflags; /* length of comm size, shared by all calls to PetscCommBuildTwoSided_Allreduce/RedScatter on this comm */
1150: struct PetscCommStash *comms; /* communicators available for PETSc to pass off to other packages */
1151: } PetscCommCounter;
1153: typedef enum {
1154: STATE_BEGIN,
1155: STATE_PENDING,
1156: STATE_END
1157: } SRState;
1159: typedef enum {
1160: PETSC_SR_REDUCE_SUM = 0,
1161: PETSC_SR_REDUCE_MAX = 1,
1162: PETSC_SR_REDUCE_MIN = 2
1163: } PetscSRReductionType;
1165: typedef struct {
1166: MPI_Comm comm;
1167: MPI_Request request;
1168: PetscBool mix;
1169: PetscBool async;
1170: PetscScalar *lvalues; /* this are the reduced values before call to MPI_Allreduce() */
1171: PetscScalar *gvalues; /* values after call to MPI_Allreduce() */
1172: void **invecs; /* for debugging only, vector/memory used with each op */
1173: PetscInt *reducetype; /* is particular value to be summed or maxed? */
1174: struct {
1175: PetscScalar v;
1176: PetscInt i;
1177: } *lvalues_mix, *gvalues_mix; /* used when mixing reduce operations */
1178: SRState state; /* are we calling xxxBegin() or xxxEnd()? */
1179: PetscInt maxops; /* total amount of space we have for requests */
1180: PetscInt numopsbegin; /* number of requests that have been queued in */
1181: PetscInt numopsend; /* number of requests that have been gotten by user */
1182: } PetscSplitReduction;
1184: PETSC_EXTERN PetscErrorCode PetscSplitReductionGet(MPI_Comm, PetscSplitReduction **);
1185: PETSC_EXTERN PetscErrorCode PetscSplitReductionEnd(PetscSplitReduction *);
1186: PETSC_EXTERN PetscErrorCode PetscSplitReductionExtend(PetscSplitReduction *);
1188: #if !defined(PETSC_SKIP_SPINLOCK)
1189: #if defined(PETSC_HAVE_THREADSAFETY)
1190: #if defined(PETSC_HAVE_CONCURRENCYKIT)
1191: #if defined(__cplusplus)
1192: /* CK does not have extern "C" protection in their include files */
1193: extern "C" {
1194: #endif
1195: #include <ck_spinlock.h>
1196: #if defined(__cplusplus)
1197: }
1198: #endif
1199: typedef ck_spinlock_t PetscSpinlock;
1200: static inline PetscErrorCode PetscSpinlockCreate(PetscSpinlock *ck_spinlock)
1201: {
1202: ck_spinlock_init(ck_spinlock);
1203: return 0;
1204: }
1205: static inline PetscErrorCode PetscSpinlockLock(PetscSpinlock *ck_spinlock)
1206: {
1207: ck_spinlock_lock(ck_spinlock);
1208: return 0;
1209: }
1210: static inline PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *ck_spinlock)
1211: {
1212: ck_spinlock_unlock(ck_spinlock);
1213: return 0;
1214: }
1215: static inline PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *ck_spinlock)
1216: {
1217: return 0;
1218: }
1219: #elif defined(PETSC_HAVE_OPENMP)
1221: #include <omp.h>
1222: typedef omp_lock_t PetscSpinlock;
1223: static inline PetscErrorCode PetscSpinlockCreate(PetscSpinlock *omp_lock)
1224: {
1225: omp_init_lock(omp_lock);
1226: return 0;
1227: }
1228: static inline PetscErrorCode PetscSpinlockLock(PetscSpinlock *omp_lock)
1229: {
1230: omp_set_lock(omp_lock);
1231: return 0;
1232: }
1233: static inline PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *omp_lock)
1234: {
1235: omp_unset_lock(omp_lock);
1236: return 0;
1237: }
1238: static inline PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *omp_lock)
1239: {
1240: omp_destroy_lock(omp_lock);
1241: return 0;
1242: }
1243: #else
1244: #error "Thread safety requires either --with-openmp or --download-concurrencykit"
1245: #endif
1247: #else
1248: typedef int PetscSpinlock;
1249: #define PetscSpinlockCreate(a) 0
1250: #define PetscSpinlockLock(a) 0
1251: #define PetscSpinlockUnlock(a) 0
1252: #define PetscSpinlockDestroy(a) 0
1253: #endif
1255: #if defined(PETSC_HAVE_THREADSAFETY)
1256: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockOpen;
1257: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStdout;
1258: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStderr;
1259: PETSC_INTERN PetscSpinlock PetscCommSpinLock;
1260: #endif
1261: #endif
1263: PETSC_EXTERN PetscLogEvent PETSC_Barrier;
1264: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSided;
1265: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSidedF;
1266: PETSC_EXTERN PetscBool use_gpu_aware_mpi;
1267: PETSC_EXTERN PetscBool PetscPrintFunctionList;
1269: #if defined(PETSC_HAVE_ADIOS)
1270: PETSC_EXTERN int64_t Petsc_adios_group;
1271: #endif
1273: #if defined(PETSC_HAVE_KOKKOS)
1274: PETSC_INTERN PetscBool PetscBeganKokkos;
1275: PETSC_EXTERN PetscBool PetscKokkosInitialized;
1276: PETSC_INTERN PetscErrorCode PetscKokkosIsInitialized_Private(PetscBool *);
1277: PETSC_INTERN PetscErrorCode PetscKokkosFinalize_Private(void);
1278: #endif
1280: #if defined(PETSC_HAVE_OPENMP)
1281: PETSC_EXTERN PetscInt PetscNumOMPThreads;
1282: #endif
1284: #endif /* PETSCIMPL_H */