Actual source code: petscimpl.h

petsc-master 2019-05-25
Report Typos and Errors

  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 PetscVFPrintfDefault(FILE*,const char[],va_list);

 14: #if defined(PETSC_HAVE_CLOSURES)
 15: PETSC_EXTERN PetscErrorCode PetscVFPrintfSetClosure(int (^)(const char*));
 16: #endif


 19: #if defined(PETSC_HAVE_CUDA)
 20: #include <cuda.h>
 21: #include <cublas_v2.h>
 22: #endif

 24: /*
 25:    All major PETSc data structures have a common core; this is defined
 26:    below by PETSCHEADER.

 28:    PetscHeaderCreate() should be used whenever creating a PETSc structure.
 29: */

 31: /*
 32:    PetscOps: structure of core operations that all PETSc objects support.

 34:       getcomm()         - Gets the object's communicator.
 35:       view()            - Is the routine for viewing the entire PETSc object; for
 36:                           example, MatView() is the general matrix viewing routine.
 37:                           This is used by PetscObjectView((PetscObject)obj) to allow
 38:                           viewing any PETSc object.
 39:       destroy()         - Is the routine for destroying the entire PETSc object;
 40:                           for example,MatDestroy() is the general matrix
 41:                           destruction routine.
 42:                           This is used by PetscObjectDestroy((PetscObject*)&obj) to allow
 43:                           destroying any PETSc object.
 44:       compose()         - Associates a PETSc object with another PETSc object with a name
 45:       query()           - Returns a different PETSc object that has been associated
 46:                           with the first object using a name.
 47:       composefunction() - Attaches an a function to a PETSc object with a name.
 48:       queryfunction()   - Requests a registered function that has been attached to a PETSc object.
 49: */

 51: typedef struct {
 52:    PetscErrorCode (*getcomm)(PetscObject,MPI_Comm *);
 53:    PetscErrorCode (*view)(PetscObject,PetscViewer);
 54:    PetscErrorCode (*destroy)(PetscObject*);
 55:    PetscErrorCode (*compose)(PetscObject,const char[],PetscObject);
 56:    PetscErrorCode (*query)(PetscObject,const char[],PetscObject *);
 57:    PetscErrorCode (*composefunction)(PetscObject,const char[],void (*)(void));
 58:    PetscErrorCode (*queryfunction)(PetscObject,const char[],void (**)(void));
 59: } PetscOps;

 61: typedef enum {PETSC_FORTRAN_CALLBACK_CLASS,PETSC_FORTRAN_CALLBACK_SUBTYPE,PETSC_FORTRAN_CALLBACK_MAXTYPE} PetscFortranCallbackType;
 62: typedef int PetscFortranCallbackId;
 63: #define PETSC_SMALLEST_FORTRAN_CALLBACK ((PetscFortranCallbackId)1000)
 64: PETSC_EXTERN PetscErrorCode PetscFortranCallbackRegister(PetscClassId,const char*,PetscFortranCallbackId*);
 65: PETSC_EXTERN PetscErrorCode PetscFortranCallbackGetSizes(PetscClassId,PetscInt*,PetscInt*);

 67: typedef struct {
 68:   void (*func)(void);
 69:   void *ctx;
 70: } PetscFortranCallback;

 72: /*
 73:    All PETSc objects begin with the fields defined in PETSCHEADER.
 74:    The PetscObject is a way of examining these fields regardless of
 75:    the specific object. In C++ this could be a base abstract class
 76:    from which all objects are derived.
 77: */
 78: #define PETSC_MAX_OPTIONS_HANDLER 5
 79: typedef struct _p_PetscObject {
 80:   PetscClassId         classid;
 81:   PetscOps             bops[1];
 82:   MPI_Comm             comm;
 83:   PetscInt             type;
 84:   PetscLogDouble       flops,time,mem,memchildren;
 85:   PetscObjectId        id;
 86:   PetscInt             refct;
 87:   PetscMPIInt          tag;
 88:   PetscFunctionList    qlist;
 89:   PetscObjectList      olist;
 90:   char                 *class_name;    /*  for example, "Vec" */
 91:   char                 *description;
 92:   char                 *mansec;
 93:   char                 *type_name;     /*  this is the subclass, for example VECSEQ which equals "seq" */
 94:   PetscObject          parent;
 95:   PetscObjectId        parentid;
 96:   char*                name;
 97:   char                 *prefix;
 98:   PetscInt             tablevel;
 99:   void                 *cpp;
100:   PetscObjectState     state;
101:   PetscInt             int_idmax,        intstar_idmax;
102:   PetscObjectState     *intcomposedstate,*intstarcomposedstate;
103:   PetscInt             *intcomposeddata, **intstarcomposeddata;
104:   PetscInt             real_idmax,        realstar_idmax;
105:   PetscObjectState     *realcomposedstate,*realstarcomposedstate;
106:   PetscReal            *realcomposeddata, **realstarcomposeddata;
107:   PetscInt             scalar_idmax,        scalarstar_idmax;
108:   PetscObjectState     *scalarcomposedstate,*scalarstarcomposedstate;
109:   PetscScalar          *scalarcomposeddata, **scalarstarcomposeddata;
110:   void                 (**fortran_func_pointers)(void);                  /* used by Fortran interface functions to stash user provided Fortran functions */
111:   PetscInt             num_fortran_func_pointers;                        /* number of Fortran function pointers allocated */
112:   PetscFortranCallback *fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
113:   PetscInt             num_fortrancallback[PETSC_FORTRAN_CALLBACK_MAXTYPE];
114:   void                 *python_context;
115:   PetscErrorCode       (*python_destroy)(void*);

117:   PetscInt             noptionhandler;
118:   PetscErrorCode       (*optionhandler[PETSC_MAX_OPTIONS_HANDLER])(PetscOptionItems*,PetscObject,void*);
119:   PetscErrorCode       (*optiondestroy[PETSC_MAX_OPTIONS_HANDLER])(PetscObject,void*);
120:   void                 *optionctx[PETSC_MAX_OPTIONS_HANDLER];
121:   PetscBool            optionsprinted;
122: #if defined(PETSC_HAVE_SAWS)
123:   PetscBool            amsmem;          /* if PETSC_TRUE then this object is registered with SAWs and visible to clients */
124:   PetscBool            amspublishblock; /* if PETSC_TRUE and publishing objects then will block at PetscObjectSAWsBlock() */
125: #endif
126:   PetscOptions         options;         /* options database used, NULL means default */
127:   PetscBool            donotPetscObjectPrintClassNamePrefixType;
128: } _p_PetscObject;

