xref: /petsc/src/sys/logging/plog.c (revision b665b14e20d08dc58a3f47e0addbfcd5129cdb60)
1 
2 /*
3       PETSc code to log object creation and destruction and PETSc events.
4 
5       This provides the public API used by the rest of PETSc and by users.
6 
7       These routines use a private API that is not used elsewhere in PETSc and is not
8       accessible to users. The private API is defined in logimpl.h and the utils directory.
9 
10       ***
11 
12       This file, and only this file, is for functions that interact with the global logging state
13 */
14 #include <petsc/private/logimpl.h> /*I    "petscsys.h"   I*/
15 #include <petsc/private/loghandlerimpl.h>
16 #include <petsctime.h>
17 #include <petscviewer.h>
18 #include <petscdevice.h>
19 #include <petsc/private/deviceimpl.h>
20 
21 #if defined(PETSC_HAVE_THREADSAFETY)
22 
23 PetscInt           petsc_log_gid = -1; /* Global threadId counter */
24 PETSC_TLS PetscInt petsc_log_tid = -1; /* Local threadId */
25 
26 /* shared variables */
27 PetscSpinlock PetscLogSpinLock;
28 
29 PetscInt PetscLogGetTid(void)
30 {
31   if (petsc_log_tid < 0) {
32     PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
33     petsc_log_tid = ++petsc_log_gid;
34     PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
35   }
36   return petsc_log_tid;
37 }
38 
39 #endif
40 
41 /* Global counters */
42 PetscLogDouble petsc_BaseTime        = 0.0;
43 PetscLogDouble petsc_TotalFlops      = 0.0; /* The number of flops */
44 PetscLogDouble petsc_send_ct         = 0.0; /* The number of sends */
45 PetscLogDouble petsc_recv_ct         = 0.0; /* The number of receives */
46 PetscLogDouble petsc_send_len        = 0.0; /* The total length of all sent messages */
47 PetscLogDouble petsc_recv_len        = 0.0; /* The total length of all received messages */
48 PetscLogDouble petsc_isend_ct        = 0.0; /* The number of immediate sends */
49 PetscLogDouble petsc_irecv_ct        = 0.0; /* The number of immediate receives */
50 PetscLogDouble petsc_isend_len       = 0.0; /* The total length of all immediate send messages */
51 PetscLogDouble petsc_irecv_len       = 0.0; /* The total length of all immediate receive messages */
52 PetscLogDouble petsc_wait_ct         = 0.0; /* The number of waits */
53 PetscLogDouble petsc_wait_any_ct     = 0.0; /* The number of anywaits */
54 PetscLogDouble petsc_wait_all_ct     = 0.0; /* The number of waitalls */
55 PetscLogDouble petsc_sum_of_waits_ct = 0.0; /* The total number of waits */
56 PetscLogDouble petsc_allreduce_ct    = 0.0; /* The number of reductions */
57 PetscLogDouble petsc_gather_ct       = 0.0; /* The number of gathers and gathervs */
58 PetscLogDouble petsc_scatter_ct      = 0.0; /* The number of scatters and scattervs */
59 
60 /* Thread Local storage */
61 PETSC_TLS PetscLogDouble petsc_TotalFlops_th      = 0.0;
62 PETSC_TLS PetscLogDouble petsc_send_ct_th         = 0.0;
63 PETSC_TLS PetscLogDouble petsc_recv_ct_th         = 0.0;
64 PETSC_TLS PetscLogDouble petsc_send_len_th        = 0.0;
65 PETSC_TLS PetscLogDouble petsc_recv_len_th        = 0.0;
66 PETSC_TLS PetscLogDouble petsc_isend_ct_th        = 0.0;
67 PETSC_TLS PetscLogDouble petsc_irecv_ct_th        = 0.0;
68 PETSC_TLS PetscLogDouble petsc_isend_len_th       = 0.0;
69 PETSC_TLS PetscLogDouble petsc_irecv_len_th       = 0.0;
70 PETSC_TLS PetscLogDouble petsc_wait_ct_th         = 0.0;
71 PETSC_TLS PetscLogDouble petsc_wait_any_ct_th     = 0.0;
72 PETSC_TLS PetscLogDouble petsc_wait_all_ct_th     = 0.0;
73 PETSC_TLS PetscLogDouble petsc_sum_of_waits_ct_th = 0.0;
74 PETSC_TLS PetscLogDouble petsc_allreduce_ct_th    = 0.0;
75 PETSC_TLS PetscLogDouble petsc_gather_ct_th       = 0.0;
76 PETSC_TLS PetscLogDouble petsc_scatter_ct_th      = 0.0;
77 
78 PetscLogDouble petsc_ctog_ct        = 0.0; /* The total number of CPU to GPU copies */
79 PetscLogDouble petsc_gtoc_ct        = 0.0; /* The total number of GPU to CPU copies */
80 PetscLogDouble petsc_ctog_sz        = 0.0; /* The total size of CPU to GPU copies */
81 PetscLogDouble petsc_gtoc_sz        = 0.0; /* The total size of GPU to CPU copies */
82 PetscLogDouble petsc_ctog_ct_scalar = 0.0; /* The total number of CPU to GPU copies */
83 PetscLogDouble petsc_gtoc_ct_scalar = 0.0; /* The total number of GPU to CPU copies */
84 PetscLogDouble petsc_ctog_sz_scalar = 0.0; /* The total size of CPU to GPU copies */
85 PetscLogDouble petsc_gtoc_sz_scalar = 0.0; /* The total size of GPU to CPU copies */
86 PetscLogDouble petsc_gflops         = 0.0; /* The flops done on a GPU */
87 PetscLogDouble petsc_gtime          = 0.0; /* The time spent on a GPU */
88 
89 PETSC_TLS PetscLogDouble petsc_ctog_ct_th        = 0.0;
90 PETSC_TLS PetscLogDouble petsc_gtoc_ct_th        = 0.0;
91 PETSC_TLS PetscLogDouble petsc_ctog_sz_th        = 0.0;
92 PETSC_TLS PetscLogDouble petsc_gtoc_sz_th        = 0.0;
93 PETSC_TLS PetscLogDouble petsc_ctog_ct_scalar_th = 0.0;
94 PETSC_TLS PetscLogDouble petsc_gtoc_ct_scalar_th = 0.0;
95 PETSC_TLS PetscLogDouble petsc_ctog_sz_scalar_th = 0.0;
96 PETSC_TLS PetscLogDouble petsc_gtoc_sz_scalar_th = 0.0;
97 PETSC_TLS PetscLogDouble petsc_gflops_th         = 0.0;
98 PETSC_TLS PetscLogDouble petsc_gtime_th          = 0.0;
99 
100 PetscBool PetscLogMemory = PETSC_FALSE;
101 PetscBool PetscLogSyncOn = PETSC_FALSE;
102 
103 PetscBool PetscLogGpuTimeFlag = PETSC_FALSE;
104 
105 PetscLogState petsc_log_state = NULL;
106 
107 #define PETSC_LOG_HANDLER_HOT_BLANK \
108   { \
109     NULL, NULL, NULL, NULL, NULL, NULL \
110   }
111 
112 PetscLogHandlerHot PetscLogHandlers[PETSC_LOG_HANDLER_MAX] = {
113   PETSC_LOG_HANDLER_HOT_BLANK,
114   PETSC_LOG_HANDLER_HOT_BLANK,
115   PETSC_LOG_HANDLER_HOT_BLANK,
116   PETSC_LOG_HANDLER_HOT_BLANK,
117 };
118 
119 #undef PETSC_LOG_HANDLERS_HOT_BLANK
120 
121 #if defined(PETSC_USE_LOG)
122   #include <../src/sys/logging/handler/impls/default/logdefault.h>
123 
124   #if defined(PETSC_HAVE_THREADSAFETY)
125 PetscErrorCode PetscAddLogDouble(PetscLogDouble *tot, PetscLogDouble *tot_th, PetscLogDouble tmp)
126 {
127   *tot_th += tmp;
128   PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
129   *tot += tmp;
130   PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
131   return PETSC_SUCCESS;
132 }
133 
134 PetscErrorCode PetscAddLogDoubleCnt(PetscLogDouble *cnt, PetscLogDouble *tot, PetscLogDouble *cnt_th, PetscLogDouble *tot_th, PetscLogDouble tmp)
135 {
136   *cnt_th = *cnt_th + 1;
137   *tot_th += tmp;
138   PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
139   *tot += (PetscLogDouble)(tmp);
140   *cnt += *cnt + 1;
141   PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
142   return PETSC_SUCCESS;
143 }
144 
145   #endif
146 
147 static PetscErrorCode PetscLogTryGetHandler(PetscLogHandlerType type, PetscLogHandler *handler)
148 {
149   PetscFunctionBegin;
150   PetscAssertPointer(handler, 2);
151   *handler = NULL;
152   for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
153     PetscLogHandler h = PetscLogHandlers[i].handler;
154     if (h) {
155       PetscBool match;
156 
157       PetscCall(PetscObjectTypeCompare((PetscObject)h, type, &match));
158       if (match) {
159         *handler = PetscLogHandlers[i].handler;
160         PetscFunctionReturn(PETSC_SUCCESS);
161       }
162     }
163   }
164   PetscFunctionReturn(PETSC_SUCCESS);
165 }
166 
167 /*@
168   PetscLogGetDefaultHandler - Get the default log handler if it is running.
169 
170   Not collective
171 
172   Output Parameter:
173 . handler - the default `PetscLogHandler`, or `NULL` if it is not running.
174 
175   Level: developer
176 
177   Notes:
178   The default handler is started with `PetscLogDefaultBegin()`,
179   if the options flags `-log_all` or `-log_view` is given without arguments,
180   or for `-log_view :output:format` if `format` is not `ascii_xml` or `ascii_flamegraph`.
181 
182   These logging functions only affect the default log handler\:
183   `PetscLogActions()`, `PetscLogObjects()`, `PetscLogStageSetVisible()`,
184   `PetscLogDeactivatePush()`, `PetscLogDeactivatePop()`, `PetscLogEventGetPerfInfo()`,
185   `PetscLogEventSetDof()`, `PetscLogEventSetError()`, `PetscLogEventsPause()`,
186   `PetscLogEventsResume()`, `PetscLogDump()`, `PetscLogObjectState()`.
187 
188 .seealso: [](ch_profiling)
189 @*/
190 PetscErrorCode PetscLogGetDefaultHandler(PetscLogHandler *handler)
191 {
192   PetscFunctionBegin;
193   PetscCall(PetscLogTryGetHandler(PETSC_LOG_HANDLER_DEFAULT, handler));
194   PetscFunctionReturn(PETSC_SUCCESS);
195 }
196 
197 static PetscErrorCode PetscLogGetHandler(PetscLogHandlerType type, PetscLogHandler *handler)
198 {
199   PetscFunctionBegin;
200   PetscAssertPointer(handler, 2);
201   PetscCall(PetscLogTryGetHandler(type, handler));
202   PetscCheck(handler != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "A PetscLogHandler of type %s has not been started.", type);
203   PetscFunctionReturn(PETSC_SUCCESS);
204 }
205 
206 /*@
207   PetscLogGetState - Get the `PetscLogState` for PETSc's global logging, used
208   by all default log handlers (`PetscLogDefaultBegin()`,
209   `PetscLogNestedBegin()`, `PetscLogTraceBegin()`, `PetscLogMPEBegin()`,
210   `PetscLogPerfstubsBegin()`).
211 
212   Collective on `PETSC_COMM_WORLD`
213 
214   Output Parameter:
215 . state - The `PetscLogState` changed by registrations (such as
216           `PetscLogEventRegister()`) and actions (such as `PetscLogEventBegin()` or
217           `PetscLogStagePush()`), or NULL if logging is not active
218 
219   Level: developer
220 
221 .seealso: [](ch_profiling), `PetscLogState`
222 @*/
223 PetscErrorCode PetscLogGetState(PetscLogState *state)
224 {
225   PetscFunctionBegin;
226   PetscAssertPointer(state, 1);
227   *state = petsc_log_state;
228   PetscFunctionReturn(PETSC_SUCCESS);
229 }
230 
231 static PetscErrorCode PetscLogHandlerCopyToHot(PetscLogHandler h, PetscLogHandlerHot *hot)
232 {
233   PetscFunctionBegin;
234   hot->handler       = h;
235   hot->eventBegin    = h->ops->eventbegin;
236   hot->eventEnd      = h->ops->eventend;
237   hot->eventSync     = h->ops->eventsync;
238   hot->objectCreate  = h->ops->objectcreate;
239   hot->objectDestroy = h->ops->objectdestroy;
240   PetscFunctionReturn(PETSC_SUCCESS);
241 }
242 
243 /*@
244   PetscLogHandlerStart - Connect a log handler to PETSc's global logging stream and state.
245 
246   Logically collective
247 
248   Input Parameters:
249 . h - a `PetscLogHandler`
250 
251   Level: developer
252 
253   Notes:
254 
255   Users should only need this if they create their own log handlers: handlers that are started
256   from the command line (such as `-log_view` and `-log_trace`) or from a function like
257   `PetscLogNestedBegin()` will automatically be started.
258 
259   There is a limit of `PESC_LOG_HANDLER_MAX` handlers that can be active at one time.
260 
261   To disconnect a handler from the global stream call `PetscLogHandlerStop()`.
262 
263   When a log handler is started, stages that have already been pushed with `PetscLogStagePush()`,
264   will be pushed for the new log handler, but it will not be informed of any events that are
265   in progress.  It is recommended to start any user-defined log handlers immediately following
266   before any user-defined stages are pushed.
267 
268 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogHandlerStop()`
269 @*/
270 PetscErrorCode PetscLogHandlerStart(PetscLogHandler h)
271 {
272   PetscFunctionBegin;
273   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
274     if (PetscLogHandlers[i].handler == h) PetscFunctionReturn(PETSC_SUCCESS);
275   }
276   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
277     if (PetscLogHandlers[i].handler == NULL) {
278       PetscCall(PetscObjectReference((PetscObject)h));
279       PetscCall(PetscLogHandlerCopyToHot(h, &PetscLogHandlers[i]));
280       if (petsc_log_state) {
281         PetscLogStage stack_height;
282         PetscIntStack orig_stack, temp_stack;
283 
284         PetscCall(PetscLogHandlerSetState(h, petsc_log_state));
285         stack_height = petsc_log_state->stage_stack->top + 1;
286         PetscCall(PetscIntStackCreate(&temp_stack));
287         orig_stack                     = petsc_log_state->stage_stack;
288         petsc_log_state->stage_stack   = temp_stack;
289         petsc_log_state->current_stage = -1;
290         for (int s = 0; s < stack_height; s++) {
291           PetscLogStage stage = (PetscLogStage)orig_stack->stack[s];
292           PetscCall(PetscLogHandlerStagePush(h, stage));
293           PetscCall(PetscIntStackPush(temp_stack, stage));
294           petsc_log_state->current_stage = stage;
295         }
296         PetscCall(PetscIntStackDestroy(temp_stack));
297         petsc_log_state->stage_stack = orig_stack;
298       }
299       PetscFunctionReturn(PETSC_SUCCESS);
300     }
301   }
302   SETERRQ(PetscObjectComm((PetscObject)h), PETSC_ERR_ARG_WRONGSTATE, "%d log handlers already started, cannot start another", PETSC_LOG_HANDLER_MAX);
303   PetscFunctionReturn(PETSC_SUCCESS);
304 }
305 
306 /*@
307   PetscLogHandlerStop - Disconnect a log handler from PETSc's global logging stream.
308 
309   Logically collective
310 
311   Input Parameters:
312 . h - a `PetscLogHandler`
313 
314   Level: developer
315 
316   Note:
317   After `PetscLogHandlerStop()`, the handler can still access the global logging state
318   with `PetscLogHandlerGetState()`, so that it can access the registry when post-processing
319   (for instance, in `PetscLogHandlerView()`),
320 
321   When a log handler is stopped, the remaining stages will be popped before it is
322   disconnected from the log stream.
323 
324 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogHandlerStart()`
325 @*/
326 PetscErrorCode PetscLogHandlerStop(PetscLogHandler h)
327 {
328   PetscFunctionBegin;
329   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
330     if (PetscLogHandlers[i].handler == h) {
331       if (petsc_log_state) {
332         PetscLogState state;
333         PetscLogStage stack_height;
334         PetscIntStack orig_stack, temp_stack;
335 
336         PetscCall(PetscLogHandlerGetState(h, &state));
337         PetscCheck(state == petsc_log_state, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "Called PetscLogHandlerStop() for a PetscLogHander that was not started.");
338         stack_height = petsc_log_state->stage_stack->top + 1;
339         PetscCall(PetscIntStackCreate(&temp_stack));
340         orig_stack                   = petsc_log_state->stage_stack;
341         petsc_log_state->stage_stack = temp_stack;
342         for (int s = 0; s < stack_height; s++) {
343           PetscLogStage stage = (PetscLogStage)orig_stack->stack[s];
344 
345           PetscCall(PetscIntStackPush(temp_stack, stage));
346         }
347         for (int s = 0; s < stack_height; s++) {
348           PetscLogStage stage;
349           PetscBool     empty;
350 
351           PetscCall(PetscIntStackPop(temp_stack, &stage));
352           PetscCall(PetscIntStackEmpty(temp_stack, &empty));
353           if (!empty) {
354             PetscCall(PetscIntStackTop(temp_stack, &petsc_log_state->current_stage));
355           } else petsc_log_state->current_stage = -1;
356           PetscCall(PetscLogHandlerStagePop(h, stage));
357         }
358         PetscCall(PetscIntStackDestroy(temp_stack));
359         petsc_log_state->stage_stack = orig_stack;
360         PetscCall(PetscIntStackTop(petsc_log_state->stage_stack, &petsc_log_state->current_stage));
361       }
362       PetscCall(PetscArrayzero(&PetscLogHandlers[i], 1));
363       PetscCall(PetscObjectDereference((PetscObject)h));
364     }
365   }
366   PetscFunctionReturn(PETSC_SUCCESS);
367 }
368 
369 /*@C
370   PetscLogIsActive - Check if logging is currently in progress.
371 
372   Not Collective
373 
374   Output Parameter:
375 . isActive - `PETSC_TRUE` if logging is in progress, `PETSC_FALSE` otherwise
376 
377   Level: beginner
378 
379 .seealso: [](ch_profiling), `PetscLogDefaultBegin()`
380 @*/
381 PetscErrorCode PetscLogIsActive(PetscBool *isActive)
382 {
383   PetscFunctionBegin;
384   *isActive = PETSC_FALSE;
385   if (petsc_log_state) {
386     for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
387       if (PetscLogHandlers[i].handler) {
388         *isActive = PETSC_TRUE;
389         PetscFunctionReturn(PETSC_SUCCESS);
390       }
391     }
392   }
393   PetscFunctionReturn(PETSC_SUCCESS);
394 }
395 
396 PETSC_UNUSED static PetscErrorCode PetscLogEventBeginIsActive(PetscBool *isActive)
397 {
398   PetscFunctionBegin;
399   *isActive = PETSC_FALSE;
400   if (petsc_log_state) {
401     for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
402       if (PetscLogHandlers[i].eventBegin) {
403         *isActive = PETSC_TRUE;
404         PetscFunctionReturn(PETSC_SUCCESS);
405       }
406     }
407   }
408   PetscFunctionReturn(PETSC_SUCCESS);
409 }
410 
411 PETSC_UNUSED static PetscErrorCode PetscLogEventEndIsActive(PetscBool *isActive)
412 {
413   PetscFunctionBegin;
414   *isActive = PETSC_FALSE;
415   if (petsc_log_state) {
416     for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
417       if (PetscLogHandlers[i].eventEnd) {
418         *isActive = PETSC_TRUE;
419         PetscFunctionReturn(PETSC_SUCCESS);
420       }
421     }
422   }
423   PetscFunctionReturn(PETSC_SUCCESS);
424 }
425 
426 static PetscErrorCode PetscLogTypeBegin(PetscLogHandlerType type)
427 {
428   PetscLogHandler handler;
429 
430   PetscFunctionBegin;
431   PetscCall(PetscLogTryGetHandler(type, &handler));
432   if (handler) PetscFunctionReturn(PETSC_SUCCESS);
433   PetscCall(PetscLogHandlerCreate(PETSC_COMM_WORLD, &handler));
434   PetscCall(PetscLogHandlerSetType(handler, type));
435   PetscCall(PetscLogHandlerStart(handler));
436   PetscCall(PetscLogHandlerDestroy(&handler));
437   PetscFunctionReturn(PETSC_SUCCESS);
438 }
439 
440 /*@C
441   PetscLogDefaultBegin - Turns on logging of objects and events using the default log handler. This logs flop
442   rates and object creation and should not slow programs down too much.
443   This routine may be called more than once.
444 
445   Logically Collective over `PETSC_COMM_WORLD`
446 
447   Options Database Key:
448 . -log_view [viewertype:filename:viewerformat] - Prints summary of flop and timing information to the
449                   screen (for code configured with --with-log=1 (which is the default))
450 
451   Example Usage:
452 .vb
453       PetscInitialize(...);
454       PetscLogDefaultBegin();
455        ... code ...
456       PetscLogView(viewer); or PetscLogDump();
457       PetscFinalize();
458 .ve
459 
460   Level: advanced
461 
462   Note:
463   `PetscLogView()` or `PetscLogDump()` actually cause the printing of
464   the logging information.
465 
466 .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`
467 @*/
468 PetscErrorCode PetscLogDefaultBegin(void)
469 {
470   PetscFunctionBegin;
471   PetscCall(PetscLogTypeBegin(PETSC_LOG_HANDLER_DEFAULT));
472   PetscFunctionReturn(PETSC_SUCCESS);
473 }
474 
475 /*@C
476   PetscLogTraceBegin - Begins trace logging.  Every time a PETSc event
477   begins or ends, the event name is printed.
478 
479   Logically Collective on `PETSC_COMM_WORLD`
480 
481   Input Parameter:
482 . file - The file to print trace in (e.g. stdout)
483 
484   Options Database Key:
485 . -log_trace [filename] - Begins `PetscLogTraceBegin()`
486 
487   Level: intermediate
488 
489   Notes:
490   `PetscLogTraceBegin()` prints the processor number, the execution time (sec),
491   then "Event begin:" or "Event end:" followed by the event name.
492 
493   `PetscLogTraceBegin()` allows tracing of all PETSc calls, which is useful
494   to determine where a program is hanging without running in the
495   debugger.  Can be used in conjunction with the -info option.
496 
497 .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogView()`, `PetscLogDefaultBegin()`
498 @*/
499 PetscErrorCode PetscLogTraceBegin(FILE *file)
500 {
501   PetscLogHandler handler;
502   PetscFunctionBegin;
503   PetscCall(PetscLogTryGetHandler(PETSC_LOG_HANDLER_TRACE, &handler));
504   if (handler) PetscFunctionReturn(PETSC_SUCCESS);
505   PetscCall(PetscLogHandlerCreateTrace(PETSC_COMM_WORLD, file, &handler));
506   PetscCall(PetscLogHandlerStart(handler));
507   PetscCall(PetscLogHandlerDestroy(&handler));
508   PetscFunctionReturn(PETSC_SUCCESS);
509 }
510 
511 PETSC_INTERN PetscErrorCode PetscLogHandlerCreate_Nested(MPI_Comm, PetscLogHandler *);
512 
513 /*@C
514   PetscLogNestedBegin - Turns on nested logging of objects and events. This logs flop
515   rates and object creation and should not slow programs down too much.
516 
517   Logically Collective over `PETSC_COMM_WORLD`
518 
519   Options Database Keys:
520 . -log_view :filename.xml:ascii_xml - Prints an XML summary of flop and timing information to the file
521 
522   Example Usage:
523 .vb
524       PetscInitialize(...);
525       PetscLogNestedBegin();
526        ... code ...
527       PetscLogView(viewer);
528       PetscFinalize();
529 .ve
530 
531   Level: advanced
532 
533 .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`
534 @*/
535 PetscErrorCode PetscLogNestedBegin(void)
536 {
537   PetscFunctionBegin;
538   PetscCall(PetscLogTypeBegin(PETSC_LOG_HANDLER_NESTED));
539   PetscFunctionReturn(PETSC_SUCCESS);
540 }
541 
542 /*@C
543   PetscLogLegacyCallbacksBegin - Create and start a log handler from callbacks
544   matching the now deprecated function pointers `PetscLogPLB`, `PetscLogPLE`,
545   `PetscLogPHC`, `PetscLogPHD`.
546 
547   Logically Collective over `PETSC_COMM_WORLD`
548 
549   Input Parameters:
550 + PetscLogPLB - A callback that will be executed by `PetscLogEventBegin()` (or `NULL`)
551 . PetscLogPLE - A callback that will be executed by `PetscLogEventEnd()` (or `NULL`)
552 . PetscLogPHC - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`)
553 - PetscLogPHD - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`)
554 
555   Calling sequence of `PetscLogPLB`:
556 + e  - a `PetscLogEvent` that is beginning
557 . _i - deprecated, unused
558 . o1 - a `PetscObject` associated with `e` (or `NULL`)
559 . o2 - a `PetscObject` associated with `e` (or `NULL`)
560 . o3 - a `PetscObject` associated with `e` (or `NULL`)
561 - o4 - a `PetscObject` associated with `e` (or `NULL`)
562 
563   Calling sequence of `PetscLogPLE`:
564 + e  - a `PetscLogEvent` that is beginning
565 . _i - deprecated, unused
566 . o1 - a `PetscObject` associated with `e` (or `NULL`)
567 . o2 - a `PetscObject` associated with `e` (or `NULL`)
568 . o3 - a `PetscObject` associated with `e` (or `NULL`)
569 - o4 - a `PetscObject` associated with `e` (or `NULL`)
570 
571   Calling sequence of `PetscLogPHC`:
572 . o - a `PetscObject` that has just been created
573 
574   Calling sequence of `PetscLogPHD`:
575 . o - a `PetscObject` that is about to be destroyed
576 
577   Level: advanced
578 
579   Notes:
580   This is for transitioning from the deprecated function `PetscLogSet()` and should not be used in new code.
581 
582   This should help migrate external log handlers to use `PetscLogHandler`, but
583   callbacks that depend on the deprecated `PetscLogStage` datatype will have to be
584   updated.
585 
586 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerStart()`, `PetscLogState`
587 @*/
588 PetscErrorCode PetscLogLegacyCallbacksBegin(PetscErrorCode (*PetscLogPLB)(PetscLogEvent e, int _i, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4), PetscErrorCode (*PetscLogPLE)(PetscLogEvent e, int _i, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4), PetscErrorCode (*PetscLogPHC)(PetscObject o), PetscErrorCode (*PetscLogPHD)(PetscObject o))
589 {
590   PetscLogHandler handler;
591 
592   PetscFunctionBegin;
593   PetscCall(PetscLogHandlerCreateLegacy(PETSC_COMM_WORLD, PetscLogPLB, PetscLogPLE, PetscLogPHC, PetscLogPHD, &handler));
594   PetscCall(PetscLogHandlerStart(handler));
595   PetscCall(PetscLogHandlerDestroy(&handler));
596   PetscFunctionReturn(PETSC_SUCCESS);
597 }
598 
599   #if defined(PETSC_HAVE_MPE)
600     #include <mpe.h>
601 static PetscBool PetscBeganMPE = PETSC_FALSE;
602   #endif
603 
604 /*@C
605   PetscLogMPEBegin - Turns on MPE logging of events. This creates large log files and slows the
606   program down.
607 
608   Collective over `PETSC_COMM_WORLD`
609 
610   Options Database Key:
611 . -log_mpe - Prints extensive log information
612 
613   Level: advanced
614 
615   Note:
616   A related routine is `PetscLogDefaultBegin()` (with the options key `-log_view`), which is
617   intended for production runs since it logs only flop rates and object creation (and should
618   not significantly slow the programs).
619 
620 .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogDefaultBegin()`, `PetscLogEventActivate()`,
621           `PetscLogEventDeactivate()`
622 @*/
623 PetscErrorCode PetscLogMPEBegin(void)
624 {
625   PetscFunctionBegin;
626   #if defined(PETSC_HAVE_MPE)
627   /* Do MPE initialization */
628   if (!MPE_Initialized_logging()) { /* This function exists in mpich 1.1.2 and higher */
629     PetscCall(PetscInfo(0, "Initializing MPE.\n"));
630     PetscCall(MPE_Init_log());
631 
632     PetscBeganMPE = PETSC_TRUE;
633   } else {
634     PetscCall(PetscInfo(0, "MPE already initialized. Not attempting to reinitialize.\n"));
635   }
636   PetscCall(PetscLogTypeBegin(PETSC_LOG_HANDLER_MPE));
637   #else
638   SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe");
639   #endif
640   PetscFunctionReturn(PETSC_SUCCESS);
641 }
642 
643   #if defined(PETSC_HAVE_TAU_PERFSTUBS)
644     #include <../src/sys/perfstubs/timer.h>
645   #endif
646 
647 /*@C
648   PetscLogPerfstubsBegin - Turns on logging of events using the perfstubs interface.
649 
650   Collective over `PETSC_COMM_WORLD`
651 
652   Options Database Key:
653 . -log_perfstubs - use an external log handler through the perfstubs interface
654 
655   Level: advanced
656 
657 .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogEventActivate()`
658 @*/
659 PetscErrorCode PetscLogPerfstubsBegin(void)
660 {
661   PetscFunctionBegin;
662   #if defined(PETSC_HAVE_TAU_PERFSTUBS)
663   PetscCall(PetscLogTypeBegin(PETSC_LOG_HANDLER_PERFSTUBS));
664   #else
665   SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without perfstubs support, reconfigure with --with-tau-perfstubs");
666   #endif
667   PetscFunctionReturn(PETSC_SUCCESS);
668 }
669 
670 /*@
671   PetscLogActions - Determines whether actions are logged for the default log handler.
672 
673   Not Collective
674 
675   Input Parameter:
676 . flag - `PETSC_TRUE` if actions are to be logged
677 
678   Options Database Key:
679 + -log_exclude_actions - (deprecated) Does nothing
680 - -log_include_actions - Turn on action logging
681 
682   Level: intermediate
683 
684   Note:
685   Logging of actions continues to consume more memory as the program
686   runs. Long running programs should consider turning this feature off.
687 
688 .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogGetDefaultHandler()`
689 @*/
690 PetscErrorCode PetscLogActions(PetscBool flag)
691 {
692   PetscLogHandler handler;
693 
694   PetscFunctionBegin;
695   PetscCall(PetscLogTryGetHandler(PETSC_LOG_HANDLER_DEFAULT, &handler));
696   if (handler) PetscCall(PetscLogHandlerDefaultSetLogActions(handler, flag));
697   PetscFunctionReturn(PETSC_SUCCESS);
698 }
699 
700 /*@
701   PetscLogObjects - Determines whether objects are logged for the graphical viewer.
702 
703   Not Collective
704 
705   Input Parameter:
706 . flag - `PETSC_TRUE` if objects are to be logged
707 
708   Options Database Key:
709 + -log_exclude_objects - (deprecated) Does nothing
710 - -log_include_objects - Turns on object logging
711 
712   Level: intermediate
713 
714   Note:
715   Logging of objects continues to consume more memory as the program
716   runs. Long running programs should consider turning this feature off.
717 
718 .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogGetDefaultHandler()`
719 @*/
720 PetscErrorCode PetscLogObjects(PetscBool flag)
721 {
722   PetscLogHandler handler;
723 
724   PetscFunctionBegin;
725   PetscCall(PetscLogTryGetHandler(PETSC_LOG_HANDLER_DEFAULT, &handler));
726   if (handler) PetscCall(PetscLogHandlerDefaultSetLogObjects(handler, flag));
727   PetscFunctionReturn(PETSC_SUCCESS);
728 }
729 
730 /*------------------------------------------------ Stage Functions --------------------------------------------------*/
731 /*@C
732   PetscLogStageRegister - Attaches a character string name to a logging stage.
733 
734   Not Collective
735 
736   Input Parameter:
737 . sname - The name to associate with that stage
738 
739   Output Parameter:
740 . stage - The stage number or -1 if logging is not active (`PetscLogIsActive()`).
741 
742   Level: intermediate
743 
744 .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`
745 @*/
746 PetscErrorCode PetscLogStageRegister(const char sname[], PetscLogStage *stage)
747 {
748   PetscLogState state;
749 
750   PetscFunctionBegin;
751   *stage = -1;
752   PetscCall(PetscLogGetState(&state));
753   if (state) PetscCall(PetscLogStateStageRegister(state, sname, stage));
754   PetscFunctionReturn(PETSC_SUCCESS);
755 }
756 
757 /*@C
758   PetscLogStagePush - This function pushes a stage on the logging stack. Events started and stopped until `PetscLogStagePop()` will be associated with the stage
759 
760   Not Collective
761 
762   Input Parameter:
763 . stage - The stage on which to log
764 
765   Example Usage:
766   If the option -log_view is used to run the program containing the
767   following code, then 2 sets of summary data will be printed during
768   PetscFinalize().
769 .vb
770       PetscInitialize(int *argc,char ***args,0,0);
771       [stage 0 of code]
772       PetscLogStagePush(1);
773       [stage 1 of code]
774       PetscLogStagePop();
775       PetscBarrier(...);
776       [more stage 0 of code]
777       PetscFinalize();
778 .ve
779 
780   Level: intermediate
781 
782   Note:
783   Use `PetscLogStageRegister()` to register a stage.
784 
785 .seealso: [](ch_profiling), `PetscLogStagePop()`, `PetscLogStageRegister()`, `PetscBarrier()`
786 @*/
787 PetscErrorCode PetscLogStagePush(PetscLogStage stage)
788 {
789   PetscLogState state;
790 
791   PetscFunctionBegin;
792   PetscCall(PetscLogGetState(&state));
793   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
794   for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
795     PetscLogHandler h = PetscLogHandlers[i].handler;
796     if (h) PetscCall(PetscLogHandlerStagePush(h, stage));
797   }
798   PetscCall(PetscLogStateStagePush(state, stage));
799   PetscFunctionReturn(PETSC_SUCCESS);
800 }
801 
802 /*@C
803   PetscLogStagePop - This function pops a stage from the logging stack that was pushed with `PetscLogStagePush()`
804 
805   Not Collective
806 
807   Example Usage:
808   If the option -log_view is used to run the program containing the
809   following code, then 2 sets of summary data will be printed during
810   PetscFinalize().
811 .vb
812       PetscInitialize(int *argc,char ***args,0,0);
813       [stage 0 of code]
814       PetscLogStagePush(1);
815       [stage 1 of code]
816       PetscLogStagePop();
817       PetscBarrier(...);
818       [more stage 0 of code]
819       PetscFinalize();
820 .ve
821 
822   Level: intermediate
823 
824 .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStageRegister()`, `PetscBarrier()`
825 @*/
826 PetscErrorCode PetscLogStagePop(void)
827 {
828   PetscLogState state;
829   PetscLogStage current_stage;
830 
831   PetscFunctionBegin;
832   PetscCall(PetscLogGetState(&state));
833   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
834   current_stage = state->current_stage;
835   PetscCall(PetscLogStateStagePop(state));
836   for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
837     PetscLogHandler h = PetscLogHandlers[i].handler;
838     if (h) PetscCall(PetscLogHandlerStagePop(h, current_stage));
839   }
840   PetscFunctionReturn(PETSC_SUCCESS);
841 }
842 
843 /*@
844   PetscLogStageSetActive - Sets if a stage is used for `PetscLogEventBegin()` and `PetscLogEventEnd()`.
845 
846   Not Collective
847 
848   Input Parameters:
849 + stage    - The stage
850 - isActive - The activity flag, `PETSC_TRUE` for logging, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
851 
852   Level: intermediate
853 
854   Note:
855   If this is set to `PETSC_FALSE` the logging acts as if the stage did not exist
856 
857 .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
858 @*/
859 PetscErrorCode PetscLogStageSetActive(PetscLogStage stage, PetscBool isActive)
860 {
861   PetscLogState state;
862 
863   PetscFunctionBegin;
864   PetscCall(PetscLogGetState(&state));
865   if (state) PetscCall(PetscLogStateStageSetActive(state, stage, isActive));
866   PetscFunctionReturn(PETSC_SUCCESS);
867 }
868 
869 /*@
870   PetscLogStageGetActive - Checks if a stage is used for `PetscLogEventBegin()` and `PetscLogEventEnd()`.
871 
872   Not Collective
873 
874   Input Parameter:
875 . stage - The stage
876 
877   Output Parameter:
878 . isActive - The activity flag, `PETSC_TRUE` for logging, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
879 
880   Level: intermediate
881 
882 .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
883 @*/
884 PetscErrorCode PetscLogStageGetActive(PetscLogStage stage, PetscBool *isActive)
885 {
886   PetscLogState state;
887 
888   PetscFunctionBegin;
889   *isActive = PETSC_FALSE;
890   PetscCall(PetscLogGetState(&state));
891   if (state) PetscCall(PetscLogStateStageGetActive(state, stage, isActive));
892   PetscFunctionReturn(PETSC_SUCCESS);
893 }
894 
895 /*@
896   PetscLogStageSetVisible - Determines stage visibility in `PetscLogView()`
897 
898   Not Collective
899 
900   Input Parameters:
901 + stage     - The stage
902 - isVisible - The visibility flag, `PETSC_TRUE` to print, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
903 
904   Level: intermediate
905 
906   Developer Notes:
907   Visibility only affects the default log handler in `PetscLogView()`: stages that are
908   set to invisible are suppressed from output.
909 
910 .seealso: [](ch_profiling), `PetscLogStageGetVisible()`, `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
911 @*/
912 PetscErrorCode PetscLogStageSetVisible(PetscLogStage stage, PetscBool isVisible)
913 {
914   PetscLogHandler handler;
915 
916   PetscFunctionBegin;
917   PetscCall(PetscLogTryGetHandler(PETSC_LOG_HANDLER_DEFAULT, &handler));
918   if (handler) { PetscCall(PetscLogHandlerDefaultStageSetVisible(handler, stage, isVisible)); }
919   PetscFunctionReturn(PETSC_SUCCESS);
920 }
921 
922 /*@
923   PetscLogStageGetVisible - Returns stage visibility in `PetscLogView()`
924 
925   Not Collective
926 
927   Input Parameter:
928 . stage - The stage
929 
930   Output Parameter:
931 . isVisible - The visibility flag, `PETSC_TRUE` to print, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
932 
933   Level: intermediate
934 
935 .seealso: [](ch_profiling), `PetscLogStageSetVisible()`, `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
936 @*/
937 PetscErrorCode PetscLogStageGetVisible(PetscLogStage stage, PetscBool *isVisible)
938 {
939   PetscLogHandler handler;
940 
941   PetscFunctionBegin;
942   *isVisible = PETSC_FALSE;
943   PetscCall(PetscLogTryGetHandler(PETSC_LOG_HANDLER_DEFAULT, &handler));
944   if (handler) { PetscCall(PetscLogHandlerDefaultStageGetVisible(handler, stage, isVisible)); }
945   PetscFunctionReturn(PETSC_SUCCESS);
946 }
947 
948 /*@C
949   PetscLogStageGetId - Returns the stage id when given the stage name.
950 
951   Not Collective
952 
953   Input Parameter:
954 . name - The stage name
955 
956   Output Parameter:
957 . stage - The stage, , or -1 if no stage with that name exists
958 
959   Level: intermediate
960 
961 .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
962 @*/
963 PetscErrorCode PetscLogStageGetId(const char name[], PetscLogStage *stage)
964 {
965   PetscLogState state;
966 
967   PetscFunctionBegin;
968   *stage = -1;
969   PetscCall(PetscLogGetState(&state));
970   if (state) PetscCall(PetscLogStateGetStageFromName(state, name, stage));
971   PetscFunctionReturn(PETSC_SUCCESS);
972 }
973 
974 /*@C
975   PetscLogStageGetName - Returns the stage name when given the stage id.
976 
977   Not Collective
978 
979   Input Parameter:
980 . stage - The stage
981 
982   Output Parameter:
983 . name - The stage name
984 
985   Level: intermediate
986 
987 .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
988 @*/
989 PetscErrorCode PetscLogStageGetName(PetscLogStage stage, const char **name)
990 {
991   PetscLogStageInfo stage_info;
992   PetscLogState     state;
993 
994   PetscFunctionBegin;
995   *name = NULL;
996   PetscCall(PetscLogGetState(&state));
997   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
998   PetscCall(PetscLogStateStageGetInfo(state, stage, &stage_info));
999   *name = stage_info.name;
1000   PetscFunctionReturn(PETSC_SUCCESS);
1001 }
1002 
1003 /*------------------------------------------------ Event Functions --------------------------------------------------*/
1004 
1005 /*@C
1006   PetscLogEventRegister - Registers an event name for logging operations
1007 
1008   Not Collective
1009 
1010   Input Parameters:
1011 + name    - The name associated with the event
1012 - classid - The classid associated to the class for this event, obtain either with
1013            `PetscClassIdRegister()` or use a predefined one such as `KSP_CLASSID`, `SNES_CLASSID`, the predefined ones
1014            are only available in C code
1015 
1016   Output Parameter:
1017 . event - The event id for use with `PetscLogEventBegin()` and `PetscLogEventEnd()`.
1018 
1019   Example Usage:
1020 .vb
1021       PetscLogEvent USER_EVENT;
1022       PetscClassId classid;
1023       PetscLogDouble user_event_flops;
1024       PetscClassIdRegister("class name",&classid);
1025       PetscLogEventRegister("User event name",classid,&USER_EVENT);
1026       PetscLogEventBegin(USER_EVENT,0,0,0,0);
1027          [code segment to monitor]
1028          PetscLogFlops(user_event_flops);
1029       PetscLogEventEnd(USER_EVENT,0,0,0,0);
1030 .ve
1031 
1032   Level: intermediate
1033 
1034   Notes:
1035   PETSc automatically logs library events if the code has been
1036   configured with --with-log (which is the default) and
1037   -log_view or -log_all is specified.  `PetscLogEventRegister()` is
1038   intended for logging user events to supplement this PETSc
1039   information.
1040 
1041   PETSc can gather data for use with the utilities Jumpshot
1042   (part of the MPICH distribution).  If PETSc has been compiled
1043   with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
1044   MPICH), the user can employ another command line option, -log_mpe,
1045   to create a logfile, "mpe.log", which can be visualized
1046   Jumpshot.
1047 
1048   The classid is associated with each event so that classes of events
1049   can be disabled simultaneously, such as all matrix events. The user
1050   can either use an existing classid, such as `MAT_CLASSID`, or create
1051   their own as shown in the example.
1052 
1053   If an existing event with the same name exists, its event handle is
1054   returned instead of creating a new event.
1055 
1056 .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogFlops()`,
1057           `PetscLogEventActivate()`, `PetscLogEventDeactivate()`, `PetscClassIdRegister()`
1058 @*/
1059 PetscErrorCode PetscLogEventRegister(const char name[], PetscClassId classid, PetscLogEvent *event)
1060 {
1061   PetscLogState state;
1062 
1063   PetscFunctionBegin;
1064   *event = -1;
1065   PetscCall(PetscLogGetState(&state));
1066   if (state) PetscCall(PetscLogStateEventRegister(state, name, classid, event));
1067   PetscFunctionReturn(PETSC_SUCCESS);
1068 }
1069 
1070 /*@
1071   PetscLogEventSetCollective - Indicates that a particular event is collective.
1072 
1073   Not Collective
1074 
1075   Input Parameters:
1076 + event      - The event id
1077 - collective - Boolean flag indicating whether a particular event is collective
1078 
1079   Level: developer
1080 
1081   Notes:
1082   New events returned from `PetscLogEventRegister()` are collective by default.
1083 
1084   Collective events are handled specially if the -log_sync is used. In that case the logging saves information about
1085   two parts of the event; the time for all the MPI ranks to synchronize and then the time for the actual computation/communication
1086   to be performed. This option is useful to debug imbalance within the computations or communications
1087 
1088 .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventRegister()`
1089 @*/
1090 PetscErrorCode PetscLogEventSetCollective(PetscLogEvent event, PetscBool collective)
1091 {
1092   PetscLogState state;
1093 
1094   PetscFunctionBegin;
1095   PetscCall(PetscLogGetState(&state));
1096   if (state) PetscCall(PetscLogStateEventSetCollective(state, event, collective));
1097   PetscFunctionReturn(PETSC_SUCCESS);
1098 }
1099 
1100 /*
1101   PetscLogClassSetActiveAll - Activate or inactivate logging for all events associated with a PETSc object class in every stage.
1102 
1103   Not Collective
1104 
1105   Input Parameters:
1106 + classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1107 - isActive - if `PETSC_FALSE`, events associated with this class will not be send to log handlers.
1108 
1109   Level: developer
1110 
1111 .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventActivateAll()`, `PetscLogStageSetActive()`, `PetscLogEventActivateClass()`
1112 */
1113 static PetscErrorCode PetscLogClassSetActiveAll(PetscClassId classid, PetscBool isActive)
1114 {
1115   PetscLogState state;
1116 
1117   PetscFunctionBegin;
1118   PetscCall(PetscLogGetState(&state));
1119   if (state) PetscCall(PetscLogStateClassSetActiveAll(state, classid, isActive));
1120   PetscFunctionReturn(PETSC_SUCCESS);
1121 }
1122 
1123 /*@
1124   PetscLogEventIncludeClass - Activates event logging for a PETSc object class in every stage.
1125 
1126   Not Collective
1127 
1128   Input Parameter:
1129 . classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1130 
1131   Level: developer
1132 
1133 .seealso: [](ch_profiling), `PetscLogEventActivateClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1134 @*/
1135 PetscErrorCode PetscLogEventIncludeClass(PetscClassId classid)
1136 {
1137   PetscFunctionBegin;
1138   PetscCall(PetscLogClassSetActiveAll(classid, PETSC_TRUE));
1139   PetscFunctionReturn(PETSC_SUCCESS);
1140 }
1141 
1142 /*@
1143   PetscLogEventExcludeClass - Deactivates event logging for a PETSc object class in every stage.
1144 
1145   Not Collective
1146 
1147   Input Parameter:
1148 . classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1149 
1150   Level: developer
1151 
1152   Note:
1153   If a class is excluded then events associated with that class are not logged.
1154 
1155 .seealso: [](ch_profiling), `PetscLogEventDeactivateClass()`, `PetscLogEventActivateClass()`, `PetscLogEventDeactivate()`, `PetscLogEventActivate()`
1156 @*/
1157 PetscErrorCode PetscLogEventExcludeClass(PetscClassId classid)
1158 {
1159   PetscFunctionBegin;
1160   PetscCall(PetscLogClassSetActiveAll(classid, PETSC_FALSE));
1161   PetscFunctionReturn(PETSC_SUCCESS);
1162 }
1163 
1164 /*
1165   PetscLogEventSetActive - Activate or inactivate logging for an event in a given stage
1166 
1167   Not Collective
1168 
1169   Input Parameters:
1170 + stage - A registered `PetscLogStage` (or `PETSC_DEFAULT` for the current stage)
1171 . event - A `PetscLogEvent`
1172 - isActive - If `PETSC_FALSE`, activity from this event (`PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventSync()`) will not be sent to log handlers during this stage
1173 
1174   Usage:
1175 .vb
1176       PetscLogEventSetActive(VEC_SetValues, PETSC_FALSE);
1177         [code where you do not want to log VecSetValues()]
1178       PetscLogEventSetActive(VEC_SetValues, PETSC_TRUE);
1179         [code where you do want to log VecSetValues()]
1180 .ve
1181 
1182   Level: advanced
1183 
1184   Note:
1185   The event may be either a pre-defined PETSc event (found in include/petsclog.h)
1186   or an event number obtained with `PetscLogEventRegister()`.
1187 
1188 .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1189 */
1190 static PetscErrorCode PetscLogEventSetActive(PetscLogStage stage, PetscLogEvent event, PetscBool isActive)
1191 {
1192   PetscLogState state;
1193 
1194   PetscFunctionBegin;
1195   PetscCall(PetscLogGetState(&state));
1196   if (state) PetscCall(PetscLogStateEventSetActive(state, stage, event, isActive));
1197   PetscFunctionReturn(PETSC_SUCCESS);
1198 }
1199 
1200 /*@
1201   PetscLogEventActivate - Indicates that a particular event should be logged.
1202 
1203   Not Collective
1204 
1205   Input Parameter:
1206 . event - The event id
1207 
1208   Example Usage:
1209 .vb
1210       PetscLogEventDeactivate(VEC_SetValues);
1211         [code where you do not want to log VecSetValues()]
1212       PetscLogEventActivate(VEC_SetValues);
1213         [code where you do want to log VecSetValues()]
1214 .ve
1215 
1216   Level: advanced
1217 
1218   Note:
1219   The event may be either a pre-defined PETSc event (found in include/petsclog.h)
1220   or an event number obtained with `PetscLogEventRegister()`.
1221 
1222 .seealso: [](ch_profiling), `PetscLogEventDeactivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1223 @*/
1224 PetscErrorCode PetscLogEventActivate(PetscLogEvent event)
1225 {
1226   PetscFunctionBegin;
1227   PetscCall(PetscLogEventSetActive(PETSC_DEFAULT, event, PETSC_TRUE));
1228   PetscFunctionReturn(PETSC_SUCCESS);
1229 }
1230 
1231 /*@
1232   PetscLogEventDeactivate - Indicates that a particular event should not be logged.
1233 
1234   Not Collective
1235 
1236   Input Parameter:
1237 . event - The event id
1238 
1239   Example Usage:
1240 .vb
1241       PetscLogEventDeactivate(VEC_SetValues);
1242         [code where you do not want to log VecSetValues()]
1243       PetscLogEventActivate(VEC_SetValues);
1244         [code where you do want to log VecSetValues()]
1245 .ve
1246 
1247   Level: advanced
1248 
1249   Note:
1250   The event may be either a pre-defined PETSc event (found in
1251   include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1252 
1253 .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1254 @*/
1255 PetscErrorCode PetscLogEventDeactivate(PetscLogEvent event)
1256 {
1257   PetscFunctionBegin;
1258   PetscCall(PetscLogEventSetActive(PETSC_DEFAULT, event, PETSC_FALSE));
1259   PetscFunctionReturn(PETSC_SUCCESS);
1260 }
1261 
1262 /*@
1263   PetscLogEventDeactivatePush - Indicates that a particular event should not be logged until `PetscLogEventDeactivatePop()` is called
1264 
1265   Not Collective
1266 
1267   Input Parameter:
1268 . event - The event id
1269 
1270   Example Usage:
1271 .vb
1272       PetscLogEventDeactivatePush(VEC_SetValues);
1273         [code where you do not want to log VecSetValues()]
1274       PetscLogEventDeactivatePop(VEC_SetValues);
1275         [code where you do want to log VecSetValues()]
1276 .ve
1277 
1278   Level: advanced
1279 
1280   Note:
1281   The event may be either a pre-defined PETSc event (found in
1282   include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1283 
1284   PETSc's default log handler (`PetscLogDefaultBegin()`) respects this function because it can make the output of `PetscLogView()` easier to interpret, but other handlers (such as the nested handler, `PetscLogNestedBegin()`) ignore it because surpressing events is not helpful in their output formats.
1285 
1286 .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEVentDeactivate()`, `PetscLogEventDeactivatePop()`
1287 @*/
1288 PetscErrorCode PetscLogEventDeactivatePush(PetscLogEvent event)
1289 {
1290   PetscLogHandler handler;
1291 
1292   PetscFunctionBegin;
1293   PetscCall(PetscLogTryGetHandler(PETSC_LOG_HANDLER_DEFAULT, &handler));
1294   if (handler) { PetscCall(PetscLogHandlerDefaultDeactivatePush(handler, PETSC_DEFAULT, event)); }
1295   PetscFunctionReturn(PETSC_SUCCESS);
1296 }
1297 
1298 /*@
1299   PetscLogEventDeactivatePop - Indicates that a particular event should again be logged after the logging was turned off with `PetscLogEventDeactivatePush()`
1300 
1301   Not Collective
1302 
1303   Input Parameter:
1304 . event - The event id
1305 
1306   Example Usage:
1307 .vb
1308       PetscLogEventDeactivatePush(VEC_SetValues);
1309         [code where you do not want to log VecSetValues()]
1310       PetscLogEventDeactivatePop(VEC_SetValues);
1311         [code where you do want to log VecSetValues()]
1312 .ve
1313 
1314   Level: advanced
1315 
1316   Note:
1317   The event may be either a pre-defined PETSc event (found in
1318   include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1319 
1320 .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`
1321 @*/
1322 PetscErrorCode PetscLogEventDeactivatePop(PetscLogEvent event)
1323 {
1324   PetscLogHandler handler;
1325 
1326   PetscFunctionBegin;
1327   PetscCall(PetscLogTryGetHandler(PETSC_LOG_HANDLER_DEFAULT, &handler));
1328   if (handler) { PetscCall(PetscLogHandlerDefaultDeactivatePop(handler, PETSC_DEFAULT, event)); }
1329   PetscFunctionReturn(PETSC_SUCCESS);
1330 }
1331 
1332 /*@
1333   PetscLogEventSetActiveAll - Turns on logging of all events
1334 
1335   Not Collective
1336 
1337   Input Parameters:
1338 + event    - The event id
1339 - isActive - The activity flag determining whether the event is logged
1340 
1341   Level: advanced
1342 
1343 .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1344 @*/
1345 PetscErrorCode PetscLogEventSetActiveAll(PetscLogEvent event, PetscBool isActive)
1346 {
1347   PetscLogState state;
1348 
1349   PetscFunctionBegin;
1350   PetscCall(PetscLogGetState(&state));
1351   if (state) PetscCall(PetscLogStateEventSetActiveAll(state, event, isActive));
1352   PetscFunctionReturn(PETSC_SUCCESS);
1353 }
1354 
1355 /*
1356   PetscLogClassSetActive - Activates event logging for a PETSc object class for the current stage
1357 
1358   Not Collective
1359 
1360   Input Parameters:
1361 + stage - A registered `PetscLogStage` (or `PETSC_DEFAULT` for the current stage)
1362 . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1363 - isActive - If `PETSC_FALSE`, events associated with this class are not sent to log handlers.
1364 
1365   Level: developer
1366 
1367 .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventActivate()`, `PetscLogEventActivateAll()`, `PetscLogStageSetActive()`
1368 */
1369 static PetscErrorCode PetscLogClassSetActive(PetscLogStage stage, PetscClassId classid, PetscBool isActive)
1370 {
1371   PetscLogState state;
1372 
1373   PetscFunctionBegin;
1374   PetscCall(PetscLogGetState(&state));
1375   if (state) PetscCall(PetscLogStateClassSetActive(state, stage, classid, isActive));
1376   PetscFunctionReturn(PETSC_SUCCESS);
1377 }
1378 
1379 /*@
1380   PetscLogEventActivateClass - Activates event logging for a PETSc object class for the current stage
1381 
1382   Not Collective
1383 
1384   Input Parameter:
1385 . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1386 
1387   Level: developer
1388 
1389 .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1390 @*/
1391 PetscErrorCode PetscLogEventActivateClass(PetscClassId classid)
1392 {
1393   PetscFunctionBegin;
1394   PetscCall(PetscLogClassSetActive(PETSC_DEFAULT, classid, PETSC_TRUE));
1395   PetscFunctionReturn(PETSC_SUCCESS);
1396 }
1397 
1398 /*@
1399   PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class for the current stage
1400 
1401   Not Collective
1402 
1403   Input Parameter:
1404 . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1405 
1406   Level: developer
1407 
1408 .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventActivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1409 @*/
1410 PetscErrorCode PetscLogEventDeactivateClass(PetscClassId classid)
1411 {
1412   PetscFunctionBegin;
1413   PetscCall(PetscLogClassSetActive(PETSC_DEFAULT, classid, PETSC_FALSE));
1414   PetscFunctionReturn(PETSC_SUCCESS);
1415 }
1416 
1417 /*MC
1418   PetscLogEventSync - Synchronizes the beginning of a user event.
1419 
1420   Synopsis:
1421   #include <petsclog.h>
1422   PetscErrorCode PetscLogEventSync(PetscLogEvent e, MPI_Comm comm)
1423 
1424   Collective
1425 
1426   Input Parameters:
1427 + e    - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1428 - comm - an MPI communicator
1429 
1430   Example Usage:
1431 .vb
1432   PetscLogEvent USER_EVENT;
1433 
1434   PetscLogEventRegister("User event", 0, &USER_EVENT);
1435   PetscLogEventSync(USER_EVENT, PETSC_COMM_WORLD);
1436   PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1437   [code segment to monitor]
1438   PetscLogEventEnd(USER_EVENT, 0, 0, 0 , 0);
1439 .ve
1440 
1441   Level: developer
1442 
1443   Note:
1444   This routine should be called only if there is not a `PetscObject` available to pass to
1445   `PetscLogEventBegin()`.
1446 
1447 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`
1448 M*/
1449 
1450 /*MC
1451   PetscLogEventBegin - Logs the beginning of a user event.
1452 
1453   Synopsis:
1454   #include <petsclog.h>
1455   PetscErrorCode PetscLogEventBegin(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
1456 
1457   Not Collective
1458 
1459   Input Parameters:
1460 + e  - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1461 . o1 - object assocated with the event, or NULL
1462 . o2 - object assocated with the event, or NULL
1463 . o3 - object assocated with the event, or NULL
1464 - o4 - object assocated with the event, or NULL
1465 
1466   Fortran Synopsis:
1467   void PetscLogEventBegin(int e, PetscErrorCode ierr)
1468 
1469   Example Usage:
1470 .vb
1471   PetscLogEvent USER_EVENT;
1472 
1473   PetscLogDouble user_event_flops;
1474   PetscLogEventRegister("User event",0, &USER_EVENT);
1475   PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1476   [code segment to monitor]
1477   PetscLogFlops(user_event_flops);
1478   PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
1479 .ve
1480 
1481   Level: intermediate
1482 
1483   Developer Note:
1484   `PetscLogEventBegin()` and `PetscLogEventBegin()` return error codes instead of explicitly
1485   handling the errors that occur in the macro directly because other packages that use this
1486   macros have used them in their own functions or methods that do not return error codes and it
1487   would be disruptive to change the current behavior.
1488 
1489 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventEnd()`, `PetscLogFlops()`
1490 M*/
1491 
1492 /*MC
1493   PetscLogEventEnd - Log the end of a user event.
1494 
1495   Synopsis:
1496   #include <petsclog.h>
1497   PetscErrorCode PetscLogEventEnd(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
1498 
1499   Not Collective
1500 
1501   Input Parameters:
1502 + e  - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1503 . o1 - object assocated with the event, or NULL
1504 . o2 - object assocated with the event, or NULL
1505 . o3 - object assocated with the event, or NULL
1506 - o4 - object assocated with the event, or NULL
1507 
1508   Fortran Synopsis:
1509   void PetscLogEventEnd(int e, PetscErrorCode ierr)
1510 
1511   Example Usage:
1512 .vb
1513   PetscLogEvent USER_EVENT;
1514 
1515   PetscLogDouble user_event_flops;
1516   PetscLogEventRegister("User event", 0, &USER_EVENT);
1517   PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1518   [code segment to monitor]
1519   PetscLogFlops(user_event_flops);
1520   PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
1521 .ve
1522 
1523   Level: intermediate
1524 
1525 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogFlops()`
1526 M*/
1527 
1528 /*@C
1529   PetscLogEventGetPerfInfo - Return the performance information about the given event in the given stage
1530 
1531   Input Parameters:
1532 + stage - The stage number or `PETSC_DETERMINE` for the current stage
1533 - event - The event number
1534 
1535   Output Parameter:
1536 . info - This structure is filled with the performance information
1537 
1538   Level: intermediate
1539 
1540   Note:
1541   This is a low level routine used by the logging functions in PETSc
1542 
1543 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1544 @*/
1545 PetscErrorCode PetscLogEventGetPerfInfo(PetscLogStage stage, PetscLogEvent event, PetscEventPerfInfo *info)
1546 {
1547   PetscLogHandler     handler;
1548   PetscEventPerfInfo *event_info;
1549 
1550   PetscFunctionBegin;
1551   PetscAssertPointer(info, 3);
1552   PetscCall(PetscLogGetHandler(PETSC_LOG_HANDLER_DEFAULT, &handler));
1553   PetscCall(PetscLogHandlerDefaultGetEventPerfInfo(handler, stage, event, &event_info));
1554   *info = *event_info;
1555   PetscFunctionReturn(PETSC_SUCCESS);
1556 }
1557 
1558 /*@C
1559   PetscLogEventSetDof - Set the nth number of degrees of freedom of a numerical problem associated with this event
1560 
1561   Not Collective
1562 
1563   Input Parameters:
1564 + event - The event id to log
1565 . n     - The dof index, in [0, 8)
1566 - dof   - The number of dofs
1567 
1568   Options Database Key:
1569 . -log_view - Activates log summary
1570 
1571   Level: developer
1572 
1573   Note:
1574   This is to enable logging of convergence
1575 
1576 .seealso: `PetscLogEventSetError()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1577 @*/
1578 PetscErrorCode PetscLogEventSetDof(PetscLogEvent event, PetscInt n, PetscLogDouble dof)
1579 {
1580   PetscLogHandler     handler;
1581   PetscEventPerfInfo *event_info;
1582 
1583   PetscFunctionBegin;
1584   PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1585   PetscCall(PetscLogTryGetHandler(PETSC_LOG_HANDLER_DEFAULT, &handler));
1586   if (handler) {
1587     PetscCall(PetscLogHandlerDefaultGetEventPerfInfo(handler, PETSC_DEFAULT, event, &event_info));
1588     event_info->dof[n] = dof;
1589   }
1590   PetscFunctionReturn(PETSC_SUCCESS);
1591 }
1592 
1593 /*@C
1594   PetscLogEventSetError - Set the nth error associated with a numerical problem associated with this event
1595 
1596   Not Collective
1597 
1598   Input Parameters:
1599 + event - The event id to log
1600 . n     - The error index, in [0, 8)
1601 - error - The error
1602 
1603   Options Database Key:
1604 . -log_view - Activates log summary
1605 
1606   Level: developer
1607 
1608   Notes:
1609   This is to enable logging of convergence, and enable users to interpret the errors as they wish. For example,
1610   as different norms, or as errors for different fields
1611 
1612   This is a low level routine used by the logging functions in PETSc
1613 
1614 .seealso: `PetscLogEventSetDof()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1615 @*/
1616 PetscErrorCode PetscLogEventSetError(PetscLogEvent event, PetscInt n, PetscLogDouble error)
1617 {
1618   PetscLogHandler     handler;
1619   PetscEventPerfInfo *event_info;
1620 
1621   PetscFunctionBegin;
1622   PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1623   PetscCall(PetscLogTryGetHandler(PETSC_LOG_HANDLER_DEFAULT, &handler));
1624   if (handler) {
1625     PetscCall(PetscLogHandlerDefaultGetEventPerfInfo(handler, PETSC_DEFAULT, event, &event_info));
1626     event_info->errors[n] = error;
1627   }
1628   PetscFunctionReturn(PETSC_SUCCESS);
1629 }
1630 
1631 /*@C
1632   PetscLogEventGetId - Returns the event id when given the event name.
1633 
1634   Not Collective
1635 
1636   Input Parameter:
1637 . name - The event name
1638 
1639   Output Parameter:
1640 . event - The event, or -1 if no event with that name exists
1641 
1642   Level: intermediate
1643 
1644 .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1645 @*/
1646 PetscErrorCode PetscLogEventGetId(const char name[], PetscLogEvent *event)
1647 {
1648   PetscLogState state;
1649 
1650   PetscFunctionBegin;
1651   *event = -1;
1652   PetscCall(PetscLogGetState(&state));
1653   if (state) PetscCall(PetscLogStateGetEventFromName(state, name, event));
1654   PetscFunctionReturn(PETSC_SUCCESS);
1655 }
1656 
1657 /*@C
1658   PetscLogEventGetName - Returns the event name when given the event id.
1659 
1660   Not Collective
1661 
1662   Input Parameter:
1663 . event - The event
1664 
1665   Output Parameter:
1666 . name - The event name
1667 
1668   Level: intermediate
1669 
1670 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
1671 @*/
1672 PetscErrorCode PetscLogEventGetName(PetscLogEvent event, const char **name)
1673 {
1674   PetscLogEventInfo event_info;
1675   PetscLogState     state;
1676 
1677   PetscFunctionBegin;
1678   *name = NULL;
1679   PetscCall(PetscLogGetState(&state));
1680   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1681   PetscCall(PetscLogStateEventGetInfo(state, event, &event_info));
1682   *name = event_info.name;
1683   PetscFunctionReturn(PETSC_SUCCESS);
1684 }
1685 
1686 /*@
1687   PetscLogEventsPause - Put event logging into "paused" mode: timers and counters for in-progress events are paused, and any events that happen before logging is resumed with `PetscLogEventsResume()` are logged in the "Main Stage" of execution.
1688 
1689   Not collective
1690 
1691   Level: advanced
1692 
1693   Notes:
1694   When an external library or runtime has is initialized it can involve lots of setup time that skews the statistics of any unrelated running events: this function is intended to isolate such calls in the default log summary (`PetscLogDefaultBegin()`, `PetscLogView()`).
1695 
1696   Other log handlers (such as the nested handler, `PetscLogNestedBegin()`) will ignore this function.
1697 
1698 .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsResume()`, `PetscLogGetDefaultHandler()`
1699 @*/
1700 PetscErrorCode PetscLogEventsPause(void)
1701 {
1702   PetscLogHandler handler;
1703 
1704   PetscFunctionBegin;
1705   PetscCall(PetscLogTryGetHandler(PETSC_LOG_HANDLER_DEFAULT, &handler));
1706   if (handler) PetscCall(PetscLogHandlerDefaultEventsPause(handler));
1707   PetscFunctionReturn(PETSC_SUCCESS);
1708 }
1709 
1710 /*@
1711   PetscLogEventsResume - Return logging to normal behavior after it was paused with `PetscLogEventsPause()`.
1712 
1713   Not collective
1714 
1715   Level: advanced
1716 
1717 .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsPause()`, `PetscLogGetDefaultHandler()`
1718 @*/
1719 PetscErrorCode PetscLogEventsResume(void)
1720 {
1721   PetscLogHandler handler;
1722 
1723   PetscFunctionBegin;
1724   PetscCall(PetscLogTryGetHandler(PETSC_LOG_HANDLER_DEFAULT, &handler));
1725   if (handler) PetscCall(PetscLogHandlerDefaultEventsResume(handler));
1726   PetscFunctionReturn(PETSC_SUCCESS);
1727 }
1728 
1729 /*------------------------------------------------ Class Functions --------------------------------------------------*/
1730 
1731 /*MC
1732    PetscLogObjectCreate - Log the creation of a `PetscObject`
1733 
1734    Synopsis:
1735    #include <petsclog.h>
1736    PetscErrorCode PetscLogObjectCreate(PetscObject h)
1737 
1738    Not Collective
1739 
1740    Input Parameters:
1741 .  h - A `PetscObject`
1742 
1743    Level: developer
1744 
1745    Developer Note:
1746      Called internally by PETSc when creating objects: users do not need to call this directly.
1747      Notification of the object creation is sent to each `PetscLogHandler` that is running.
1748 
1749 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectDestroy()`
1750 M*/
1751 
1752 /*MC
1753    PetscLogObjectDestroy - Logs the destruction of a `PetscObject`
1754 
1755    Synopsis:
1756    #include <petsclog.h>
1757    PetscErrorCode PetscLogObjectDestroy(PetscObject h)
1758 
1759    Not Collective
1760 
1761    Input Parameters:
1762 .  h - A `PetscObject`
1763 
1764    Level: developer
1765 
1766    Developer Note:
1767      Called internally by PETSc when destroying objects: users do not need to call this directly.
1768      Notification of the object creation is sent to each `PetscLogHandler` that is running.
1769 
1770 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectCreate()`
1771 M*/
1772 
1773 /*@C
1774   PetscLogClassGetClassId - Returns the `PetscClassId` when given the class name.
1775 
1776   Not Collective
1777 
1778   Input Parameter:
1779 . name - The class name
1780 
1781   Output Parameter:
1782 . classid - The `PetscClassId` id, or -1 if no class with that name exists
1783 
1784   Level: intermediate
1785 
1786 .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1787 @*/
1788 PetscErrorCode PetscLogClassGetClassId(const char name[], PetscClassId *classid)
1789 {
1790   PetscLogClass     log_class;
1791   PetscLogClassInfo class_info;
1792   PetscLogState     state;
1793 
1794   PetscFunctionBegin;
1795   *classid = -1;
1796   PetscCall(PetscLogGetState(&state));
1797   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1798   PetscCall(PetscLogStateGetClassFromName(state, name, &log_class));
1799   if (log_class < 0) {
1800     *classid = -1;
1801     PetscFunctionReturn(PETSC_SUCCESS);
1802   }
1803   PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1804   *classid = class_info.classid;
1805   PetscFunctionReturn(PETSC_SUCCESS);
1806 }
1807 
1808 /*@C
1809   PetscLogClassIdGetName - Returns a `PetscClassId`'s name.
1810 
1811   Not Collective
1812 
1813   Input Parameter:
1814 . classid - A `PetscClassId`
1815 
1816   Output Parameter:
1817 . name - The class name
1818 
1819   Level: intermediate
1820 
1821 .seealso: [](ch_profiling), `PetscLogClassRegister()`, `PetscLogClassBegin()`, `PetscLogClassEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadClass()`
1822 @*/
1823 PetscErrorCode PetscLogClassIdGetName(PetscClassId classid, const char **name)
1824 {
1825   PetscLogClass     log_class;
1826   PetscLogClassInfo class_info;
1827   PetscLogState     state;
1828 
1829   PetscFunctionBegin;
1830   PetscCall(PetscLogGetState(&state));
1831   PetscCall(PetscLogStateGetClassFromClassId(state, classid, &log_class));
1832   PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1833   *name = class_info.name;
1834   PetscFunctionReturn(PETSC_SUCCESS);
1835 }
1836 
1837 /*------------------------------------------------ Output Functions -------------------------------------------------*/
1838 /*@C
1839   PetscLogDump - Dumps logs of objects to a file. This file is intended to
1840   be read by bin/petscview. This program no longer exists.
1841 
1842   Collective on `PETSC_COMM_WORLD`
1843 
1844   Input Parameter:
1845 . sname - an optional file name
1846 
1847   Example Usage:
1848 .vb
1849   PetscInitialize(...);
1850   PetscLogDefaultBegin();
1851   // ... code ...
1852   PetscLogDump(filename);
1853   PetscFinalize();
1854 .ve
1855 
1856   Level: advanced
1857 
1858   Note:
1859   The default file name is Log.<rank> where <rank> is the MPI process rank. If no name is specified,
1860   this file will be used.
1861 
1862 .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
1863 @*/
1864 PetscErrorCode PetscLogDump(const char sname[])
1865 {
1866   PetscLogHandler handler;
1867 
1868   PetscFunctionBegin;
1869   PetscCall(PetscLogGetHandler(PETSC_LOG_HANDLER_DEFAULT, &handler));
1870   PetscCall(PetscLogHandlerDump_Default(handler, sname));
1871   PetscFunctionReturn(PETSC_SUCCESS);
1872 }
1873 
1874 /*@C
1875   PetscLogMPEDump - Dumps the MPE logging info to file for later use with Jumpshot.
1876 
1877   Collective over `PETSC_COMM_WORLD`
1878 
1879   Input Parameter:
1880 . sname - filename for the MPE logfile
1881 
1882   Level: advanced
1883 
1884 .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogMPEBegin()`
1885 @*/
1886 PetscErrorCode PetscLogMPEDump(const char sname[])
1887 {
1888   PetscFunctionBegin;
1889   #if defined(PETSC_HAVE_MPE)
1890   if (PetscBeganMPE) {
1891     char name[PETSC_MAX_PATH_LEN];
1892 
1893     PetscCall(PetscInfo(0, "Finalizing MPE.\n"));
1894     if (sname) {
1895       PetscCall(PetscStrncpy(name, sname, sizeof(name)));
1896     } else {
1897       PetscCall(PetscGetProgramName(name, sizeof(name)));
1898     }
1899     PetscCall(MPE_Finish_log(name));
1900   } else {
1901     PetscCall(PetscInfo(0, "Not finalizing MPE (not started by PETSc).\n"));
1902   }
1903   #else
1904   SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe");
1905   #endif
1906   PetscFunctionReturn(PETSC_SUCCESS);
1907 }
1908 
1909 /*@C
1910   PetscLogView - Prints a summary of the logging.
1911 
1912   Collective over MPI_Comm
1913 
1914   Input Parameter:
1915 . viewer - an ASCII viewer
1916 
1917   Options Database Keys:
1918 + -log_view [:filename]                    - Prints summary of log information
1919 . -log_view :filename.py:ascii_info_detail - Saves logging information from each process as a Python file
1920 . -log_view :filename.xml:ascii_xml        - Saves a summary of the logging information in a nested format (see below for how to view it)
1921 . -log_view :filename.txt:ascii_flamegraph - Saves logging information in a format suitable for visualising as a Flame Graph (see below for how to view it)
1922 . -log_view_memory                         - Also display memory usage in each event
1923 . -log_view_gpu_time                       - Also display time in each event for GPU kernels (Note this may slow the computation)
1924 . -log_all                                 - Saves a file Log.rank for each MPI rank with details of each step of the computation
1925 - -log_trace [filename]                    - Displays a trace of what each process is doing
1926 
1927   Level: beginner
1928 
1929   Notes:
1930   It is possible to control the logging programmatically but we recommend using the options database approach whenever possible
1931   By default the summary is printed to stdout.
1932 
1933   Before calling this routine you must have called either PetscLogDefaultBegin() or PetscLogNestedBegin()
1934 
1935   If PETSc is configured with --with-logging=0 then this functionality is not available
1936 
1937   To view the nested XML format filename.xml first copy  ${PETSC_DIR}/share/petsc/xml/performance_xml2html.xsl to the current
1938   directory then open filename.xml with your browser. Specific notes for certain browsers
1939 $    Firefox and Internet explorer - simply open the file
1940 $    Google Chrome - you must start up Chrome with the option --allow-file-access-from-files
1941 $    Safari - see https://ccm.net/faq/36342-safari-how-to-enable-local-file-access
1942   or one can use the package http://xmlsoft.org/XSLT/xsltproc2.html to translate the xml file to html and then open it with
1943   your browser.
1944   Alternatively, use the script ${PETSC_DIR}/lib/petsc/bin/petsc-performance-view to automatically open a new browser
1945   window and render the XML log file contents.
1946 
1947   The nested XML format was kindly donated by Koos Huijssen and Christiaan M. Klaij  MARITIME  RESEARCH  INSTITUTE  NETHERLANDS
1948 
1949   The Flame Graph output can be visualised using either the original Flame Graph script (https://github.com/brendangregg/FlameGraph)
1950   or using speedscope (https://www.speedscope.app).
1951   Old XML profiles may be converted into this format using the script ${PETSC_DIR}/lib/petsc/bin/xml2flamegraph.py.
1952 
1953 .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogDump()`
1954 @*/
1955 PetscErrorCode PetscLogView(PetscViewer viewer)
1956 {
1957   PetscBool         isascii;
1958   PetscViewerFormat format;
1959   int               stage;
1960   PetscLogState     state;
1961   PetscIntStack     temp_stack;
1962   PetscLogHandler   handler;
1963   PetscBool         is_empty;
1964 
1965   PetscFunctionBegin;
1966   PetscCall(PetscLogGetState(&state));
1967   /* Pop off any stages the user forgot to remove */
1968   PetscCall(PetscIntStackCreate(&temp_stack));
1969   PetscCall(PetscLogStateGetCurrentStage(state, &stage));
1970   while (stage >= 0) {
1971     PetscCall(PetscLogStagePop());
1972     PetscCall(PetscIntStackPush(temp_stack, stage));
1973     PetscCall(PetscLogStateGetCurrentStage(state, &stage));
1974   }
1975   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
1976   PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Currently can only view logging to ASCII");
1977   PetscCall(PetscViewerGetFormat(viewer, &format));
1978   if (format == PETSC_VIEWER_ASCII_XML || format == PETSC_VIEWER_ASCII_FLAMEGRAPH) {
1979     PetscCall(PetscLogGetHandler(PETSC_LOG_HANDLER_NESTED, &handler));
1980     PetscCall(PetscLogHandlerView(handler, viewer));
1981   } else {
1982     PetscCall(PetscLogGetHandler(PETSC_LOG_HANDLER_DEFAULT, &handler));
1983     PetscCall(PetscLogHandlerView(handler, viewer));
1984   }
1985   PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
1986   while (!is_empty) {
1987     PetscCall(PetscIntStackPop(temp_stack, &stage));
1988     PetscCall(PetscLogStagePush(stage));
1989     PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
1990   }
1991   PetscCall(PetscIntStackDestroy(temp_stack));
1992   PetscFunctionReturn(PETSC_SUCCESS);
1993 }
1994 
1995 /*@C
1996   PetscLogViewFromOptions - Processes command line options to determine if/how a `PetscLog` is to be viewed.
1997 
1998   Collective on `PETSC_COMM_WORLD`
1999 
2000   Level: developer
2001 
2002 .seealso: [](ch_profiling), `PetscLogView()`
2003 @*/
2004 PetscErrorCode PetscLogViewFromOptions(void)
2005 {
2006   PetscViewer       viewer;
2007   PetscBool         flg;
2008   PetscViewerFormat format;
2009 
2010   PetscFunctionBegin;
2011   PetscCall(PetscOptionsGetViewer(PETSC_COMM_WORLD, NULL, NULL, "-log_view", &viewer, &format, &flg));
2012   if (flg) {
2013     PetscCall(PetscViewerPushFormat(viewer, format));
2014     PetscCall(PetscLogView(viewer));
2015     PetscCall(PetscViewerPopFormat(viewer));
2016     PetscCall(PetscViewerDestroy(&viewer));
2017   }
2018   PetscFunctionReturn(PETSC_SUCCESS);
2019 }
2020 
2021 PETSC_INTERN PetscErrorCode PetscLogHandlerNestedSetThreshold(PetscLogHandler, PetscLogDouble, PetscLogDouble *);
2022 
2023 /*@
2024   PetscLogSetThreshold - Set the threshold time for logging the events; this is a percentage out of 100, so 1. means any event
2025   that takes 1 or more percent of the time.
2026 
2027   Logically Collective over `PETSC_COMM_WORLD`
2028 
2029   Input Parameter:
2030 . newThresh - the threshold to use
2031 
2032   Output Parameter:
2033 . oldThresh - the previously set threshold value
2034 
2035   Options Database Keys:
2036 . -log_view :filename.xml:ascii_xml - Prints an XML summary of flop and timing information to the file
2037 
2038   Example Usage:
2039 .vb
2040   PetscInitialize(...);
2041   PetscLogNestedBegin();
2042   PetscLogSetThreshold(0.1,&oldthresh);
2043   // ... code ...
2044   PetscLogView(viewer);
2045   PetscFinalize();
2046 .ve
2047 
2048   Level: advanced
2049 
2050   Note:
2051   This threshold is only used by the nested log handler
2052 
2053 .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`,
2054           `PetscLogNestedBegin()`
2055 @*/
2056 PetscErrorCode PetscLogSetThreshold(PetscLogDouble newThresh, PetscLogDouble *oldThresh)
2057 {
2058   PetscLogHandler handler;
2059 
2060   PetscFunctionBegin;
2061   PetscCall(PetscLogTryGetHandler(PETSC_LOG_HANDLER_NESTED, &handler));
2062   PetscCall(PetscLogHandlerNestedSetThreshold(handler, newThresh, oldThresh));
2063   PetscFunctionReturn(PETSC_SUCCESS);
2064 }
2065 
2066 /*----------------------------------------------- Counter Functions -------------------------------------------------*/
2067 /*@C
2068   PetscGetFlops - Returns the number of flops used on this processor
2069   since the program began.
2070 
2071   Not Collective
2072 
2073   Output Parameter:
2074 . flops - number of floating point operations
2075 
2076   Level: intermediate
2077 
2078   Notes:
2079   A global counter logs all PETSc flop counts.  The user can use
2080   `PetscLogFlops()` to increment this counter to include flops for the
2081   application code.
2082 
2083   A separate counter `PetscLogGPUFlops()` logs the flops that occur on any GPU associated with this MPI rank
2084 
2085 .seealso: [](ch_profiling), `PetscLogGPUFlops()`, `PetscTime()`, `PetscLogFlops()`
2086 @*/
2087 PetscErrorCode PetscGetFlops(PetscLogDouble *flops)
2088 {
2089   PetscFunctionBegin;
2090   *flops = petsc_TotalFlops;
2091   PetscFunctionReturn(PETSC_SUCCESS);
2092 }
2093 
2094 /*@C
2095   PetscLogObjectState - Record information about an object with the default log handler
2096 
2097   Not Collective
2098 
2099   Input Parameters:
2100 + obj    - the `PetscObject`
2101 . format - a printf-style format string
2102 - ...    - printf arguments to format
2103 
2104   Level: developer
2105 
2106 .seealso: [](ch_profiling), `PetscLogObjectCreate()`, `PetscLogObjectDestroy()`, `PetscLogGetDefaultHandler()`
2107 @*/
2108 PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
2109 {
2110   PetscLogHandler handler;
2111   va_list         Argp;
2112 
2113   PetscFunctionBegin;
2114   PetscCall(PetscLogTryGetHandler(PETSC_LOG_HANDLER_DEFAULT, &handler));
2115   if (handler) {
2116     va_start(Argp, format);
2117     PetscCall(PetscLogHandlerDefaultLogObjectState(handler, obj, format, Argp));
2118     va_end(Argp);
2119   }
2120   PetscFunctionReturn(PETSC_SUCCESS);
2121 }
2122 
2123 /*MC
2124   PetscLogFlops - Adds floating point operations to the global counter.
2125 
2126   Synopsis:
2127   #include <petsclog.h>
2128   PetscErrorCode PetscLogFlops(PetscLogDouble f)
2129 
2130   Not Collective
2131 
2132   Input Parameter:
2133 . f - flop counter
2134 
2135   Example Usage:
2136 .vb
2137   PetscLogEvent USER_EVENT;
2138 
2139   PetscLogEventRegister("User event", 0, &USER_EVENT);
2140   PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
2141   [code segment to monitor]
2142   PetscLogFlops(user_flops)
2143   PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
2144 .ve
2145 
2146   Level: intermediate
2147 
2148   Note:
2149    A global counter logs all PETSc flop counts. The user can use PetscLogFlops() to increment
2150    this counter to include flops for the application code.
2151 
2152 .seealso: [](ch_profiling), `PetscLogGPUFlops()`, `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscGetFlops()`
2153 M*/
2154 
2155 /*MC
2156   PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice) to get accurate
2157   timings
2158 
2159   Synopsis:
2160   #include <petsclog.h>
2161   void PetscPreLoadBegin(PetscBool flag, char *name);
2162 
2163   Not Collective
2164 
2165   Input Parameters:
2166 + flag - `PETSC_TRUE` to run twice, `PETSC_FALSE` to run once, may be overridden with command
2167          line option `-preload true|false`
2168 - name - name of first stage (lines of code timed separately with `-log_view`) to be preloaded
2169 
2170   Example Usage:
2171 .vb
2172   PetscPreLoadBegin(PETSC_TRUE, "first stage");
2173   // lines of code
2174   PetscPreLoadStage("second stage");
2175   // lines of code
2176   PetscPreLoadEnd();
2177 .ve
2178 
2179   Level: intermediate
2180 
2181   Note:
2182   Only works in C/C++, not Fortran
2183 
2184   Flags available within the macro\:
2185 + PetscPreLoadingUsed - `PETSC_TRUE` if we are or have done preloading
2186 . PetscPreLoadingOn   - `PETSC_TRUE` if it is CURRENTLY doing preload
2187 . PetscPreLoadIt      - `0` for the first computation (with preloading turned off it is only
2188                         `0`) `1`  for the second
2189 - PetscPreLoadMax     - number of times it will do the computation, only one when preloading is
2190                         turned on
2191 
2192   The first two variables are available throughout the program, the second two only between the
2193   `PetscPreLoadBegin()` and `PetscPreLoadEnd()`
2194 
2195 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
2196 M*/
2197 
2198 /*MC
2199   PetscPreLoadEnd - End a segment of code that may be preloaded (run twice) to get accurate
2200   timings
2201 
2202   Synopsis:
2203   #include <petsclog.h>
2204   void PetscPreLoadEnd(void);
2205 
2206   Not Collective
2207 
2208   Example Usage:
2209 .vb
2210   PetscPreLoadBegin(PETSC_TRUE, "first stage");
2211   // lines of code
2212   PetscPreLoadStage("second stage");
2213   // lines of code
2214   PetscPreLoadEnd();
2215 .ve
2216 
2217   Level: intermediate
2218 
2219   Note:
2220   Only works in C/C++ not fortran
2221 
2222 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadStage()`
2223 M*/
2224 
2225 /*MC
2226   PetscPreLoadStage - Start a new segment of code to be timed separately to get accurate timings
2227 
2228   Synopsis:
2229   #include <petsclog.h>
2230   void PetscPreLoadStage(char *name);
2231 
2232   Not Collective
2233 
2234   Example Usage:
2235 .vb
2236   PetscPreLoadBegin(PETSC_TRUE,"first stage");
2237   // lines of code
2238   PetscPreLoadStage("second stage");
2239   // lines of code
2240   PetscPreLoadEnd();
2241 .ve
2242 
2243   Level: intermediate
2244 
2245   Note:
2246   Only works in C/C++ not fortran
2247 
2248 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`
2249 M*/
2250 
2251   #if PetscDefined(HAVE_DEVICE)
2252     #include <petsc/private/deviceimpl.h>
2253 
2254 /*
2255    This cannot be called by users between PetscInitialize() and PetscFinalize() at any random location in the code
2256    because it will result in timing results that cannot be interpreted.
2257 */
2258 static PetscErrorCode PetscLogGpuTime_Off(void)
2259 {
2260   PetscLogGpuTimeFlag = PETSC_FALSE;
2261   return PETSC_SUCCESS;
2262 }
2263 
2264 /*@C
2265   PetscLogGpuTime - turn on the logging of GPU time for GPU kernels
2266 
2267   Options Database Key:
2268 . -log_view_gpu_time - provide the GPU times in the `-log_view` output
2269 
2270   Level: advanced
2271 
2272   Notes:
2273   Turning on the timing of the GPU kernels can slow down the entire computation and should only
2274   be used when studying the performance of operations on GPU such as vector operations and
2275   matrix-vector operations.
2276 
2277   This routine should only be called once near the beginning of the program. Once it is started
2278   it cannot be turned off.
2279 
2280 .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTimeBegin()`
2281 @*/
2282 PetscErrorCode PetscLogGpuTime(void)
2283 {
2284   if (!PetscLogGpuTimeFlag) PetscCall(PetscRegisterFinalize(PetscLogGpuTime_Off));
2285   PetscLogGpuTimeFlag = PETSC_TRUE;
2286   return PETSC_SUCCESS;
2287 }
2288 
2289 /*@C
2290   PetscLogGpuTimeBegin - Start timer for device
2291 
2292   Level: intermediate
2293 
2294   Notes:
2295   When CUDA or HIP is enabled, the timer is run on the GPU, it is a separate logging of time
2296   devoted to GPU computations (excluding kernel launch times).
2297 
2298   When CUDA or HIP is not available, the timer is run on the CPU, it is a separate logging of
2299   time devoted to GPU computations (including kernel launch times).
2300 
2301   There is no need to call WaitForCUDA() or WaitForHIP() between `PetscLogGpuTimeBegin()` and
2302   `PetscLogGpuTimeEnd()`
2303 
2304   This timer should NOT include times for data transfers between the GPU and CPU, nor setup
2305   actions such as allocating space.
2306 
2307   The regular logging captures the time for data transfers and any CPU activities during the
2308   event. It is used to compute the flop rate on the GPU as it is actively engaged in running a
2309   kernel.
2310 
2311   Developer Notes:
2312   The GPU event timer captures the execution time of all the kernels launched in the default
2313   stream by the CPU between `PetscLogGpuTimeBegin()` and `PetsLogGpuTimeEnd()`.
2314 
2315   `PetscLogGpuTimeBegin()` and `PetsLogGpuTimeEnd()` insert the begin and end events into the
2316   default stream (stream 0). The device will record a time stamp for the event when it reaches
2317   that event in the stream. The function xxxEventSynchronize() is called in
2318   `PetsLogGpuTimeEnd()` to block CPU execution, but not continued GPU execution, until the
2319   timer event is recorded.
2320 
2321 .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTime()`
2322 @*/
2323 PetscErrorCode PetscLogGpuTimeBegin(void)
2324 {
2325   PetscBool isActive;
2326 
2327   PetscFunctionBegin;
2328   PetscCall(PetscLogEventBeginIsActive(&isActive));
2329   if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2330   if (PetscDefined(HAVE_DEVICE)) {
2331     PetscDeviceContext dctx;
2332 
2333     PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2334     PetscCall(PetscDeviceContextBeginTimer_Internal(dctx));
2335   } else {
2336     PetscCall(PetscTimeSubtract(&petsc_gtime));
2337   }
2338   PetscFunctionReturn(PETSC_SUCCESS);
2339 }
2340 
2341 /*@C
2342   PetscLogGpuTimeEnd - Stop timer for device
2343 
2344   Level: intermediate
2345 
2346 .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeBegin()`
2347 @*/
2348 PetscErrorCode PetscLogGpuTimeEnd(void)
2349 {
2350   PetscBool isActive;
2351 
2352   PetscFunctionBegin;
2353   PetscCall(PetscLogEventEndIsActive(&isActive));
2354   if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2355   if (PetscDefined(HAVE_DEVICE)) {
2356     PetscDeviceContext dctx;
2357     PetscLogDouble     elapsed;
2358 
2359     PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2360     PetscCall(PetscDeviceContextEndTimer_Internal(dctx, &elapsed));
2361     petsc_gtime += (elapsed / 1000.0);
2362   } else {
2363     PetscCall(PetscTimeAdd(&petsc_gtime));
2364   }
2365   PetscFunctionReturn(PETSC_SUCCESS);
2366 }
2367 
2368   #endif /* end of PETSC_HAVE_DEVICE */
2369 
2370 /* -- Utility functions for logging from fortran -- */
2371 
2372 PETSC_EXTERN PetscErrorCode PetscASend(int count, int datatype)
2373 {
2374   PetscFunctionBegin;
2375   PetscCall(PetscAddLogDouble(&petsc_send_ct, &petsc_send_ct_th, 1));
2376   #if !defined(MPIUNI_H) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO)
2377   PetscCall(PetscMPITypeSize(count, MPI_Type_f2c((MPI_Fint)datatype), &petsc_send_len, &petsc_send_len_th));
2378   #endif
2379   PetscFunctionReturn(PETSC_SUCCESS);
2380 }
2381 
2382 PETSC_EXTERN PetscErrorCode PetscARecv(int count, int datatype)
2383 {
2384   PetscFunctionBegin;
2385   PetscCall(PetscAddLogDouble(&petsc_recv_ct, &petsc_recv_ct_th, 1));
2386   #if !defined(MPIUNI_H) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO)
2387   PetscCall(PetscMPITypeSize(count, MPI_Type_f2c((MPI_Fint)datatype), &petsc_recv_len, &petsc_recv_len_th));
2388   #endif
2389   PetscFunctionReturn(PETSC_SUCCESS);
2390 }
2391 
2392 PETSC_EXTERN PetscErrorCode PetscAReduce(void)
2393 {
2394   PetscFunctionBegin;
2395   PetscCall(PetscAddLogDouble(&petsc_allreduce_ct, &petsc_allreduce_ct_th, 1));
2396   PetscFunctionReturn(PETSC_SUCCESS);
2397 }
2398 
2399 #endif /* PETSC_USE_LOG*/
2400 
2401 PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2402 PetscClassId PETSC_OBJECT_CLASSID  = 0;
2403 
2404 static PetscBool PetscLogInitializeCalled = PETSC_FALSE;
2405 
2406 PETSC_INTERN PetscErrorCode PetscLogInitialize(void)
2407 {
2408   int stage;
2409 
2410   PetscFunctionBegin;
2411   if (PetscLogInitializeCalled) PetscFunctionReturn(PETSC_SUCCESS);
2412   PetscLogInitializeCalled = PETSC_TRUE;
2413   if (PetscDefined(USE_LOG)) {
2414     /* Setup default logging structures */
2415     PetscCall(PetscLogStateCreate(&petsc_log_state));
2416     for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2417       if (PetscLogHandlers[i].handler) PetscCall(PetscLogHandlerSetState(PetscLogHandlers[i].handler, petsc_log_state));
2418     }
2419     PetscCall(PetscLogStateStageRegister(petsc_log_state, "Main Stage", &stage));
2420     PetscCall(PetscSpinlockCreate(&PetscLogSpinLock));
2421 #if defined(PETSC_HAVE_THREADSAFETY)
2422     petsc_log_tid = 0;
2423     petsc_log_gid = 0;
2424 #endif
2425 
2426     /* All processors sync here for more consistent logging */
2427     PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
2428     PetscCall(PetscTime(&petsc_BaseTime));
2429     PetscCall(PetscLogStagePush(stage));
2430   }
2431   PetscFunctionReturn(PETSC_SUCCESS);
2432 }
2433 
2434 PETSC_INTERN PetscErrorCode PetscLogFinalize(void)
2435 {
2436   PetscFunctionBegin;
2437   if (PetscDefined(USE_LOG)) {
2438     /* Resetting phase */
2439     // pop remaining stages
2440     if (petsc_log_state) {
2441       while (petsc_log_state->current_stage >= 0) { PetscCall(PetscLogStagePop()); }
2442     }
2443     for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) PetscCall(PetscLogHandlerDestroy(&PetscLogHandlers[i].handler));
2444     PetscCall(PetscArrayzero(PetscLogHandlers, PETSC_LOG_HANDLER_MAX));
2445     PetscCall(PetscLogStateDestroy(&petsc_log_state));
2446 
2447     petsc_TotalFlops         = 0.0;
2448     petsc_BaseTime           = 0.0;
2449     petsc_TotalFlops         = 0.0;
2450     petsc_send_ct            = 0.0;
2451     petsc_recv_ct            = 0.0;
2452     petsc_send_len           = 0.0;
2453     petsc_recv_len           = 0.0;
2454     petsc_isend_ct           = 0.0;
2455     petsc_irecv_ct           = 0.0;
2456     petsc_isend_len          = 0.0;
2457     petsc_irecv_len          = 0.0;
2458     petsc_wait_ct            = 0.0;
2459     petsc_wait_any_ct        = 0.0;
2460     petsc_wait_all_ct        = 0.0;
2461     petsc_sum_of_waits_ct    = 0.0;
2462     petsc_allreduce_ct       = 0.0;
2463     petsc_gather_ct          = 0.0;
2464     petsc_scatter_ct         = 0.0;
2465     petsc_TotalFlops_th      = 0.0;
2466     petsc_send_ct_th         = 0.0;
2467     petsc_recv_ct_th         = 0.0;
2468     petsc_send_len_th        = 0.0;
2469     petsc_recv_len_th        = 0.0;
2470     petsc_isend_ct_th        = 0.0;
2471     petsc_irecv_ct_th        = 0.0;
2472     petsc_isend_len_th       = 0.0;
2473     petsc_irecv_len_th       = 0.0;
2474     petsc_wait_ct_th         = 0.0;
2475     petsc_wait_any_ct_th     = 0.0;
2476     petsc_wait_all_ct_th     = 0.0;
2477     petsc_sum_of_waits_ct_th = 0.0;
2478     petsc_allreduce_ct_th    = 0.0;
2479     petsc_gather_ct_th       = 0.0;
2480     petsc_scatter_ct_th      = 0.0;
2481 
2482     petsc_ctog_ct    = 0.0;
2483     petsc_gtoc_ct    = 0.0;
2484     petsc_ctog_sz    = 0.0;
2485     petsc_gtoc_sz    = 0.0;
2486     petsc_gflops     = 0.0;
2487     petsc_gtime      = 0.0;
2488     petsc_ctog_ct_th = 0.0;
2489     petsc_gtoc_ct_th = 0.0;
2490     petsc_ctog_sz_th = 0.0;
2491     petsc_gtoc_sz_th = 0.0;
2492     petsc_gflops_th  = 0.0;
2493     petsc_gtime_th   = 0.0;
2494   }
2495   PETSC_LARGEST_CLASSID    = PETSC_SMALLEST_CLASSID;
2496   PETSC_OBJECT_CLASSID     = 0;
2497   PetscLogInitializeCalled = PETSC_FALSE;
2498   PetscFunctionReturn(PETSC_SUCCESS);
2499 }
2500 
2501 /*@C
2502   PetscClassIdRegister - Registers a new class name for objects and logging operations in an application code.
2503 
2504   Not Collective
2505 
2506   Input Parameter:
2507 . name - The class name
2508 
2509   Output Parameter:
2510 . oclass - The class id or classid
2511 
2512   Level: developer
2513 
2514 .seealso: [](ch_profiling), `PetscLogEventRegister()`
2515 @*/
2516 PetscErrorCode PetscClassIdRegister(const char name[], PetscClassId *oclass)
2517 {
2518   PetscFunctionBegin;
2519   *oclass = ++PETSC_LARGEST_CLASSID;
2520 #if defined(PETSC_USE_LOG)
2521   {
2522     PetscLogState state;
2523     PetscLogClass logclass;
2524 
2525     PetscCall(PetscLogGetState(&state));
2526     if (state) PetscCall(PetscLogStateClassRegister(state, name, *oclass, &logclass));
2527   }
2528 #endif
2529   PetscFunctionReturn(PETSC_SUCCESS);
2530 }
2531