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