130: #define PETSCHEADER(ObjectOps) \
131:   _p_PetscObject hdr;          \
132:   ObjectOps      ops[1]

134: #define  PETSCFREEDHEADER -1

136: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectDestroyFunction)(PetscObject*); /* force cast in next macro to NEVER use extern "C" style */
137: PETSC_EXTERN_TYPEDEF typedef PetscErrorCode (*PetscObjectViewFunction)(PetscObject,PetscViewer);

139: /*@C
140:     PetscHeaderCreate - Creates a PETSc object of a particular class

142:     Input Parameters:
143: +   classid - the classid associated with this object (for example VEC_CLASSID)
144: .   class_name - string name of class; should be static (for example "Vec")
145: .   descr - string containing short description; should be static (for example "Vector")
146: .   mansec - string indicating section in manual pages; should be static (for example "Vec")
147: .   comm - the MPI Communicator
148: .   destroy - the destroy routine for this object (for example VecDestroy())
149: -   view - the view routine for this object (for example VecView())

151:     Output Parameter:
152: .   h - the newly created object

154:     Level: developer

156: .seealso: PetscHeaderDestroy(), PetscClassIdRegister()

158: @*/
159: #define PetscHeaderCreate(h,classid,class_name,descr,mansec,comm,destroy,view) \
160:   (PetscNew(&(h)) || \
161:    PetscHeaderCreate_Private((PetscObject)h,classid,class_name,descr,mansec,comm,(PetscObjectDestroyFunction)destroy,(PetscObjectViewFunction)view) || \
162:    PetscLogObjectCreate(h) || \
163:    PetscLogObjectMemory((PetscObject)h,sizeof(*(h))))

165: PETSC_EXTERN PetscErrorCode PetscComposedQuantitiesDestroy(PetscObject obj);
166: PETSC_EXTERN PetscErrorCode PetscHeaderCreate_Private(PetscObject,PetscClassId,const char[],const char[],const char[],MPI_Comm,PetscObjectDestroyFunction,PetscObjectViewFunction);

168: /*@C
169:     PetscHeaderDestroy - Final step in destroying a PetscObject

171:     Input Parameters:
172: .   h - the header created with PetscHeaderCreate()

174:     Level: developer

176: .seealso: PetscHeaderCreate()
177: @*/
178: #define PetscHeaderDestroy(h) (PetscHeaderDestroy_Private((PetscObject)(*h)) || PetscFree(*h))

