Actual source code: plog.c
1: /*
2: PETSc code to log object creation and destruction and PETSc events.
4: This provides the public API used by the rest of PETSc and by users.
6: These routines use a private API that is not used elsewhere in PETSc and is not
7: accessible to users. The private API is defined in logimpl.h and the utils directory.
9: ***
11: This file, and only this file, is for functions that interact with the global logging state
12: */
13: #include <petsc/private/logimpl.h>
14: #include <petsc/private/loghandlerimpl.h>
15: #include <petsctime.h>
16: #include <petscviewer.h>
17: #include <petscdevice.h>
18: #include <petsc/private/deviceimpl.h>
20: #if defined(PETSC_HAVE_THREADSAFETY)
22: PetscInt petsc_log_gid = -1; /* Global threadId counter */
23: PETSC_TLS PetscInt petsc_log_tid = -1; /* Local threadId */
25: /* shared variables */
26: PetscSpinlock PetscLogSpinLock;
28: PetscInt PetscLogGetTid(void)
29: {
30: if (petsc_log_tid < 0) {
31: PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
32: petsc_log_tid = ++petsc_log_gid;
33: PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
34: }
35: return petsc_log_tid;
36: }
38: #endif
40: /* Global counters */
41: PetscLogDouble petsc_BaseTime = 0.0;
42: PetscLogDouble petsc_TotalFlops = 0.0; /* The number of flops */
43: PetscLogDouble petsc_send_ct = 0.0; /* The number of sends */
44: PetscLogDouble petsc_recv_ct = 0.0; /* The number of receives */
45: PetscLogDouble petsc_send_len = 0.0; /* The total length of all sent messages */
46: PetscLogDouble petsc_recv_len = 0.0; /* The total length of all received messages */
47: PetscLogDouble petsc_isend_ct = 0.0; /* The number of immediate sends */
48: PetscLogDouble petsc_irecv_ct = 0.0; /* The number of immediate receives */
49: PetscLogDouble petsc_isend_len = 0.0; /* The total length of all immediate send messages */
50: PetscLogDouble petsc_irecv_len = 0.0; /* The total length of all immediate receive messages */
51: PetscLogDouble petsc_wait_ct = 0.0; /* The number of waits */
52: PetscLogDouble petsc_wait_any_ct = 0.0; /* The number of anywaits */
53: PetscLogDouble petsc_wait_all_ct = 0.0; /* The number of waitalls */
54: PetscLogDouble petsc_sum_of_waits_ct = 0.0; /* The total number of waits */
55: PetscLogDouble petsc_allreduce_ct = 0.0; /* The number of reductions */
56: PetscLogDouble petsc_gather_ct = 0.0; /* The number of gathers and gathervs */
57: PetscLogDouble petsc_scatter_ct = 0.0; /* The number of scatters and scattervs */
59: /* Thread Local storage */
60: PETSC_TLS PetscLogDouble petsc_TotalFlops_th = 0.0;
61: PETSC_TLS PetscLogDouble petsc_send_ct_th = 0.0;
62: PETSC_TLS PetscLogDouble petsc_recv_ct_th = 0.0;
63: PETSC_TLS PetscLogDouble petsc_send_len_th = 0.0;
64: PETSC_TLS PetscLogDouble petsc_recv_len_th = 0.0;
65: PETSC_TLS PetscLogDouble petsc_isend_ct_th = 0.0;
66: PETSC_TLS PetscLogDouble petsc_irecv_ct_th = 0.0;
67: PETSC_TLS PetscLogDouble petsc_isend_len_th = 0.0;
68: PETSC_TLS PetscLogDouble petsc_irecv_len_th = 0.0;
69: PETSC_TLS PetscLogDouble petsc_wait_ct_th = 0.0;
70: PETSC_TLS PetscLogDouble petsc_wait_any_ct_th = 0.0;
71: PETSC_TLS PetscLogDouble petsc_wait_all_ct_th = 0.0;
72: PETSC_TLS PetscLogDouble petsc_sum_of_waits_ct_th = 0.0;
73: PETSC_TLS PetscLogDouble petsc_allreduce_ct_th = 0.0;
74: PETSC_TLS PetscLogDouble petsc_gather_ct_th = 0.0;
75: PETSC_TLS PetscLogDouble petsc_scatter_ct_th = 0.0;
77: PetscLogDouble petsc_ctog_ct = 0.0; /* The total number of CPU to GPU copies */
78: PetscLogDouble petsc_gtoc_ct = 0.0; /* The total number of GPU to CPU copies */
79: PetscLogDouble petsc_ctog_sz = 0.0; /* The total size of CPU to GPU copies */
80: PetscLogDouble petsc_gtoc_sz = 0.0; /* The total size of GPU to CPU copies */
81: PetscLogDouble petsc_ctog_ct_scalar = 0.0; /* The total number of CPU to GPU copies */
82: PetscLogDouble petsc_gtoc_ct_scalar = 0.0; /* The total number of GPU to CPU copies */
83: PetscLogDouble petsc_ctog_sz_scalar = 0.0; /* The total size of CPU to GPU copies */
84: PetscLogDouble petsc_gtoc_sz_scalar = 0.0; /* The total size of GPU to CPU copies */
85: PetscLogDouble petsc_gflops = 0.0; /* The flops done on a GPU */
86: PetscLogDouble petsc_gtime = 0.0; /* The time spent on a GPU */
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 defined(PETSC_USE_LOG)
125: #include <../src/sys/logging/handler/impls/default/logdefault.h>
127: #if defined(PETSC_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 [viewertype:filename:viewerformat] - Prints summary of flop and timing (profiling) information to the
476: screen (for PETSc configured with `--with-log=1` (which is the default)).
477: This option must be provided before `PetscInitialize()`.
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: /*@C
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 too much.
551: Logically Collective on `PETSC_COMM_WORLD`, No Fortran Support
553: Options Database Keys:
554: . -log_view :filename.xml:ascii_xml - Prints an XML summary of flop and timing information to the file
556: Example Usage:
557: .vb
558: PetscInitialize(...);
559: PetscLogNestedBegin();
560: ... code ...
561: PetscLogView(viewer);
562: PetscFinalize();
563: .ve
565: Level: advanced
567: .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`
568: @*/
569: PetscErrorCode PetscLogNestedBegin(void)
570: {
571: PetscFunctionBegin;
572: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERNESTED));
573: PetscFunctionReturn(PETSC_SUCCESS);
574: }
576: /*@C
577: PetscLogLegacyCallbacksBegin - Create and start a log handler from callbacks
578: matching the now deprecated function pointers `PetscLogPLB`, `PetscLogPLE`,
579: `PetscLogPHC`, `PetscLogPHD`.
581: Logically Collective on `PETSC_COMM_WORLD`
583: Input Parameters:
584: + PetscLogPLB - A callback that will be executed by `PetscLogEventBegin()` (or `NULL`)
585: . PetscLogPLE - A callback that will be executed by `PetscLogEventEnd()` (or `NULL`)
586: . PetscLogPHC - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`)
587: - PetscLogPHD - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`)
589: Calling sequence of `PetscLogPLB`:
590: + e - a `PetscLogEvent` that is beginning
591: . _i - deprecated, unused
592: . o1 - a `PetscObject` associated with `e` (or `NULL`)
593: . o2 - a `PetscObject` associated with `e` (or `NULL`)
594: . o3 - a `PetscObject` associated with `e` (or `NULL`)
595: - o4 - a `PetscObject` associated with `e` (or `NULL`)
597: Calling sequence of `PetscLogPLE`:
598: + e - a `PetscLogEvent` that is beginning
599: . _i - deprecated, unused
600: . o1 - a `PetscObject` associated with `e` (or `NULL`)
601: . o2 - a `PetscObject` associated with `e` (or `NULL`)
602: . o3 - a `PetscObject` associated with `e` (or `NULL`)
603: - o4 - a `PetscObject` associated with `e` (or `NULL`)
605: Calling sequence of `PetscLogPHC`:
606: . o - a `PetscObject` that has just been created
608: Calling sequence of `PetscLogPHD`:
609: . o - a `PetscObject` that is about to be destroyed
611: Level: advanced
613: Notes:
614: This is for transitioning from the deprecated function `PetscLogSet()` and should not be used in new code.
616: This should help migrate external log handlers to use `PetscLogHandler`, but
617: callbacks that depend on the deprecated `PetscLogStage` datatype will have to be
618: updated.
620: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerStart()`, `PetscLogState`
621: @*/
622: 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))
623: {
624: PetscLogHandler handler;
626: PetscFunctionBegin;
627: PetscCall(PetscLogHandlerCreateLegacy(PETSC_COMM_WORLD, PetscLogPLB, PetscLogPLE, PetscLogPHC, PetscLogPHD, &handler));
628: PetscCall(PetscLogHandlerStart(handler));
629: PetscCall(PetscLogHandlerDestroy(&handler));
630: PetscFunctionReturn(PETSC_SUCCESS);
631: }
633: #if defined(PETSC_HAVE_MPE)
634: #include <mpe.h>
635: static PetscBool PetscBeganMPE = PETSC_FALSE;
636: #endif
638: /*@C
639: PetscLogMPEBegin - Turns on MPE logging of events. This creates large log files and slows the
640: program down.
642: Collective on `PETSC_COMM_WORLD`, No Fortran Support
644: Options Database Key:
645: . -log_mpe - Prints extensive log information
647: Level: advanced
649: Note:
650: A related routine is `PetscLogDefaultBegin()` (with the options key `-log_view`), which is
651: intended for production runs since it logs only flop rates and object creation (and should
652: not significantly slow the programs).
654: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogDefaultBegin()`, `PetscLogEventActivate()`,
655: `PetscLogEventDeactivate()`
656: @*/
657: PetscErrorCode PetscLogMPEBegin(void)
658: {
659: PetscFunctionBegin;
660: #if defined(PETSC_HAVE_MPE)
661: /* Do MPE initialization */
662: if (!MPE_Initialized_logging()) { /* This function exists in mpich 1.1.2 and higher */
663: PetscCall(PetscInfo(0, "Initializing MPE.\n"));
664: PetscCall(MPE_Init_log());
666: PetscBeganMPE = PETSC_TRUE;
667: } else {
668: PetscCall(PetscInfo(0, "MPE already initialized. Not attempting to reinitialize.\n"));
669: }
670: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERMPE));
671: #else
672: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe");
673: #endif
674: PetscFunctionReturn(PETSC_SUCCESS);
675: }
677: #if defined(PETSC_HAVE_TAU_PERFSTUBS)
678: #include <../src/sys/perfstubs/timer.h>
679: #endif
681: /*@C
682: PetscLogPerfstubsBegin - Turns on logging of events using the perfstubs interface.
684: Collective on `PETSC_COMM_WORLD`, No Fortran Support
686: Options Database Key:
687: . -log_perfstubs - use an external log handler through the perfstubs interface
689: Level: advanced
691: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogEventActivate()`
692: @*/
693: PetscErrorCode PetscLogPerfstubsBegin(void)
694: {
695: PetscFunctionBegin;
696: #if defined(PETSC_HAVE_TAU_PERFSTUBS)
697: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERPERFSTUBS));
698: #else
699: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without perfstubs support, reconfigure with --with-tau-perfstubs");
700: #endif
701: PetscFunctionReturn(PETSC_SUCCESS);
702: }
704: /*@
705: PetscLogActions - Determines whether actions are logged for the default log handler.
707: Not Collective
709: Input Parameter:
710: . flag - `PETSC_TRUE` if actions are to be logged
712: Options Database Key:
713: + -log_exclude_actions - (deprecated) Does nothing
714: - -log_include_actions - Turn on action logging
716: Level: intermediate
718: Note:
719: Logging of actions continues to consume more memory as the program
720: runs. Long running programs should consider turning this feature off.
722: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogGetDefaultHandler()`
723: @*/
724: PetscErrorCode PetscLogActions(PetscBool flag)
725: {
726: PetscFunctionBegin;
727: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
728: PetscLogHandler h = PetscLogHandlers[i].handler;
730: if (h) PetscCall(PetscLogHandlerSetLogActions(h, flag));
731: }
732: PetscFunctionReturn(PETSC_SUCCESS);
733: }
735: /*@
736: PetscLogObjects - Determines whether objects are logged for the graphical viewer.
738: Not Collective
740: Input Parameter:
741: . flag - `PETSC_TRUE` if objects are to be logged
743: Options Database Key:
744: + -log_exclude_objects - (deprecated) Does nothing
745: - -log_include_objects - Turns on object logging
747: Level: intermediate
749: Note:
750: Logging of objects continues to consume more memory as the program
751: runs. Long running programs should consider turning this feature off.
753: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogGetDefaultHandler()`
754: @*/
755: PetscErrorCode PetscLogObjects(PetscBool flag)
756: {
757: PetscFunctionBegin;
758: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
759: PetscLogHandler h = PetscLogHandlers[i].handler;
761: if (h) PetscCall(PetscLogHandlerSetLogObjects(h, flag));
762: }
763: PetscFunctionReturn(PETSC_SUCCESS);
764: }
766: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
767: /*@
768: PetscLogStageRegister - Attaches a character string name to a logging stage.
770: Not Collective
772: Input Parameter:
773: . sname - The name to associate with that stage
775: Output Parameter:
776: . stage - The stage number or -1 if logging is not active (`PetscLogIsActive()`).
778: Level: intermediate
780: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`
781: @*/
782: PetscErrorCode PetscLogStageRegister(const char sname[], PetscLogStage *stage)
783: {
784: PetscLogState state;
786: PetscFunctionBegin;
787: *stage = -1;
788: PetscCall(PetscLogGetState(&state));
789: if (state) PetscCall(PetscLogStateStageRegister(state, sname, stage));
790: PetscFunctionReturn(PETSC_SUCCESS);
791: }
793: /*@
794: PetscLogStagePush - This function pushes a stage on the logging stack. Events started and stopped until `PetscLogStagePop()` will be associated with the stage
796: Not Collective
798: Input Parameter:
799: . stage - The stage on which to log
801: Example Usage:
802: If the option -log_view is used to run the program containing the
803: following code, then 2 sets of summary data will be printed during
804: PetscFinalize().
805: .vb
806: PetscInitialize(int *argc,char ***args,0,0);
807: [stage 0 of code]
808: PetscLogStagePush(1);
809: [stage 1 of code]
810: PetscLogStagePop();
811: PetscBarrier(...);
812: [more stage 0 of code]
813: PetscFinalize();
814: .ve
816: Level: intermediate
818: Note:
819: Use `PetscLogStageRegister()` to register a stage.
821: .seealso: [](ch_profiling), `PetscLogStagePop()`, `PetscLogStageRegister()`, `PetscBarrier()`
822: @*/
823: PetscErrorCode PetscLogStagePush(PetscLogStage stage)
824: {
825: PetscLogState state;
827: PetscFunctionBegin;
828: PetscCall(PetscLogGetState(&state));
829: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
830: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
831: PetscLogHandler h = PetscLogHandlers[i].handler;
832: if (h) PetscCall(PetscLogHandlerStagePush(h, stage));
833: }
834: PetscCall(PetscLogStateStagePush(state, stage));
835: PetscFunctionReturn(PETSC_SUCCESS);
836: }
838: /*@
839: PetscLogStagePop - This function pops a stage from the logging stack that was pushed with `PetscLogStagePush()`
841: Not Collective
843: Example Usage:
844: If the option -log_view is used to run the program containing the
845: following code, then 2 sets of summary data will be printed during
846: PetscFinalize().
847: .vb
848: PetscInitialize(int *argc,char ***args,0,0);
849: [stage 0 of code]
850: PetscLogStagePush(1);
851: [stage 1 of code]
852: PetscLogStagePop();
853: PetscBarrier(...);
854: [more stage 0 of code]
855: PetscFinalize();
856: .ve
858: Level: intermediate
860: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStageRegister()`, `PetscBarrier()`
861: @*/
862: PetscErrorCode PetscLogStagePop(void)
863: {
864: PetscLogState state;
865: PetscLogStage current_stage;
867: PetscFunctionBegin;
868: PetscCall(PetscLogGetState(&state));
869: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
870: current_stage = state->current_stage;
871: PetscCall(PetscLogStateStagePop(state));
872: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
873: PetscLogHandler h = PetscLogHandlers[i].handler;
874: if (h) PetscCall(PetscLogHandlerStagePop(h, current_stage));
875: }
876: PetscFunctionReturn(PETSC_SUCCESS);
877: }
879: /*@
880: PetscLogStageSetActive - Sets if a stage is used for `PetscLogEventBegin()` and `PetscLogEventEnd()`.
882: Not Collective
884: Input Parameters:
885: + stage - The stage
886: - isActive - The activity flag, `PETSC_TRUE` for logging, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
888: Level: intermediate
890: Note:
891: If this is set to `PETSC_FALSE` the logging acts as if the stage did not exist
893: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
894: @*/
895: PetscErrorCode PetscLogStageSetActive(PetscLogStage stage, PetscBool isActive)
896: {
897: PetscLogState state;
899: PetscFunctionBegin;
900: PetscCall(PetscLogGetState(&state));
901: if (state) PetscCall(PetscLogStateStageSetActive(state, stage, isActive));
902: PetscFunctionReturn(PETSC_SUCCESS);
903: }
905: /*@
906: PetscLogStageGetActive - Checks if a stage is used for `PetscLogEventBegin()` and `PetscLogEventEnd()`.
908: Not Collective
910: Input Parameter:
911: . stage - The stage
913: Output Parameter:
914: . isActive - The activity flag, `PETSC_TRUE` for logging, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
916: Level: intermediate
918: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
919: @*/
920: PetscErrorCode PetscLogStageGetActive(PetscLogStage stage, PetscBool *isActive)
921: {
922: PetscLogState state;
924: PetscFunctionBegin;
925: *isActive = PETSC_FALSE;
926: PetscCall(PetscLogGetState(&state));
927: if (state) PetscCall(PetscLogStateStageGetActive(state, stage, isActive));
928: PetscFunctionReturn(PETSC_SUCCESS);
929: }
931: /*@
932: PetscLogStageSetVisible - Determines stage visibility in `PetscLogView()`
934: Not Collective
936: Input Parameters:
937: + stage - The stage
938: - isVisible - The visibility flag, `PETSC_TRUE` to print, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
940: Level: intermediate
942: Developer Notes:
943: Visibility only affects the default log handler in `PetscLogView()`: stages that are
944: set to invisible are suppressed from output.
946: .seealso: [](ch_profiling), `PetscLogStageGetVisible()`, `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
947: @*/
948: PetscErrorCode PetscLogStageSetVisible(PetscLogStage stage, PetscBool isVisible)
949: {
950: PetscFunctionBegin;
951: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
952: PetscLogHandler h = PetscLogHandlers[i].handler;
954: if (h) PetscCall(PetscLogHandlerStageSetVisible(h, stage, isVisible));
955: }
956: PetscFunctionReturn(PETSC_SUCCESS);
957: }
959: /*@
960: PetscLogStageGetVisible - Returns stage visibility in `PetscLogView()`
962: Not Collective
964: Input Parameter:
965: . stage - The stage
967: Output Parameter:
968: . isVisible - The visibility flag, `PETSC_TRUE` to print, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
970: Level: intermediate
972: .seealso: [](ch_profiling), `PetscLogStageSetVisible()`, `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
973: @*/
974: PetscErrorCode PetscLogStageGetVisible(PetscLogStage stage, PetscBool *isVisible)
975: {
976: PetscLogHandler handler;
978: PetscFunctionBegin;
979: *isVisible = PETSC_FALSE;
980: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
981: if (handler) PetscCall(PetscLogHandlerStageGetVisible(handler, stage, isVisible));
982: PetscFunctionReturn(PETSC_SUCCESS);
983: }
985: /*@
986: PetscLogStageGetId - Returns the stage id when given the stage name.
988: Not Collective
990: Input Parameter:
991: . name - The stage name
993: Output Parameter:
994: . stage - The stage, , or -1 if no stage with that name exists
996: Level: intermediate
998: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
999: @*/
1000: PetscErrorCode PetscLogStageGetId(const char name[], PetscLogStage *stage)
1001: {
1002: PetscLogState state;
1004: PetscFunctionBegin;
1005: *stage = -1;
1006: PetscCall(PetscLogGetState(&state));
1007: if (state) PetscCall(PetscLogStateGetStageFromName(state, name, stage));
1008: PetscFunctionReturn(PETSC_SUCCESS);
1009: }
1011: /*@
1012: PetscLogStageGetName - Returns the stage name when given the stage id.
1014: Not Collective
1016: Input Parameter:
1017: . stage - The stage
1019: Output Parameter:
1020: . name - The stage name
1022: Level: intermediate
1024: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
1025: @*/
1026: PetscErrorCode PetscLogStageGetName(PetscLogStage stage, const char *name[])
1027: {
1028: PetscLogStageInfo stage_info;
1029: PetscLogState state;
1031: PetscFunctionBegin;
1032: *name = NULL;
1033: PetscCall(PetscLogGetState(&state));
1034: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1035: PetscCall(PetscLogStateStageGetInfo(state, stage, &stage_info));
1036: *name = stage_info.name;
1037: PetscFunctionReturn(PETSC_SUCCESS);
1038: }
1040: /*------------------------------------------------ Event Functions --------------------------------------------------*/
1042: /*@
1043: PetscLogEventRegister - Registers an event name for logging operations
1045: Not Collective
1047: Input Parameters:
1048: + name - The name associated with the event
1049: - classid - The classid associated to the class for this event, obtain either with
1050: `PetscClassIdRegister()` or use a predefined one such as `KSP_CLASSID`, `SNES_CLASSID`, the predefined ones
1051: are only available in C code
1053: Output Parameter:
1054: . event - The event id for use with `PetscLogEventBegin()` and `PetscLogEventEnd()`.
1056: Example Usage:
1057: .vb
1058: PetscLogEvent USER_EVENT;
1059: PetscClassId classid;
1060: PetscLogDouble user_event_flops;
1061: PetscClassIdRegister("class name",&classid);
1062: PetscLogEventRegister("User event name",classid,&USER_EVENT);
1063: PetscLogEventBegin(USER_EVENT,0,0,0,0);
1064: [code segment to monitor]
1065: PetscLogFlops(user_event_flops);
1066: PetscLogEventEnd(USER_EVENT,0,0,0,0);
1067: .ve
1069: Level: intermediate
1071: Notes:
1072: PETSc automatically logs library events if the code has been
1073: configured with --with-log (which is the default) and
1074: -log_view or -log_all is specified. `PetscLogEventRegister()` is
1075: intended for logging user events to supplement this PETSc
1076: information.
1078: PETSc can gather data for use with the utilities Jumpshot
1079: (part of the MPICH distribution). If PETSc has been compiled
1080: with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
1081: MPICH), the user can employ another command line option, -log_mpe,
1082: to create a logfile, "mpe.log", which can be visualized
1083: Jumpshot.
1085: The classid is associated with each event so that classes of events
1086: can be disabled simultaneously, such as all matrix events. The user
1087: can either use an existing classid, such as `MAT_CLASSID`, or create
1088: their own as shown in the example.
1090: If an existing event with the same name exists, its event handle is
1091: returned instead of creating a new event.
1093: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogFlops()`,
1094: `PetscLogEventActivate()`, `PetscLogEventDeactivate()`, `PetscClassIdRegister()`
1095: @*/
1096: PetscErrorCode PetscLogEventRegister(const char name[], PetscClassId classid, PetscLogEvent *event)
1097: {
1098: PetscLogState state;
1100: PetscFunctionBegin;
1101: *event = -1;
1102: PetscCall(PetscLogGetState(&state));
1103: if (state) PetscCall(PetscLogStateEventRegister(state, name, classid, event));
1104: PetscFunctionReturn(PETSC_SUCCESS);
1105: }
1107: /*@
1108: PetscLogEventSetCollective - Indicates that a particular event is collective.
1110: Logically Collective
1112: Input Parameters:
1113: + event - The event id
1114: - collective - `PetscBool` indicating whether a particular event is collective
1116: Level: developer
1118: Notes:
1119: New events returned from `PetscLogEventRegister()` are collective by default.
1121: Collective events are handled specially if the command line option `-log_sync` is used. In that case the logging saves information about
1122: two parts of the event; the time for all the MPI ranks to synchronize and then the time for the actual computation/communication
1123: to be performed. This option is useful to debug imbalance within the computations or communications.
1125: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventRegister()`
1126: @*/
1127: PetscErrorCode PetscLogEventSetCollective(PetscLogEvent event, PetscBool collective)
1128: {
1129: PetscLogState state;
1131: PetscFunctionBegin;
1132: PetscCall(PetscLogGetState(&state));
1133: if (state) PetscCall(PetscLogStateEventSetCollective(state, event, collective));
1134: PetscFunctionReturn(PETSC_SUCCESS);
1135: }
1137: /*
1138: PetscLogClassSetActiveAll - Activate or inactivate logging for all events associated with a PETSc object class in every stage.
1140: Not Collective
1142: Input Parameters:
1143: + classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1144: - isActive - if `PETSC_FALSE`, events associated with this class will not be send to log handlers.
1146: Level: developer
1148: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventActivateAll()`, `PetscLogStageSetActive()`, `PetscLogEventActivateClass()`
1149: */
1150: static PetscErrorCode PetscLogClassSetActiveAll(PetscClassId classid, PetscBool isActive)
1151: {
1152: PetscLogState state;
1154: PetscFunctionBegin;
1155: PetscCall(PetscLogGetState(&state));
1156: if (state) PetscCall(PetscLogStateClassSetActiveAll(state, classid, isActive));
1157: PetscFunctionReturn(PETSC_SUCCESS);
1158: }
1160: /*@
1161: PetscLogEventIncludeClass - Activates event logging for a PETSc object class in every stage.
1163: Not Collective
1165: Input Parameter:
1166: . classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1168: Level: developer
1170: .seealso: [](ch_profiling), `PetscLogEventActivateClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1171: @*/
1172: PetscErrorCode PetscLogEventIncludeClass(PetscClassId classid)
1173: {
1174: PetscFunctionBegin;
1175: PetscCall(PetscLogClassSetActiveAll(classid, PETSC_TRUE));
1176: PetscFunctionReturn(PETSC_SUCCESS);
1177: }
1179: /*@
1180: PetscLogEventExcludeClass - Deactivates event logging for a PETSc object class in every stage.
1182: Not Collective
1184: Input Parameter:
1185: . classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1187: Level: developer
1189: Note:
1190: If a class is excluded then events associated with that class are not logged.
1192: .seealso: [](ch_profiling), `PetscLogEventDeactivateClass()`, `PetscLogEventActivateClass()`, `PetscLogEventDeactivate()`, `PetscLogEventActivate()`
1193: @*/
1194: PetscErrorCode PetscLogEventExcludeClass(PetscClassId classid)
1195: {
1196: PetscFunctionBegin;
1197: PetscCall(PetscLogClassSetActiveAll(classid, PETSC_FALSE));
1198: PetscFunctionReturn(PETSC_SUCCESS);
1199: }
1201: /*
1202: PetscLogEventSetActive - Activate or inactivate logging for an event in a given stage
1204: Not Collective
1206: Input Parameters:
1207: + stage - A registered `PetscLogStage` (or `PETSC_DEFAULT` for the current stage)
1208: . event - A `PetscLogEvent`
1209: - isActive - If `PETSC_FALSE`, activity from this event (`PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventSync()`) will not be sent to log handlers during this stage
1211: Usage:
1212: .vb
1213: PetscLogEventSetActive(VEC_SetValues, PETSC_FALSE);
1214: [code where you do not want to log VecSetValues()]
1215: PetscLogEventSetActive(VEC_SetValues, PETSC_TRUE);
1216: [code where you do want to log VecSetValues()]
1217: .ve
1219: Level: advanced
1221: Note:
1222: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
1223: or an event number obtained with `PetscLogEventRegister()`.
1225: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1226: */
1227: static PetscErrorCode PetscLogEventSetActive(PetscLogStage stage, PetscLogEvent event, PetscBool isActive)
1228: {
1229: PetscLogState state;
1231: PetscFunctionBegin;
1232: PetscCall(PetscLogGetState(&state));
1233: if (state) PetscCall(PetscLogStateEventSetActive(state, stage, event, isActive));
1234: PetscFunctionReturn(PETSC_SUCCESS);
1235: }
1237: /*@
1238: PetscLogEventActivate - Indicates that a particular event should be logged.
1240: Not Collective
1242: Input Parameter:
1243: . event - The event id
1245: Example Usage:
1246: .vb
1247: PetscLogEventDeactivate(VEC_SetValues);
1248: [code where you do not want to log VecSetValues()]
1249: PetscLogEventActivate(VEC_SetValues);
1250: [code where you do want to log VecSetValues()]
1251: .ve
1253: Level: advanced
1255: Note:
1256: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
1257: or an event number obtained with `PetscLogEventRegister()`.
1259: .seealso: [](ch_profiling), `PetscLogEventDeactivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1260: @*/
1261: PetscErrorCode PetscLogEventActivate(PetscLogEvent event)
1262: {
1263: PetscFunctionBegin;
1264: PetscCall(PetscLogEventSetActive(PETSC_DEFAULT, event, PETSC_TRUE));
1265: PetscFunctionReturn(PETSC_SUCCESS);
1266: }
1268: /*@
1269: PetscLogEventDeactivate - Indicates that a particular event should not be logged.
1271: Not Collective
1273: Input Parameter:
1274: . event - The event id
1276: Example Usage:
1277: .vb
1278: PetscLogEventDeactivate(VEC_SetValues);
1279: [code where you do not want to log VecSetValues()]
1280: PetscLogEventActivate(VEC_SetValues);
1281: [code where you do want to log VecSetValues()]
1282: .ve
1284: Level: advanced
1286: Note:
1287: The event may be either a pre-defined PETSc event (found in
1288: include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1290: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1291: @*/
1292: PetscErrorCode PetscLogEventDeactivate(PetscLogEvent event)
1293: {
1294: PetscFunctionBegin;
1295: PetscCall(PetscLogEventSetActive(PETSC_DEFAULT, event, PETSC_FALSE));
1296: PetscFunctionReturn(PETSC_SUCCESS);
1297: }
1299: /*@
1300: PetscLogEventDeactivatePush - Indicates that a particular event should not be logged until `PetscLogEventDeactivatePop()` is called
1302: Not Collective
1304: Input Parameter:
1305: . event - The event id
1307: Example Usage:
1308: .vb
1309: PetscLogEventDeactivatePush(VEC_SetValues);
1310: [code where you do not want to log VecSetValues()]
1311: PetscLogEventDeactivatePop(VEC_SetValues);
1312: [code where you do want to log VecSetValues()]
1313: .ve
1315: Level: advanced
1317: Note:
1318: The event may be either a pre-defined PETSc event (found in
1319: include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1321: 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.
1323: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivate()`, `PetscLogEventDeactivatePop()`
1324: @*/
1325: PetscErrorCode PetscLogEventDeactivatePush(PetscLogEvent event)
1326: {
1327: PetscFunctionBegin;
1328: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1329: PetscLogHandler h = PetscLogHandlers[i].handler;
1331: if (h) PetscCall(PetscLogHandlerEventDeactivatePush(h, PETSC_DEFAULT, event));
1332: }
1333: PetscFunctionReturn(PETSC_SUCCESS);
1334: }
1336: /*@
1337: PetscLogEventDeactivatePop - Indicates that a particular event should again be logged after the logging was turned off with `PetscLogEventDeactivatePush()`
1339: Not Collective
1341: Input Parameter:
1342: . event - The event id
1344: Example Usage:
1345: .vb
1346: PetscLogEventDeactivatePush(VEC_SetValues);
1347: [code where you do not want to log VecSetValues()]
1348: PetscLogEventDeactivatePop(VEC_SetValues);
1349: [code where you do want to log VecSetValues()]
1350: .ve
1352: Level: advanced
1354: Note:
1355: The event may be either a pre-defined PETSc event (found in
1356: include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1358: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`
1359: @*/
1360: PetscErrorCode PetscLogEventDeactivatePop(PetscLogEvent event)
1361: {
1362: PetscFunctionBegin;
1363: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1364: PetscLogHandler h = PetscLogHandlers[i].handler;
1366: if (h) PetscCall(PetscLogHandlerEventDeactivatePop(h, PETSC_DEFAULT, event));
1367: }
1368: PetscFunctionReturn(PETSC_SUCCESS);
1369: }
1371: /*@
1372: PetscLogEventSetActiveAll - Turns on logging of all events
1374: Not Collective
1376: Input Parameters:
1377: + event - The event id
1378: - isActive - The activity flag determining whether the event is logged
1380: Level: advanced
1382: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1383: @*/
1384: PetscErrorCode PetscLogEventSetActiveAll(PetscLogEvent event, PetscBool isActive)
1385: {
1386: PetscLogState state;
1388: PetscFunctionBegin;
1389: PetscCall(PetscLogGetState(&state));
1390: if (state) PetscCall(PetscLogStateEventSetActiveAll(state, event, isActive));
1391: PetscFunctionReturn(PETSC_SUCCESS);
1392: }
1394: /*
1395: PetscLogClassSetActive - Activates event logging for a PETSc object class for the current stage
1397: Not Collective
1399: Input Parameters:
1400: + stage - A registered `PetscLogStage` (or `PETSC_DEFAULT` for the current stage)
1401: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1402: - isActive - If `PETSC_FALSE`, events associated with this class are not sent to log handlers.
1404: Level: developer
1406: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventActivate()`, `PetscLogEventActivateAll()`, `PetscLogStageSetActive()`
1407: */
1408: static PetscErrorCode PetscLogClassSetActive(PetscLogStage stage, PetscClassId classid, PetscBool isActive)
1409: {
1410: PetscLogState state;
1412: PetscFunctionBegin;
1413: PetscCall(PetscLogGetState(&state));
1414: if (state) PetscCall(PetscLogStateClassSetActive(state, stage, classid, isActive));
1415: PetscFunctionReturn(PETSC_SUCCESS);
1416: }
1418: /*@
1419: PetscLogEventActivateClass - Activates event logging for a PETSc object class for the current stage
1421: Not Collective
1423: Input Parameter:
1424: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1426: Level: developer
1428: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1429: @*/
1430: PetscErrorCode PetscLogEventActivateClass(PetscClassId classid)
1431: {
1432: PetscFunctionBegin;
1433: PetscCall(PetscLogClassSetActive(PETSC_DEFAULT, classid, PETSC_TRUE));
1434: PetscFunctionReturn(PETSC_SUCCESS);
1435: }
1437: /*@
1438: PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class for the current stage
1440: Not Collective
1442: Input Parameter:
1443: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1445: Level: developer
1447: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventActivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1448: @*/
1449: PetscErrorCode PetscLogEventDeactivateClass(PetscClassId classid)
1450: {
1451: PetscFunctionBegin;
1452: PetscCall(PetscLogClassSetActive(PETSC_DEFAULT, classid, PETSC_FALSE));
1453: PetscFunctionReturn(PETSC_SUCCESS);
1454: }
1456: /*MC
1457: PetscLogEventSync - Synchronizes the beginning of a user event.
1459: Synopsis:
1460: #include <petsclog.h>
1461: PetscErrorCode PetscLogEventSync(PetscLogEvent e, MPI_Comm comm)
1463: Collective
1465: Input Parameters:
1466: + e - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1467: - comm - an MPI communicator
1469: Example Usage:
1470: .vb
1471: PetscLogEvent USER_EVENT;
1473: PetscLogEventRegister("User event", 0, &USER_EVENT);
1474: PetscLogEventSync(USER_EVENT, PETSC_COMM_WORLD);
1475: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1476: [code segment to monitor]
1477: PetscLogEventEnd(USER_EVENT, 0, 0, 0 , 0);
1478: .ve
1480: Level: developer
1482: Note:
1483: This routine should be called only if there is not a `PetscObject` available to pass to
1484: `PetscLogEventBegin()`.
1486: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`
1487: M*/
1489: /*MC
1490: PetscLogEventBegin - Logs the beginning of a user event.
1492: Synopsis:
1493: #include <petsclog.h>
1494: PetscErrorCode PetscLogEventBegin(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
1496: Not Collective
1498: Input Parameters:
1499: + e - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1500: . o1 - object associated with the event, or `NULL`
1501: . o2 - object associated with the event, or `NULL`
1502: . o3 - object associated with the event, or `NULL`
1503: - o4 - object associated with the event, or `NULL`
1505: Fortran Synopsis:
1506: void PetscLogEventBegin(int e, PetscErrorCode ierr)
1508: Example Usage:
1509: .vb
1510: PetscLogEvent USER_EVENT;
1512: PetscLogDouble user_event_flops;
1513: PetscLogEventRegister("User event",0, &USER_EVENT);
1514: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1515: [code segment to monitor]
1516: PetscLogFlops(user_event_flops);
1517: PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
1518: .ve
1520: Level: intermediate
1522: Developer Note:
1523: `PetscLogEventBegin()` and `PetscLogEventBegin()` return error codes instead of explicitly
1524: handling the errors that occur in the macro directly because other packages that use this
1525: macros have used them in their own functions or methods that do not return error codes and it
1526: would be disruptive to change the current behavior.
1528: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventEnd()`, `PetscLogFlops()`
1529: M*/
1531: /*MC
1532: PetscLogEventEnd - Log the end of a user event.
1534: Synopsis:
1535: #include <petsclog.h>
1536: PetscErrorCode PetscLogEventEnd(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
1538: Not Collective
1540: Input Parameters:
1541: + e - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1542: . o1 - object associated with the event, or `NULL`
1543: . o2 - object associated with the event, or `NULL`
1544: . o3 - object associated with the event, or `NULL`
1545: - o4 - object associated with the event, or `NULL`
1547: Fortran Synopsis:
1548: void PetscLogEventEnd(int e, PetscErrorCode ierr)
1550: Example Usage:
1551: .vb
1552: PetscLogEvent USER_EVENT;
1554: PetscLogDouble user_event_flops;
1555: PetscLogEventRegister("User event", 0, &USER_EVENT);
1556: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1557: [code segment to monitor]
1558: PetscLogFlops(user_event_flops);
1559: PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
1560: .ve
1562: Level: intermediate
1564: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogFlops()`
1565: M*/
1567: /*@C
1568: PetscLogStageGetPerfInfo - Return the performance information about the given stage
1570: No Fortran Support
1572: Input Parameters:
1573: . stage - The stage number or `PETSC_DETERMINE` for the current stage
1575: Output Parameter:
1576: . info - This structure is filled with the performance information
1578: Level: intermediate
1580: Notes:
1581: This is a low level routine used by the logging functions in PETSc.
1583: A `PETSCLOGHANDLERDEFAULT` must be running for this to work, having been started either with
1584: `PetscLogDefaultBegin()` or from the command line with `-log_view`. If it was not started,
1585: all performance statistics in `info` will be zeroed.
1587: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1588: @*/
1589: PetscErrorCode PetscLogStageGetPerfInfo(PetscLogStage stage, PetscEventPerfInfo *info)
1590: {
1591: PetscLogHandler handler;
1592: PetscEventPerfInfo *event_info;
1594: PetscFunctionBegin;
1595: PetscAssertPointer(info, 2);
1596: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1597: if (handler) {
1598: PetscCall(PetscLogHandlerGetStagePerfInfo(handler, stage, &event_info));
1599: *info = *event_info;
1600: } else {
1601: PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogStageGetPerfInfo() returning zeros\n"));
1602: PetscCall(PetscMemzero(info, sizeof(*info)));
1603: }
1604: PetscFunctionReturn(PETSC_SUCCESS);
1605: }
1607: /*@C
1608: PetscLogEventGetPerfInfo - Return the performance information about the given event in the given stage
1610: No Fortran Support
1612: Input Parameters:
1613: + stage - The stage number or `PETSC_DETERMINE` for the current stage
1614: - event - The event number
1616: Output Parameter:
1617: . info - This structure is filled with the performance information
1619: Level: intermediate
1621: Note:
1622: This is a low level routine used by the logging functions in PETSc
1624: A `PETSCLOGHANDLERDEFAULT` must be running for this to work, having been started either with
1625: `PetscLogDefaultBegin()` or from the command line with `-log_view`. If it was not started,
1626: all performance statistics in `info` will be zeroed.
1628: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1629: @*/
1630: PetscErrorCode PetscLogEventGetPerfInfo(PetscLogStage stage, PetscLogEvent event, PetscEventPerfInfo *info)
1631: {
1632: PetscLogHandler handler;
1633: PetscEventPerfInfo *event_info;
1635: PetscFunctionBegin;
1636: PetscAssertPointer(info, 3);
1637: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1638: if (handler) {
1639: PetscCall(PetscLogHandlerGetEventPerfInfo(handler, stage, event, &event_info));
1640: *info = *event_info;
1641: } else {
1642: PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogEventGetPerfInfo() returning zeros\n"));
1643: PetscCall(PetscMemzero(info, sizeof(*info)));
1644: }
1645: PetscFunctionReturn(PETSC_SUCCESS);
1646: }
1648: /*@
1649: PetscLogEventSetDof - Set the nth number of degrees of freedom of a numerical problem associated with this event
1651: Not Collective
1653: Input Parameters:
1654: + event - The event id to log
1655: . n - The dof index, in [0, 8)
1656: - dof - The number of dofs
1658: Options Database Key:
1659: . -log_view - Activates log summary
1661: Level: developer
1663: Note:
1664: This is to enable logging of convergence
1666: .seealso: `PetscLogEventSetError()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1667: @*/
1668: PetscErrorCode PetscLogEventSetDof(PetscLogEvent event, PetscInt n, PetscLogDouble dof)
1669: {
1670: PetscFunctionBegin;
1671: PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1672: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1673: PetscLogHandler h = PetscLogHandlers[i].handler;
1675: if (h) {
1676: PetscEventPerfInfo *event_info;
1678: PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1679: if (event_info) event_info->dof[n] = dof;
1680: }
1681: }
1682: PetscFunctionReturn(PETSC_SUCCESS);
1683: }
1685: /*@
1686: PetscLogEventSetError - Set the nth error associated with a numerical problem associated with this event
1688: Not Collective
1690: Input Parameters:
1691: + event - The event id to log
1692: . n - The error index, in [0, 8)
1693: - error - The error
1695: Options Database Key:
1696: . -log_view - Activates log summary
1698: Level: developer
1700: Notes:
1701: This is to enable logging of convergence, and enable users to interpret the errors as they wish. For example,
1702: as different norms, or as errors for different fields
1704: This is a low level routine used by the logging functions in PETSc
1706: .seealso: `PetscLogEventSetDof()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1707: @*/
1708: PetscErrorCode PetscLogEventSetError(PetscLogEvent event, PetscInt n, PetscLogDouble error)
1709: {
1710: PetscFunctionBegin;
1711: PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1712: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1713: PetscLogHandler h = PetscLogHandlers[i].handler;
1715: if (h) {
1716: PetscEventPerfInfo *event_info;
1718: PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1719: if (event_info) event_info->errors[n] = error;
1720: }
1721: }
1722: PetscFunctionReturn(PETSC_SUCCESS);
1723: }
1725: /*@
1726: PetscLogEventGetId - Returns the event id when given the event name.
1728: Not Collective
1730: Input Parameter:
1731: . name - The event name
1733: Output Parameter:
1734: . event - The event, or -1 if no event with that name exists
1736: Level: intermediate
1738: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1739: @*/
1740: PetscErrorCode PetscLogEventGetId(const char name[], PetscLogEvent *event)
1741: {
1742: PetscLogState state;
1744: PetscFunctionBegin;
1745: *event = -1;
1746: PetscCall(PetscLogGetState(&state));
1747: if (state) PetscCall(PetscLogStateGetEventFromName(state, name, event));
1748: PetscFunctionReturn(PETSC_SUCCESS);
1749: }
1751: /*@
1752: PetscLogEventGetName - Returns the event name when given the event id.
1754: Not Collective
1756: Input Parameter:
1757: . event - The event
1759: Output Parameter:
1760: . name - The event name
1762: Level: intermediate
1764: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
1765: @*/
1766: PetscErrorCode PetscLogEventGetName(PetscLogEvent event, const char *name[])
1767: {
1768: PetscLogEventInfo event_info;
1769: PetscLogState state;
1771: PetscFunctionBegin;
1772: *name = NULL;
1773: PetscCall(PetscLogGetState(&state));
1774: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1775: PetscCall(PetscLogStateEventGetInfo(state, event, &event_info));
1776: *name = event_info.name;
1777: PetscFunctionReturn(PETSC_SUCCESS);
1778: }
1780: /*@
1781: 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.
1783: Not collective
1785: Level: advanced
1787: Notes:
1788: 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()`).
1790: Other log handlers (such as the nested handler, `PetscLogNestedBegin()`) will ignore this function.
1792: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsResume()`, `PetscLogGetDefaultHandler()`
1793: @*/
1794: PetscErrorCode PetscLogEventsPause(void)
1795: {
1796: PetscFunctionBegin;
1797: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1798: PetscLogHandler h = PetscLogHandlers[i].handler;
1800: if (h) PetscCall(PetscLogHandlerEventsPause(h));
1801: }
1802: PetscFunctionReturn(PETSC_SUCCESS);
1803: }
1805: /*@
1806: PetscLogEventsResume - Return logging to normal behavior after it was paused with `PetscLogEventsPause()`.
1808: Not collective
1810: Level: advanced
1812: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsPause()`, `PetscLogGetDefaultHandler()`
1813: @*/
1814: PetscErrorCode PetscLogEventsResume(void)
1815: {
1816: PetscFunctionBegin;
1817: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1818: PetscLogHandler h = PetscLogHandlers[i].handler;
1820: if (h) PetscCall(PetscLogHandlerEventsResume(h));
1821: }
1822: PetscFunctionReturn(PETSC_SUCCESS);
1823: }
1825: /*------------------------------------------------ Class Functions --------------------------------------------------*/
1827: /*MC
1828: PetscLogObjectCreate - Log the creation of a `PetscObject`
1830: Synopsis:
1831: #include <petsclog.h>
1832: PetscErrorCode PetscLogObjectCreate(PetscObject h)
1834: Not Collective
1836: Input Parameters:
1837: . h - A `PetscObject`
1839: Level: developer
1841: Developer Note:
1842: Called internally by PETSc when creating objects: users do not need to call this directly.
1843: Notification of the object creation is sent to each `PetscLogHandler` that is running.
1845: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectDestroy()`
1846: M*/
1848: /*MC
1849: PetscLogObjectDestroy - Logs the destruction of a `PetscObject`
1851: Synopsis:
1852: #include <petsclog.h>
1853: PetscErrorCode PetscLogObjectDestroy(PetscObject h)
1855: Not Collective
1857: Input Parameters:
1858: . h - A `PetscObject`
1860: Level: developer
1862: Developer Note:
1863: Called internally by PETSc when destroying objects: users do not need to call this directly.
1864: Notification of the object creation is sent to each `PetscLogHandler` that is running.
1866: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectCreate()`
1867: M*/
1869: /*@
1870: PetscLogClassGetClassId - Returns the `PetscClassId` when given the class name.
1872: Not Collective
1874: Input Parameter:
1875: . name - The class name
1877: Output Parameter:
1878: . classid - The `PetscClassId` id, or -1 if no class with that name exists
1880: Level: intermediate
1882: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1883: @*/
1884: PetscErrorCode PetscLogClassGetClassId(const char name[], PetscClassId *classid)
1885: {
1886: PetscLogClass log_class;
1887: PetscLogClassInfo class_info;
1888: PetscLogState state;
1890: PetscFunctionBegin;
1891: *classid = -1;
1892: PetscCall(PetscLogGetState(&state));
1893: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1894: PetscCall(PetscLogStateGetClassFromName(state, name, &log_class));
1895: if (log_class < 0) {
1896: *classid = -1;
1897: PetscFunctionReturn(PETSC_SUCCESS);
1898: }
1899: PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1900: *classid = class_info.classid;
1901: PetscFunctionReturn(PETSC_SUCCESS);
1902: }
1904: /*@C
1905: PetscLogClassIdGetName - Returns a `PetscClassId`'s name.
1907: Not Collective
1909: Input Parameter:
1910: . classid - A `PetscClassId`
1912: Output Parameter:
1913: . name - The class name
1915: Level: intermediate
1917: .seealso: [](ch_profiling), `PetscLogClassRegister()`, `PetscLogClassBegin()`, `PetscLogClassEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadClass()`
1918: @*/
1919: PetscErrorCode PetscLogClassIdGetName(PetscClassId classid, const char **name)
1920: {
1921: PetscLogClass log_class;
1922: PetscLogClassInfo class_info;
1923: PetscLogState state;
1925: PetscFunctionBegin;
1926: PetscCall(PetscLogGetState(&state));
1927: PetscCall(PetscLogStateGetClassFromClassId(state, classid, &log_class));
1928: PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1929: *name = class_info.name;
1930: PetscFunctionReturn(PETSC_SUCCESS);
1931: }
1933: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1934: /*@
1935: PetscLogDump - Dumps logs of objects to a file. This file is intended to
1936: be read by bin/petscview. This program no longer exists.
1938: Collective on `PETSC_COMM_WORLD`
1940: Input Parameter:
1941: . sname - an optional file name
1943: Example Usage:
1944: .vb
1945: PetscInitialize(...);
1946: PetscLogDefaultBegin();
1947: // ... code ...
1948: PetscLogDump(filename);
1949: PetscFinalize();
1950: .ve
1952: Level: advanced
1954: Note:
1955: The default file name is Log.<rank> where <rank> is the MPI process rank. If no name is specified,
1956: this file will be used.
1958: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
1959: @*/
1960: PetscErrorCode PetscLogDump(const char sname[])
1961: {
1962: PetscLogHandler handler;
1964: PetscFunctionBegin;
1965: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1966: PetscCall(PetscLogHandlerDump(handler, sname));
1967: PetscFunctionReturn(PETSC_SUCCESS);
1968: }
1970: /*@
1971: PetscLogMPEDump - Dumps the MPE logging info to file for later use with Jumpshot.
1973: Collective on `PETSC_COMM_WORLD`
1975: Input Parameter:
1976: . sname - filename for the MPE logfile
1978: Level: advanced
1980: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogMPEBegin()`
1981: @*/
1982: PetscErrorCode PetscLogMPEDump(const char sname[])
1983: {
1984: PetscFunctionBegin;
1985: #if defined(PETSC_HAVE_MPE)
1986: if (PetscBeganMPE) {
1987: char name[PETSC_MAX_PATH_LEN];
1989: PetscCall(PetscInfo(0, "Finalizing MPE.\n"));
1990: if (sname) {
1991: PetscCall(PetscStrncpy(name, sname, sizeof(name)));
1992: } else {
1993: PetscCall(PetscGetProgramName(name, sizeof(name)));
1994: }
1995: PetscCall(MPE_Finish_log(name));
1996: } else {
1997: PetscCall(PetscInfo(0, "Not finalizing MPE (not started by PETSc).\n"));
1998: }
1999: #else
2000: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe");
2001: #endif
2002: PetscFunctionReturn(PETSC_SUCCESS);
2003: }
2005: /*@
2006: PetscLogView - Prints a summary of the logging.
2008: Collective
2010: Input Parameter:
2011: . viewer - an ASCII viewer
2013: Options Database Keys:
2014: + -log_view [:filename] - Prints summary of log information
2015: . -log_view :filename.py:ascii_info_detail - Saves logging information from each process as a Python file
2016: . -log_view :filename.xml:ascii_xml - Saves a summary of the logging information in a nested format (see below for how to view it)
2017: . -log_view :filename.txt:ascii_flamegraph - Saves logging information in a format suitable for visualising as a Flame Graph (see below for how to view it)
2018: . -log_view_memory - Also display memory usage in each event
2019: . -log_view_gpu_time - Also display time in each event for GPU kernels (Note this may slow the computation)
2020: . -log_view_gpu_energy - Also display energy (estimated with power*gtime) in Joules for GPU kernels
2021: . -log_view_gpu_energy_meter - [Experimental] Also display energy (readings from energy meters) in Joules for GPU kernels. This option is ignored if -log_view_gpu_energy is provided.
2022: . -log_all - Saves a file Log.rank for each MPI rank with details of each step of the computation
2023: - -log_trace [filename] - Displays a trace of what each process is doing
2025: Level: beginner
2027: Notes:
2028: It is possible to control the logging programmatically but we recommend using the options database approach whenever possible
2029: By default the summary is printed to stdout.
2031: Before calling this routine you must have called either PetscLogDefaultBegin() or PetscLogNestedBegin()
2033: If PETSc is configured with --with-log=0 then this functionality is not available
2035: To view the nested XML format filename.xml first copy ${PETSC_DIR}/share/petsc/xml/performance_xml2html.xsl to the current
2036: directory then open filename.xml with your browser. Specific notes for certain browsers
2037: .vb
2038: Firefox and Internet explorer - simply open the file
2039: Google Chrome - you must start up Chrome with the option --allow-file-access-from-files
2040: Safari - see https://ccm.net/faq/36342-safari-how-to-enable-local-file-access
2041: .ve
2042: or one can use the package <http://xmlsoft.org/XSLT/xsltproc2.html> to translate the xml file to html and then open it with
2043: your browser.
2044: Alternatively, use the script ${PETSC_DIR}/lib/petsc/bin/petsc-performance-view to automatically open a new browser
2045: window and render the XML log file contents.
2047: The nested XML format was kindly donated by Koos Huijssen and Christiaan M. Klaij MARITIME RESEARCH INSTITUTE NETHERLANDS
2049: The Flame Graph output can be visualised using either the original Flame Graph script <https://github.com/brendangregg/FlameGraph>
2050: or using speedscope <https://www.speedscope.app>.
2051: Old XML profiles may be converted into this format using the script ${PETSC_DIR}/lib/petsc/bin/xml2flamegraph.py.
2053: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogDump()`
2054: @*/
2055: PetscErrorCode PetscLogView(PetscViewer viewer)
2056: {
2057: PetscBool isascii;
2058: PetscViewerFormat format;
2059: int stage;
2060: PetscLogState state;
2061: PetscIntStack temp_stack;
2062: PetscLogHandler handler;
2063: PetscBool is_empty;
2065: PetscFunctionBegin;
2066: PetscCall(PetscLogGetState(&state));
2067: /* Pop off any stages the user forgot to remove */
2068: PetscCall(PetscIntStackCreate(&temp_stack));
2069: PetscCall(PetscLogStateGetCurrentStage(state, &stage));
2070: while (stage >= 0) {
2071: PetscCall(PetscLogStagePop());
2072: PetscCall(PetscIntStackPush(temp_stack, stage));
2073: PetscCall(PetscLogStateGetCurrentStage(state, &stage));
2074: }
2075: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
2076: PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Currently can only view logging to ASCII");
2077: PetscCall(PetscViewerGetFormat(viewer, &format));
2078: if (format == PETSC_VIEWER_ASCII_XML || format == PETSC_VIEWER_ASCII_FLAMEGRAPH) {
2079: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERNESTED, &handler));
2080: PetscCall(PetscLogHandlerView(handler, viewer));
2081: } else {
2082: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
2083: PetscCall(PetscLogHandlerView(handler, viewer));
2084: }
2085: PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
2086: while (!is_empty) {
2087: PetscCall(PetscIntStackPop(temp_stack, &stage));
2088: PetscCall(PetscLogStagePush(stage));
2089: PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
2090: }
2091: PetscCall(PetscIntStackDestroy(temp_stack));
2092: PetscFunctionReturn(PETSC_SUCCESS);
2093: }
2095: /*@C
2096: PetscLogViewFromOptions - Processes command line options to determine if/how a `PetscLog` is to be viewed.
2098: Collective on `PETSC_COMM_WORLD`
2100: Level: developer
2102: Note:
2103: This function has a different API and behavior than `PetscObjectViewFromOptions()`
2105: .seealso: [](ch_profiling), `PetscLogView()`
2106: @*/
2107: PetscErrorCode PetscLogViewFromOptions(void)
2108: {
2109: PetscInt n_max = PETSC_LOG_VIEW_FROM_OPTIONS_MAX;
2110: PetscViewer viewers[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2111: PetscViewerFormat formats[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2112: PetscBool flg;
2114: PetscFunctionBegin;
2115: PetscCall(PetscOptionsCreateViewers(PETSC_COMM_WORLD, NULL, NULL, "-log_view", &n_max, viewers, formats, &flg));
2116: /*
2117: PetscLogHandlerView_Default_Info() wants to be sure that the only objects still around are these viewers, so keep track of how many there are
2118: */
2119: PetscLogNumViewersCreated = n_max;
2120: for (PetscInt i = 0; i < n_max; i++) {
2121: PetscInt refct;
2123: PetscCall(PetscViewerPushFormat(viewers[i], formats[i]));
2124: PetscCall(PetscLogView(viewers[i]));
2125: PetscCall(PetscViewerPopFormat(viewers[i]));
2126: PetscCall(PetscObjectGetReference((PetscObject)viewers[i], &refct));
2127: PetscCall(PetscViewerDestroy(&viewers[i]));
2128: if (refct == 1) PetscLogNumViewersDestroyed++;
2129: }
2130: PetscLogNumViewersDestroyed = 0;
2131: PetscFunctionReturn(PETSC_SUCCESS);
2132: }
2134: PETSC_INTERN PetscErrorCode PetscLogHandlerNestedSetThreshold(PetscLogHandler, PetscLogDouble, PetscLogDouble *);
2136: /*@
2137: PetscLogSetThreshold - Set the threshold time for logging the events; this is a percentage out of 100, so 1. means any event
2138: that takes 1 or more percent of the time.
2140: Logically Collective on `PETSC_COMM_WORLD`
2142: Input Parameter:
2143: . newThresh - the threshold to use
2145: Output Parameter:
2146: . oldThresh - the previously set threshold value
2148: Options Database Keys:
2149: . -log_view :filename.xml:ascii_xml - Prints an XML summary of flop and timing information to the file
2151: Example Usage:
2152: .vb
2153: PetscInitialize(...);
2154: PetscLogNestedBegin();
2155: PetscLogSetThreshold(0.1,&oldthresh);
2156: // ... code ...
2157: PetscLogView(viewer);
2158: PetscFinalize();
2159: .ve
2161: Level: advanced
2163: Note:
2164: This threshold is only used by the nested log handler
2166: .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`,
2167: `PetscLogNestedBegin()`
2168: @*/
2169: PetscErrorCode PetscLogSetThreshold(PetscLogDouble newThresh, PetscLogDouble *oldThresh)
2170: {
2171: PetscLogHandler handler;
2173: PetscFunctionBegin;
2174: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERNESTED, &handler));
2175: PetscCall(PetscLogHandlerNestedSetThreshold(handler, newThresh, oldThresh));
2176: PetscFunctionReturn(PETSC_SUCCESS);
2177: }
2179: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
2180: /*@
2181: PetscGetFlops - Returns the number of flops used on this processor
2182: since the program began.
2184: Not Collective
2186: Output Parameter:
2187: . flops - number of floating point operations
2189: Level: intermediate
2191: Notes:
2192: A global counter logs all PETSc flop counts. The user can use
2193: `PetscLogFlops()` to increment this counter to include flops for the
2194: application code.
2196: A separate counter `PetscLogGpuFlops()` logs the flops that occur on any GPU associated with this MPI rank
2198: .seealso: [](ch_profiling), `PetscLogGpuFlops()`, `PetscTime()`, `PetscLogFlops()`
2199: @*/
2200: PetscErrorCode PetscGetFlops(PetscLogDouble *flops)
2201: {
2202: PetscFunctionBegin;
2203: *flops = petsc_TotalFlops;
2204: PetscFunctionReturn(PETSC_SUCCESS);
2205: }
2207: /*@C
2208: PetscLogObjectState - Record information about an object with the default log handler
2210: Not Collective
2212: Input Parameters:
2213: + obj - the `PetscObject`
2214: . format - a printf-style format string
2215: - ... - printf arguments to format
2217: Level: developer
2219: .seealso: [](ch_profiling), `PetscLogObjectCreate()`, `PetscLogObjectDestroy()`, `PetscLogGetDefaultHandler()`
2220: @*/
2221: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
2222: {
2223: PetscFunctionBegin;
2224: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2225: PetscLogHandler h = PetscLogHandlers[i].handler;
2227: if (h) {
2228: va_list Argp;
2229: va_start(Argp, format);
2230: PetscCall(PetscLogHandlerLogObjectState_Internal(h, obj, format, Argp));
2231: va_end(Argp);
2232: }
2233: }
2234: PetscFunctionReturn(PETSC_SUCCESS);
2235: }
2237: /*MC
2238: PetscLogFlops - Adds floating point operations to the global counter.
2240: Synopsis:
2241: #include <petsclog.h>
2242: PetscErrorCode PetscLogFlops(PetscLogDouble f)
2244: Not Collective
2246: Input Parameter:
2247: . f - flop counter
2249: Example Usage:
2250: .vb
2251: PetscLogEvent USER_EVENT;
2253: PetscLogEventRegister("User event", 0, &USER_EVENT);
2254: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
2255: [code segment to monitor]
2256: PetscLogFlops(user_flops)
2257: PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
2258: .ve
2260: Level: intermediate
2262: Note:
2263: A global counter logs all PETSc flop counts. The user can use PetscLogFlops() to increment
2264: this counter to include flops for the application code.
2266: .seealso: [](ch_profiling), `PetscLogGpuFlops()`, `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscGetFlops()`
2267: M*/
2269: /*MC
2270: PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice) to get accurate
2271: timings
2273: Synopsis:
2274: #include <petsclog.h>
2275: void PetscPreLoadBegin(PetscBool flag, char *name);
2277: Not Collective
2279: Input Parameters:
2280: + flag - `PETSC_TRUE` to run twice, `PETSC_FALSE` to run once, may be overridden with command
2281: line option `-preload true|false`
2282: - name - name of first stage (lines of code timed separately with `-log_view`) to be preloaded
2284: Example Usage:
2285: .vb
2286: PetscPreLoadBegin(PETSC_TRUE, "first stage");
2287: // lines of code
2288: PetscPreLoadStage("second stage");
2289: // lines of code
2290: PetscPreLoadEnd();
2291: .ve
2293: Level: intermediate
2295: Note:
2296: Only works in C/C++, not Fortran
2298: Flags available within the macro\:
2299: + PetscPreLoadingUsed - `PETSC_TRUE` if we are or have done preloading
2300: . PetscPreLoadingOn - `PETSC_TRUE` if it is CURRENTLY doing preload
2301: . PetscPreLoadIt - `0` for the first computation (with preloading turned off it is only
2302: `0`) `1` for the second
2303: - PetscPreLoadMax - number of times it will do the computation, only one when preloading is
2304: turned on
2306: The first two variables are available throughout the program, the second two only between the
2307: `PetscPreLoadBegin()` and `PetscPreLoadEnd()`
2309: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
2310: M*/
2312: /*MC
2313: PetscPreLoadEnd - End a segment of code that may be preloaded (run twice) to get accurate
2314: timings
2316: Synopsis:
2317: #include <petsclog.h>
2318: void PetscPreLoadEnd(void);
2320: Not Collective
2322: Example Usage:
2323: .vb
2324: PetscPreLoadBegin(PETSC_TRUE, "first stage");
2325: // lines of code
2326: PetscPreLoadStage("second stage");
2327: // lines of code
2328: PetscPreLoadEnd();
2329: .ve
2331: Level: intermediate
2333: Note:
2334: Only works in C/C++ not Fortran
2336: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadStage()`
2337: M*/
2339: /*MC
2340: PetscPreLoadStage - Start a new segment of code to be timed separately to get accurate timings
2342: Synopsis:
2343: #include <petsclog.h>
2344: void PetscPreLoadStage(char *name);
2346: Not Collective
2348: Example Usage:
2349: .vb
2350: PetscPreLoadBegin(PETSC_TRUE,"first stage");
2351: // lines of code
2352: PetscPreLoadStage("second stage");
2353: // lines of code
2354: PetscPreLoadEnd();
2355: .ve
2357: Level: intermediate
2359: Note:
2360: Only works in C/C++ not Fortran
2362: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`
2363: M*/
2365: #if PetscDefined(HAVE_DEVICE)
2366: #include <petsc/private/deviceimpl.h>
2368: /*@
2369: PetscLogGpuTime - turn on the logging of GPU time for GPU kernels
2371: Options Database Key:
2372: . -log_view_gpu_time - provide the GPU times for all events in the `-log_view` output
2374: Level: advanced
2376: Notes:
2377: Turning on the timing of the GPU kernels can slow down the entire computation and should only
2378: be used when studying the performance of individual operations on GPU such as vector operations and
2379: matrix-vector operations.
2381: 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
2383: This routine should only be called once near the beginning of the program. Once it is started
2384: it cannot be turned off.
2386: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTimeBegin()`
2387: @*/
2388: PetscErrorCode PetscLogGpuTime(void)
2389: {
2390: PetscFunctionBegin;
2391: PetscCheck(petsc_gtime == 0.0, PETSC_COMM_SELF, PETSC_ERR_SUP, "GPU logging has already been turned on");
2392: PetscLogGpuTimeFlag = PETSC_TRUE;
2393: PetscFunctionReturn(PETSC_SUCCESS);
2394: }
2396: /*@
2397: PetscLogGpuTimeBegin - Start timer for device
2399: Level: intermediate
2401: Notes:
2402: When GPU is enabled, the timer is run on the GPU, it is a separate logging of time
2403: devoted to GPU computations (excluding kernel launch times).
2405: When GPU is not available, the timer is run on the CPU, it is a separate logging of
2406: time devoted to GPU computations (including kernel launch times).
2408: There is no need to call WaitForCUDA() or WaitForHIP() between `PetscLogGpuTimeBegin()` and
2409: `PetscLogGpuTimeEnd()`
2411: This timer should NOT include times for data transfers between the GPU and CPU, nor setup
2412: actions such as allocating space.
2414: The regular logging captures the time for data transfers and any CPU activities during the
2415: event. It is used to compute the flop rate on the GPU as it is actively engaged in running a
2416: kernel.
2418: Developer Notes:
2419: The GPU event timer captures the execution time of all the kernels launched in the default
2420: stream by the CPU between `PetscLogGpuTimeBegin()` and `PetscLogGpuTimeEnd()`.
2422: `PetscLogGpuTimeBegin()` and `PetscLogGpuTimeEnd()` insert the begin and end events into the
2423: default stream (stream 0). The device will record a time stamp for the event when it reaches
2424: that event in the stream. The function xxxEventSynchronize() is called in
2425: `PetscLogGpuTimeEnd()` to block CPU execution, but not continued GPU execution, until the
2426: timer event is recorded.
2428: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTime()`
2429: @*/
2430: PetscErrorCode PetscLogGpuTimeBegin(void)
2431: {
2432: PetscBool isActive;
2434: PetscFunctionBegin;
2435: PetscCall(PetscLogEventBeginIsActive(&isActive));
2436: if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2437: if (!PetscDefined(HAVE_KOKKOS_WITHOUT_GPU)) {
2438: PetscDeviceContext dctx;
2440: PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2441: PetscCall(PetscDeviceContextBeginTimer_Internal(dctx));
2442: } else {
2443: PetscCall(PetscTimeSubtract(&petsc_gtime));
2444: }
2445: PetscFunctionReturn(PETSC_SUCCESS);
2446: }
2448: /*@
2449: PetscLogGpuTimeEnd - Stop timer for device
2451: Level: intermediate
2453: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeBegin()`
2454: @*/
2455: PetscErrorCode PetscLogGpuTimeEnd(void)
2456: {
2457: PetscBool isActive;
2459: PetscFunctionBegin;
2460: PetscCall(PetscLogEventEndIsActive(&isActive));
2461: if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2462: if (!PetscDefined(HAVE_KOKKOS_WITHOUT_GPU)) {
2463: PetscDeviceContext dctx;
2464: PetscLogDouble elapsed;
2466: PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2467: PetscCall(PetscDeviceContextEndTimer_Internal(dctx, &elapsed));
2468: petsc_gtime += (elapsed / 1000.0);
2469: #if PetscDefined(HAVE_CUDA_VERSION_12_2PLUS)
2470: if (PetscLogGpuEnergyFlag) {
2471: PetscLogDouble power;
2472: PetscCall(PetscDeviceContextGetPower_Internal(dctx, &power));
2473: petsc_genergy += (power * elapsed / 1000000.0); // convert to Joules
2474: }
2475: #endif
2476: } else {
2477: PetscCall(PetscTimeAdd(&petsc_gtime));
2478: }
2479: PetscFunctionReturn(PETSC_SUCCESS);
2480: }
2482: /*@
2483: PetscLogGpuEnergy - turn on the logging of GPU energy (estimated with power*gtime) for GPU kernels
2485: Options Database Key:
2486: . -log_view_gpu_energy - provide the GPU energy consumption (estimated with power*gtime) for all events in the `-log_view` output
2488: Level: advanced
2490: Note:
2491: This option is mutually exclusive to `-log_view_gpu_energy_meter`.
2493: Developer Note:
2494: This option turns on energy monitoring of GPU kernels and requires CUDA version >= 12.2. The energy consumption is estimated as
2495: instant_power * gpu_kernel_time. Due to the delay in NVML power sampling, we read the instantaneous power draw at the end of each
2496: event using `nvmlDeviceGetFieldValues()` with the field ID `NVML_FI_DEV_POWER_INSTANT`.
2498: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuEnergyMeter()`
2499: @*/
2500: PetscErrorCode PetscLogGpuEnergy(void)
2501: {
2502: PetscFunctionBegin;
2503: PetscCheck(PetscDefined(HAVE_CUDA_VERSION_12_2PLUS), PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "-log_view_gpu_energy requires CUDA version >= 12.2");
2504: PetscCheck(petsc_genergy == 0.0, PETSC_COMM_SELF, PETSC_ERR_SUP, "GPU energy logging has already been turned on");
2505: PetscLogGpuEnergyFlag = PETSC_TRUE;
2506: PetscLogGpuEnergyMeterFlag = PETSC_FALSE;
2507: PetscFunctionReturn(PETSC_SUCCESS);
2508: }
2510: /*@
2511: PetscLogGpuEnergyMeter - turn on the logging of GPU energy (readings from energy meters) for GPU kernels
2513: Options Database Key:
2514: . -log_view_gpu_energy_meter - provide the GPU energy (readings from energy meters) consumption for all events in the `-log_view` output
2516: Level: advanced
2518: Note:
2519: This option is mutually exclusive to `-log_view_gpu_energy`.
2521: Developer Note:
2522: This option turns on energy monitoring of GPU kernels. The energy consumption is measured directly using the NVML API
2523: `nvmlDeviceGetTotalEnergyConsumption()`, which returns the total energy used by the GPU since the driver was last initialized.
2524: For newer GPUs, energy readings are updated every 20-100ms, so this approach may be inaccurate for short-duration GPU events.
2526: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuEnergyMeterEnd()`, `PetscLogGpuEnergyMeterBegin()`
2527: @*/
2528: PetscErrorCode PetscLogGpuEnergyMeter(void)
2529: {
2530: PetscFunctionBegin;
2531: PetscCheck(petsc_genergy == 0.0, PETSC_COMM_SELF, PETSC_ERR_SUP, "GPU energy logging has already been turned on");
2532: PetscLogGpuEnergyMeterFlag = PETSC_TRUE;
2533: PetscLogGpuEnergyFlag = PETSC_FALSE;
2534: PetscFunctionReturn(PETSC_SUCCESS);
2535: }
2537: /*@
2538: PetscLogGpuEnergyMeterBegin - Start energy meter for device
2540: Level: intermediate
2542: Notes:
2543: The GPU event energy meter captures the energy used by the GPU between `PetscLogGpuEnergyMeterBegin()` and `PetscLogGpuEnergyMeterEnd()`.
2545: `PetscLogGpuEnergyMeterBegin()` and `PetscLogGpuEnergyMeterEnd()` collect the energy readings using `nvmlDeviceGetTotalEnergyConsumption()`.
2546: The function `cupmStreamSynchronize()` is called before the energy query to ensure completion.
2548: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuEnergyMeterEnd()`, `PetscLogGpuEnergyMeter()`
2549: @*/
2550: PetscErrorCode PetscLogGpuEnergyMeterBegin(void)
2551: {
2552: PetscBool isActive;
2554: PetscFunctionBegin;
2555: PetscCall(PetscLogEventBeginIsActive(&isActive));
2556: if (!isActive || !PetscLogGpuEnergyMeterFlag) PetscFunctionReturn(PETSC_SUCCESS);
2557: if (!PetscDefined(HAVE_KOKKOS_WITHOUT_GPU)) {
2558: PetscDeviceContext dctx;
2560: PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2561: PetscCall(PetscDeviceContextBeginEnergyMeter_Internal(dctx));
2562: }
2563: PetscFunctionReturn(PETSC_SUCCESS);
2564: }
2566: /*@
2567: PetscLogGpuEnergyMeterEnd - Stop energy meter for device
2569: Level: intermediate
2571: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuEnergyMeterBegin()`
2572: @*/
2573: PetscErrorCode PetscLogGpuEnergyMeterEnd(void)
2574: {
2575: PetscBool isActive;
2577: PetscFunctionBegin;
2578: PetscCall(PetscLogEventEndIsActive(&isActive));
2579: if (!isActive || !PetscLogGpuEnergyMeterFlag) PetscFunctionReturn(PETSC_SUCCESS);
2580: if (!PetscDefined(HAVE_KOKKOS_WITHOUT_GPU)) {
2581: PetscDeviceContext dctx;
2582: PetscLogDouble energy;
2584: PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2585: PetscCall(PetscDeviceContextEndEnergyMeter_Internal(dctx, &energy));
2586: petsc_genergy_meter += (energy / 1000.0); // convert to Joules
2587: }
2588: PetscFunctionReturn(PETSC_SUCCESS);
2589: }
2590: #endif /* end of PETSC_HAVE_DEVICE */
2592: #endif /* PETSC_USE_LOG*/
2594: PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2595: PetscClassId PETSC_OBJECT_CLASSID = 0;
2597: static PetscBool PetscLogInitializeCalled = PETSC_FALSE;
2599: PETSC_INTERN PetscErrorCode PetscLogInitialize(void)
2600: {
2601: int stage;
2603: PetscFunctionBegin;
2604: if (PetscLogInitializeCalled) PetscFunctionReturn(PETSC_SUCCESS);
2605: PetscLogInitializeCalled = PETSC_TRUE;
2606: if (PetscDefined(USE_LOG)) {
2607: /* Setup default logging structures */
2608: PetscCall(PetscLogStateCreate(&petsc_log_state));
2609: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2610: if (PetscLogHandlers[i].handler) PetscCall(PetscLogHandlerSetState(PetscLogHandlers[i].handler, petsc_log_state));
2611: }
2612: PetscCall(PetscLogStateStageRegister(petsc_log_state, "Main Stage", &stage));
2613: PetscCall(PetscSpinlockCreate(&PetscLogSpinLock));
2614: #if defined(PETSC_HAVE_THREADSAFETY)
2615: petsc_log_tid = 0;
2616: petsc_log_gid = 0;
2617: #endif
2619: /* All processors sync here for more consistent logging */
2620: PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
2621: PetscCall(PetscTime(&petsc_BaseTime));
2622: PetscCall(PetscLogStagePush(stage));
2623: }
2624: PetscFunctionReturn(PETSC_SUCCESS);
2625: }
2627: PETSC_INTERN PetscErrorCode PetscLogFinalize(void)
2628: {
2629: PetscFunctionBegin;
2630: if (PetscDefined(USE_LOG)) {
2631: /* Resetting phase */
2632: // pop remaining stages
2633: if (petsc_log_state) {
2634: while (petsc_log_state->current_stage >= 0) PetscCall(PetscLogStagePop());
2635: }
2636: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) PetscCall(PetscLogHandlerDestroy(&PetscLogHandlers[i].handler));
2637: PetscCall(PetscArrayzero(PetscLogHandlers, PETSC_LOG_HANDLER_MAX));
2638: PetscCall(PetscLogStateDestroy(&petsc_log_state));
2640: petsc_TotalFlops = 0.0;
2641: petsc_BaseTime = 0.0;
2642: petsc_TotalFlops = 0.0;
2643: petsc_send_ct = 0.0;
2644: petsc_recv_ct = 0.0;
2645: petsc_send_len = 0.0;
2646: petsc_recv_len = 0.0;
2647: petsc_isend_ct = 0.0;
2648: petsc_irecv_ct = 0.0;
2649: petsc_isend_len = 0.0;
2650: petsc_irecv_len = 0.0;
2651: petsc_wait_ct = 0.0;
2652: petsc_wait_any_ct = 0.0;
2653: petsc_wait_all_ct = 0.0;
2654: petsc_sum_of_waits_ct = 0.0;
2655: petsc_allreduce_ct = 0.0;
2656: petsc_gather_ct = 0.0;
2657: petsc_scatter_ct = 0.0;
2658: petsc_TotalFlops_th = 0.0;
2659: petsc_send_ct_th = 0.0;
2660: petsc_recv_ct_th = 0.0;
2661: petsc_send_len_th = 0.0;
2662: petsc_recv_len_th = 0.0;
2663: petsc_isend_ct_th = 0.0;
2664: petsc_irecv_ct_th = 0.0;
2665: petsc_isend_len_th = 0.0;
2666: petsc_irecv_len_th = 0.0;
2667: petsc_wait_ct_th = 0.0;
2668: petsc_wait_any_ct_th = 0.0;
2669: petsc_wait_all_ct_th = 0.0;
2670: petsc_sum_of_waits_ct_th = 0.0;
2671: petsc_allreduce_ct_th = 0.0;
2672: petsc_gather_ct_th = 0.0;
2673: petsc_scatter_ct_th = 0.0;
2675: petsc_ctog_ct = 0.0;
2676: petsc_gtoc_ct = 0.0;
2677: petsc_ctog_sz = 0.0;
2678: petsc_gtoc_sz = 0.0;
2679: petsc_gflops = 0.0;
2680: petsc_gtime = 0.0;
2681: petsc_genergy = 0.0;
2682: petsc_genergy_meter = 0.0;
2683: petsc_ctog_ct_th = 0.0;
2684: petsc_gtoc_ct_th = 0.0;
2685: petsc_ctog_sz_th = 0.0;
2686: petsc_gtoc_sz_th = 0.0;
2687: petsc_gflops_th = 0.0;
2688: petsc_gtime_th = 0.0;
2689: }
2690: PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2691: PETSC_OBJECT_CLASSID = 0;
2692: PetscLogInitializeCalled = PETSC_FALSE;
2693: PetscFunctionReturn(PETSC_SUCCESS);
2694: }
2696: /*@
2697: PetscClassIdRegister - Registers a new class name for objects and logging operations in an application code.
2699: Not Collective
2701: Input Parameter:
2702: . name - The class name
2704: Output Parameter:
2705: . oclass - The class id or classid
2707: Level: developer
2709: .seealso: [](ch_profiling), `PetscLogEventRegister()`
2710: @*/
2711: PetscErrorCode PetscClassIdRegister(const char name[], PetscClassId *oclass)
2712: {
2713: PetscFunctionBegin;
2714: *oclass = ++PETSC_LARGEST_CLASSID;
2715: #if defined(PETSC_USE_LOG)
2716: {
2717: PetscLogState state;
2718: PetscLogClass logclass;
2720: PetscCall(PetscLogGetState(&state));
2721: if (state) PetscCall(PetscLogStateClassRegister(state, name, *oclass, &logclass));
2722: }
2723: #endif
2724: PetscFunctionReturn(PETSC_SUCCESS);
2725: }