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