1
2 /*
3 Defines the basic header of all PETSc objects.
4 */
5
6 #if !defined(PETSCIMPL_H)
7 #define PETSCIMPL_H
8 #include <petscsys.h>
9
10 /* These are used internally by PETSc ASCII IO routines*/
11 #include <stdarg.h>
12 PETSC_EXTERN PetscErrorCode PetscVFPrintfDefault(FILE*,const char[],va_list);
13
14 #if defined(PETSC_HAVE_CLOSURE)
15 PETSC_EXTERN PetscErrorCode PetscVFPrintfSetClosure(int (^)(const char*));
16 #endif
17
18 /*
19 All major PETSc data structures have a common core; this is defined
20 below by PETSCHEADER.
21
22 PetscHeaderCreate() should be used whenever creating a PETSc structure.
23 */
24
25 /*
26 PetscOps: structure of core operations that all PETSc objects support.
27
28 getcomm() - Gets the object's communicator.
29 view() - Is the routine for viewing the entire PETSc object; for
30 example, MatView() is the general matrix viewing routine.
31 This is used by PetscObjectView((PetscObject)obj) to allow
32 viewing any PETSc object.
33 destroy() - Is the routine for destroying the entire PETSc object;
34 for example,MatDestroy() is the general matrix
35 destruction routine.
36 This is used by PetscObjectDestroy((PetscObject*)&obj) to allow
37 destroying any PETSc object.
38 compose() - Associates a PETSc object with another PETSc object with a name
39 query() - Returns a different PETSc object that has been associated
40 with the first object using a name.
41 composefunction() - Attaches an a function to a PETSc object with a name.
42 queryfunction() - Requests a registered function that has been attached to a PETSc object.
43 */
44
45 typedef struct {
46 PetscErrorCode (*getcomm)(PetscObject,MPI_Comm *);
47 PetscErrorCode (*view)(PetscObject,PetscViewer);
48 PetscErrorCode (*destroy)(PetscObject*);
49 PetscErrorCode (*compose)(PetscObject,const char[],PetscObject);
50 PetscErrorCode (*query)(PetscObject,const char[],PetscObject *);
51 PetscErrorCode (*composefunction)(PetscObject,const char[],void (*)(void));
52 PetscErrorCode (*queryfunction)(PetscObject,const char[],void (**)(void));
53 } PetscOps;
54
55 typedef enum {PETSC_FORTRAN_CALLBACK_CLASS,PETSC_FORTRAN_CALLBACK_SUBTYPE,PETSC_FORTRAN_CALLBACK_MAXTYPE} PetscFortranCallbackType;
56 typedef int PetscFortranCallbackId;
57 #define PETSC_SMALLEST_FORTRAN_CALLBACK ((PetscFortranCallbackId)1000)
58 PETSC_EXTERN PetscErrorCode PetscFortranCallbackRegister(PetscClassId,const char*,PetscFortranCallbackId*);
59 PETSC_EXTERN PetscErrorCode PetscFortranCallbackGetSizes(PetscClassId,PetscInt*,PetscInt*);
60
61 typedef struct {
62 void (*func)(void);
63 void *ctx;
64 } PetscFortranCallback;
65
66 /*
67 All PETSc objects begin with the fields defined in PETSCHEADER.
68 The PetscObject is a way of examining these fields regardless of
69 the specific object. In C++ this could be a base abstract class
70 from which all objects are derived.
71 */
72 #define PETSC_MAX_OPTIONS_HANDLER 5
73 typedef struct _p_PetscObject {
74 PetscClassId classid;
75 PetscOps bops[1];
76 MPI_Comm comm;
77 PetscInt type;
78 PetscLogDouble flops,time,mem,memchildren;
79 PetscObjectId id;
80 PetscInt refct;
81 PetscMPIInt tag;
82 PetscFunctionList qlist;
83 PetscObjectList olist;
84 char *class_name; /* for example, "Vec" */
85 char *description;
86 char *mansec;
87 char *type_name; /* this is the subclass, for example VECSEQ which equals "seq" */
88 PetscObject parent;
89 PetscObjectId parentid;
90 char* name;
91 char *prefix;
92 PetscInt tablevel;
93 void *cpp;
94 PetscObjectState state;
95 PetscInt int_idmax, intstar_idmax;
96 PetscObjectState *intcomposedstate,*intstarcomposedstate;
97 PetscInt *intcomposeddata, **intstarcomposeddata;
98 PetscInt real_idmax, realstar_idmax;
99 PetscObjectState *realcomposedstate,*realstarcomposedstate;
100 PetscReal *realcomposeddata, **realstarcomposeddata;
101 PetscInt scalar_idmax, scalarstar_idmax;
102 PetscObjectState *scalarcomposedstate,*scalarstarcomposedstate;
103 PetscScalar *scalarcomposeddata, **scalarstarcomposeddata;
104 void (**fortran_func_pointers)(void); /* used by Fortran interface functions to stash user provided Fortran functions */
105 PetscInt num_fortran_func_pointers; /* number of Fortran function pointers allocated */
106 PetscFortranCallback *fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
107 PetscInt num_fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
108 void *python_context;
109 PetscErrorCode (*python_destroy)(void*);
110
111 PetscInt noptionhandler;
112 PetscErrorCode (*optionhandler[PETSC_MAX_OPTIONS_HANDLER])(PetscOptionItems*,PetscObject,void*);
113 PetscErrorCode (*optiondestroy[PETSC_MAX_OPTIONS_HANDLER])(PetscObject,void*);
114 void *optionctx[PETSC_MAX_OPTIONS_HANDLER];
115 PetscBool optionsprinted;
116 #if defined(PETSC_HAVE_SAWS)
117 PetscBool amsmem; /* if PETSC_TRUE then this object is registered with SAWs and visible to clients */
118 PetscBool amspublishblock; /* if PETSC_TRUE and publishing objects then will block at PetscObjectSAWsBlock() */
119 #endif
120 PetscOptions options; /* options database used, NULL means default */
121 PetscBool donotPetscObjectPrintClassNamePrefixType;
122 } _p_PetscObject;
123
124 #define PETSCHEADER(ObjectOps) \
125 _p_PetscObject hdr; \
126 ObjectOps ops[1]
127
128 #define PETSCFREEDHEADER -1
129
130 PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectDestroyFunction)(PetscObject*); /* force cast in next macro to NEVER use extern "C" style */
131 PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectViewFunction)(PetscObject,PetscViewer);
132
133 /*@C
134 PetscHeaderCreate - Creates a PETSc object of a particular class
135
136 Input Parameters:
137 + classid - the classid associated with this object (for example VEC_CLASSID)
138 . class_name - string name of class; should be static (for example "Vec")
139 . descr - string containing short description; should be static (for example "Vector")
140 . mansec - string indicating section in manual pages; should be static (for example "Vec")
141 . comm - the MPI Communicator
142 . destroy - the destroy routine for this object (for example VecDestroy())
143 - view - the view routine for this object (for example VecView())
144
145 Output Parameter:
146 . h - the newly created object
147
148 Level: developer
149
150 .seealso: PetscHeaderDestroy(), PetscClassIdRegister()
151
152 @*/
153 #define PetscHeaderCreate(h,classid,class_name,descr,mansec,comm,destroy,view) \
154 (PetscNew(&(h)) || \
155 PetscHeaderCreate_Private((PetscObject)(h),classid,class_name,descr,mansec,comm,(PetscObjectDestroyFunction)(destroy),(PetscObjectViewFunction)(view)) || \
156 PetscLogObjectCreate(h) || \
157 PetscLogObjectMemory((PetscObject)(h),sizeof(*(h))))
158
159 PETSC_EXTERN PetscErrorCode PetscComposedQuantitiesDestroy(PetscObject obj);
160 PETSC_EXTERN PetscErrorCode PetscHeaderCreate_Private(PetscObject,PetscClassId,const char[],const char[],const char[],MPI_Comm,PetscObjectDestroyFunction,PetscObjectViewFunction);
161
162 /*@C
163 PetscHeaderDestroy - Final step in destroying a PetscObject
164
165 Input Parameters:
166 . h - the header created with PetscHeaderCreate()
167
168 Level: developer
169
170 .seealso: PetscHeaderCreate()
171 @*/
172 #define PetscHeaderDestroy(h) (PetscHeaderDestroy_Private((PetscObject)(*(h))) || PetscFree(*(h)))
173
174 PETSC_EXTERN PetscErrorCode PetscHeaderDestroy_Private(PetscObject);
175 PETSC_EXTERN PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject,PetscObject);
176 PETSC_EXTERN PetscErrorCode PetscObjectSetFortranCallback(PetscObject,PetscFortranCallbackType,PetscFortranCallbackId*,void(*)(void),void *ctx);
177 PETSC_EXTERN PetscErrorCode PetscObjectGetFortranCallback(PetscObject,PetscFortranCallbackType,PetscFortranCallbackId,void(**)(void),void **ctx);
178
179 PETSC_INTERN PetscErrorCode PetscCitationsInitialize(void);
180 PETSC_INTERN PetscErrorCode PetscFreeMPIResources(void);
181 PETSC_INTERN PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions,PetscBool*);
182
183
184 PETSC_EXTERN PetscBool PetscCheckPointer(const void*,PetscDataType);
185 /*
186 Macros to test if a PETSc object is valid and if pointers are valid
187 */
188 #if !defined(PETSC_USE_DEBUG)
189
190 #define PetscValidHeaderSpecific(h,ck,arg) do {(void)(h);} while (0)
191 #define PetscValidHeaderSpecificType(h,ck,arg,t) do {(void)(h);} while (0)
192 #define PetscValidHeader(h,arg) do {(void)(h);} while (0)
193 #define PetscValidPointer(h,arg) do {(void)(h);} while (0)
194 #define PetscValidCharPointer(h,arg) do {(void)(h);} while (0)
195 #define PetscValidIntPointer(h,arg) do {(void)(h);} while (0)
196 #define PetscValidBoolPointer(h,arg) do {(void)(h);} while (0)
197 #define PetscValidScalarPointer(h,arg) do {(void)(h);} while (0)
198 #define PetscValidRealPointer(h,arg) do {(void)(h);} while (0)
199 #define PetscValidFunction(h,arg) do {(void)(h);} while (0)
200
201 #else
202
203 /* This check is for subtype methods such as DMDAGetCorners() that do not use the PetscTryMethod() or PetscUseMethod() paradigm */
204 #define PetscValidHeaderSpecificType(h,ck,arg,t) \
205 do { \
206 PetscErrorCode _7_ierr; \
207 PetscBool _7_same; \
208 PetscValidHeaderSpecific(h,ck,arg); \
209 _7_ierr = PetscObjectTypeCompare((PetscObject)(h),t,&_7_same);CHKERRQ(_7_ierr); \
210 if (!_7_same) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Wrong subtype object:Parameter # %d must have implementation %s it is %s",arg,t,((PetscObject)(h))->type_name); \
211 } while (0)
212
213 #define PetscValidHeaderSpecific(h,ck,arg) \
214 do { \
215 if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg); \
216 if (!PetscCheckPointer(h,PETSC_OBJECT)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Invalid Pointer to Object: Parameter # %d",arg); \
217 if (((PetscObject)(h))->classid != ck) { \
218 if (((PetscObject)(h))->classid == PETSCFREEDHEADER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
219 else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Wrong type of object: Parameter # %d",arg); \
220 } \
221 } while (0)
222
223 #define PetscValidHeader(h,arg) \
224 do { \
225 if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg); \
226 if (!PetscCheckPointer(h,PETSC_OBJECT)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Invalid Pointer to Object: Parameter # %d",arg); \
227 if (((PetscObject)(h))->classid == PETSCFREEDHEADER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
228 else if (((PetscObject)(h))->classid < PETSC_SMALLEST_CLASSID || ((PetscObject)(h))->classid > PETSC_LARGEST_CLASSID) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Invalid type of object: Parameter # %d",arg); \
229 } while (0)
230
231 #define PetscValidPointer(h,arg) \
232 do { \
233 if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
234 if (!PetscCheckPointer(h,PETSC_CHAR)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Invalid Pointer: Parameter # %d",arg); \
235 } while (0)
236
237 #define PetscValidCharPointer(h,arg) \
238 do { \
239 if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg);\
240 if (!PetscCheckPointer(h,PETSC_CHAR)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Invalid Pointer to char: Parameter # %d",arg); \
241 } while (0)
242
243 #define PetscValidIntPointer(h,arg) \
244 do { \
245 if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Null Pointer: Parameter # %d",arg); \
246 if (!PetscCheckPointer(h,PETSC_INT)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Invalid Pointer to PetscInt: Parameter # %d",arg); \
247 } while (0)
248
249 #define PetscValidBoolPointer(h,arg) \
250 do { \
251 if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Null Pointer: Parameter # %d",arg); \
252 if (!PetscCheckPointer(h,PETSC_BOOL)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Invalid Pointer to PetscBool: Parameter # %d",arg); \
253 } while (0)
254
255 #define PetscValidScalarPointer(h,arg) \
256 do { \
257 if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
258 if (!PetscCheckPointer(h,PETSC_SCALAR)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Invalid Pointer to PetscScalar: Parameter # %d",arg); \
259 } while (0)
260
261 #define PetscValidRealPointer(h,arg) \
262 do { \
263 if (!(h)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
264 if (!PetscCheckPointer(h,PETSC_REAL)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Invalid Pointer to PetscReal: Parameter # %d",arg); \
265 } while (0)
266
267 #define PetscValidFunction(f,arg) \
268 do { \
269 if (!(f)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Function Pointer: Parameter # %d",arg); \
270 } while (0)
271
272 #endif
273
274 #define PetscSorted(n,idx,sorted) \
275 do { \
276 PetscInt _i_; \
277 (sorted) = PETSC_TRUE; \
278 for (_i_ = 1; _i_ < (n); _i_++) \
279 if ((idx)[_i_] < (idx)[_i_ - 1]) \
280 { (sorted) = PETSC_FALSE; break; } \
281 } while (0)
282
283 #if !defined(PETSC_USE_DEBUG)
284
285 #define PetscCheckSameType(a,arga,b,argb) do {(void)(a);(void)(b);} while (0)
286 #define PetscCheckTypeName(a,type) do {(void)(a);} while (0)
287 #define PetscCheckTypeNames(a,type1,type2) do {(void)(a);} while (0)
288 #define PetscValidType(a,arg) do {(void)(a);} while (0)
289 #define PetscCheckSameComm(a,arga,b,argb) do {(void)(a);(void)(b);} while (0)
290 #define PetscCheckSameTypeAndComm(a,arga,b,argb) do {(void)(a);(void)(b);} while (0)
291 #define PetscValidLogicalCollectiveScalar(a,b,arg) do {(void)(a);(void)(b);} while (0)
292 #define PetscValidLogicalCollectiveReal(a,b,arg) do {(void)(a);(void)(b);} while (0)
293 #define PetscValidLogicalCollectiveInt(a,b,arg) do {(void)(a);(void)(b);} while (0)
294 #define PetscValidLogicalCollectiveMPIInt(a,b,arg) do {(void)(a);(void)(b);} while (0)
295 #define PetscValidLogicalCollectiveBool(a,b,arg) do {(void)(a);(void)(b);} while (0)
296 #define PetscValidLogicalCollectiveEnum(a,b,arg) do {(void)(a);(void)(b);} while (0)
297 #define PetscCheckSorted(n,idx) do {(void)(n);(void)(idx);} while (0)
298
299 #else
300
301 /*
302 For example, in the dot product between two vectors,
303 both vectors must be either Seq or MPI, not one of each
304 */
305 #define PetscCheckSameType(a,arga,b,argb) \
306 do { \
307 if (((PetscObject)(a))->type != ((PetscObject)(b))->type) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMETYPE,"Objects not of same type: Argument # %d and %d",arga,argb); \
308 } while (0)
309 /*
310 Check type_name
311 */
312 #define PetscCheckTypeName(a,type) \
313 do { \
314 PetscBool _7_match; \
315 PetscErrorCode _7_ierr; \
316 _7_ierr = PetscObjectTypeCompare(((PetscObject)(a)),(type),&_7_match);CHKERRQ(_7_ierr); \
317 if (!_7_match) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Object (%s) is not %s",(char*)(((PetscObject)(a))->type_name),type); \
318 } while (0)
319
320 #define PetscCheckTypeNames(a,type1,type2) \
321 do { \
322 PetscBool _7_match; \
323 PetscErrorCode _7_ierr; \
324 _7_ierr = PetscObjectTypeCompareAny(((PetscObject)(a)),&_7_match,(type1),(type2),"");CHKERRQ(_7_ierr); \
325 if (!_7_match) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Object (%s) is not %s or %s",(char*)(((PetscObject)(a))->type_name),type1,type2); \
326 } while (0)
327 /*
328 Use this macro to check if the type is set
329 */
330 #define PetscValidType(a,arg) \
331 do { \
332 if (!((PetscObject)(a))->type_name) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"%s object's type is not set: Argument # %d",((PetscObject)(a))->class_name,arg); \
333 } while (0)
334 /*
335 Sometimes object must live on same communicator to inter-operate
336 */
337 #define PetscCheckSameComm(a,arga,b,argb) \
338 do { \
339 PetscErrorCode _7_ierr; \
340 PetscMPIInt _7_flag; \
341 _7_ierr = MPI_Comm_compare(PetscObjectComm((PetscObject)(a)),PetscObjectComm((PetscObject)(b)),&_7_flag);CHKERRQ(_7_ierr); \
342 if (_7_flag != MPI_CONGRUENT && _7_flag != MPI_IDENT) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"Different communicators in the two objects: Argument # %d and %d flag %d",arga,argb,_7_flag); \
343 } while (0)
344
345 #define PetscCheckSameTypeAndComm(a,arga,b,argb) \
346 do { \
347 PetscCheckSameType(a,arga,b,argb); \
348 PetscCheckSameComm(a,arga,b,argb); \
349 } while (0)
350
351 #define PetscValidLogicalCollectiveScalar(a,b,arg) \
352 do { \
353 PetscErrorCode _7_ierr; \
354 PetscScalar b0=(b); \
355 PetscReal b1[5],b2[5]; \
356 if (PetscIsNanScalar(b0)) {b1[4] = 1;} else {b1[4] = 0;}; \
357 b1[0] = -PetscRealPart(b0); b1[1] = PetscRealPart(b0); b1[2] = -PetscImaginaryPart(b0); b1[3] = PetscImaginaryPart(b0); \
358 _7_ierr = MPI_Allreduce(b1,b2,5,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)(a)));CHKERRQ(_7_ierr); \
359 if (!(b2[4] > 0) && !(PetscEqualReal(-b2[0],b2[1]) && PetscEqualReal(-b2[2],b2[3]))) SETERRQ1(PetscObjectComm((PetscObject)(a)),PETSC_ERR_ARG_WRONG,"Scalar value must be same on all processes, argument # %d",arg); \
360 } while (0)
361
362 #define PetscValidLogicalCollectiveReal(a,b,arg) \
363 do { \
364 PetscErrorCode _7_ierr; \
365 PetscReal b0=(b),b1[3],b2[3]; \
366 if (PetscIsNanReal(b0)) {b1[2] = 1;} else {b1[2] = 0;}; \
367 b1[0] = -b0; b1[1] = b0; \
368 _7_ierr = MPI_Allreduce(b1,b2,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)(a)));CHKERRQ(_7_ierr); \
369 if (!(b2[2] > 0) && !PetscEqualReal(-b2[0],b2[1])) SETERRQ1(PetscObjectComm((PetscObject)(a)),PETSC_ERR_ARG_WRONG,"Real value must be same on all processes, argument # %d",arg); \
370 } while (0)
371
372 #define PetscValidLogicalCollectiveInt(a,b,arg) \
373 do { \
374 PetscErrorCode _7_ierr; \
375 PetscInt b0=(b),b1[2],b2[2]; \
376 b1[0] = -b0; b1[1] = b0; \
377 _7_ierr = MPIU_Allreduce(b1,b2,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));CHKERRQ(_7_ierr); \
378 if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)(a)),PETSC_ERR_ARG_WRONG,"Int value must be same on all processes, argument # %d",arg); \
379 } while (0)
380
381 #define PetscValidLogicalCollectiveMPIInt(a,b,arg) \
382 do { \
383 PetscErrorCode _7_ierr; \
384 PetscMPIInt b0=(b),b1[2],b2[2]; \
385 b1[0] = -b0; b1[1] = b0; \
386 _7_ierr = MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));CHKERRQ(_7_ierr); \
387 if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)(a)),PETSC_ERR_ARG_WRONG,"PetscMPIInt value must be same on all processes, argument # %d",arg); \
388 } while (0)
389
390 #define PetscValidLogicalCollectiveBool(a,b,arg) \
391 do { \
392 PetscErrorCode _7_ierr; \
393 PetscMPIInt b0=(PetscMPIInt)(b),b1[2],b2[2]; \
394 b1[0] = -b0; b1[1] = b0; \
395 _7_ierr = MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));CHKERRQ(_7_ierr); \
396 if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)(a)),PETSC_ERR_ARG_WRONG,"Bool value must be same on all processes, argument # %d",arg); \
397 } while (0)
398
399 #define PetscValidLogicalCollectiveEnum(a,b,arg) \
400 do { \
401 PetscErrorCode _7_ierr; \
402 PetscMPIInt b0=(PetscMPIInt)(b),b1[2],b2[2]; \
403 b1[0] = -b0; b1[1] = b0; \
404 _7_ierr = MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));CHKERRQ(_7_ierr); \
405 if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)(a)),PETSC_ERR_ARG_WRONG,"Enum value must be same on all processes, argument # %d",arg); \
406 } while (0)
407
408 #define PetscCheckSorted(n,idx) \
409 do { \
410 PetscBool _1_flg; \
411 PetscSorted(n,idx,_1_flg); \
412 if (!_1_flg) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Input array needs to be sorted"); \
413 } while (0)
414
415 #endif
416
417 /*
418 PetscTryMethod - Queries an object for a method, if it exists then calls it.
419 These are intended to be used only inside PETSc functions.
420
421 Level: developer
422
423 .seealso: PetscUseMethod()
424 */
425 #define PetscTryMethod(obj,A,B,C) \
426 0; do { PetscErrorCode (*_7_f)B, _7_ierr; \
427 _7_ierr = PetscObjectQueryFunction((PetscObject)(obj),A,&_7_f);CHKERRQ(_7_ierr); \
428 if (_7_f) {_7_ierr = (*_7_f)C;CHKERRQ(_7_ierr);} \
429 } while (0)
430
431 /*
432 PetscUseMethod - Queries an object for a method, if it exists then calls it, otherwise generates an error.
433 These are intended to be used only inside PETSc functions.
434
435 Level: developer
436
437 .seealso: PetscTryMethod()
438 */
439 #define PetscUseMethod(obj,A,B,C) \
440 0; do { PetscErrorCode (*_7_f)B, _7_ierr; \
441 _7_ierr = PetscObjectQueryFunction((PetscObject)(obj),A,&_7_f);CHKERRQ(_7_ierr); \
442 if (_7_f) {_7_ierr = (*_7_f)C;CHKERRQ(_7_ierr);} \
443 else SETERRQ1(PetscObjectComm((PetscObject)(obj)),PETSC_ERR_SUP,"Cannot locate function %s in object",A); \
444 } while (0)
445
446 /*MC
447 PetscObjectStateIncrease - Increases the state of any PetscObject
448
449 Synopsis:
450 #include "petsc/private/petscimpl.h"
451 PetscErrorCode PetscObjectStateIncrease(PetscObject obj)
452
453 Logically Collective
454
455 Input Parameter:
456 . obj - any PETSc object, for example a Vec, Mat or KSP. This must be
457 cast with a (PetscObject), for example,
458 PetscObjectStateIncrease((PetscObject)mat);
459
460 Notes:
461 object state is an integer which gets increased every time
462 the object is changed internally. By saving and later querying the object state
463 one can determine whether information about the object is still current.
464 Currently, state is maintained for Vec and Mat objects.
465
466 This routine is mostly for internal use by PETSc; a developer need only
467 call it after explicit access to an object's internals. Routines such
468 as VecSet() or MatScale() already call this routine. It is also called, as a
469 precaution, in VecRestoreArray(), MatRestoreRow(), MatDenseRestoreArray().
470
471 This routine is logically collective because state equality comparison needs to be possible without communication.
472
473 Level: developer
474
475 seealso: PetscObjectStateGet()
476
477 M*/
478 #define PetscObjectStateIncrease(obj) ((obj)->state++,0)
479
480 PETSC_EXTERN PetscErrorCode PetscObjectStateGet(PetscObject,PetscObjectState*);
481 PETSC_EXTERN PetscErrorCode PetscObjectStateSet(PetscObject,PetscObjectState);
482 PETSC_EXTERN PetscErrorCode PetscObjectComposedDataRegister(PetscInt*);
483 PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject);
484 PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject);
485 PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject);
486 PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject);
487 PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject);
488 PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject);
489 PETSC_EXTERN PetscInt PetscObjectComposedDataMax;
490 /*MC
491 PetscObjectComposedDataSetInt - attach integer data to a PetscObject
492
493 Synopsis:
494 #include "petsc/private/petscimpl.h"
495 PetscErrorCode PetscObjectComposedDataSetInt(PetscObject obj,int id,int data)
496
497 Not collective
498
499 Input parameters:
500 + obj - the object to which data is to be attached
501 . id - the identifier for the data
502 - data - the data to be attached
503
504 Notes
505 The data identifier can best be created through a call to PetscObjectComposedDataRegister()
506
507 Level: developer
508 M*/
509 #define PetscObjectComposedDataSetInt(obj,id,data) \
510 ((((obj)->int_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseInt(obj)) || \
511 ((obj)->intcomposeddata[id] = data,(obj)->intcomposedstate[id] = (obj)->state, 0))
512
513 /*MC
514 PetscObjectComposedDataGetInt - retrieve integer data attached to an object
515
516 Synopsis:
517 #include "petsc/private/petscimpl.h"
518 PetscErrorCode PetscObjectComposedDataGetInt(PetscObject obj,int id,int data,PetscBool flag)
519
520 Not collective
521
522 Input parameters:
523 + obj - the object from which data is to be retrieved
524 - id - the identifier for the data
525
526 Output parameters:
527 + data - the data to be retrieved
528 - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
529
530 The 'data' and 'flag' variables are inlined, so they are not pointers.
531
532 Level: developer
533 M*/
534 #define PetscObjectComposedDataGetInt(obj,id,data,flag) \
535 ((((obj)->intcomposedstate && ((obj)->intcomposedstate[id] == (obj)->state)) ? \
536 (data = (obj)->intcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
537
538 /*MC
539 PetscObjectComposedDataSetIntstar - attach integer array data to a PetscObject
540
541 Synopsis:
542 #include "petsc/private/petscimpl.h"
543 PetscErrorCode PetscObjectComposedDataSetIntstar(PetscObject obj,int id,int *data)
544
545 Not collective
546
547 Input parameters:
548 + obj - the object to which data is to be attached
549 . id - the identifier for the data
550 - data - the data to be attached
551
552 Notes
553 The data identifier can best be determined through a call to
554 PetscObjectComposedDataRegister()
555
556 Level: developer
557 M*/
558 #define PetscObjectComposedDataSetIntstar(obj,id,data) \
559 ((((obj)->intstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseIntstar(obj)) || \
560 ((obj)->intstarcomposeddata[id] = data,(obj)->intstarcomposedstate[id] = (obj)->state, 0))
561
562 /*MC
563 PetscObjectComposedDataGetIntstar - retrieve integer array data
564 attached to an object
565
566 Synopsis:
567 #include "petsc/private/petscimpl.h"
568 PetscErrorCode PetscObjectComposedDataGetIntstar(PetscObject obj,int id,int *data,PetscBool flag)
569
570 Not collective
571
572 Input parameters:
573 + obj - the object from which data is to be retrieved
574 - id - the identifier for the data
575
576 Output parameters:
577 + data - the data to be retrieved
578 - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
579
580 The 'data' and 'flag' variables are inlined, so they are not pointers.
581
582 Level: developer
583 M*/
584 #define PetscObjectComposedDataGetIntstar(obj,id,data,flag) \
585 ((((obj)->intstarcomposedstate && ((obj)->intstarcomposedstate[id] == (obj)->state)) ? \
586 (data = (obj)->intstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
587
588 /*MC
589 PetscObjectComposedDataSetReal - attach real data to a PetscObject
590
591 Synopsis:
592 #include "petsc/private/petscimpl.h"
593 PetscErrorCode PetscObjectComposedDataSetReal(PetscObject obj,int id,PetscReal data)
594
595 Not collective
596
597 Input parameters:
598 + obj - the object to which data is to be attached
599 . id - the identifier for the data
600 - data - the data to be attached
601
602 Notes
603 The data identifier can best be determined through a call to
604 PetscObjectComposedDataRegister()
605
606 Level: developer
607 M*/
608 #define PetscObjectComposedDataSetReal(obj,id,data) \
609 ((((obj)->real_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseReal(obj)) || \
610 ((obj)->realcomposeddata[id] = data,(obj)->realcomposedstate[id] = (obj)->state, 0))
611
612 /*MC
613 PetscObjectComposedDataGetReal - retrieve real data attached to an object
614
615 Synopsis:
616 #include "petsc/private/petscimpl.h"
617 PetscErrorCode PetscObjectComposedDataGetReal(PetscObject obj,int id,PetscReal data,PetscBool flag)
618
619 Not collective
620
621 Input parameters:
622 + obj - the object from which data is to be retrieved
623 - id - the identifier for the data
624
625 Output parameters:
626 + data - the data to be retrieved
627 - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
628
629 The 'data' and 'flag' variables are inlined, so they are not pointers.
630
631 Level: developer
632 M*/
633 #define PetscObjectComposedDataGetReal(obj,id,data,flag) \
634 ((((obj)->realcomposedstate && ((obj)->realcomposedstate[id] == (obj)->state)) ? \
635 (data = (obj)->realcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
636
637 /*MC
638 PetscObjectComposedDataSetRealstar - attach real array data to a PetscObject
639
640 Synopsis:
641 #include "petsc/private/petscimpl.h"
642 PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *data)
643
644 Not collective
645
646 Input parameters:
647 + obj - the object to which data is to be attached
648 . id - the identifier for the data
649 - data - the data to be attached
650
651 Notes
652 The data identifier can best be determined through a call to
653 PetscObjectComposedDataRegister()
654
655 Level: developer
656 M*/
657 #define PetscObjectComposedDataSetRealstar(obj,id,data) \
658 ((((obj)->realstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseRealstar(obj)) || \
659 ((obj)->realstarcomposeddata[id] = data, (obj)->realstarcomposedstate[id] = (obj)->state, 0))
660
661 /*MC
662 PetscObjectComposedDataGetRealstar - retrieve real array data
663 attached to an object
664
665 Synopsis:
666 #include "petsc/private/petscimpl.h"
667 PetscErrorCode PetscObjectComposedDataGetRealstar(PetscObject obj,int id,PetscReal *data,PetscBool flag)
668
669 Not collective
670
671 Input parameters:
672 + obj - the object from which data is to be retrieved
673 - id - the identifier for the data
674
675 Output parameters:
676 + data - the data to be retrieved
677 - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
678
679 The 'data' and 'flag' variables are inlined, so they are not pointers.
680
681 Level: developer
682 M*/
683 #define PetscObjectComposedDataGetRealstar(obj,id,data,flag) \
684 ((((obj)->realstarcomposedstate && ((obj)->realstarcomposedstate[id] == (obj)->state)) ? \
685 (data = (obj)->realstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
686
687 /*MC
688 PetscObjectComposedDataSetScalar - attach scalar data to a PetscObject
689
690 Synopsis:
691 #include "petsc/private/petscimpl.h"
692 PetscErrorCode PetscObjectComposedDataSetScalar(PetscObject obj,int id,PetscScalar data)
693
694 Not collective
695
696 Input parameters:
697 + obj - the object to which data is to be attached
698 . id - the identifier for the data
699 - data - the data to be attached
700
701 Notes
702 The data identifier can best be determined through a call to
703 PetscObjectComposedDataRegister()
704
705 Level: developer
706 M*/
707 #if defined(PETSC_USE_COMPLEX)
708 #define PetscObjectComposedDataSetScalar(obj,id,data) \
709 ((((obj)->scalar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalar(obj)) || \
710 ((obj)->scalarcomposeddata[id] = data,(obj)->scalarcomposedstate[id] = (obj)->state, 0))
711 #else
712 #define PetscObjectComposedDataSetScalar(obj,id,data) \
713 PetscObjectComposedDataSetReal(obj,id,data)
714 #endif
715 /*MC
716 PetscObjectComposedDataGetScalar - retrieve scalar data attached to an object
717
718 Synopsis:
719 #include "petsc/private/petscimpl.h"
720 PetscErrorCode PetscObjectComposedDataGetScalar(PetscObject obj,int id,PetscScalar data,PetscBool flag)
721
722 Not collective
723
724 Input parameters:
725 + obj - the object from which data is to be retrieved
726 - id - the identifier for the data
727
728 Output parameters:
729 + data - the data to be retrieved
730 - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
731
732 The 'data' and 'flag' variables are inlined, so they are not pointers.
733
734 Level: developer
735 M*/
736 #if defined(PETSC_USE_COMPLEX)
737 #define PetscObjectComposedDataGetScalar(obj,id,data,flag) \
738 ((((obj)->scalarcomposedstate && ((obj)->scalarcomposedstate[id] == (obj)->state)) ? \
739 (data = (obj)->scalarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
740 #else
741 #define PetscObjectComposedDataGetScalar(obj,id,data,flag) \
742 PetscObjectComposedDataGetReal(obj,id,data,flag)
743 #endif
744
745 /*MC
746 PetscObjectComposedDataSetScalarstar - attach scalar array data to a PetscObject
747
748 Synopsis:
749 #include "petsc/private/petscimpl.h"
750 PetscErrorCode PetscObjectComposedDataSetScalarstar(PetscObject obj,int id,PetscScalar *data)
751
752 Not collective
753
754 Input parameters:
755 + obj - the object to which data is to be attached
756 . id - the identifier for the data
757 - data - the data to be attached
758
759 Notes
760 The data identifier can best be determined through a call to
761 PetscObjectComposedDataRegister()
762
763 Level: developer
764 M*/
765 #if defined(PETSC_USE_COMPLEX)
766 #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
767 ((((obj)->scalarstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalarstar(obj)) || \
768 ((obj)->scalarstarcomposeddata[id] = data,(obj)->scalarstarcomposedstate[id] = (obj)->state, 0))
769 #else
770 #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
771 PetscObjectComposedDataSetRealstar(obj,id,data)
772 #endif
773 /*MC
774 PetscObjectComposedDataGetScalarstar - retrieve scalar array data
775 attached to an object
776
777 Synopsis:
778 #include "petsc/private/petscimpl.h"
779 PetscErrorCode PetscObjectComposedDataGetScalarstar(PetscObject obj,int id,PetscScalar *data,PetscBool flag)
780
781 Not collective
782
783 Input parameters:
784 + obj - the object from which data is to be retrieved
785 - id - the identifier for the data
786
787 Output parameters:
788 + data - the data to be retrieved
789 - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
790
791 The 'data' and 'flag' variables are inlined, so they are not pointers.
792
793 Level: developer
794 M*/
795 #if defined(PETSC_USE_COMPLEX)
796 #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag) \
797 ((((obj)->scalarstarcomposedstate && ((obj)->scalarstarcomposedstate[id] == (obj)->state)) ? \
798 (data = (obj)->scalarstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
799 #else
800 #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag) \
801 PetscObjectComposedDataGetRealstar(obj,id,data,flag)
802 #endif
803
804 PETSC_EXTERN PetscMPIInt Petsc_Counter_keyval;
805 PETSC_EXTERN PetscMPIInt Petsc_InnerComm_keyval;
806 PETSC_EXTERN PetscMPIInt Petsc_OuterComm_keyval;
807 PETSC_EXTERN PetscMPIInt Petsc_Seq_keyval;
808 PETSC_EXTERN PetscMPIInt Petsc_ShmComm_keyval;
809
810 /*
811 PETSc communicators have this attribute, see
812 PetscCommDuplicate(), PetscCommDestroy(), PetscCommGetNewTag(), PetscObjectGetName()
813 */
814 typedef struct {
815 PetscMPIInt tag; /* next free tag value */
816 PetscInt refcount; /* number of references, communicator can be freed when this reaches 0 */
817 PetscInt namecount; /* used to generate the next name, as in Vec_0, Mat_1, ... */
818 PetscMPIInt *iflags; /* length of comm size, shared by all calls to PetscCommBuildTwoSided_Allreduce/RedScatter on this comm */
819 } PetscCommCounter;
820
821 typedef enum {STATE_BEGIN, STATE_PENDING, STATE_END} SRState;
822
823 typedef enum {PETSC_SR_REDUCE_SUM=0,PETSC_SR_REDUCE_MAX=1,PETSC_SR_REDUCE_MIN=2} PetscSRReductionType;
824
825 typedef struct {
826 MPI_Comm comm;
827 MPI_Request request;
828 PetscBool async;
829 PetscScalar *lvalues; /* this are the reduced values before call to MPI_Allreduce() */
830 PetscScalar *gvalues; /* values after call to MPI_Allreduce() */
831 void **invecs; /* for debugging only, vector/memory used with each op */
832 PetscInt *reducetype; /* is particular value to be summed or maxed? */
833 SRState state; /* are we calling xxxBegin() or xxxEnd()? */
834 PetscInt maxops; /* total amount of space we have for requests */
835 PetscInt numopsbegin; /* number of requests that have been queued in */
836 PetscInt numopsend; /* number of requests that have been gotten by user */
837 } PetscSplitReduction;
838
839 PETSC_EXTERN PetscErrorCode PetscSplitReductionGet(MPI_Comm,PetscSplitReduction**);
840 PETSC_EXTERN PetscErrorCode PetscSplitReductionEnd(PetscSplitReduction*);
841 PETSC_EXTERN PetscErrorCode PetscSplitReductionExtend(PetscSplitReduction*);
842
843 #if !defined(PETSC_SKIP_SPINLOCK)
844 #if defined(PETSC_HAVE_THREADSAFETY)
845 # if defined(PETSC_HAVE_CONCURRENCYKIT)
846 #if defined(__cplusplus)
847 /* CK does not have extern "C" protection in their include files */
848 extern "C" {
849 #endif
850 #include <ck_spinlock.h>
851 #if defined(__cplusplus)
852 }
853 #endif
854 typedef ck_spinlock_t PetscSpinlock;
PetscSpinlockCreate(PetscSpinlock * ck_spinlock)855 PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockCreate(PetscSpinlock *ck_spinlock)
856 {
857 ck_spinlock_init(ck_spinlock);
858 return 0;
859 }
PetscSpinlockLock(PetscSpinlock * ck_spinlock)860 PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockLock(PetscSpinlock *ck_spinlock)
861 {
862 ck_spinlock_lock(ck_spinlock);
863 return 0;
864 }
PetscSpinlockUnlock(PetscSpinlock * ck_spinlock)865 PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *ck_spinlock)
866 {
867 ck_spinlock_unlock(ck_spinlock);
868 return 0;
869 }
PetscSpinlockDestroy(PetscSpinlock * ck_spinlock)870 PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *ck_spinlock)
871 {
872 return 0;
873 }
874 # elif defined(PETSC_HAVE_OPENMP)
875
876 #include <omp.h>
877 typedef omp_lock_t PetscSpinlock;
PetscSpinlockCreate(PetscSpinlock * omp_lock)878 PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockCreate(PetscSpinlock *omp_lock)
879 {
880 omp_init_lock(omp_lock);
881 return 0;
882 }
PetscSpinlockLock(PetscSpinlock * omp_lock)883 PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockLock(PetscSpinlock *omp_lock)
884 {
885 omp_set_lock(omp_lock);
886 return 0;
887 }
PetscSpinlockUnlock(PetscSpinlock * omp_lock)888 PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *omp_lock)
889 {
890 omp_unset_lock(omp_lock);
891 return 0;
892 }
PetscSpinlockDestroy(PetscSpinlock * omp_lock)893 PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *omp_lock)
894 {
895 omp_destroy_lock(omp_lock);
896 return 0;
897 }
898 #else
899 Thread safety requires either --with-openmp or --download-concurrencykit
900 #endif
901
902 #else
903 typedef int PetscSpinlock;
904 #define PetscSpinlockCreate(a) 0
905 #define PetscSpinlockLock(a) 0
906 #define PetscSpinlockUnlock(a) 0
907 #define PetscSpinlockDestroy(a) 0
908 #endif
909
910 #if defined(PETSC_HAVE_THREADSAFETY)
911 PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockOpen;
912 PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStdout;
913 PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStderr;
914 PETSC_INTERN PetscSpinlock PetscCommSpinLock;
915 #endif
916 #endif
917
918 PETSC_EXTERN PetscLogEvent PETSC_Barrier;
919 PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSided;
920 PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSidedF;
921 PETSC_EXTERN PetscBool use_gpu_aware_mpi;
922
923 #if defined(PETSC_HAVE_ADIOS)
924 PETSC_EXTERN int64_t Petsc_adios_group;
925 #endif
926
927 #if defined(PETSC_HAVE_KOKKOS)
928 PETSC_INTERN PetscBool PetscBeganKokkos;
929 PETSC_INTERN PetscErrorCode PetscKokkosInitialize_Private(void); /* C bindings for the Kokkos C++ routines */
930 PETSC_INTERN PetscErrorCode PetscKokkosIsInitialized_Private(PetscBool*);
931 PETSC_INTERN PetscErrorCode PetscKokkosFinalize_Private(void);
932 PETSC_EXTERN PetscErrorCode PetscKokkosInitializeCheck(void); /* Check if CUDA is initialized and init CUDA if not yet. */
933 #endif
934
935 #if defined(PETSC_HAVE_CUDA)
936 PETSC_EXTERN PetscBool PetscCUDAInitialized; /* Has petsc initialized CUDA? One can use this flag to guard CUDA calls. */
937 PETSC_EXTERN PetscBool PetscMPICUDAAwarenessCheck(void);
938 #endif
939
940 #if defined(PETSC_HAVE_HIP)
941 PETSC_EXTERN PetscBool PetscHIPInitialized;
942 PETSC_EXTERN PetscBool PetscMPIHIPAwarenessCheck(void);
943 #endif
944
945 PETSC_EXTERN PetscBool PetscCreatedGpuObjects;
946 #endif /* PETSCIMPL_H */
947