Actual source code: petscimpl.h
2: /*
3: Defines the basic header of all PETSc objects.
4: */
6: #if !defined(PETSCIMPL_H)
7: #define PETSCIMPL_H
8: #include <petscsys.h>
10: #if defined(PETSC_CLANG_STATIC_ANALYZER)
11: #define PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(expr)
12: #else
13: #define PetscDisableStaticAnalyzerForExpressionUnderstandingThatThisIsDangerousAndBugprone(expr) \
14: 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 (*getcomm)(PetscObject,MPI_Comm *);
68: PetscErrorCode (*view)(PetscObject,PetscViewer);
69: PetscErrorCode (*destroy)(PetscObject*);
70: PetscErrorCode (*compose)(PetscObject,const char[],PetscObject);
71: PetscErrorCode (*query)(PetscObject,const char[],PetscObject *);
72: PetscErrorCode (*composefunction)(PetscObject,const char[],void (*)(void));
73: PetscErrorCode (*queryfunction)(PetscObject,const char[],void (**)(void));
74: } PetscOps;
76: typedef enum {PETSC_FORTRAN_CALLBACK_CLASS,PETSC_FORTRAN_CALLBACK_SUBTYPE,PETSC_FORTRAN_CALLBACK_MAXTYPE} PetscFortranCallbackType;
77: typedef size_t PetscFortranCallbackId;
78: #define PETSC_SMALLEST_FORTRAN_CALLBACK ((PetscFortranCallbackId)1000)
79: PETSC_EXTERN PetscErrorCode PetscFortranCallbackRegister(PetscClassId,const char*,PetscFortranCallbackId*);
80: PETSC_EXTERN PetscErrorCode PetscFortranCallbackGetSizes(PetscClassId,PetscFortranCallbackId*,PetscFortranCallbackId*);
82: typedef struct {
83: void (*func)(void);
84: void *ctx;
85: } PetscFortranCallback;
87: /*
88: All PETSc objects begin with the fields defined in PETSCHEADER.
89: The PetscObject is a way of examining these fields regardless of
90: the specific object. In C++ this could be a base abstract class
91: from which all objects are derived.
92: */
93: #define PETSC_MAX_OPTIONS_HANDLER 5
94: typedef struct _p_PetscObject {
95: PetscClassId classid;
96: PetscOps bops[1];
97: MPI_Comm comm;
98: PetscInt type;
99: PetscLogDouble flops,time,mem,memchildren;
100: PetscObjectId id;
101: PetscInt refct;
102: PetscMPIInt tag;
103: PetscFunctionList qlist;
104: PetscObjectList olist;
105: char *class_name; /* for example, "Vec" */
106: char *description;
107: char *mansec;
108: char *type_name; /* this is the subclass, for example VECSEQ which equals "seq" */
109: PetscObject parent;
110: PetscObjectId parentid;
111: char* name;
112: char *prefix;
113: PetscInt tablevel;
114: void *cpp;
115: PetscObjectState state;
116: PetscInt int_idmax, intstar_idmax;
117: PetscObjectState *intcomposedstate,*intstarcomposedstate;
118: PetscInt *intcomposeddata, **intstarcomposeddata;
119: PetscInt real_idmax, realstar_idmax;
120: PetscObjectState *realcomposedstate,*realstarcomposedstate;
121: PetscReal *realcomposeddata, **realstarcomposeddata;
122: PetscInt scalar_idmax, scalarstar_idmax;
123: PetscObjectState *scalarcomposedstate,*scalarstarcomposedstate;
124: PetscScalar *scalarcomposeddata, **scalarstarcomposeddata;
125: void (**fortran_func_pointers)(void); /* used by Fortran interface functions to stash user provided Fortran functions */
126: PetscFortranCallbackId num_fortran_func_pointers; /* number of Fortran function pointers allocated */
127: PetscFortranCallback *fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
128: PetscFortranCallbackId num_fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
129: void *python_context;
130: PetscErrorCode (*python_destroy)(void*);
132: PetscInt noptionhandler;
133: PetscErrorCode (*optionhandler[PETSC_MAX_OPTIONS_HANDLER])(PetscOptionItems*,PetscObject,void*);
134: PetscErrorCode (*optiondestroy[PETSC_MAX_OPTIONS_HANDLER])(PetscObject,void*);
135: void *optionctx[PETSC_MAX_OPTIONS_HANDLER];
136: PetscBool optionsprinted;
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 donotPetscObjectPrintClassNamePrefixType;
143: } _p_PetscObject;
145: #define PETSCHEADER(ObjectOps) \
146: _p_PetscObject hdr; \
147: ObjectOps ops[1]
149: #define PETSCFREEDHEADER -1
151: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectDestroyFunction)(PetscObject*); /* force cast in next macro to NEVER use extern "C" style */
152: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectViewFunction)(PetscObject,PetscViewer);
154: /*@C
155: PetscHeaderCreate - Creates a PETSc object of a particular class
157: Input Parameters:
158: + classid - the classid associated with this object (for example VEC_CLASSID)
159: . class_name - string name of class; should be static (for example "Vec")
160: . descr - string containing short description; should be static (for example "Vector")
161: . mansec - string indicating section in manual pages; should be static (for example "Vec")
162: . comm - the MPI Communicator
163: . destroy - the destroy routine for this object (for example VecDestroy())
164: - view - the view routine for this object (for example VecView())
166: Output Parameter:
167: . h - the newly created object
169: Level: developer
171: .seealso: PetscHeaderDestroy(), PetscClassIdRegister()
173: @*/
174: #define PetscHeaderCreate(h,classid,class_name,descr,mansec,comm,destroy,view) \
175: (PetscNew(&(h)) || \
176: PetscHeaderCreate_Private((PetscObject)(h),classid,class_name,descr,mansec,comm,(PetscObjectDestroyFunction)(destroy),(PetscObjectViewFunction)(view)) || \
177: PetscLogObjectCreate(h) || \
178: PetscLogObjectMemory((PetscObject)(h),sizeof(*(h))))
180: PETSC_EXTERN PetscErrorCode PetscComposedQuantitiesDestroy(PetscObject obj);
181: PETSC_EXTERN PetscErrorCode PetscHeaderCreate_Private(PetscObject,PetscClassId,const char[],const char[],const char[],MPI_Comm,PetscObjectDestroyFunction,PetscObjectViewFunction);
183: /*@C
184: PetscHeaderDestroy - Final step in destroying a PetscObject
186: Input Parameters:
187: . h - the header created with PetscHeaderCreate()
189: Level: developer
191: .seealso: PetscHeaderCreate()
192: @*/
193: #define PetscHeaderDestroy(h) (PetscHeaderDestroy_Private((PetscObject)(*(h))) || PetscFree(*(h)))
195: PETSC_EXTERN PetscErrorCode PetscHeaderDestroy_Private(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);
208: #if !defined(PETSC_CLANG_STATIC_ANALYZER)
209: /*
210: Macros to test if a PETSc object is valid and if pointers are valid
211: */
212: #if !defined(PETSC_USE_DEBUG)
225: #else
227: /* This check is for subtype methods such as DMDAGetCorners() that do not use the PetscTryMethod() or PetscUseMethod() paradigm */
229: do { \
230: PetscBool _7_same; \
232: PetscObjectTypeCompare((PetscObject)(h),t,&_7_same); \
234: } while (0)
239: } while (0)
243: if (((PetscObject)(h))->classid != ck) { \
245: else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Wrong type of object: Parameter # %d",arg); \
246: } \
247: } while (0)
253: } while (0)
263: do { \
265: } while (0)
266: #endif
267: #else /* PETSC_CLANG_STATIC_ANALYZER */
268: template <typename T>
270: template <typename T>
272: template <typename T>
274: template <typename T>
276: template <typename T>
278: template <typename T>
280: template <typename T>
282: template <typename T>
284: template <typename T>
286: template <typename T>
289: #endif /* PETSC_CLANG_STATIC_ANALYZER */
291: #define PetscSorted(n,idx,sorted) \
292: do { \
293: (sorted) = PETSC_TRUE; \
294: for (PetscInt _i_ = 1; _i_ < (n); ++_i_) { \
295: if ((idx)[_i_] < (idx)[_i_ - 1]) { (sorted) = PETSC_FALSE; break; } \
296: } \
297: } while (0)
299: #if !defined(PETSC_CLANG_STATIC_ANALYZER)
300: #if !defined(PETSC_USE_DEBUG)
316: #else
318: /*
319: For example, in the dot product between two vectors,
320: both vectors must be either Seq or MPI, not one of each
321: */
323: do { \
325: } while (0)
327: /*
328: Check type_name
329: */
331: do { \
332: PetscBool _7_match; \
333: PetscObjectTypeCompare(((PetscObject)(a)),(type),&_7_match); \
335: } while (0)
338: do { \
339: PetscBool _7_match; \
340: PetscObjectTypeCompareAny(((PetscObject)(a)),&_7_match,(type1),(type2),""); \
342: } while (0)
343: /*
344: Use this macro to check if the type is set
345: */
348: do { \
350: } while (0)
351: /*
352: Sometimes object must live on same communicator to inter-operate
353: */
355: do { \
356: PetscMPIInt _7_flag; \
357: MPI_Comm_compare(PetscObjectComm((PetscObject)(a)),PetscObjectComm((PetscObject)(b)),&_7_flag); \
359: } while (0)
362: do { \
365: } while (0)
368: do { \
369: PetscScalar b0=(b); \
370: PetscReal b1[5],b2[5]; \
371: if (PetscIsNanScalar(b0)) {b1[4] = 1;} else {b1[4] = 0;}; \
372: b1[0] = -PetscRealPart(b0); b1[1] = PetscRealPart(b0); b1[2] = -PetscImaginaryPart(b0); b1[3] = PetscImaginaryPart(b0); \
373: MPIU_Allreduce(b1,b2,5,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)(a)));\
375: } while (0)
378: do { \
379: PetscReal b0=(b),b1[3],b2[3]; \
380: if (PetscIsNanReal(b0)) {b1[2] = 1;} else {b1[2] = 0;}; \
381: b1[0] = -b0; b1[1] = b0; \
382: MPIU_Allreduce(b1,b2,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)(a)));\
384: } while (0)
387: do { \
388: PetscInt b0=(b),b1[2],b2[2]; \
389: b1[0] = -b0; b1[1] = b0; \
390: MPIU_Allreduce(b1,b2,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));\
392: } while (0)
395: do { \
396: PetscMPIInt b0=(b),b1[2],b2[2]; \
397: b1[0] = -b0; b1[1] = b0; \
398: MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));\
400: } while (0)
403: do { \
404: PetscMPIInt b0=(PetscMPIInt)(b),b1[2],b2[2]; \
405: b1[0] = -b0; b1[1] = b0; \
406: MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));\
408: } while (0)
411: do { \
412: PetscMPIInt b0=(PetscMPIInt)(b),b1[2],b2[2]; \
413: b1[0] = -b0; b1[1] = b0; \
414: MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)(a)));\
416: } while (0)
419: do { \
420: PetscBool _1_flg; \
421: PetscSorted(n,idx,_1_flg); \
423: } while (0)
425: #endif
426: #else /* PETSC_CLANG_STATIC_ANALYZER */
427: template <typename Ta,typename Tb>
431: template <typename T>
433: template <typename Ta,typename Tb>
435: template <typename Ta,typename Tb>
437: template <typename Ta,typename Tb>
439: template <typename Ta,typename Tb>
441: template <typename Ta,typename Tb>
443: template <typename Ta,typename Tb>
445: template <typename Ta,typename Tb>
447: template <typename Ta,typename Tb>
450: #endif /* PETSC_CLANG_STATIC_ANALYZER */
452: /*
453: PetscTryMethod - Queries an object for a method, if it exists then calls it.
454: These are intended to be used only inside PETSc functions.
456: Level: developer
458: .seealso: PetscUseMethod()
459: */
460: #define PetscTryMethod(obj,A,B,C) do { \
461: PetscErrorCode (*_7_f)B; \
462: PetscObjectQueryFunction((PetscObject)(obj),A,&_7_f); \
463: if (_7_f) (*_7_f)C; \
464: } while (0)
466: /*
467: PetscUseMethod - Queries an object for a method, if it exists then calls it, otherwise generates an error.
468: These are intended to be used only inside PETSc functions.
470: Level: developer
472: .seealso: PetscTryMethod()
473: */
474: #define PetscUseMethod(obj,A,B,C) do { \
475: PetscErrorCode (*_7_f)B; \
476: PetscObjectQueryFunction((PetscObject)(obj),A,&_7_f); \
478: (*_7_f)C; \
479: } while (0)
481: /*MC
482: PetscObjectStateIncrease - Increases the state of any PetscObject
484: Synopsis:
485: #include "petsc/private/petscimpl.h"
486: PetscErrorCode PetscObjectStateIncrease(PetscObject obj)
488: Logically Collective
490: Input Parameter:
491: . obj - any PETSc object, for example a Vec, Mat or KSP. This must be
492: cast with a (PetscObject), for example,
493: PetscObjectStateIncrease((PetscObject)mat);
495: Notes:
496: object state is an integer which gets increased every time
497: the object is changed internally. By saving and later querying the object state
498: one can determine whether information about the object is still current.
499: Currently, state is maintained for Vec and Mat objects.
501: This routine is mostly for internal use by PETSc; a developer need only
502: call it after explicit access to an object's internals. Routines such
503: as VecSet() or MatScale() already call this routine. It is also called, as a
504: precaution, in VecRestoreArray(), MatRestoreRow(), MatDenseRestoreArray().
506: This routine is logically collective because state equality comparison needs to be possible without communication.
508: Level: developer
510: seealso: PetscObjectStateGet()
512: M*/
513: #define PetscObjectStateIncrease(obj) ((obj)->state++,0)
515: PETSC_EXTERN PetscErrorCode PetscObjectStateGet(PetscObject,PetscObjectState*);
516: PETSC_EXTERN PetscErrorCode PetscObjectStateSet(PetscObject,PetscObjectState);
517: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataRegister(PetscInt*);
518: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject);
519: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject);
520: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject);
521: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject);
522: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject);
523: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject);
524: PETSC_EXTERN PetscInt PetscObjectComposedDataMax;
525: /*MC
526: PetscObjectComposedDataSetInt - attach integer data to a PetscObject
528: Synopsis:
529: #include "petsc/private/petscimpl.h"
530: PetscErrorCode PetscObjectComposedDataSetInt(PetscObject obj,int id,int data)
532: Not collective
534: Input parameters:
535: + obj - the object to which data is to be attached
536: . id - the identifier for the data
537: - data - the data to be attached
539: Notes
540: The data identifier can best be created through a call to PetscObjectComposedDataRegister()
542: Level: developer
543: M*/
544: #define PetscObjectComposedDataSetInt(obj,id,data) \
545: ((((obj)->int_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseInt(obj)) || \
546: ((obj)->intcomposeddata[id] = data,(obj)->intcomposedstate[id] = (obj)->state, 0))
548: /*MC
549: PetscObjectComposedDataGetInt - retrieve integer data attached to an object
551: Synopsis:
552: #include "petsc/private/petscimpl.h"
553: PetscErrorCode PetscObjectComposedDataGetInt(PetscObject obj,int id,int data,PetscBool flag)
555: Not collective
557: Input parameters:
558: + obj - the object from which data is to be retrieved
559: - id - the identifier for the data
561: Output parameters:
562: + data - the data to be retrieved
563: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
565: The 'data' and 'flag' variables are inlined, so they are not pointers.
567: Level: developer
568: M*/
569: #define PetscObjectComposedDataGetInt(obj,id,data,flag) \
570: ((((obj)->intcomposedstate && ((obj)->intcomposedstate[id] == (obj)->state)) ? \
571: (data = (obj)->intcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
573: /*MC
574: PetscObjectComposedDataSetIntstar - attach integer array data to a PetscObject
576: Synopsis:
577: #include "petsc/private/petscimpl.h"
578: PetscErrorCode PetscObjectComposedDataSetIntstar(PetscObject obj,int id,int *data)
580: Not collective
582: Input parameters:
583: + obj - the object to which data is to be attached
584: . id - the identifier for the data
585: - data - the data to be attached
587: Notes
588: The data identifier can best be determined through a call to
589: PetscObjectComposedDataRegister()
591: Level: developer
592: M*/
593: #define PetscObjectComposedDataSetIntstar(obj,id,data) \
594: ((((obj)->intstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseIntstar(obj)) || \
595: ((obj)->intstarcomposeddata[id] = data,(obj)->intstarcomposedstate[id] = (obj)->state, 0))
597: /*MC
598: PetscObjectComposedDataGetIntstar - retrieve integer array data
599: attached to an object
601: Synopsis:
602: #include "petsc/private/petscimpl.h"
603: PetscErrorCode PetscObjectComposedDataGetIntstar(PetscObject obj,int id,int *data,PetscBool flag)
605: Not collective
607: Input parameters:
608: + obj - the object from which data is to be retrieved
609: - id - the identifier for the data
611: Output parameters:
612: + data - the data to be retrieved
613: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
615: The 'data' and 'flag' variables are inlined, so they are not pointers.
617: Level: developer
618: M*/
619: #define PetscObjectComposedDataGetIntstar(obj,id,data,flag) \
620: ((((obj)->intstarcomposedstate && ((obj)->intstarcomposedstate[id] == (obj)->state)) ? \
621: (data = (obj)->intstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
623: /*MC
624: PetscObjectComposedDataSetReal - attach real data to a PetscObject
626: Synopsis:
627: #include "petsc/private/petscimpl.h"
628: PetscErrorCode PetscObjectComposedDataSetReal(PetscObject obj,int id,PetscReal data)
630: Not collective
632: Input parameters:
633: + obj - the object to which data is to be attached
634: . id - the identifier for the data
635: - data - the data to be attached
637: Notes
638: The data identifier can best be determined through a call to
639: PetscObjectComposedDataRegister()
641: Level: developer
642: M*/
643: #define PetscObjectComposedDataSetReal(obj,id,data) \
644: ((((obj)->real_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseReal(obj)) || \
645: ((obj)->realcomposeddata[id] = data,(obj)->realcomposedstate[id] = (obj)->state, 0))
647: /*MC
648: PetscObjectComposedDataGetReal - retrieve real data attached to an object
650: Synopsis:
651: #include "petsc/private/petscimpl.h"
652: PetscErrorCode PetscObjectComposedDataGetReal(PetscObject obj,int id,PetscReal data,PetscBool flag)
654: Not collective
656: Input parameters:
657: + obj - the object from which data is to be retrieved
658: - id - the identifier for the data
660: Output parameters:
661: + data - the data to be retrieved
662: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
664: The 'data' and 'flag' variables are inlined, so they are not pointers.
666: Level: developer
667: M*/
668: #define PetscObjectComposedDataGetReal(obj,id,data,flag) \
669: ((((obj)->realcomposedstate && ((obj)->realcomposedstate[id] == (obj)->state)) ? \
670: (data = (obj)->realcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
672: /*MC
673: PetscObjectComposedDataSetRealstar - attach real array data to a PetscObject
675: Synopsis:
676: #include "petsc/private/petscimpl.h"
677: PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *data)
679: Not collective
681: Input parameters:
682: + obj - the object to which data is to be attached
683: . id - the identifier for the data
684: - data - the data to be attached
686: Notes
687: The data identifier can best be determined through a call to
688: PetscObjectComposedDataRegister()
690: Level: developer
691: M*/
692: #define PetscObjectComposedDataSetRealstar(obj,id,data) \
693: ((((obj)->realstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseRealstar(obj)) || \
694: ((obj)->realstarcomposeddata[id] = data, (obj)->realstarcomposedstate[id] = (obj)->state, 0))
696: /*MC
697: PetscObjectComposedDataGetRealstar - retrieve real array data
698: attached to an object
700: Synopsis:
701: #include "petsc/private/petscimpl.h"
702: PetscErrorCode PetscObjectComposedDataGetRealstar(PetscObject obj,int id,PetscReal *data,PetscBool flag)
704: Not collective
706: Input parameters:
707: + obj - the object from which data is to be retrieved
708: - id - the identifier for the data
710: Output parameters:
711: + data - the data to be retrieved
712: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
714: The 'data' and 'flag' variables are inlined, so they are not pointers.
716: Level: developer
717: M*/
718: #define PetscObjectComposedDataGetRealstar(obj,id,data,flag) \
719: ((((obj)->realstarcomposedstate && ((obj)->realstarcomposedstate[id] == (obj)->state)) ? \
720: (data = (obj)->realstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
722: /*MC
723: PetscObjectComposedDataSetScalar - attach scalar data to a PetscObject
725: Synopsis:
726: #include "petsc/private/petscimpl.h"
727: PetscErrorCode PetscObjectComposedDataSetScalar(PetscObject obj,int id,PetscScalar data)
729: Not collective
731: Input parameters:
732: + obj - the object to which data is to be attached
733: . id - the identifier for the data
734: - data - the data to be attached
736: Notes
737: The data identifier can best be determined through a call to
738: PetscObjectComposedDataRegister()
740: Level: developer
741: M*/
742: #if defined(PETSC_USE_COMPLEX)
743: #define PetscObjectComposedDataSetScalar(obj,id,data) \
744: ((((obj)->scalar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalar(obj)) || \
745: ((obj)->scalarcomposeddata[id] = data,(obj)->scalarcomposedstate[id] = (obj)->state, 0))
746: #else
747: #define PetscObjectComposedDataSetScalar(obj,id,data) \
748: PetscObjectComposedDataSetReal(obj,id,data)
749: #endif
750: /*MC
751: PetscObjectComposedDataGetScalar - retrieve scalar data attached to an object
753: Synopsis:
754: #include "petsc/private/petscimpl.h"
755: PetscErrorCode PetscObjectComposedDataGetScalar(PetscObject obj,int id,PetscScalar data,PetscBool flag)
757: Not collective
759: Input parameters:
760: + obj - the object from which data is to be retrieved
761: - id - the identifier for the data
763: Output parameters:
764: + data - the data to be retrieved
765: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
767: The 'data' and 'flag' variables are inlined, so they are not pointers.
769: Level: developer
770: M*/
771: #if defined(PETSC_USE_COMPLEX)
772: #define PetscObjectComposedDataGetScalar(obj,id,data,flag) \
773: ((((obj)->scalarcomposedstate && ((obj)->scalarcomposedstate[id] == (obj)->state)) ? \
774: (data = (obj)->scalarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
775: #else
776: #define PetscObjectComposedDataGetScalar(obj,id,data,flag) \
777: PetscObjectComposedDataGetReal(obj,id,data,flag)
778: #endif
780: /*MC
781: PetscObjectComposedDataSetScalarstar - attach scalar array data to a PetscObject
783: Synopsis:
784: #include "petsc/private/petscimpl.h"
785: PetscErrorCode PetscObjectComposedDataSetScalarstar(PetscObject obj,int id,PetscScalar *data)
787: Not collective
789: Input parameters:
790: + obj - the object to which data is to be attached
791: . id - the identifier for the data
792: - data - the data to be attached
794: Notes
795: The data identifier can best be determined through a call to
796: PetscObjectComposedDataRegister()
798: Level: developer
799: M*/
800: #if defined(PETSC_USE_COMPLEX)
801: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
802: ((((obj)->scalarstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalarstar(obj)) || \
803: ((obj)->scalarstarcomposeddata[id] = data,(obj)->scalarstarcomposedstate[id] = (obj)->state, 0))
804: #else
805: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
806: PetscObjectComposedDataSetRealstar(obj,id,data)
807: #endif
808: /*MC
809: PetscObjectComposedDataGetScalarstar - retrieve scalar array data
810: attached to an object
812: Synopsis:
813: #include "petsc/private/petscimpl.h"
814: PetscErrorCode PetscObjectComposedDataGetScalarstar(PetscObject obj,int id,PetscScalar *data,PetscBool flag)
816: Not collective
818: Input parameters:
819: + obj - the object from which data is to be retrieved
820: - id - the identifier for the data
822: Output parameters:
823: + data - the data to be retrieved
824: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
826: The 'data' and 'flag' variables are inlined, so they are not pointers.
828: Level: developer
829: M*/
830: #if defined(PETSC_USE_COMPLEX)
831: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag) \
832: ((((obj)->scalarstarcomposedstate && ((obj)->scalarstarcomposedstate[id] == (obj)->state)) ? \
833: (data = (obj)->scalarstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
834: #else
835: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag) \
836: PetscObjectComposedDataGetRealstar(obj,id,data,flag)
837: #endif
839: PETSC_EXTERN PetscMPIInt Petsc_Counter_keyval;
840: PETSC_EXTERN PetscMPIInt Petsc_InnerComm_keyval;
841: PETSC_EXTERN PetscMPIInt Petsc_OuterComm_keyval;
842: PETSC_EXTERN PetscMPIInt Petsc_Seq_keyval;
843: PETSC_EXTERN PetscMPIInt Petsc_ShmComm_keyval;
845: struct PetscCommStash {
846: struct PetscCommStash *next;
847: MPI_Comm comm;
848: };
850: /*
851: PETSc communicators have this attribute, see
852: PetscCommDuplicate(), PetscCommDestroy(), PetscCommGetNewTag(), PetscObjectGetName()
853: */
854: typedef struct {
855: PetscMPIInt tag; /* next free tag value */
856: PetscInt refcount; /* number of references, communicator can be freed when this reaches 0 */
857: PetscInt namecount; /* used to generate the next name, as in Vec_0, Mat_1, ... */
858: PetscMPIInt *iflags; /* length of comm size, shared by all calls to PetscCommBuildTwoSided_Allreduce/RedScatter on this comm */
859: struct PetscCommStash *comms; /* communicators available for PETSc to pass off to other packages */
860: } PetscCommCounter;
862: typedef enum {STATE_BEGIN, STATE_PENDING, STATE_END} SRState;
864: typedef enum {PETSC_SR_REDUCE_SUM=0,PETSC_SR_REDUCE_MAX=1,PETSC_SR_REDUCE_MIN=2} PetscSRReductionType;
866: typedef struct {
867: MPI_Comm comm;
868: MPI_Request request;
869: PetscBool mix;
870: PetscBool async;
871: PetscScalar *lvalues; /* this are the reduced values before call to MPI_Allreduce() */
872: PetscScalar *gvalues; /* values after call to MPI_Allreduce() */
873: void **invecs; /* for debugging only, vector/memory used with each op */
874: PetscInt *reducetype; /* is particular value to be summed or maxed? */
875: struct { PetscScalar v; PetscInt i; } *lvalues_mix,*gvalues_mix; /* used when mixing reduce operations */
876: SRState state; /* are we calling xxxBegin() or xxxEnd()? */
877: PetscInt maxops; /* total amount of space we have for requests */
878: PetscInt numopsbegin; /* number of requests that have been queued in */
879: PetscInt numopsend; /* number of requests that have been gotten by user */
880: } PetscSplitReduction;
882: PETSC_EXTERN PetscErrorCode PetscSplitReductionGet(MPI_Comm,PetscSplitReduction**);
883: PETSC_EXTERN PetscErrorCode PetscSplitReductionEnd(PetscSplitReduction*);
884: PETSC_EXTERN PetscErrorCode PetscSplitReductionExtend(PetscSplitReduction*);
886: #if !defined(PETSC_SKIP_SPINLOCK)
887: #if defined(PETSC_HAVE_THREADSAFETY)
888: # if defined(PETSC_HAVE_CONCURRENCYKIT)
889: #if defined(__cplusplus)
890: /* CK does not have extern "C" protection in their include files */
891: extern "C" {
892: #endif
893: #include <ck_spinlock.h>
894: #if defined(__cplusplus)
895: }
896: #endif
897: typedef ck_spinlock_t PetscSpinlock;
898: static inline PetscErrorCode PetscSpinlockCreate(PetscSpinlock *ck_spinlock)
899: {
900: ck_spinlock_init(ck_spinlock);
901: return 0;
902: }
903: static inline PetscErrorCode PetscSpinlockLock(PetscSpinlock *ck_spinlock)
904: {
905: ck_spinlock_lock(ck_spinlock);
906: return 0;
907: }
908: static inline PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *ck_spinlock)
909: {
910: ck_spinlock_unlock(ck_spinlock);
911: return 0;
912: }
913: static inline PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *ck_spinlock)
914: {
915: return 0;
916: }
917: # elif defined(PETSC_HAVE_OPENMP)
919: #include <omp.h>
920: typedef omp_lock_t PetscSpinlock;
921: static inline PetscErrorCode PetscSpinlockCreate(PetscSpinlock *omp_lock)
922: {
923: omp_init_lock(omp_lock);
924: return 0;
925: }
926: static inline PetscErrorCode PetscSpinlockLock(PetscSpinlock *omp_lock)
927: {
928: omp_set_lock(omp_lock);
929: return 0;
930: }
931: static inline PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *omp_lock)
932: {
933: omp_unset_lock(omp_lock);
934: return 0;
935: }
936: static inline PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *omp_lock)
937: {
938: omp_destroy_lock(omp_lock);
939: return 0;
940: }
941: #else
942: #error "Thread safety requires either --with-openmp or --download-concurrencykit"
943: #endif
945: #else
946: typedef int PetscSpinlock;
947: #define PetscSpinlockCreate(a) 0
948: #define PetscSpinlockLock(a) 0
949: #define PetscSpinlockUnlock(a) 0
950: #define PetscSpinlockDestroy(a) 0
951: #endif
953: #if defined(PETSC_HAVE_THREADSAFETY)
954: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockOpen;
955: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStdout;
956: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStderr;
957: PETSC_INTERN PetscSpinlock PetscCommSpinLock;
958: #endif
959: #endif
961: PETSC_EXTERN PetscLogEvent PETSC_Barrier;
962: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSided;
963: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSidedF;
964: PETSC_EXTERN PetscBool use_gpu_aware_mpi;
966: #if defined(PETSC_HAVE_ADIOS)
967: PETSC_EXTERN int64_t Petsc_adios_group;
968: #endif
970: #if defined(PETSC_HAVE_KOKKOS)
971: PETSC_INTERN PetscBool PetscBeganKokkos;
972: PETSC_EXTERN PetscBool PetscKokkosInitialized;
973: PETSC_INTERN PetscErrorCode PetscKokkosIsInitialized_Private(PetscBool*);
974: PETSC_INTERN PetscErrorCode PetscKokkosFinalize_Private(void);
975: #endif
977: #if defined(PETSC_HAVE_OPENMP)
978: PETSC_EXTERN PetscInt PetscNumOMPThreads;
979: #endif
981: #endif /* PETSCIMPL_H */