180: PETSC_EXTERN PetscErrorCode PetscHeaderDestroy_Private(PetscObject);
181: PETSC_EXTERN PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject,PetscObject);
182: PETSC_EXTERN PetscErrorCode PetscObjectSetFortranCallback(PetscObject,PetscFortranCallbackType,PetscFortranCallbackId*,void(*)(void),void *ctx);
183: PETSC_EXTERN PetscErrorCode PetscObjectGetFortranCallback(PetscObject,PetscFortranCallbackType,PetscFortranCallbackId,void(**)(void),void **ctx);

185: PETSC_INTERN PetscErrorCode PetscCitationsInitialize(void);
186: PETSC_INTERN PetscErrorCode PetscFreeMPIResources(void);




192: /*
193:     Macros to test if a PETSc object is valid and if pointers are valid
194: */
195: #if !defined(PETSC_USE_DEBUG)


207: #else

209: /*  This check is for subtype methods such as DMDAGetCorners() that do not use the PetscTryMethod() or PetscUseMethod() paradigm */
211:   do {   \
212:     PetscErrorCode __ierr; \
213:     PetscBool      same; \
215:     __PetscObjectTypeCompare((PetscObject)h,t,&same);CHKERRQ(__ierr);      \
216:     if (!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); \
217:   } while (0)

220:   do {                                                                  \
221:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg); \
223:     if (((PetscObject)(h))->classid != ck) {                            \
224:       if (((PetscObject)(h))->classid == PETSCFREEDHEADER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
225:       else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Wrong type of object: Parameter # %d",arg); \
226:     }                                                                   \
227:   } while (0)

230:   do {                                                                  \
231:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Object: Parameter # %d",arg); \
233:     if (((PetscObject)(h))->classid == PETSCFREEDHEADER) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"Object already free: Parameter # %d",arg); \
234:     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); \
235:   } while (0)

238:   do {                                                                  \
239:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
241:   } while (0)

244:   do {                                                                  \
245:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg);\
247:   } while (0)

250:   do {                                                                  \
251:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_BADPTR,"Null Pointer: Parameter # %d",arg); \
253:   } while (0)

256:   do {                                                                  \
257:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
259:   } while (0)

262:   do {                                                                  \
263:     if (!h) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Pointer: Parameter # %d",arg); \
265:   } while (0)

268:   do {                                                                  \
269:     if (!f) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Null Function Pointer: Parameter # %d",arg); \
270:   } while (0)

272: #endif

274: #if !defined(PETSC_USE_DEBUG)


289: #else

291: /*
292:     For example, in the dot product between two vectors,
293:   both vectors must be either Seq or MPI, not one of each
294: */
296:   do {                                                                  \
297:     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); \
298:   } while (0)
299: /*
300:     Check type_name
301: */
303:   do {                                                                  \
304:     PetscBool      __match;                                             \
305:     PetscErrorCode _7_ierr;                                             \
306:     _7_PetscObjectTypeCompare(((PetscObject)a),(type),&__match);CHKERRQ(_7_ierr); \
307:     if (!__match) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Object (%s) is not %s",(char*)(((PetscObject)a)->type_name),type); \
308:   } while (0)

311:   do {                                                                  \
312:     PetscBool       __match;                                            \
313:     PetscErrorCode _7_ierr;                                             \
314:     _7_PetscObjectTypeCompareAny(((PetscObject)a),&__match,(type1),(type2),"");CHKERRQ(_7_ierr); \
315:     if (!__match) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Object (%s) is not %s or %s",(char*)(((PetscObject)a)->type_name),type1,type2); \
316:   } while (0)
317: /*
318:    Use this macro to check if the type is set
319: */
321:   do {                                                                  \
322:     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); \
323:   } while (0)
324: /*
325:    Sometimes object must live on same communicator to inter-operate
326: */
328:   do {                                                                  \
329:     PetscErrorCode _6_ierr,__flag;                                      \
330:     _6_MPI_Comm_compare(PetscObjectComm((PetscObject)a),PetscObjectComm((PetscObject)b),&__flag);CHKERRQ(_6_ierr);                                                   \
331:     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); \
332:   } while (0)

335:   do {                                                  \
338:   } while (0)

341:   do {                                                                  \
342:     PetscErrorCode _7_ierr;                                             \
343:     PetscReal b1[5],b2[5];                                              \
344:     if (PetscIsNanScalar(b)) {b1[4] = 1;} else {b1[4] = 0;};            \
345:     b1[0] = -PetscRealPart(b); b1[1] = PetscRealPart(b);b1[2] = -PetscImaginaryPart(b); b1[3] = PetscImaginaryPart(b);         \
346:     _7_MPI_Allreduce(b1,b2,5,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
347:     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); \
348:   } while (0)

