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