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