351:   do {                                                                  \
352:     PetscErrorCode _7_ierr;                                             \
353:     PetscReal b1[3],b2[3];                                              \
354:     if (PetscIsNanReal(b)) {b1[2] = 1;} else {b1[2] = 0;};              \
355:     b1[0] = -b; b1[1] = b;                                              \
356:     _7_MPI_Allreduce(b1,b2,3,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
357:     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); \
358:   } while (0)

361:   do {                                                                  \
362:     PetscErrorCode _7_ierr;                                             \
363:     PetscInt b1[2],b2[2];                                               \
364:     b1[0] = -b; b1[1] = b;                                              \
365:     _7_MPIU_Allreduce(b1,b2,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
366:     if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)a),PETSC_ERR_ARG_WRONG,"Int value must be same on all processes, argument # %d",c); \
367:   } 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,"Bool value must be same on all processes, argument # %d",c); \
378:   } while (0)

381:   do {                                                                  \
382:     PetscErrorCode _7_ierr;                                             \
383:     PetscMPIInt b1[2],b2[2];                                            \
384:     b1[0] = -(PetscMPIInt)b; b1[1] = (PetscMPIInt)b;                    \
385:     _7_MPIU_Allreduce(b1,b2,2,MPI_INT,MPI_MAX,PetscObjectComm((PetscObject)a));CHKERRQ(_7_ierr); \
386:     if (-b2[0] != b2[1]) SETERRQ1(PetscObjectComm((PetscObject)a),PETSC_ERR_ARG_WRONG,"Enum value must be same on all processes, argument # %d",c); \
387:   } while (0)

389: #endif

391: /*
392:    PetscTryMethod - Queries an object for a method, if it exists then calls it.
393:               These are intended to be used only inside PETSc functions.

395:    Level: developer

397: .seealso: PetscUseMethod()
398: */
399: #define  PetscTryMethod(obj,A,B,C) \
400:   0; do { PetscErrorCode (*f)B, __ierr; \
401:     __PetscObjectQueryFunction((PetscObject)obj,A,&f);CHKERRQ(__ierr); \
402:     if (f) {__(*f)C;CHKERRQ(__ierr);} \
403:   } while(0)

405: /*
406:    PetscUseMethod - Queries an object for a method, if it exists then calls it, otherwise generates an error.
407:               These are intended to be used only inside PETSc functions.

409:    Level: developer

411: .seealso: PetscTryMethod()
412: */
413: #define  PetscUseMethod(obj,A,B,C) \
414:   0; do { PetscErrorCode (*f)B, __ierr; \
415:     __PetscObjectQueryFunction((PetscObject)obj,A,&f);CHKERRQ(__ierr); \
416:     if (f) {__(*f)C;CHKERRQ(__ierr);} \
417:     else SETERRQ1(PetscObjectComm((PetscObject)obj),PETSC_ERR_SUP,"Cannot locate function %s in object",A); \
418:   } while(0)

420: /*MC
421:    PetscObjectStateIncrease - Increases the state of any PetscObject

423:    Synopsis:
424:    #include "petsc/private/petscimpl.h"
425:    PetscErrorCode PetscObjectStateIncrease(PetscObject obj)

427:    Logically Collective

429:    Input Parameter:
430: .  obj - any PETSc object, for example a Vec, Mat or KSP. This must be
431:          cast with a (PetscObject), for example,
432:          PetscObjectStateIncrease((PetscObject)mat);

434:    Notes:
435:     object state is an integer which gets increased every time
436:    the object is changed internally. By saving and later querying the object state
437:    one can determine whether information about the object is still current.
438:    Currently, state is maintained for Vec and Mat objects.

440:    This routine is mostly for internal use by PETSc; a developer need only
441:    call it after explicit access to an object's internals. Routines such
442:    as VecSet() or MatScale() already call this routine. It is also called, as a
443:    precaution, in VecRestoreArray(), MatRestoreRow(), MatDenseRestoreArray().

445:    This routine is logically collective because state equality comparison needs to be possible without communication.

447:    Level: developer

449:    seealso: PetscObjectStateGet()

451:    Concepts: state

453: M*/
454: #define PetscObjectStateIncrease(obj) ((obj)->state++,0)

