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