Actual source code: logimpl.h

  1: #pragma once

  3: #include <petsc/private/petscimpl.h>

  5: #include <petsc/private/logimpldeprecated.h>

  7: /* --- Macros for resizable arrays that show up frequently in the implementation of logging --- */

  9: #define PETSC_LOG_RESIZABLE_ARRAY(Container, Entry, Key, Constructor, Destructor, Equal) \
 10:   typedef struct _n_PetscLog##Container    *PetscLog##Container; \
 11:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Create(int, PetscLog##Container *); \
 12:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Destroy(PetscLog##Container *); \
 13:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Recapacity(PetscLog##Container, int); \
 14:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Resize(PetscLog##Container, int); \
 15:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Push(PetscLog##Container, Entry); \
 16:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Find(PetscLog##Container, Key, int *); \
 17:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##GetSize(PetscLog##Container, PetscInt *, PetscInt *); \
 18:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Get(PetscLog##Container, PetscInt, Entry *); \
 19:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##GetRef(PetscLog##Container, PetscInt, Entry **); \
 20:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Set(PetscLog##Container, PetscInt, Entry); \
 21:   struct _n_PetscLog##Container { \
 22:     int    num_entries; \
 23:     int    max_entries; \
 24:     Entry *array; \
 25:   }; \
 26:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Create(int max_init, PetscLog##Container *a_p) \
 27:   { \
 28:     PetscLog##Container a; \
 29:     PetscErrorCode (*constructor)(Entry *) = Constructor; \
 30:     PetscFunctionBegin; \
 31:     PetscCall(PetscNew(a_p)); \
 32:     a              = *a_p; \
 33:     a->num_entries = 0; \
 34:     a->max_entries = max_init; \
 35:     if (constructor) { \
 36:       PetscCall(PetscMalloc1(max_init, &(a->array))); \
 37:     } else { \
 38:       PetscCall(PetscCalloc1(max_init, &(a->array))); \
 39:     } \
 40:     PetscFunctionReturn(PETSC_SUCCESS); \
 41:   } \
 42:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Destroy(PetscLog##Container *a_p) \
 43:   { \
 44:     PetscLog##Container a; \
 45:     PetscErrorCode (*destructor)(Entry *) = Destructor; \
 46:     PetscFunctionBegin; \
 47:     a    = *a_p; \
 48:     *a_p = NULL; \
 49:     if (a == NULL) PetscFunctionReturn(PETSC_SUCCESS); \
 50:     if (destructor) { \
 51:       for (int i = 0; i < a->num_entries; i++) { PetscCall((*destructor)(&(a->array[i]))); } \
 52:     } \
 53:     PetscCall(PetscFree(a->array)); \
 54:     PetscCall(PetscFree(a)); \
 55:     PetscFunctionReturn(PETSC_SUCCESS); \
 56:   } \
 57:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Recapacity(PetscLog##Container a, int new_size) \
 58:   { \
 59:     PetscErrorCode (*constructor)(Entry *) = Constructor; \
 60:     PetscFunctionBegin; \
 61:     if (new_size > a->max_entries) { \
 62:       int    new_max_entries = 2; \
 63:       int    rem_size        = PetscMax(0, new_size - 1); \
 64:       Entry *new_array; \
 65:       while (rem_size >>= 1) new_max_entries *= 2; \
 66:       if (constructor) { \
 67:         PetscCall(PetscMalloc1(new_max_entries, &new_array)); \
 68:       } else { \
 69:         PetscCall(PetscCalloc1(new_max_entries, &new_array)); \
 70:       } \
 71:       PetscCall(PetscArraycpy(new_array, a->array, a->num_entries)); \
 72:       PetscCall(PetscFree(a->array)); \
 73:       a->array       = new_array; \
 74:       a->max_entries = new_max_entries; \
 75:     } \
 76:     PetscFunctionReturn(PETSC_SUCCESS); \
 77:   } \
 78:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Resize(PetscLog##Container a, int new_size) \
 79:   { \
 80:     PetscErrorCode (*constructor)(Entry *) = Constructor; \
 81:     PetscFunctionBegin; \
 82:     PetscCall(PetscLog##Container##Recapacity(a, new_size)); \
 83:     if (constructor) \
 84:       for (int i = a->num_entries; i < new_size; i++) PetscCall((*constructor)(&(a->array[i]))); \
 85:     a->num_entries = PetscMax(a->num_entries, new_size); \
 86:     PetscFunctionReturn(PETSC_SUCCESS); \
 87:   } \
 88:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Push(PetscLog##Container a, Entry new_entry) \
 89:   { \
 90:     PetscFunctionBegin; \
 91:     PetscCall(PetscLog##Container##Recapacity(a, a->num_entries + 1)); \
 92:     a->array[a->num_entries++] = new_entry; \
 93:     PetscFunctionReturn(PETSC_SUCCESS); \
 94:   } \
 95:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Find(PetscLog##Container a, Key key, int *idx_p) \
 96:   { \
 97:     PetscErrorCode (*equal)(Entry *, Key, PetscBool *) = Equal; \
 98:     PetscFunctionBegin; \
 99:     *idx_p = -1; \
100:     if (equal) { \
101:       for (int i = 0; i < a->num_entries; i++) { \
102:         PetscBool is_equal; \
103:         PetscCall((*equal)(&(a->array[i]), key, &is_equal)); \
104:         if (is_equal) { \
105:           *idx_p = i; \
106:           break; \
107:         } \
108:       } \
109:     } \
110:     PetscFunctionReturn(PETSC_SUCCESS); \
111:   } \
112:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##GetSize(PetscLog##Container a, PetscInt *num_entries, PetscInt *max_entries) \
113:   { \
114:     PetscFunctionBegin; \
115:     if (num_entries) *num_entries = a->num_entries; \
116:     if (max_entries) *max_entries = a->max_entries; \
117:     PetscFunctionReturn(PETSC_SUCCESS); \
118:   } \
119:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Get(PetscLog##Container a, PetscInt i, Entry *entry) \
120:   { \
121:     PetscFunctionBegin; \
122:     PetscCheck(i >= 0 && i < a->num_entries, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Index %d is not in range [0,%d)", (int)i, a->num_entries); \
123:     *entry = a->array[i]; \
124:     PetscFunctionReturn(PETSC_SUCCESS); \
125:   } \
126:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##GetRef(PetscLog##Container a, PetscInt i, Entry **entry) \
127:   { \
128:     PetscFunctionBegin; \
129:     PetscCheck(i >= 0 && i < a->num_entries, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Index %d is not in range [0,%d)", (int)i, a->num_entries); \
130:     *entry = &a->array[i]; \
131:     PetscFunctionReturn(PETSC_SUCCESS); \
132:   } \
133:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Set(PetscLog##Container a, PetscInt i, Entry entry) \
134:   { \
135:     PetscFunctionBegin; \
136:     PetscCheck(i >= 0 && i < a->num_entries, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Index %d is not in range [0,%d)", (int)i, a->num_entries); \
137:     a->array[i] = entry; \
138:     PetscFunctionReturn(PETSC_SUCCESS); \
139:   }

141: /* --- the registry: information about registered things ---

143:    Log handler instances should not change the registry: it is shared
144:    data that should be useful to more than one type of logging

146:  */

148: PETSC_INTERN PetscErrorCode PetscLogRegistryCreate(PetscLogRegistry *);
149: PETSC_INTERN PetscErrorCode PetscLogRegistryDestroy(PetscLogRegistry);
150: PETSC_INTERN PetscErrorCode PetscLogRegistryStageRegister(PetscLogRegistry, const char[], PetscLogStage *);
151: PETSC_INTERN PetscErrorCode PetscLogRegistryEventRegister(PetscLogRegistry, const char[], PetscClassId, PetscLogStage *);
152: PETSC_INTERN PetscErrorCode PetscLogRegistryClassRegister(PetscLogRegistry, const char[], PetscClassId, PetscLogClass *);
153: PETSC_INTERN PetscErrorCode PetscLogRegistryGetEventFromName(PetscLogRegistry, const char[], PetscLogEvent *);
154: PETSC_INTERN PetscErrorCode PetscLogRegistryGetStageFromName(PetscLogRegistry, const char[], PetscLogStage *);
155: PETSC_INTERN PetscErrorCode PetscLogRegistryGetClassFromClassId(PetscLogRegistry, PetscClassId, PetscLogClass *);
156: PETSC_INTERN PetscErrorCode PetscLogRegistryGetClassFromName(PetscLogRegistry, const char[], PetscLogClass *);
157: PETSC_INTERN PetscErrorCode PetscLogRegistryGetNumEvents(PetscLogRegistry, PetscInt *, PetscInt *);
158: PETSC_INTERN PetscErrorCode PetscLogRegistryGetNumStages(PetscLogRegistry, PetscInt *, PetscInt *);
159: PETSC_INTERN PetscErrorCode PetscLogRegistryGetNumClasses(PetscLogRegistry, PetscInt *, PetscInt *);
160: PETSC_INTERN PetscErrorCode PetscLogRegistryEventGetInfo(PetscLogRegistry, PetscLogEvent, PetscLogEventInfo *);
161: PETSC_INTERN PetscErrorCode PetscLogRegistryStageGetInfo(PetscLogRegistry, PetscLogStage, PetscLogStageInfo *);
162: PETSC_INTERN PetscErrorCode PetscLogRegistryClassGetInfo(PetscLogRegistry, PetscLogClass, PetscLogClassInfo *);
163: PETSC_INTERN PetscErrorCode PetscLogRegistryEventSetCollective(PetscLogRegistry, PetscLogEvent, PetscBool);

165: /* --- globally synchronized registry information --- */

167: typedef struct _n_PetscLogGlobalNames *PetscLogGlobalNames;

169: PETSC_INTERN PetscErrorCode PetscLogGlobalNamesCreate(MPI_Comm, PetscInt, const char **, PetscLogGlobalNames *);
170: PETSC_INTERN PetscErrorCode PetscLogGlobalNamesDestroy(PetscLogGlobalNames *);
171: PETSC_INTERN PetscErrorCode PetscLogGlobalNamesGetSize(PetscLogGlobalNames, PetscInt *, PetscInt *);
172: PETSC_INTERN PetscErrorCode PetscLogGlobalNamesGlobalGetName(PetscLogGlobalNames, PetscInt, const char **);
173: PETSC_INTERN PetscErrorCode PetscLogGlobalNamesGlobalGetLocal(PetscLogGlobalNames, PetscInt, PetscInt *);
174: PETSC_INTERN PetscErrorCode PetscLogGlobalNamesLocalGetGlobal(PetscLogGlobalNames, PetscInt, PetscInt *);
175: PETSC_INTERN PetscErrorCode PetscLogRegistryCreateGlobalStageNames(MPI_Comm, PetscLogRegistry, PetscLogGlobalNames *);
176: PETSC_INTERN PetscErrorCode PetscLogRegistryCreateGlobalEventNames(MPI_Comm, PetscLogRegistry, PetscLogGlobalNames *);

178: /* A simple stack */
179: struct _n_PetscIntStack {
180:   int  top;   /* The top of the stack */
181:   int  max;   /* The maximum stack size */
182:   int *stack; /* The storage */
183: };

185: /* Thread-safety internals */

187: /* SpinLock for shared Log variables */
188: PETSC_INTERN PetscSpinlock PetscLogSpinLock;

190: #if defined(PETSC_HAVE_THREADSAFETY)
191:   #if defined(__cplusplus)
192:     #define PETSC_TLS thread_local
193:   #else
194:     #define PETSC_TLS _Thread_local
195:   #endif
196:   #define PETSC_INTERN_TLS extern PETSC_TLS PETSC_VISIBILITY_INTERNAL

198: /* Access PETSc internal thread id */
199: PETSC_INTERN PetscInt PetscLogGetTid(void);
200: #else
201:   #define PETSC_TLS
202:   #define PETSC_INTERN_TLS PETSC_INTERN
203: #endif

205: PETSC_EXTERN PetscBool PetscLogGpuTimeFlag;

207: #if PetscDefined(USE_LOG)
208: PETSC_INTERN PetscErrorCode PetscLogTypeBegin(PetscLogHandlerType type);
209: #else
210:   #define PetscLogTypeBegin(t) ((void)(t), PETSC_SUCCESS)
211: #endif

213: #define PETSC_LOG_VIEW_FROM_OPTIONS_MAX 4