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