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