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 PetscDefined(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 */
87: PetscLogDouble petsc_genergy = 0.0; /* The energy (estimated with power*gtime) consumed on a GPU */
88: PetscLogDouble petsc_genergy_meter = 0.0; /* Readings from the energy meter on a GPU */
90: PETSC_TLS PetscLogDouble petsc_ctog_ct_th = 0.0;
91: PETSC_TLS PetscLogDouble petsc_gtoc_ct_th = 0.0;
92: PETSC_TLS PetscLogDouble petsc_ctog_sz_th = 0.0;
93: PETSC_TLS PetscLogDouble petsc_gtoc_sz_th = 0.0;
94: PETSC_TLS PetscLogDouble petsc_ctog_ct_scalar_th = 0.0;
95: PETSC_TLS PetscLogDouble petsc_gtoc_ct_scalar_th = 0.0;
96: PETSC_TLS PetscLogDouble petsc_ctog_sz_scalar_th = 0.0;
97: PETSC_TLS PetscLogDouble petsc_gtoc_sz_scalar_th = 0.0;
98: PETSC_TLS PetscLogDouble petsc_gflops_th = 0.0;
99: PETSC_TLS PetscLogDouble petsc_gtime_th = 0.0;
101: PetscBool PetscLogMemory = PETSC_FALSE;
102: PetscBool PetscLogSyncOn = PETSC_FALSE;
104: PetscBool PetscLogGpuTimeFlag = PETSC_FALSE;
105: PetscBool PetscLogGpuEnergyFlag = PETSC_FALSE;
106: PetscBool PetscLogGpuEnergyMeterFlag = PETSC_FALSE;
108: PetscInt PetscLogNumViewersCreated = 0;
109: PetscInt PetscLogNumViewersDestroyed = 0;
111: PetscLogState petsc_log_state = NULL;
113: #define PETSC_LOG_HANDLER_HOT_BLANK {NULL, NULL, NULL, NULL, NULL, NULL}
115: PetscLogHandlerHot PetscLogHandlers[PETSC_LOG_HANDLER_MAX] = {
116: PETSC_LOG_HANDLER_HOT_BLANK,
117: PETSC_LOG_HANDLER_HOT_BLANK,
118: PETSC_LOG_HANDLER_HOT_BLANK,
119: PETSC_LOG_HANDLER_HOT_BLANK,
120: };
122: #undef PETSC_LOG_HANDLERS_HOT_BLANK
124: #if PetscDefined(USE_LOG)
125: #include <../src/sys/logging/handler/impls/default/logdefault.h>
127: #if PetscDefined(HAVE_THREADSAFETY)
128: /*@
129: PetscAddLogDouble - Atomically add a `PetscLogDouble` value to both a global counter and its per-thread counterpart
131: Not Collective; No Fortran Support
133: Input Parameters:
134: + tot - pointer to the global counter to update
135: . tot_th - pointer to the per-thread counter to update
136: - value - the value to add to both counters
138: Level: developer
140: Note:
141: When PETSc is built without thread safety this is a fast macro that performs the same update without locking.
143: .seealso: `PetscAddLogDoubleCnt()`, `PetscLogFlops()`, `PetscLogDouble`
144: @*/
145: PetscErrorCode PetscAddLogDouble(PetscLogDouble *tot, PetscLogDouble *tot_th, PetscLogDouble value)
146: {
147: *tot_th += value;
148: PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
149: *tot += value;
150: PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
151: return PETSC_SUCCESS;
152: }
154: /*@
155: PetscAddLogDoubleCnt - Atomically update both a count pair and a size pair of `PetscLogDouble` counters (global and per-thread)
157: Not Collective; No Fortran Support
159: Input Parameters:
160: + cnt - pointer to the global count counter to increment by one
161: . tot - pointer to the global size counter to update
162: . cnt_th - pointer to the per-thread count counter to increment by one
163: . tot_th - pointer to the per-thread size counter to update
164: - value - the size value to add to the size counters
166: Level: developer
168: .seealso: `PetscAddLogDouble()`, `PetscLogFlops()`, `PetscLogDouble`
169: @*/
170: PetscErrorCode PetscAddLogDoubleCnt(PetscLogDouble *cnt, PetscLogDouble *tot, PetscLogDouble *cnt_th, PetscLogDouble *tot_th, PetscLogDouble value)
171: {
172: *cnt_th = *cnt_th + 1;
173: *tot_th += value;
174: PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
175: *tot += (PetscLogDouble)value;
176: *cnt += *cnt + 1;
177: PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
178: return PETSC_SUCCESS;
179: }
181: #endif
183: static PetscErrorCode PetscLogTryGetHandler(PetscLogHandlerType type, PetscLogHandler *handler)
184: {
185: PetscFunctionBegin;
186: PetscAssertPointer(handler, 2);
187: *handler = NULL;
188: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
189: PetscLogHandler h = PetscLogHandlers[i].handler;
190: if (h) {
191: PetscBool match;
193: PetscCall(PetscObjectTypeCompare((PetscObject)h, type, &match));
194: if (match) {
195: *handler = PetscLogHandlers[i].handler;
196: PetscFunctionReturn(PETSC_SUCCESS);
197: }
198: }
199: }
200: PetscFunctionReturn(PETSC_SUCCESS);
201: }
203: /*@
204: PetscLogGetDefaultHandler - Get the default log handler if it is running.
206: Not collective
208: Output Parameter:
209: . handler - the default `PetscLogHandler`, or `NULL` if it is not running.
211: Level: developer
213: Notes:
214: The default handler is started with `PetscLogDefaultBegin()`,
215: if the options flags `-log_all` or `-log_view` is given without arguments,
216: or for `-log_view :output:format` if `format` is not `ascii_xml` or `ascii_flamegraph`.
218: .seealso: [](ch_profiling)
219: @*/
220: PetscErrorCode PetscLogGetDefaultHandler(PetscLogHandler *handler)
221: {
222: PetscFunctionBegin;
223: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, handler));
224: PetscFunctionReturn(PETSC_SUCCESS);
225: }
227: static PetscErrorCode PetscLogGetHandler(PetscLogHandlerType type, PetscLogHandler *handler)
228: {
229: PetscFunctionBegin;
230: PetscAssertPointer(handler, 2);
231: PetscCall(PetscLogTryGetHandler(type, handler));
232: PetscCheck(*handler != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "A PetscLogHandler of type %s has not been started.", type);
233: PetscFunctionReturn(PETSC_SUCCESS);
234: }
236: /*@
237: PetscLogGetState - Get the `PetscLogState` for PETSc's global logging, used
238: by all default log handlers (`PetscLogDefaultBegin()`,
239: `PetscLogNestedBegin()`, `PetscLogTraceBegin()`, `PetscLogMPEBegin()`,
240: `PetscLogPerfstubsBegin()`).
242: Collective on `PETSC_COMM_WORLD`
244: Output Parameter:
245: . state - The `PetscLogState` changed by registrations (such as
246: `PetscLogEventRegister()`) and actions (such as `PetscLogEventBegin()` or
247: `PetscLogStagePush()`), or `NULL` if logging is not active
249: Level: developer
251: .seealso: [](ch_profiling), `PetscLogState`
252: @*/
253: PetscErrorCode PetscLogGetState(PetscLogState *state)
254: {
255: PetscFunctionBegin;
256: PetscAssertPointer(state, 1);
257: *state = petsc_log_state;
258: PetscFunctionReturn(PETSC_SUCCESS);
259: }
261: static PetscErrorCode PetscLogHandlerCopyToHot(PetscLogHandler h, PetscLogHandlerHot *hot)
262: {
263: PetscFunctionBegin;
264: hot->handler = h;
265: hot->eventBegin = h->ops->eventbegin;
266: hot->eventEnd = h->ops->eventend;
267: hot->eventSync = h->ops->eventsync;
268: hot->objectCreate = h->ops->objectcreate;
269: hot->objectDestroy = h->ops->objectdestroy;
270: PetscFunctionReturn(PETSC_SUCCESS);
271: }
273: /*@
274: PetscLogHandlerStart - Connect a log handler to PETSc's global logging stream and state.
276: Logically collective
278: Input Parameters:
279: . h - a `PetscLogHandler`
281: Level: developer
283: Notes:
284: Users should only need this if they create their own log handlers: handlers that are started
285: from the command line (such as `-log_view` and `-log_trace`) or from a function like
286: `PetscLogNestedBegin()` will automatically be started.
288: There is a limit of `PESC_LOG_HANDLER_MAX` handlers that can be active at one time.
290: To disconnect a handler from the global stream call `PetscLogHandlerStop()`.
292: When a log handler is started, stages that have already been pushed with `PetscLogStagePush()`,
293: will be pushed for the new log handler, but it will not be informed of any events that are
294: in progress. It is recommended to start any user-defined log handlers immediately following
295: `PetscInitialize()` before any user-defined stages are pushed.
297: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogHandlerStop()`, `PetscInitialize()`
298: @*/
299: PetscErrorCode PetscLogHandlerStart(PetscLogHandler h)
300: {
301: PetscFunctionBegin;
302: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
303: if (PetscLogHandlers[i].handler == h) PetscFunctionReturn(PETSC_SUCCESS);
304: }
305: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
306: if (PetscLogHandlers[i].handler == NULL) {
307: PetscCall(PetscObjectReference((PetscObject)h));
308: PetscCall(PetscLogHandlerCopyToHot(h, &PetscLogHandlers[i]));
309: if (petsc_log_state) {
310: PetscLogStage stack_height;
311: PetscIntStack orig_stack, temp_stack;
313: PetscCall(PetscLogHandlerSetState(h, petsc_log_state));
314: stack_height = petsc_log_state->stage_stack->top + 1;
315: PetscCall(PetscIntStackCreate(&temp_stack));
316: orig_stack = petsc_log_state->stage_stack;
317: petsc_log_state->stage_stack = temp_stack;
318: petsc_log_state->current_stage = -1;
319: for (int s = 0; s < stack_height; s++) {
320: PetscLogStage stage = orig_stack->stack[s];
321: PetscCall(PetscLogHandlerStagePush(h, stage));
322: PetscCall(PetscIntStackPush(temp_stack, stage));
323: petsc_log_state->current_stage = stage;
324: }
325: PetscCall(PetscIntStackDestroy(temp_stack));
326: petsc_log_state->stage_stack = orig_stack;
327: }
328: PetscFunctionReturn(PETSC_SUCCESS);
329: }
330: }
331: SETERRQ(PetscObjectComm((PetscObject)h), PETSC_ERR_ARG_WRONGSTATE, "%d log handlers already started, cannot start another", PETSC_LOG_HANDLER_MAX);
332: PetscFunctionReturn(PETSC_SUCCESS);
333: }
335: /*@
336: PetscLogHandlerStop - Disconnect a log handler from PETSc's global logging stream.
338: Logically collective
340: Input Parameters:
341: . h - a `PetscLogHandler`
343: Level: developer
345: Note:
346: After `PetscLogHandlerStop()`, the handler can still access the global logging state
347: with `PetscLogHandlerGetState()`, so that it can access the registry when post-processing
348: (for instance, in `PetscLogHandlerView()`),
350: When a log handler is stopped, the remaining stages will be popped before it is
351: disconnected from the log stream.
353: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogHandlerStart()`
354: @*/
355: PetscErrorCode PetscLogHandlerStop(PetscLogHandler h)
356: {
357: PetscFunctionBegin;
358: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
359: if (PetscLogHandlers[i].handler == h) {
360: if (petsc_log_state) {
361: PetscLogState state;
362: PetscLogStage stack_height;
363: PetscIntStack orig_stack, temp_stack;
365: PetscCall(PetscLogHandlerGetState(h, &state));
366: PetscCheck(state == petsc_log_state, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "Called PetscLogHandlerStop() for a PetscLogHander that was not started.");
367: stack_height = petsc_log_state->stage_stack->top + 1;
368: PetscCall(PetscIntStackCreate(&temp_stack));
369: orig_stack = petsc_log_state->stage_stack;
370: petsc_log_state->stage_stack = temp_stack;
371: for (int s = 0; s < stack_height; s++) {
372: PetscLogStage stage = orig_stack->stack[s];
374: PetscCall(PetscIntStackPush(temp_stack, stage));
375: }
376: for (int s = 0; s < stack_height; s++) {
377: PetscLogStage stage;
378: PetscBool empty;
380: PetscCall(PetscIntStackPop(temp_stack, &stage));
381: PetscCall(PetscIntStackEmpty(temp_stack, &empty));
382: if (!empty) PetscCall(PetscIntStackTop(temp_stack, &petsc_log_state->current_stage));
383: else petsc_log_state->current_stage = -1;
384: PetscCall(PetscLogHandlerStagePop(h, stage));
385: }
386: PetscCall(PetscIntStackDestroy(temp_stack));
387: petsc_log_state->stage_stack = orig_stack;
388: PetscCall(PetscIntStackTop(petsc_log_state->stage_stack, &petsc_log_state->current_stage));
389: }
390: PetscCall(PetscArrayzero(&PetscLogHandlers[i], 1));
391: PetscCall(PetscObjectDereference((PetscObject)h));
392: }
393: }
394: PetscFunctionReturn(PETSC_SUCCESS);
395: }
397: /*@
398: PetscLogIsActive - Check if logging (profiling) is currently in progress.
400: Not Collective
402: Output Parameter:
403: . isActive - `PETSC_TRUE` if logging is in progress, `PETSC_FALSE` otherwise
405: Level: beginner
407: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`
408: @*/
409: PetscErrorCode PetscLogIsActive(PetscBool *isActive)
410: {
411: PetscFunctionBegin;
412: *isActive = PETSC_FALSE;
413: if (petsc_log_state) {
414: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
415: if (PetscLogHandlers[i].handler) {
416: *isActive = PETSC_TRUE;
417: PetscFunctionReturn(PETSC_SUCCESS);
418: }
419: }
420: }
421: PetscFunctionReturn(PETSC_SUCCESS);
422: }
424: PETSC_UNUSED static PetscErrorCode PetscLogEventBeginIsActive(PetscBool *isActive)
425: {
426: PetscFunctionBegin;
427: *isActive = PETSC_FALSE;
428: if (petsc_log_state) {
429: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
430: if (PetscLogHandlers[i].eventBegin) {
431: *isActive = PETSC_TRUE;
432: PetscFunctionReturn(PETSC_SUCCESS);
433: }
434: }
435: }
436: PetscFunctionReturn(PETSC_SUCCESS);
437: }
439: PETSC_UNUSED static PetscErrorCode PetscLogEventEndIsActive(PetscBool *isActive)
440: {
441: PetscFunctionBegin;
442: *isActive = PETSC_FALSE;
443: if (petsc_log_state) {
444: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
445: if (PetscLogHandlers[i].eventEnd) {
446: *isActive = PETSC_TRUE;
447: PetscFunctionReturn(PETSC_SUCCESS);
448: }
449: }
450: }
451: PetscFunctionReturn(PETSC_SUCCESS);
452: }
454: PETSC_INTERN PetscErrorCode PetscLogTypeBegin(PetscLogHandlerType type)
455: {
456: PetscLogHandler handler;
458: PetscFunctionBegin;
459: PetscCall(PetscLogTryGetHandler(type, &handler));
460: if (handler) PetscFunctionReturn(PETSC_SUCCESS);
461: PetscCall(PetscLogHandlerCreate(PETSC_COMM_WORLD, &handler));
462: PetscCall(PetscLogHandlerSetType(handler, type));
463: PetscCall(PetscLogHandlerStart(handler));
464: PetscCall(PetscLogHandlerDestroy(&handler));
465: PetscFunctionReturn(PETSC_SUCCESS);
466: }
468: /*@
469: PetscLogDefaultBegin - Turns on logging (profiling) of PETSc code using the default log handler (profiler). This logs time, flop
470: rates, and object creation and should not slow programs down too much.
472: Logically Collective on `PETSC_COMM_WORLD`
474: Options Database Key:
475: . -log_view viewer_specification - Displays summary of flop and timing (profiling) information (for PETSc configured `--with-log`, which is the default).
476: This option must be provided before `PetscInitialize()`. See `PetscOptionsCreateViewer()` for the
477: format of `viewer_specification`
479: Example Usage:
480: .vb
481: PetscInitialize(...);
482: PetscLogDefaultBegin();
483: ... code ...
484: PetscLogView(viewer); or PetscLogDump();
485: PetscFinalize();
486: .ve
488: Level: advanced
490: Notes:
491: `PetscLogView()` or `PetscLogDump()` actually cause the printing of
492: the logging information.
494: This routine may be called more than once.
496: To provide the `-log_view` option in your source code you must call PetscCall(PetscOptionsSetValue(NULL, "-log_view", NULL));
497: before you call `PetscInitialize()`
499: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`
500: @*/
501: PetscErrorCode PetscLogDefaultBegin(void)
502: {
503: PetscFunctionBegin;
504: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERDEFAULT));
505: PetscFunctionReturn(PETSC_SUCCESS);
506: }
508: /*@
509: PetscLogTraceBegin - Begins trace logging. Every time a PETSc event
510: begins or ends, the event name is printed.
512: Logically Collective on `PETSC_COMM_WORLD`, No Fortran Support
514: Input Parameter:
515: . file - The file to print trace in (e.g. stdout)
517: Options Database Key:
518: . -log_trace [filename] - Begins `PetscLogTraceBegin()`
520: Level: intermediate
522: Notes:
523: `PetscLogTraceBegin()` prints the processor number, the execution time (sec),
524: then "Event begin:" or "Event end:" followed by the event name.
526: `PetscLogTraceBegin()` allows tracing of all PETSc calls, which is useful
527: to determine where a program is hanging without running in the
528: debugger. Can be used in conjunction with the -info option.
530: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogView()`, `PetscLogDefaultBegin()`
531: @*/
532: PetscErrorCode PetscLogTraceBegin(FILE *file)
533: {
534: PetscLogHandler handler;
536: PetscFunctionBegin;
537: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERTRACE, &handler));
538: if (handler) PetscFunctionReturn(PETSC_SUCCESS);
539: PetscCall(PetscLogHandlerCreateTrace(PETSC_COMM_WORLD, file, &handler));
540: PetscCall(PetscLogHandlerStart(handler));
541: PetscCall(PetscLogHandlerDestroy(&handler));
542: PetscFunctionReturn(PETSC_SUCCESS);
543: }
545: PETSC_INTERN PetscErrorCode PetscLogHandlerCreate_Nested(MPI_Comm, PetscLogHandler *);
547: /*@
548: PetscLogNestedBegin - Turns on nested logging of objects and events. This logs flop
549: rates and object creation and should not slow programs down much.
551: Logically Collective on `PETSC_COMM_WORLD`, No Fortran Support
553: Options Database Key:
554: . -log_view :filename.xml:ascii_xml - Prints an XML summary of flop and timing information to the file `filename.xml`.
555: See `PetscOptionsCreateViewer()` for other possible viewer specifications
557: Example Usage:
558: .vb
559: PetscInitialize(...);
560: PetscLogNestedBegin();
561: ... code ...
562: PetscLogView(viewer);
563: PetscFinalize();
564: .ve
566: Level: advanced
568: .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`
569: @*/
570: PetscErrorCode PetscLogNestedBegin(void)
571: {
572: PetscFunctionBegin;
573: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERNESTED));
574: PetscFunctionReturn(PETSC_SUCCESS);
575: }
577: /*@
578: PetscLogLegacyCallbacksBegin - Create and start a log handler from callbacks
579: matching the now deprecated function pointers `PetscLogPLB`, `PetscLogPLE`,
580: `PetscLogPHC`, `PetscLogPHD`.
582: Logically Collective on `PETSC_COMM_WORLD`
584: Input Parameters:
585: + PetscLogPLB - A callback that will be executed by `PetscLogEventBegin()` (or `NULL`)
586: . PetscLogPLE - A callback that will be executed by `PetscLogEventEnd()` (or `NULL`)
587: . PetscLogPHC - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`)
588: - PetscLogPHD - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`)
590: Calling sequence of `PetscLogPLB`:
591: + e - a `PetscLogEvent` that is beginning
592: . _i - deprecated, unused
593: . o1 - a `PetscObject` associated with `e` (or `NULL`)
594: . o2 - a `PetscObject` associated with `e` (or `NULL`)
595: . o3 - a `PetscObject` associated with `e` (or `NULL`)
596: - o4 - a `PetscObject` associated with `e` (or `NULL`)
598: Calling sequence of `PetscLogPLE`:
599: + e - a `PetscLogEvent` that is beginning
600: . _i - deprecated, unused
601: . o1 - a `PetscObject` associated with `e` (or `NULL`)
602: . o2 - a `PetscObject` associated with `e` (or `NULL`)
603: . o3 - a `PetscObject` associated with `e` (or `NULL`)
604: - o4 - a `PetscObject` associated with `e` (or `NULL`)
606: Calling sequence of `PetscLogPHC`:
607: . o - a `PetscObject` that has just been created
609: Calling sequence of `PetscLogPHD`:
610: . o - a `PetscObject` that is about to be destroyed
612: Level: advanced
614: Notes:
615: This is for transitioning from the deprecated function `PetscLogSet()` and should not be used in new code.
617: This should help migrate external log handlers to use `PetscLogHandler`, but
618: callbacks that depend on the deprecated `PetscLogStage` datatype will have to be
619: updated.
621: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerStart()`, `PetscLogState`
622: @*/
623: 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))
624: {
625: PetscLogHandler handler;
627: PetscFunctionBegin;
628: PetscCall(PetscLogHandlerCreateLegacy(PETSC_COMM_WORLD, PetscLogPLB, PetscLogPLE, PetscLogPHC, PetscLogPHD, &handler));
629: PetscCall(PetscLogHandlerStart(handler));
630: PetscCall(PetscLogHandlerDestroy(&handler));
631: PetscFunctionReturn(PETSC_SUCCESS);
632: }
634: #if PetscDefined(HAVE_MPE)
635: #include <mpe.h>
636: static PetscBool PetscBeganMPE = PETSC_FALSE;
637: #endif
639: /*@
640: PetscLogMPEBegin - Turns on MPE logging of events. This creates large log files and slows the
641: program down.
643: Collective on `PETSC_COMM_WORLD`, No Fortran Support
645: Options Database Key:
646: . -log_mpe - Prints extensive log information
648: Level: advanced
650: Note:
651: A related routine is `PetscLogDefaultBegin()` (with the options key `-log_view`), which is
652: intended for production runs since it logs only flop rates and object creation (and should
653: not significantly slow the programs).
655: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogDefaultBegin()`, `PetscLogEventActivate()`,
656: `PetscLogEventDeactivate()`
657: @*/
658: PetscErrorCode PetscLogMPEBegin(void)
659: {
660: PetscFunctionBegin;
661: #if PetscDefined(HAVE_MPE)
662: /* Do MPE initialization */
663: if (!MPE_Initialized_logging()) { /* This function exists in mpich 1.1.2 and higher */
664: PetscCall(PetscInfo(0, "Initializing MPE.\n"));
665: PetscCall(MPE_Init_log());
667: PetscBeganMPE = PETSC_TRUE;
668: } else {
669: PetscCall(PetscInfo(0, "MPE already initialized. Not attempting to reinitialize.\n"));
670: }
671: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERMPE));
672: #else
673: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe");
674: #endif
675: PetscFunctionReturn(PETSC_SUCCESS);
676: }
678: #if PetscDefined(HAVE_TAU_PERFSTUBS)
679: #include <../src/sys/perfstubs/timer.h>
680: #endif
682: /*@
683: PetscLogPerfstubsBegin - Turns on logging of events using the perfstubs interface.
685: Collective on `PETSC_COMM_WORLD`, No Fortran Support
687: Options Database Key:
688: . -log_perfstubs - use an external log handler through the perfstubs interface
690: Level: advanced
692: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogEventActivate()`
693: @*/
694: PetscErrorCode PetscLogPerfstubsBegin(void)
695: {
696: PetscFunctionBegin;
697: #if PetscDefined(HAVE_TAU_PERFSTUBS)
698: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERPERFSTUBS));
699: #else
700: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without perfstubs support, reconfigure with --with-tau-perfstubs");
701: #endif
702: PetscFunctionReturn(PETSC_SUCCESS);
703: }
705: /*@
706: PetscLogActions - Determines whether actions are logged for the default log handler.
708: Not Collective
710: Input Parameter:
711: . flag - `PETSC_TRUE` if actions are to be logged
713: Options Database Key:
714: + -log_exclude_actions - (deprecated) Does nothing
715: - -log_include_actions - Turn on action logging
717: Level: intermediate
719: Note:
720: Logging of actions continues to consume more memory as the program
721: runs. Long running programs should consider turning this feature off.
723: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogGetDefaultHandler()`
724: @*/
725: PetscErrorCode PetscLogActions(PetscBool flag)
726: {
727: PetscFunctionBegin;
728: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
729: PetscLogHandler h = PetscLogHandlers[i].handler;
731: if (h) PetscCall(PetscLogHandlerSetLogActions(h, flag));
732: }
733: PetscFunctionReturn(PETSC_SUCCESS);
734: }
736: /*@
737: PetscLogObjects - Determines whether objects are logged for the graphical viewer.
739: Not Collective
741: Input Parameter:
742: . flag - `PETSC_TRUE` if objects are to be logged
744: Options Database Key:
745: + -log_exclude_objects - (deprecated) Does nothing
746: - -log_include_objects - Turns on object logging
748: Level: intermediate
750: Note:
751: Logging of objects continues to consume more memory as the program
752: runs. Long running programs should consider turning this feature off.
754: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogGetDefaultHandler()`
755: @*/
756: PetscErrorCode PetscLogObjects(PetscBool flag)
757: {
758: PetscFunctionBegin;
759: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
760: PetscLogHandler h = PetscLogHandlers[i].handler;
762: if (h) PetscCall(PetscLogHandlerSetLogObjects(h, flag));
763: }
764: PetscFunctionReturn(PETSC_SUCCESS);
765: }
767: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
768: /*@
769: PetscLogStageRegister - Attaches a character string name to a logging stage.
771: Not Collective
773: Input Parameter:
774: . sname - The name to associate with that stage
776: Output Parameter:
777: . stage - The stage number or -1 if logging is not active (`PetscLogIsActive()`).
779: Level: intermediate
781: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`
782: @*/
783: PetscErrorCode PetscLogStageRegister(const char sname[], PetscLogStage *stage)
784: {
785: PetscLogState state;
787: PetscFunctionBegin;
788: *stage = -1;
789: PetscCall(PetscLogGetState(&state));
790: if (state) PetscCall(PetscLogStateStageRegister(state, sname, stage));
791: PetscFunctionReturn(PETSC_SUCCESS);
792: }
794: /*@
795: PetscLogStagePush - This function pushes a stage on the logging stack. Events started and stopped until `PetscLogStagePop()` will be associated with the stage
797: Not Collective
799: Input Parameter:
800: . stage - The stage on which to log
802: Example Usage:
803: If the option `-log_view` is used to run the program containing the
804: following code, then 2 sets of summary data will be printed during
805: PetscFinalize().
806: .vb
807: PetscInitialize(int *argc,char ***args,0,0);
808: [stage 0 of code]
809: PetscLogStagePush(1);
810: [stage 1 of code]
811: PetscLogStagePop();
812: PetscBarrier(...);
813: [more stage 0 of code]
814: PetscFinalize();
815: .ve
817: Level: intermediate
819: Note:
820: Use `PetscLogStageRegister()` to register a stage.
822: .seealso: [](ch_profiling), `PetscLogStagePop()`, `PetscLogStageRegister()`, `PetscBarrier()`
823: @*/
824: PetscErrorCode PetscLogStagePush(PetscLogStage stage)
825: {
826: PetscLogState state;
828: PetscFunctionBegin;
829: PetscCall(PetscLogGetState(&state));
830: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
831: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
832: PetscLogHandler h = PetscLogHandlers[i].handler;
833: if (h) PetscCall(PetscLogHandlerStagePush(h, stage));
834: }
835: PetscCall(PetscLogStateStagePush(state, stage));
836: PetscFunctionReturn(PETSC_SUCCESS);
837: }
839: /*@
840: PetscLogStagePop - This function pops a stage from the logging stack that was pushed with `PetscLogStagePush()`
842: Not Collective
844: Example Usage:
845: If the option `-log_view` is used to run the program containing the
846: following code, then 2 sets of summary data will be printed during
847: PetscFinalize().
848: .vb
849: PetscInitialize(int *argc,char ***args,0,0);
850: [stage 0 of code]
851: PetscLogStagePush(1);
852: [stage 1 of code]
853: PetscLogStagePop();
854: PetscBarrier(...);
855: [more stage 0 of code]
856: PetscFinalize();
857: .ve
859: Level: intermediate
861: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStageRegister()`, `PetscBarrier()`
862: @*/
863: PetscErrorCode PetscLogStagePop(void)
864: {
865: PetscLogState state;
866: PetscLogStage current_stage;
868: PetscFunctionBegin;
869: PetscCall(PetscLogGetState(&state));
870: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
871: current_stage = state->current_stage;
872: PetscCall(PetscLogStateStagePop(state));
873: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
874: PetscLogHandler h = PetscLogHandlers[i].handler;
875: if (h) PetscCall(PetscLogHandlerStagePop(h, current_stage));
876: }
877: PetscFunctionReturn(PETSC_SUCCESS);
878: }
880: /*@
881: PetscLogStageSetActive - Sets if a stage is used for `PetscLogEventBegin()` and `PetscLogEventEnd()`.
883: Not Collective
885: Input Parameters:
886: + stage - The stage
887: - isActive - The activity flag, `PETSC_TRUE` for logging, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
889: Level: intermediate
891: Note:
892: If this is set to `PETSC_FALSE` the logging acts as if the stage did not exist
894: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
895: @*/
896: PetscErrorCode PetscLogStageSetActive(PetscLogStage stage, PetscBool isActive)
897: {
898: PetscLogState state;
900: PetscFunctionBegin;
901: PetscCall(PetscLogGetState(&state));
902: if (state) PetscCall(PetscLogStateStageSetActive(state, stage, isActive));
903: PetscFunctionReturn(PETSC_SUCCESS);
904: }
906: /*@
907: PetscLogStageGetActive - Checks if a stage is used for `PetscLogEventBegin()` and `PetscLogEventEnd()`.
909: Not Collective
911: Input Parameter:
912: . stage - The stage
914: Output Parameter:
915: . isActive - The activity flag, `PETSC_TRUE` for logging, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
917: Level: intermediate
919: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
920: @*/
921: PetscErrorCode PetscLogStageGetActive(PetscLogStage stage, PetscBool *isActive)
922: {
923: PetscLogState state;
925: PetscFunctionBegin;
926: *isActive = PETSC_FALSE;
927: PetscCall(PetscLogGetState(&state));
928: if (state) PetscCall(PetscLogStateStageGetActive(state, stage, isActive));
929: PetscFunctionReturn(PETSC_SUCCESS);
930: }
932: /*@
933: PetscLogStageSetVisible - Determines stage visibility in `PetscLogView()`
935: Not Collective
937: Input Parameters:
938: + stage - The stage
939: - isVisible - The visibility flag, `PETSC_TRUE` to print, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
941: Level: intermediate
943: Developer Notes:
944: Visibility only affects the default log handler in `PetscLogView()`; stages that are
945: set to invisible are suppressed from output.
947: .seealso: [](ch_profiling), `PetscLogStageGetVisible()`, `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
948: @*/
949: PetscErrorCode PetscLogStageSetVisible(PetscLogStage stage, PetscBool isVisible)
950: {
951: PetscFunctionBegin;
952: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
953: PetscLogHandler h = PetscLogHandlers[i].handler;
955: if (h) PetscCall(PetscLogHandlerStageSetVisible(h, stage, isVisible));
956: }
957: PetscFunctionReturn(PETSC_SUCCESS);
958: }
960: /*@
961: PetscLogStageGetVisible - Returns stage visibility in `PetscLogView()`
963: Not Collective
965: Input Parameter:
966: . stage - The stage
968: Output Parameter:
969: . isVisible - The visibility flag, `PETSC_TRUE` to print, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
971: Level: intermediate
973: .seealso: [](ch_profiling), `PetscLogStageSetVisible()`, `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
974: @*/
975: PetscErrorCode PetscLogStageGetVisible(PetscLogStage stage, PetscBool *isVisible)
976: {
977: PetscLogHandler handler;
979: PetscFunctionBegin;
980: *isVisible = PETSC_FALSE;
981: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
982: if (handler) PetscCall(PetscLogHandlerStageGetVisible(handler, stage, isVisible));
983: PetscFunctionReturn(PETSC_SUCCESS);
984: }
986: /*@
987: PetscLogStageGetId - Returns the stage id when given the stage name.
989: Not Collective
991: Input Parameter:
992: . name - The stage name
994: Output Parameter:
995: . stage - The stage, , or -1 if no stage with that name exists
997: Level: intermediate
999: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
1000: @*/
1001: PetscErrorCode PetscLogStageGetId(const char name[], PetscLogStage *stage)
1002: {
1003: PetscLogState state;
1005: PetscFunctionBegin;
1006: *stage = -1;
1007: PetscCall(PetscLogGetState(&state));
1008: if (state) PetscCall(PetscLogStateGetStageFromName(state, name, stage));
1009: PetscFunctionReturn(PETSC_SUCCESS);
1010: }
1012: /*@
1013: PetscLogStageGetName - Returns the stage name when given the stage id.
1015: Not Collective
1017: Input Parameter:
1018: . stage - The stage
1020: Output Parameter:
1021: . name - The stage name
1023: Level: intermediate
1025: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
1026: @*/
1027: PetscErrorCode PetscLogStageGetName(PetscLogStage stage, const char *name[])
1028: {
1029: PetscLogStageInfo stage_info;
1030: PetscLogState state;
1032: PetscFunctionBegin;
1033: *name = NULL;
1034: PetscCall(PetscLogGetState(&state));
1035: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1036: PetscCall(PetscLogStateStageGetInfo(state, stage, &stage_info));
1037: *name = stage_info.name;
1038: PetscFunctionReturn(PETSC_SUCCESS);
1039: }
1041: /*------------------------------------------------ Event Functions --------------------------------------------------*/
1043: /*@
1044: PetscLogEventRegister - Registers an event name for logging operations
1046: Not Collective
1048: Input Parameters:
1049: + name - The name associated with the event
1050: - classid - The classid associated to the class for this event, obtain either with
1051: `PetscClassIdRegister()` or use a predefined one such as `KSP_CLASSID`, `SNES_CLASSID`, the predefined ones
1052: are only available in C code
1054: Output Parameter:
1055: . event - The event id for use with `PetscLogEventBegin()` and `PetscLogEventEnd()`.
1057: Example Usage:
1058: .vb
1059: PetscLogEvent USER_EVENT;
1060: PetscClassId classid;
1061: PetscLogDouble user_event_flops;
1062: PetscClassIdRegister("class name",&classid);
1063: PetscLogEventRegister("User event name",classid,&USER_EVENT);
1064: PetscLogEventBegin(USER_EVENT,0,0,0,0);
1065: [code segment to monitor]
1066: PetscLogFlops(user_event_flops);
1067: PetscLogEventEnd(USER_EVENT,0,0,0,0);
1068: .ve
1070: Level: intermediate
1072: Notes:
1073: PETSc automatically logs library events if the code has been
1074: configured with `--with-log` (which is the default) and
1075: `-log_view` or `-log_all` is specified. `PetscLogEventRegister()` is
1076: intended for logging user events to supplement this PETSc
1077: information.
1079: PETSc can gather data for use with the utilities Jumpshot
1080: (part of the MPICH distribution). If PETSc has been compiled
1081: with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
1082: MPICH), the user can employ another command line option, `-log_mpe`,
1083: to create a logfile, "mpe.log", which can be visualized
1084: Jumpshot.
1086: The `classid` is associated with each event so that classes of events
1087: can be disabled simultaneously, such as all matrix events. The user
1088: can either use an existing `classid`, such as `MAT_CLASSID`, or create
1089: their own as shown in the example.
1091: If an existing event with the same name exists, its event handle is
1092: returned instead of creating a new event.
1094: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogFlops()`,
1095: `PetscLogEventActivate()`, `PetscLogEventDeactivate()`, `PetscClassIdRegister()`
1096: @*/
1097: PetscErrorCode PetscLogEventRegister(const char name[], PetscClassId classid, PetscLogEvent *event)
1098: {
1099: PetscLogState state;
1101: PetscFunctionBegin;
1102: *event = -1;
1103: PetscCall(PetscLogGetState(&state));
1104: if (state) PetscCall(PetscLogStateEventRegister(state, name, classid, event));
1105: PetscFunctionReturn(PETSC_SUCCESS);
1106: }
1108: /*@
1109: PetscLogEventSetCollective - Indicates that a particular event is collective.
1111: Logically Collective
1113: Input Parameters:
1114: + event - The event id
1115: - collective - `PetscBool` indicating whether a particular event is collective
1117: Level: developer
1119: Notes:
1120: New events returned from `PetscLogEventRegister()` are collective by default.
1122: Collective events are handled specially if the command line option `-log_sync` is used. In that case the logging saves information about
1123: two parts of the event; the time for all the MPI ranks to synchronize and then the time for the actual computation/communication
1124: to be performed. This option is useful to debug imbalance within the computations or communications.
1126: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventRegister()`
1127: @*/
1128: PetscErrorCode PetscLogEventSetCollective(PetscLogEvent event, PetscBool collective)
1129: {
1130: PetscLogState state;
1132: PetscFunctionBegin;
1133: PetscCall(PetscLogGetState(&state));
1134: if (state) PetscCall(PetscLogStateEventSetCollective(state, event, collective));
1135: PetscFunctionReturn(PETSC_SUCCESS);
1136: }
1138: /*
1139: PetscLogClassSetActiveAll - Activate or inactivate logging for all events associated with a PETSc object class in every stage.
1141: Not Collective
1143: Input Parameters:
1144: + classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1145: - isActive - if `PETSC_FALSE`, events associated with this class will not be send to log handlers.
1147: Level: developer
1149: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventActivateAll()`, `PetscLogStageSetActive()`, `PetscLogEventActivateClass()`
1150: */
1151: static PetscErrorCode PetscLogClassSetActiveAll(PetscClassId classid, PetscBool isActive)
1152: {
1153: PetscLogState state;
1155: PetscFunctionBegin;
1156: PetscCall(PetscLogGetState(&state));
1157: if (state) PetscCall(PetscLogStateClassSetActiveAll(state, classid, isActive));
1158: PetscFunctionReturn(PETSC_SUCCESS);
1159: }
1161: /*@
1162: PetscLogEventIncludeClass - Activates event logging for a PETSc object class in every stage.
1164: Not Collective
1166: Input Parameter:
1167: . classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1169: Level: developer
1171: .seealso: [](ch_profiling), `PetscLogEventActivateClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1172: @*/
1173: PetscErrorCode PetscLogEventIncludeClass(PetscClassId classid)
1174: {
1175: PetscFunctionBegin;
1176: PetscCall(PetscLogClassSetActiveAll(classid, PETSC_TRUE));
1177: PetscFunctionReturn(PETSC_SUCCESS);
1178: }
1180: /*@
1181: PetscLogEventExcludeClass - Deactivates event logging for a PETSc object class in every stage.
1183: Not Collective
1185: Input Parameter:
1186: . classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1188: Level: developer
1190: Note:
1191: If a class is excluded then events associated with that class are not logged.
1193: .seealso: [](ch_profiling), `PetscLogEventDeactivateClass()`, `PetscLogEventActivateClass()`, `PetscLogEventDeactivate()`, `PetscLogEventActivate()`
1194: @*/
1195: PetscErrorCode PetscLogEventExcludeClass(PetscClassId classid)
1196: {
1197: PetscFunctionBegin;
1198: PetscCall(PetscLogClassSetActiveAll(classid, PETSC_FALSE));
1199: PetscFunctionReturn(PETSC_SUCCESS);
1200: }
1202: /*
1203: PetscLogEventSetActive - Activate or inactivate logging for an event in a given stage
1205: Not Collective
1207: Input Parameters:
1208: + stage - A registered `PetscLogStage` (or `PETSC_DEFAULT` for the current stage)
1209: . event - A `PetscLogEvent`
1210: - isActive - If `PETSC_FALSE`, activity from this event (`PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventSync()`) will not be sent to log handlers during this stage
1212: Usage:
1213: .vb
1214: PetscLogEventSetActive(VEC_SetValues, PETSC_FALSE);
1215: [code where you do not want to log VecSetValues()]
1216: PetscLogEventSetActive(VEC_SetValues, PETSC_TRUE);
1217: [code where you do want to log VecSetValues()]
1218: .ve
1220: Level: advanced
1222: Note:
1223: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
1224: or an event number obtained with `PetscLogEventRegister()`.
1226: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1227: */
1228: static PetscErrorCode PetscLogEventSetActive(PetscLogStage stage, PetscLogEvent event, PetscBool isActive)
1229: {
1230: PetscLogState state;
1232: PetscFunctionBegin;
1233: PetscCall(PetscLogGetState(&state));
1234: if (state) PetscCall(PetscLogStateEventSetActive(state, stage, event, isActive));
1235: PetscFunctionReturn(PETSC_SUCCESS);
1236: }
1238: /*@
1239: PetscLogEventActivate - Indicates that a particular event should be logged.
1241: Not Collective
1243: Input Parameter:
1244: . event - The event id
1246: Example Usage:
1247: .vb
1248: PetscLogEventDeactivate(VEC_SetValues);
1249: [code where you do not want to log VecSetValues()]
1250: PetscLogEventActivate(VEC_SetValues);
1251: [code where you do want to log VecSetValues()]
1252: .ve
1254: Level: advanced
1256: Note:
1257: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
1258: or an event number obtained with `PetscLogEventRegister()`.
1260: .seealso: [](ch_profiling), `PetscLogEventDeactivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1261: @*/
1262: PetscErrorCode PetscLogEventActivate(PetscLogEvent event)
1263: {
1264: PetscFunctionBegin;
1265: PetscCall(PetscLogEventSetActive(PETSC_DEFAULT, event, PETSC_TRUE));
1266: PetscFunctionReturn(PETSC_SUCCESS);
1267: }
1269: /*@
1270: PetscLogEventDeactivate - Indicates that a particular event should not be logged.
1272: Not Collective
1274: Input Parameter:
1275: . event - The event id
1277: Example Usage:
1278: .vb
1279: PetscLogEventDeactivate(VEC_SetValues);
1280: [code where you do not want to log VecSetValues()]
1281: PetscLogEventActivate(VEC_SetValues);
1282: [code where you do want to log VecSetValues()]
1283: .ve
1285: Level: advanced
1287: Note:
1288: The event may be either a pre-defined PETSc event (found in
1289: include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1291: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1292: @*/
1293: PetscErrorCode PetscLogEventDeactivate(PetscLogEvent event)
1294: {
1295: PetscFunctionBegin;
1296: PetscCall(PetscLogEventSetActive(PETSC_DEFAULT, event, PETSC_FALSE));
1297: PetscFunctionReturn(PETSC_SUCCESS);
1298: }
1300: /*@
1301: PetscLogEventDeactivatePush - Indicates that a particular event should not be logged until `PetscLogEventDeactivatePop()` is called
1303: Not Collective
1305: Input Parameter:
1306: . event - The event id
1308: Example Usage:
1309: .vb
1310: PetscLogEventDeactivatePush(VEC_SetValues);
1311: [code where you do not want to log VecSetValues()]
1312: PetscLogEventDeactivatePop(VEC_SetValues);
1313: [code where you do want to log VecSetValues()]
1314: .ve
1316: Level: advanced
1318: Note:
1319: The event may be either a pre-defined PETSc event (found in
1320: include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1322: 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.
1324: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivate()`, `PetscLogEventDeactivatePop()`
1325: @*/
1326: PetscErrorCode PetscLogEventDeactivatePush(PetscLogEvent event)
1327: {
1328: PetscFunctionBegin;
1329: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1330: PetscLogHandler h = PetscLogHandlers[i].handler;
1332: if (h) PetscCall(PetscLogHandlerEventDeactivatePush(h, PETSC_DEFAULT, event));
1333: }
1334: PetscFunctionReturn(PETSC_SUCCESS);
1335: }
1337: /*@
1338: PetscLogEventDeactivatePop - Indicates that a particular event should again be logged after the logging was turned off with `PetscLogEventDeactivatePush()`
1340: Not Collective
1342: Input Parameter:
1343: . event - The event id
1345: Example Usage:
1346: .vb
1347: PetscLogEventDeactivatePush(VEC_SetValues);
1348: [code where you do not want to log VecSetValues()]
1349: PetscLogEventDeactivatePop(VEC_SetValues);
1350: [code where you do want to log VecSetValues()]
1351: .ve
1353: Level: advanced
1355: Note:
1356: The event may be either a pre-defined PETSc event (found in
1357: include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1359: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`
1360: @*/
1361: PetscErrorCode PetscLogEventDeactivatePop(PetscLogEvent event)
1362: {
1363: PetscFunctionBegin;
1364: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1365: PetscLogHandler h = PetscLogHandlers[i].handler;
1367: if (h) PetscCall(PetscLogHandlerEventDeactivatePop(h, PETSC_DEFAULT, event));
1368: }
1369: PetscFunctionReturn(PETSC_SUCCESS);
1370: }
1372: /*@
1373: PetscLogEventSetActiveAll - Turns on logging of all events
1375: Not Collective
1377: Input Parameters:
1378: + event - The event id
1379: - isActive - The activity flag determining whether the event is logged
1381: Level: advanced
1383: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1384: @*/
1385: PetscErrorCode PetscLogEventSetActiveAll(PetscLogEvent event, PetscBool isActive)
1386: {
1387: PetscLogState state;
1389: PetscFunctionBegin;
1390: PetscCall(PetscLogGetState(&state));
1391: if (state) PetscCall(PetscLogStateEventSetActiveAll(state, event, isActive));
1392: PetscFunctionReturn(PETSC_SUCCESS);
1393: }
1395: /*
1396: PetscLogClassSetActive - Activates event logging for a PETSc object class for the current stage
1398: Not Collective
1400: Input Parameters:
1401: + stage - A registered `PetscLogStage` (or `PETSC_DEFAULT` for the current stage)
1402: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1403: - isActive - If `PETSC_FALSE`, events associated with this class are not sent to log handlers.
1405: Level: developer
1407: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventActivate()`, `PetscLogEventActivateAll()`, `PetscLogStageSetActive()`
1408: */
1409: static PetscErrorCode PetscLogClassSetActive(PetscLogStage stage, PetscClassId classid, PetscBool isActive)
1410: {
1411: PetscLogState state;
1413: PetscFunctionBegin;
1414: PetscCall(PetscLogGetState(&state));
1415: if (state) PetscCall(PetscLogStateClassSetActive(state, stage, classid, isActive));
1416: PetscFunctionReturn(PETSC_SUCCESS);
1417: }
1419: /*@
1420: PetscLogEventActivateClass - Activates event logging for a PETSc object class for the current stage
1422: Not Collective
1424: Input Parameter:
1425: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1427: Level: developer
1429: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1430: @*/
1431: PetscErrorCode PetscLogEventActivateClass(PetscClassId classid)
1432: {
1433: PetscFunctionBegin;
1434: PetscCall(PetscLogClassSetActive(PETSC_DEFAULT, classid, PETSC_TRUE));
1435: PetscFunctionReturn(PETSC_SUCCESS);
1436: }
1438: /*@
1439: PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class for the current stage
1441: Not Collective
1443: Input Parameter:
1444: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1446: Level: developer
1448: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventActivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1449: @*/
1450: PetscErrorCode PetscLogEventDeactivateClass(PetscClassId classid)
1451: {
1452: PetscFunctionBegin;
1453: PetscCall(PetscLogClassSetActive(PETSC_DEFAULT, classid, PETSC_FALSE));
1454: PetscFunctionReturn(PETSC_SUCCESS);
1455: }
1457: /*MC
1458: PetscLogEventSync - Synchronizes the beginning of an event.
1460: Synopsis:
1461: #include <petsclog.h>
1462: PetscErrorCode PetscLogEventSync(PetscLogEvent e, MPI_Comm comm)
1464: Collective
1466: Input Parameters:
1467: + e - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1468: - comm - an MPI communicator
1470: Example Usage:
1471: .vb
1472: PetscLogEvent USER_EVENT;
1474: PetscLogEventRegister("User event", 0, &USER_EVENT);
1475: PetscLogEventSync(USER_EVENT, PETSC_COMM_WORLD);
1476: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1477: [code segment to monitor]
1478: PetscLogEventEnd(USER_EVENT, 0, 0, 0 , 0);
1479: .ve
1481: Level: developer
1483: Note:
1484: This routine should be called only if there is not a `PetscObject` available to pass to
1485: `PetscLogEventBegin()`.
1487: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`
1488: M*/
1490: /*MC
1491: PetscLogEventBegin - Logs the beginning of an event.
1493: Synopsis:
1494: #include <petsclog.h>
1495: PetscErrorCode PetscLogEventBegin(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
1497: Not Collective
1499: Input Parameters:
1500: + e - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1501: . o1 - object associated with the event, or `NULL`
1502: . o2 - object associated with the event, or `NULL`
1503: . o3 - object associated with the event, or `NULL`
1504: - o4 - object associated with the event, or `NULL`
1506: Fortran Synopsis:
1507: void PetscLogEventBegin(int e, PetscErrorCode ierr)
1509: Example Usage:
1510: .vb
1511: PetscLogEvent USER_EVENT;
1513: PetscLogDouble user_event_flops;
1514: PetscLogEventRegister("User event",0, &USER_EVENT);
1515: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1516: [code segment to monitor]
1517: PetscLogFlops(user_event_flops);
1518: PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
1519: .ve
1521: Level: intermediate
1523: Developer Note:
1524: `PetscLogEventBegin()` and `PetscLogEventBegin()` return error codes instead of explicitly
1525: handling the errors that occur in the macro directly because other packages that use this
1526: macros have used them in their own functions or methods that do not return error codes and it
1527: would be disruptive to change the current behavior.
1529: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventEnd()`, `PetscLogFlops()`
1530: M*/
1532: /*MC
1533: PetscLogEventEnd - Log the end of an event.
1535: Synopsis:
1536: #include <petsclog.h>
1537: PetscErrorCode PetscLogEventEnd(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
1539: Not Collective
1541: Input Parameters:
1542: + e - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1543: . o1 - object associated with the event, or `NULL`
1544: . o2 - object associated with the event, or `NULL`
1545: . o3 - object associated with the event, or `NULL`
1546: - o4 - object associated with the event, or `NULL`
1548: Fortran Synopsis:
1549: void PetscLogEventEnd(int e, PetscErrorCode ierr)
1551: Example Usage:
1552: .vb
1553: PetscLogEvent USER_EVENT;
1555: PetscLogDouble user_event_flops;
1556: PetscLogEventRegister("User event", 0, &USER_EVENT);
1557: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1558: [code segment to monitor]
1559: PetscLogFlops(user_event_flops);
1560: PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
1561: .ve
1563: Level: intermediate
1565: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogFlops()`
1566: M*/
1568: /*@
1569: PetscLogStageGetPerfInfo - Return the performance information about the given stage
1571: No Fortran Support
1573: Input Parameters:
1574: . stage - The stage number or `PETSC_DETERMINE` for the current stage
1576: Output Parameter:
1577: . info - This structure is filled with the performance information
1579: Level: intermediate
1581: Notes:
1582: This is a low level routine used by the logging functions in PETSc.
1584: A `PETSCLOGHANDLERDEFAULT` must be running for this to work, having been started either with
1585: `PetscLogDefaultBegin()` or from the command line with `-log_view`. If it was not started,
1586: all performance statistics in `info` will be zeroed.
1588: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1589: @*/
1590: PetscErrorCode PetscLogStageGetPerfInfo(PetscLogStage stage, PetscEventPerfInfo *info)
1591: {
1592: PetscLogHandler handler;
1593: PetscEventPerfInfo *event_info;
1595: PetscFunctionBegin;
1596: PetscAssertPointer(info, 2);
1597: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1598: if (handler) {
1599: PetscCall(PetscLogHandlerGetStagePerfInfo(handler, stage, &event_info));
1600: *info = *event_info;
1601: } else {
1602: PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogStageGetPerfInfo() returning zeros\n"));
1603: PetscCall(PetscMemzero(info, sizeof(*info)));
1604: }
1605: PetscFunctionReturn(PETSC_SUCCESS);
1606: }
1608: /*@
1609: PetscLogEventGetPerfInfo - Return the performance information about the given event in the given stage
1611: No Fortran Support
1613: Input Parameters:
1614: + stage - The stage number or `PETSC_DETERMINE` for the current stage
1615: - event - The event number
1617: Output Parameter:
1618: . info - This structure is filled with the performance information
1620: Level: intermediate
1622: Note:
1623: This is a low level routine used by the logging functions in PETSc
1625: A `PETSCLOGHANDLERDEFAULT` must be running for this to work, having been started either with
1626: `PetscLogDefaultBegin()` or from the command line with `-log_view`. If it was not started,
1627: all performance statistics in `info` will be zeroed.
1629: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1630: @*/
1631: PetscErrorCode PetscLogEventGetPerfInfo(PetscLogStage stage, PetscLogEvent event, PetscEventPerfInfo *info)
1632: {
1633: PetscLogHandler handler;
1634: PetscEventPerfInfo *event_info;
1636: PetscFunctionBegin;
1637: PetscAssertPointer(info, 3);
1638: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1639: if (handler) {
1640: PetscCall(PetscLogHandlerGetEventPerfInfo(handler, stage, event, &event_info));
1641: *info = *event_info;
1642: } else {
1643: PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogEventGetPerfInfo() returning zeros\n"));
1644: PetscCall(PetscMemzero(info, sizeof(*info)));
1645: }
1646: PetscFunctionReturn(PETSC_SUCCESS);
1647: }
1649: /*@
1650: PetscLogEventSetDof - Set the nth number of degrees of freedom of a numerical problem associated with this event
1652: Not Collective
1654: Input Parameters:
1655: + event - The event id to log
1656: . n - The dof index, in [0, 8)
1657: - dof - The number of dofs
1659: Level: developer
1661: Note:
1662: This is to enable logging of convergence
1664: .seealso: `PetscLogEventSetError()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1665: @*/
1666: PetscErrorCode PetscLogEventSetDof(PetscLogEvent event, PetscInt n, PetscLogDouble dof)
1667: {
1668: PetscFunctionBegin;
1669: PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1670: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1671: PetscLogHandler h = PetscLogHandlers[i].handler;
1673: if (h) {
1674: PetscEventPerfInfo *event_info;
1676: PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1677: if (event_info) event_info->dof[n] = dof;
1678: }
1679: }
1680: PetscFunctionReturn(PETSC_SUCCESS);
1681: }
1683: /*@
1684: PetscLogEventSetError - Set the nth error associated with a numerical problem associated with this event
1686: Not Collective
1688: Input Parameters:
1689: + event - The event id to log
1690: . n - The error index, in [0, 8)
1691: - error - The error
1693: Level: developer
1695: Notes:
1696: This is to enable logging of convergence, and enable users to interpret the errors as they wish. For example,
1697: as different norms, or as errors for different fields
1699: This is a low level routine used by the logging functions in PETSc
1701: .seealso: `PetscLogEventSetDof()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1702: @*/
1703: PetscErrorCode PetscLogEventSetError(PetscLogEvent event, PetscInt n, PetscLogDouble error)
1704: {
1705: PetscFunctionBegin;
1706: PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1707: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1708: PetscLogHandler h = PetscLogHandlers[i].handler;
1710: if (h) {
1711: PetscEventPerfInfo *event_info;
1713: PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1714: if (event_info) event_info->errors[n] = error;
1715: }
1716: }
1717: PetscFunctionReturn(PETSC_SUCCESS);
1718: }
1720: /*@
1721: PetscLogEventGetId - Returns the event id when given the event name.
1723: Not Collective
1725: Input Parameter:
1726: . name - The event name
1728: Output Parameter:
1729: . event - The event, or -1 if no event with that name exists
1731: Level: intermediate
1733: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1734: @*/
1735: PetscErrorCode PetscLogEventGetId(const char name[], PetscLogEvent *event)
1736: {
1737: PetscLogState state;
1739: PetscFunctionBegin;
1740: *event = -1;
1741: PetscCall(PetscLogGetState(&state));
1742: if (state) PetscCall(PetscLogStateGetEventFromName(state, name, event));
1743: PetscFunctionReturn(PETSC_SUCCESS);
1744: }
1746: /*@
1747: PetscLogEventGetName - Returns the event name when given the event id.
1749: Not Collective
1751: Input Parameter:
1752: . event - The event
1754: Output Parameter:
1755: . name - The event name
1757: Level: intermediate
1759: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
1760: @*/
1761: PetscErrorCode PetscLogEventGetName(PetscLogEvent event, const char *name[])
1762: {
1763: PetscLogEventInfo event_info;
1764: PetscLogState state;
1766: PetscFunctionBegin;
1767: *name = NULL;
1768: PetscCall(PetscLogGetState(&state));
1769: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1770: PetscCall(PetscLogStateEventGetInfo(state, event, &event_info));
1771: *name = event_info.name;
1772: PetscFunctionReturn(PETSC_SUCCESS);
1773: }
1775: /*@
1776: 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.
1778: Not collective
1780: Level: advanced
1782: Notes:
1783: 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()`).
1785: Other log handlers (such as `PetscLogNestedBegin()`) will ignore this function.
1787: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsResume()`, `PetscLogGetDefaultHandler()`
1788: @*/
1789: PetscErrorCode PetscLogEventsPause(void)
1790: {
1791: PetscFunctionBegin;
1792: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1793: PetscLogHandler h = PetscLogHandlers[i].handler;
1795: if (h) PetscCall(PetscLogHandlerEventsPause(h));
1796: }
1797: PetscFunctionReturn(PETSC_SUCCESS);
1798: }
1800: /*@
1801: PetscLogEventsResume - Return logging to normal behavior after it was paused with `PetscLogEventsPause()`.
1803: Not collective
1805: Level: advanced
1807: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsPause()`, `PetscLogGetDefaultHandler()`
1808: @*/
1809: PetscErrorCode PetscLogEventsResume(void)
1810: {
1811: PetscFunctionBegin;
1812: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1813: PetscLogHandler h = PetscLogHandlers[i].handler;
1815: if (h) PetscCall(PetscLogHandlerEventsResume(h));
1816: }
1817: PetscFunctionReturn(PETSC_SUCCESS);
1818: }
1820: /*------------------------------------------------ Class Functions --------------------------------------------------*/
1822: /*MC
1823: PetscLogObjectCreate - Log the creation of a `PetscObject`
1825: Synopsis:
1826: #include <petsclog.h>
1827: PetscErrorCode PetscLogObjectCreate(PetscObject h)
1829: Not Collective
1831: Input Parameters:
1832: . h - A `PetscObject`
1834: Level: developer
1836: Developer Note:
1837: Called internally by PETSc when creating objects: users do not need to call this directly.
1838: Notification of the object creation is sent to each `PetscLogHandler` that is running.
1840: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectDestroy()`
1841: M*/
1843: /*MC
1844: PetscLogObjectDestroy - Logs the destruction of a `PetscObject`
1846: Synopsis:
1847: #include <petsclog.h>
1848: PetscErrorCode PetscLogObjectDestroy(PetscObject h)
1850: Not Collective
1852: Input Parameters:
1853: . h - A `PetscObject`
1855: Level: developer
1857: Developer Note:
1858: Called internally by PETSc when destroying objects: users do not need to call this directly.
1859: Notification of the object creation is sent to each `PetscLogHandler` that is running.
1861: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectCreate()`
1862: M*/
1864: /*@
1865: PetscLogClassGetClassId - Returns the `PetscClassId` when given the class name.
1867: Not Collective
1869: Input Parameter:
1870: . name - The class name
1872: Output Parameter:
1873: . classid - The `PetscClassId` id, or -1 if no class with that name exists
1875: Level: intermediate
1877: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1878: @*/
1879: PetscErrorCode PetscLogClassGetClassId(const char name[], PetscClassId *classid)
1880: {
1881: PetscLogClass log_class;
1882: PetscLogClassInfo class_info;
1883: PetscLogState state;
1885: PetscFunctionBegin;
1886: *classid = -1;
1887: PetscCall(PetscLogGetState(&state));
1888: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1889: PetscCall(PetscLogStateGetClassFromName(state, name, &log_class));
1890: if (log_class < 0) {
1891: *classid = -1;
1892: PetscFunctionReturn(PETSC_SUCCESS);
1893: }
1894: PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1895: *classid = class_info.classid;
1896: PetscFunctionReturn(PETSC_SUCCESS);
1897: }
1899: /*@
1900: PetscLogClassIdGetName - Returns a `PetscClassId`'s name.
1902: Not Collective
1904: Input Parameter:
1905: . classid - A `PetscClassId`
1907: Output Parameter:
1908: . name - The class name
1910: Level: intermediate
1912: .seealso: [](ch_profiling), `PetscLogClassRegister()`, `PetscLogClassBegin()`, `PetscLogClassEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadClass()`
1913: @*/
1914: PetscErrorCode PetscLogClassIdGetName(PetscClassId classid, const char *name[])
1915: {
1916: PetscLogClass log_class;
1917: PetscLogClassInfo class_info;
1918: PetscLogState state;
1920: PetscFunctionBegin;
1921: PetscCall(PetscLogGetState(&state));
1922: PetscCall(PetscLogStateGetClassFromClassId(state, classid, &log_class));
1923: PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1924: *name = class_info.name;
1925: PetscFunctionReturn(PETSC_SUCCESS);
1926: }
1928: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1929: /*@
1930: PetscLogDump - Dumps logs of objects to a file. There is currently no utility to read the dump file.
1932: Collective on `PETSC_COMM_WORLD`
1934: Input Parameter:
1935: . sname - an optional file name
1937: Example Usage:
1938: .vb
1939: PetscInitialize(...);
1940: PetscLogDefaultBegin();
1941: // ... code ...
1942: PetscLogDump(filename);
1943: PetscFinalize();
1944: .ve
1946: Level: advanced
1948: Note:
1949: The default file name is Log.<rank> where <rank> is the MPI process rank. If no name is specified,
1950: this file will be used.
1952: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
1953: @*/
1954: PetscErrorCode PetscLogDump(const char sname[])
1955: {
1956: PetscLogHandler handler;
1958: PetscFunctionBegin;
1959: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1960: PetscCall(PetscLogHandlerDump(handler, sname));
1961: PetscFunctionReturn(PETSC_SUCCESS);
1962: }
1964: /*@
1965: PetscLogMPEDump - Dumps the MPE logging info to file for later use with Jumpshot.
1967: Collective on `PETSC_COMM_WORLD`
1969: Input Parameter:
1970: . sname - filename for the MPE logfile
1972: Level: advanced
1974: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogMPEBegin()`
1975: @*/
1976: PetscErrorCode PetscLogMPEDump(const char sname[])
1977: {
1978: PetscFunctionBegin;
1979: #if PetscDefined(HAVE_MPE)
1980: if (PetscBeganMPE) {
1981: char name[PETSC_MAX_PATH_LEN];
1983: PetscCall(PetscInfo(0, "Finalizing MPE.\n"));
1984: if (sname) {
1985: PetscCall(PetscStrncpy(name, sname, sizeof(name)));
1986: } else {
1987: PetscCall(PetscGetProgramName(name, sizeof(name)));
1988: }
1989: PetscCall(MPE_Finish_log(name));
1990: } else {
1991: PetscCall(PetscInfo(0, "Not finalizing MPE (not started by PETSc).\n"));
1992: }
1993: #else
1994: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe");
1995: #endif
1996: PetscFunctionReturn(PETSC_SUCCESS);
1997: }
1999: /*@
2000: PetscLogView - Prints a summary of the logging.
2002: Collective
2004: Input Parameter:
2005: . viewer - an ASCII viewer
2007: Options Database Keys:
2008: + -log_view viewer_specification - Views summary of the logging at the conclusion of the program, see `PetscOptionsCreateViewer()` for the format of `viewer_specification`
2009: . -log_view_memory (true|false) - Also display memory usage in each event
2010: . -log_view_gpu_time - Also display time in each event for GPU kernels (Note this may slow the computation)
2011: . -log_view_gpu_energy - Also display energy (estimated with power*gtime) in Joules for GPU kernels
2012: . -log_view_gpu_energy_meter - [Experimental] Also display energy (readings from energy meters) in Joules for GPU kernels.
2013: This option is ignored if `-log_view_gpu_energy` is provided.
2014: . -log_all [filename] - Saves a file `Log.rank` for each MPI process with details of each step of the computation, where
2015: `rank` is the rank of each MPI process
2016: - -log_trace [filename] - Displays a trace of what each process is doing
2018: Level: beginner
2020: Notes:
2021: It is possible to control the logging programmatically but we recommend using the options database approach whenever possible
2022: By default the summary is printed to stdout.
2024: Before calling this routine you must have called either `PetscLogDefaultBegin()` or `PetscLogNestedBegin()`
2026: If PETSc is configured with `--with-log=0` then this functionality is not available
2028: To view the nested XML format `filename.xml` first copy `${PETSC_DIR}/share/petsc/xml/performance_xml2html.xsl` to the current
2029: directory then open `filename.xml` with your browser. Specific notes for certain browsers
2030: .vb
2031: Firefox and Internet explorer - simply open the file
2032: Google Chrome - you must start up Chrome with the option `--allow-file-access-from-files`
2033: Safari - see https://ccm.net/faq/36342-safari-how-to-enable-local-file-access
2034: .ve
2035: or one can use the package <http://xmlsoft.org/XSLT/xsltproc2.html> to translate the xml file to html and then open it with
2036: your browser.
2037: Alternatively, use the script `${PETSC_DIR}/lib/petsc/bin/petsc-performance-view` to automatically open a new browser
2038: window and render the XML log file contents.
2040: The nested XML format was kindly donated by Koos Huijssen and Christiaan M. Klaij MARITIME RESEARCH INSTITUTE NETHERLANDS
2042: The Flame Graph output can be visualised using either the original Flame Graph script <https://github.com/brendangregg/FlameGraph>
2043: or using speedscope <https://www.speedscope.app>.
2044: Old XML profiles may be converted into this format using the script `${PETSC_DIR}/lib/petsc/bin/xml2flamegraph.py`.
2046: Example Usage:
2047: .vb
2048: -log_view :filename - Prints summary of log information to a file
2049: -log_view :filename.py:ascii_info_detail - Saves logging information from each process as a Python file
2050: -log_view :filename.xml:ascii_xml - Saves a summary of the logging information in a nested format (see above for how to view it)
2051: -log_view :filename.txt:ascii_flamegraph - Saves logging information in a format suitable for visualising as a Flame Graph (see above for how to view it)
2052: -log_view :filename.csv:ascii_csv - Saves logging information as a comma-separated values file
2053: .ve
2055: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogDump()`
2056: @*/
2057: PetscErrorCode PetscLogView(PetscViewer viewer)
2058: {
2059: PetscBool isascii;
2060: PetscViewerFormat format;
2061: int stage;
2062: PetscLogState state;
2063: PetscIntStack temp_stack;
2064: PetscLogHandler handler;
2065: PetscBool is_empty;
2067: PetscFunctionBegin;
2068: PetscCall(PetscLogGetState(&state));
2069: /* Pop off any stages the user forgot to remove */
2070: PetscCall(PetscIntStackCreate(&temp_stack));
2071: PetscCall(PetscLogStateGetCurrentStage(state, &stage));
2072: while (stage >= 0) {
2073: PetscCall(PetscLogStagePop());
2074: PetscCall(PetscIntStackPush(temp_stack, stage));
2075: PetscCall(PetscLogStateGetCurrentStage(state, &stage));
2076: }
2077: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
2078: PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Currently can only view logging to ASCII");
2079: PetscCall(PetscViewerGetFormat(viewer, &format));
2080: if (format == PETSC_VIEWER_ASCII_XML || format == PETSC_VIEWER_ASCII_FLAMEGRAPH) {
2081: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERNESTED, &handler));
2082: PetscCall(PetscLogHandlerView(handler, viewer));
2083: } else {
2084: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
2085: PetscCall(PetscLogHandlerView(handler, viewer));
2086: }
2087: PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
2088: while (!is_empty) {
2089: PetscCall(PetscIntStackPop(temp_stack, &stage));
2090: PetscCall(PetscLogStagePush(stage));
2091: PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
2092: }
2093: PetscCall(PetscIntStackDestroy(temp_stack));
2094: PetscFunctionReturn(PETSC_SUCCESS);
2095: }
2097: /*@
2098: PetscLogViewFromOptions - Processes command line options to determine if/how a `PetscLog` is to be viewed.
2100: Collective on `PETSC_COMM_WORLD`
2102: Options Database Key:
2103: . -log_view viewer_specification,viewer_specification - list of up to four specifications of viewers, see `PetscOptionsCreateViewer()` for their format
2105: Level: developer
2107: Note:
2108: This function has a different API and behavior than `PetscObjectViewFromOptions()`
2110: .seealso: [](ch_profiling), `PetscLogView()`
2111: @*/
2112: PetscErrorCode PetscLogViewFromOptions(void)
2113: {
2114: PetscInt n_max = PETSC_LOG_VIEW_FROM_OPTIONS_MAX;
2115: PetscViewer viewers[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2116: PetscViewerFormat formats[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2117: PetscBool flg;
2119: PetscFunctionBegin;
2120: PetscCall(PetscOptionsCreateViewers(PETSC_COMM_WORLD, NULL, NULL, "-log_view", &n_max, viewers, formats, &flg));
2121: /*
2122: PetscLogHandlerView_Default_Info() wants to be sure that the only objects still around are these viewers, so keep track of how many there are
2123: */
2124: PetscLogNumViewersCreated = n_max;
2125: for (PetscInt i = 0; i < n_max; i++) {
2126: PetscInt refct;
2128: PetscCall(PetscViewerPushFormat(viewers[i], formats[i]));
2129: PetscCall(PetscLogView(viewers[i]));
2130: PetscCall(PetscViewerPopFormat(viewers[i]));
2131: PetscCall(PetscObjectGetReference((PetscObject)viewers[i], &refct));
2132: PetscCall(PetscViewerDestroy(&viewers[i]));
2133: if (refct == 1) PetscLogNumViewersDestroyed++;
2134: }
2135: PetscLogNumViewersDestroyed = 0;
2136: PetscFunctionReturn(PETSC_SUCCESS);
2137: }
2139: PETSC_INTERN PetscErrorCode PetscLogHandlerNestedSetThreshold(PetscLogHandler, PetscLogDouble, PetscLogDouble *);
2141: /*@
2142: PetscLogSetThreshold - Set the threshold time for logging the events; this is a percentage out of 100, so 1. means any event
2143: that takes 1 or more percent of the time.
2145: Logically Collective on `PETSC_COMM_WORLD`
2147: Input Parameter:
2148: . newThresh - the threshold to use
2150: Output Parameter:
2151: . oldThresh - the previously set threshold value
2153: Options Database Key:
2154: . -log_threshold threshold - provide the threshold
2156: Example Usage:
2157: .vb
2158: PetscInitialize(...);
2159: PetscLogNestedBegin();
2160: PetscLogSetThreshold(0.1,&oldthresh);
2161: // ... code ...
2162: PetscLogView(viewer);
2163: PetscFinalize();
2164: .ve
2166: Level: advanced
2168: Note:
2169: This threshold is only used by the nested log handler
2171: .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`,
2172: `PetscLogNestedBegin()`
2173: @*/
2174: PetscErrorCode PetscLogSetThreshold(PetscLogDouble newThresh, PetscLogDouble *oldThresh)
2175: {
2176: PetscLogHandler handler;
2178: PetscFunctionBegin;
2179: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERNESTED, &handler));
2180: PetscCall(PetscLogHandlerNestedSetThreshold(handler, newThresh, oldThresh));
2181: PetscFunctionReturn(PETSC_SUCCESS);
2182: }
2184: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
2185: /*@
2186: PetscGetFlops - Returns the number of flops used on this processor
2187: since the program began.
2189: Not Collective
2191: Output Parameter:
2192: . flops - number of floating point operations
2194: Level: intermediate
2196: Notes:
2197: A global counter logs all PETSc flop counts. The user can use
2198: `PetscLogFlops()` to increment this counter to include flops for the
2199: application code.
2201: A separate counter `PetscLogGpuFlops()` logs the flops that occur on any GPU associated with this MPI rank
2203: .seealso: [](ch_profiling), `PetscLogGpuFlops()`, `PetscTime()`, `PetscLogFlops()`
2204: @*/
2205: PetscErrorCode PetscGetFlops(PetscLogDouble *flops)
2206: {
2207: PetscFunctionBegin;
2208: *flops = petsc_TotalFlops;
2209: PetscFunctionReturn(PETSC_SUCCESS);
2210: }
2212: /*@
2213: PetscLogObjectState - Record information about an object with the default log handler
2215: Not Collective
2217: Input Parameters:
2218: + obj - the `PetscObject`
2219: . format - a printf-style format string
2220: - ... - `printf()` arguments to format
2222: Level: developer
2224: .seealso: [](ch_profiling), `PetscLogObjectCreate()`, `PetscLogObjectDestroy()`, `PetscLogGetDefaultHandler()`
2225: @*/
2226: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
2227: {
2228: PetscFunctionBegin;
2229: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2230: PetscLogHandler h = PetscLogHandlers[i].handler;
2232: if (h) {
2233: va_list Argp;
2234: va_start(Argp, format);
2235: PetscCall(PetscLogHandlerLogObjectState_Internal(h, obj, format, Argp));
2236: va_end(Argp);
2237: }
2238: }
2239: PetscFunctionReturn(PETSC_SUCCESS);
2240: }
2242: /*MC
2243: PetscLogFlops - Adds floating point operations to the global counter.
2245: Synopsis:
2246: #include <petsclog.h>
2247: PetscErrorCode PetscLogFlops(PetscLogDouble f)
2249: Not Collective
2251: Input Parameter:
2252: . f - flop counter
2254: Example Usage:
2255: .vb
2256: PetscLogEvent USER_EVENT;
2258: PetscLogEventRegister("User event", 0, &USER_EVENT);
2259: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
2260: [code segment to monitor]
2261: PetscLogFlops(user_flops)
2262: PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
2263: .ve
2265: Level: intermediate
2267: Note:
2268: A global counter logs all PETSc flop counts. The user can use PetscLogFlops() to increment
2269: this counter to include flops for the application code.
2271: .seealso: [](ch_profiling), `PetscLogGpuFlops()`, `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscGetFlops()`
2272: M*/
2274: /*MC
2275: PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice) to get accurate
2276: timings
2278: Synopsis:
2279: #include <petsclog.h>
2280: void PetscPreLoadBegin(PetscBool flag, char *name);
2282: Not Collective
2284: Input Parameters:
2285: + flag - `PETSC_TRUE` to run twice, `PETSC_FALSE` to run once, may be overridden with command
2286: line option `-preload true|false`
2287: - name - name of first stage (lines of code timed separately with `-log_view`) to be preloaded
2289: Example Usage:
2290: .vb
2291: PetscPreLoadBegin(PETSC_TRUE, "first stage");
2292: // lines of code
2293: PetscPreLoadStage("second stage");
2294: // lines of code
2295: PetscPreLoadEnd();
2296: .ve
2298: Level: intermediate
2300: Note:
2301: Only works in C/C++, not Fortran
2303: Flags available within the macro\:
2304: + PetscPreLoadingUsed - `PETSC_TRUE` if we are or have done preloading
2305: . PetscPreLoadingOn - `PETSC_TRUE` if it is CURRENTLY doing preload
2306: . PetscPreLoadIt - `0` for the first computation (with preloading turned off it is only
2307: `0`) `1` for the second
2308: - PetscPreLoadMax - number of times it will do the computation, only one when preloading is
2309: turned on
2311: The first two variables are available throughout the program, the second two only between the
2312: `PetscPreLoadBegin()` and `PetscPreLoadEnd()`
2314: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
2315: M*/
2317: /*MC
2318: PetscPreLoadEnd - End a segment of code that may be preloaded (run twice) to get accurate
2319: timings
2321: Synopsis:
2322: #include <petsclog.h>
2323: void PetscPreLoadEnd(void);
2325: Not Collective
2327: Example Usage:
2328: .vb
2329: PetscPreLoadBegin(PETSC_TRUE, "first stage");
2330: // lines of code
2331: PetscPreLoadStage("second stage");
2332: // lines of code
2333: PetscPreLoadEnd();
2334: .ve
2336: Level: intermediate
2338: Note:
2339: Only works in C/C++ not Fortran
2341: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadStage()`
2342: M*/
2344: /*MC
2345: PetscPreLoadStage - Start a new segment of code to be timed separately to get accurate timings
2347: Synopsis:
2348: #include <petsclog.h>
2349: void PetscPreLoadStage(char *name);
2351: Not Collective
2353: Example Usage:
2354: .vb
2355: PetscPreLoadBegin(PETSC_TRUE,"first stage");
2356: // lines of code
2357: PetscPreLoadStage("second stage");
2358: // lines of code
2359: PetscPreLoadEnd();
2360: .ve
2362: Level: intermediate
2364: Note:
2365: Only works in C/C++ not Fortran
2367: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`
2368: M*/
2370: #if PetscDefined(HAVE_DEVICE)
2371: #include <petsc/private/deviceimpl.h>
2373: /*@
2374: PetscLogGpuTime - turn on the logging of GPU time for GPU kernels
2376: Options Database Key:
2377: . -log_view_gpu_time - provide the GPU times for all events in the `-log_view` output
2379: Level: advanced
2381: Notes:
2382: Turning on the timing of the GPU kernels can slow down the entire computation and should only
2383: be used when studying the performance of individual operations on GPU such as vector operations and
2384: matrix-vector operations.
2386: 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
2388: This routine should only be called once near the beginning of the program. Once it is started
2389: it cannot be turned off.
2391: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTimeBegin()`
2392: @*/
2393: PetscErrorCode PetscLogGpuTime(void)
2394: {
2395: PetscFunctionBegin;
2396: PetscCheck(petsc_gtime == 0.0, PETSC_COMM_SELF, PETSC_ERR_SUP, "GPU logging has already been turned on");
2397: PetscLogGpuTimeFlag = PETSC_TRUE;
2398: PetscFunctionReturn(PETSC_SUCCESS);
2399: }
2401: /*@
2402: PetscLogGpuTimeBegin - Start timer for device
2404: Level: intermediate
2406: Notes:
2407: When GPU is enabled, the timer is run on the GPU, it is a separate logging of time
2408: devoted to GPU computations (excluding kernel launch times).
2410: When GPU is not available, the timer is run on the CPU, it is a separate logging of
2411: time devoted to GPU computations (including kernel launch times).
2413: There is no need to call `WaitForCUDA()` or `WaitForHIP()` between `PetscLogGpuTimeBegin()` and
2414: `PetscLogGpuTimeEnd()`
2416: This timer should NOT include times for data transfers between the GPU and CPU, nor setup
2417: actions such as allocating space.
2419: The regular logging captures the time for data transfers and any CPU activities during the
2420: event. It is used to compute the flop rate on the GPU as it is actively engaged in running a
2421: kernel.
2423: Developer Notes:
2424: The GPU event timer captures the execution time of all the kernels launched in the default
2425: stream by the CPU between `PetscLogGpuTimeBegin()` and `PetscLogGpuTimeEnd()`.
2427: `PetscLogGpuTimeBegin()` and `PetscLogGpuTimeEnd()` insert the begin and end events into the
2428: default stream (stream 0). The device will record a time stamp for the event when it reaches
2429: that event in the stream. The function xxxEventSynchronize() is called in
2430: `PetscLogGpuTimeEnd()` to block CPU execution, but not continued GPU execution, until the
2431: timer event is recorded.
2433: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTime()`
2434: @*/
2435: PetscErrorCode PetscLogGpuTimeBegin(void)
2436: {
2437: PetscBool isActive;
2439: PetscFunctionBegin;
2440: PetscCall(PetscLogEventBeginIsActive(&isActive));
2441: if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2442: if (!PetscDefined(HAVE_KOKKOS_WITHOUT_GPU)) {
2443: PetscDeviceContext dctx;
2445: PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2446: PetscCall(PetscDeviceContextBeginTimer_Internal(dctx));
2447: } else {
2448: PetscCall(PetscTimeSubtract(&petsc_gtime));
2449: }
2450: PetscFunctionReturn(PETSC_SUCCESS);
2451: }
2453: /*@
2454: PetscLogGpuTimeEnd - Stop timer for device
2456: Level: intermediate
2458: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeBegin()`
2459: @*/
2460: PetscErrorCode PetscLogGpuTimeEnd(void)
2461: {
2462: PetscBool isActive;
2464: PetscFunctionBegin;
2465: PetscCall(PetscLogEventEndIsActive(&isActive));
2466: if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2467: if (!PetscDefined(HAVE_KOKKOS_WITHOUT_GPU)) {
2468: PetscDeviceContext dctx;
2469: PetscLogDouble elapsed;
2471: PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2472: PetscCall(PetscDeviceContextEndTimer_Internal(dctx, &elapsed));
2473: petsc_gtime += (elapsed / 1000.0);
2474: #if PetscDefined(HAVE_CUDA_VERSION_12_2PLUS)
2475: if (PetscLogGpuEnergyFlag) {
2476: PetscLogDouble power;
2477: PetscCall(PetscDeviceContextGetPower_Internal(dctx, &power));
2478: petsc_genergy += (power * elapsed / 1000000.0); // convert to Joules
2479: }
2480: #endif
2481: } else {
2482: PetscCall(PetscTimeAdd(&petsc_gtime));
2483: }
2484: PetscFunctionReturn(PETSC_SUCCESS);
2485: }
2487: /*@
2488: PetscLogGpuEnergy - turn on the logging of GPU energy (estimated with power*gtime) for GPU kernels
2490: Options Database Key:
2491: . -log_view_gpu_energy - provide the GPU energy consumption (estimated with power*gtime) for all events in the `-log_view` output
2493: Level: advanced
2495: Note:
2496: This option is mutually exclusive to `-log_view_gpu_energy_meter`.
2498: Developer Note:
2499: This option turns on energy monitoring of GPU kernels and requires CUDA version >= 12.2. The energy consumption is estimated as
2500: instant_power * gpu_kernel_time. Due to the delay in NVML power sampling, we read the instantaneous power draw at the end of each
2501: event using `nvmlDeviceGetFieldValues()` with the field ID `NVML_FI_DEV_POWER_INSTANT`.
2503: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuEnergyMeter()`
2504: @*/
2505: PetscErrorCode PetscLogGpuEnergy(void)
2506: {
2507: PetscFunctionBegin;
2508: PetscCheck(PetscDefined(HAVE_CUDA_VERSION_12_2PLUS), PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "-log_view_gpu_energy requires CUDA version >= 12.2");
2509: PetscCheck(petsc_genergy == 0.0, PETSC_COMM_SELF, PETSC_ERR_SUP, "GPU energy logging has already been turned on");
2510: PetscLogGpuEnergyFlag = PETSC_TRUE;
2511: PetscLogGpuEnergyMeterFlag = PETSC_FALSE;
2512: PetscFunctionReturn(PETSC_SUCCESS);
2513: }
2515: /*@
2516: PetscLogGpuEnergyMeter - turn on the logging of GPU energy (readings from energy meters) for GPU kernels
2518: Options Database Key:
2519: . -log_view_gpu_energy_meter - provide the GPU energy (readings from energy meters) consumption for all events in the `-log_view` output
2521: Level: advanced
2523: Note:
2524: This option is mutually exclusive to `-log_view_gpu_energy`.
2526: Developer Note:
2527: This option turns on energy monitoring of GPU kernels. The energy consumption is measured directly using the NVML API
2528: `nvmlDeviceGetTotalEnergyConsumption()`, which returns the total energy used by the GPU since the driver was last initialized.
2529: For newer GPUs, energy readings are updated every 20-100ms, so this approach may be inaccurate for short-duration GPU events.
2531: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuEnergyMeterEnd()`, `PetscLogGpuEnergyMeterBegin()`
2532: @*/
2533: PetscErrorCode PetscLogGpuEnergyMeter(void)
2534: {
2535: PetscFunctionBegin;
2536: PetscCheck(petsc_genergy == 0.0, PETSC_COMM_SELF, PETSC_ERR_SUP, "GPU energy logging has already been turned on");
2537: PetscLogGpuEnergyMeterFlag = PETSC_TRUE;
2538: PetscLogGpuEnergyFlag = PETSC_FALSE;
2539: PetscFunctionReturn(PETSC_SUCCESS);
2540: }
2542: /*@
2543: PetscLogGpuEnergyMeterBegin - Start energy meter for device
2545: Level: intermediate
2547: Notes:
2548: The GPU event energy meter captures the energy used by the GPU between `PetscLogGpuEnergyMeterBegin()` and `PetscLogGpuEnergyMeterEnd()`.
2550: `PetscLogGpuEnergyMeterBegin()` and `PetscLogGpuEnergyMeterEnd()` collect the energy readings using `nvmlDeviceGetTotalEnergyConsumption()`.
2551: The function `cupmStreamSynchronize()` is called before the energy query to ensure completion.
2553: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuEnergyMeterEnd()`, `PetscLogGpuEnergyMeter()`
2554: @*/
2555: PetscErrorCode PetscLogGpuEnergyMeterBegin(void)
2556: {
2557: PetscBool isActive;
2559: PetscFunctionBegin;
2560: PetscCall(PetscLogEventBeginIsActive(&isActive));
2561: if (!isActive || !PetscLogGpuEnergyMeterFlag) PetscFunctionReturn(PETSC_SUCCESS);
2562: if (!PetscDefined(HAVE_KOKKOS_WITHOUT_GPU)) {
2563: PetscDeviceContext dctx;
2565: PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2566: PetscCall(PetscDeviceContextBeginEnergyMeter_Internal(dctx));
2567: }
2568: PetscFunctionReturn(PETSC_SUCCESS);
2569: }
2571: /*@
2572: PetscLogGpuEnergyMeterEnd - Stop energy meter for device
2574: Level: intermediate
2576: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuEnergyMeterBegin()`
2577: @*/
2578: PetscErrorCode PetscLogGpuEnergyMeterEnd(void)
2579: {
2580: PetscBool isActive;
2582: PetscFunctionBegin;
2583: PetscCall(PetscLogEventEndIsActive(&isActive));
2584: if (!isActive || !PetscLogGpuEnergyMeterFlag) PetscFunctionReturn(PETSC_SUCCESS);
2585: if (!PetscDefined(HAVE_KOKKOS_WITHOUT_GPU)) {
2586: PetscDeviceContext dctx;
2587: PetscLogDouble energy;
2589: PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2590: PetscCall(PetscDeviceContextEndEnergyMeter_Internal(dctx, &energy));
2591: petsc_genergy_meter += (energy / 1000.0); // convert to Joules
2592: }
2593: PetscFunctionReturn(PETSC_SUCCESS);
2594: }
2595: #endif /* end of PETSC_HAVE_DEVICE */
2597: #endif /* PETSC_USE_LOG*/
2599: PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2600: PetscClassId PETSC_OBJECT_CLASSID = 0;
2602: static PetscBool PetscLogInitializeCalled = PETSC_FALSE;
2604: PETSC_INTERN PetscErrorCode PetscLogInitialize(void)
2605: {
2606: int stage;
2608: PetscFunctionBegin;
2609: if (PetscLogInitializeCalled) PetscFunctionReturn(PETSC_SUCCESS);
2610: PetscLogInitializeCalled = PETSC_TRUE;
2611: if (PetscDefined(USE_LOG)) {
2612: /* Setup default logging structures */
2613: PetscCall(PetscLogStateCreate(&petsc_log_state));
2614: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2615: if (PetscLogHandlers[i].handler) PetscCall(PetscLogHandlerSetState(PetscLogHandlers[i].handler, petsc_log_state));
2616: }
2617: PetscCall(PetscLogStateStageRegister(petsc_log_state, "Main Stage", &stage));
2618: PetscCall(PetscSpinlockCreate(&PetscLogSpinLock));
2619: #if PetscDefined(HAVE_THREADSAFETY)
2620: petsc_log_tid = 0;
2621: petsc_log_gid = 0;
2622: #endif
2624: /* All processors sync here for more consistent logging */
2625: PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
2626: PetscCall(PetscTime(&petsc_BaseTime));
2627: PetscCall(PetscLogStagePush(stage));
2628: }
2629: PetscFunctionReturn(PETSC_SUCCESS);
2630: }
2632: PETSC_INTERN PetscErrorCode PetscLogFinalize(void)
2633: {
2634: PetscFunctionBegin;
2635: if (PetscDefined(USE_LOG)) {
2636: /* Resetting phase */
2637: // pop remaining stages
2638: if (petsc_log_state) {
2639: while (petsc_log_state->current_stage >= 0) PetscCall(PetscLogStagePop());
2640: }
2641: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) PetscCall(PetscLogHandlerDestroy(&PetscLogHandlers[i].handler));
2642: PetscCall(PetscArrayzero(PetscLogHandlers, PETSC_LOG_HANDLER_MAX));
2643: PetscCall(PetscLogStateDestroy(&petsc_log_state));
2645: petsc_TotalFlops = 0.0;
2646: petsc_BaseTime = 0.0;
2647: petsc_TotalFlops = 0.0;
2648: petsc_send_ct = 0.0;
2649: petsc_recv_ct = 0.0;
2650: petsc_send_len = 0.0;
2651: petsc_recv_len = 0.0;
2652: petsc_isend_ct = 0.0;
2653: petsc_irecv_ct = 0.0;
2654: petsc_isend_len = 0.0;
2655: petsc_irecv_len = 0.0;
2656: petsc_wait_ct = 0.0;
2657: petsc_wait_any_ct = 0.0;
2658: petsc_wait_all_ct = 0.0;
2659: petsc_sum_of_waits_ct = 0.0;
2660: petsc_allreduce_ct = 0.0;
2661: petsc_gather_ct = 0.0;
2662: petsc_scatter_ct = 0.0;
2663: petsc_TotalFlops_th = 0.0;
2664: petsc_send_ct_th = 0.0;
2665: petsc_recv_ct_th = 0.0;
2666: petsc_send_len_th = 0.0;
2667: petsc_recv_len_th = 0.0;
2668: petsc_isend_ct_th = 0.0;
2669: petsc_irecv_ct_th = 0.0;
2670: petsc_isend_len_th = 0.0;
2671: petsc_irecv_len_th = 0.0;
2672: petsc_wait_ct_th = 0.0;
2673: petsc_wait_any_ct_th = 0.0;
2674: petsc_wait_all_ct_th = 0.0;
2675: petsc_sum_of_waits_ct_th = 0.0;
2676: petsc_allreduce_ct_th = 0.0;
2677: petsc_gather_ct_th = 0.0;
2678: petsc_scatter_ct_th = 0.0;
2680: petsc_ctog_ct = 0.0;
2681: petsc_gtoc_ct = 0.0;
2682: petsc_ctog_sz = 0.0;
2683: petsc_gtoc_sz = 0.0;
2684: petsc_gflops = 0.0;
2685: petsc_gtime = 0.0;
2686: petsc_genergy = 0.0;
2687: petsc_genergy_meter = 0.0;
2688: petsc_ctog_ct_th = 0.0;
2689: petsc_gtoc_ct_th = 0.0;
2690: petsc_ctog_sz_th = 0.0;
2691: petsc_gtoc_sz_th = 0.0;
2692: petsc_gflops_th = 0.0;
2693: petsc_gtime_th = 0.0;
2694: }
2695: PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2696: PETSC_OBJECT_CLASSID = 0;
2697: PetscLogInitializeCalled = PETSC_FALSE;
2698: PetscFunctionReturn(PETSC_SUCCESS);
2699: }
2701: /*@
2702: PetscClassIdRegister - Registers a new class name for objects and logging operations in an application code.
2704: Not Collective
2706: Input Parameter:
2707: . name - The class name
2709: Output Parameter:
2710: . oclass - The class id or classid
2712: Level: developer
2714: .seealso: [](ch_profiling), `PetscLogEventRegister()`
2715: @*/
2716: PetscErrorCode PetscClassIdRegister(const char name[], PetscClassId *oclass)
2717: {
2718: PetscFunctionBegin;
2719: *oclass = ++PETSC_LARGEST_CLASSID;
2720: #if PetscDefined(USE_LOG)
2721: {
2722: PetscLogState state;
2723: PetscLogClass logclass;
2725: PetscCall(PetscLogGetState(&state));
2726: if (state) PetscCall(PetscLogStateClassRegister(state, name, *oclass, &logclass));
2727: }
2728: #endif
2729: PetscFunctionReturn(PETSC_SUCCESS);
2730: }