Actual source code: petscimpl.h
petsc-3.8.3 2017-12-09
2: /*
3: Defines the basic header of all PETSc objects.
4: */
6: #if !defined(_PETSCHEAD_H)
7: #define _PETSCHEAD_H
8: #include <petscsys.h>
10: /* These are used internally by PETSc ASCII IO routines*/
11: #include <stdarg.h>
12: PETSC_EXTERN PetscErrorCode PetscVSNPrintf(char*,size_t,const char[],size_t*,va_list);
13: PETSC_EXTERN PetscErrorCode (*PetscVFPrintf)(FILE*,const char[],va_list);
14: PETSC_EXTERN PetscErrorCode PetscVFPrintfDefault(FILE*,const char[],va_list);
16: #if defined(PETSC_HAVE_MATLAB_ENGINE)
17: PETSC_EXTERN PetscErrorCode PetscVFPrintf_Matlab(FILE*,const char[],va_list);
18: #endif
20: #if defined(PETSC_HAVE_CLOSURES)
21: PETSC_EXTERN PetscErrorCode PetscVFPrintfSetClosure(int (^)(const char*));
22: #endif
25: #if defined(PETSC_HAVE_CUDA)
26: #include <cuda.h>
27: #include <cublas_v2.h>
28: #endif
30: /*
31: All major PETSc data structures have a common core; this is defined
32: below by PETSCHEADER.
34: PetscHeaderCreate() should be used whenever creating a PETSc structure.
35: */
37: /*
38: PetscOps: structure of core operations that all PETSc objects support.
40: getcomm() - Gets the object's communicator.
41: view() - Is the routine for viewing the entire PETSc object; for
42: example, MatView() is the general matrix viewing routine.
43: This is used by PetscObjectView((PetscObject)obj) to allow
44: viewing any PETSc object.
45: destroy() - Is the routine for destroying the entire PETSc object;
46: for example,MatDestroy() is the general matrix
47: destruction routine.
48: This is used by PetscObjectDestroy((PetscObject*)&obj) to allow
49: destroying any PETSc object.
50: compose() - Associates a PETSc object with another PETSc object with a name
51: query() - Returns a different PETSc object that has been associated
52: with the first object using a name.
53: composefunction() - Attaches an a function to a PETSc object with a name.
54: queryfunction() - Requests a registered function that has been attached to a PETSc object.
55: */
57: typedef struct {
58: PetscErrorCode (*getcomm)(PetscObject,MPI_Comm *);
59: PetscErrorCode (*view)(PetscObject,PetscViewer);
60: PetscErrorCode (*destroy)(PetscObject*);
61: PetscErrorCode (*compose)(PetscObject,const char[],PetscObject);
62: PetscErrorCode (*query)(PetscObject,const char[],PetscObject *);
63: PetscErrorCode (*composefunction)(PetscObject,const char[],void (*)(void));
64: PetscErrorCode (*queryfunction)(PetscObject,const char[],void (**)(void));
65: } PetscOps;
67: typedef enum {PETSC_FORTRAN_CALLBACK_CLASS,PETSC_FORTRAN_CALLBACK_SUBTYPE,PETSC_FORTRAN_CALLBACK_MAXTYPE} PetscFortranCallbackType;
68: typedef int PetscFortranCallbackId;
69: #define PETSC_SMALLEST_FORTRAN_CALLBACK ((PetscFortranCallbackId)1000)
70: PETSC_EXTERN PetscErrorCode PetscFortranCallbackRegister(PetscClassId,const char*,PetscFortranCallbackId*);
71: PETSC_EXTERN PetscErrorCode PetscFortranCallbackGetSizes(PetscClassId,PetscInt*,PetscInt*);
73: typedef struct {
74: void (*func)(void);
75: void *ctx;
76: } PetscFortranCallback;
78: /*
79: All PETSc objects begin with the fields defined in PETSCHEADER.
80: The PetscObject is a way of examining these fields regardless of
81: the specific object. In C++ this could be a base abstract class
82: from which all objects are derived.
83: */
84: #define PETSC_MAX_OPTIONS_HANDLER 5
85: typedef struct _p_PetscObject {
86: PetscClassId classid;
87: PetscOps bops[1];
88: MPI_Comm comm;
89: PetscInt type;
90: PetscLogDouble flops,time,mem,memchildren;
91: PetscObjectId id;
92: PetscInt refct;
93: PetscMPIInt tag;
94: PetscFunctionList qlist;
95: PetscObjectList olist;
96: char *class_name; /* for example, "Vec" */
97: char *description;
98: char *mansec;
99: char *type_name; /* this is the subclass, for example VECSEQ which equals "seq" */
100: PetscObject parent;
101: PetscObjectId parentid;
102: char* name;
103: char *prefix;
104: PetscInt tablevel;
105: void *cpp;
106: PetscObjectState state;
107: PetscInt int_idmax, intstar_idmax;
108: PetscObjectState *intcomposedstate,*intstarcomposedstate;
109: PetscInt *intcomposeddata, **intstarcomposeddata;
110: PetscInt real_idmax, realstar_idmax;
111: PetscObjectState *realcomposedstate,*realstarcomposedstate;
112: PetscReal *realcomposeddata, **realstarcomposeddata;
113: PetscInt scalar_idmax, scalarstar_idmax;
114: PetscObjectState *scalarcomposedstate,*scalarstarcomposedstate;
115: PetscScalar *scalarcomposeddata, **scalarstarcomposeddata;
116: void (**fortran_func_pointers)(void); /* used by Fortran interface functions to stash user provided Fortran functions */
117: PetscInt num_fortran_func_pointers; /* number of Fortran function pointers allocated */
118: PetscFortranCallback *fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
119: PetscInt num_fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
120: void *python_context;
121: PetscErrorCode (*python_destroy)(void*);
123: PetscInt noptionhandler;
124: PetscErrorCode (*optionhandler[PETSC_MAX_OPTIONS_HANDLER])(PetscOptionItems*,PetscObject,void*);
125: PetscErrorCode (*optiondestroy[PETSC_MAX_OPTIONS_HANDLER])(PetscObject,void*);
126: void *optionctx[PETSC_MAX_OPTIONS_HANDLER];
127: PetscBool optionsprinted;
128: #if defined(PETSC_HAVE_SAWS)
129: PetscBool amsmem; /* if PETSC_TRUE then this object is registered with SAWs and visible to clients */
130: PetscBool amspublishblock; /* if PETSC_TRUE and publishing objects then will block at PetscObjectSAWsBlock() */
131: #endif
132: PetscOptions options; /* options database used, NULL means default */
133: } _p_PetscObject;
135: #define PETSCHEADER(ObjectOps) \
136: _p_PetscObject hdr; \
137: ObjectOps ops[1]
139: #define PETSCFREEDHEADER -1
141: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectDestroyFunction)(PetscObject*); /* force cast in next macro to NEVER use extern "C" style */
142: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectViewFunction)(PetscObject,PetscViewer);
144: /*@C
145: PetscHeaderCreate - Creates a PETSc object of a particular class
147: Input Parameters:
148: + classid - the classid associated with this object (for example VEC_CLASSID)
149: . class_name - string name of class; should be static (for example "Vec")
150: . descr - string containing short description; should be static (for example "Vector")
151: . mansec - string indicating section in manual pages; should be static (for example "Vec")
152: . comm - the MPI Communicator
153: . destroy - the destroy routine for this object (for example VecDestroy())
154: - view - the view routine for this object (for example VecView())
156: Output Parameter:
157: . h - the newly created object
159: Level: developer
161: .seealso: PetscHeaderDestroy(), PetscClassIdRegister()
163: @*/
164: #define PetscHeaderCreate(h,classid,class_name,descr,mansec,comm,destroy,view) \
165: (PetscNew(&(h)) || \
166: PetscHeaderCreate_Private((PetscObject)h,classid,class_name,descr,mansec,comm,(PetscObjectDestroyFunction)destroy,(PetscObjectViewFunction)view) || \
167: PetscLogObjectCreate(h) || \
168: PetscLogObjectMemory((PetscObject)h,sizeof(*(h))))
170: PETSC_EXTERN PetscErrorCode PetscComposedQuantitiesDestroy(PetscObject obj);
171: PETSC_EXTERN PetscErrorCode PetscHeaderCreate_Private(PetscObject,PetscClassId,const char[],const char[],const char[],MPI_Comm,PetscObjectDestroyFunction,PetscObjectViewFunction);
173: /*@C
174: PetscHeaderDestroy - Final step in destroying a PetscObject
176: Input Parameters:
177: . h - the header created with PetscHeaderCreate()
179: Level: developer
181: .seealso: PetscHeaderCreate()
182: @*/
183: #define PetscHeaderDestroy(h) (PetscHeaderDestroy_Private((PetscObject)(*h)) || PetscFree(*h))
185: PETSC_EXTERN PetscErrorCode PetscHeaderDestroy_Private(PetscObject);
186: PETSC_EXTERN PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject,PetscObject);
187: PETSC_EXTERN PetscErrorCode PetscObjectSetFortranCallback(PetscObject,PetscFortranCallbackType,PetscFortranCallbackId*,void(*)(void),void *ctx);
188: PETSC_EXTERN PetscErrorCode PetscObjectGetFortranCallback(PetscObject,PetscFortranCallbackType,PetscFortranCallbackId,void(**)(void),void **ctx);
190: PETSC_INTERN PetscErrorCode PetscCitationsInitialize(void);
191: PETSC_INTERN PetscErrorCode PetscOptionsFindPair_Private(PetscOptions,const char[],const char[],char**,PetscBool*);
192: PETSC_INTERN PetscErrorCode PetscFreeMPIResources(void);
198: /*
199: Macros to test if a PETSc object is valid and if pointers are valid
200: */
201: #if !defined(PETSC_USE_DEBUG)
212: #else
215: do { \
216: if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg); \
218: if (((PetscObject)(h))->classid != ck) { \
219: if (((PetscObject)(h))->classid == PETSCFREEDHEADER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
220: else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Wrong type of object: Parameter # %d",arg); \
221: } \
222: } while (0)
225: do { \
226: if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg); \
228: if (((PetscObject)(h))->classid == PETSCFREEDHEADER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
229: 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); \
230: } while (0)
233: do { \
234: if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
236: } while (0)
239: do { \
240: if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg);\
242: } while (0)
245: do { \
246: if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Null Pointer: Parameter # %d",arg); \
248: } while (0)
251: do { \
252: if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
254: } while (0)
257: do { \
258: if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
260: } while (0)
263: do { \
264: if (!f) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Function Pointer: Parameter # %d",arg); \
265: } while (0)
267: #endif
269: #if !defined(PETSC_USE_DEBUG)
284: #else
286: /*
287: For example, in the dot product between two vectors,
288: both vectors must be either Seq or MPI, not one of each
289: */
291: 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);
292: /*
293: Check type_name
294: */
296: do { \
297: PetscBool __match; \
298: PetscErrorCode _7_ierr; \
299: _7_PetscObjectTypeCompare(((PetscObject)a),(type),&__match);CHKERRQ(_7_ierr); \
300: if (!__match) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Object (%s) is not %s",(char*)(((PetscObject)a)->type_name),type); \
301: } while (0)
304: do { \
305: PetscBool __match; \
306: PetscErrorCode _7_ierr; \
307: _7_PetscObjectTypeCompareAny(((PetscObject)a),&__match,(type1),(type2),"");CHKERRQ(_7_ierr); \
308: if (!__match) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Object (%s) is not %s or %s",(char*)(((PetscObject)a)->type_name),type1,type2); \
309: } while (0)
310: /*
311: Use this macro to check if the type is set
312: */
314: 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);
315: /*
316: Sometimes object must live on same communicator to inter-operate
317: */
319: do { \
320: PetscErrorCode _6_ierr,__flag; \
321: _6_MPI_Comm_compare(PetscObjectComm((PetscObject)a),PetscObjectComm((PetscObject)b),&__flag);CHKERRQ(_6_ierr); \
322: if (__flag != MPI_CONGRUENT && __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,__flag); \
323: } while (0)
326: do { \
329: } while (0)
332: do { \
333: PetscErrorCode _7_ierr; \
334: PetscReal b1[5],b2[5]; \
335: if (PetscIsNanScalar(b)) {b1[4] = 1;} else {b1[4] = 0;}; \
336: b1[0] = -PetscRealPart(b); b1[1] = PetscRealPart(b);b1[2] = -PetscImaginaryPart(b); b1[3] = PetscImaginaryPart(b); \
337: _7_MPI_Allreduce(b1,b2,5,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
338: 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",c); \
339: } while (0)
342: do { \
343: PetscErrorCode _7_ierr; \
344: PetscReal b1[3],b2[3]; \
345: if (PetscIsNanReal(b)) {b1[2] = 1;} else {b1[2] = 0;}; \
346: b1[0] = -b; b1[1] = b; \
347: _7_MPI_Allreduce(b1,b2,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
348: 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",c); \
349: } while (0)
352: do { \
353: PetscErrorCode _7_ierr; \
354: PetscInt b1[2],b2[2]; \
355: b1[0] = -b; b1[1] = b; \
356: _7_MPIU_Allreduce(b1,b2,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
357: if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)a),PETSC_ERR_ARG_WRONG,"Int value must be same on all processes, argument # %d",c); \
358: } while (0)
363: do { \
364: PetscErrorCode _7_ierr; \
365: PetscMPIInt b1[2],b2[2]; \
366: b1[0] = -(PetscMPIInt)b; b1[1] = (PetscMPIInt)b; \
367: _7_MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
368: if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)a),PETSC_ERR_ARG_WRONG,"Bool value must be same on all processes, argument # %d",c); \
369: } while (0)
372: do { \
373: PetscErrorCode _7_ierr; \
374: PetscMPIInt b1[2],b2[2]; \
375: b1[0] = -(PetscMPIInt)b; b1[1] = (PetscMPIInt)b; \
376: _7_MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
377: if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)a),PETSC_ERR_ARG_WRONG,"Enum value must be same on all processes, argument # %d",c); \
378: } while (0)
380: #endif
382: /*
383: PetscTryMethod - Queries an object for a method, if it exists then calls it.
384: These are intended to be used only inside PETSc functions.
386: Level: developer
388: .seealso: PetscUseMethod()
389: */
390: #define PetscTryMethod(obj,A,B,C) \
391: 0;{ PetscErrorCode (*f)B, __ierr; \
392: __PetscObjectQueryFunction((PetscObject)obj,A,&f);CHKERRQ(__ierr); \
393: if (f) {__(*f)C;CHKERRQ(__ierr);}\
394: }
396: /*
397: PetscUseMethod - Queries an object for a method, if it exists then calls it, otherwise generates an error.
398: These are intended to be used only inside PETSc functions.
400: Level: developer
402: .seealso: PetscTryMethod()
403: */
404: #define PetscUseMethod(obj,A,B,C) \
405: 0;{ PetscErrorCode (*f)B, __ierr; \
406: __PetscObjectQueryFunction((PetscObject)obj,A,&f);CHKERRQ(__ierr); \
407: if (f) {__(*f)C;CHKERRQ(__ierr);}\
408: else SETERRQ1(PetscObjectComm((PetscObject)obj),PETSC_ERR_SUP,"Cannot locate function %s in object",A); \
409: }
411: /*MC
412: PetscObjectStateIncrease - Increases the state of any PetscObject
414: Synopsis:
415: #include "petsc/private/petscimpl.h"
416: PetscErrorCode PetscObjectStateIncrease(PetscObject obj)
418: Logically Collective
420: Input Parameter:
421: . obj - any PETSc object, for example a Vec, Mat or KSP. This must be
422: cast with a (PetscObject), for example,
423: PetscObjectStateIncrease((PetscObject)mat);
425: Notes: object state is an integer which gets increased every time
426: the object is changed internally. By saving and later querying the object state
427: one can determine whether information about the object is still current.
428: Currently, state is maintained for Vec and Mat objects.
430: This routine is mostly for internal use by PETSc; a developer need only
431: call it after explicit access to an object's internals. Routines such
432: as VecSet() or MatScale() already call this routine. It is also called, as a
433: precaution, in VecRestoreArray(), MatRestoreRow(), MatDenseRestoreArray().
435: This routine is logically collective because state equality comparison needs to be possible without communication.
437: Level: developer
439: seealso: PetscObjectStateGet()
441: Concepts: state
443: M*/
444: #define PetscObjectStateIncrease(obj) ((obj)->state++,0)
446: PETSC_EXTERN PetscErrorCode PetscObjectStateGet(PetscObject,PetscObjectState*);
447: PETSC_EXTERN PetscErrorCode PetscObjectStateSet(PetscObject,PetscObjectState);
448: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataRegister(PetscInt*);
449: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject);
450: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject);
451: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject);
452: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject);
453: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject);
454: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject);
455: PETSC_EXTERN PetscInt PetscObjectComposedDataMax;
456: /*MC
457: PetscObjectComposedDataSetInt - attach integer data to a PetscObject
459: Synopsis:
460: #include "petsc/private/petscimpl.h"
461: PetscErrorCode PetscObjectComposedDataSetInt(PetscObject obj,int id,int data)
463: Not collective
465: Input parameters:
466: + obj - the object to which data is to be attached
467: . id - the identifier for the data
468: - data - the data to be attached
470: Notes
471: The data identifier can best be created through a call to PetscObjectComposedDataRegister()
473: Level: developer
474: M*/
475: #define PetscObjectComposedDataSetInt(obj,id,data) \
476: ((((obj)->int_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseInt(obj)) || \
477: ((obj)->intcomposeddata[id] = data,(obj)->intcomposedstate[id] = (obj)->state, 0))
479: /*MC
480: PetscObjectComposedDataGetInt - retrieve integer data attached to an object
482: Synopsis:
483: #include "petsc/private/petscimpl.h"
484: PetscErrorCode PetscObjectComposedDataGetInt(PetscObject obj,int id,int data,PetscBool flag)
486: Not collective
488: Input parameters:
489: + obj - the object from which data is to be retrieved
490: - id - the identifier for the data
492: Output parameters
493: + data - the data to be retrieved
494: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
496: The 'data' and 'flag' variables are inlined, so they are not pointers.
498: Level: developer
499: M*/
500: #define PetscObjectComposedDataGetInt(obj,id,data,flag) \
501: ((((obj)->intcomposedstate && ((obj)->intcomposedstate[id] == (obj)->state)) ? \
502: (data = (obj)->intcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
504: /*MC
505: PetscObjectComposedDataSetIntstar - attach integer array data to a PetscObject
507: Synopsis:
508: #include "petsc/private/petscimpl.h"
509: PetscErrorCode PetscObjectComposedDataSetIntstar(PetscObject obj,int id,int *data)
511: Not collective
513: Input parameters:
514: + obj - the object to which data is to be attached
515: . id - the identifier for the data
516: - data - the data to be attached
518: Notes
519: The data identifier can best be determined through a call to
520: PetscObjectComposedDataRegister()
522: Level: developer
523: M*/
524: #define PetscObjectComposedDataSetIntstar(obj,id,data) \
525: ((((obj)->intstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseIntstar(obj)) || \
526: ((obj)->intstarcomposeddata[id] = data,(obj)->intstarcomposedstate[id] = (obj)->state, 0))
528: /*MC
529: PetscObjectComposedDataGetIntstar - retrieve integer array data
530: attached to an object
532: Synopsis:
533: #include "petsc/private/petscimpl.h"
534: PetscErrorCode PetscObjectComposedDataGetIntstar(PetscObject obj,int id,int *data,PetscBool flag)
536: Not collective
538: Input parameters:
539: + obj - the object from which data is to be retrieved
540: - id - the identifier for the data
542: Output parameters
543: + data - the data to be retrieved
544: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
546: The 'data' and 'flag' variables are inlined, so they are not pointers.
548: Level: developer
549: M*/
550: #define PetscObjectComposedDataGetIntstar(obj,id,data,flag) \
551: ((((obj)->intstarcomposedstate && ((obj)->intstarcomposedstate[id] == (obj)->state)) ? \
552: (data = (obj)->intstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
554: /*MC
555: PetscObjectComposedDataSetReal - attach real data to a PetscObject
557: Synopsis:
558: #include "petsc/private/petscimpl.h"
559: PetscErrorCode PetscObjectComposedDataSetReal(PetscObject obj,int id,PetscReal data)
561: Not collective
563: Input parameters:
564: + obj - the object to which data is to be attached
565: . id - the identifier for the data
566: - data - the data to be attached
568: Notes
569: The data identifier can best be determined through a call to
570: PetscObjectComposedDataRegister()
572: Level: developer
573: M*/
574: #define PetscObjectComposedDataSetReal(obj,id,data) \
575: ((((obj)->real_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseReal(obj)) || \
576: ((obj)->realcomposeddata[id] = data,(obj)->realcomposedstate[id] = (obj)->state, 0))
578: /*MC
579: PetscObjectComposedDataGetReal - retrieve real data attached to an object
581: Synopsis:
582: #include "petsc/private/petscimpl.h"
583: PetscErrorCode PetscObjectComposedDataGetReal(PetscObject obj,int id,PetscReal data,PetscBool flag)
585: Not collective
587: Input parameters:
588: + obj - the object from which data is to be retrieved
589: - id - the identifier for the data
591: Output parameters
592: + data - the data to be retrieved
593: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
595: The 'data' and 'flag' variables are inlined, so they are not pointers.
597: Level: developer
598: M*/
599: #define PetscObjectComposedDataGetReal(obj,id,data,flag) \
600: ((((obj)->realcomposedstate && ((obj)->realcomposedstate[id] == (obj)->state)) ? \
601: (data = (obj)->realcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
603: /*MC
604: PetscObjectComposedDataSetRealstar - attach real array data to a PetscObject
606: Synopsis:
607: #include "petsc/private/petscimpl.h"
608: PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *data)
610: Not collective
612: Input parameters:
613: + obj - the object to which data is to be attached
614: . id - the identifier for the data
615: - data - the data to be attached
617: Notes
618: The data identifier can best be determined through a call to
619: PetscObjectComposedDataRegister()
621: Level: developer
622: M*/
623: #define PetscObjectComposedDataSetRealstar(obj,id,data) \
624: ((((obj)->realstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseRealstar(obj)) || \
625: ((obj)->realstarcomposeddata[id] = data, (obj)->realstarcomposedstate[id] = (obj)->state, 0))
627: /*MC
628: PetscObjectComposedDataGetRealstar - retrieve real array data
629: attached to an object
631: Synopsis:
632: #include "petsc/private/petscimpl.h"
633: PetscErrorCode PetscObjectComposedDataGetRealstar(PetscObject obj,int id,PetscReal *data,PetscBool flag)
635: Not collective
637: Input parameters:
638: + obj - the object from which data is to be retrieved
639: - id - the identifier for the data
641: Output parameters
642: + data - the data to be retrieved
643: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
645: The 'data' and 'flag' variables are inlined, so they are not pointers.
647: Level: developer
648: M*/
649: #define PetscObjectComposedDataGetRealstar(obj,id,data,flag) \
650: ((((obj)->realstarcomposedstate && ((obj)->realstarcomposedstate[id] == (obj)->state)) ? \
651: (data = (obj)->realstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
653: /*MC
654: PetscObjectComposedDataSetScalar - attach scalar data to a PetscObject
656: Synopsis:
657: #include "petsc/private/petscimpl.h"
658: PetscErrorCode PetscObjectComposedDataSetScalar(PetscObject obj,int id,PetscScalar data)
660: Not collective
662: Input parameters:
663: + obj - the object to which data is to be attached
664: . id - the identifier for the data
665: - data - the data to be attached
667: Notes
668: The data identifier can best be determined through a call to
669: PetscObjectComposedDataRegister()
671: Level: developer
672: M*/
673: #if defined(PETSC_USE_COMPLEX)
674: #define PetscObjectComposedDataSetScalar(obj,id,data) \
675: ((((obj)->scalar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalar(obj)) || \
676: ((obj)->scalarcomposeddata[id] = data,(obj)->scalarcomposedstate[id] = (obj)->state, 0))
677: #else
678: #define PetscObjectComposedDataSetScalar(obj,id,data) \
679: PetscObjectComposedDataSetReal(obj,id,data)
680: #endif
681: /*MC
682: PetscObjectComposedDataGetScalar - retrieve scalar data attached to an object
684: Synopsis:
685: #include "petsc/private/petscimpl.h"
686: PetscErrorCode PetscObjectComposedDataGetScalar(PetscObject obj,int id,PetscScalar data,PetscBool flag)
688: Not collective
690: Input parameters:
691: + obj - the object from which data is to be retrieved
692: - id - the identifier for the data
694: Output parameters
695: + data - the data to be retrieved
696: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
698: The 'data' and 'flag' variables are inlined, so they are not pointers.
700: Level: developer
701: M*/
702: #if defined(PETSC_USE_COMPLEX)
703: #define PetscObjectComposedDataGetScalar(obj,id,data,flag) \
704: ((((obj)->scalarcomposedstate && ((obj)->scalarcomposedstate[id] == (obj)->state) ) ? \
705: (data = (obj)->scalarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
706: #else
707: #define PetscObjectComposedDataGetScalar(obj,id,data,flag) \
708: PetscObjectComposedDataGetReal(obj,id,data,flag)
709: #endif
711: /*MC
712: PetscObjectComposedDataSetScalarstar - attach scalar array data to a PetscObject
714: Synopsis:
715: #include "petsc/private/petscimpl.h"
716: PetscErrorCode PetscObjectComposedDataSetScalarstar(PetscObject obj,int id,PetscScalar *data)
718: Not collective
720: Input parameters:
721: + obj - the object to which data is to be attached
722: . id - the identifier for the data
723: - data - the data to be attached
725: Notes
726: The data identifier can best be determined through a call to
727: PetscObjectComposedDataRegister()
729: Level: developer
730: M*/
731: #if defined(PETSC_USE_COMPLEX)
732: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
733: ((((obj)->scalarstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalarstar(obj)) || \
734: ((obj)->scalarstarcomposeddata[id] = data,(obj)->scalarstarcomposedstate[id] = (obj)->state, 0))
735: #else
736: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
737: PetscObjectComposedDataSetRealstar(obj,id,data)
738: #endif
739: /*MC
740: PetscObjectComposedDataGetScalarstar - retrieve scalar array data
741: attached to an object
743: Synopsis:
744: #include "petsc/private/petscimpl.h"
745: PetscErrorCode PetscObjectComposedDataGetScalarstar(PetscObject obj,int id,PetscScalar *data,PetscBool flag)
747: Not collective
749: Input parameters:
750: + obj - the object from which data is to be retrieved
751: - id - the identifier for the data
753: Output parameters
754: + data - the data to be retrieved
755: - flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise
757: The 'data' and 'flag' variables are inlined, so they are not pointers.
759: Level: developer
760: M*/
761: #if defined(PETSC_USE_COMPLEX)
762: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag) \
763: ((((obj)->scalarstarcomposedstate && ((obj)->scalarstarcomposedstate[id] == (obj)->state)) ? \
764: (data = (obj)->scalarstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
765: #else
766: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag) \
767: PetscObjectComposedDataGetRealstar(obj,id,data,flag)
768: #endif
770: PETSC_EXTERN PetscErrorCode PetscObjectGetId(PetscObject,PetscObjectId*);
772: PETSC_EXTERN PetscErrorCode PetscMonitorCompare(PetscErrorCode (*)(void),void *,PetscErrorCode (*)(void**),PetscErrorCode (*)(void),void *,PetscErrorCode (*)(void**),PetscBool *);
774: PETSC_EXTERN PetscMPIInt Petsc_Counter_keyval;
775: PETSC_EXTERN PetscMPIInt Petsc_InnerComm_keyval;
776: PETSC_EXTERN PetscMPIInt Petsc_OuterComm_keyval;
777: PETSC_EXTERN PetscMPIInt Petsc_Seq_keyval;
779: /*
780: PETSc communicators have this attribute, see
781: PetscCommDuplicate(), PetscCommDestroy(), PetscCommGetNewTag(), PetscObjectGetName()
782: */
783: typedef struct {
784: PetscMPIInt tag; /* next free tag value */
785: PetscInt refcount; /* number of references, communicator can be freed when this reaches 0 */
786: PetscInt namecount; /* used to generate the next name, as in Vec_0, Mat_1, ... */
787: } PetscCommCounter;
789: #if defined(PETSC_HAVE_CUSP)
790: /*E
791: PetscCUSPFlag - indicates which memory (CPU, GPU, or none contains valid vector
793: PETSC_CUSP_UNALLOCATED - no memory contains valid matrix entries; NEVER used for vectors
794: PETSC_CUSP_GPU - GPU has valid vector/matrix entries
795: PETSC_CUSP_CPU - CPU has valid vector/matrix entries
796: PETSC_CUSP_BOTH - Both GPU and CPU have valid vector/matrix entries and they match
798: Level: developer
799: E*/
800: typedef enum {PETSC_CUSP_UNALLOCATED,PETSC_CUSP_GPU,PETSC_CUSP_CPU,PETSC_CUSP_BOTH} PetscCUSPFlag;
801: #elif defined(PETSC_HAVE_VIENNACL)
802: /*E
803: PetscViennaCLFlag - indicates which memory (CPU, GPU, or none contains valid vector
805: PETSC_VIENNACL_UNALLOCATED - no memory contains valid matrix entries; NEVER used for vectors
806: PETSC_VIENNACL_GPU - GPU has valid vector/matrix entries
807: PETSC_VIENNACL_CPU - CPU has valid vector/matrix entries
808: PETSC_VIENNACL_BOTH - Both GPU and CPU have valid vector/matrix entries and they match
810: Level: developer
811: E*/
812: typedef enum {PETSC_VIENNACL_UNALLOCATED,PETSC_VIENNACL_GPU,PETSC_VIENNACL_CPU,PETSC_VIENNACL_BOTH} PetscViennaCLFlag;
813: #elif defined(PETSC_HAVE_VECCUDA)
814: /*E
815: PetscCUDAFlag - indicates which memory (CPU, GPU, or none contains valid vector
817: PETSC_CUDA_UNALLOCATED - no memory contains valid matrix entries; NEVER used for vectors
818: PETSC_CUDA_GPU - GPU has valid vector/matrix entries
819: PETSC_CUDA_CPU - CPU has valid vector/matrix entries
820: PETSC_CUDA_BOTH - Both GPU and CPU have valid vector/matrix entries and they match
822: Level: developer
823: E*/
824: typedef enum {PETSC_CUDA_UNALLOCATED,PETSC_CUDA_GPU,PETSC_CUDA_CPU,PETSC_CUDA_BOTH} PetscCUDAFlag;
825: #endif
827: #if defined(PETSC_HAVE_CUSP) || defined(PETSC_HAVE_VECCUDA)
828: PETSC_EXTERN cublasHandle_t cublasv2handle;
829: #endif
831: typedef enum {STATE_BEGIN, STATE_PENDING, STATE_END} SRState;
833: #define REDUCE_SUM 0
834: #define REDUCE_MAX 1
835: #define REDUCE_MIN 2
837: typedef struct {
838: MPI_Comm comm;
839: MPI_Request request;
840: PetscBool async;
841: PetscScalar *lvalues; /* this are the reduced values before call to MPI_Allreduce() */
842: PetscScalar *gvalues; /* values after call to MPI_Allreduce() */
843: void **invecs; /* for debugging only, vector/memory used with each op */
844: PetscInt *reducetype; /* is particular value to be summed or maxed? */
845: SRState state; /* are we calling xxxBegin() or xxxEnd()? */
846: PetscInt maxops; /* total amount of space we have for requests */
847: PetscInt numopsbegin; /* number of requests that have been queued in */
848: PetscInt numopsend; /* number of requests that have been gotten by user */
849: } PetscSplitReduction;
851: PETSC_EXTERN PetscErrorCode PetscSplitReductionGet(MPI_Comm,PetscSplitReduction**);
852: PETSC_EXTERN PetscErrorCode PetscSplitReductionEnd(PetscSplitReduction*);
853: PETSC_EXTERN PetscErrorCode PetscSplitReductionExtend(PetscSplitReduction*);
855: #if !defined(PETSC_SKIP_SPINLOCK)
856: #if defined(PETSC_HAVE_THREADSAFETY)
857: # if defined(PETSC_HAVE_CONCURRENCYKIT)
858: #if defined(__cplusplus)
859: /* CK does not have extern "C" protection in their include files */
860: extern "C" {
861: #endif
862: #include <ck_spinlock.h>
863: #if defined(__cplusplus)
864: }
865: #endif
866: typedef ck_spinlock_t PetscSpinlock;
867: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockCreate(PetscSpinlock *ck_spinlock)
868: {
869: ck_spinlock_init(ck_spinlock);
870: return 0;
871: }
872: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockLock(PetscSpinlock *ck_spinlock)
873: {
874: ck_spinlock_lock(ck_spinlock);
875: return 0;
876: }
877: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *ck_spinlock)
878: {
879: ck_spinlock_unlock(ck_spinlock);
880: return 0;
881: }
882: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *ck_spinlock)
883: {
884: return 0;
885: }
886: # elif defined(PETSC_HAVE_OPENMP)
888: #include <omp.h>
889: typedef omp_lock_t PetscSpinlock;
890: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockCreate(PetscSpinlock *omp_lock)
891: {
892: omp_init_lock(omp_lock);
893: return 0;
894: }
895: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockLock(PetscSpinlock *omp_lock)
896: {
897: omp_set_lock(omp_lock);
898: return 0;
899: }
900: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *omp_lock)
901: {
902: omp_unset_lock(omp_lock);
903: return 0;
904: }
905: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *omp_lock)
906: {
907: omp_destroy_lock(omp_lock);
908: return 0;
909: }
910: #else
911: Thread safety requires either --with-openmp or --download-concurrencykit
912: #endif
914: #else
915: typedef int PetscSpinlock;
916: #define PetscSpinlockCreate(a) 0
917: #define PetscSpinlockLock(a) 0
918: #define PetscSpinlockUnlock(a) 0
919: #define PetscSpinlockDestroy(a) 0
920: #endif
922: #if defined(PETSC_HAVE_THREADSAFETY)
923: extern PetscSpinlock PetscViewerASCIISpinLockOpen;
924: extern PetscSpinlock PetscViewerASCIISpinLockStdout;
925: extern PetscSpinlock PetscViewerASCIISpinLockStderr;
926: extern PetscSpinlock PetscCommSpinLock;
927: #endif
928: #endif
930: #endif /* _PETSCHEAD_H */