xref: /petsc/include/petsc/private/logimpl.h (revision 7f031e8bf1f008cdd443cdad0cd45837cb20997c)
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