456: PETSC_EXTERN PetscErrorCode PetscObjectStateGet(PetscObject,PetscObjectState*);
457: PETSC_EXTERN PetscErrorCode PetscObjectStateSet(PetscObject,PetscObjectState);
458: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataRegister(PetscInt*);
459: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject);
460: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject);
461: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject);
462: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject);
463: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject);
464: PETSC_EXTERN PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject);
465: PETSC_EXTERN PetscInt         PetscObjectComposedDataMax;
466: /*MC
467:    PetscObjectComposedDataSetInt - attach integer data to a PetscObject

469:    Synopsis:
470:    #include "petsc/private/petscimpl.h"
471:    PetscErrorCode PetscObjectComposedDataSetInt(PetscObject obj,int id,int data)

473:    Not collective

475:    Input parameters:
476: +  obj - the object to which data is to be attached
477: .  id - the identifier for the data
478: -  data - the data to  be attached

480:    Notes
481:    The data identifier can best be created through a call to  PetscObjectComposedDataRegister()

483:    Level: developer
484: M*/
485: #define PetscObjectComposedDataSetInt(obj,id,data)                                      \
486:   ((((obj)->int_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseInt(obj)) ||  \
487:    ((obj)->intcomposeddata[id] = data,(obj)->intcomposedstate[id] = (obj)->state, 0))

489: /*MC
490:    PetscObjectComposedDataGetInt - retrieve integer data attached to an object

492:    Synopsis:
493:    #include "petsc/private/petscimpl.h"
494:    PetscErrorCode PetscObjectComposedDataGetInt(PetscObject obj,int id,int data,PetscBool  flag)

496:    Not collective

498:    Input parameters:
499: +  obj - the object from which data is to be retrieved
500: -  id - the identifier for the data

502:    Output parameters
503: +  data - the data to be retrieved
504: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

506:    The 'data' and 'flag' variables are inlined, so they are not pointers.

508:    Level: developer
509: M*/
510: #define PetscObjectComposedDataGetInt(obj,id,data,flag)                            \
511:   ((((obj)->intcomposedstate && ((obj)->intcomposedstate[id] == (obj)->state)) ?   \
512:    (data = (obj)->intcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

514: /*MC
515:    PetscObjectComposedDataSetIntstar - attach integer array data to a PetscObject

517:    Synopsis:
518:    #include "petsc/private/petscimpl.h"
519:    PetscErrorCode PetscObjectComposedDataSetIntstar(PetscObject obj,int id,int *data)

521:    Not collective

523:    Input parameters:
524: +  obj - the object to which data is to be attached
525: .  id - the identifier for the data
526: -  data - the data to  be attached

528:    Notes
529:    The data identifier can best be determined through a call to
530:    PetscObjectComposedDataRegister()

532:    Level: developer
533: M*/
534: #define PetscObjectComposedDataSetIntstar(obj,id,data)                                          \
535:   ((((obj)->intstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseIntstar(obj)) ||  \
536:    ((obj)->intstarcomposeddata[id] = data,(obj)->intstarcomposedstate[id] = (obj)->state, 0))

538: /*MC
539:    PetscObjectComposedDataGetIntstar - retrieve integer array data
540:    attached to an object

542:    Synopsis:
543:    #include "petsc/private/petscimpl.h"
544:    PetscErrorCode PetscObjectComposedDataGetIntstar(PetscObject obj,int id,int *data,PetscBool  flag)

546:    Not collective

548:    Input parameters:
549: +  obj - the object from which data is to be retrieved
550: -  id - the identifier for the data

552:    Output parameters
553: +  data - the data to be retrieved
554: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

556:    The 'data' and 'flag' variables are inlined, so they are not pointers.

558:    Level: developer
559: M*/
560: #define PetscObjectComposedDataGetIntstar(obj,id,data,flag)                               \
561:   ((((obj)->intstarcomposedstate && ((obj)->intstarcomposedstate[id] == (obj)->state)) ?  \
562:    (data = (obj)->intstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

564: /*MC
565:    PetscObjectComposedDataSetReal - attach real data to a PetscObject

567:    Synopsis:
568:    #include "petsc/private/petscimpl.h"
569:    PetscErrorCode PetscObjectComposedDataSetReal(PetscObject obj,int id,PetscReal data)

571:    Not collective

573:    Input parameters:
574: +  obj - the object to which data is to be attached
575: .  id - the identifier for the data
576: -  data - the data to  be attached

578:    Notes
579:    The data identifier can best be determined through a call to
580:    PetscObjectComposedDataRegister()

582:    Level: developer
583: M*/
584: #define PetscObjectComposedDataSetReal(obj,id,data)                                       \
585:   ((((obj)->real_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseReal(obj)) ||  \
586:    ((obj)->realcomposeddata[id] = data,(obj)->realcomposedstate[id] = (obj)->state, 0))

588: /*MC
589:    PetscObjectComposedDataGetReal - retrieve real data attached to an object

591:    Synopsis:
592:    #include "petsc/private/petscimpl.h"
593:    PetscErrorCode PetscObjectComposedDataGetReal(PetscObject obj,int id,PetscReal data,PetscBool  flag)

595:    Not collective

597:    Input parameters:
598: +  obj - the object from which data is to be retrieved
599: -  id - the identifier for the data

601:    Output parameters
602: +  data - the data to be retrieved
603: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

605:    The 'data' and 'flag' variables are inlined, so they are not pointers.

607:    Level: developer
608: M*/
609: #define PetscObjectComposedDataGetReal(obj,id,data,flag)                            \
610:   ((((obj)->realcomposedstate && ((obj)->realcomposedstate[id] == (obj)->state)) ?  \
611:    (data = (obj)->realcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

613: /*MC
614:    PetscObjectComposedDataSetRealstar - attach real array data to a PetscObject

616:    Synopsis:
617:    #include "petsc/private/petscimpl.h"
618:    PetscErrorCode PetscObjectComposedDataSetRealstar(PetscObject obj,int id,PetscReal *data)

620:    Not collective

622:    Input parameters:
623: +  obj - the object to which data is to be attached
624: .  id - the identifier for the data
625: -  data - the data to  be attached

627:    Notes
628:    The data identifier can best be determined through a call to
629:    PetscObjectComposedDataRegister()

631:    Level: developer
632: M*/
633: #define PetscObjectComposedDataSetRealstar(obj,id,data)                                           \
634:   ((((obj)->realstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseRealstar(obj)) ||  \
635:    ((obj)->realstarcomposeddata[id] = data, (obj)->realstarcomposedstate[id] = (obj)->state, 0))

637: /*MC
638:    PetscObjectComposedDataGetRealstar - retrieve real array data
639:    attached to an object

641:    Synopsis:
642:    #include "petsc/private/petscimpl.h"
643:    PetscErrorCode PetscObjectComposedDataGetRealstar(PetscObject obj,int id,PetscReal *data,PetscBool  flag)

645:    Not collective

647:    Input parameters:
648: +  obj - the object from which data is to be retrieved
649: -  id - the identifier for the data

651:    Output parameters
652: +  data - the data to be retrieved
653: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

655:    The 'data' and 'flag' variables are inlined, so they are not pointers.

657:    Level: developer
658: M*/
659: #define PetscObjectComposedDataGetRealstar(obj,id,data,flag)                                \
660:   ((((obj)->realstarcomposedstate && ((obj)->realstarcomposedstate[id] == (obj)->state)) ?  \
661:    (data = (obj)->realstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)

663: /*MC
664:    PetscObjectComposedDataSetScalar - attach scalar data to a PetscObject

666:    Synopsis:
667:    #include "petsc/private/petscimpl.h"
668:    PetscErrorCode PetscObjectComposedDataSetScalar(PetscObject obj,int id,PetscScalar data)

670:    Not collective

672:    Input parameters:
673: +  obj - the object to which data is to be attached
674: .  id - the identifier for the data
675: -  data - the data to  be attached

677:    Notes
678:    The data identifier can best be determined through a call to
679:    PetscObjectComposedDataRegister()

681:    Level: developer
682: M*/
683: #if defined(PETSC_USE_COMPLEX)
684: #define PetscObjectComposedDataSetScalar(obj,id,data)                                        \
685:   ((((obj)->scalar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalar(obj)) || \
686:    ((obj)->scalarcomposeddata[id] = data,(obj)->scalarcomposedstate[id] = (obj)->state, 0))
687: #else
688: #define PetscObjectComposedDataSetScalar(obj,id,data) \
689:         PetscObjectComposedDataSetReal(obj,id,data)
690: #endif
691: /*MC
692:    PetscObjectComposedDataGetScalar - retrieve scalar data attached to an object

694:    Synopsis:
695:    #include "petsc/private/petscimpl.h"
696:    PetscErrorCode PetscObjectComposedDataGetScalar(PetscObject obj,int id,PetscScalar data,PetscBool  flag)

698:    Not collective

700:    Input parameters:
701: +  obj - the object from which data is to be retrieved
702: -  id - the identifier for the data

704:    Output parameters
705: +  data - the data to be retrieved
706: -  flag - PETSC_TRUE if the data item exists and is valid, PETSC_FALSE otherwise

708:    The 'data' and 'flag' variables are inlined, so they are not pointers.

710:    Level: developer
711: M*/
712: #if defined(PETSC_USE_COMPLEX)
713: #define PetscObjectComposedDataGetScalar(obj,id,data,flag)                              \
714:   ((((obj)->scalarcomposedstate && ((obj)->scalarcomposedstate[id] == (obj)->state) ) ? \
715:    (data = (obj)->scalarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
716: #else
717: #define PetscObjectComposedDataGetScalar(obj,id,data,flag)                             \
718:         PetscObjectComposedDataGetReal(obj,id,data,flag)
719: #endif

721: /*MC
722:    PetscObjectComposedDataSetScalarstar - attach scalar array data to a PetscObject

724:    Synopsis:
725:    #include "petsc/private/petscimpl.h"
726:    PetscErrorCode PetscObjectComposedDataSetScalarstar(PetscObject obj,int id,PetscScalar *data)

728:    Not collective

730:    Input parameters:
731: +  obj - the object to which data is to be attached
732: .  id - the identifier for the data
733: -  data - the data to  be attached

735:    Notes
736:    The data identifier can best be determined through a call to
737:    PetscObjectComposedDataRegister()

739:    Level: developer
740: M*/
741: #if defined(PETSC_USE_COMPLEX)
742: #define PetscObjectComposedDataSetScalarstar(obj,id,data)                                             \
743:   ((((obj)->scalarstar_idmax < PetscObjectComposedDataMax) && PetscObjectComposedDataIncreaseScalarstar(obj)) ||  \
744:    ((obj)->scalarstarcomposeddata[id] = data,(obj)->scalarstarcomposedstate[id] = (obj)->state, 0))
745: #else
746: #define PetscObjectComposedDataSetScalarstar(obj,id,data) \
747:         PetscObjectComposedDataSetRealstar(obj,id,data)
748: #endif
749: /*MC
750:    PetscObjectComposedDataGetScalarstar - retrieve scalar array data
751:    attached to an object

753:    Synopsis:
754:    #include "petsc/private/petscimpl.h"
755:    PetscErrorCode PetscObjectComposedDataGetScalarstar(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 PetscObjectComposedDataGetScalarstar(obj,id,data,flag)                                 \
773:   ((((obj)->scalarstarcomposedstate && ((obj)->scalarstarcomposedstate[id] == (obj)->state)) ? \
774:        (data = (obj)->scalarstarcomposeddata[id],flag = PETSC_TRUE) : (flag = PETSC_FALSE)),0)
775: #else
776: #define PetscObjectComposedDataGetScalarstar(obj,id,data,flag)         \
777:         PetscObjectComposedDataGetRealstar(obj,id,data,flag)
778: #endif

780: PETSC_EXTERN PetscErrorCode PetscObjectGetId(PetscObject,PetscObjectId*);

782: PETSC_EXTERN PetscErrorCode PetscMonitorCompare(PetscErrorCode (*)(void),void *,PetscErrorCode (*)(void**),PetscErrorCode (*)(void),void *,PetscErrorCode (*)(void**),PetscBool *);

784: PETSC_EXTERN PetscMPIInt Petsc_Counter_keyval;
785: PETSC_EXTERN PetscMPIInt Petsc_InnerComm_keyval;
786: PETSC_EXTERN PetscMPIInt Petsc_OuterComm_keyval;
787: PETSC_EXTERN PetscMPIInt Petsc_Seq_keyval;
788: PETSC_EXTERN PetscMPIInt Petsc_ShmComm_keyval;

790: /*
791:   PETSc communicators have this attribute, see
792:   PetscCommDuplicate(), PetscCommDestroy(), PetscCommGetNewTag(), PetscObjectGetName()
793: */
794: typedef struct {
795:   PetscMPIInt tag;              /* next free tag value */
796:   PetscInt    refcount;         /* number of references, communicator can be freed when this reaches 0 */
797:   PetscInt    namecount;        /* used to generate the next name, as in Vec_0, Mat_1, ... */
798: } PetscCommCounter;

800: /*E
801:     PetscOffloadFlag - indicates which memory (CPU, GPU, or none contains valid vector

803:    PETSC_OFFLOAD_UNALLOCATED  - no memory contains valid matrix entries; NEVER used for vectors
804:    PETSC_OFFLOAD_GPU - GPU has valid vector/matrix entries
805:    PETSC_OFFLOAD_CPU - CPU has valid vector/matrix entries
806:    PETSC_OFFLOAD_BOTH - Both GPU and CPU have valid vector/matrix entries and they match

808:    Level: developer
809: E*/
810: typedef enum {PETSC_OFFLOAD_UNALLOCATED,PETSC_OFFLOAD_GPU,PETSC_OFFLOAD_CPU,PETSC_OFFLOAD_BOTH} PetscOffloadFlag;

812: typedef enum {STATE_BEGIN, STATE_PENDING, STATE_END} SRState;

814: typedef enum {PETSC_SR_REDUCE_SUM=0,PETSC_SR_REDUCE_MAX=1,PETSC_SR_REDUCE_MIN=2} PetscSRReductionType;

816: typedef struct {
817:   MPI_Comm    comm;
818:   MPI_Request request;
819:   PetscBool   async;
820:   PetscScalar *lvalues;     /* this are the reduced values before call to MPI_Allreduce() */
821:   PetscScalar *gvalues;     /* values after call to MPI_Allreduce() */
822:   void        **invecs;     /* for debugging only, vector/memory used with each op */
823:   PetscInt    *reducetype;  /* is particular value to be summed or maxed? */
824:   SRState     state;        /* are we calling xxxBegin() or xxxEnd()? */
825:   PetscInt    maxops;       /* total amount of space we have for requests */
826:   PetscInt    numopsbegin;  /* number of requests that have been queued in */
827:   PetscInt    numopsend;    /* number of requests that have been gotten by user */
828: } PetscSplitReduction;

830: PETSC_EXTERN PetscErrorCode PetscSplitReductionGet(MPI_Comm,PetscSplitReduction**);
831: PETSC_EXTERN PetscErrorCode PetscSplitReductionEnd(PetscSplitReduction*);
832: PETSC_EXTERN PetscErrorCode PetscSplitReductionExtend(PetscSplitReduction*);

834: #if !defined(PETSC_SKIP_SPINLOCK)
835: #if defined(PETSC_HAVE_THREADSAFETY)
836: #  if defined(PETSC_HAVE_CONCURRENCYKIT)
837: #if defined(__cplusplus)
838: /*  CK does not have extern "C" protection in their include files */
839: extern "C" {
840: #endif
841: #include <ck_spinlock.h>
842: #if defined(__cplusplus)
843: }
844: #endif
845: typedef ck_spinlock_t PetscSpinlock;
846: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockCreate(PetscSpinlock *ck_spinlock)
847: {
848:   ck_spinlock_init(ck_spinlock);
849:   return 0;
850: }
851: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockLock(PetscSpinlock *ck_spinlock)
852: {
853:   ck_spinlock_lock(ck_spinlock);
854:   return 0;
855: }
856: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *ck_spinlock)
857: {
858:   ck_spinlock_unlock(ck_spinlock);
859:   return 0;
860: }
861: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *ck_spinlock)
862: {
863:   return 0;
864: }
865: #  elif defined(PETSC_HAVE_OPENMP)

867: #include <omp.h>
868: typedef omp_lock_t PetscSpinlock;
869: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockCreate(PetscSpinlock *omp_lock)
870: {
871:   omp_init_lock(omp_lock);
872:   return 0;
873: }
874: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockLock(PetscSpinlock *omp_lock)
875: {
876:   omp_set_lock(omp_lock);
877:   return 0;
878: }
879: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockUnlock(PetscSpinlock *omp_lock)
880: {
881:   omp_unset_lock(omp_lock);
882:   return 0;
883: }
884: PETSC_STATIC_INLINE PetscErrorCode PetscSpinlockDestroy(PetscSpinlock *omp_lock)
885: {
886:   omp_destroy_lock(omp_lock);
887:   return 0;
888: }
889: #else
890: Thread safety requires either --with-openmp or --download-concurrencykit
891: #endif

893: #else
894: typedef int PetscSpinlock;
895: #define PetscSpinlockCreate(a)  0
896: #define PetscSpinlockLock(a)    0
897: #define PetscSpinlockUnlock(a)  0
898: #define PetscSpinlockDestroy(a) 0
899: #endif

901: #if defined(PETSC_HAVE_THREADSAFETY)
902: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockOpen;
903: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStdout;
904: PETSC_INTERN PetscSpinlock PetscViewerASCIISpinLockStderr;
905: PETSC_INTERN PetscSpinlock PetscCommSpinLock;
906: #endif
907: #endif

909: PETSC_EXTERN PetscLogEvent PETSC_Barrier;
910: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSided;
911: PETSC_EXTERN PetscLogEvent PETSC_BuildTwoSidedF;

913: #if defined(PETSC_HAVE_ADIOS)
914: PETSC_EXTERN int64_t Petsc_adios_group;
915: #endif

917: #endif /* _PETSCHEAD_H */