Actual source code: logimpl.h
1: #pragma once
2: /* all of the logging files have problems with automatic integer casting so checking is turned off for them here */
3: #if defined(__GNUC__) || defined(__clang__)
4: #pragma GCC diagnostic ignored "-Wconversion"
5: #endif
7: #include <petsc/private/petscimpl.h>
9: #include <petsc/private/logimpldeprecated.h>
11: /* --- Macros for resizable arrays that show up frequently in the implementation of logging --- */
13: #define PETSC_LOG_RESIZABLE_ARRAY(Container, Entry, Key, Constructor, Destructor, Equal) \
14: typedef struct _n_PetscLog##Container *PetscLog##Container; \
15: static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Create(int, PetscLog##Container *); \
16: static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Destroy(PetscLog##Container *); \
17: static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Recapacity(PetscLog##Container, int); \
18: static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Resize(PetscLog##Container, int); \
19: static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Push(PetscLog##Container, Entry); \
20: static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Find(PetscLog##Container, Key, int *); \
21: static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##GetSize(PetscLog##Container, PetscInt *, PetscInt *); \
22: static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Get(PetscLog##Container, PetscInt, Entry *); \
23: static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##GetRef(PetscLog##Container, PetscInt, Entry **); \
24: static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Set(PetscLog##Container, PetscInt, Entry); \
25: struct _n_PetscLog##Container { \
26: int num_entries; \
27: int max_entries; \
28: Entry *array; \
29: }; \
30: static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Create(int max_init, PetscLog##Container *a_p) \
31: { \
32: PetscLog##Container a; \
33: PetscErrorCode (*constructor)(Entry *) = Constructor; \
34: PetscFunctionBegin; \
35: PetscCall(PetscNew(a_p)); \
36: a = *a_p; \
37: a->num_entries = 0; \
38: a->max_entries = max_init; \
39: if (constructor) { \
40: PetscCall(PetscMalloc1(max_init, &a->array)); \
41: } else { \
42: PetscCall(PetscCalloc1(max_init, &a->array)); \
43: } \
44: PetscFunctionReturn(PETSC_SUCCESS); \
45: } \
46: static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Destroy(PetscLog##Container *a_p) \
47: { \
48: PetscLog##Container a; \
49: PetscErrorCode (*destructor)(Entry *) = Destructor; \
50: PetscFunctionBegin; \
51: a = *a_p; \
52: *a_p = NULL; \
53: if (a == NULL) PetscFunctionReturn(PETSC_SUCCESS); \
54: if (destructor) { \
55: for (int i = 0; i < a->num_entries; i++) PetscCall((*destructor)(&a->array[i])); \
56: } \
57: PetscCall(PetscFree(a->array)); \
58: PetscCall(PetscFree(a)); \
59: PetscFunctionReturn(PETSC_SUCCESS); \
60: } \
61: static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Recapacity(PetscLog##Container a, int new_size) \
62: { \
63: PetscErrorCode (*constructor)(Entry *) = Constructor; \
64: PetscFunctionBegin; \
65: if (new_size > a->max_entries) { \
66: int new_max_entries = 2; \
67: int rem_size = PetscMax(0, new_size - 1); \
68: Entry *new_array; \
69: while (rem_size >>= 1) new_max_entries *= 2; \
70: if (constructor) { \
71: PetscCall(PetscMalloc1(new_max_entries, &new_array)); \
72: } else { \
73: PetscCall(PetscCalloc1(new_max_entries, &new_array)); \
74: } \
75: PetscCall(PetscArraycpy(new_array, a->array, a->num_entries)); \
76: PetscCall(PetscFree(a->array)); \
77: a->array = new_array; \
78: a->max_entries = new_max_entries; \
79: } \
80: PetscFunctionReturn(PETSC_SUCCESS); \
81: } \
82: static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Resize(PetscLog##Container a, int new_size) \
83: { \
84: PetscErrorCode (*constructor)(Entry *) = Constructor; \
85: PetscFunctionBegin; \
86: PetscCall(PetscLog##Container##Recapacity(a, new_size)); \
87: if (constructor) \
88: for (int i = a->num_entries; i < new_size; i++) PetscCall((*constructor)(&a->array[i])); \
89: a->num_entries = PetscMax(a->num_entries, new_size); \
90: PetscFunctionReturn(PETSC_SUCCESS); \
91: } \
92: static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Push(PetscLog##Container a, Entry new_entry) \
93: { \
94: PetscFunctionBegin; \
95: PetscCall(PetscLog##Container##Recapacity(a, a->num_entries + 1)); \
96: a->array[a->num_entries++] = new_entry; \
97: PetscFunctionReturn(PETSC_SUCCESS); \
98: } \
99: static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Find(PetscLog##Container a, Key key, int *idx_p) \
100: { \
101: PetscErrorCode (*equal)(Entry *, Key, PetscBool *) = Equal; \
102: PetscFunctionBegin; \
103: *idx_p = -1; \
104: if (equal) { \
105: for (int i = 0; i < a->num_entries; i++) { \
106: PetscBool is_equal; \
107: PetscCall((*equal)(&a->array[i], key, &is_equal)); \
108: if (is_equal) { \
109: *idx_p = i; \
110: break; \
111: } \
112: } \
113: } \
114: PetscFunctionReturn(PETSC_SUCCESS); \
115: } \
116: static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##GetSize(PetscLog##Container a, PetscInt *num_entries, PetscInt *max_entries) \
117: { \
118: PetscFunctionBegin; \
119: if (num_entries) *num_entries = a->num_entries; \
120: if (max_entries) *max_entries = a->max_entries; \
121: PetscFunctionReturn(PETSC_SUCCESS); \
122: } \
123: static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Get(PetscLog##Container a, PetscInt i, Entry *entry) \
124: { \
125: PetscFunctionBegin; \
126: 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); \
127: *entry = a->array[i]; \
128: PetscFunctionReturn(PETSC_SUCCESS); \
129: } \
130: static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##GetRef(PetscLog##Container a, PetscInt i, Entry **entry) \
131: { \
132: PetscFunctionBegin; \
133: 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); \
134: *entry = &a->array[i]; \
135: PetscFunctionReturn(PETSC_SUCCESS); \
136: } \
137: static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Set(PetscLog##Container a, PetscInt i, Entry entry) \
138: { \
139: PetscFunctionBegin; \
140: 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); \
141: a->array[i] = entry; \
142: PetscFunctionReturn(PETSC_SUCCESS); \
143: }
145: /* --- the registry: information about registered things ---
147: Log handler instances should not change the registry: it is shared
148: data that should be useful to more than one type of logging
150: */
152: PETSC_INTERN PetscErrorCode PetscLogRegistryCreate(PetscLogRegistry *);
153: PETSC_INTERN PetscErrorCode PetscLogRegistryDestroy(PetscLogRegistry);
154: PETSC_INTERN PetscErrorCode PetscLogRegistryStageRegister(PetscLogRegistry, const char[], PetscLogStage *);
155: PETSC_INTERN PetscErrorCode PetscLogRegistryEventRegister(PetscLogRegistry, const char[], PetscClassId, PetscLogStage *);
156: PETSC_INTERN PetscErrorCode PetscLogRegistryClassRegister(PetscLogRegistry, const char[], PetscClassId, PetscLogClass *);
157: PETSC_INTERN PetscErrorCode PetscLogRegistryGetEventFromName(PetscLogRegistry, const char[], PetscLogEvent *);
158: PETSC_INTERN PetscErrorCode PetscLogRegistryGetStageFromName(PetscLogRegistry, const char[], PetscLogStage *);
159: PETSC_INTERN PetscErrorCode PetscLogRegistryGetClassFromClassId(PetscLogRegistry, PetscClassId, PetscLogClass *);
160: PETSC_INTERN PetscErrorCode PetscLogRegistryGetClassFromName(PetscLogRegistry, const char[], PetscLogClass *);
161: PETSC_INTERN PetscErrorCode PetscLogRegistryGetNumEvents(PetscLogRegistry, PetscInt *, PetscInt *);
162: PETSC_INTERN PetscErrorCode PetscLogRegistryGetNumStages(PetscLogRegistry, PetscInt *, PetscInt *);
163: PETSC_INTERN PetscErrorCode PetscLogRegistryGetNumClasses(PetscLogRegistry, PetscInt *, PetscInt *);
164: PETSC_INTERN PetscErrorCode PetscLogRegistryEventGetInfo(PetscLogRegistry, PetscLogEvent, PetscLogEventInfo *);
165: PETSC_INTERN PetscErrorCode PetscLogRegistryStageGetInfo(PetscLogRegistry, PetscLogStage, PetscLogStageInfo *);
166: PETSC_INTERN PetscErrorCode PetscLogRegistryClassGetInfo(PetscLogRegistry, PetscLogClass, PetscLogClassInfo *);
167: PETSC_INTERN PetscErrorCode PetscLogRegistryEventSetCollective(PetscLogRegistry, PetscLogEvent, PetscBool);
169: /* --- globally synchronized registry information --- */
171: typedef struct _n_PetscLogGlobalNames *PetscLogGlobalNames;
173: PETSC_INTERN PetscErrorCode PetscLogGlobalNamesCreate(MPI_Comm, PetscInt, const char **, PetscLogGlobalNames *);
174: PETSC_INTERN PetscErrorCode PetscLogGlobalNamesDestroy(PetscLogGlobalNames *);
175: PETSC_INTERN PetscErrorCode PetscLogGlobalNamesGetSize(PetscLogGlobalNames, PetscInt *, PetscInt *);
176: PETSC_INTERN PetscErrorCode PetscLogGlobalNamesGlobalGetName(PetscLogGlobalNames, PetscInt, const char **);
177: PETSC_INTERN PetscErrorCode PetscLogGlobalNamesGlobalGetLocal(PetscLogGlobalNames, PetscInt, PetscInt *);
178: PETSC_INTERN PetscErrorCode PetscLogGlobalNamesLocalGetGlobal(PetscLogGlobalNames, PetscInt, PetscInt *);
179: PETSC_INTERN PetscErrorCode PetscLogRegistryCreateGlobalStageNames(MPI_Comm, PetscLogRegistry, PetscLogGlobalNames *);
180: PETSC_INTERN PetscErrorCode PetscLogRegistryCreateGlobalEventNames(MPI_Comm, PetscLogRegistry, PetscLogGlobalNames *);
182: /* A simple stack */
183: struct _n_PetscIntStack {
184: int top; /* The top of the stack */
185: int max; /* The maximum stack size */
186: int *stack; /* The storage */
187: };
189: /* Thread-safety internals */
191: /* SpinLock for shared Log variables */
192: PETSC_INTERN PetscSpinlock PetscLogSpinLock;
194: #if defined(PETSC_HAVE_THREADSAFETY)
195: #if defined(__cplusplus)
196: #define PETSC_TLS thread_local
197: #else
198: #define PETSC_TLS _Thread_local
199: #endif
200: #define PETSC_INTERN_TLS extern PETSC_TLS PETSC_VISIBILITY_INTERNAL
202: /* Access PETSc internal thread id */
203: PETSC_INTERN PetscInt PetscLogGetTid(void);
204: #else
205: #define PETSC_TLS
206: #define PETSC_INTERN_TLS PETSC_INTERN
207: #endif
209: PETSC_EXTERN PetscBool PetscLogGpuTimeFlag;
211: #if PetscDefined(USE_LOG)
212: PETSC_INTERN PetscErrorCode PetscLogTypeBegin(PetscLogHandlerType type);
213: #else
214: #define PetscLogTypeBegin(t) ((void)(t), PETSC_SUCCESS)
215: #endif
217: #define PETSC_LOG_VIEW_FROM_OPTIONS_MAX 4