xref: /petsc/src/sys/logging/plog.c (revision a29dfd43bb0c77e2653d3bfa2c953f902720a6d2)
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 // clang-format off
107 #define PETSC_LOG_HANDLER_HOT_BLANK {NULL, NULL, NULL, NULL, NULL, NULL}
108 // clang-format on
109 
110 PetscLogHandlerHot PetscLogHandlers[PETSC_LOG_HANDLER_MAX] = {
111   PETSC_LOG_HANDLER_HOT_BLANK,
112   PETSC_LOG_HANDLER_HOT_BLANK,
113   PETSC_LOG_HANDLER_HOT_BLANK,
114   PETSC_LOG_HANDLER_HOT_BLANK,
115 };
116 
117 #undef PETSC_LOG_HANDLERS_HOT_BLANK
118 
119 #if defined(PETSC_USE_LOG)
120   #include <../src/sys/logging/handler/impls/default/logdefault.h>
121 
122   #if defined(PETSC_HAVE_THREADSAFETY)
123 PetscErrorCode PetscAddLogDouble(PetscLogDouble *tot, PetscLogDouble *tot_th, PetscLogDouble tmp)
124 {
125   *tot_th += tmp;
126   PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
127   *tot += tmp;
128   PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
129   return PETSC_SUCCESS;
130 }
131 
132 PetscErrorCode PetscAddLogDoubleCnt(PetscLogDouble *cnt, PetscLogDouble *tot, PetscLogDouble *cnt_th, PetscLogDouble *tot_th, PetscLogDouble tmp)
133 {
134   *cnt_th = *cnt_th + 1;
135   *tot_th += tmp;
136   PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
137   *tot += (PetscLogDouble)(tmp);
138   *cnt += *cnt + 1;
139   PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
140   return PETSC_SUCCESS;
141 }
142 
143   #endif
144 
145 static PetscErrorCode PetscLogTryGetHandler(PetscLogHandlerType type, PetscLogHandler *handler)
146 {
147   PetscFunctionBegin;
148   PetscAssertPointer(handler, 2);
149   *handler = NULL;
150   for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
151     PetscLogHandler h = PetscLogHandlers[i].handler;
152     if (h) {
153       PetscBool match;
154 
155       PetscCall(PetscObjectTypeCompare((PetscObject)h, type, &match));
156       if (match) {
157         *handler = PetscLogHandlers[i].handler;
158         PetscFunctionReturn(PETSC_SUCCESS);
159       }
160     }
161   }
162   PetscFunctionReturn(PETSC_SUCCESS);
163 }
164 
165 /*@
166   PetscLogGetDefaultHandler - Get the default log handler if it is running.
167 
168   Not collective
169 
170   Output Parameter:
171 . handler - the default `PetscLogHandler`, or `NULL` if it is not running.
172 
173   Level: developer
174 
175   Notes:
176   The default handler is started with `PetscLogDefaultBegin()`,
177   if the options flags `-log_all` or `-log_view` is given without arguments,
178   or for `-log_view :output:format` if `format` is not `ascii_xml` or `ascii_flamegraph`.
179 
180 .seealso: [](ch_profiling)
181 @*/
182 PetscErrorCode PetscLogGetDefaultHandler(PetscLogHandler *handler)
183 {
184   PetscFunctionBegin;
185   PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, handler));
186   PetscFunctionReturn(PETSC_SUCCESS);
187 }
188 
189 static PetscErrorCode PetscLogGetHandler(PetscLogHandlerType type, PetscLogHandler *handler)
190 {
191   PetscFunctionBegin;
192   PetscAssertPointer(handler, 2);
193   PetscCall(PetscLogTryGetHandler(type, handler));
194   PetscCheck(*handler != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "A PetscLogHandler of type %s has not been started.", type);
195   PetscFunctionReturn(PETSC_SUCCESS);
196 }
197 
198 /*@
199   PetscLogGetState - Get the `PetscLogState` for PETSc's global logging, used
200   by all default log handlers (`PetscLogDefaultBegin()`,
201   `PetscLogNestedBegin()`, `PetscLogTraceBegin()`, `PetscLogMPEBegin()`,
202   `PetscLogPerfstubsBegin()`).
203 
204   Collective on `PETSC_COMM_WORLD`
205 
206   Output Parameter:
207 . state - The `PetscLogState` changed by registrations (such as
208           `PetscLogEventRegister()`) and actions (such as `PetscLogEventBegin()` or
209           `PetscLogStagePush()`), or `NULL` if logging is not active
210 
211   Level: developer
212 
213 .seealso: [](ch_profiling), `PetscLogState`
214 @*/
215 PetscErrorCode PetscLogGetState(PetscLogState *state)
216 {
217   PetscFunctionBegin;
218   PetscAssertPointer(state, 1);
219   *state = petsc_log_state;
220   PetscFunctionReturn(PETSC_SUCCESS);
221 }
222 
223 static PetscErrorCode PetscLogHandlerCopyToHot(PetscLogHandler h, PetscLogHandlerHot *hot)
224 {
225   PetscFunctionBegin;
226   hot->handler       = h;
227   hot->eventBegin    = h->ops->eventbegin;
228   hot->eventEnd      = h->ops->eventend;
229   hot->eventSync     = h->ops->eventsync;
230   hot->objectCreate  = h->ops->objectcreate;
231   hot->objectDestroy = h->ops->objectdestroy;
232   PetscFunctionReturn(PETSC_SUCCESS);
233 }
234 
235 /*@
236   PetscLogHandlerStart - Connect a log handler to PETSc's global logging stream and state.
237 
238   Logically collective
239 
240   Input Parameters:
241 . h - a `PetscLogHandler`
242 
243   Level: developer
244 
245   Notes:
246   Users should only need this if they create their own log handlers: handlers that are started
247   from the command line (such as `-log_view` and `-log_trace`) or from a function like
248   `PetscLogNestedBegin()` will automatically be started.
249 
250   There is a limit of `PESC_LOG_HANDLER_MAX` handlers that can be active at one time.
251 
252   To disconnect a handler from the global stream call `PetscLogHandlerStop()`.
253 
254   When a log handler is started, stages that have already been pushed with `PetscLogStagePush()`,
255   will be pushed for the new log handler, but it will not be informed of any events that are
256   in progress.  It is recommended to start any user-defined log handlers immediately following
257   `PetscInitialize()`  before any user-defined stages are pushed.
258 
259 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogHandlerStop()`, `PetscInitialize()`
260 @*/
261 PetscErrorCode PetscLogHandlerStart(PetscLogHandler h)
262 {
263   PetscFunctionBegin;
264   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
265     if (PetscLogHandlers[i].handler == h) PetscFunctionReturn(PETSC_SUCCESS);
266   }
267   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
268     if (PetscLogHandlers[i].handler == NULL) {
269       PetscCall(PetscObjectReference((PetscObject)h));
270       PetscCall(PetscLogHandlerCopyToHot(h, &PetscLogHandlers[i]));
271       if (petsc_log_state) {
272         PetscLogStage stack_height;
273         PetscIntStack orig_stack, temp_stack;
274 
275         PetscCall(PetscLogHandlerSetState(h, petsc_log_state));
276         stack_height = petsc_log_state->stage_stack->top + 1;
277         PetscCall(PetscIntStackCreate(&temp_stack));
278         orig_stack                     = petsc_log_state->stage_stack;
279         petsc_log_state->stage_stack   = temp_stack;
280         petsc_log_state->current_stage = -1;
281         for (int s = 0; s < stack_height; s++) {
282           PetscLogStage stage = (PetscLogStage)orig_stack->stack[s];
283           PetscCall(PetscLogHandlerStagePush(h, stage));
284           PetscCall(PetscIntStackPush(temp_stack, stage));
285           petsc_log_state->current_stage = stage;
286         }
287         PetscCall(PetscIntStackDestroy(temp_stack));
288         petsc_log_state->stage_stack = orig_stack;
289       }
290       PetscFunctionReturn(PETSC_SUCCESS);
291     }
292   }
293   SETERRQ(PetscObjectComm((PetscObject)h), PETSC_ERR_ARG_WRONGSTATE, "%d log handlers already started, cannot start another", PETSC_LOG_HANDLER_MAX);
294   PetscFunctionReturn(PETSC_SUCCESS);
295 }
296 
297 /*@
298   PetscLogHandlerStop - Disconnect a log handler from PETSc's global logging stream.
299 
300   Logically collective
301 
302   Input Parameters:
303 . h - a `PetscLogHandler`
304 
305   Level: developer
306 
307   Note:
308   After `PetscLogHandlerStop()`, the handler can still access the global logging state
309   with `PetscLogHandlerGetState()`, so that it can access the registry when post-processing
310   (for instance, in `PetscLogHandlerView()`),
311 
312   When a log handler is stopped, the remaining stages will be popped before it is
313   disconnected from the log stream.
314 
315 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogHandlerStart()`
316 @*/
317 PetscErrorCode PetscLogHandlerStop(PetscLogHandler h)
318 {
319   PetscFunctionBegin;
320   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
321     if (PetscLogHandlers[i].handler == h) {
322       if (petsc_log_state) {
323         PetscLogState state;
324         PetscLogStage stack_height;
325         PetscIntStack orig_stack, temp_stack;
326 
327         PetscCall(PetscLogHandlerGetState(h, &state));
328         PetscCheck(state == petsc_log_state, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "Called PetscLogHandlerStop() for a PetscLogHander that was not started.");
329         stack_height = petsc_log_state->stage_stack->top + 1;
330         PetscCall(PetscIntStackCreate(&temp_stack));
331         orig_stack                   = petsc_log_state->stage_stack;
332         petsc_log_state->stage_stack = temp_stack;
333         for (int s = 0; s < stack_height; s++) {
334           PetscLogStage stage = (PetscLogStage)orig_stack->stack[s];
335 
336           PetscCall(PetscIntStackPush(temp_stack, stage));
337         }
338         for (int s = 0; s < stack_height; s++) {
339           PetscLogStage stage;
340           PetscBool     empty;
341 
342           PetscCall(PetscIntStackPop(temp_stack, &stage));
343           PetscCall(PetscIntStackEmpty(temp_stack, &empty));
344           if (!empty) {
345             PetscCall(PetscIntStackTop(temp_stack, &petsc_log_state->current_stage));
346           } else petsc_log_state->current_stage = -1;
347           PetscCall(PetscLogHandlerStagePop(h, stage));
348         }
349         PetscCall(PetscIntStackDestroy(temp_stack));
350         petsc_log_state->stage_stack = orig_stack;
351         PetscCall(PetscIntStackTop(petsc_log_state->stage_stack, &petsc_log_state->current_stage));
352       }
353       PetscCall(PetscArrayzero(&PetscLogHandlers[i], 1));
354       PetscCall(PetscObjectDereference((PetscObject)h));
355     }
356   }
357   PetscFunctionReturn(PETSC_SUCCESS);
358 }
359 
360 /*@
361   PetscLogIsActive - Check if logging is currently in progress.
362 
363   Not Collective
364 
365   Output Parameter:
366 . isActive - `PETSC_TRUE` if logging is in progress, `PETSC_FALSE` otherwise
367 
368   Level: beginner
369 
370 .seealso: [](ch_profiling), `PetscLogDefaultBegin()`
371 @*/
372 PetscErrorCode PetscLogIsActive(PetscBool *isActive)
373 {
374   PetscFunctionBegin;
375   *isActive = PETSC_FALSE;
376   if (petsc_log_state) {
377     for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
378       if (PetscLogHandlers[i].handler) {
379         *isActive = PETSC_TRUE;
380         PetscFunctionReturn(PETSC_SUCCESS);
381       }
382     }
383   }
384   PetscFunctionReturn(PETSC_SUCCESS);
385 }
386 
387 PETSC_UNUSED static PetscErrorCode PetscLogEventBeginIsActive(PetscBool *isActive)
388 {
389   PetscFunctionBegin;
390   *isActive = PETSC_FALSE;
391   if (petsc_log_state) {
392     for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
393       if (PetscLogHandlers[i].eventBegin) {
394         *isActive = PETSC_TRUE;
395         PetscFunctionReturn(PETSC_SUCCESS);
396       }
397     }
398   }
399   PetscFunctionReturn(PETSC_SUCCESS);
400 }
401 
402 PETSC_UNUSED static PetscErrorCode PetscLogEventEndIsActive(PetscBool *isActive)
403 {
404   PetscFunctionBegin;
405   *isActive = PETSC_FALSE;
406   if (petsc_log_state) {
407     for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
408       if (PetscLogHandlers[i].eventEnd) {
409         *isActive = PETSC_TRUE;
410         PetscFunctionReturn(PETSC_SUCCESS);
411       }
412     }
413   }
414   PetscFunctionReturn(PETSC_SUCCESS);
415 }
416 
417 PETSC_INTERN PetscErrorCode PetscLogTypeBegin(PetscLogHandlerType type)
418 {
419   PetscLogHandler handler;
420 
421   PetscFunctionBegin;
422   PetscCall(PetscLogTryGetHandler(type, &handler));
423   if (handler) PetscFunctionReturn(PETSC_SUCCESS);
424   PetscCall(PetscLogHandlerCreate(PETSC_COMM_WORLD, &handler));
425   PetscCall(PetscLogHandlerSetType(handler, type));
426   PetscCall(PetscLogHandlerStart(handler));
427   PetscCall(PetscLogHandlerDestroy(&handler));
428   PetscFunctionReturn(PETSC_SUCCESS);
429 }
430 
431 /*@
432   PetscLogDefaultBegin - Turns on logging of objects and events using the default log handler. This logs flop
433   rates and object creation and should not slow programs down too much.
434   This routine may be called more than once.
435 
436   Logically Collective on `PETSC_COMM_WORLD`
437 
438   Options Database Key:
439 . -log_view [viewertype:filename:viewerformat] - Prints summary of flop and timing information to the
440                                                  screen (for code configured with --with-log=1 (which is the default))
441 
442   Example Usage:
443 .vb
444       PetscInitialize(...);
445       PetscLogDefaultBegin();
446        ... code ...
447       PetscLogView(viewer); or PetscLogDump();
448       PetscFinalize();
449 .ve
450 
451   Level: advanced
452 
453   Note:
454   `PetscLogView()` or `PetscLogDump()` actually cause the printing of
455   the logging information.
456 
457 .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`
458 @*/
459 PetscErrorCode PetscLogDefaultBegin(void)
460 {
461   PetscFunctionBegin;
462   PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERDEFAULT));
463   PetscFunctionReturn(PETSC_SUCCESS);
464 }
465 
466 /*@C
467   PetscLogTraceBegin - Begins trace logging.  Every time a PETSc event
468   begins or ends, the event name is printed.
469 
470   Logically Collective on `PETSC_COMM_WORLD`, No Fortran Support
471 
472   Input Parameter:
473 . file - The file to print trace in (e.g. stdout)
474 
475   Options Database Key:
476 . -log_trace [filename] - Begins `PetscLogTraceBegin()`
477 
478   Level: intermediate
479 
480   Notes:
481   `PetscLogTraceBegin()` prints the processor number, the execution time (sec),
482   then "Event begin:" or "Event end:" followed by the event name.
483 
484   `PetscLogTraceBegin()` allows tracing of all PETSc calls, which is useful
485   to determine where a program is hanging without running in the
486   debugger.  Can be used in conjunction with the -info option.
487 
488 .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogView()`, `PetscLogDefaultBegin()`
489 @*/
490 PetscErrorCode PetscLogTraceBegin(FILE *file)
491 {
492   PetscLogHandler handler;
493 
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 /*@
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`, No Fortran Support
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`, No Fortran Support
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`, No Fortran Support
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 /*@
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 /*@
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 /*@
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 /*@
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 /*@
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 /*@
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   Logically 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 command line option -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   No Fortran Support
1530 
1531   Input Parameters:
1532 . stage - The stage number or `PETSC_DETERMINE` for the current stage
1533 
1534   Output Parameter:
1535 . info - This structure is filled with the performance information
1536 
1537   Level: intermediate
1538 
1539   Notes:
1540   This is a low level routine used by the logging functions in PETSc.
1541 
1542   A `PETSCLOGHANDLERDEFAULT` must be running for this to work, having been started either with
1543   `PetscLogDefaultBegin()` or from the command line with `-log_view`.  If it was not started,
1544   all performance statistics in `info` will be zeroed.
1545 
1546 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1547 @*/
1548 PetscErrorCode PetscLogStageGetPerfInfo(PetscLogStage stage, PetscEventPerfInfo *info)
1549 {
1550   PetscLogHandler     handler;
1551   PetscEventPerfInfo *event_info;
1552 
1553   PetscFunctionBegin;
1554   PetscAssertPointer(info, 2);
1555   PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1556   if (handler) {
1557     PetscCall(PetscLogHandlerGetStagePerfInfo(handler, stage, &event_info));
1558     *info = *event_info;
1559   } else {
1560     PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogStageGetPerfInfo() returning zeros\n"));
1561     PetscCall(PetscMemzero(info, sizeof(*info)));
1562   }
1563   PetscFunctionReturn(PETSC_SUCCESS);
1564 }
1565 
1566 /*@C
1567   PetscLogEventGetPerfInfo - Return the performance information about the given event in the given stage
1568 
1569   No Fortran Support
1570 
1571   Input Parameters:
1572 + stage - The stage number or `PETSC_DETERMINE` for the current stage
1573 - event - The event number
1574 
1575   Output Parameter:
1576 . info - This structure is filled with the performance information
1577 
1578   Level: intermediate
1579 
1580   Note:
1581   This is a low level routine used by the logging functions in PETSc
1582 
1583   A `PETSCLOGHANDLERDEFAULT` must be running for this to work, having been started either with
1584   `PetscLogDefaultBegin()` or from the command line with `-log_view`.  If it was not started,
1585   all performance statistics in `info` will be zeroed.
1586 
1587 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1588 @*/
1589 PetscErrorCode PetscLogEventGetPerfInfo(PetscLogStage stage, PetscLogEvent event, PetscEventPerfInfo *info)
1590 {
1591   PetscLogHandler     handler;
1592   PetscEventPerfInfo *event_info;
1593 
1594   PetscFunctionBegin;
1595   PetscAssertPointer(info, 3);
1596   PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1597   if (handler) {
1598     PetscCall(PetscLogHandlerGetEventPerfInfo(handler, stage, event, &event_info));
1599     *info = *event_info;
1600   } else {
1601     PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogEventGetPerfInfo() returning zeros\n"));
1602     PetscCall(PetscMemzero(info, sizeof(*info)));
1603   }
1604   PetscFunctionReturn(PETSC_SUCCESS);
1605 }
1606 
1607 /*@
1608   PetscLogEventSetDof - Set the nth number of degrees of freedom of a numerical problem associated with this event
1609 
1610   Not Collective
1611 
1612   Input Parameters:
1613 + event - The event id to log
1614 . n     - The dof index, in [0, 8)
1615 - dof   - The number of dofs
1616 
1617   Options Database Key:
1618 . -log_view - Activates log summary
1619 
1620   Level: developer
1621 
1622   Note:
1623   This is to enable logging of convergence
1624 
1625 .seealso: `PetscLogEventSetError()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1626 @*/
1627 PetscErrorCode PetscLogEventSetDof(PetscLogEvent event, PetscInt n, PetscLogDouble dof)
1628 {
1629   PetscFunctionBegin;
1630   PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1631   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1632     PetscLogHandler h = PetscLogHandlers[i].handler;
1633 
1634     if (h) {
1635       PetscEventPerfInfo *event_info;
1636 
1637       PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1638       if (event_info) event_info->dof[n] = dof;
1639     }
1640   }
1641   PetscFunctionReturn(PETSC_SUCCESS);
1642 }
1643 
1644 /*@
1645   PetscLogEventSetError - Set the nth error associated with a numerical problem associated with this event
1646 
1647   Not Collective
1648 
1649   Input Parameters:
1650 + event - The event id to log
1651 . n     - The error index, in [0, 8)
1652 - error - The error
1653 
1654   Options Database Key:
1655 . -log_view - Activates log summary
1656 
1657   Level: developer
1658 
1659   Notes:
1660   This is to enable logging of convergence, and enable users to interpret the errors as they wish. For example,
1661   as different norms, or as errors for different fields
1662 
1663   This is a low level routine used by the logging functions in PETSc
1664 
1665 .seealso: `PetscLogEventSetDof()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1666 @*/
1667 PetscErrorCode PetscLogEventSetError(PetscLogEvent event, PetscInt n, PetscLogDouble error)
1668 {
1669   PetscFunctionBegin;
1670   PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1671   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1672     PetscLogHandler h = PetscLogHandlers[i].handler;
1673 
1674     if (h) {
1675       PetscEventPerfInfo *event_info;
1676 
1677       PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1678       if (event_info) event_info->errors[n] = error;
1679     }
1680   }
1681   PetscFunctionReturn(PETSC_SUCCESS);
1682 }
1683 
1684 /*@
1685   PetscLogEventGetId - Returns the event id when given the event name.
1686 
1687   Not Collective
1688 
1689   Input Parameter:
1690 . name - The event name
1691 
1692   Output Parameter:
1693 . event - The event, or -1 if no event with that name exists
1694 
1695   Level: intermediate
1696 
1697 .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1698 @*/
1699 PetscErrorCode PetscLogEventGetId(const char name[], PetscLogEvent *event)
1700 {
1701   PetscLogState state;
1702 
1703   PetscFunctionBegin;
1704   *event = -1;
1705   PetscCall(PetscLogGetState(&state));
1706   if (state) PetscCall(PetscLogStateGetEventFromName(state, name, event));
1707   PetscFunctionReturn(PETSC_SUCCESS);
1708 }
1709 
1710 /*@
1711   PetscLogEventGetName - Returns the event name when given the event id.
1712 
1713   Not Collective
1714 
1715   Input Parameter:
1716 . event - The event
1717 
1718   Output Parameter:
1719 . name - The event name
1720 
1721   Level: intermediate
1722 
1723 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
1724 @*/
1725 PetscErrorCode PetscLogEventGetName(PetscLogEvent event, const char *name[])
1726 {
1727   PetscLogEventInfo event_info;
1728   PetscLogState     state;
1729 
1730   PetscFunctionBegin;
1731   *name = NULL;
1732   PetscCall(PetscLogGetState(&state));
1733   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1734   PetscCall(PetscLogStateEventGetInfo(state, event, &event_info));
1735   *name = event_info.name;
1736   PetscFunctionReturn(PETSC_SUCCESS);
1737 }
1738 
1739 /*@
1740   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.
1741 
1742   Not collective
1743 
1744   Level: advanced
1745 
1746   Notes:
1747   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()`).
1748 
1749   Other log handlers (such as the nested handler, `PetscLogNestedBegin()`) will ignore this function.
1750 
1751 .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsResume()`, `PetscLogGetDefaultHandler()`
1752 @*/
1753 PetscErrorCode PetscLogEventsPause(void)
1754 {
1755   PetscFunctionBegin;
1756   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1757     PetscLogHandler h = PetscLogHandlers[i].handler;
1758 
1759     if (h) PetscCall(PetscLogHandlerEventsPause(h));
1760   }
1761   PetscFunctionReturn(PETSC_SUCCESS);
1762 }
1763 
1764 /*@
1765   PetscLogEventsResume - Return logging to normal behavior after it was paused with `PetscLogEventsPause()`.
1766 
1767   Not collective
1768 
1769   Level: advanced
1770 
1771 .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsPause()`, `PetscLogGetDefaultHandler()`
1772 @*/
1773 PetscErrorCode PetscLogEventsResume(void)
1774 {
1775   PetscFunctionBegin;
1776   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1777     PetscLogHandler h = PetscLogHandlers[i].handler;
1778 
1779     if (h) PetscCall(PetscLogHandlerEventsResume(h));
1780   }
1781   PetscFunctionReturn(PETSC_SUCCESS);
1782 }
1783 
1784 /*------------------------------------------------ Class Functions --------------------------------------------------*/
1785 
1786 /*MC
1787    PetscLogObjectCreate - Log the creation of a `PetscObject`
1788 
1789    Synopsis:
1790    #include <petsclog.h>
1791    PetscErrorCode PetscLogObjectCreate(PetscObject h)
1792 
1793    Not Collective
1794 
1795    Input Parameters:
1796 .  h - A `PetscObject`
1797 
1798    Level: developer
1799 
1800    Developer Note:
1801      Called internally by PETSc when creating objects: users do not need to call this directly.
1802      Notification of the object creation is sent to each `PetscLogHandler` that is running.
1803 
1804 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectDestroy()`
1805 M*/
1806 
1807 /*MC
1808    PetscLogObjectDestroy - Logs the destruction of a `PetscObject`
1809 
1810    Synopsis:
1811    #include <petsclog.h>
1812    PetscErrorCode PetscLogObjectDestroy(PetscObject h)
1813 
1814    Not Collective
1815 
1816    Input Parameters:
1817 .  h - A `PetscObject`
1818 
1819    Level: developer
1820 
1821    Developer Note:
1822      Called internally by PETSc when destroying objects: users do not need to call this directly.
1823      Notification of the object creation is sent to each `PetscLogHandler` that is running.
1824 
1825 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectCreate()`
1826 M*/
1827 
1828 /*@
1829   PetscLogClassGetClassId - Returns the `PetscClassId` when given the class name.
1830 
1831   Not Collective
1832 
1833   Input Parameter:
1834 . name - The class name
1835 
1836   Output Parameter:
1837 . classid - The `PetscClassId` id, or -1 if no class with that name exists
1838 
1839   Level: intermediate
1840 
1841 .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1842 @*/
1843 PetscErrorCode PetscLogClassGetClassId(const char name[], PetscClassId *classid)
1844 {
1845   PetscLogClass     log_class;
1846   PetscLogClassInfo class_info;
1847   PetscLogState     state;
1848 
1849   PetscFunctionBegin;
1850   *classid = -1;
1851   PetscCall(PetscLogGetState(&state));
1852   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1853   PetscCall(PetscLogStateGetClassFromName(state, name, &log_class));
1854   if (log_class < 0) {
1855     *classid = -1;
1856     PetscFunctionReturn(PETSC_SUCCESS);
1857   }
1858   PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1859   *classid = class_info.classid;
1860   PetscFunctionReturn(PETSC_SUCCESS);
1861 }
1862 
1863 /*@C
1864   PetscLogClassIdGetName - Returns a `PetscClassId`'s name.
1865 
1866   Not Collective
1867 
1868   Input Parameter:
1869 . classid - A `PetscClassId`
1870 
1871   Output Parameter:
1872 . name - The class name
1873 
1874   Level: intermediate
1875 
1876 .seealso: [](ch_profiling), `PetscLogClassRegister()`, `PetscLogClassBegin()`, `PetscLogClassEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadClass()`
1877 @*/
1878 PetscErrorCode PetscLogClassIdGetName(PetscClassId classid, const char **name)
1879 {
1880   PetscLogClass     log_class;
1881   PetscLogClassInfo class_info;
1882   PetscLogState     state;
1883 
1884   PetscFunctionBegin;
1885   PetscCall(PetscLogGetState(&state));
1886   PetscCall(PetscLogStateGetClassFromClassId(state, classid, &log_class));
1887   PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1888   *name = class_info.name;
1889   PetscFunctionReturn(PETSC_SUCCESS);
1890 }
1891 
1892 /*------------------------------------------------ Output Functions -------------------------------------------------*/
1893 /*@
1894   PetscLogDump - Dumps logs of objects to a file. This file is intended to
1895   be read by bin/petscview. This program no longer exists.
1896 
1897   Collective on `PETSC_COMM_WORLD`
1898 
1899   Input Parameter:
1900 . sname - an optional file name
1901 
1902   Example Usage:
1903 .vb
1904   PetscInitialize(...);
1905   PetscLogDefaultBegin();
1906   // ... code ...
1907   PetscLogDump(filename);
1908   PetscFinalize();
1909 .ve
1910 
1911   Level: advanced
1912 
1913   Note:
1914   The default file name is Log.<rank> where <rank> is the MPI process rank. If no name is specified,
1915   this file will be used.
1916 
1917 .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
1918 @*/
1919 PetscErrorCode PetscLogDump(const char sname[])
1920 {
1921   PetscLogHandler handler;
1922 
1923   PetscFunctionBegin;
1924   PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1925   PetscCall(PetscLogHandlerDump(handler, sname));
1926   PetscFunctionReturn(PETSC_SUCCESS);
1927 }
1928 
1929 /*@
1930   PetscLogMPEDump - Dumps the MPE logging info to file for later use with Jumpshot.
1931 
1932   Collective on `PETSC_COMM_WORLD`
1933 
1934   Input Parameter:
1935 . sname - filename for the MPE logfile
1936 
1937   Level: advanced
1938 
1939 .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogMPEBegin()`
1940 @*/
1941 PetscErrorCode PetscLogMPEDump(const char sname[])
1942 {
1943   PetscFunctionBegin;
1944   #if defined(PETSC_HAVE_MPE)
1945   if (PetscBeganMPE) {
1946     char name[PETSC_MAX_PATH_LEN];
1947 
1948     PetscCall(PetscInfo(0, "Finalizing MPE.\n"));
1949     if (sname) {
1950       PetscCall(PetscStrncpy(name, sname, sizeof(name)));
1951     } else {
1952       PetscCall(PetscGetProgramName(name, sizeof(name)));
1953     }
1954     PetscCall(MPE_Finish_log(name));
1955   } else {
1956     PetscCall(PetscInfo(0, "Not finalizing MPE (not started by PETSc).\n"));
1957   }
1958   #else
1959   SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe");
1960   #endif
1961   PetscFunctionReturn(PETSC_SUCCESS);
1962 }
1963 
1964 /*@
1965   PetscLogView - Prints a summary of the logging.
1966 
1967   Collective
1968 
1969   Input Parameter:
1970 . viewer - an ASCII viewer
1971 
1972   Options Database Keys:
1973 + -log_view [:filename]                    - Prints summary of log information
1974 . -log_view :filename.py:ascii_info_detail - Saves logging information from each process as a Python file
1975 . -log_view :filename.xml:ascii_xml        - Saves a summary of the logging information in a nested format (see below for how to view it)
1976 . -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)
1977 . -log_view_memory                         - Also display memory usage in each event
1978 . -log_view_gpu_time                       - Also display time in each event for GPU kernels (Note this may slow the computation)
1979 . -log_all                                 - Saves a file Log.rank for each MPI rank with details of each step of the computation
1980 - -log_trace [filename]                    - Displays a trace of what each process is doing
1981 
1982   Level: beginner
1983 
1984   Notes:
1985   It is possible to control the logging programmatically but we recommend using the options database approach whenever possible
1986   By default the summary is printed to stdout.
1987 
1988   Before calling this routine you must have called either PetscLogDefaultBegin() or PetscLogNestedBegin()
1989 
1990   If PETSc is configured with --with-logging=0 then this functionality is not available
1991 
1992   To view the nested XML format filename.xml first copy  ${PETSC_DIR}/share/petsc/xml/performance_xml2html.xsl to the current
1993   directory then open filename.xml with your browser. Specific notes for certain browsers
1994 .vb
1995     Firefox and Internet explorer - simply open the file
1996     Google Chrome - you must start up Chrome with the option --allow-file-access-from-files
1997     Safari - see https://ccm.net/faq/36342-safari-how-to-enable-local-file-access
1998 .ve
1999   or one can use the package <http://xmlsoft.org/XSLT/xsltproc2.html> to translate the xml file to html and then open it with
2000   your browser.
2001   Alternatively, use the script ${PETSC_DIR}/lib/petsc/bin/petsc-performance-view to automatically open a new browser
2002   window and render the XML log file contents.
2003 
2004   The nested XML format was kindly donated by Koos Huijssen and Christiaan M. Klaij  MARITIME  RESEARCH  INSTITUTE  NETHERLANDS
2005 
2006   The Flame Graph output can be visualised using either the original Flame Graph script <https://github.com/brendangregg/FlameGraph>
2007   or using speedscope <https://www.speedscope.app>.
2008   Old XML profiles may be converted into this format using the script ${PETSC_DIR}/lib/petsc/bin/xml2flamegraph.py.
2009 
2010 .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogDump()`
2011 @*/
2012 PetscErrorCode PetscLogView(PetscViewer viewer)
2013 {
2014   PetscBool         isascii;
2015   PetscViewerFormat format;
2016   int               stage;
2017   PetscLogState     state;
2018   PetscIntStack     temp_stack;
2019   PetscLogHandler   handler;
2020   PetscBool         is_empty;
2021 
2022   PetscFunctionBegin;
2023   PetscCall(PetscLogGetState(&state));
2024   /* Pop off any stages the user forgot to remove */
2025   PetscCall(PetscIntStackCreate(&temp_stack));
2026   PetscCall(PetscLogStateGetCurrentStage(state, &stage));
2027   while (stage >= 0) {
2028     PetscCall(PetscLogStagePop());
2029     PetscCall(PetscIntStackPush(temp_stack, stage));
2030     PetscCall(PetscLogStateGetCurrentStage(state, &stage));
2031   }
2032   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
2033   PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Currently can only view logging to ASCII");
2034   PetscCall(PetscViewerGetFormat(viewer, &format));
2035   if (format == PETSC_VIEWER_ASCII_XML || format == PETSC_VIEWER_ASCII_FLAMEGRAPH) {
2036     PetscCall(PetscLogGetHandler(PETSCLOGHANDLERNESTED, &handler));
2037     PetscCall(PetscLogHandlerView(handler, viewer));
2038   } else {
2039     PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
2040     PetscCall(PetscLogHandlerView(handler, viewer));
2041   }
2042   PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
2043   while (!is_empty) {
2044     PetscCall(PetscIntStackPop(temp_stack, &stage));
2045     PetscCall(PetscLogStagePush(stage));
2046     PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
2047   }
2048   PetscCall(PetscIntStackDestroy(temp_stack));
2049   PetscFunctionReturn(PETSC_SUCCESS);
2050 }
2051 
2052 /*@C
2053   PetscLogViewFromOptions - Processes command line options to determine if/how a `PetscLog` is to be viewed.
2054 
2055   Collective on `PETSC_COMM_WORLD`
2056 
2057   Level: developer
2058 
2059 .seealso: [](ch_profiling), `PetscLogView()`
2060 @*/
2061 PetscErrorCode PetscLogViewFromOptions(void)
2062 {
2063   PetscInt          n_max = PETSC_LOG_VIEW_FROM_OPTIONS_MAX;
2064   PetscViewer       viewers[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2065   PetscViewerFormat formats[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2066   PetscBool         flg;
2067 
2068   PetscFunctionBegin;
2069   PetscCall(PetscOptionsCreateViewers(PETSC_COMM_WORLD, NULL, NULL, "-log_view", &n_max, viewers, formats, &flg));
2070   for (PetscInt i = 0; i < n_max; i++) {
2071     PetscCall(PetscViewerPushFormat(viewers[i], formats[i]));
2072     PetscCall(PetscLogView(viewers[i]));
2073     PetscCall(PetscViewerPopFormat(viewers[i]));
2074     PetscCall(PetscViewerDestroy(&viewers[i]));
2075   }
2076   PetscFunctionReturn(PETSC_SUCCESS);
2077 }
2078 
2079 PETSC_INTERN PetscErrorCode PetscLogHandlerNestedSetThreshold(PetscLogHandler, PetscLogDouble, PetscLogDouble *);
2080 
2081 /*@
2082   PetscLogSetThreshold - Set the threshold time for logging the events; this is a percentage out of 100, so 1. means any event
2083   that takes 1 or more percent of the time.
2084 
2085   Logically Collective on `PETSC_COMM_WORLD`
2086 
2087   Input Parameter:
2088 . newThresh - the threshold to use
2089 
2090   Output Parameter:
2091 . oldThresh - the previously set threshold value
2092 
2093   Options Database Keys:
2094 . -log_view :filename.xml:ascii_xml - Prints an XML summary of flop and timing information to the file
2095 
2096   Example Usage:
2097 .vb
2098   PetscInitialize(...);
2099   PetscLogNestedBegin();
2100   PetscLogSetThreshold(0.1,&oldthresh);
2101   // ... code ...
2102   PetscLogView(viewer);
2103   PetscFinalize();
2104 .ve
2105 
2106   Level: advanced
2107 
2108   Note:
2109   This threshold is only used by the nested log handler
2110 
2111 .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`,
2112           `PetscLogNestedBegin()`
2113 @*/
2114 PetscErrorCode PetscLogSetThreshold(PetscLogDouble newThresh, PetscLogDouble *oldThresh)
2115 {
2116   PetscLogHandler handler;
2117 
2118   PetscFunctionBegin;
2119   PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERNESTED, &handler));
2120   PetscCall(PetscLogHandlerNestedSetThreshold(handler, newThresh, oldThresh));
2121   PetscFunctionReturn(PETSC_SUCCESS);
2122 }
2123 
2124 /*----------------------------------------------- Counter Functions -------------------------------------------------*/
2125 /*@
2126   PetscGetFlops - Returns the number of flops used on this processor
2127   since the program began.
2128 
2129   Not Collective
2130 
2131   Output Parameter:
2132 . flops - number of floating point operations
2133 
2134   Level: intermediate
2135 
2136   Notes:
2137   A global counter logs all PETSc flop counts.  The user can use
2138   `PetscLogFlops()` to increment this counter to include flops for the
2139   application code.
2140 
2141   A separate counter `PetscLogGpuFlops()` logs the flops that occur on any GPU associated with this MPI rank
2142 
2143 .seealso: [](ch_profiling), `PetscLogGpuFlops()`, `PetscTime()`, `PetscLogFlops()`
2144 @*/
2145 PetscErrorCode PetscGetFlops(PetscLogDouble *flops)
2146 {
2147   PetscFunctionBegin;
2148   *flops = petsc_TotalFlops;
2149   PetscFunctionReturn(PETSC_SUCCESS);
2150 }
2151 
2152 /*@C
2153   PetscLogObjectState - Record information about an object with the default log handler
2154 
2155   Not Collective
2156 
2157   Input Parameters:
2158 + obj    - the `PetscObject`
2159 . format - a printf-style format string
2160 - ...    - printf arguments to format
2161 
2162   Level: developer
2163 
2164 .seealso: [](ch_profiling), `PetscLogObjectCreate()`, `PetscLogObjectDestroy()`, `PetscLogGetDefaultHandler()`
2165 @*/
2166 PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
2167 {
2168   PetscFunctionBegin;
2169   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2170     PetscLogHandler h = PetscLogHandlers[i].handler;
2171 
2172     if (h) {
2173       va_list Argp;
2174       va_start(Argp, format);
2175       PetscCall(PetscLogHandlerLogObjectState_Internal(h, obj, format, Argp));
2176       va_end(Argp);
2177     }
2178   }
2179   PetscFunctionReturn(PETSC_SUCCESS);
2180 }
2181 
2182 /*MC
2183   PetscLogFlops - Adds floating point operations to the global counter.
2184 
2185   Synopsis:
2186   #include <petsclog.h>
2187   PetscErrorCode PetscLogFlops(PetscLogDouble f)
2188 
2189   Not Collective
2190 
2191   Input Parameter:
2192 . f - flop counter
2193 
2194   Example Usage:
2195 .vb
2196   PetscLogEvent USER_EVENT;
2197 
2198   PetscLogEventRegister("User event", 0, &USER_EVENT);
2199   PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
2200   [code segment to monitor]
2201   PetscLogFlops(user_flops)
2202   PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
2203 .ve
2204 
2205   Level: intermediate
2206 
2207   Note:
2208    A global counter logs all PETSc flop counts. The user can use PetscLogFlops() to increment
2209    this counter to include flops for the application code.
2210 
2211 .seealso: [](ch_profiling), `PetscLogGpuFlops()`, `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscGetFlops()`
2212 M*/
2213 
2214 /*MC
2215   PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice) to get accurate
2216   timings
2217 
2218   Synopsis:
2219   #include <petsclog.h>
2220   void PetscPreLoadBegin(PetscBool flag, char *name);
2221 
2222   Not Collective
2223 
2224   Input Parameters:
2225 + flag - `PETSC_TRUE` to run twice, `PETSC_FALSE` to run once, may be overridden with command
2226          line option `-preload true|false`
2227 - name - name of first stage (lines of code timed separately with `-log_view`) to be preloaded
2228 
2229   Example Usage:
2230 .vb
2231   PetscPreLoadBegin(PETSC_TRUE, "first stage");
2232   // lines of code
2233   PetscPreLoadStage("second stage");
2234   // lines of code
2235   PetscPreLoadEnd();
2236 .ve
2237 
2238   Level: intermediate
2239 
2240   Note:
2241   Only works in C/C++, not Fortran
2242 
2243   Flags available within the macro\:
2244 + PetscPreLoadingUsed - `PETSC_TRUE` if we are or have done preloading
2245 . PetscPreLoadingOn   - `PETSC_TRUE` if it is CURRENTLY doing preload
2246 . PetscPreLoadIt      - `0` for the first computation (with preloading turned off it is only
2247                         `0`) `1`  for the second
2248 - PetscPreLoadMax     - number of times it will do the computation, only one when preloading is
2249                         turned on
2250 
2251   The first two variables are available throughout the program, the second two only between the
2252   `PetscPreLoadBegin()` and `PetscPreLoadEnd()`
2253 
2254 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
2255 M*/
2256 
2257 /*MC
2258   PetscPreLoadEnd - End a segment of code that may be preloaded (run twice) to get accurate
2259   timings
2260 
2261   Synopsis:
2262   #include <petsclog.h>
2263   void PetscPreLoadEnd(void);
2264 
2265   Not Collective
2266 
2267   Example Usage:
2268 .vb
2269   PetscPreLoadBegin(PETSC_TRUE, "first stage");
2270   // lines of code
2271   PetscPreLoadStage("second stage");
2272   // lines of code
2273   PetscPreLoadEnd();
2274 .ve
2275 
2276   Level: intermediate
2277 
2278   Note:
2279   Only works in C/C++ not Fortran
2280 
2281 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadStage()`
2282 M*/
2283 
2284 /*MC
2285   PetscPreLoadStage - Start a new segment of code to be timed separately to get accurate timings
2286 
2287   Synopsis:
2288   #include <petsclog.h>
2289   void PetscPreLoadStage(char *name);
2290 
2291   Not Collective
2292 
2293   Example Usage:
2294 .vb
2295   PetscPreLoadBegin(PETSC_TRUE,"first stage");
2296   // lines of code
2297   PetscPreLoadStage("second stage");
2298   // lines of code
2299   PetscPreLoadEnd();
2300 .ve
2301 
2302   Level: intermediate
2303 
2304   Note:
2305   Only works in C/C++ not Fortran
2306 
2307 .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`
2308 M*/
2309 
2310   #if PetscDefined(HAVE_DEVICE)
2311     #include <petsc/private/deviceimpl.h>
2312 
2313 /*@
2314   PetscLogGpuTime - turn on the logging of GPU time for GPU kernels
2315 
2316   Options Database Key:
2317 . -log_view_gpu_time - provide the GPU times for all events in the `-log_view` output
2318 
2319   Level: advanced
2320 
2321   Notes:
2322   Turning on the timing of the GPU kernels can slow down the entire computation and should only
2323   be used when studying the performance of individual operations on GPU such as vector operations and
2324   matrix-vector operations.
2325 
2326   If this option is not used then times for most of the events in the `-log_view` output will be listed as Nan, indicating the times are not available
2327 
2328   This routine should only be called once near the beginning of the program. Once it is started
2329   it cannot be turned off.
2330 
2331 .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTimeBegin()`
2332 @*/
2333 PetscErrorCode PetscLogGpuTime(void)
2334 {
2335   PetscFunctionBegin;
2336   PetscCheck(petsc_gtime == 0.0, PETSC_COMM_SELF, PETSC_ERR_SUP, "GPU logging has already been turned on");
2337   PetscLogGpuTimeFlag = PETSC_TRUE;
2338   PetscFunctionReturn(PETSC_SUCCESS);
2339 }
2340 
2341 /*@
2342   PetscLogGpuTimeBegin - Start timer for device
2343 
2344   Level: intermediate
2345 
2346   Notes:
2347   When GPU is enabled, the timer is run on the GPU, it is a separate logging of time
2348   devoted to GPU computations (excluding kernel launch times).
2349 
2350   When GPU is not available, the timer is run on the CPU, it is a separate logging of
2351   time devoted to GPU computations (including kernel launch times).
2352 
2353   There is no need to call WaitForCUDA() or WaitForHIP() between `PetscLogGpuTimeBegin()` and
2354   `PetscLogGpuTimeEnd()`
2355 
2356   This timer should NOT include times for data transfers between the GPU and CPU, nor setup
2357   actions such as allocating space.
2358 
2359   The regular logging captures the time for data transfers and any CPU activities during the
2360   event. It is used to compute the flop rate on the GPU as it is actively engaged in running a
2361   kernel.
2362 
2363   Developer Notes:
2364   The GPU event timer captures the execution time of all the kernels launched in the default
2365   stream by the CPU between `PetscLogGpuTimeBegin()` and `PetsLogGpuTimeEnd()`.
2366 
2367   `PetscLogGpuTimeBegin()` and `PetsLogGpuTimeEnd()` insert the begin and end events into the
2368   default stream (stream 0). The device will record a time stamp for the event when it reaches
2369   that event in the stream. The function xxxEventSynchronize() is called in
2370   `PetsLogGpuTimeEnd()` to block CPU execution, but not continued GPU execution, until the
2371   timer event is recorded.
2372 
2373 .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTime()`
2374 @*/
2375 PetscErrorCode PetscLogGpuTimeBegin(void)
2376 {
2377   PetscBool isActive;
2378 
2379   PetscFunctionBegin;
2380   PetscCall(PetscLogEventBeginIsActive(&isActive));
2381   if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2382     #if defined(PETSC_HAVE_DEVICE) && !defined(PETSC_HAVE_KOKKOS_WITHOUT_GPU)
2383   {
2384     PetscDeviceContext dctx;
2385 
2386     PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2387     PetscCall(PetscDeviceContextBeginTimer_Internal(dctx));
2388   }
2389     #else
2390   PetscCall(PetscTimeSubtract(&petsc_gtime));
2391     #endif
2392   PetscFunctionReturn(PETSC_SUCCESS);
2393 }
2394 
2395 /*@
2396   PetscLogGpuTimeEnd - Stop timer for device
2397 
2398   Level: intermediate
2399 
2400 .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeBegin()`
2401 @*/
2402 PetscErrorCode PetscLogGpuTimeEnd(void)
2403 {
2404   PetscBool isActive;
2405 
2406   PetscFunctionBegin;
2407   PetscCall(PetscLogEventEndIsActive(&isActive));
2408   if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2409     #if defined(PETSC_HAVE_DEVICE) && !defined(PETSC_HAVE_KOKKOS_WITHOUT_GPU)
2410   {
2411     PetscDeviceContext dctx;
2412     PetscLogDouble     elapsed;
2413 
2414     PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2415     PetscCall(PetscDeviceContextEndTimer_Internal(dctx, &elapsed));
2416     petsc_gtime += (elapsed / 1000.0);
2417   }
2418     #else
2419   PetscCall(PetscTimeAdd(&petsc_gtime));
2420     #endif
2421   PetscFunctionReturn(PETSC_SUCCESS);
2422 }
2423 
2424   #endif /* end of PETSC_HAVE_DEVICE */
2425 
2426 #endif /* PETSC_USE_LOG*/
2427 
2428 /* -- Utility functions for logging from Fortran -- */
2429 
2430 PETSC_EXTERN PetscErrorCode PetscASend(int count, int datatype)
2431 {
2432   PetscFunctionBegin;
2433 #if PetscDefined(USE_LOG)
2434   PetscCall(PetscAddLogDouble(&petsc_send_ct, &petsc_send_ct_th, 1));
2435   #if !defined(MPIUNI_H) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO)
2436   PetscCall(PetscMPITypeSize(count, MPI_Type_f2c((MPI_Fint)datatype), &petsc_send_len, &petsc_send_len_th));
2437   #endif
2438 #endif
2439   PetscFunctionReturn(PETSC_SUCCESS);
2440 }
2441 
2442 PETSC_EXTERN PetscErrorCode PetscARecv(int count, int datatype)
2443 {
2444   PetscFunctionBegin;
2445 #if PetscDefined(USE_LOG)
2446   PetscCall(PetscAddLogDouble(&petsc_recv_ct, &petsc_recv_ct_th, 1));
2447   #if !defined(MPIUNI_H) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO)
2448   PetscCall(PetscMPITypeSize(count, MPI_Type_f2c((MPI_Fint)datatype), &petsc_recv_len, &petsc_recv_len_th));
2449   #endif
2450 #endif
2451   PetscFunctionReturn(PETSC_SUCCESS);
2452 }
2453 
2454 PETSC_EXTERN PetscErrorCode PetscAReduce(void)
2455 {
2456   PetscFunctionBegin;
2457   if (PetscDefined(USE_LOG)) PetscCall(PetscAddLogDouble(&petsc_allreduce_ct, &petsc_allreduce_ct_th, 1));
2458   PetscFunctionReturn(PETSC_SUCCESS);
2459 }
2460 
2461 PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2462 PetscClassId PETSC_OBJECT_CLASSID  = 0;
2463 
2464 static PetscBool PetscLogInitializeCalled = PETSC_FALSE;
2465 
2466 PETSC_INTERN PetscErrorCode PetscLogInitialize(void)
2467 {
2468   int stage;
2469 
2470   PetscFunctionBegin;
2471   if (PetscLogInitializeCalled) PetscFunctionReturn(PETSC_SUCCESS);
2472   PetscLogInitializeCalled = PETSC_TRUE;
2473   if (PetscDefined(USE_LOG)) {
2474     /* Setup default logging structures */
2475     PetscCall(PetscLogStateCreate(&petsc_log_state));
2476     for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2477       if (PetscLogHandlers[i].handler) PetscCall(PetscLogHandlerSetState(PetscLogHandlers[i].handler, petsc_log_state));
2478     }
2479     PetscCall(PetscLogStateStageRegister(petsc_log_state, "Main Stage", &stage));
2480     PetscCall(PetscSpinlockCreate(&PetscLogSpinLock));
2481 #if defined(PETSC_HAVE_THREADSAFETY)
2482     petsc_log_tid = 0;
2483     petsc_log_gid = 0;
2484 #endif
2485 
2486     /* All processors sync here for more consistent logging */
2487     PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
2488     PetscCall(PetscTime(&petsc_BaseTime));
2489     PetscCall(PetscLogStagePush(stage));
2490   }
2491   PetscFunctionReturn(PETSC_SUCCESS);
2492 }
2493 
2494 PETSC_INTERN PetscErrorCode PetscLogFinalize(void)
2495 {
2496   PetscFunctionBegin;
2497   if (PetscDefined(USE_LOG)) {
2498     /* Resetting phase */
2499     // pop remaining stages
2500     if (petsc_log_state) {
2501       while (petsc_log_state->current_stage >= 0) { PetscCall(PetscLogStagePop()); }
2502     }
2503     for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) PetscCall(PetscLogHandlerDestroy(&PetscLogHandlers[i].handler));
2504     PetscCall(PetscArrayzero(PetscLogHandlers, PETSC_LOG_HANDLER_MAX));
2505     PetscCall(PetscLogStateDestroy(&petsc_log_state));
2506 
2507     petsc_TotalFlops         = 0.0;
2508     petsc_BaseTime           = 0.0;
2509     petsc_TotalFlops         = 0.0;
2510     petsc_send_ct            = 0.0;
2511     petsc_recv_ct            = 0.0;
2512     petsc_send_len           = 0.0;
2513     petsc_recv_len           = 0.0;
2514     petsc_isend_ct           = 0.0;
2515     petsc_irecv_ct           = 0.0;
2516     petsc_isend_len          = 0.0;
2517     petsc_irecv_len          = 0.0;
2518     petsc_wait_ct            = 0.0;
2519     petsc_wait_any_ct        = 0.0;
2520     petsc_wait_all_ct        = 0.0;
2521     petsc_sum_of_waits_ct    = 0.0;
2522     petsc_allreduce_ct       = 0.0;
2523     petsc_gather_ct          = 0.0;
2524     petsc_scatter_ct         = 0.0;
2525     petsc_TotalFlops_th      = 0.0;
2526     petsc_send_ct_th         = 0.0;
2527     petsc_recv_ct_th         = 0.0;
2528     petsc_send_len_th        = 0.0;
2529     petsc_recv_len_th        = 0.0;
2530     petsc_isend_ct_th        = 0.0;
2531     petsc_irecv_ct_th        = 0.0;
2532     petsc_isend_len_th       = 0.0;
2533     petsc_irecv_len_th       = 0.0;
2534     petsc_wait_ct_th         = 0.0;
2535     petsc_wait_any_ct_th     = 0.0;
2536     petsc_wait_all_ct_th     = 0.0;
2537     petsc_sum_of_waits_ct_th = 0.0;
2538     petsc_allreduce_ct_th    = 0.0;
2539     petsc_gather_ct_th       = 0.0;
2540     petsc_scatter_ct_th      = 0.0;
2541 
2542     petsc_ctog_ct    = 0.0;
2543     petsc_gtoc_ct    = 0.0;
2544     petsc_ctog_sz    = 0.0;
2545     petsc_gtoc_sz    = 0.0;
2546     petsc_gflops     = 0.0;
2547     petsc_gtime      = 0.0;
2548     petsc_ctog_ct_th = 0.0;
2549     petsc_gtoc_ct_th = 0.0;
2550     petsc_ctog_sz_th = 0.0;
2551     petsc_gtoc_sz_th = 0.0;
2552     petsc_gflops_th  = 0.0;
2553     petsc_gtime_th   = 0.0;
2554   }
2555   PETSC_LARGEST_CLASSID    = PETSC_SMALLEST_CLASSID;
2556   PETSC_OBJECT_CLASSID     = 0;
2557   PetscLogInitializeCalled = PETSC_FALSE;
2558   PetscFunctionReturn(PETSC_SUCCESS);
2559 }
2560 
2561 /*@
2562   PetscClassIdRegister - Registers a new class name for objects and logging operations in an application code.
2563 
2564   Not Collective
2565 
2566   Input Parameter:
2567 . name - The class name
2568 
2569   Output Parameter:
2570 . oclass - The class id or classid
2571 
2572   Level: developer
2573 
2574 .seealso: [](ch_profiling), `PetscLogEventRegister()`
2575 @*/
2576 PetscErrorCode PetscClassIdRegister(const char name[], PetscClassId *oclass)
2577 {
2578   PetscFunctionBegin;
2579   *oclass = ++PETSC_LARGEST_CLASSID;
2580 #if defined(PETSC_USE_LOG)
2581   {
2582     PetscLogState state;
2583     PetscLogClass logclass;
2584 
2585     PetscCall(PetscLogGetState(&state));
2586     if (state) PetscCall(PetscLogStateClassRegister(state, name, *oclass, &logclass));
2587   }
2588 #endif
2589   PetscFunctionReturn(PETSC_SUCCESS);
2590 }
2591