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