1 #pragma once 2 3 #include <petsc/private/petscimpl.h> 4 5 #include <petsc/private/logimpldeprecated.h> 6 7 /* --- Macros for resizable arrays that show up frequently in the implementation of logging --- */ 8 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 %" PetscInt_FMT " is not in range [0,%d)", 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 %" PetscInt_FMT " is not in range [0,%d)", 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 %" PetscInt_FMT " is not in range [0,%d)", i, a->num_entries); \ 137 a->array[i] = entry; \ 138 PetscFunctionReturn(PETSC_SUCCESS); \ 139 } 140 141 /* --- the registry: information about registered things --- 142 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 145 146 */ 147 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); 164 165 /* --- globally synchronized registry information --- */ 166 167 typedef struct _n_PetscLogGlobalNames *PetscLogGlobalNames; 168 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 *); 177 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 }; 184 185 /* Thread-safety internals */ 186 187 /* SpinLock for shared Log variables */ 188 PETSC_INTERN PetscSpinlock PetscLogSpinLock; 189 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 197 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 204 205 PETSC_EXTERN PetscBool PetscLogGpuTimeFlag; 206 PETSC_EXTERN PetscBool PetscLogGpuEnergyFlag; 207 PETSC_EXTERN PetscBool PetscLogGpuEnergyMeterFlag; 208 PETSC_INTERN PetscInt PetscLogNumViewersCreated; 209 PETSC_INTERN PetscInt PetscLogNumViewersDestroyed; 210 211 #if PetscDefined(USE_LOG) 212 PETSC_INTERN PetscErrorCode PetscLogTypeBegin(PetscLogHandlerType type); 213 #else 214 #define PetscLogTypeBegin(t) ((void)(t), PETSC_SUCCESS) 215 #endif 216 217 #define PETSC_LOG_VIEW_FROM_OPTIONS_MAX 4 218