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