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