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