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: /*@
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: /*@
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`, No Fortran Support
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: /*@
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`, No Fortran Support
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`, No Fortran Support
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`, No Fortran Support
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: /*@
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: /*@
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: /*@
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: /*@
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: /*@
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: /*@
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: No Fortran Support
1531: Input Parameters:
1532: . stage - The stage number or `PETSC_DETERMINE` for the current stage
1534: Output Parameter:
1535: . info - This structure is filled with the performance information
1537: Level: intermediate
1539: Notes:
1540: This is a low level routine used by the logging functions in PETSc.
1542: A `PETSCLOGHANDLERDEFAULT` must be running for this to work, having been started either with
1543: `PetscLogDefaultBegin()` or from the command line with `-log_view`. If it was not started,
1544: all performance statistics in `info` will be zeroed.
1546: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1547: @*/
1548: PetscErrorCode PetscLogStageGetPerfInfo(PetscLogStage stage, PetscEventPerfInfo *info)
1549: {
1550: PetscLogHandler handler;
1551: PetscEventPerfInfo *event_info;
1553: PetscFunctionBegin;
1554: PetscAssertPointer(info, 2);
1555: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1556: if (handler) {
1557: PetscCall(PetscLogHandlerGetStagePerfInfo(handler, stage, &event_info));
1558: *info = *event_info;
1559: } else {
1560: PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogStageGetPerfInfo() returning zeros\n"));
1561: PetscCall(PetscMemzero(info, sizeof(*info)));
1562: }
1563: PetscFunctionReturn(PETSC_SUCCESS);
1564: }
1566: /*@C
1567: PetscLogEventGetPerfInfo - Return the performance information about the given event in the given stage
1569: No Fortran Support
1571: Input Parameters:
1572: + stage - The stage number or `PETSC_DETERMINE` for the current stage
1573: - event - The event number
1575: Output Parameter:
1576: . info - This structure is filled with the performance information
1578: Level: intermediate
1580: Note:
1581: This is a low level routine used by the logging functions in PETSc
1583: A `PETSCLOGHANDLERDEFAULT` must be running for this to work, having been started either with
1584: `PetscLogDefaultBegin()` or from the command line with `-log_view`. If it was not started,
1585: all performance statistics in `info` will be zeroed.
1587: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1588: @*/
1589: PetscErrorCode PetscLogEventGetPerfInfo(PetscLogStage stage, PetscLogEvent event, PetscEventPerfInfo *info)
1590: {
1591: PetscLogHandler handler;
1592: PetscEventPerfInfo *event_info;
1594: PetscFunctionBegin;
1595: PetscAssertPointer(info, 3);
1596: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1597: if (handler) {
1598: PetscCall(PetscLogHandlerGetEventPerfInfo(handler, stage, event, &event_info));
1599: *info = *event_info;
1600: } else {
1601: PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogEventGetPerfInfo() returning zeros\n"));
1602: PetscCall(PetscMemzero(info, sizeof(*info)));
1603: }
1604: PetscFunctionReturn(PETSC_SUCCESS);
1605: }
1607: /*@
1608: PetscLogEventSetDof - Set the nth number of degrees of freedom of a numerical problem associated with this event
1610: Not Collective
1612: Input Parameters:
1613: + event - The event id to log
1614: . n - The dof index, in [0, 8)
1615: - dof - The number of dofs
1617: Options Database Key:
1618: . -log_view - Activates log summary
1620: Level: developer
1622: Note:
1623: This is to enable logging of convergence
1625: .seealso: `PetscLogEventSetError()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1626: @*/
1627: PetscErrorCode PetscLogEventSetDof(PetscLogEvent event, PetscInt n, PetscLogDouble dof)
1628: {
1629: PetscFunctionBegin;
1630: PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1631: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1632: PetscLogHandler h = PetscLogHandlers[i].handler;
1634: if (h) {
1635: PetscEventPerfInfo *event_info;
1637: PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1638: if (event_info) event_info->dof[n] = dof;
1639: }
1640: }
1641: PetscFunctionReturn(PETSC_SUCCESS);
1642: }
1644: /*@
1645: PetscLogEventSetError - Set the nth error associated with a numerical problem associated with this event
1647: Not Collective
1649: Input Parameters:
1650: + event - The event id to log
1651: . n - The error index, in [0, 8)
1652: - error - The error
1654: Options Database Key:
1655: . -log_view - Activates log summary
1657: Level: developer
1659: Notes:
1660: This is to enable logging of convergence, and enable users to interpret the errors as they wish. For example,
1661: as different norms, or as errors for different fields
1663: This is a low level routine used by the logging functions in PETSc
1665: .seealso: `PetscLogEventSetDof()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1666: @*/
1667: PetscErrorCode PetscLogEventSetError(PetscLogEvent event, PetscInt n, PetscLogDouble error)
1668: {
1669: PetscFunctionBegin;
1670: PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1671: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1672: PetscLogHandler h = PetscLogHandlers[i].handler;
1674: if (h) {
1675: PetscEventPerfInfo *event_info;
1677: PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1678: if (event_info) event_info->errors[n] = error;
1679: }
1680: }
1681: PetscFunctionReturn(PETSC_SUCCESS);
1682: }
1684: /*@
1685: PetscLogEventGetId - Returns the event id when given the event name.
1687: Not Collective
1689: Input Parameter:
1690: . name - The event name
1692: Output Parameter:
1693: . event - The event, or -1 if no event with that name exists
1695: Level: intermediate
1697: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1698: @*/
1699: PetscErrorCode PetscLogEventGetId(const char name[], PetscLogEvent *event)
1700: {
1701: PetscLogState state;
1703: PetscFunctionBegin;
1704: *event = -1;
1705: PetscCall(PetscLogGetState(&state));
1706: if (state) PetscCall(PetscLogStateGetEventFromName(state, name, event));
1707: PetscFunctionReturn(PETSC_SUCCESS);
1708: }
1710: /*@
1711: PetscLogEventGetName - Returns the event name when given the event id.
1713: Not Collective
1715: Input Parameter:
1716: . event - The event
1718: Output Parameter:
1719: . name - The event name
1721: Level: intermediate
1723: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
1724: @*/
1725: PetscErrorCode PetscLogEventGetName(PetscLogEvent event, const char *name[])
1726: {
1727: PetscLogEventInfo event_info;
1728: PetscLogState state;
1730: PetscFunctionBegin;
1731: *name = NULL;
1732: PetscCall(PetscLogGetState(&state));
1733: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1734: PetscCall(PetscLogStateEventGetInfo(state, event, &event_info));
1735: *name = event_info.name;
1736: PetscFunctionReturn(PETSC_SUCCESS);
1737: }
1739: /*@
1740: PetscLogEventsPause - Put event logging into "paused" mode: timers and counters for in-progress events are paused, and any events that happen before logging is resumed with `PetscLogEventsResume()` are logged in the "Main Stage" of execution.
1742: Not collective
1744: Level: advanced
1746: Notes:
1747: When an external library or runtime has is initialized it can involve lots of setup time that skews the statistics of any unrelated running events: this function is intended to isolate such calls in the default log summary (`PetscLogDefaultBegin()`, `PetscLogView()`).
1749: Other log handlers (such as the nested handler, `PetscLogNestedBegin()`) will ignore this function.
1751: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsResume()`, `PetscLogGetDefaultHandler()`
1752: @*/
1753: PetscErrorCode PetscLogEventsPause(void)
1754: {
1755: PetscFunctionBegin;
1756: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1757: PetscLogHandler h = PetscLogHandlers[i].handler;
1759: if (h) PetscCall(PetscLogHandlerEventsPause(h));
1760: }
1761: PetscFunctionReturn(PETSC_SUCCESS);
1762: }
1764: /*@
1765: PetscLogEventsResume - Return logging to normal behavior after it was paused with `PetscLogEventsPause()`.
1767: Not collective
1769: Level: advanced
1771: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsPause()`, `PetscLogGetDefaultHandler()`
1772: @*/
1773: PetscErrorCode PetscLogEventsResume(void)
1774: {
1775: PetscFunctionBegin;
1776: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1777: PetscLogHandler h = PetscLogHandlers[i].handler;
1779: if (h) PetscCall(PetscLogHandlerEventsResume(h));
1780: }
1781: PetscFunctionReturn(PETSC_SUCCESS);
1782: }
1784: /*------------------------------------------------ Class Functions --------------------------------------------------*/
1786: /*MC
1787: PetscLogObjectCreate - Log the creation of a `PetscObject`
1789: Synopsis:
1790: #include <petsclog.h>
1791: PetscErrorCode PetscLogObjectCreate(PetscObject h)
1793: Not Collective
1795: Input Parameters:
1796: . h - A `PetscObject`
1798: Level: developer
1800: Developer Note:
1801: Called internally by PETSc when creating objects: users do not need to call this directly.
1802: Notification of the object creation is sent to each `PetscLogHandler` that is running.
1804: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectDestroy()`
1805: M*/
1807: /*MC
1808: PetscLogObjectDestroy - Logs the destruction of a `PetscObject`
1810: Synopsis:
1811: #include <petsclog.h>
1812: PetscErrorCode PetscLogObjectDestroy(PetscObject h)
1814: Not Collective
1816: Input Parameters:
1817: . h - A `PetscObject`
1819: Level: developer
1821: Developer Note:
1822: Called internally by PETSc when destroying objects: users do not need to call this directly.
1823: Notification of the object creation is sent to each `PetscLogHandler` that is running.
1825: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectCreate()`
1826: M*/
1828: /*@
1829: PetscLogClassGetClassId - Returns the `PetscClassId` when given the class name.
1831: Not Collective
1833: Input Parameter:
1834: . name - The class name
1836: Output Parameter:
1837: . classid - The `PetscClassId` id, or -1 if no class with that name exists
1839: Level: intermediate
1841: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1842: @*/
1843: PetscErrorCode PetscLogClassGetClassId(const char name[], PetscClassId *classid)
1844: {
1845: PetscLogClass log_class;
1846: PetscLogClassInfo class_info;
1847: PetscLogState state;
1849: PetscFunctionBegin;
1850: *classid = -1;
1851: PetscCall(PetscLogGetState(&state));
1852: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1853: PetscCall(PetscLogStateGetClassFromName(state, name, &log_class));
1854: if (log_class < 0) {
1855: *classid = -1;
1856: PetscFunctionReturn(PETSC_SUCCESS);
1857: }
1858: PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1859: *classid = class_info.classid;
1860: PetscFunctionReturn(PETSC_SUCCESS);
1861: }
1863: /*@C
1864: PetscLogClassIdGetName - Returns a `PetscClassId`'s name.
1866: Not Collective
1868: Input Parameter:
1869: . classid - A `PetscClassId`
1871: Output Parameter:
1872: . name - The class name
1874: Level: intermediate
1876: .seealso: [](ch_profiling), `PetscLogClassRegister()`, `PetscLogClassBegin()`, `PetscLogClassEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadClass()`
1877: @*/
1878: PetscErrorCode PetscLogClassIdGetName(PetscClassId classid, const char **name)
1879: {
1880: PetscLogClass log_class;
1881: PetscLogClassInfo class_info;
1882: PetscLogState state;
1884: PetscFunctionBegin;
1885: PetscCall(PetscLogGetState(&state));
1886: PetscCall(PetscLogStateGetClassFromClassId(state, classid, &log_class));
1887: PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1888: *name = class_info.name;
1889: PetscFunctionReturn(PETSC_SUCCESS);
1890: }
1892: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1893: /*@
1894: PetscLogDump - Dumps logs of objects to a file. This file is intended to
1895: be read by bin/petscview. This program no longer exists.
1897: Collective on `PETSC_COMM_WORLD`
1899: Input Parameter:
1900: . sname - an optional file name
1902: Example Usage:
1903: .vb
1904: PetscInitialize(...);
1905: PetscLogDefaultBegin();
1906: // ... code ...
1907: PetscLogDump(filename);
1908: PetscFinalize();
1909: .ve
1911: Level: advanced
1913: Note:
1914: The default file name is Log.<rank> where <rank> is the MPI process rank. If no name is specified,
1915: this file will be used.
1917: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
1918: @*/
1919: PetscErrorCode PetscLogDump(const char sname[])
1920: {
1921: PetscLogHandler handler;
1923: PetscFunctionBegin;
1924: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1925: PetscCall(PetscLogHandlerDump(handler, sname));
1926: PetscFunctionReturn(PETSC_SUCCESS);
1927: }
1929: /*@
1930: PetscLogMPEDump - Dumps the MPE logging info to file for later use with Jumpshot.
1932: Collective on `PETSC_COMM_WORLD`
1934: Input Parameter:
1935: . sname - filename for the MPE logfile
1937: Level: advanced
1939: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogMPEBegin()`
1940: @*/
1941: PetscErrorCode PetscLogMPEDump(const char sname[])
1942: {
1943: PetscFunctionBegin;
1944: #if defined(PETSC_HAVE_MPE)
1945: if (PetscBeganMPE) {
1946: char name[PETSC_MAX_PATH_LEN];
1948: PetscCall(PetscInfo(0, "Finalizing MPE.\n"));
1949: if (sname) {
1950: PetscCall(PetscStrncpy(name, sname, sizeof(name)));
1951: } else {
1952: PetscCall(PetscGetProgramName(name, sizeof(name)));
1953: }
1954: PetscCall(MPE_Finish_log(name));
1955: } else {
1956: PetscCall(PetscInfo(0, "Not finalizing MPE (not started by PETSc).\n"));
1957: }
1958: #else
1959: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe");
1960: #endif
1961: PetscFunctionReturn(PETSC_SUCCESS);
1962: }
1964: /*@
1965: PetscLogView - Prints a summary of the logging.
1967: Collective
1969: Input Parameter:
1970: . viewer - an ASCII viewer
1972: Options Database Keys:
1973: + -log_view [:filename] - Prints summary of log information
1974: . -log_view :filename.py:ascii_info_detail - Saves logging information from each process as a Python file
1975: . -log_view :filename.xml:ascii_xml - Saves a summary of the logging information in a nested format (see below for how to view it)
1976: . -log_view :filename.txt:ascii_flamegraph - Saves logging information in a format suitable for visualising as a Flame Graph (see below for how to view it)
1977: . -log_view_memory - Also display memory usage in each event
1978: . -log_view_gpu_time - Also display time in each event for GPU kernels (Note this may slow the computation)
1979: . -log_all - Saves a file Log.rank for each MPI rank with details of each step of the computation
1980: - -log_trace [filename] - Displays a trace of what each process is doing
1982: Level: beginner
1984: Notes:
1985: It is possible to control the logging programmatically but we recommend using the options database approach whenever possible
1986: By default the summary is printed to stdout.
1988: Before calling this routine you must have called either PetscLogDefaultBegin() or PetscLogNestedBegin()
1990: If PETSc is configured with --with-logging=0 then this functionality is not available
1992: To view the nested XML format filename.xml first copy ${PETSC_DIR}/share/petsc/xml/performance_xml2html.xsl to the current
1993: directory then open filename.xml with your browser. Specific notes for certain browsers
1994: .vb
1995: Firefox and Internet explorer - simply open the file
1996: Google Chrome - you must start up Chrome with the option --allow-file-access-from-files
1997: Safari - see https://ccm.net/faq/36342-safari-how-to-enable-local-file-access
1998: .ve
1999: or one can use the package <http://xmlsoft.org/XSLT/xsltproc2.html> to translate the xml file to html and then open it with
2000: your browser.
2001: Alternatively, use the script ${PETSC_DIR}/lib/petsc/bin/petsc-performance-view to automatically open a new browser
2002: window and render the XML log file contents.
2004: The nested XML format was kindly donated by Koos Huijssen and Christiaan M. Klaij MARITIME RESEARCH INSTITUTE NETHERLANDS
2006: The Flame Graph output can be visualised using either the original Flame Graph script <https://github.com/brendangregg/FlameGraph>
2007: or using speedscope <https://www.speedscope.app>.
2008: Old XML profiles may be converted into this format using the script ${PETSC_DIR}/lib/petsc/bin/xml2flamegraph.py.
2010: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogDump()`
2011: @*/
2012: PetscErrorCode PetscLogView(PetscViewer viewer)
2013: {
2014: PetscBool isascii;
2015: PetscViewerFormat format;
2016: int stage;
2017: PetscLogState state;
2018: PetscIntStack temp_stack;
2019: PetscLogHandler handler;
2020: PetscBool is_empty;
2022: PetscFunctionBegin;
2023: PetscCall(PetscLogGetState(&state));
2024: /* Pop off any stages the user forgot to remove */
2025: PetscCall(PetscIntStackCreate(&temp_stack));
2026: PetscCall(PetscLogStateGetCurrentStage(state, &stage));
2027: while (stage >= 0) {
2028: PetscCall(PetscLogStagePop());
2029: PetscCall(PetscIntStackPush(temp_stack, stage));
2030: PetscCall(PetscLogStateGetCurrentStage(state, &stage));
2031: }
2032: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
2033: PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Currently can only view logging to ASCII");
2034: PetscCall(PetscViewerGetFormat(viewer, &format));
2035: if (format == PETSC_VIEWER_ASCII_XML || format == PETSC_VIEWER_ASCII_FLAMEGRAPH) {
2036: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERNESTED, &handler));
2037: PetscCall(PetscLogHandlerView(handler, viewer));
2038: } else {
2039: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
2040: PetscCall(PetscLogHandlerView(handler, viewer));
2041: }
2042: PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
2043: while (!is_empty) {
2044: PetscCall(PetscIntStackPop(temp_stack, &stage));
2045: PetscCall(PetscLogStagePush(stage));
2046: PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
2047: }
2048: PetscCall(PetscIntStackDestroy(temp_stack));
2049: PetscFunctionReturn(PETSC_SUCCESS);
2050: }
2052: /*@C
2053: PetscLogViewFromOptions - Processes command line options to determine if/how a `PetscLog` is to be viewed.
2055: Collective on `PETSC_COMM_WORLD`
2057: Level: developer
2059: .seealso: [](ch_profiling), `PetscLogView()`
2060: @*/
2061: PetscErrorCode PetscLogViewFromOptions(void)
2062: {
2063: PetscInt n_max = PETSC_LOG_VIEW_FROM_OPTIONS_MAX;
2064: PetscViewer viewers[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2065: PetscViewerFormat formats[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2066: PetscBool flg;
2068: PetscFunctionBegin;
2069: PetscCall(PetscOptionsGetViewers(PETSC_COMM_WORLD, NULL, NULL, "-log_view", &n_max, viewers, formats, &flg));
2070: for (PetscInt i = 0; i < n_max; i++) {
2071: PetscCall(PetscViewerPushFormat(viewers[i], formats[i]));
2072: PetscCall(PetscLogView(viewers[i]));
2073: PetscCall(PetscViewerPopFormat(viewers[i]));
2074: PetscCall(PetscOptionsRestoreViewer(&viewers[i]));
2075: }
2076: PetscFunctionReturn(PETSC_SUCCESS);
2077: }
2079: PETSC_INTERN PetscErrorCode PetscLogHandlerNestedSetThreshold(PetscLogHandler, PetscLogDouble, PetscLogDouble *);
2081: /*@
2082: PetscLogSetThreshold - Set the threshold time for logging the events; this is a percentage out of 100, so 1. means any event
2083: that takes 1 or more percent of the time.
2085: Logically Collective on `PETSC_COMM_WORLD`
2087: Input Parameter:
2088: . newThresh - the threshold to use
2090: Output Parameter:
2091: . oldThresh - the previously set threshold value
2093: Options Database Keys:
2094: . -log_view :filename.xml:ascii_xml - Prints an XML summary of flop and timing information to the file
2096: Example Usage:
2097: .vb
2098: PetscInitialize(...);
2099: PetscLogNestedBegin();
2100: PetscLogSetThreshold(0.1,&oldthresh);
2101: // ... code ...
2102: PetscLogView(viewer);
2103: PetscFinalize();
2104: .ve
2106: Level: advanced
2108: Note:
2109: This threshold is only used by the nested log handler
2111: .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`,
2112: `PetscLogNestedBegin()`
2113: @*/
2114: PetscErrorCode PetscLogSetThreshold(PetscLogDouble newThresh, PetscLogDouble *oldThresh)
2115: {
2116: PetscLogHandler handler;
2118: PetscFunctionBegin;
2119: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERNESTED, &handler));
2120: PetscCall(PetscLogHandlerNestedSetThreshold(handler, newThresh, oldThresh));
2121: PetscFunctionReturn(PETSC_SUCCESS);
2122: }
2124: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
2125: /*@
2126: PetscGetFlops - Returns the number of flops used on this processor
2127: since the program began.
2129: Not Collective
2131: Output Parameter:
2132: . flops - number of floating point operations
2134: Level: intermediate
2136: Notes:
2137: A global counter logs all PETSc flop counts. The user can use
2138: `PetscLogFlops()` to increment this counter to include flops for the
2139: application code.
2141: A separate counter `PetscLogGpuFlops()` logs the flops that occur on any GPU associated with this MPI rank
2143: .seealso: [](ch_profiling), `PetscLogGpuFlops()`, `PetscTime()`, `PetscLogFlops()`
2144: @*/
2145: PetscErrorCode PetscGetFlops(PetscLogDouble *flops)
2146: {
2147: PetscFunctionBegin;
2148: *flops = petsc_TotalFlops;
2149: PetscFunctionReturn(PETSC_SUCCESS);
2150: }
2152: /*@C
2153: PetscLogObjectState - Record information about an object with the default log handler
2155: Not Collective
2157: Input Parameters:
2158: + obj - the `PetscObject`
2159: . format - a printf-style format string
2160: - ... - printf arguments to format
2162: Level: developer
2164: .seealso: [](ch_profiling), `PetscLogObjectCreate()`, `PetscLogObjectDestroy()`, `PetscLogGetDefaultHandler()`
2165: @*/
2166: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
2167: {
2168: PetscFunctionBegin;
2169: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2170: PetscLogHandler h = PetscLogHandlers[i].handler;
2172: if (h) {
2173: va_list Argp;
2174: va_start(Argp, format);
2175: PetscCall(PetscLogHandlerLogObjectState_Internal(h, obj, format, Argp));
2176: va_end(Argp);
2177: }
2178: }
2179: PetscFunctionReturn(PETSC_SUCCESS);
2180: }
2182: /*MC
2183: PetscLogFlops - Adds floating point operations to the global counter.
2185: Synopsis:
2186: #include <petsclog.h>
2187: PetscErrorCode PetscLogFlops(PetscLogDouble f)
2189: Not Collective
2191: Input Parameter:
2192: . f - flop counter
2194: Example Usage:
2195: .vb
2196: PetscLogEvent USER_EVENT;
2198: PetscLogEventRegister("User event", 0, &USER_EVENT);
2199: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
2200: [code segment to monitor]
2201: PetscLogFlops(user_flops)
2202: PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
2203: .ve
2205: Level: intermediate
2207: Note:
2208: A global counter logs all PETSc flop counts. The user can use PetscLogFlops() to increment
2209: this counter to include flops for the application code.
2211: .seealso: [](ch_profiling), `PetscLogGpuFlops()`, `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscGetFlops()`
2212: M*/
2214: /*MC
2215: PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice) to get accurate
2216: timings
2218: Synopsis:
2219: #include <petsclog.h>
2220: void PetscPreLoadBegin(PetscBool flag, char *name);
2222: Not Collective
2224: Input Parameters:
2225: + flag - `PETSC_TRUE` to run twice, `PETSC_FALSE` to run once, may be overridden with command
2226: line option `-preload true|false`
2227: - name - name of first stage (lines of code timed separately with `-log_view`) to be preloaded
2229: Example Usage:
2230: .vb
2231: PetscPreLoadBegin(PETSC_TRUE, "first stage");
2232: // lines of code
2233: PetscPreLoadStage("second stage");
2234: // lines of code
2235: PetscPreLoadEnd();
2236: .ve
2238: Level: intermediate
2240: Note:
2241: Only works in C/C++, not Fortran
2243: Flags available within the macro\:
2244: + PetscPreLoadingUsed - `PETSC_TRUE` if we are or have done preloading
2245: . PetscPreLoadingOn - `PETSC_TRUE` if it is CURRENTLY doing preload
2246: . PetscPreLoadIt - `0` for the first computation (with preloading turned off it is only
2247: `0`) `1` for the second
2248: - PetscPreLoadMax - number of times it will do the computation, only one when preloading is
2249: turned on
2251: The first two variables are available throughout the program, the second two only between the
2252: `PetscPreLoadBegin()` and `PetscPreLoadEnd()`
2254: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
2255: M*/
2257: /*MC
2258: PetscPreLoadEnd - End a segment of code that may be preloaded (run twice) to get accurate
2259: timings
2261: Synopsis:
2262: #include <petsclog.h>
2263: void PetscPreLoadEnd(void);
2265: Not Collective
2267: Example Usage:
2268: .vb
2269: PetscPreLoadBegin(PETSC_TRUE, "first stage");
2270: // lines of code
2271: PetscPreLoadStage("second stage");
2272: // lines of code
2273: PetscPreLoadEnd();
2274: .ve
2276: Level: intermediate
2278: Note:
2279: Only works in C/C++ not Fortran
2281: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadStage()`
2282: M*/
2284: /*MC
2285: PetscPreLoadStage - Start a new segment of code to be timed separately to get accurate timings
2287: Synopsis:
2288: #include <petsclog.h>
2289: void PetscPreLoadStage(char *name);
2291: Not Collective
2293: Example Usage:
2294: .vb
2295: PetscPreLoadBegin(PETSC_TRUE,"first stage");
2296: // lines of code
2297: PetscPreLoadStage("second stage");
2298: // lines of code
2299: PetscPreLoadEnd();
2300: .ve
2302: Level: intermediate
2304: Note:
2305: Only works in C/C++ not Fortran
2307: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`
2308: M*/
2310: #if PetscDefined(HAVE_DEVICE)
2311: #include <petsc/private/deviceimpl.h>
2313: /*@
2314: PetscLogGpuTime - turn on the logging of GPU time for GPU kernels
2316: Options Database Key:
2317: . -log_view_gpu_time - provide the GPU times for all events in the `-log_view` output
2319: Level: advanced
2321: Notes:
2322: Turning on the timing of the GPU kernels can slow down the entire computation and should only
2323: be used when studying the performance of individual operations on GPU such as vector operations and
2324: matrix-vector operations.
2326: If this option is not used then times for most of the events in the `-log_view` output will be listed as Nan, indicating the times are not available
2328: This routine should only be called once near the beginning of the program. Once it is started
2329: it cannot be turned off.
2331: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTimeBegin()`
2332: @*/
2333: PetscErrorCode PetscLogGpuTime(void)
2334: {
2335: PetscFunctionBegin;
2336: PetscCheck(petsc_gtime == 0.0, PETSC_COMM_SELF, PETSC_ERR_SUP, "GPU logging has already been turned on");
2337: PetscLogGpuTimeFlag = PETSC_TRUE;
2338: PetscFunctionReturn(PETSC_SUCCESS);
2339: }
2341: /*@
2342: PetscLogGpuTimeBegin - Start timer for device
2344: Level: intermediate
2346: Notes:
2347: When CUDA or HIP is enabled, the timer is run on the GPU, it is a separate logging of time
2348: devoted to GPU computations (excluding kernel launch times).
2350: When CUDA or HIP is not available, the timer is run on the CPU, it is a separate logging of
2351: time devoted to GPU computations (including kernel launch times).
2353: There is no need to call WaitForCUDA() or WaitForHIP() between `PetscLogGpuTimeBegin()` and
2354: `PetscLogGpuTimeEnd()`
2356: This timer should NOT include times for data transfers between the GPU and CPU, nor setup
2357: actions such as allocating space.
2359: The regular logging captures the time for data transfers and any CPU activities during the
2360: event. It is used to compute the flop rate on the GPU as it is actively engaged in running a
2361: kernel.
2363: Developer Notes:
2364: The GPU event timer captures the execution time of all the kernels launched in the default
2365: stream by the CPU between `PetscLogGpuTimeBegin()` and `PetsLogGpuTimeEnd()`.
2367: `PetscLogGpuTimeBegin()` and `PetsLogGpuTimeEnd()` insert the begin and end events into the
2368: default stream (stream 0). The device will record a time stamp for the event when it reaches
2369: that event in the stream. The function xxxEventSynchronize() is called in
2370: `PetsLogGpuTimeEnd()` to block CPU execution, but not continued GPU execution, until the
2371: timer event is recorded.
2373: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTime()`
2374: @*/
2375: PetscErrorCode PetscLogGpuTimeBegin(void)
2376: {
2377: PetscBool isActive;
2379: PetscFunctionBegin;
2380: PetscCall(PetscLogEventBeginIsActive(&isActive));
2381: if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2382: if (PetscDefined(HAVE_DEVICE)) {
2383: PetscDeviceContext dctx;
2385: PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2386: PetscCall(PetscDeviceContextBeginTimer_Internal(dctx));
2387: } else {
2388: PetscCall(PetscTimeSubtract(&petsc_gtime));
2389: }
2390: PetscFunctionReturn(PETSC_SUCCESS);
2391: }
2393: /*@
2394: PetscLogGpuTimeEnd - Stop timer for device
2396: Level: intermediate
2398: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeBegin()`
2399: @*/
2400: PetscErrorCode PetscLogGpuTimeEnd(void)
2401: {
2402: PetscBool isActive;
2404: PetscFunctionBegin;
2405: PetscCall(PetscLogEventEndIsActive(&isActive));
2406: if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2407: if (PetscDefined(HAVE_DEVICE)) {
2408: PetscDeviceContext dctx;
2409: PetscLogDouble elapsed;
2411: PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2412: PetscCall(PetscDeviceContextEndTimer_Internal(dctx, &elapsed));
2413: petsc_gtime += (elapsed / 1000.0);
2414: } else {
2415: PetscCall(PetscTimeAdd(&petsc_gtime));
2416: }
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: /*@
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: }