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: PetscErrorCode (*non_cyclic_references)(PetscObject, PetscInt *);
104: PetscInt64 cidx;
105: PetscMPIInt tag;
106: PetscFunctionList qlist;
107: PetscObjectList olist;
108: char *class_name; /* for example, "Vec" */
109: char *description;
110: char *mansec;
111: char *type_name; /* this is the subclass, for example VECSEQ which equals "seq" */
112: char *name;
113: char *prefix;
114: PetscInt tablevel;
115: void *cpp;
116: PetscObjectState state;
117: PetscInt int_idmax, intstar_idmax;
118: PetscObjectState *intcomposedstate, *intstarcomposedstate;
119: PetscInt *intcomposeddata, **intstarcomposeddata;
120: PetscInt real_idmax, realstar_idmax;
121: PetscObjectState *realcomposedstate, *realstarcomposedstate;
122: PetscReal *realcomposeddata, **realstarcomposeddata;
123: PetscInt scalar_idmax, scalarstar_idmax;
124: PetscObjectState *scalarcomposedstate, *scalarstarcomposedstate;
125: PetscScalar *scalarcomposeddata, **scalarstarcomposeddata;
126: void (**fortran_func_pointers)(void); /* used by Fortran interface functions to stash user provided Fortran functions */
127: PetscFortranCallbackId num_fortran_func_pointers; /* number of Fortran function pointers allocated */
128: PetscFortranCallback *fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
129: PetscFortranCallbackId num_fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
130: void *python_context;
131: PetscErrorCode (*python_destroy)(void *);
133: PetscInt noptionhandler;
134: PetscErrorCode (*optionhandler[PETSC_MAX_OPTIONS_HANDLER])(PetscObject, PetscOptionItems *, void *);
135: PetscErrorCode (*optiondestroy[PETSC_MAX_OPTIONS_HANDLER])(PetscObject, void *);
136: void *optionctx[PETSC_MAX_OPTIONS_HANDLER];
137: #if defined(PETSC_HAVE_SAWS)
138: PetscBool amsmem; /* if PETSC_TRUE then this object is registered with SAWs and visible to clients */
139: PetscBool amspublishblock; /* if PETSC_TRUE and publishing objects then will block at PetscObjectSAWsBlock() */
140: #endif
141: PetscOptions options; /* options database used, NULL means default */
142: PetscBool optionsprinted;
143: PetscBool donotPetscObjectPrintClassNamePrefixType;
144: } _p_PetscObject;
146: #define PETSCHEADER(ObjectOps) \
147: _p_PetscObject hdr; \
148: ObjectOps ops[1]
150: #define PETSCFREEDHEADER -1
152: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectDestroyFunction)(PetscObject *); /* force cast in next macro to NEVER use extern "C" style */
153: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectViewFunction)(PetscObject, PetscViewer);
155: /*@C
156: PetscHeaderCreate - Creates a PETSc object of a particular class
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")
161: . descr - string containing short description; should be static (for example "Vector")
162: . mansec - string indicating section in manual pages; should be static (for example "Vec")
163: . comm - the MPI Communicator
164: . destroy - the destroy routine for this object (for example `VecDestroy()`)
165: - view - the view routine for this object (for example `VecView()`)
167: Output Parameter:
168: . h - the newly created object
170: Level: developer
172: .seealso: `PetscHeaderDestroy()`, `PetscClassIdRegister()`
174: @*/
175: #define PetscHeaderCreate(h, classid, class_name, descr, mansec, comm, destroy, view) \
176: (PetscNew(&(h)) || PetscHeaderCreate_Private((PetscObject)(h), classid, class_name, descr, mansec, comm, (PetscObjectDestroyFunction)(destroy), (PetscObjectViewFunction)(view)) || PetscLogObjectCreate(h))
178: PETSC_EXTERN PetscErrorCode PetscComposedQuantitiesDestroy(PetscObject obj);
179: PETSC_EXTERN PetscErrorCode PetscHeaderCreate_Private(PetscObject, PetscClassId, const char[], const char[], const char[], MPI_Comm, PetscObjectDestroyFunction, PetscObjectViewFunction);
180: PETSC_INTERN PetscObjectId PetscObjectNewId_Internal(void);
182: /*@C
183: PetscHeaderDestroy - Final step in destroying a PetscObject
185: Input Parameters:
186: . h - the header created with `PetscHeaderCreate()`
188: Level: developer
190: .seealso: `PetscHeaderCreate()`
191: @*/
192: #define PetscHeaderDestroy(h) (PetscHeaderDestroy_Private((PetscObject)(*(h)), PETSC_FALSE) || PetscFree(*(h)))
194: PETSC_EXTERN PetscErrorCode PetscHeaderDestroy_Private(PetscObject, PetscBool);
195: PETSC_SINGLE_LIBRARY_INTERN PetscErrorCode PetscHeaderReset_Internal(PetscObject);
196: PETSC_EXTERN PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject, PetscObject);
197: PETSC_EXTERN PetscErrorCode PetscObjectSetFortranCallback(PetscObject, PetscFortranCallbackType, PetscFortranCallbackId *, void (*)(void), void *ctx);
198: PETSC_EXTERN PetscErrorCode PetscObjectGetFortranCallback(PetscObject, PetscFortranCallbackType, PetscFortranCallbackId, void (**)(void), void **ctx);
200: PETSC_INTERN PetscErrorCode PetscCitationsInitialize(void);
201: PETSC_INTERN PetscErrorCode PetscFreeMPIResources(void);
202: PETSC_INTERN PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions, PetscBool *);
204: /* Code shared between C and Fortran */
205: PETSC_INTERN PetscErrorCode PetscInitialize_Common(const char *, const char *, const char *, PetscBool, PetscBool, PetscInt);
207: #if PetscDefined(HAVE_SETJMP_H)
209: #else
211: #endif
212: #if !defined(PETSC_CLANG_STATIC_ANALYZER)
213: /*
214: Macros to test if a PETSc object is valid and if pointers are valid
215: */
216: #if !defined(PETSC_USE_DEBUG)
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: do { \
264: (void)(h); \
265: } while (0)
267: #else
269: /* This check is for subtype methods such as DMDAGetCorners() that do not use the PetscTryMethod() or PetscUseMethod() paradigm */
271: do { \
272: PetscBool _7_same; \
274: PetscObjectTypeCompare((PetscObject)(h), t, &_7_same); \
276: } while (0)
279: do { \
282: } while (0)
285: do { \
287: if (((PetscObject)(h))->classid != ck) { \
289: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Wrong type of object: Parameter # %d", arg); \
290: } \
291: } while (0)
294: do { \
298: } while (0)
310: do { \
312: } while (0)
313: #endif
314: #else /* PETSC_CLANG_STATIC_ANALYZER */
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: template <typename T>
339: template <typename T>
341: #endif /* PETSC_CLANG_STATIC_ANALYZER */
343: #define PetscSorted(n, idx, sorted) \
344: do { \
345: (sorted) = PETSC_TRUE; \
346: for (PetscInt _i_ = 1; _i_ < (n); ++_i_) { \
347: if ((idx)[_i_] < (idx)[_i_ - 1]) { \
348: (sorted) = PETSC_FALSE; \
349: break; \
350: } \
351: } \
352: } while (0)
354: #if !defined(PETSC_CLANG_STATIC_ANALYZER)
355: #if !defined(PETSC_USE_DEBUG)
358: do { \
359: (void)(a); \
360: (void)(b); \
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: } while (0)
375: do { \
376: (void)(a); \
377: (void)(b); \
378: } while (0)
380: do { \
381: (void)(a); \
382: (void)(b); \
383: } while (0)
385: do { \
386: (void)(a); \
387: (void)(b); \
388: } while (0)
390: do { \
391: (void)(a); \
392: (void)(b); \
393: } while (0)
395: do { \
396: (void)(a); \
397: (void)(b); \
398: } while (0)
400: do { \
401: (void)(a); \
402: (void)(b); \
403: } while (0)
405: do { \
406: (void)(a); \
407: (void)(b); \
408: } while (0)
410: do { \
411: (void)(a); \
412: (void)(b); \
413: } while (0)
415: do { \
416: (void)(n); \
417: (void)(idx); \
418: } while (0)
420: #else
422: /*
423: This macro currently does nothing, the plan is for each PetscObject to have a PetscInt "type"
424: member associated with the string type_name that can be quickly compared.
426: **Do not swap this macro to compare string type_name!**
428: This macro is used incorrectly in the code. Many places that do not need identity of the
429: types incorrectly call this check and would need to be fixed if this macro is enabled.
430: */
431: #if 0
433: do { \
434: PetscBool pcst_type_eq_ = PETSC_TRUE; \
435: PetscStrcmp(((PetscObject)(a))->type_name, (((PetscObject)(b)))->type_name, &pcst_type_eq_); \
437: } while (0)
438: #else
440: do { \
441: (void)(a); \
442: (void)(b); \
443: } while (0)
444: #endif
446: /*
447: Check type_name
448: */
450: do { \
451: PetscBool _7_match; \
452: PetscObjectTypeCompare(((PetscObject)(a)), (type), &_7_match); \
454: } while (0)
457: do { \
458: PetscBool _7_match; \
459: PetscObjectTypeCompareAny(((PetscObject)(a)), &_7_match, (type1), (type2), ""); \
461: } while (0)
463: /*
464: Use this macro to check if the type is set
465: */
468: /*
469: Sometimes object must live on same communicator to inter-operate
470: */
472: do { \
473: PetscMPIInt _7_flag; \
474: MPI_Comm_compare(PetscObjectComm((PetscObject)(a)), PetscObjectComm((PetscObject)(b)), &_7_flag); \
476: } while (0)
479: do { \
482: } while (0)
485: do { \
486: PetscScalar b0 = (b); \
487: PetscReal b1[5], b2[5]; \
488: if (PetscIsNanScalar(b0)) { \
489: b1[4] = 1; \
490: } else { \
491: b1[4] = 0; \
492: }; \
493: b1[0] = -PetscRealPart(b0); \
494: b1[1] = PetscRealPart(b0); \
495: b1[2] = -PetscImaginaryPart(b0); \
496: b1[3] = PetscImaginaryPart(b0); \
497: MPIU_Allreduce(b1, b2, 5, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)(a))); \
499: } while (0)
502: do { \
503: PetscReal b0 = (b), b1[3], b2[3]; \
504: if (PetscIsNanReal(b0)) { \
505: b1[2] = 1; \
506: } else { \
507: b1[2] = 0; \
508: }; \
509: b1[0] = -b0; \
510: b1[1] = b0; \
511: MPIU_Allreduce(b1, b2, 3, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)(a))); \
513: } while (0)
516: do { \
517: PetscInt b0 = (b), b1[2], b2[2]; \
518: b1[0] = -b0; \
519: b1[1] = b0; \
520: MPIU_Allreduce(b1, b2, 2, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)(a))); \
522: } while (0)
525: do { \
526: PetscMPIInt b0 = (b), b1[2], b2[2]; \
527: b1[0] = -b0; \
528: b1[1] = b0; \
529: MPIU_Allreduce(b1, b2, 2, MPI_INT, MPI_MAX, PetscObjectComm((PetscObject)(a))); \
531: } while (0)
534: do { \
535: PetscMPIInt b0 = (PetscMPIInt)(b), b1[2], b2[2]; \
536: b1[0] = -b0; \
537: b1[1] = b0; \
538: MPIU_Allreduce(b1, b2, 2, MPI_INT, MPI_MAX, PetscObjectComm((PetscObject)(a))); \
540: } while (0)
543: do { \
544: PetscMPIInt b0 = (PetscMPIInt)(b), b1[2], b2[2]; \
545: b1[0] = -b0; \
546: b1[1] = b0; \
547: MPIU_Allreduce(b1, b2, 2, MPI_INT, MPI_MAX, PetscObjectComm((PetscObject)(a))); \
549: } while (0)
552: do { \
553: PetscBool _1_flg; \
554: PetscSorted(n, idx, _1_flg); \
556: } while (0)
558: #endif
559: #else /* PETSC_CLANG_STATIC_ANALYZER */
560: template <typename Ta, typename Tb>
562: template <typename Ta, typename Tb>
564: template <typename Ta, typename Tb, typename Tc>
566: template <typename T>
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 Ta, typename Tb>
582: template <typename Ta, typename Tb>
584: template <typename T>
586: #endif /* PETSC_CLANG_STATIC_ANALYZER */
588: /*MC
589: PetscTryMethod - Queries an object for a method added with `PetscObjectComposeFunction()`, if it exists then calls it.
591: Synopsis:
592: #include "petsc/private/petscimpl.h"
593: PetscTryMethod(PetscObject obj,const char *name,(arg_types),(arg_value))
595: Input Parameters:
596: + obj - the object
597: . name - the name of the method, for example, "KSPGMRESSetRestart_C" for the function `KSPGMRESSetRestart()`
598: . arg_types - the argument types for the method, for example, (KSP,PetscInt)
599: - args - the arguements for the method, for example, (ksp,restart))
601: Level: developer
603: Notes:
604: The object is always the implicit first argument of the method and is not listed in arg_types or args
606: This does not return an error code, it is a macro that returns with an erorr code on error.
608: Use `PetscUseTypeMethod()` or `PetscTryTypeMethod()` to call functions that are included in the objects function table, the `ops` array
609: in the object.
612: M*/
613: #define PetscTryMethod(obj, A, B, C) \
614: do { \
615: PetscErrorCode(*_7_f) B; \
616: PetscObjectQueryFunction((PetscObject)(obj), A, &_7_f); \
617: if (_7_f) (*_7_f)C; \
618: } while (0)
620: /*MC
621: PetscUseMethod - Queries an object for a method added with `PetscObjectComposeFunction()`, if it exists then calls it, otherwise generates an error.
623: Synopsis:
624: #include "petsc/private/petscimpl.h"
625: PetscUseMethod(PetscObject obj,const char *name,(arg_types),(arg_value))
627: Input Parameters:
628: + obj - the object
629: . name - the name of the method, for example, "KSPGMRESSetRestart_C" for the function `KSPGMRESSetRestart()`
630: . arg_types - the argument types for the method, for example, (KSP,PetscInt)
631: - args - the arguements for the method, for example, (ksp,restart))
633: Level: developer
635: Notes:
636: The object is always the implicit first argument of the method and is not listed in arg_types or args
638: This does not return an error code, it is a macro that returns with an erorr code on error.
640: Use `PetscUseTypeMethod()` or `PetscTryTypeMethod()` to call functions that are included in the objects function table, the `ops` array
641: in the object.
644: M*/
645: #define PetscUseMethod(obj, A, B, C) \
646: do { \
647: PetscErrorCode(*_7_f) B; \
648: PetscObjectQueryFunction((PetscObject)(obj), A, &_7_f); \
650: (*_7_f)C; \
651: } while (0)
653: /*
654: Use Microsoft traditional preprocessor.
656: The Microsoft compiler option -Zc:preprocessor available in recent versions of the compiler
657: sets _MSVC_TRADITIONAL to zero so this code path is not used.
659: It appears the Intel Windows compiler icl does not have an equaivalent of -Zc:preprocessor
661: These macros use the trick that Windows compilers remove the , before the __VA_ARGS__ if __VA_ARGS__ does not exist
663: PetscCall() cannot be used in the macros because the remove the , trick does not work in a macro in a macro
664: */
665: #if (defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)) || defined(__ICL)
667: #define PetscUseTypeMethod(obj, OP, ...) \
668: do { \
669: PetscErrorCode ierr_p_; \
670: PetscStackUpdateLine; \
672: ierr_p_ = (*(obj)->ops->OP)(obj, __VA_ARGS__); \
673: ierr_p_; \
674: } while (0)
676: #define PetscTryTypeMethod(obj, OP, ...) \
677: do { \
678: if ((obj)->ops->OP) { \
679: PetscErrorCode ierr_p_; \
680: PetscStackUpdateLine; \
681: ierr_p_ = (*(obj)->ops->OP)(obj, __VA_ARGS__); \
682: ierr_p_; \
683: } \
684: } while (0)
686: #else
688: /*MC
689: 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
691: Synopsis:
692: #include "petsc/private/petscimpl.h"
693: PetscUseTypeMethod(obj,method,other_args)
695: Input Parameters:
696: + obj - the object the method is called on
697: . method - the name of the method, for example, mult for the PETSc routine MatMult()
698: - other_args - the other arguments for the method, obj is the first argument
700: Level: developer
702: Note:
703: This does not return an error code, it is a macro that returns with an erorr code on error.
705: Use `PetscUseMethod()` or `PetscTryMethod()` to call functions that have been composed to an object with `PetscObjectComposeFunction()`
708: M*/
709: #define PetscUseTypeMethod(obj, ...) \
710: do { \
712: PetscStringize(PETSC_FIRST_ARG((__VA_ARGS__,unused))), ((PetscObject)obj)->class_name, ((PetscObject)obj)->type_name); \
713: (*(obj)->ops->PETSC_FIRST_ARG((__VA_ARGS__, unused)))(obj PETSC_REST_ARG(__VA_ARGS__)); \
714: } while (0)
716: /*MC
717: 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
719: Synopsis:
720: #include "petsc/private/petscimpl.h"
721: PetscTryTtype(obj,method,other_args)
723: Input Parameters:
724: + obj - the object the method is called on
725: . method - the name of the method, for example, mult for the PETSc routine MatMult()
726: - other_args - the other arguments for the method, obj is the first argument
728: Level: developer
730: Note:
731: This does not return an error code, it is a macro that returns with an erorr code on error.
733: Use `PetscUseMethod()` or `PetscTryMethod()` to call functions that have been composed to an object with `PetscObjectComposeFunction()`
736: M*/
737: #define PetscTryTypeMethod(obj, ...) \
738: do { \
739: if ((obj)->ops->PETSC_FIRST_ARG((__VA_ARGS__, unused))) (*(obj)->ops->PETSC_FIRST_ARG((__VA_ARGS__, unused)))(obj PETSC_REST_ARG(__VA_ARGS__)); \
740: } while (0)
742: #endif
744: /*MC
745: PetscObjectStateIncrease - Increases the state of any `PetscObject`
747: Synopsis:
748: #include "petsc/private/petscimpl.h"
749: PetscErrorCode PetscObjectStateIncrease(PetscObject obj)
751: Logically Collective
753: Input Parameter:
754: . obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`. This must be
755: cast with a (PetscObject), for example,
756: `PetscObjectStateIncrease`((`PetscObject`)mat);
758: Notes:
759: Object state is a 64 bit integer which gets increased every time
760: the object is changed internally. By saving and later querying the object state
761: one can determine whether information about the object is still current.
762: Currently, state is maintained for `Vec` and `Mat` objects.
764: This routine is mostly for internal use by PETSc; a developer need only
765: call it after explicit access to an object's internals. Routines such
766: as `VecSet()` or `MatScale()` already call this routine. It is also called, as a
767: precaution, in `VecRestoreArray()`, `MatRestoreRow()`, `MatDenseRestoreArray()`.
769: Routines such as `VecNorm()` can by-pass the computation if the norm has already been computed and the vector's state has not changed.
771: This routine is logically collective because state equality comparison needs to be possible without communication.
773: `Mat` also has `MatGetNonzeroState()` and `MatSetNonzeroState()` for tracking changes to the nonzero structure.
775: Level: developer
777: .seealso: `PetscObjectStateGet()`, `MatSetNonzeroState()`, `PetscObject`
779: M*/
780: #define PetscObjectStateIncrease(obj) ((obj)->state++, 0)
782: PETSC_EXTERN PetscErrorCode PetscObjectStateGet(PetscObject, PetscObjectState *);
783: PETSC_EXTERN PetscErrorCode PetscObjectStateSet(PetscObject, PetscObjectState);
784: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataRegister(PetscInt *);
785: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject);
786: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject);
787: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject);
788: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject);
789: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject);
790: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject);
791: PETSC_EXTERN PetscInt PetscObjectComposedDataMax;
793: /*MC
794: PetscObjectComposedDataSetInt - attach integer data to a `PetscObject` that may be accessed with `PetscObjectComposedDataGetInt()`
796: Synopsis:
797: #include "petsc/private/petscimpl.h"
798: PetscErrorCode PetscObjectComposedDataSetInt(PetscObject obj,int id,int data)
800: Not collective
802: Input parameters:
803: + obj - the object to which data is to be attached
804: . id - the identifier for the data
805: - data - the data to be attached
807: Notes:
808: The data identifier can be created through a call to `PetscObjectComposedDataRegister()`
810: This allows the efficient composition of a single integer value with a `PetscObject`. Complex data may be
811: attached with `PetscObjectCompose()`
813: Level: developer
815: .seealso: `PetscObjectComposedDataGetInt()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetReal()`,
816: `PetscObjectComposedDataGetIntstar()`, `PetscObjectComposedDataSetIntstar()`, `PetscObject`,
817: `PetscObjectCompose()`, `PetscObjectQuery()`
818: M*/
819: #define PetscObjectComposedDataSetInt(obj, id, data) ((((obj)->int_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseInt(obj)) || ((obj)->intcomposeddata[id] = data, (obj)->intcomposedstate[id] = (obj)->state, 0))
821: /*MC
822: PetscObjectComposedDataGetInt - retrieve integer data attached to an object with `PetscObjectComposedDataSetInt()`
824: Synopsis:
825: #include "petsc/private/petscimpl.h"
826: PetscErrorCode PetscObjectComposedDataGetInt(PetscObject obj,int id,int data,PetscBool flag)
828: Not collective
830: Input parameters:
831: + obj - the object from which data is to be retrieved
832: - id - the identifier for the data
834: Output parameters:
835: + data - the data to be retrieved
836: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
838: Level: developer
840: Notes:
841: The 'data' and 'flag' variables are inlined, so they are not pointers.
843: The length of the array accessed must be known.
845: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetReal()`,
846: `PetscObjectComposedDataGetIntstar()`, `PetscObjectComposedDataSetIntstar()`, `PetscObject`,
847: `PetscObjectCompose()`, `PetscObjectQuery()`
848: M*/
849: #define PetscObjectComposedDataGetInt(obj, id, data, flag) (((obj)->intcomposedstate ? (data = (obj)->intcomposeddata[id], flag = (PetscBool)((obj)->intcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
851: /*MC
852: PetscObjectComposedDataSetIntstar - attach an integer array data to a `PetscObject` that may be accessed with `PetscObjectComposedDataGetIntstar()`
854: Synopsis:
855: #include "petsc/private/petscimpl.h"
856: PetscErrorCode PetscObjectComposedDataSetIntstar(PetscObject obj,int id,int *data)
858: Not collective
860: Input parameters:
861: + obj - the object to which data is to be attached
862: . id - the identifier for the data
863: - data - the data to be attached
865: Notes:
866: The data identifier can be determined through a call to `PetscObjectComposedDataRegister()`
868: The length of the array accessed must be known, it is not available through this API.
870: Level: developer
872: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetReal()`,
873: `PetscObjectComposedDataGetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
874: `PetscObjectCompose()`, `PetscObjectQuery()`
875: M*/
876: #define PetscObjectComposedDataSetIntstar(obj, id, data) \
877: ((((obj)->intstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseIntstar(obj)) || ((obj)->intstarcomposeddata[id] = data, (obj)->intstarcomposedstate[id] = (obj)->state, 0))
879: /*MC
880: PetscObjectComposedDataGetIntstar - retrieve integer array data attached to an object with `PetscObjectComposedDataSetIntstar()`
882: Synopsis:
883: #include "petsc/private/petscimpl.h"
884: PetscErrorCode PetscObjectComposedDataGetIntstar(PetscObject obj,int id,int *data,PetscBool flag)
886: Not collective
888: Input parameters:
889: + obj - the object from which data is to be retrieved
890: - id - the identifier for the data
892: Output parameters:
893: + data - the data to be retrieved
894: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
896: Notes:
897: The 'data' and 'flag' variables are inlined, so they are not pointers.
899: The length of the array accessed must be known, it is not available through this API.
901: Level: developer
903: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetReal()`,
904: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
905: `PetscObjectCompose()`, `PetscObjectQuery()`
906: M*/
907: #define PetscObjectComposedDataGetIntstar(obj, id, data, flag) (((obj)->intstarcomposedstate ? (data = (obj)->intstarcomposeddata[id], flag = (PetscBool)((obj)->intstarcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
909: /*MC
910: PetscObjectComposedDataSetReal - attach real data to a `PetscObject` that may be accessed with `PetscObjectComposedDataGetReal()`
912: Synopsis:
913: #include "petsc/private/petscimpl.h"
914: PetscErrorCode PetscObjectComposedDataSetReal(PetscObject obj,int id,PetscReal data)
916: Not collective
918: Input parameters:
919: + obj - the object to which data is to be attached
920: . id - the identifier for the data
921: - data - the data to be attached
923: Note:
924: The data identifier can be determined through a call to `PetscObjectComposedDataRegister()`
926: Level: developer
928: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
929: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
930: `PetscObjectCompose()`, `PetscObjectQuery()`
931: M*/
932: #define PetscObjectComposedDataSetReal(obj, id, data) ((((obj)->real_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseReal(obj)) || ((obj)->realcomposeddata[id] = data, (obj)->realcomposedstate[id] = (obj)->state, 0))
934: /*MC
935: PetscObjectComposedDataGetReal - retrieve real data attached to an object set with `PetscObjectComposedDataSetReal()`
937: Synopsis:
938: #include "petsc/private/petscimpl.h"
939: PetscErrorCode PetscObjectComposedDataGetReal(PetscObject obj,int id,PetscReal data,PetscBool flag)
941: Not collective
943: Input parameters:
944: + obj - the object from which data is to be retrieved
945: - id - the identifier for the data
947: Output parameters:
948: + data - the data to be retrieved
949: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
951: Note:
952: The 'data' and 'flag' variables are inlined, so they are not pointers.
954: Level: developer
956: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataSetIntstar()`,
957: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
958: `PetscObjectCompose()`, `PetscObjectQuery()`
959: M*/
960: #define PetscObjectComposedDataGetReal(obj, id, data, flag) (((obj)->realcomposedstate ? (data = (obj)->realcomposeddata[id], flag = (PetscBool)((obj)->realcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
962: /*MC
963: PetscObjectComposedDataSetRealstar - attach real array data to a `PetscObject` that may be retrieved with `PetscObjectComposedDataGetRealstar()`
965: Synopsis:
966: #include "petsc/private/petscimpl.h"
967: PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *data)
969: Not collective
971: Input parameters:
972: + obj - the object to which data is to be attached
973: . id - the identifier for the data
974: - data - the data to be attached
976: Notes:
977: The data identifier can be determined through a call to `PetscObjectComposedDataRegister()`
979: The length of the array accessed must be known, it is not available through this API.
981: Level: developer
983: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
984: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
985: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataGetRealstar()`
986: M*/
987: #define PetscObjectComposedDataSetRealstar(obj, id, data) \
988: ((((obj)->realstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseRealstar(obj)) || ((obj)->realstarcomposeddata[id] = data, (obj)->realstarcomposedstate[id] = (obj)->state, 0))
990: /*MC
991: PetscObjectComposedDataGetRealstar - retrieve real array data attached to an object with `PetscObjectComposedDataSetRealstar()`
993: Synopsis:
994: #include "petsc/private/petscimpl.h"
995: PetscErrorCode PetscObjectComposedDataGetRealstar(PetscObject obj,int id,PetscReal *data,PetscBool flag)
997: Not collective
999: Input parameters:
1000: + obj - the object from which data is to be retrieved
1001: - id - the identifier for the data
1003: Output parameters:
1004: + data - the data to be retrieved
1005: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
1007: Notes:
1008: The 'data' and 'flag' variables are inlined, so they are not pointers.
1010: The length of the array accessed must be known, it is not available through this API.
1012: Level: developer
1014: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
1015: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1016: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`
1017: M*/
1018: #define PetscObjectComposedDataGetRealstar(obj, id, data, flag) (((obj)->realstarcomposedstate ? (data = (obj)->realstarcomposeddata[id], flag = (PetscBool)((obj)->realstarcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
1020: /*MC
1021: PetscObjectComposedDataSetScalar - attach scalar data to a PetscObject that may be retrieved with `PetscObjectComposedDataGetScalar()`
1023: Synopsis:
1024: #include "petsc/private/petscimpl.h"
1025: PetscErrorCode PetscObjectComposedDataSetScalar(PetscObject obj,int id,PetscScalar data)
1027: Not collective
1029: Input parameters:
1030: + obj - the object to which data is to be attached
1031: . id - the identifier for the data
1032: - data - the data to be attached
1034: Note:
1035: The data identifier can be determined through a call to `PetscObjectComposedDataRegister()`
1037: Level: developer
1039: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
1040: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1041: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataGetScalar()`
1042: M*/
1043: #if defined(PETSC_USE_COMPLEX)
1044: #define PetscObjectComposedDataSetScalar(obj, id, data) ((((obj)->scalar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalar(obj)) || ((obj)->scalarcomposeddata[id] = data, (obj)->scalarcomposedstate[id] = (obj)->state, 0))
1045: #else
1046: #define PetscObjectComposedDataSetScalar(obj, id, data) PetscObjectComposedDataSetReal(obj, id, data)
1047: #endif
1048: /*MC
1049: PetscObjectComposedDataGetScalar - retrieve scalar data attached to an object that was set with `PetscObjectComposedDataSetScalar()`
1051: Synopsis:
1052: #include "petsc/private/petscimpl.h"
1053: PetscErrorCode PetscObjectComposedDataGetScalar(PetscObject obj,int id,PetscScalar data,PetscBool flag)
1055: Not collective
1057: Input parameters:
1058: + obj - the object from which data is to be retrieved
1059: - id - the identifier for the data
1061: Output parameters:
1062: + data - the data to be retrieved
1063: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
1065: Note:
1066: The 'data' and 'flag' variables are inlined, so they are not pointers.
1068: Level: developer
1070: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
1071: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1072: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataSetScalar()`
1073: M*/
1074: #if defined(PETSC_USE_COMPLEX)
1075: #define PetscObjectComposedDataGetScalar(obj, id, data, flag) (((obj)->scalarcomposedstate ? (data = (obj)->scalarcomposeddata[id], flag = (PetscBool)((obj)->scalarcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
1076: #else
1077: #define PetscObjectComposedDataGetScalar(obj, id, data, flag) PetscObjectComposedDataGetReal(obj, id, data, flag)
1078: #endif
1080: /*MC
1081: PetscObjectComposedDataSetScalarstar - attach scalar array data to a `PetscObject` that may be retrieved with `PetscObjectComposedDataSetScalarstar()`
1083: Synopsis:
1084: #include "petsc/private/petscimpl.h"
1085: PetscErrorCode PetscObjectComposedDataSetScalarstar(PetscObject obj,int id,PetscScalar *data)
1087: Not collective
1089: Input parameters:
1090: + obj - the object to which data is to be attached
1091: . id - the identifier for the data
1092: - data - the data to be attached
1094: Notes:
1095: The data identifier can be determined through a call to `PetscObjectComposedDataRegister()`
1097: The length of the array accessed must be known, it is not available through this API.
1099: Level: developer
1101: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
1102: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1103: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataGetScalarstar()`
1104: M*/
1105: #if defined(PETSC_USE_COMPLEX)
1106: #define PetscObjectComposedDataSetScalarstar(obj, id, data) \
1107: ((((obj)->scalarstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalarstar(obj)) || ((obj)->scalarstarcomposeddata[id] = data, (obj)->scalarstarcomposedstate[id] = (obj)->state, 0))
1108: #else
1109: #define PetscObjectComposedDataSetScalarstar(obj, id, data) PetscObjectComposedDataSetRealstar(obj, id, data)
1110: #endif
1111: /*MC
1112: PetscObjectComposedDataGetScalarstar - retrieve scalar array data set with `PetscObjectComposedDataSetScalarstar()`
1113: attached to an object
1115: Synopsis:
1116: #include "petsc/private/petscimpl.h"
1117: PetscErrorCode PetscObjectComposedDataGetScalarstar(PetscObject obj,int id,PetscScalar *data,PetscBool flag)
1119: Not collective
1121: Input parameters:
1122: + obj - the object from which data is to be retrieved
1123: - id - the identifier for the data
1125: Output parameters:
1126: + data - the data to be retrieved
1127: - flag - `PETSC_TRUE` if the data item exists and is valid, `PETSC_FALSE` otherwise
1129: Notes:
1130: The 'data' and 'flag' variables are inlined, so they are not pointers.
1132: The length of the array accessed must be known, it is not available through this API.
1134: Level: developer
1136: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
1137: `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
1138: `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataSetScalarstar()`
1139: M*/
1140: #if defined(PETSC_USE_COMPLEX)
1141: #define PetscObjectComposedDataGetScalarstar(obj, id, data, flag) (((obj)->scalarstarcomposedstate ? (data = (obj)->scalarstarcomposeddata[id], flag = (PetscBool)((obj)->scalarstarcomposedstate[id] == (obj)->state)) : (flag = PETSC_FALSE)), 0)
1142: #else
1143: #define PetscObjectComposedDataGetScalarstar(obj, id, data, flag) PetscObjectComposedDataGetRealstar(obj, id, data, flag)
1144: #endif
1146: PETSC_EXTERN PetscMPIInt Petsc_Counter_keyval;
1147: PETSC_EXTERN PetscMPIInt Petsc_InnerComm_keyval;
1148: PETSC_EXTERN PetscMPIInt Petsc_OuterComm_keyval;
1149: PETSC_EXTERN PetscMPIInt Petsc_Seq_keyval;
1150: PETSC_EXTERN PetscMPIInt Petsc_ShmComm_keyval;
1151: PETSC_EXTERN PetscMPIInt Petsc_CreationIdx_keyval;
1152: PETSC_EXTERN PetscMPIInt Petsc_Garbage_HMap_keyval;
1154: struct PetscCommStash {
1155: struct PetscCommStash *next;
1156: MPI_Comm comm;
1157: };
1159: /*
1160: PETSc communicators have this attribute, see
1161: PetscCommDuplicate(), PetscCommDestroy(), PetscCommGetNewTag(), PetscObjectGetName()
1162: */
1163: typedef struct {
1164: PetscMPIInt tag; /* next free tag value */
1165: PetscInt refcount; /* number of references, communicator can be freed when this reaches 0 */
1166: PetscInt namecount; /* used to generate the next name, as in Vec_0, Mat_1, ... */
1167: PetscMPIInt *iflags; /* length of comm size, shared by all calls to PetscCommBuildTwoSided_Allreduce/RedScatter on this comm */
1168: struct PetscCommStash *comms; /* communicators available for PETSc to pass off to other packages */
1169: } PetscCommCounter;
1171: typedef enum {
1172: STATE_BEGIN,
1173: STATE_PENDING,
1174: STATE_END
1175: } SRState;
1177: typedef enum {
1178: PETSC_SR_REDUCE_SUM = 0,
1179: PETSC_SR_REDUCE_MAX = 1,
1180: PETSC_SR_REDUCE_MIN = 2
1181: } PetscSRReductionType;
1183: typedef struct {
1184: MPI_Comm comm;
1185: MPI_Request request;
1186: PetscBool mix;
1187: PetscBool async;
1188: PetscScalar *lvalues; /* this are the reduced values before call to MPI_Allreduce() */
1189: PetscScalar *gvalues; /* values after call to MPI_Allreduce() */
1190: void **invecs; /* for debugging only, vector/memory used with each op */
1191: PetscInt *reducetype; /* is particular value to be summed or maxed? */
1192: struct {
1193: PetscScalar v;
1194: PetscInt i;
1195: } *lvalues_mix, *gvalues_mix; /* used when mixing reduce operations */
1196: SRState state; /* are we calling xxxBegin() or xxxEnd()? */
1197: PetscInt maxops; /* total amount of space we have for requests */
1198: PetscInt numopsbegin; /* number of requests that have been queued in */
1199: PetscInt numopsend; /* number of requests that have been gotten by user */
1200: } PetscSplitReduction;
1202: PETSC_EXTERN PetscErrorCode PetscSplitReductionGet(MPI_Comm, PetscSplitReduction **);
1203: PETSC_EXTERN PetscErrorCode PetscSplitReductionEnd(PetscSplitReduction *);
1204: PETSC_EXTERN PetscErrorCode PetscSplitReductionExtend(PetscSplitReduction *);
1206: #if !defined(PETSC_SKIP_SPINLOCK)
1207: #if defined(PETSC_HAVE_THREADSAFETY)
1208: #if defined(PETSC_HAVE_CONCURRENCYKIT)
1209: #if defined(__cplusplus)
1210: /* CK does not have extern "C" protection in their include files */
1211: extern "C" {
1212: #endif
1213: #include <ck_spinlock.h>
1214: #if defined(__cplusplus)
1215: }
1216: #endif
1217: typedef ck_spinlock_t PetscSpinlock;
1218: static inline PetscErrorCode PetscSpinlockCreate(PetscSpinlock *ck_spinlock)
1219: {
1220: ck_spinlock_init(ck_spinlock);
1221: return 0;
1222: }
1223: static inline PetscErrorCode PetscSpinlockLock(PetscSpinlock *ck_spinlock)
1224: {
1225: ck_spinlock_lock(ck_spinlock);
1226: return 0;
1227: }
1228: static inline PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *ck_spinlock)
1229: {
1230: ck_spinlock_unlock(ck_spinlock);
1231: return 0;
1232: }
1233: static inline PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *ck_spinlock)
1234: {
1235: return 0;
1236: }
1237: #elif defined(PETSC_HAVE_OPENMP)
1239: #include <omp.h>
1240: typedef omp_lock_t PetscSpinlock;
1241: static inline PetscErrorCode PetscSpinlockCreate(PetscSpinlock *omp_lock)
1242: {
1243: omp_init_lock(omp_lock);
1244: return 0;
1245: }
1246: static inline PetscErrorCode PetscSpinlockLock(PetscSpinlock *omp_lock)
1247: {
1248: omp_set_lock(omp_lock);
1249: return 0;
1250: }
1251: static inline PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *omp_lock)
1252: {
1253: omp_unset_lock(omp_lock);
1254: return 0;
1255: }
1256: static inline PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *omp_lock)
1257: {
1258: omp_destroy_lock(omp_lock);
1259: return 0;
1260: }
1261: #else
1262: #error "Thread safety requires either --with-openmp or --download-concurrencykit"
1263: #endif
1265: #else
1266: typedef int PetscSpinlock;
1267: #define PetscSpinlockCreate(a) 0
1268: #define PetscSpinlockLock(a) 0
1269: #define PetscSpinlockUnlock(a) 0
1270: #define PetscSpinlockDestroy(a) 0
1271: #endif
1273: #if defined(PETSC_HAVE_THREADSAFETY)
1274: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockOpen;
1275: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStdout;
1276: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStderr;
1277: PETSC_INTERN PetscSpinlock PetscCommSpinLock;
1278: #endif
1279: #endif
1281: PETSC_EXTERN PetscLogEvent PETSC_Barrier;
1282: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSided;
1283: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSidedF;
1284: PETSC_EXTERN PetscBool use_gpu_aware_mpi;
1285: PETSC_EXTERN PetscBool PetscPrintFunctionList;
1287: #if defined(PETSC_HAVE_ADIOS)
1288: PETSC_EXTERN int64_t Petsc_adios_group;
1289: #endif
1291: #if defined(PETSC_HAVE_KOKKOS)
1292: PETSC_INTERN PetscBool PetscBeganKokkos;
1293: PETSC_EXTERN PetscBool PetscKokkosInitialized;
1294: PETSC_INTERN PetscErrorCode PetscKokkosIsInitialized_Private(PetscBool *);
1295: PETSC_INTERN PetscErrorCode PetscKokkosFinalize_Private(void);
1296: #endif
1298: #if defined(PETSC_HAVE_OPENMP)
1299: PETSC_EXTERN PetscInt PetscNumOMPThreads;
1300: #endif
1302: #endif /* PETSCIMPL_H */