xref: /petsc/include/petsclog.h (revision b93211885051a68d5a4e2963b141f71fa7a24c4c)
1 /*
2     Defines profile/logging in PETSc.
3 */
4 #ifndef PETSCLOG_H
5 #define PETSCLOG_H
6 
7 #include <petscsys.h>
8 #include <petsctime.h>
9 #include <petscbt.h>
10 #include <petsclogtypes.h>
11 
12 /* SUBMANSEC = Profiling */
13 
14 /* General logging of information; different from event logging */
15 PETSC_EXTERN PetscErrorCode PetscInfo_Private(const char[], PetscObject, const char[], ...) PETSC_ATTRIBUTE_FORMAT(3, 4);
16 #if defined(PETSC_USE_INFO)
17   #define PetscInfo(A, ...) PetscInfo_Private(PETSC_FUNCTION_NAME, ((PetscObject)A), __VA_ARGS__)
18 #else
19   #define PetscInfo(A, ...) PETSC_SUCCESS
20 #endif
21 
22 #define PetscInfo1(...) PETSC_DEPRECATED_MACRO(3, 17, 0, "PetscInfo()", ) PetscInfo(__VA_ARGS__)
23 #define PetscInfo2(...) PETSC_DEPRECATED_MACRO(3, 17, 0, "PetscInfo()", ) PetscInfo(__VA_ARGS__)
24 #define PetscInfo3(...) PETSC_DEPRECATED_MACRO(3, 17, 0, "PetscInfo()", ) PetscInfo(__VA_ARGS__)
25 #define PetscInfo4(...) PETSC_DEPRECATED_MACRO(3, 17, 0, "PetscInfo()", ) PetscInfo(__VA_ARGS__)
26 #define PetscInfo5(...) PETSC_DEPRECATED_MACRO(3, 17, 0, "PetscInfo()", ) PetscInfo(__VA_ARGS__)
27 #define PetscInfo6(...) PETSC_DEPRECATED_MACRO(3, 17, 0, "PetscInfo()", ) PetscInfo(__VA_ARGS__)
28 #define PetscInfo7(...) PETSC_DEPRECATED_MACRO(3, 17, 0, "PetscInfo()", ) PetscInfo(__VA_ARGS__)
29 #define PetscInfo8(...) PETSC_DEPRECATED_MACRO(3, 17, 0, "PetscInfo()", ) PetscInfo(__VA_ARGS__)
30 #define PetscInfo9(...) PETSC_DEPRECATED_MACRO(3, 17, 0, "PetscInfo()", ) PetscInfo(__VA_ARGS__)
31 
32 /*E
33   PetscInfoCommFlag - Describes the method by which to filter information displayed by `PetscInfo()` by communicator size
34 
35   Values:
36 + `PETSC_INFO_COMM_ALL` - Default uninitialized value. `PetscInfo()` will not filter based on
37                           communicator size (i.e. will print for all communicators)
38 . `PETSC_INFO_COMM_NO_SELF` - `PetscInfo()` will NOT print for communicators with size = 1 (i.e. *_COMM_SELF)
39 - `PETSC_INFO_COMM_ONLY_SELF` - `PetscInfo()` will ONLY print for communicators with size = 1
40 
41   Level: intermediate
42 
43   Note:
44   Used as an input for `PetscInfoSetFilterCommSelf()`
45 
46 .seealso: `PetscInfo()`, `PetscInfoSetFromOptions()`, `PetscInfoSetFilterCommSelf()`
47 E*/
48 typedef enum {
49   PETSC_INFO_COMM_ALL       = -1,
50   PETSC_INFO_COMM_NO_SELF   = 0,
51   PETSC_INFO_COMM_ONLY_SELF = 1
52 } PetscInfoCommFlag;
53 
54 PETSC_EXTERN const char *const PetscInfoCommFlags[];
55 PETSC_EXTERN PetscErrorCode    PetscInfoDeactivateClass(PetscClassId);
56 PETSC_EXTERN PetscErrorCode    PetscInfoActivateClass(PetscClassId);
57 PETSC_EXTERN PetscErrorCode    PetscInfoEnabled(PetscClassId, PetscBool *);
58 PETSC_EXTERN PetscErrorCode    PetscInfoAllow(PetscBool);
59 PETSC_EXTERN PetscErrorCode    PetscInfoSetFile(const char[], const char[]);
60 PETSC_EXTERN PetscErrorCode    PetscInfoGetFile(char **, FILE **);
61 PETSC_EXTERN PetscErrorCode    PetscInfoSetClasses(PetscBool, PetscInt, const char *const *);
62 PETSC_EXTERN PetscErrorCode    PetscInfoGetClass(const char *, PetscBool *);
63 PETSC_EXTERN PetscErrorCode    PetscInfoGetInfo(PetscBool *, PetscBool *, PetscBool *, PetscBool *, PetscInfoCommFlag *);
64 PETSC_EXTERN PetscErrorCode    PetscInfoProcessClass(const char[], PetscInt, const PetscClassId[]);
65 PETSC_EXTERN PetscErrorCode    PetscInfoSetFilterCommSelf(PetscInfoCommFlag);
66 PETSC_EXTERN PetscErrorCode    PetscInfoSetFromOptions(PetscOptions);
67 PETSC_EXTERN PetscErrorCode    PetscInfoDestroy(void);
68 PETSC_EXTERN PetscBool         PetscLogPrintInfo; /* if true, indicates PetscInfo() is turned on */
69 
70 #define PETSC_EVENT 1311311
71 PETSC_EXTERN PetscLogEvent PETSC_LARGEST_EVENT;
72 
73 PETSC_EXTERN PetscErrorCode PetscIntStackCreate(PetscIntStack *);
74 PETSC_EXTERN PetscErrorCode PetscIntStackDestroy(PetscIntStack);
75 PETSC_EXTERN PetscErrorCode PetscIntStackPush(PetscIntStack, int);
76 PETSC_EXTERN PetscErrorCode PetscIntStackPop(PetscIntStack, int *);
77 PETSC_EXTERN PetscErrorCode PetscIntStackTop(PetscIntStack, int *);
78 PETSC_EXTERN PetscErrorCode PetscIntStackEmpty(PetscIntStack, PetscBool *);
79 
80 PETSC_EXTERN PetscErrorCode PetscLogStateCreate(PetscLogState *);
81 PETSC_EXTERN PetscErrorCode PetscLogStateDestroy(PetscLogState *);
82 PETSC_EXTERN PetscErrorCode PetscLogStateGetRegistry(PetscLogState, PetscLogRegistry *);
83 
84 PETSC_EXTERN PetscErrorCode PetscLogStateClassRegister(PetscLogState, const char[], PetscClassId, PetscLogStage *);
85 PETSC_EXTERN PetscErrorCode PetscLogStateClassSetActive(PetscLogState, PetscLogStage, PetscClassId, PetscBool);
86 PETSC_EXTERN PetscErrorCode PetscLogStateClassSetActiveAll(PetscLogState, PetscClassId, PetscBool);
87 
88 PETSC_EXTERN PetscErrorCode PetscLogStateStageRegister(PetscLogState, const char[], PetscLogStage *);
89 PETSC_EXTERN PetscErrorCode PetscLogStateStagePush(PetscLogState, PetscLogStage);
90 PETSC_EXTERN PetscErrorCode PetscLogStateStagePop(PetscLogState);
91 PETSC_EXTERN PetscErrorCode PetscLogStateStageSetActive(PetscLogState, PetscLogStage, PetscBool);
92 PETSC_EXTERN PetscErrorCode PetscLogStateStageGetActive(PetscLogState, PetscLogStage, PetscBool *);
93 PETSC_EXTERN PetscErrorCode PetscLogStateGetCurrentStage(PetscLogState, PetscLogStage *);
94 
95 PETSC_EXTERN PetscErrorCode PetscLogStateEventRegister(PetscLogState, const char[], PetscClassId, PetscLogEvent *);
96 PETSC_EXTERN PetscErrorCode PetscLogStateEventSetCollective(PetscLogState, PetscLogEvent, PetscBool);
97 PETSC_EXTERN PetscErrorCode PetscLogStateEventSetActive(PetscLogState, PetscLogStage, PetscLogEvent, PetscBool);
98 PETSC_EXTERN PetscErrorCode PetscLogStateEventSetActiveAll(PetscLogState, PetscLogEvent, PetscBool);
99 PETSC_EXTERN PetscErrorCode PetscLogStateEventGetActive(PetscLogState, PetscLogStage, PetscLogEvent, PetscBool *);
100 
101 PETSC_EXTERN PetscErrorCode PetscLogStateGetEventFromName(PetscLogState, const char[], PetscLogEvent *);
102 PETSC_EXTERN PetscErrorCode PetscLogStateGetStageFromName(PetscLogState, const char[], PetscLogStage *);
103 PETSC_EXTERN PetscErrorCode PetscLogStateGetClassFromName(PetscLogState, const char[], PetscLogClass *);
104 PETSC_EXTERN PetscErrorCode PetscLogStateGetClassFromClassId(PetscLogState, PetscClassId, PetscLogClass *);
105 PETSC_EXTERN PetscErrorCode PetscLogStateGetNumEvents(PetscLogState, PetscInt *);
106 PETSC_EXTERN PetscErrorCode PetscLogStateGetNumStages(PetscLogState, PetscInt *);
107 PETSC_EXTERN PetscErrorCode PetscLogStateGetNumClasses(PetscLogState, PetscInt *);
108 PETSC_EXTERN PetscErrorCode PetscLogStateEventGetInfo(PetscLogState, PetscLogEvent, PetscLogEventInfo *);
109 PETSC_EXTERN PetscErrorCode PetscLogStateStageGetInfo(PetscLogState, PetscLogStage, PetscLogStageInfo *);
110 PETSC_EXTERN PetscErrorCode PetscLogStateClassGetInfo(PetscLogState, PetscLogClass, PetscLogClassInfo *);
111 
112 PETSC_EXTERN PetscClassId PETSCLOGHANDLER_CLASSID;
113 
114 PETSC_EXTERN PetscFunctionList PetscLogHandlerList;
115 
116 PETSC_EXTERN PetscErrorCode PetscLogHandlerRegister(const char[], PetscErrorCode (*)(PetscLogHandler));
117 PETSC_EXTERN PetscErrorCode PetscLogHandlerCreate(MPI_Comm, PetscLogHandler *);
118 PETSC_EXTERN PetscErrorCode PetscLogHandlerSetType(PetscLogHandler, PetscLogHandlerType);
119 PETSC_EXTERN PetscErrorCode PetscLogHandlerGetType(PetscLogHandler, PetscLogHandlerType *);
120 PETSC_EXTERN PetscErrorCode PetscLogHandlerDestroy(PetscLogHandler *);
121 PETSC_EXTERN PetscErrorCode PetscLogHandlerSetState(PetscLogHandler, PetscLogState);
122 PETSC_EXTERN PetscErrorCode PetscLogHandlerGetState(PetscLogHandler, PetscLogState *);
123 PETSC_EXTERN PetscErrorCode PetscLogHandlerEventBegin(PetscLogHandler, PetscLogEvent, PetscObject, PetscObject, PetscObject, PetscObject);
124 PETSC_EXTERN PetscErrorCode PetscLogHandlerEventEnd(PetscLogHandler, PetscLogEvent, PetscObject, PetscObject, PetscObject, PetscObject);
125 PETSC_EXTERN PetscErrorCode PetscLogHandlerEventSync(PetscLogHandler, PetscLogEvent, MPI_Comm);
126 PETSC_EXTERN PetscErrorCode PetscLogHandlerObjectCreate(PetscLogHandler, PetscObject);
127 PETSC_EXTERN PetscErrorCode PetscLogHandlerObjectDestroy(PetscLogHandler, PetscObject);
128 PETSC_EXTERN PetscErrorCode PetscLogHandlerStagePush(PetscLogHandler, PetscLogStage);
129 PETSC_EXTERN PetscErrorCode PetscLogHandlerStagePop(PetscLogHandler, PetscLogStage);
130 PETSC_EXTERN PetscErrorCode PetscLogHandlerView(PetscLogHandler, PetscViewer);
131 
132 /* All events are inactive if an invalid stage is set, like if there have been more stage pops than stage pushes */
133 #define PetscLogStateStageEventIsActive(state, stage, event) ((stage >= 0) && PetscBTLookup((state)->active, (stage)) && PetscBTLookup((state)->active, (stage) + (event + 1) * (state)->bt_num_stages))
134 
135 /* Handle multithreading */
136 #if defined(PETSC_HAVE_THREADSAFETY)
137   #if defined(__cplusplus)
138     #define PETSC_TLS thread_local
139   #else
140     #define PETSC_TLS _Thread_local
141   #endif
142   #define PETSC_EXTERN_TLS extern PETSC_TLS PETSC_VISIBILITY_PUBLIC
143 PETSC_EXTERN PetscErrorCode PetscAddLogDouble(PetscLogDouble *, PetscLogDouble *, PetscLogDouble);
144 PETSC_EXTERN PetscErrorCode PetscAddLogDoubleCnt(PetscLogDouble *, PetscLogDouble *, PetscLogDouble *, PetscLogDouble *, PetscLogDouble);
145 #else
146   #define PETSC_EXTERN_TLS PETSC_EXTERN
147   #define PETSC_TLS
148   #define PetscAddLogDouble(a, b, c)          ((PetscErrorCode)((*(a) += (c), PETSC_SUCCESS) || ((*(b) += (c)), PETSC_SUCCESS)))
149   #define PetscAddLogDoubleCnt(a, b, c, d, e) ((PetscErrorCode)(PetscAddLogDouble(a, c, 1) || PetscAddLogDouble(b, d, e)))
150 #endif
151 
152 /*
153     PetscClassRegInfo, PetscClassPerfInfo - Each class has two data structures associated with it. The first has
154        static information about it, the second collects statistics on how many objects of the class are created,
155        how much memory they use, etc.
156 
157     PetscClassRegLog, PetscClassPerfLog - arrays of the PetscClassRegInfo and PetscClassPerfInfo for all classes.
158 */
159 typedef struct {
160   char        *name;    /* The class name */
161   PetscClassId classid; /* The integer identifying this class */
162 } PetscClassRegInfo;
163 
164 typedef struct {
165   PetscClassId   id;           /* The integer identifying this class */
166   int            creations;    /* The number of objects of this class created */
167   int            destructions; /* The number of objects of this class destroyed */
168   PetscLogDouble mem;          /* The total memory allocated by objects of this class; this is completely wrong and should possibly be removed */
169   PetscLogDouble descMem;      /* The total memory allocated by descendents of these objects; this is completely wrong and should possibly be removed */
170 } PetscClassPerfInfo;
171 
172 typedef struct _n_PetscClassRegLog *PetscClassRegLog;
173 struct _n_PetscClassRegLog {
174   int                numClasses; /* The number of classes registered */
175   int                maxClasses; /* The maximum number of classes */
176   PetscClassRegInfo *classInfo;  /* The structure for class information (classids are monotonicly increasing) */
177 };
178 
179 typedef struct _n_PetscClassPerfLog *PetscClassPerfLog;
180 struct _n_PetscClassPerfLog {
181   int                 numClasses; /* The number of logging classes */
182   int                 maxClasses; /* The maximum number of classes */
183   PetscClassPerfInfo *classInfo;  /* The structure for class information (classids are monotonicly increasing) */
184 };
185 
186 /*
187     PetscEventRegInfo, PetscEventPerfInfo - Each event has two data structures associated with it. The first has
188        static information about it, the second collects statistics on how many times the event is used, how
189        much time it takes, etc.
190 
191     PetscEventRegLog, PetscEventPerfLog - an array of all PetscEventRegInfo and PetscEventPerfInfo for all events. There is one
192       of these for each stage.
193 
194 */
195 typedef struct {
196   char        *name;       /* The name of this event */
197   PetscClassId classid;    /* The class the event is associated with */
198   PetscBool    collective; /* Flag this event as collective */
199 #if defined(PETSC_HAVE_TAU_PERFSTUBS)
200   void *timer; /* Associated external tool timer for this event */
201 #endif
202 #if defined(PETSC_HAVE_MPE)
203   int mpe_id_begin; /* MPE IDs that define the event */
204   int mpe_id_end;
205 #endif
206 } PetscEventRegInfo;
207 
208 typedef struct _n_PetscEventRegLog *PetscEventRegLog;
209 struct _n_PetscEventRegLog {
210   int                numEvents; /* The number of registered events */
211   int                maxEvents; /* The maximum number of events */
212   PetscEventRegInfo *eventInfo; /* The registration information for each event */
213 };
214 
215 typedef struct _n_PetscEventPerfLog *PetscEventPerfLog;
216 struct _n_PetscEventPerfLog {
217   int                 numEvents; /* The number of logging events */
218   int                 maxEvents; /* The maximum number of events */
219   PetscEventPerfInfo *eventInfo; /* The performance information for each event */
220 };
221 
222 /*
223    PetscStageInfo - Contains all the information about a particular stage.
224 
225    PetscStageLog - An array of PetscStageInfo for each registered stage. There is a single one of these in the code.
226 */
227 typedef struct _PetscStageInfo {
228   char              *name;     /* The stage name */
229   PetscBool          used;     /* The stage was pushed on this processor */
230   PetscEventPerfInfo perfInfo; /* The stage performance information */
231   PetscEventPerfLog  eventLog; /* The event information for this stage */
232   PetscClassPerfLog  classLog; /* The class information for this stage */
233 #if defined(PETSC_HAVE_TAU_PERFSTUBS)
234   void *timer; /* Associated external tool timer for this stage */
235 #endif
236 } PetscStageInfo;
237 
238 typedef struct _n_PetscStageLog *PetscStageLog;
239 struct _n_PetscStageLog {
240   int              numStages; /* The number of registered stages */
241   int              maxStages; /* The maximum number of stages */
242   PetscIntStack    stack;     /* The stack for active stages */
243   int              curStage;  /* The current stage (only used in macros so we don't call PetscIntStackTop) */
244   PetscStageInfo  *stageInfo; /* The information for each stage */
245   PetscEventRegLog eventLog;  /* The registered events */
246   PetscClassRegLog classLog;  /* The registered classes */
247 };
248 
249 PETSC_DEPRECATED_FUNCTION(3, 18, 0, "PetscLogObjectParent()", ) static inline PetscErrorCode PetscLogObjectParent(PetscObject o, PetscObject p)
250 {
251   (void)o;
252   (void)p;
253   return PETSC_SUCCESS;
254 }
255 
256 PETSC_DEPRECATED_FUNCTION(3, 18, 0, "PetscLogObjectMemory()", ) static inline PetscErrorCode PetscLogObjectMemory(PetscObject o, PetscLogDouble m)
257 {
258   (void)o;
259   (void)m;
260   return PETSC_SUCCESS;
261 }
262 
263 #if defined(PETSC_USE_LOG) /* --- Logging is turned on --------------------------------*/
264 PETSC_EXTERN PetscStageLog  petsc_stageLog;
265 PETSC_EXTERN PetscErrorCode PetscLogGetStageLog(PetscStageLog *);
266 PETSC_EXTERN PetscErrorCode PetscStageLogGetCurrent(PetscStageLog, int *);
267 PETSC_EXTERN PetscErrorCode PetscStageLogGetEventPerfLog(PetscStageLog, int, PetscEventPerfLog *);
268 
269 PETSC_EXTERN PetscErrorCode PetscGetFlops(PetscLogDouble *);
270 
271   #if defined(PETSC_HAVE_MPE)
272 PETSC_EXTERN PetscErrorCode PetscLogMPEBegin(void);
273 PETSC_EXTERN PetscErrorCode PetscLogMPEDump(const char[]);
274   #endif
275 
276 PETSC_EXTERN PetscErrorCode (*PetscLogPLB)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject);
277 PETSC_EXTERN PetscErrorCode (*PetscLogPLE)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject);
278 PETSC_EXTERN PetscErrorCode (*PetscLogPHC)(PetscObject);
279 PETSC_EXTERN PetscErrorCode (*PetscLogPHD)(PetscObject);
280 
281   #define PetscLogObjectParents(p, n, d) PetscMacroReturnStandard(for (int _i = 0; _i < (n); ++_i) PetscCall(PetscLogObjectParent((PetscObject)(p), (PetscObject)(d)[_i]));)
282   #define PetscLogObjectCreate(h)        ((PetscLogPHC) ? (*PetscLogPHC)((PetscObject)(h)) : PETSC_SUCCESS)
283   #define PetscLogObjectDestroy(h)       ((PetscLogPHD) ? (*PetscLogPHD)((PetscObject)(h)) : PETSC_SUCCESS)
284 PETSC_EXTERN PetscErrorCode PetscLogObjectState(PetscObject, const char[], ...) PETSC_ATTRIBUTE_FORMAT(2, 3);
285 
286 /* Initialization functions */
287 PETSC_EXTERN PetscErrorCode PetscLogDefaultBegin(void);
288 PETSC_EXTERN PetscErrorCode PetscLogAllBegin(void);
289 PETSC_EXTERN PetscErrorCode PetscLogNestedBegin(void);
290 PETSC_EXTERN PetscErrorCode PetscLogTraceBegin(FILE *);
291 PETSC_EXTERN PetscErrorCode PetscLogActions(PetscBool);
292 PETSC_EXTERN PetscErrorCode PetscLogObjects(PetscBool);
293 PETSC_EXTERN PetscErrorCode PetscLogSetThreshold(PetscLogDouble, PetscLogDouble *);
294 PETSC_EXTERN PetscErrorCode PetscLogSet(PetscErrorCode (*)(int, int, PetscObject, PetscObject, PetscObject, PetscObject), PetscErrorCode (*)(int, int, PetscObject, PetscObject, PetscObject, PetscObject));
295 
296 /* Output functions */
297 PETSC_EXTERN PetscErrorCode PetscLogView(PetscViewer);
298 PETSC_EXTERN PetscErrorCode PetscLogViewFromOptions(void);
299 PETSC_EXTERN PetscErrorCode PetscLogDump(const char[]);
300 
301 /* Status checking functions */
302 PETSC_EXTERN PetscErrorCode PetscLogIsActive(PetscBool *);
303 
304 /* Stage functions */
305 PETSC_EXTERN PetscErrorCode PetscLogStageRegister(const char[], PetscLogStage *);
306 PETSC_EXTERN PetscErrorCode PetscLogStagePush(PetscLogStage);
307 PETSC_EXTERN PetscErrorCode PetscLogStagePop(void);
308 PETSC_EXTERN PetscErrorCode PetscLogStageSetActive(PetscLogStage, PetscBool);
309 PETSC_EXTERN PetscErrorCode PetscLogStageGetActive(PetscLogStage, PetscBool *);
310 PETSC_EXTERN PetscErrorCode PetscLogStageSetVisible(PetscLogStage, PetscBool);
311 PETSC_EXTERN PetscErrorCode PetscLogStageGetVisible(PetscLogStage, PetscBool *);
312 PETSC_EXTERN PetscErrorCode PetscLogStageGetId(const char[], PetscLogStage *);
313 
314 /* Event functions */
315 PETSC_EXTERN PetscErrorCode PetscLogEventRegister(const char[], PetscClassId, PetscLogEvent *);
316 PETSC_EXTERN PetscErrorCode PetscLogEventSetCollective(PetscLogEvent, PetscBool);
317 PETSC_EXTERN PetscErrorCode PetscLogEventIncludeClass(PetscClassId);
318 PETSC_EXTERN PetscErrorCode PetscLogEventExcludeClass(PetscClassId);
319 PETSC_EXTERN PetscErrorCode PetscLogEventActivate(PetscLogEvent);
320 PETSC_EXTERN PetscErrorCode PetscLogEventDeactivate(PetscLogEvent);
321 PETSC_EXTERN PetscErrorCode PetscLogEventDeactivatePush(PetscLogEvent);
322 PETSC_EXTERN PetscErrorCode PetscLogEventDeactivatePop(PetscLogEvent);
323 PETSC_EXTERN PetscErrorCode PetscLogEventSetActiveAll(PetscLogEvent, PetscBool);
324 PETSC_EXTERN PetscErrorCode PetscLogEventActivateClass(PetscClassId);
325 PETSC_EXTERN PetscErrorCode PetscLogEventDeactivateClass(PetscClassId);
326 PETSC_EXTERN PetscErrorCode PetscLogEventGetId(const char[], PetscLogEvent *);
327 PETSC_EXTERN PetscErrorCode PetscLogEventGetPerfInfo(int, PetscLogEvent, PetscEventPerfInfo *);
328 PETSC_EXTERN PetscErrorCode PetscLogEventSetDof(PetscLogEvent, PetscInt, PetscLogDouble);
329 PETSC_EXTERN PetscErrorCode PetscLogEventSetError(PetscLogEvent, PetscInt, PetscLogDouble);
330 PETSC_EXTERN PetscErrorCode PetscLogPushCurrentEvent_Internal(PetscLogEvent);
331 PETSC_EXTERN PetscErrorCode PetscLogPopCurrentEvent_Internal(void);
332 
333 PETSC_EXTERN PetscBool PetscLogMemory;
334 
335 PETSC_EXTERN PetscBool      PetscLogSyncOn; /* true if logging synchronization is enabled */
336 PETSC_EXTERN PetscErrorCode PetscLogEventSynchronize(PetscLogEvent, MPI_Comm);
337 
338   #define PetscLogEventSync(e, comm) \
339     ((PetscErrorCode)(((PetscLogPLB && petsc_stageLog->stageInfo[petsc_stageLog->curStage].perfInfo.active && petsc_stageLog->stageInfo[petsc_stageLog->curStage].eventLog->eventInfo[e].active) ? PetscLogEventSynchronize((e), (comm)) : PETSC_SUCCESS)))
340 
341   #define PetscLogEventBegin(e, o1, o2, o3, o4) \
342     ((PetscErrorCode)((PetscLogPLB && petsc_stageLog->stageInfo[petsc_stageLog->curStage].perfInfo.active && petsc_stageLog->stageInfo[petsc_stageLog->curStage].eventLog->eventInfo[e].active) ? (PetscErrorCode)(((*PetscLogPLB)((e), 0, (PetscObject)(o1), (PetscObject)(o2), (PetscObject)(o3), (PetscObject)(o4))) || PetscLogPushCurrentEvent_Internal(e)) : PETSC_SUCCESS))
343 
344   #define PetscLogEventEnd(e, o1, o2, o3, o4) \
345     ((PetscErrorCode)((PetscLogPLE && petsc_stageLog->stageInfo[petsc_stageLog->curStage].perfInfo.active && petsc_stageLog->stageInfo[petsc_stageLog->curStage].eventLog->eventInfo[e].active) ? (PetscErrorCode)(((*PetscLogPLE)((e), 0, (PetscObject)(o1), (PetscObject)(o2), (PetscObject)(o3), (PetscObject)(o4))) || PetscLogPopCurrentEvent_Internal()) : PETSC_SUCCESS))
346 
347 PETSC_EXTERN PetscErrorCode PetscLogEventGetFlops(PetscLogEvent, PetscLogDouble *);
348 PETSC_EXTERN PetscErrorCode PetscLogEventZeroFlops(PetscLogEvent);
349 
350 /* Global flop counter */
351 PETSC_EXTERN PetscLogDouble petsc_TotalFlops;
352 PETSC_EXTERN PetscLogDouble petsc_irecv_ct;
353 PETSC_EXTERN PetscLogDouble petsc_isend_ct;
354 PETSC_EXTERN PetscLogDouble petsc_recv_ct;
355 PETSC_EXTERN PetscLogDouble petsc_send_ct;
356 PETSC_EXTERN PetscLogDouble petsc_irecv_len;
357 PETSC_EXTERN PetscLogDouble petsc_isend_len;
358 PETSC_EXTERN PetscLogDouble petsc_recv_len;
359 PETSC_EXTERN PetscLogDouble petsc_send_len;
360 PETSC_EXTERN PetscLogDouble petsc_allreduce_ct;
361 PETSC_EXTERN PetscLogDouble petsc_gather_ct;
362 PETSC_EXTERN PetscLogDouble petsc_scatter_ct;
363 PETSC_EXTERN PetscLogDouble petsc_wait_ct;
364 PETSC_EXTERN PetscLogDouble petsc_wait_any_ct;
365 PETSC_EXTERN PetscLogDouble petsc_wait_all_ct;
366 PETSC_EXTERN PetscLogDouble petsc_sum_of_waits_ct;
367 
368 /* Thread local storage */
369 PETSC_EXTERN_TLS PetscLogDouble petsc_TotalFlops_th;
370 PETSC_EXTERN_TLS PetscLogDouble petsc_irecv_ct_th;
371 PETSC_EXTERN_TLS PetscLogDouble petsc_isend_ct_th;
372 PETSC_EXTERN_TLS PetscLogDouble petsc_recv_ct_th;
373 PETSC_EXTERN_TLS PetscLogDouble petsc_send_ct_th;
374 PETSC_EXTERN_TLS PetscLogDouble petsc_irecv_len_th;
375 PETSC_EXTERN_TLS PetscLogDouble petsc_isend_len_th;
376 PETSC_EXTERN_TLS PetscLogDouble petsc_recv_len_th;
377 PETSC_EXTERN_TLS PetscLogDouble petsc_send_len_th;
378 PETSC_EXTERN_TLS PetscLogDouble petsc_allreduce_ct_th;
379 PETSC_EXTERN_TLS PetscLogDouble petsc_gather_ct_th;
380 PETSC_EXTERN_TLS PetscLogDouble petsc_scatter_ct_th;
381 PETSC_EXTERN_TLS PetscLogDouble petsc_wait_ct_th;
382 PETSC_EXTERN_TLS PetscLogDouble petsc_wait_any_ct_th;
383 PETSC_EXTERN_TLS PetscLogDouble petsc_wait_all_ct_th;
384 PETSC_EXTERN_TLS PetscLogDouble petsc_sum_of_waits_ct_th;
385 
386   /*
387    Flop counting:  We count each arithmetic operation (e.g., addition, multiplication) separately.
388 
389    For the complex numbers version, note that
390        1 complex addition = 2 flops
391        1 complex multiplication = 6 flops,
392    where we define 1 flop as that for a double precision scalar.  We roughly approximate
393    flop counting for complex numbers by multiplying the total flops by 4; this corresponds
394    to the assumption that we're counting mostly additions and multiplications -- and
395    roughly the same number of each.  More accurate counting could be done by distinguishing
396    among the various arithmetic operations.
397  */
398 
399   #if defined(PETSC_USE_COMPLEX)
400     #define PETSC_FLOPS_PER_OP 4.0
401   #else
402     #define PETSC_FLOPS_PER_OP 1.0
403   #endif
404 
405 /*@C
406        PetscLogFlops - Log how many flops are performed in a calculation
407 
408    Input Parameter:
409 .   flops - the number of flops
410 
411    Level: intermediate
412 
413    Note:
414      To limit the chance of integer overflow when multiplying by a constant, represent the constant as a double,
415      not an integer. Use `PetscLogFlops`(4.0*n) not `PetscLogFlops`(4*n)
416 
417 .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`
418 @*/
419 static inline PetscErrorCode PetscLogFlops(PetscLogDouble n)
420 {
421   PetscAssert(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cannot log negative flops");
422   return PetscAddLogDouble(&petsc_TotalFlops, &petsc_TotalFlops_th, PETSC_FLOPS_PER_OP * n);
423 }
424 
425   /*
426      These are used internally in the PETSc routines to keep a count of MPI messages and
427    their sizes.
428 
429      This does not work for MPI-Uni because our include/petsc/mpiuni/mpi.h file
430    uses macros to defined the MPI operations.
431 
432      It does not work correctly from HP-UX because it processes the
433    macros in a way that sometimes it double counts, hence
434    PETSC_HAVE_BROKEN_RECURSIVE_MACRO
435 
436      It does not work with Windows because winmpich lacks MPI_Type_size()
437 */
438   #if !defined(MPIUNI_H) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO)
439 /*
440    Logging of MPI activities
441 */
442 static inline PetscErrorCode PetscMPITypeSize(PetscInt count, MPI_Datatype type, PetscLogDouble *length, PetscLogDouble *length_th)
443 {
444   PetscMPIInt typesize;
445 
446   if (type == MPI_DATATYPE_NULL) return PETSC_SUCCESS;
447   PetscCallMPI(MPI_Type_size(type, &typesize));
448   return PetscAddLogDouble(length, length_th, (PetscLogDouble)(count * typesize));
449 }
450 
451 static inline PetscErrorCode PetscMPITypeSizeComm(MPI_Comm comm, const PetscMPIInt *counts, MPI_Datatype type, PetscLogDouble *length, PetscLogDouble *length_th)
452 {
453   PetscMPIInt    typesize, size, p;
454   PetscLogDouble l;
455 
456   if (type == MPI_DATATYPE_NULL) return PETSC_SUCCESS;
457   PetscCallMPI(MPI_Comm_size(comm, &size));
458   PetscCallMPI(MPI_Type_size(type, &typesize));
459   for (p = 0, l = 0.0; p < size; ++p) l += (PetscLogDouble)(counts[p] * typesize);
460   return PetscAddLogDouble(length, length_th, l);
461 }
462 
463 /*
464     Returns 1 if the communicator is parallel else zero
465 */
466 static inline int PetscMPIParallelComm(MPI_Comm comm)
467 {
468   PetscMPIInt size;
469   MPI_Comm_size(comm, &size);
470   return size > 1;
471 }
472 
473     #define MPI_Irecv(buf, count, datatype, source, tag, comm, request) \
474       (PetscAddLogDouble(&petsc_irecv_ct, &petsc_irecv_ct_th, 1) || PetscMPITypeSize((count), (datatype), &(petsc_irecv_len), &(petsc_irecv_len_th)) || MPI_Irecv((buf), (count), (datatype), (source), (tag), (comm), (request)))
475 
476     #define MPI_Irecv_c(buf, count, datatype, source, tag, comm, request) \
477       (PetscAddLogDouble(&petsc_irecv_ct, &petsc_irecv_ct_th, 1) || PetscMPITypeSize((count), (datatype), &(petsc_irecv_len), &(petsc_irecv_len_th)) || MPI_Irecv_c((buf), (count), (datatype), (source), (tag), (comm), (request)))
478 
479     #define MPI_Isend(buf, count, datatype, dest, tag, comm, request) \
480       (PetscAddLogDouble(&petsc_isend_ct, &petsc_isend_ct_th, 1) || PetscMPITypeSize((count), (datatype), &(petsc_isend_len), &(petsc_isend_len_th)) || MPI_Isend((buf), (count), (datatype), (dest), (tag), (comm), (request)))
481 
482     #define MPI_Isend_c(buf, count, datatype, dest, tag, comm, request) \
483       (PetscAddLogDouble(&petsc_isend_ct, &petsc_isend_ct_th, 1) || PetscMPITypeSize((count), (datatype), &(petsc_isend_len), &(petsc_isend_len_th)) || MPI_Isend_c((buf), (count), (datatype), (dest), (tag), (comm), (request)))
484 
485     #define MPI_Startall_irecv(count, datatype, number, requests) \
486       (PetscAddLogDouble(&petsc_irecv_ct, &petsc_irecv_ct_th, number) || PetscMPITypeSize((count), (datatype), &(petsc_irecv_len), &(petsc_irecv_len_th)) || ((number) && MPI_Startall((number), (requests))))
487 
488     #define MPI_Startall_isend(count, datatype, number, requests) \
489       (PetscAddLogDouble(&petsc_isend_ct, &petsc_isend_ct_th, number) || PetscMPITypeSize((count), (datatype), &(petsc_isend_len), &(petsc_isend_len_th)) || ((number) && MPI_Startall((number), (requests))))
490 
491     #define MPI_Start_isend(count, datatype, requests) (PetscAddLogDouble(&petsc_isend_ct, &petsc_isend_ct_th, 1) || PetscMPITypeSize((count), (datatype), (&petsc_isend_len), (&petsc_isend_len_th)) || MPI_Start((requests)))
492 
493     #define MPI_Recv(buf, count, datatype, source, tag, comm, status) \
494       (PetscAddLogDouble(&petsc_recv_ct, &petsc_recv_ct_th, 1) || PetscMPITypeSize((count), (datatype), (&petsc_recv_len), (&petsc_recv_len_th)) || MPI_Recv((buf), (count), (datatype), (source), (tag), (comm), (status)))
495 
496     #define MPI_Recv_c(buf, count, datatype, source, tag, comm, status) \
497       (PetscAddLogDouble(&petsc_recv_ct, &petsc_recv_ct_th, 1) || PetscMPITypeSize((count), (datatype), (&petsc_recv_len), &(petsc_recv_len_th)) || MPI_Recv_c((buf), (count), (datatype), (source), (tag), (comm), (status)))
498 
499     #define MPI_Send(buf, count, datatype, dest, tag, comm) \
500       (PetscAddLogDouble(&petsc_send_ct, &petsc_send_ct_th, 1) || PetscMPITypeSize((count), (datatype), (&petsc_send_len), (&petsc_send_len_th)) || MPI_Send((buf), (count), (datatype), (dest), (tag), (comm)))
501 
502     #define MPI_Send_c(buf, count, datatype, dest, tag, comm) \
503       (PetscAddLogDouble(&petsc_send_ct, &petsc_send_ct_th, 1) || PetscMPITypeSize((count), (datatype), (&petsc_send_len), (&petsc_send_len_th)) || MPI_Send_c((buf), (count), (datatype), (dest), (tag), (comm)))
504 
505     #define MPI_Wait(request, status) (PetscAddLogDouble(&petsc_wait_ct, &petsc_wait_ct_th, 1) || PetscAddLogDouble(&petsc_sum_of_waits_ct, &petsc_sum_of_waits_ct_th, 1) || MPI_Wait((request), (status)))
506 
507     #define MPI_Waitany(a, b, c, d) (PetscAddLogDouble(&petsc_wait_any_ct, &petsc_wait_any_ct_th, 1) || PetscAddLogDouble(&petsc_sum_of_waits_ct, &petsc_sum_of_waits_ct_th, 1) || MPI_Waitany((a), (b), (c), (d)))
508 
509     #define MPI_Waitall(count, array_of_requests, array_of_statuses) \
510       (PetscAddLogDouble(&petsc_wait_all_ct, &petsc_wait_all_ct_th, 1) || PetscAddLogDouble(&petsc_sum_of_waits_ct, &petsc_sum_of_waits_ct_th, count) || MPI_Waitall((count), (array_of_requests), (array_of_statuses)))
511 
512     #define MPI_Allreduce(sendbuf, recvbuf, count, datatype, op, comm) (PetscAddLogDouble(&petsc_allreduce_ct, &petsc_allreduce_ct_th, PetscMPIParallelComm(comm)) || MPI_Allreduce((sendbuf), (recvbuf), (count), (datatype), (op), (comm)))
513 
514     #define MPI_Bcast(buffer, count, datatype, root, comm) (PetscAddLogDouble(&petsc_allreduce_ct, &petsc_allreduce_ct_th, PetscMPIParallelComm(comm)) || MPI_Bcast((buffer), (count), (datatype), (root), (comm)))
515 
516     #define MPI_Reduce_scatter_block(sendbuf, recvbuf, recvcount, datatype, op, comm) \
517       (PetscAddLogDouble(&petsc_allreduce_ct, &petsc_allreduce_ct_th, PetscMPIParallelComm(comm)) || MPI_Reduce_scatter_block((sendbuf), (recvbuf), (recvcount), (datatype), (op), (comm)))
518 
519     #define MPI_Alltoall(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm) \
520       (PetscAddLogDouble(&petsc_allreduce_ct, &petsc_allreduce_ct_th, PetscMPIParallelComm(comm)) || PetscMPITypeSize((sendcount), (sendtype), (&petsc_send_len), (&petsc_send_len_th)) || MPI_Alltoall((sendbuf), (sendcount), (sendtype), (recvbuf), (recvcount), (recvtype), (comm)))
521 
522     #define MPI_Alltoallv(sendbuf, sendcnts, sdispls, sendtype, recvbuf, recvcnts, rdispls, recvtype, comm) \
523       (PetscAddLogDouble(&petsc_allreduce_ct, &petsc_allreduce_ct_th, PetscMPIParallelComm(comm)) || PetscMPITypeSizeComm((comm), (sendcnts), (sendtype), (&petsc_send_len), (&petsc_send_len_th)) || MPI_Alltoallv((sendbuf), (sendcnts), (sdispls), (sendtype), (recvbuf), (recvcnts), (rdispls), (recvtype), (comm)))
524 
525     #define MPI_Allgather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm) \
526       (PetscAddLogDouble(&petsc_gather_ct, &petsc_gather_ct_th, PetscMPIParallelComm(comm)) || MPI_Allgather((sendbuf), (sendcount), (sendtype), (recvbuf), (recvcount), (recvtype), (comm)))
527 
528     #define MPI_Allgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcount, displs, recvtype, comm) \
529       (PetscAddLogDouble(&petsc_gather_ct, &petsc_gather_ct_th, PetscMPIParallelComm(comm)) || MPI_Allgatherv((sendbuf), (sendcount), (sendtype), (recvbuf), (recvcount), (displs), (recvtype), (comm)))
530 
531     #define MPI_Gather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm) \
532       (PetscAddLogDouble(&petsc_gather_ct, &petsc_gather_ct_th, 1) || PetscMPITypeSize((sendcount), (sendtype), (&petsc_send_len), (&petsc_send_len_th)) || MPI_Gather((sendbuf), (sendcount), (sendtype), (recvbuf), (recvcount), (recvtype), (root), (comm)))
533 
534     #define MPI_Gatherv(sendbuf, sendcount, sendtype, recvbuf, recvcount, displs, recvtype, root, comm) \
535       (PetscAddLogDouble(&petsc_gather_ct, &petsc_gather_ct_th, 1) || PetscMPITypeSize((sendcount), (sendtype), (&petsc_send_len), (&petsc_send_len_th)) || MPI_Gatherv((sendbuf), (sendcount), (sendtype), (recvbuf), (recvcount), (displs), (recvtype), (root), (comm)))
536 
537     #define MPI_Scatter(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm) \
538       (PetscAddLogDouble(&petsc_scatter_ct, &petsc_scatter_ct_th, 1) || PetscMPITypeSize((recvcount), (recvtype), (&petsc_recv_len), &(petsc_recv_len_th)) || MPI_Scatter((sendbuf), (sendcount), (sendtype), (recvbuf), (recvcount), (recvtype), (root), (comm)))
539 
540     #define MPI_Scatterv(sendbuf, sendcount, displs, sendtype, recvbuf, recvcount, recvtype, root, comm) \
541       (PetscAddLogDouble(&petsc_scatter_ct, &petsc_scatter_ct_th, 1) || PetscMPITypeSize((recvcount), (recvtype), (&petsc_recv_len), &(petsc_recv_len_th)) || MPI_Scatterv((sendbuf), (sendcount), (displs), (sendtype), (recvbuf), (recvcount), (recvtype), (root), (comm)))
542 
543     #define MPI_Ialltoall(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm, request) \
544       (PetscAddLogDouble(&petsc_allreduce_ct, &petsc_allreduce_ct_th, PetscMPIParallelComm(comm)) || PetscMPITypeSize((sendcount), (sendtype), (&petsc_send_len), (&petsc_send_len_th)) || MPI_Ialltoall((sendbuf), (sendcount), (sendtype), (recvbuf), (recvcount), (recvtype), (comm), (request)))
545 
546     #define MPI_Ialltoallv(sendbuf, sendcnts, sdispls, sendtype, recvbuf, recvcnts, rdispls, recvtype, comm, request) \
547       (PetscAddLogDouble(&petsc_allreduce_ct, &petsc_allreduce_ct_th, PetscMPIParallelComm(comm)) || PetscMPITypeSizeComm((comm), (sendcnts), (sendtype), (&petsc_send_len), (&petsc_send_len_th)) || MPI_Ialltoallv((sendbuf), (sendcnts), (sdispls), (sendtype), (recvbuf), (recvcnts), (rdispls), (recvtype), (comm), (request)))
548 
549     #define MPI_Iallgather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm, request) \
550       (PetscAddLogDouble(&petsc_gather_ct, &petsc_gather_ct_th, PetscMPIParallelComm(comm)) || MPI_Iallgather((sendbuf), (sendcount), (sendtype), (recvbuf), (recvcount), (recvtype), (comm), (request)))
551 
552     #define MPI_Iallgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcount, displs, recvtype, comm, request) \
553       (PetscAddLogDouble(&petsc_gather_ct, &petsc_gather_ct_th, PetscMPIParallelComm(comm)) || MPI_Iallgatherv((sendbuf), (sendcount), (sendtype), (recvbuf), (recvcount), (displs), (recvtype), (comm), (request)))
554 
555     #define MPI_Igather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm, request) \
556       (PetscAddLogDouble(&petsc_gather_ct, &petsc_gather_ct_th, 1) || PetscMPITypeSize((sendcount), (sendtype), (&petsc_send_len), (&petsc_send_len_th)) || MPI_Igather((sendbuf), (sendcount), (sendtype), (recvbuf), (recvcount), (recvtype), (root), (comm), (request)))
557 
558     #define MPI_Igatherv(sendbuf, sendcount, sendtype, recvbuf, recvcount, displs, recvtype, root, comm, request) \
559       (PetscAddLogDouble(&petsc_gather_ct, &petsc_gather_ct_th, 1) || PetscMPITypeSize((sendcount), (sendtype), (&petsc_send_len), (&petsc_send_len_th)) || MPI_Igatherv((sendbuf), (sendcount), (sendtype), (recvbuf), (recvcount), (displs), (recvtype), (root), (comm), (request)))
560 
561     #define MPI_Iscatter(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm, request) \
562       (PetscAddLogDouble(&petsc_scatter_ct, &petsc_scatter_ct_th, 1) || PetscMPITypeSize((recvcount), (recvtype), (&petsc_recv_len), (&petsc_recv_len_th)) || MPI_Iscatter((sendbuf), (sendcount), (sendtype), (recvbuf), (recvcount), (recvtype), (root), (comm), (request)))
563 
564     #define MPI_Iscatterv(sendbuf, sendcount, displs, sendtype, recvbuf, recvcount, recvtype, root, comm, request) \
565       (PetscAddLogDouble(&petsc_scatter_ct, &petsc_scatter_ct_th, 1) || PetscMPITypeSize((recvcount), (recvtype), (&petsc_recv_len), (&petsc_recv_len_th)) || MPI_Iscatterv((sendbuf), (sendcount), (displs), (sendtype), (recvbuf), (recvcount), (recvtype), (root), (comm), (request)))
566 
567     #define MPIX_Send_enqueue(buf, count, datatype, dest, tag, comm) \
568       (PetscAddLogDouble(&petsc_send_ct, &petsc_send_ct_th, 1) || PetscMPITypeSize((count), (datatype), (&petsc_send_len), (&petsc_send_len_th)) || MPIX_Send_enqueue((buf), (count), (datatype), (dest), (tag), (comm)))
569 
570     #define MPIX_Recv_enqueue(buf, count, datatype, source, tag, comm, status) \
571       (PetscAddLogDouble(&petsc_recv_ct, &petsc_recv_ct_th, 1) || PetscMPITypeSize((count), (datatype), (&petsc_recv_len), (&petsc_recv_len_th)) || MPIX_Recv_enqueue((buf), (count), (datatype), (source), (tag), (comm), (status)))
572 
573     #define MPIX_Isend_enqueue(buf, count, datatype, dest, tag, comm, request) \
574       (PetscAddLogDouble(&petsc_isend_ct, &petsc_isend_ct_th, 1) || PetscMPITypeSize((count), (datatype), &(petsc_isend_len), &(petsc_isend_len_th)) || MPIX_Isend_enqueue((buf), (count), (datatype), (dest), (tag), (comm), (request)))
575 
576     #define MPIX_Irecv_enqueue(buf, count, datatype, source, tag, comm, request) \
577       (PetscAddLogDouble(&petsc_irecv_ct, &petsc_irecv_ct_th, 1) || PetscMPITypeSize((count), (datatype), &(petsc_irecv_len), &(petsc_irecv_len_th)) || MPIX_Irecv_enqueue((buf), (count), (datatype), (source), (tag), (comm), (request)))
578 
579     #define MPIX_Allreduce_enqueue(sendbuf, recvbuf, count, datatype, op, comm) \
580       (PetscAddLogDouble(&petsc_allreduce_ct, &petsc_allreduce_ct_th, PetscMPIParallelComm(comm)) || MPIX_Allreduce_enqueue((sendbuf), (recvbuf), (count), (datatype), (op), (comm)))
581 
582     #define MPIX_Wait_enqueue(request, status) (PetscAddLogDouble(&petsc_wait_ct, &petsc_wait_ct_th, 1) || PetscAddLogDouble(&petsc_sum_of_waits_ct, &petsc_sum_of_waits_ct_th, 1) || MPIX_Wait_enqueue((request), (status)))
583 
584     #define MPIX_Waitall_enqueue(count, array_of_requests, array_of_statuses) \
585       (PetscAddLogDouble(&petsc_wait_all_ct, &petsc_wait_all_ct_th, 1) || PetscAddLogDouble(&petsc_sum_of_waits_ct, &petsc_sum_of_waits_ct_th, count) || MPIX_Waitall_enqueue((count), (array_of_requests), (array_of_statuses)))
586   #else
587 
588     #define MPI_Startall_irecv(count, datatype, number, requests) ((number) && MPI_Startall((number), (requests)))
589 
590     #define MPI_Startall_isend(count, datatype, number, requests) ((number) && MPI_Startall((number), (requests)))
591 
592     #define MPI_Start_isend(count, datatype, requests) (MPI_Start((requests)))
593 
594   #endif /* !MPIUNI_H && ! PETSC_HAVE_BROKEN_RECURSIVE_MACRO */
595 
596 #else /* ---Logging is turned off --------------------------------------------*/
597 
598   #define PetscLogMemory PETSC_FALSE
599 
600   #define PetscLogFlops(n) ((void)(n), PETSC_SUCCESS)
601   #define PetscGetFlops(a) (*(a) = 0.0, PETSC_SUCCESS)
602 
603   #define PetscLogStageRegister(a, b)   PETSC_SUCCESS
604   #define PetscLogStagePush(a)          PETSC_SUCCESS
605   #define PetscLogStagePop()            PETSC_SUCCESS
606   #define PetscLogStageSetActive(a, b)  PETSC_SUCCESS
607   #define PetscLogStageGetActive(a, b)  PETSC_SUCCESS
608   #define PetscLogStageGetVisible(a, b) PETSC_SUCCESS
609   #define PetscLogStageSetVisible(a, b) PETSC_SUCCESS
610   #define PetscLogStageGetId(a, b)      (*(b) = 0, PETSC_SUCCESS)
611 
612   #define PetscLogEventRegister(a, b, c)    PETSC_SUCCESS
613   #define PetscLogEventSetCollective(a, b)  PETSC_SUCCESS
614   #define PetscLogEventIncludeClass(a)      PETSC_SUCCESS
615   #define PetscLogEventExcludeClass(a)      PETSC_SUCCESS
616   #define PetscLogEventActivate(a)          PETSC_SUCCESS
617   #define PetscLogEventDeactivate(a)        PETSC_SUCCESS
618   #define PetscLogEventDeactivatePush(a)    PETSC_SUCCESS
619   #define PetscLogEventDeactivatePop(a)     PETSC_SUCCESS
620   #define PetscLogEventActivateClass(a)     PETSC_SUCCESS
621   #define PetscLogEventDeactivateClass(a)   PETSC_SUCCESS
622   #define PetscLogEventSetActiveAll(a, b)   PETSC_SUCCESS
623   #define PetscLogEventGetId(a, b)          (*(b) = 0, PETSC_SUCCESS)
624   #define PetscLogEventGetPerfInfo(a, b, c) PETSC_SUCCESS
625   #define PetscLogEventSetDof(a, b, c)      PETSC_SUCCESS
626   #define PetscLogEventSetError(a, b, c)    PETSC_SUCCESS
627 
628   #define PetscLogPLB PETSC_SUCCESS
629   #define PetscLogPLE PETSC_SUCCESS
630   #define PetscLogPHC PETSC_SUCCESS
631   #define PetscLogPHD PETSC_SUCCESS
632 
633   #define PetscLogObjectParents(p, n, c) PETSC_SUCCESS
634   #define PetscLogObjectCreate(h)        PETSC_SUCCESS
635   #define PetscLogObjectDestroy(h)       PETSC_SUCCESS
636 PETSC_EXTERN PetscErrorCode PetscLogObjectState(PetscObject, const char[], ...) PETSC_ATTRIBUTE_FORMAT(2, 3);
637 
638   #define PetscLogDefaultBegin()     PETSC_SUCCESS
639   #define PetscLogAllBegin()         PETSC_SUCCESS
640   #define PetscLogNestedBegin()      PETSC_SUCCESS
641   #define PetscLogTraceBegin(file)   PETSC_SUCCESS
642   #define PetscLogActions(a)         PETSC_SUCCESS
643   #define PetscLogObjects(a)         PETSC_SUCCESS
644   #define PetscLogSetThreshold(a, b) PETSC_SUCCESS
645   #define PetscLogSet(lb, le)        PETSC_SUCCESS
646   #define PetscLogIsActive(flag)     (*(flag) = PETSC_FALSE, PETSC_SUCCESS)
647 
648   #define PetscLogView(viewer)      PETSC_SUCCESS
649   #define PetscLogViewFromOptions() PETSC_SUCCESS
650   #define PetscLogDump(c)           PETSC_SUCCESS
651 
652   #define PetscLogEventSync(e, comm)                            PETSC_SUCCESS
653   #define PetscLogEventBegin(e, o1, o2, o3, o4)                 PETSC_SUCCESS
654   #define PetscLogEventEnd(e, o1, o2, o3, o4)                   PETSC_SUCCESS
655 
656   /* If PETSC_USE_LOG is NOT defined, these still need to be! */
657   #define MPI_Startall_irecv(count, datatype, number, requests) ((number) && MPI_Startall(number, requests))
658   #define MPI_Startall_isend(count, datatype, number, requests) ((number) && MPI_Startall(number, requests))
659   #define MPI_Start_isend(count, datatype, requests)            MPI_Start(requests)
660 
661 #endif /* PETSC_USE_LOG */
662 
663 #define PetscPreLoadBegin(flag, name) \
664   do { \
665     PetscBool     PetscPreLoading = flag; \
666     int           PetscPreLoadMax, PetscPreLoadIt; \
667     PetscLogStage _stageNum; \
668     PetscCall(PetscOptionsGetBool(NULL, NULL, "-preload", &PetscPreLoading, NULL)); \
669     PetscPreLoadMax     = (int)(PetscPreLoading); \
670     PetscPreLoadingUsed = PetscPreLoading ? PETSC_TRUE : PetscPreLoadingUsed; \
671     for (PetscPreLoadIt = 0; PetscPreLoadIt <= PetscPreLoadMax; PetscPreLoadIt++) { \
672       PetscPreLoadingOn = PetscPreLoading; \
673       PetscCall(PetscBarrier(NULL)); \
674       if (PetscPreLoadIt > 0) PetscCall(PetscLogStageGetId(name, &_stageNum)); \
675       else PetscCall(PetscLogStageRegister(name, &_stageNum)); \
676       PetscCall(PetscLogStageSetActive(_stageNum, (PetscBool)(!PetscPreLoadMax || PetscPreLoadIt))); \
677       PetscCall(PetscLogStagePush(_stageNum))
678 
679 #define PetscPreLoadEnd() \
680   PetscCall(PetscLogStagePop()); \
681   PetscPreLoading = PETSC_FALSE; \
682   } \
683   } \
684   while (0)
685 
686 #define PetscPreLoadStage(name) \
687   do { \
688     PetscCall(PetscLogStagePop()); \
689     if (PetscPreLoadIt > 0) PetscCall(PetscLogStageGetId(name, &_stageNum)); \
690     else PetscCall(PetscLogStageRegister(name, &_stageNum)); \
691     PetscCall(PetscLogStageSetActive(_stageNum, (PetscBool)(!PetscPreLoadMax || PetscPreLoadIt))); \
692     PetscCall(PetscLogStagePush(_stageNum)); \
693   } while (0)
694 
695 /* some vars for logging */
696 PETSC_EXTERN PetscBool PetscPreLoadingUsed; /* true if we are or have done preloading */
697 PETSC_EXTERN PetscBool PetscPreLoadingOn;   /* true if we are currently in a preloading calculation */
698 
699 #if defined(PETSC_USE_LOG) && defined(PETSC_HAVE_DEVICE)
700 
701 /* Global GPU counters */
702 PETSC_EXTERN PetscLogDouble petsc_ctog_ct;
703 PETSC_EXTERN PetscLogDouble petsc_gtoc_ct;
704 PETSC_EXTERN PetscLogDouble petsc_ctog_sz;
705 PETSC_EXTERN PetscLogDouble petsc_gtoc_sz;
706 PETSC_EXTERN PetscLogDouble petsc_ctog_ct_scalar;
707 PETSC_EXTERN PetscLogDouble petsc_gtoc_ct_scalar;
708 PETSC_EXTERN PetscLogDouble petsc_ctog_sz_scalar;
709 PETSC_EXTERN PetscLogDouble petsc_gtoc_sz_scalar;
710 PETSC_EXTERN PetscLogDouble petsc_gflops;
711 PETSC_EXTERN PetscLogDouble petsc_gtime;
712 
713 /* Thread local storage */
714 PETSC_EXTERN_TLS PetscLogDouble petsc_ctog_ct_th;
715 PETSC_EXTERN_TLS PetscLogDouble petsc_gtoc_ct_th;
716 PETSC_EXTERN_TLS PetscLogDouble petsc_ctog_sz_th;
717 PETSC_EXTERN_TLS PetscLogDouble petsc_gtoc_sz_th;
718 PETSC_EXTERN_TLS PetscLogDouble petsc_ctog_ct_scalar_th;
719 PETSC_EXTERN_TLS PetscLogDouble petsc_gtoc_ct_scalar_th;
720 PETSC_EXTERN_TLS PetscLogDouble petsc_ctog_sz_scalar_th;
721 PETSC_EXTERN_TLS PetscLogDouble petsc_gtoc_sz_scalar_th;
722 PETSC_EXTERN_TLS PetscLogDouble petsc_gflops_th;
723 PETSC_EXTERN_TLS PetscLogDouble petsc_gtime_th;
724 
725 PETSC_EXTERN PetscErrorCode PetscLogGpuTime(void);
726 PETSC_EXTERN PetscErrorCode PetscLogGpuTimeBegin(void);
727 PETSC_EXTERN PetscErrorCode PetscLogGpuTimeEnd(void);
728 
729 /*@C
730        PetscLogGpuFlops - Log how many flops are performed in a calculation on the device
731 
732    Input Parameter:
733 .   flops - the number of flops
734 
735    Level: intermediate
736 
737    Notes:
738      To limit the chance of integer overflow when multiplying by a constant, represent the constant as a double,
739      not an integer. Use `PetscLogFlops`(4.0*n) not `PetscLogFlops`(4*n)
740 
741      The values are also added to the total flop count for the MPI rank that is set with `PetscLogFlops()`; hence the number of flops
742      just on the CPU would be the value from set from `PetscLogFlops()` minus the value set from `PetscLogGpuFlops()`
743 
744 .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogFlops()`, `PetscLogGpuTimeBegin()`, `PetscLogGpuTimeEnd()`
745 @*/
746 static inline PetscErrorCode PetscLogGpuFlops(PetscLogDouble n)
747 {
748   PetscAssert(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cannot log negative flops");
749   PetscCall(PetscAddLogDouble(&petsc_TotalFlops, &petsc_TotalFlops_th, PETSC_FLOPS_PER_OP * n));
750   PetscCall(PetscAddLogDouble(&petsc_gflops, &petsc_gflops_th, PETSC_FLOPS_PER_OP * n));
751   return PETSC_SUCCESS;
752 }
753 
754 static inline PetscErrorCode PetscLogGpuTimeAdd(PetscLogDouble t)
755 {
756   return PetscAddLogDouble(&petsc_gtime, &petsc_gtime_th, t);
757 }
758 
759 static inline PetscErrorCode PetscLogCpuToGpu(PetscLogDouble size)
760 {
761   return PetscAddLogDoubleCnt(&petsc_ctog_ct, &petsc_ctog_sz, &petsc_ctog_ct_th, &petsc_ctog_sz_th, size);
762 }
763 
764 static inline PetscErrorCode PetscLogGpuToCpu(PetscLogDouble size)
765 {
766   return PetscAddLogDoubleCnt(&petsc_gtoc_ct, &petsc_gtoc_sz, &petsc_gtoc_ct_th, &petsc_gtoc_sz_th, size);
767 }
768 
769 static inline PetscErrorCode PetscLogCpuToGpuScalar(PetscLogDouble size)
770 {
771   return PetscAddLogDoubleCnt(&petsc_ctog_ct_scalar, &petsc_ctog_sz_scalar, &petsc_ctog_ct_scalar_th, &petsc_ctog_sz_scalar_th, size);
772 }
773 
774 static inline PetscErrorCode PetscLogGpuToCpuScalar(PetscLogDouble size)
775 {
776   return PetscAddLogDoubleCnt(&petsc_gtoc_ct_scalar, &petsc_gtoc_sz_scalar, &petsc_gtoc_ct_scalar_th, &petsc_gtoc_sz_scalar_th, size);
777 }
778 #else
779 
780   #define PetscLogCpuToGpu(a)       PETSC_SUCCESS
781   #define PetscLogGpuToCpu(a)       PETSC_SUCCESS
782   #define PetscLogCpuToGpuScalar(a) PETSC_SUCCESS
783   #define PetscLogGpuToCpuScalar(a) PETSC_SUCCESS
784   #define PetscLogGpuFlops(a)       PETSC_SUCCESS
785   #define PetscLogGpuTime()         PETSC_SUCCESS
786   #define PetscLogGpuTimeAdd(a)     PETSC_SUCCESS
787   #define PetscLogGpuTimeBegin()    PETSC_SUCCESS
788   #define PetscLogGpuTimeEnd()      PETSC_SUCCESS
789 
790 #endif /* PETSC_USE_LOG && PETSC_HAVE_DEVICE */
791 
792 /* remove TLS defines */
793 #undef PETSC_EXTERN_TLS
794 #undef PETSC_TLS
795 
796 #endif
797