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 <petsc/private/deviceimpl.h>
17: #if PetscDefined(HAVE_THREADSAFETY)
19: PetscInt petsc_log_gid = -1; /* Global threadId counter */
20: PETSC_TLS PetscInt petsc_log_tid = -1; /* Local threadId */
22: /* shared variables */
23: PetscSpinlock PetscLogSpinLock;
25: PetscInt PetscLogGetTid(void)
26: {
27: if (petsc_log_tid < 0) {
28: PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
29: petsc_log_tid = ++petsc_log_gid;
30: PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
31: }
32: return petsc_log_tid;
33: }
35: #endif
37: /* Global counters */
38: PetscLogDouble petsc_BaseTime = 0.0;
39: PetscLogDouble petsc_TotalFlops = 0.0; /* The number of flops */
40: PetscLogDouble petsc_send_ct = 0.0; /* The number of sends */
41: PetscLogDouble petsc_recv_ct = 0.0; /* The number of receives */
42: PetscLogDouble petsc_send_len = 0.0; /* The total length of all sent messages */
43: PetscLogDouble petsc_recv_len = 0.0; /* The total length of all received messages */
44: PetscLogDouble petsc_isend_ct = 0.0; /* The number of immediate sends */
45: PetscLogDouble petsc_irecv_ct = 0.0; /* The number of immediate receives */
46: PetscLogDouble petsc_isend_len = 0.0; /* The total length of all immediate send messages */
47: PetscLogDouble petsc_irecv_len = 0.0; /* The total length of all immediate receive messages */
48: PetscLogDouble petsc_wait_ct = 0.0; /* The number of waits */
49: PetscLogDouble petsc_wait_any_ct = 0.0; /* The number of anywaits */
50: PetscLogDouble petsc_wait_all_ct = 0.0; /* The number of waitalls */
51: PetscLogDouble petsc_sum_of_waits_ct = 0.0; /* The total number of waits */
52: PetscLogDouble petsc_allreduce_ct = 0.0; /* The number of reductions */
53: PetscLogDouble petsc_gather_ct = 0.0; /* The number of gathers and gathervs */
54: PetscLogDouble petsc_scatter_ct = 0.0; /* The number of scatters and scattervs */
56: /* Thread Local storage */
57: PETSC_TLS PetscLogDouble petsc_TotalFlops_th = 0.0;
58: PETSC_TLS PetscLogDouble petsc_send_ct_th = 0.0;
59: PETSC_TLS PetscLogDouble petsc_recv_ct_th = 0.0;
60: PETSC_TLS PetscLogDouble petsc_send_len_th = 0.0;
61: PETSC_TLS PetscLogDouble petsc_recv_len_th = 0.0;
62: PETSC_TLS PetscLogDouble petsc_isend_ct_th = 0.0;
63: PETSC_TLS PetscLogDouble petsc_irecv_ct_th = 0.0;
64: PETSC_TLS PetscLogDouble petsc_isend_len_th = 0.0;
65: PETSC_TLS PetscLogDouble petsc_irecv_len_th = 0.0;
66: PETSC_TLS PetscLogDouble petsc_wait_ct_th = 0.0;
67: PETSC_TLS PetscLogDouble petsc_wait_any_ct_th = 0.0;
68: PETSC_TLS PetscLogDouble petsc_wait_all_ct_th = 0.0;
69: PETSC_TLS PetscLogDouble petsc_sum_of_waits_ct_th = 0.0;
70: PETSC_TLS PetscLogDouble petsc_allreduce_ct_th = 0.0;
71: PETSC_TLS PetscLogDouble petsc_gather_ct_th = 0.0;
72: PETSC_TLS PetscLogDouble petsc_scatter_ct_th = 0.0;
74: PetscLogDouble petsc_ctog_ct = 0.0; /* The total number of CPU to GPU copies */
75: PetscLogDouble petsc_gtoc_ct = 0.0; /* The total number of GPU to CPU copies */
76: PetscLogDouble petsc_ctog_sz = 0.0; /* The total size of CPU to GPU copies */
77: PetscLogDouble petsc_gtoc_sz = 0.0; /* The total size of GPU to CPU copies */
78: PetscLogDouble petsc_ctog_ct_scalar = 0.0; /* The total number of CPU to GPU copies */
79: PetscLogDouble petsc_gtoc_ct_scalar = 0.0; /* The total number of GPU to CPU copies */
80: PetscLogDouble petsc_ctog_sz_scalar = 0.0; /* The total size of CPU to GPU copies */
81: PetscLogDouble petsc_gtoc_sz_scalar = 0.0; /* The total size of GPU to CPU copies */
82: PetscLogDouble petsc_gflops = 0.0; /* The flops done on a GPU */
83: PetscLogDouble petsc_gtime = 0.0; /* The time spent on a GPU */
84: PetscLogDouble petsc_genergy = 0.0; /* The energy (estimated with power*gtime) consumed on a GPU */
85: PetscLogDouble petsc_genergy_meter = 0.0; /* Readings from the energy meter on a GPU */
87: PETSC_TLS PetscLogDouble petsc_ctog_ct_th = 0.0;
88: PETSC_TLS PetscLogDouble petsc_gtoc_ct_th = 0.0;
89: PETSC_TLS PetscLogDouble petsc_ctog_sz_th = 0.0;
90: PETSC_TLS PetscLogDouble petsc_gtoc_sz_th = 0.0;
91: PETSC_TLS PetscLogDouble petsc_ctog_ct_scalar_th = 0.0;
92: PETSC_TLS PetscLogDouble petsc_gtoc_ct_scalar_th = 0.0;
93: PETSC_TLS PetscLogDouble petsc_ctog_sz_scalar_th = 0.0;
94: PETSC_TLS PetscLogDouble petsc_gtoc_sz_scalar_th = 0.0;
95: PETSC_TLS PetscLogDouble petsc_gflops_th = 0.0;
96: PETSC_TLS PetscLogDouble petsc_gtime_th = 0.0;
98: PetscBool PetscLogMemory = PETSC_FALSE;
99: PetscBool PetscLogSyncOn = PETSC_FALSE;
101: PetscBool PetscLogGpuTimeFlag = PETSC_FALSE;
102: PetscBool PetscLogGpuEnergyFlag = PETSC_FALSE;
103: PetscBool PetscLogGpuEnergyMeterFlag = PETSC_FALSE;
105: PetscInt PetscLogNumViewersCreated = 0;
106: PetscInt PetscLogNumViewersDestroyed = 0;
108: PetscLogState petsc_log_state = NULL;
110: #define PETSC_LOG_HANDLER_HOT_BLANK {NULL, NULL, NULL, NULL, NULL, NULL}
112: PetscLogHandlerHot PetscLogHandlers[PETSC_LOG_HANDLER_MAX] = {
113: PETSC_LOG_HANDLER_HOT_BLANK,
114: PETSC_LOG_HANDLER_HOT_BLANK,
115: PETSC_LOG_HANDLER_HOT_BLANK,
116: PETSC_LOG_HANDLER_HOT_BLANK,
117: };
119: #undef PETSC_LOG_HANDLERS_HOT_BLANK
121: #if PetscDefined(USE_LOG)
122: #include <../src/sys/logging/handler/impls/default/logdefault.h>
124: #if PetscDefined(HAVE_THREADSAFETY)
125: /*@
126: PetscAddLogDouble - Atomically add a `PetscLogDouble` value to both a global counter and its per-thread counterpart
128: Not Collective; No Fortran Support
130: Input Parameters:
131: + tot - pointer to the global counter to update
132: . tot_th - pointer to the per-thread counter to update
133: - value - the value to add to both counters
135: Level: developer
137: Note:
138: When PETSc is built without thread safety this is a fast macro that performs the same update without locking.
140: .seealso: `PetscAddLogDoubleCnt()`, `PetscLogFlops()`, `PetscLogDouble`
141: @*/
142: PetscErrorCode PetscAddLogDouble(PetscLogDouble *tot, PetscLogDouble *tot_th, PetscLogDouble value)
143: {
144: *tot_th += value;
145: PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
146: *tot += value;
147: PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
148: return PETSC_SUCCESS;
149: }
151: /*@
152: PetscAddLogDoubleCnt - Atomically update both a count pair and a size pair of `PetscLogDouble` counters (global and per-thread)
154: Not Collective; No Fortran Support
156: Input Parameters:
157: + cnt - pointer to the global count counter to increment by one
158: . tot - pointer to the global size counter to update
159: . cnt_th - pointer to the per-thread count counter to increment by one
160: . tot_th - pointer to the per-thread size counter to update
161: - value - the size value to add to the size counters
163: Level: developer
165: .seealso: `PetscAddLogDouble()`, `PetscLogFlops()`, `PetscLogDouble`
166: @*/
167: PetscErrorCode PetscAddLogDoubleCnt(PetscLogDouble *cnt, PetscLogDouble *tot, PetscLogDouble *cnt_th, PetscLogDouble *tot_th, PetscLogDouble value)
168: {
169: *cnt_th = *cnt_th + 1;
170: *tot_th += value;
171: PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
172: *tot += (PetscLogDouble)value;
173: *cnt += *cnt + 1;
174: PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
175: return PETSC_SUCCESS;
176: }
178: #endif
180: static PetscErrorCode PetscLogTryGetHandler(PetscLogHandlerType type, PetscLogHandler *handler)
181: {
182: PetscFunctionBegin;
183: PetscAssertPointer(handler, 2);
184: *handler = NULL;
185: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
186: PetscLogHandler h = PetscLogHandlers[i].handler;
187: if (h) {
188: PetscBool match;
190: PetscCall(PetscObjectTypeCompare((PetscObject)h, type, &match));
191: if (match) {
192: *handler = PetscLogHandlers[i].handler;
193: PetscFunctionReturn(PETSC_SUCCESS);
194: }
195: }
196: }
197: PetscFunctionReturn(PETSC_SUCCESS);
198: }
200: /*@
201: PetscLogGetDefaultHandler - Get the default log handler if it is running.
203: Not collective
205: Output Parameter:
206: . handler - the default `PetscLogHandler`, or `NULL` if it is not running.
208: Level: developer
210: Notes:
211: The default handler is started with `PetscLogDefaultBegin()`,
212: if the options flags `-log_all` or `-log_view` is given without arguments,
213: or for `-log_view :output:format` if `format` is not `ascii_xml` or `ascii_flamegraph`.
215: .seealso: [](ch_profiling)
216: @*/
217: PetscErrorCode PetscLogGetDefaultHandler(PetscLogHandler *handler)
218: {
219: PetscFunctionBegin;
220: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, handler));
221: PetscFunctionReturn(PETSC_SUCCESS);
222: }
224: static PetscErrorCode PetscLogGetHandler(PetscLogHandlerType type, PetscLogHandler *handler)
225: {
226: PetscFunctionBegin;
227: PetscAssertPointer(handler, 2);
228: PetscCall(PetscLogTryGetHandler(type, handler));
229: PetscCheck(*handler != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "A PetscLogHandler of type %s has not been started.", type);
230: PetscFunctionReturn(PETSC_SUCCESS);
231: }
233: /*@
234: PetscLogGetState - Get the `PetscLogState` for PETSc's global logging, used
235: by all default log handlers (`PetscLogDefaultBegin()`,
236: `PetscLogNestedBegin()`, `PetscLogTraceBegin()`, `PetscLogMPEBegin()`,
237: `PetscLogPerfstubsBegin()`).
239: Collective on `PETSC_COMM_WORLD`
241: Output Parameter:
242: . state - The `PetscLogState` changed by registrations (such as
243: `PetscLogEventRegister()`) and actions (such as `PetscLogEventBegin()` or
244: `PetscLogStagePush()`), or `NULL` if logging is not active
246: Level: developer
248: .seealso: [](ch_profiling), `PetscLogState`
249: @*/
250: PetscErrorCode PetscLogGetState(PetscLogState *state)
251: {
252: PetscFunctionBegin;
253: PetscAssertPointer(state, 1);
254: *state = petsc_log_state;
255: PetscFunctionReturn(PETSC_SUCCESS);
256: }
258: static PetscErrorCode PetscLogHandlerCopyToHot(PetscLogHandler h, PetscLogHandlerHot *hot)
259: {
260: PetscFunctionBegin;
261: hot->handler = h;
262: hot->eventBegin = h->ops->eventbegin;
263: hot->eventEnd = h->ops->eventend;
264: hot->eventSync = h->ops->eventsync;
265: hot->objectCreate = h->ops->objectcreate;
266: hot->objectDestroy = h->ops->objectdestroy;
267: PetscFunctionReturn(PETSC_SUCCESS);
268: }
270: /*@
271: PetscLogHandlerStart - Connect a log handler to PETSc's global logging stream and state.
273: Logically collective
275: Input Parameters:
276: . h - a `PetscLogHandler`
278: Level: developer
280: Notes:
281: Users should only need this if they create their own log handlers: handlers that are started
282: from the command line (such as `-log_view` and `-log_trace`) or from a function like
283: `PetscLogNestedBegin()` will automatically be started.
285: There is a limit of `PESC_LOG_HANDLER_MAX` handlers that can be active at one time.
287: To disconnect a handler from the global stream call `PetscLogHandlerStop()`.
289: When a log handler is started, stages that have already been pushed with `PetscLogStagePush()`,
290: will be pushed for the new log handler, but it will not be informed of any events that are
291: in progress. It is recommended to start any user-defined log handlers immediately following
292: `PetscInitialize()` before any user-defined stages are pushed.
294: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogHandlerStop()`, `PetscInitialize()`
295: @*/
296: PetscErrorCode PetscLogHandlerStart(PetscLogHandler h)
297: {
298: PetscFunctionBegin;
299: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
300: if (PetscLogHandlers[i].handler == h) PetscFunctionReturn(PETSC_SUCCESS);
301: }
302: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
303: if (PetscLogHandlers[i].handler == NULL) {
304: PetscCall(PetscObjectReference((PetscObject)h));
305: PetscCall(PetscLogHandlerCopyToHot(h, &PetscLogHandlers[i]));
306: if (petsc_log_state) {
307: PetscLogStage stack_height;
308: PetscIntStack orig_stack, temp_stack;
310: PetscCall(PetscLogHandlerSetState(h, petsc_log_state));
311: stack_height = petsc_log_state->stage_stack->top + 1;
312: PetscCall(PetscIntStackCreate(&temp_stack));
313: orig_stack = petsc_log_state->stage_stack;
314: petsc_log_state->stage_stack = temp_stack;
315: petsc_log_state->current_stage = -1;
316: for (int s = 0; s < stack_height; s++) {
317: PetscLogStage stage = orig_stack->stack[s];
318: PetscCall(PetscLogHandlerStagePush(h, stage));
319: PetscCall(PetscIntStackPush(temp_stack, stage));
320: petsc_log_state->current_stage = stage;
321: }
322: PetscCall(PetscIntStackDestroy(temp_stack));
323: petsc_log_state->stage_stack = orig_stack;
324: }
325: PetscFunctionReturn(PETSC_SUCCESS);
326: }
327: }
328: SETERRQ(PetscObjectComm((PetscObject)h), PETSC_ERR_ARG_WRONGSTATE, "%d log handlers already started, cannot start another", PETSC_LOG_HANDLER_MAX);
329: PetscFunctionReturn(PETSC_SUCCESS);
330: }
332: /*@
333: PetscLogHandlerStop - Disconnect a log handler from PETSc's global logging stream.
335: Logically collective
337: Input Parameters:
338: . h - a `PetscLogHandler`
340: Level: developer
342: Note:
343: After `PetscLogHandlerStop()`, the handler can still access the global logging state
344: with `PetscLogHandlerGetState()`, so that it can access the registry when post-processing
345: (for instance, in `PetscLogHandlerView()`),
347: When a log handler is stopped, the remaining stages will be popped before it is
348: disconnected from the log stream.
350: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogHandlerStart()`
351: @*/
352: PetscErrorCode PetscLogHandlerStop(PetscLogHandler h)
353: {
354: PetscFunctionBegin;
355: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
356: if (PetscLogHandlers[i].handler == h) {
357: if (petsc_log_state) {
358: PetscLogState state;
359: PetscLogStage stack_height;
360: PetscIntStack orig_stack, temp_stack;
362: PetscCall(PetscLogHandlerGetState(h, &state));
363: PetscCheck(state == petsc_log_state, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "Called PetscLogHandlerStop() for a PetscLogHander that was not started.");
364: stack_height = petsc_log_state->stage_stack->top + 1;
365: PetscCall(PetscIntStackCreate(&temp_stack));
366: orig_stack = petsc_log_state->stage_stack;
367: petsc_log_state->stage_stack = temp_stack;
368: for (int s = 0; s < stack_height; s++) {
369: PetscLogStage stage = orig_stack->stack[s];
371: PetscCall(PetscIntStackPush(temp_stack, stage));
372: }
373: for (int s = 0; s < stack_height; s++) {
374: PetscLogStage stage;
375: PetscBool empty;
377: PetscCall(PetscIntStackPop(temp_stack, &stage));
378: PetscCall(PetscIntStackEmpty(temp_stack, &empty));
379: if (!empty) PetscCall(PetscIntStackTop(temp_stack, &petsc_log_state->current_stage));
380: else petsc_log_state->current_stage = -1;
381: PetscCall(PetscLogHandlerStagePop(h, stage));
382: }
383: PetscCall(PetscIntStackDestroy(temp_stack));
384: petsc_log_state->stage_stack = orig_stack;
385: PetscCall(PetscIntStackTop(petsc_log_state->stage_stack, &petsc_log_state->current_stage));
386: }
387: PetscCall(PetscArrayzero(&PetscLogHandlers[i], 1));
388: PetscCall(PetscObjectDereference((PetscObject)h));
389: }
390: }
391: PetscFunctionReturn(PETSC_SUCCESS);
392: }
394: /*@
395: PetscLogIsActive - Check if logging (profiling) is currently in progress.
397: Not Collective
399: Output Parameter:
400: . isActive - `PETSC_TRUE` if logging is in progress, `PETSC_FALSE` otherwise
402: Level: beginner
404: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`
405: @*/
406: PetscErrorCode PetscLogIsActive(PetscBool *isActive)
407: {
408: PetscFunctionBegin;
409: *isActive = PETSC_FALSE;
410: if (petsc_log_state) {
411: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
412: if (PetscLogHandlers[i].handler) {
413: *isActive = PETSC_TRUE;
414: PetscFunctionReturn(PETSC_SUCCESS);
415: }
416: }
417: }
418: PetscFunctionReturn(PETSC_SUCCESS);
419: }
421: PETSC_UNUSED static PetscErrorCode PetscLogEventBeginIsActive(PetscBool *isActive)
422: {
423: PetscFunctionBegin;
424: *isActive = PETSC_FALSE;
425: if (petsc_log_state) {
426: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
427: if (PetscLogHandlers[i].eventBegin) {
428: *isActive = PETSC_TRUE;
429: PetscFunctionReturn(PETSC_SUCCESS);
430: }
431: }
432: }
433: PetscFunctionReturn(PETSC_SUCCESS);
434: }
436: PETSC_UNUSED static PetscErrorCode PetscLogEventEndIsActive(PetscBool *isActive)
437: {
438: PetscFunctionBegin;
439: *isActive = PETSC_FALSE;
440: if (petsc_log_state) {
441: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
442: if (PetscLogHandlers[i].eventEnd) {
443: *isActive = PETSC_TRUE;
444: PetscFunctionReturn(PETSC_SUCCESS);
445: }
446: }
447: }
448: PetscFunctionReturn(PETSC_SUCCESS);
449: }
451: PETSC_INTERN PetscErrorCode PetscLogTypeBegin(PetscLogHandlerType type)
452: {
453: PetscLogHandler handler;
455: PetscFunctionBegin;
456: PetscCall(PetscLogTryGetHandler(type, &handler));
457: if (handler) PetscFunctionReturn(PETSC_SUCCESS);
458: PetscCall(PetscLogHandlerCreate(PETSC_COMM_WORLD, &handler));
459: PetscCall(PetscLogHandlerSetType(handler, type));
460: PetscCall(PetscLogHandlerStart(handler));
461: PetscCall(PetscLogHandlerDestroy(&handler));
462: PetscFunctionReturn(PETSC_SUCCESS);
463: }
465: /*@
466: PetscLogDefaultBegin - Turns on logging (profiling) of PETSc code using the default log handler (profiler). This logs time, flop
467: rates, and object creation and should not slow programs down too much.
469: Logically Collective on `PETSC_COMM_WORLD`
471: Options Database Key:
472: . -log_view viewer_specification - Displays summary of flop and timing (profiling) information (for PETSc configured `--with-log`, which is the default).
473: This option must be provided before `PetscInitialize()`. See `PetscOptionsCreateViewer()` for the
474: format of `viewer_specification`
476: Example Usage:
477: .vb
478: PetscInitialize(...);
479: PetscLogDefaultBegin();
480: ... code ...
481: PetscLogView(viewer); or PetscLogDump();
482: PetscFinalize();
483: .ve
485: Level: advanced
487: Notes:
488: `PetscLogView()` or `PetscLogDump()` actually cause the printing of
489: the logging information.
491: This routine may be called more than once.
493: To provide the `-log_view` option in your source code you must call PetscCall(PetscOptionsSetValue(NULL, "-log_view", NULL));
494: before you call `PetscInitialize()`
496: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`
497: @*/
498: PetscErrorCode PetscLogDefaultBegin(void)
499: {
500: PetscFunctionBegin;
501: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERDEFAULT));
502: PetscFunctionReturn(PETSC_SUCCESS);
503: }
505: /*@
506: PetscLogTraceBegin - Begins trace logging. Every time a PETSc event
507: begins or ends, the event name is printed.
509: Logically Collective on `PETSC_COMM_WORLD`, No Fortran Support
511: Input Parameter:
512: . file - The file to print trace in (e.g. stdout)
514: Options Database Key:
515: . -log_trace [filename] - Begins `PetscLogTraceBegin()`
517: Level: intermediate
519: Notes:
520: `PetscLogTraceBegin()` prints the processor number, the execution time (sec),
521: then "Event begin:" or "Event end:" followed by the event name.
523: `PetscLogTraceBegin()` allows tracing of all PETSc calls, which is useful
524: to determine where a program is hanging without running in the
525: debugger. Can be used in conjunction with the -info option.
527: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogView()`, `PetscLogDefaultBegin()`
528: @*/
529: PetscErrorCode PetscLogTraceBegin(FILE *file)
530: {
531: PetscLogHandler handler;
533: PetscFunctionBegin;
534: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERTRACE, &handler));
535: if (handler) PetscFunctionReturn(PETSC_SUCCESS);
536: PetscCall(PetscLogHandlerCreateTrace(PETSC_COMM_WORLD, file, &handler));
537: PetscCall(PetscLogHandlerStart(handler));
538: PetscCall(PetscLogHandlerDestroy(&handler));
539: PetscFunctionReturn(PETSC_SUCCESS);
540: }
542: PETSC_INTERN PetscErrorCode PetscLogHandlerCreate_Nested(MPI_Comm, PetscLogHandler *);
544: /*@
545: PetscLogNestedBegin - Turns on nested logging of objects and events. This logs flop
546: rates and object creation and should not slow programs down much.
548: Logically Collective on `PETSC_COMM_WORLD`, No Fortran Support
550: Options Database Key:
551: . -log_view :filename.xml:ascii_xml - Prints an XML summary of flop and timing information to the file `filename.xml`.
552: See `PetscOptionsCreateViewer()` for other possible viewer specifications
554: Example Usage:
555: .vb
556: PetscInitialize(...);
557: PetscLogNestedBegin();
558: ... code ...
559: PetscLogView(viewer);
560: PetscFinalize();
561: .ve
563: Level: advanced
565: .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`
566: @*/
567: PetscErrorCode PetscLogNestedBegin(void)
568: {
569: PetscFunctionBegin;
570: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERNESTED));
571: PetscFunctionReturn(PETSC_SUCCESS);
572: }
574: /*@
575: PetscLogLegacyCallbacksBegin - Create and start a log handler from callbacks
576: matching the now deprecated function pointers `PetscLogPLB`, `PetscLogPLE`,
577: `PetscLogPHC`, `PetscLogPHD`.
579: Logically Collective on `PETSC_COMM_WORLD`
581: Input Parameters:
582: + PetscLogPLB - A callback that will be executed by `PetscLogEventBegin()` (or `NULL`)
583: . PetscLogPLE - A callback that will be executed by `PetscLogEventEnd()` (or `NULL`)
584: . PetscLogPHC - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`)
585: - PetscLogPHD - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`)
587: Calling sequence of `PetscLogPLB`:
588: + e - a `PetscLogEvent` that is beginning
589: . _i - deprecated, unused
590: . o1 - a `PetscObject` associated with `e` (or `NULL`)
591: . o2 - a `PetscObject` associated with `e` (or `NULL`)
592: . o3 - a `PetscObject` associated with `e` (or `NULL`)
593: - o4 - a `PetscObject` associated with `e` (or `NULL`)
595: Calling sequence of `PetscLogPLE`:
596: + e - a `PetscLogEvent` that is beginning
597: . _i - deprecated, unused
598: . o1 - a `PetscObject` associated with `e` (or `NULL`)
599: . o2 - a `PetscObject` associated with `e` (or `NULL`)
600: . o3 - a `PetscObject` associated with `e` (or `NULL`)
601: - o4 - a `PetscObject` associated with `e` (or `NULL`)
603: Calling sequence of `PetscLogPHC`:
604: . o - a `PetscObject` that has just been created
606: Calling sequence of `PetscLogPHD`:
607: . o - a `PetscObject` that is about to be destroyed
609: Level: advanced
611: Notes:
612: This is for transitioning from the deprecated function `PetscLogSet()` and should not be used in new code.
614: This should help migrate external log handlers to use `PetscLogHandler`, but
615: callbacks that depend on the deprecated `PetscLogStage` datatype will have to be
616: updated.
618: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerStart()`, `PetscLogState`
619: @*/
620: 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))
621: {
622: PetscLogHandler handler;
624: PetscFunctionBegin;
625: PetscCall(PetscLogHandlerCreateLegacy(PETSC_COMM_WORLD, PetscLogPLB, PetscLogPLE, PetscLogPHC, PetscLogPHD, &handler));
626: PetscCall(PetscLogHandlerStart(handler));
627: PetscCall(PetscLogHandlerDestroy(&handler));
628: PetscFunctionReturn(PETSC_SUCCESS);
629: }
631: #if PetscDefined(HAVE_MPE)
632: #include <mpe.h>
633: static PetscBool PetscBeganMPE = PETSC_FALSE;
634: #endif
636: /*@
637: PetscLogMPEBegin - Turns on MPE logging of events. This creates large log files and slows the
638: program down.
640: Collective on `PETSC_COMM_WORLD`, No Fortran Support
642: Options Database Key:
643: . -log_mpe - Prints extensive log information
645: Level: advanced
647: Note:
648: A related routine is `PetscLogDefaultBegin()` (with the options key `-log_view`), which is
649: intended for production runs since it logs only flop rates and object creation (and should
650: not significantly slow the programs).
652: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogDefaultBegin()`, `PetscLogEventActivate()`,
653: `PetscLogEventDeactivate()`
654: @*/
655: PetscErrorCode PetscLogMPEBegin(void)
656: {
657: PetscFunctionBegin;
658: #if PetscDefined(HAVE_MPE)
659: /* Do MPE initialization */
660: if (!MPE_Initialized_logging()) { /* This function exists in mpich 1.1.2 and higher */
661: PetscCall(PetscInfo(0, "Initializing MPE.\n"));
662: PetscCall(MPE_Init_log());
664: PetscBeganMPE = PETSC_TRUE;
665: } else {
666: PetscCall(PetscInfo(0, "MPE already initialized. Not attempting to reinitialize.\n"));
667: }
668: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERMPE));
669: #else
670: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe");
671: #endif
672: PetscFunctionReturn(PETSC_SUCCESS);
673: }
675: #if PetscDefined(HAVE_TAU_PERFSTUBS)
676: #include <../src/sys/perfstubs/timer.h>
677: #endif
679: /*@
680: PetscLogPerfstubsBegin - Turns on logging of events using the perfstubs interface.
682: Collective on `PETSC_COMM_WORLD`, No Fortran Support
684: Options Database Key:
685: . -log_perfstubs - use an external log handler through the perfstubs interface
687: Level: advanced
689: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogEventActivate()`
690: @*/
691: PetscErrorCode PetscLogPerfstubsBegin(void)
692: {
693: PetscFunctionBegin;
694: #if PetscDefined(HAVE_TAU_PERFSTUBS)
695: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERPERFSTUBS));
696: #else
697: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without perfstubs support, reconfigure with --with-tau-perfstubs");
698: #endif
699: PetscFunctionReturn(PETSC_SUCCESS);
700: }
702: /*@
703: PetscLogActions - Determines whether actions are logged for the default log handler.
705: Not Collective
707: Input Parameter:
708: . flag - `PETSC_TRUE` if actions are to be logged
710: Options Database Key:
711: + -log_exclude_actions - (deprecated) Does nothing
712: - -log_include_actions - Turn on action logging
714: Level: intermediate
716: Note:
717: Logging of actions continues to consume more memory as the program
718: runs. Long running programs should consider turning this feature off.
720: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogGetDefaultHandler()`
721: @*/
722: PetscErrorCode PetscLogActions(PetscBool flag)
723: {
724: PetscFunctionBegin;
725: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
726: PetscLogHandler h = PetscLogHandlers[i].handler;
728: if (h) PetscCall(PetscLogHandlerSetLogActions(h, flag));
729: }
730: PetscFunctionReturn(PETSC_SUCCESS);
731: }
733: /*@
734: PetscLogObjects - Determines whether objects are logged for the graphical viewer.
736: Not Collective
738: Input Parameter:
739: . flag - `PETSC_TRUE` if objects are to be logged
741: Options Database Key:
742: + -log_exclude_objects - (deprecated) Does nothing
743: - -log_include_objects - Turns on object logging
745: Level: intermediate
747: Note:
748: Logging of objects continues to consume more memory as the program
749: runs. Long running programs should consider turning this feature off.
751: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogGetDefaultHandler()`
752: @*/
753: PetscErrorCode PetscLogObjects(PetscBool flag)
754: {
755: PetscFunctionBegin;
756: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
757: PetscLogHandler h = PetscLogHandlers[i].handler;
759: if (h) PetscCall(PetscLogHandlerSetLogObjects(h, flag));
760: }
761: PetscFunctionReturn(PETSC_SUCCESS);
762: }
764: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
765: /*@
766: PetscLogStageRegister - Attaches a character string name to a logging stage.
768: Not Collective
770: Input Parameter:
771: . sname - The name to associate with that stage
773: Output Parameter:
774: . stage - The stage number or -1 if logging is not active (`PetscLogIsActive()`).
776: Level: intermediate
778: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`
779: @*/
780: PetscErrorCode PetscLogStageRegister(const char sname[], PetscLogStage *stage)
781: {
782: PetscLogState state;
784: PetscFunctionBegin;
785: *stage = -1;
786: PetscCall(PetscLogGetState(&state));
787: if (state) PetscCall(PetscLogStateStageRegister(state, sname, stage));
788: PetscFunctionReturn(PETSC_SUCCESS);
789: }
791: /*@
792: PetscLogStagePush - This function pushes a stage on the logging stack. Events started and stopped until `PetscLogStagePop()` will be associated with the stage
794: Not Collective
796: Input Parameter:
797: . stage - The stage on which to log
799: Example Usage:
800: If the option `-log_view` is used to run the program containing the
801: following code, then 2 sets of summary data will be printed during
802: PetscFinalize().
803: .vb
804: PetscInitialize(int *argc,char ***args,0,0);
805: [stage 0 of code]
806: PetscLogStagePush(1);
807: [stage 1 of code]
808: PetscLogStagePop();
809: PetscBarrier(...);
810: [more stage 0 of code]
811: PetscFinalize();
812: .ve
814: Level: intermediate
816: Note:
817: Use `PetscLogStageRegister()` to register a stage.
819: .seealso: [](ch_profiling), `PetscLogStagePop()`, `PetscLogStageRegister()`, `PetscBarrier()`
820: @*/
821: PetscErrorCode PetscLogStagePush(PetscLogStage stage)
822: {
823: PetscLogState state;
825: PetscFunctionBegin;
826: PetscCall(PetscLogGetState(&state));
827: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
828: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
829: PetscLogHandler h = PetscLogHandlers[i].handler;
830: if (h) PetscCall(PetscLogHandlerStagePush(h, stage));
831: }
832: PetscCall(PetscLogStateStagePush(state, stage));
833: PetscFunctionReturn(PETSC_SUCCESS);
834: }
836: /*@
837: PetscLogStagePop - This function pops a stage from the logging stack that was pushed with `PetscLogStagePush()`
839: Not Collective
841: Example Usage:
842: If the option `-log_view` is used to run the program containing the
843: following code, then 2 sets of summary data will be printed during
844: PetscFinalize().
845: .vb
846: PetscInitialize(int *argc,char ***args,0,0);
847: [stage 0 of code]
848: PetscLogStagePush(1);
849: [stage 1 of code]
850: PetscLogStagePop();
851: PetscBarrier(...);
852: [more stage 0 of code]
853: PetscFinalize();
854: .ve
856: Level: intermediate
858: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStageRegister()`, `PetscBarrier()`
859: @*/
860: PetscErrorCode PetscLogStagePop(void)
861: {
862: PetscLogState state;
863: PetscLogStage current_stage;
865: PetscFunctionBegin;
866: PetscCall(PetscLogGetState(&state));
867: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
868: current_stage = state->current_stage;
869: PetscCall(PetscLogStateStagePop(state));
870: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
871: PetscLogHandler h = PetscLogHandlers[i].handler;
872: if (h) PetscCall(PetscLogHandlerStagePop(h, current_stage));
873: }
874: PetscFunctionReturn(PETSC_SUCCESS);
875: }
877: /*@
878: PetscLogStageSetActive - Sets if a stage is used for `PetscLogEventBegin()` and `PetscLogEventEnd()`.
880: Not Collective
882: Input Parameters:
883: + stage - The stage
884: - isActive - The activity flag, `PETSC_TRUE` for logging, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
886: Level: intermediate
888: Note:
889: If this is set to `PETSC_FALSE` the logging acts as if the stage did not exist
891: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`
892: @*/
893: PetscErrorCode PetscLogStageSetActive(PetscLogStage stage, PetscBool isActive)
894: {
895: PetscLogState state;
897: PetscFunctionBegin;
898: PetscCall(PetscLogGetState(&state));
899: if (state) PetscCall(PetscLogStateStageSetActive(state, stage, isActive));
900: PetscFunctionReturn(PETSC_SUCCESS);
901: }
903: /*@
904: PetscLogStageGetActive - Checks if a stage is used for `PetscLogEventBegin()` and `PetscLogEventEnd()`.
906: Not Collective
908: Input Parameter:
909: . stage - The stage
911: Output Parameter:
912: . isActive - The activity flag, `PETSC_TRUE` for logging, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
914: Level: intermediate
916: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`
917: @*/
918: PetscErrorCode PetscLogStageGetActive(PetscLogStage stage, PetscBool *isActive)
919: {
920: PetscLogState state;
922: PetscFunctionBegin;
923: *isActive = PETSC_FALSE;
924: PetscCall(PetscLogGetState(&state));
925: if (state) PetscCall(PetscLogStateStageGetActive(state, stage, isActive));
926: PetscFunctionReturn(PETSC_SUCCESS);
927: }
929: /*@
930: PetscLogStageSetVisible - Determines stage visibility in `PetscLogView()`
932: Not Collective
934: Input Parameters:
935: + stage - The stage
936: - isVisible - The visibility flag, `PETSC_TRUE` to print, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
938: Level: intermediate
940: Developer Notes:
941: Visibility only affects the default log handler in `PetscLogView()`; stages that are
942: set to invisible are suppressed from output.
944: .seealso: [](ch_profiling), `PetscLogStageGetVisible()`, `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
945: @*/
946: PetscErrorCode PetscLogStageSetVisible(PetscLogStage stage, PetscBool isVisible)
947: {
948: PetscFunctionBegin;
949: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
950: PetscLogHandler h = PetscLogHandlers[i].handler;
952: if (h) PetscCall(PetscLogHandlerStageSetVisible(h, stage, isVisible));
953: }
954: PetscFunctionReturn(PETSC_SUCCESS);
955: }
957: /*@
958: PetscLogStageGetVisible - Returns stage visibility in `PetscLogView()`
960: Not Collective
962: Input Parameter:
963: . stage - The stage
965: Output Parameter:
966: . isVisible - The visibility flag, `PETSC_TRUE` to print, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
968: Level: intermediate
970: .seealso: [](ch_profiling), `PetscLogStageSetVisible()`, `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
971: @*/
972: PetscErrorCode PetscLogStageGetVisible(PetscLogStage stage, PetscBool *isVisible)
973: {
974: PetscLogHandler handler;
976: PetscFunctionBegin;
977: *isVisible = PETSC_FALSE;
978: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
979: if (handler) PetscCall(PetscLogHandlerStageGetVisible(handler, stage, isVisible));
980: PetscFunctionReturn(PETSC_SUCCESS);
981: }
983: /*@
984: PetscLogStageGetId - Returns the stage id when given the stage name.
986: Not Collective
988: Input Parameter:
989: . name - The stage name
991: Output Parameter:
992: . stage - The stage, , or -1 if no stage with that name exists
994: Level: intermediate
996: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`
997: @*/
998: PetscErrorCode PetscLogStageGetId(const char name[], PetscLogStage *stage)
999: {
1000: PetscLogState state;
1002: PetscFunctionBegin;
1003: *stage = -1;
1004: PetscCall(PetscLogGetState(&state));
1005: if (state) PetscCall(PetscLogStateGetStageFromName(state, name, stage));
1006: PetscFunctionReturn(PETSC_SUCCESS);
1007: }
1009: /*@
1010: PetscLogStageGetName - Returns the stage name when given the stage id.
1012: Not Collective
1014: Input Parameter:
1015: . stage - The stage
1017: Output Parameter:
1018: . name - The stage name
1020: Level: intermediate
1022: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`
1023: @*/
1024: PetscErrorCode PetscLogStageGetName(PetscLogStage stage, const char *name[])
1025: {
1026: PetscLogStageInfo stage_info;
1027: PetscLogState state;
1029: PetscFunctionBegin;
1030: *name = NULL;
1031: PetscCall(PetscLogGetState(&state));
1032: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1033: PetscCall(PetscLogStateStageGetInfo(state, stage, &stage_info));
1034: *name = stage_info.name;
1035: PetscFunctionReturn(PETSC_SUCCESS);
1036: }
1038: /*------------------------------------------------ Event Functions --------------------------------------------------*/
1040: /*@
1041: PetscLogEventRegister - Registers an event name for logging operations
1043: Not Collective
1045: Input Parameters:
1046: + name - The name associated with the event
1047: - classid - The classid associated to the class for this event, obtain either with
1048: `PetscClassIdRegister()` or use a predefined one such as `KSP_CLASSID`, `SNES_CLASSID`, the predefined ones
1049: are only available in C code
1051: Output Parameter:
1052: . event - The event id for use with `PetscLogEventBegin()` and `PetscLogEventEnd()`.
1054: Example Usage:
1055: .vb
1056: PetscLogEvent USER_EVENT;
1057: PetscClassId classid;
1058: PetscLogDouble user_event_flops;
1059: PetscClassIdRegister("class name",&classid);
1060: PetscLogEventRegister("User event name",classid,&USER_EVENT);
1061: PetscLogEventBegin(USER_EVENT,0,0,0,0);
1062: [code segment to monitor]
1063: PetscLogFlops(user_event_flops);
1064: PetscLogEventEnd(USER_EVENT,0,0,0,0);
1065: .ve
1067: Level: intermediate
1069: Notes:
1070: PETSc automatically logs library events if the code has been
1071: configured with `--with-log` (which is the default) and
1072: `-log_view` or `-log_all` is specified. `PetscLogEventRegister()` is
1073: intended for logging user events to supplement this PETSc
1074: information.
1076: PETSc can gather data for use with the utilities Jumpshot
1077: (part of the MPICH distribution). If PETSc has been compiled
1078: with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
1079: MPICH), the user can employ another command line option, `-log_mpe`,
1080: to create a logfile, "mpe.log", which can be visualized
1081: Jumpshot.
1083: The `classid` is associated with each event so that classes of events
1084: can be disabled simultaneously, such as all matrix events. The user
1085: can either use an existing `classid`, such as `MAT_CLASSID`, or create
1086: their own as shown in the example.
1088: If an existing event with the same name exists, its event handle is
1089: returned instead of creating a new event.
1091: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogFlops()`,
1092: `PetscLogEventActivate()`, `PetscLogEventDeactivate()`, `PetscClassIdRegister()`
1093: @*/
1094: PetscErrorCode PetscLogEventRegister(const char name[], PetscClassId classid, PetscLogEvent *event)
1095: {
1096: PetscLogState state;
1098: PetscFunctionBegin;
1099: *event = -1;
1100: PetscCall(PetscLogGetState(&state));
1101: if (state) PetscCall(PetscLogStateEventRegister(state, name, classid, event));
1102: PetscFunctionReturn(PETSC_SUCCESS);
1103: }
1105: /*@
1106: PetscLogEventSetCollective - Indicates that a particular event is collective.
1108: Logically Collective
1110: Input Parameters:
1111: + event - The event id
1112: - collective - `PetscBool` indicating whether a particular event is collective
1114: Level: developer
1116: Notes:
1117: New events returned from `PetscLogEventRegister()` are collective by default.
1119: Collective events are handled specially if the command line option `-log_sync` is used. In that case the logging saves information about
1120: two parts of the event; the time for all the MPI ranks to synchronize and then the time for the actual computation/communication
1121: to be performed. This option is useful to debug imbalance within the computations or communications.
1123: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventRegister()`
1124: @*/
1125: PetscErrorCode PetscLogEventSetCollective(PetscLogEvent event, PetscBool collective)
1126: {
1127: PetscLogState state;
1129: PetscFunctionBegin;
1130: PetscCall(PetscLogGetState(&state));
1131: if (state) PetscCall(PetscLogStateEventSetCollective(state, event, collective));
1132: PetscFunctionReturn(PETSC_SUCCESS);
1133: }
1135: /*
1136: PetscLogClassSetActiveAll - Activate or inactivate logging for all events associated with a PETSc object class in every stage.
1138: Not Collective
1140: Input Parameters:
1141: + classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1142: - isActive - if `PETSC_FALSE`, events associated with this class will not be send to log handlers.
1144: Level: developer
1146: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventActivateAll()`, `PetscLogStageSetActive()`, `PetscLogEventActivateClass()`
1147: */
1148: static PetscErrorCode PetscLogClassSetActiveAll(PetscClassId classid, PetscBool isActive)
1149: {
1150: PetscLogState state;
1152: PetscFunctionBegin;
1153: PetscCall(PetscLogGetState(&state));
1154: if (state) PetscCall(PetscLogStateClassSetActiveAll(state, classid, isActive));
1155: PetscFunctionReturn(PETSC_SUCCESS);
1156: }
1158: /*@
1159: PetscLogEventIncludeClass - Activates event logging for a PETSc object class in every stage.
1161: Not Collective
1163: Input Parameter:
1164: . classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1166: Level: developer
1168: .seealso: [](ch_profiling), `PetscLogEventActivateClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1169: @*/
1170: PetscErrorCode PetscLogEventIncludeClass(PetscClassId classid)
1171: {
1172: PetscFunctionBegin;
1173: PetscCall(PetscLogClassSetActiveAll(classid, PETSC_TRUE));
1174: PetscFunctionReturn(PETSC_SUCCESS);
1175: }
1177: /*@
1178: PetscLogEventExcludeClass - Deactivates event logging for a PETSc object class in every stage.
1180: Not Collective
1182: Input Parameter:
1183: . classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1185: Level: developer
1187: Note:
1188: If a class is excluded then events associated with that class are not logged.
1190: .seealso: [](ch_profiling), `PetscLogEventDeactivateClass()`, `PetscLogEventActivateClass()`, `PetscLogEventDeactivate()`, `PetscLogEventActivate()`
1191: @*/
1192: PetscErrorCode PetscLogEventExcludeClass(PetscClassId classid)
1193: {
1194: PetscFunctionBegin;
1195: PetscCall(PetscLogClassSetActiveAll(classid, PETSC_FALSE));
1196: PetscFunctionReturn(PETSC_SUCCESS);
1197: }
1199: /*
1200: PetscLogEventSetActive - Activate or inactivate logging for an event in a given stage
1202: Not Collective
1204: Input Parameters:
1205: + stage - A registered `PetscLogStage` (or `PETSC_DEFAULT` for the current stage)
1206: . event - A `PetscLogEvent`
1207: - isActive - If `PETSC_FALSE`, activity from this event (`PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventSync()`) will not be sent to log handlers during this stage
1209: Usage:
1210: .vb
1211: PetscLogEventSetActive(VEC_SetValues, PETSC_FALSE);
1212: [code where you do not want to log VecSetValues()]
1213: PetscLogEventSetActive(VEC_SetValues, PETSC_TRUE);
1214: [code where you do want to log VecSetValues()]
1215: .ve
1217: Level: advanced
1219: Note:
1220: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
1221: or an event number obtained with `PetscLogEventRegister()`.
1223: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1224: */
1225: static PetscErrorCode PetscLogEventSetActive(PetscLogStage stage, PetscLogEvent event, PetscBool isActive)
1226: {
1227: PetscLogState state;
1229: PetscFunctionBegin;
1230: PetscCall(PetscLogGetState(&state));
1231: if (state) PetscCall(PetscLogStateEventSetActive(state, stage, event, isActive));
1232: PetscFunctionReturn(PETSC_SUCCESS);
1233: }
1235: /*@
1236: PetscLogEventActivate - Indicates that a particular event should be logged.
1238: Not Collective
1240: Input Parameter:
1241: . event - The event id
1243: Example Usage:
1244: .vb
1245: PetscLogEventDeactivate(VEC_SetValues);
1246: [code where you do not want to log VecSetValues()]
1247: PetscLogEventActivate(VEC_SetValues);
1248: [code where you do want to log VecSetValues()]
1249: .ve
1251: Level: advanced
1253: Note:
1254: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
1255: or an event number obtained with `PetscLogEventRegister()`.
1257: .seealso: [](ch_profiling), `PetscLogEventDeactivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1258: @*/
1259: PetscErrorCode PetscLogEventActivate(PetscLogEvent event)
1260: {
1261: PetscFunctionBegin;
1262: PetscCall(PetscLogEventSetActive(PETSC_DEFAULT, event, PETSC_TRUE));
1263: PetscFunctionReturn(PETSC_SUCCESS);
1264: }
1266: /*@
1267: PetscLogEventDeactivate - Indicates that a particular event should not be logged.
1269: Not Collective
1271: Input Parameter:
1272: . event - The event id
1274: Example Usage:
1275: .vb
1276: PetscLogEventDeactivate(VEC_SetValues);
1277: [code where you do not want to log VecSetValues()]
1278: PetscLogEventActivate(VEC_SetValues);
1279: [code where you do want to log VecSetValues()]
1280: .ve
1282: Level: advanced
1284: Note:
1285: The event may be either a pre-defined PETSc event (found in
1286: include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1288: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1289: @*/
1290: PetscErrorCode PetscLogEventDeactivate(PetscLogEvent event)
1291: {
1292: PetscFunctionBegin;
1293: PetscCall(PetscLogEventSetActive(PETSC_DEFAULT, event, PETSC_FALSE));
1294: PetscFunctionReturn(PETSC_SUCCESS);
1295: }
1297: /*@
1298: PetscLogEventDeactivatePush - Indicates that a particular event should not be logged until `PetscLogEventDeactivatePop()` is called
1300: Not Collective
1302: Input Parameter:
1303: . event - The event id
1305: Example Usage:
1306: .vb
1307: PetscLogEventDeactivatePush(VEC_SetValues);
1308: [code where you do not want to log VecSetValues()]
1309: PetscLogEventDeactivatePop(VEC_SetValues);
1310: [code where you do want to log VecSetValues()]
1311: .ve
1313: Level: advanced
1315: Note:
1316: The event may be either a pre-defined PETSc event (found in
1317: include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1319: 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.
1321: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivate()`, `PetscLogEventDeactivatePop()`
1322: @*/
1323: PetscErrorCode PetscLogEventDeactivatePush(PetscLogEvent event)
1324: {
1325: PetscFunctionBegin;
1326: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1327: PetscLogHandler h = PetscLogHandlers[i].handler;
1329: if (h) PetscCall(PetscLogHandlerEventDeactivatePush(h, PETSC_DEFAULT, event));
1330: }
1331: PetscFunctionReturn(PETSC_SUCCESS);
1332: }
1334: /*@
1335: PetscLogEventDeactivatePop - Indicates that a particular event should again be logged after the logging was turned off with `PetscLogEventDeactivatePush()`
1337: Not Collective
1339: Input Parameter:
1340: . event - The event id
1342: Example Usage:
1343: .vb
1344: PetscLogEventDeactivatePush(VEC_SetValues);
1345: [code where you do not want to log VecSetValues()]
1346: PetscLogEventDeactivatePop(VEC_SetValues);
1347: [code where you do want to log VecSetValues()]
1348: .ve
1350: Level: advanced
1352: Note:
1353: The event may be either a pre-defined PETSc event (found in
1354: include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1356: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`
1357: @*/
1358: PetscErrorCode PetscLogEventDeactivatePop(PetscLogEvent event)
1359: {
1360: PetscFunctionBegin;
1361: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1362: PetscLogHandler h = PetscLogHandlers[i].handler;
1364: if (h) PetscCall(PetscLogHandlerEventDeactivatePop(h, PETSC_DEFAULT, event));
1365: }
1366: PetscFunctionReturn(PETSC_SUCCESS);
1367: }
1369: /*@
1370: PetscLogEventSetActiveAll - Turns on logging of all events
1372: Not Collective
1374: Input Parameters:
1375: + event - The event id
1376: - isActive - The activity flag determining whether the event is logged
1378: Level: advanced
1380: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1381: @*/
1382: PetscErrorCode PetscLogEventSetActiveAll(PetscLogEvent event, PetscBool isActive)
1383: {
1384: PetscLogState state;
1386: PetscFunctionBegin;
1387: PetscCall(PetscLogGetState(&state));
1388: if (state) PetscCall(PetscLogStateEventSetActiveAll(state, event, isActive));
1389: PetscFunctionReturn(PETSC_SUCCESS);
1390: }
1392: /*
1393: PetscLogClassSetActive - Activates event logging for a PETSc object class for the current stage
1395: Not Collective
1397: Input Parameters:
1398: + stage - A registered `PetscLogStage` (or `PETSC_DEFAULT` for the current stage)
1399: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1400: - isActive - If `PETSC_FALSE`, events associated with this class are not sent to log handlers.
1402: Level: developer
1404: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventActivate()`, `PetscLogEventActivateAll()`, `PetscLogStageSetActive()`
1405: */
1406: static PetscErrorCode PetscLogClassSetActive(PetscLogStage stage, PetscClassId classid, PetscBool isActive)
1407: {
1408: PetscLogState state;
1410: PetscFunctionBegin;
1411: PetscCall(PetscLogGetState(&state));
1412: if (state) PetscCall(PetscLogStateClassSetActive(state, stage, classid, isActive));
1413: PetscFunctionReturn(PETSC_SUCCESS);
1414: }
1416: /*@
1417: PetscLogEventActivateClass - Activates event logging for a PETSc object class for the current stage
1419: Not Collective
1421: Input Parameter:
1422: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1424: Level: developer
1426: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1427: @*/
1428: PetscErrorCode PetscLogEventActivateClass(PetscClassId classid)
1429: {
1430: PetscFunctionBegin;
1431: PetscCall(PetscLogClassSetActive(PETSC_DEFAULT, classid, PETSC_TRUE));
1432: PetscFunctionReturn(PETSC_SUCCESS);
1433: }
1435: /*@
1436: PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class for the current stage
1438: Not Collective
1440: Input Parameter:
1441: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1443: Level: developer
1445: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventActivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1446: @*/
1447: PetscErrorCode PetscLogEventDeactivateClass(PetscClassId classid)
1448: {
1449: PetscFunctionBegin;
1450: PetscCall(PetscLogClassSetActive(PETSC_DEFAULT, classid, PETSC_FALSE));
1451: PetscFunctionReturn(PETSC_SUCCESS);
1452: }
1454: /*MC
1455: PetscLogEventSync - Synchronizes the beginning of an event.
1457: Synopsis:
1458: #include <petsclog.h>
1459: PetscErrorCode PetscLogEventSync(PetscLogEvent e, MPI_Comm comm)
1461: Collective
1463: Input Parameters:
1464: + e - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1465: - comm - an MPI communicator
1467: Example Usage:
1468: .vb
1469: PetscLogEvent USER_EVENT;
1471: PetscLogEventRegister("User event", 0, &USER_EVENT);
1472: PetscLogEventSync(USER_EVENT, PETSC_COMM_WORLD);
1473: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1474: [code segment to monitor]
1475: PetscLogEventEnd(USER_EVENT, 0, 0, 0 , 0);
1476: .ve
1478: Level: developer
1480: Note:
1481: This routine should be called only if there is not a `PetscObject` available to pass to
1482: `PetscLogEventBegin()`.
1484: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`
1485: M*/
1487: /*MC
1488: PetscLogEventBegin - Logs the beginning of an event.
1490: Synopsis:
1491: #include <petsclog.h>
1492: PetscErrorCode PetscLogEventBegin(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
1494: Not Collective
1496: Input Parameters:
1497: + e - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1498: . o1 - object associated with the event, or `NULL`
1499: . o2 - object associated with the event, or `NULL`
1500: . o3 - object associated with the event, or `NULL`
1501: - o4 - object associated with the event, or `NULL`
1503: Fortran Synopsis:
1504: void PetscLogEventBegin(int e, PetscErrorCode ierr)
1506: Example Usage:
1507: .vb
1508: PetscLogEvent USER_EVENT;
1510: PetscLogDouble user_event_flops;
1511: PetscLogEventRegister("User event",0, &USER_EVENT);
1512: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1513: [code segment to monitor]
1514: PetscLogFlops(user_event_flops);
1515: PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
1516: .ve
1518: Level: intermediate
1520: Developer Note:
1521: `PetscLogEventBegin()` and `PetscLogEventBegin()` return error codes instead of explicitly
1522: handling the errors that occur in the macro directly because other packages that use this
1523: macros have used them in their own functions or methods that do not return error codes and it
1524: would be disruptive to change the current behavior.
1526: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventEnd()`, `PetscLogFlops()`
1527: M*/
1529: /*MC
1530: PetscLogEventEnd - Log the end of an event.
1532: Synopsis:
1533: #include <petsclog.h>
1534: PetscErrorCode PetscLogEventEnd(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
1536: Not Collective
1538: Input Parameters:
1539: + e - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1540: . o1 - object associated with the event, or `NULL`
1541: . o2 - object associated with the event, or `NULL`
1542: . o3 - object associated with the event, or `NULL`
1543: - o4 - object associated with the event, or `NULL`
1545: Fortran Synopsis:
1546: void PetscLogEventEnd(int e, PetscErrorCode ierr)
1548: Example Usage:
1549: .vb
1550: PetscLogEvent USER_EVENT;
1552: PetscLogDouble user_event_flops;
1553: PetscLogEventRegister("User event", 0, &USER_EVENT);
1554: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1555: [code segment to monitor]
1556: PetscLogFlops(user_event_flops);
1557: PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
1558: .ve
1560: Level: intermediate
1562: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogFlops()`
1563: M*/
1565: /*@
1566: PetscLogStageGetPerfInfo - Return the performance information about the given stage
1568: No Fortran Support
1570: Input Parameters:
1571: . stage - The stage number or `PETSC_DETERMINE` for the current stage
1573: Output Parameter:
1574: . info - This structure is filled with the performance information
1576: Level: intermediate
1578: Notes:
1579: This is a low level routine used by the logging functions in PETSc.
1581: A `PETSCLOGHANDLERDEFAULT` must be running for this to work, having been started either with
1582: `PetscLogDefaultBegin()` or from the command line with `-log_view`. If it was not started,
1583: all performance statistics in `info` will be zeroed.
1585: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1586: @*/
1587: PetscErrorCode PetscLogStageGetPerfInfo(PetscLogStage stage, PetscEventPerfInfo *info)
1588: {
1589: PetscLogHandler handler;
1590: PetscEventPerfInfo *event_info;
1592: PetscFunctionBegin;
1593: PetscAssertPointer(info, 2);
1594: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1595: if (handler) {
1596: PetscCall(PetscLogHandlerGetStagePerfInfo(handler, stage, &event_info));
1597: *info = *event_info;
1598: } else {
1599: PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogStageGetPerfInfo() returning zeros\n"));
1600: PetscCall(PetscMemzero(info, sizeof(*info)));
1601: }
1602: PetscFunctionReturn(PETSC_SUCCESS);
1603: }
1605: /*@
1606: PetscLogEventGetPerfInfo - Return the performance information about the given event in the given stage
1608: No Fortran Support
1610: Input Parameters:
1611: + stage - The stage number or `PETSC_DETERMINE` for the current stage
1612: - event - The event number
1614: Output Parameter:
1615: . info - This structure is filled with the performance information
1617: Level: intermediate
1619: Note:
1620: This is a low level routine used by the logging functions in PETSc
1622: A `PETSCLOGHANDLERDEFAULT` must be running for this to work, having been started either with
1623: `PetscLogDefaultBegin()` or from the command line with `-log_view`. If it was not started,
1624: all performance statistics in `info` will be zeroed.
1626: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1627: @*/
1628: PetscErrorCode PetscLogEventGetPerfInfo(PetscLogStage stage, PetscLogEvent event, PetscEventPerfInfo *info)
1629: {
1630: PetscLogHandler handler;
1631: PetscEventPerfInfo *event_info;
1633: PetscFunctionBegin;
1634: PetscAssertPointer(info, 3);
1635: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1636: if (handler) {
1637: PetscCall(PetscLogHandlerGetEventPerfInfo(handler, stage, event, &event_info));
1638: *info = *event_info;
1639: } else {
1640: PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogEventGetPerfInfo() returning zeros\n"));
1641: PetscCall(PetscMemzero(info, sizeof(*info)));
1642: }
1643: PetscFunctionReturn(PETSC_SUCCESS);
1644: }
1646: /*@
1647: PetscLogEventSetDof - Set the nth number of degrees of freedom of a numerical problem associated with this event
1649: Not Collective
1651: Input Parameters:
1652: + event - The event id to log
1653: . n - The dof index, in [0, 8)
1654: - dof - The number of dofs
1656: Level: developer
1658: Note:
1659: This is to enable logging of convergence
1661: .seealso: `PetscLogEventSetError()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1662: @*/
1663: PetscErrorCode PetscLogEventSetDof(PetscLogEvent event, PetscInt n, PetscLogDouble dof)
1664: {
1665: PetscFunctionBegin;
1666: PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1667: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1668: PetscLogHandler h = PetscLogHandlers[i].handler;
1670: if (h) {
1671: PetscEventPerfInfo *event_info;
1673: PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1674: if (event_info) event_info->dof[n] = dof;
1675: }
1676: }
1677: PetscFunctionReturn(PETSC_SUCCESS);
1678: }
1680: /*@
1681: PetscLogEventSetError - Set the nth error associated with a numerical problem associated with this event
1683: Not Collective
1685: Input Parameters:
1686: + event - The event id to log
1687: . n - The error index, in [0, 8)
1688: - error - The error
1690: Level: developer
1692: Notes:
1693: This is to enable logging of convergence, and enable users to interpret the errors as they wish. For example,
1694: as different norms, or as errors for different fields
1696: This is a low level routine used by the logging functions in PETSc
1698: .seealso: `PetscLogEventSetDof()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1699: @*/
1700: PetscErrorCode PetscLogEventSetError(PetscLogEvent event, PetscInt n, PetscLogDouble error)
1701: {
1702: PetscFunctionBegin;
1703: PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1704: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1705: PetscLogHandler h = PetscLogHandlers[i].handler;
1707: if (h) {
1708: PetscEventPerfInfo *event_info;
1710: PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1711: if (event_info) event_info->errors[n] = error;
1712: }
1713: }
1714: PetscFunctionReturn(PETSC_SUCCESS);
1715: }
1717: /*@
1718: PetscLogEventGetId - Returns the event id when given the event name.
1720: Not Collective
1722: Input Parameter:
1723: . name - The event name
1725: Output Parameter:
1726: . event - The event, or -1 if no event with that name exists
1728: Level: intermediate
1730: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1731: @*/
1732: PetscErrorCode PetscLogEventGetId(const char name[], PetscLogEvent *event)
1733: {
1734: PetscLogState state;
1736: PetscFunctionBegin;
1737: *event = -1;
1738: PetscCall(PetscLogGetState(&state));
1739: if (state) PetscCall(PetscLogStateGetEventFromName(state, name, event));
1740: PetscFunctionReturn(PETSC_SUCCESS);
1741: }
1743: /*@
1744: PetscLogEventGetName - Returns the event name when given the event id.
1746: Not Collective
1748: Input Parameter:
1749: . event - The event
1751: Output Parameter:
1752: . name - The event name
1754: Level: intermediate
1756: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`
1757: @*/
1758: PetscErrorCode PetscLogEventGetName(PetscLogEvent event, const char *name[])
1759: {
1760: PetscLogEventInfo event_info;
1761: PetscLogState state;
1763: PetscFunctionBegin;
1764: *name = NULL;
1765: PetscCall(PetscLogGetState(&state));
1766: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1767: PetscCall(PetscLogStateEventGetInfo(state, event, &event_info));
1768: *name = event_info.name;
1769: PetscFunctionReturn(PETSC_SUCCESS);
1770: }
1772: /*@
1773: 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.
1775: Not collective
1777: Level: advanced
1779: Notes:
1780: 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()`).
1782: Other log handlers (such as `PetscLogNestedBegin()`) will ignore this function.
1784: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsResume()`, `PetscLogGetDefaultHandler()`
1785: @*/
1786: PetscErrorCode PetscLogEventsPause(void)
1787: {
1788: PetscFunctionBegin;
1789: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1790: PetscLogHandler h = PetscLogHandlers[i].handler;
1792: if (h) PetscCall(PetscLogHandlerEventsPause(h));
1793: }
1794: PetscFunctionReturn(PETSC_SUCCESS);
1795: }
1797: /*@
1798: PetscLogEventsResume - Return logging to normal behavior after it was paused with `PetscLogEventsPause()`.
1800: Not collective
1802: Level: advanced
1804: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsPause()`, `PetscLogGetDefaultHandler()`
1805: @*/
1806: PetscErrorCode PetscLogEventsResume(void)
1807: {
1808: PetscFunctionBegin;
1809: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1810: PetscLogHandler h = PetscLogHandlers[i].handler;
1812: if (h) PetscCall(PetscLogHandlerEventsResume(h));
1813: }
1814: PetscFunctionReturn(PETSC_SUCCESS);
1815: }
1817: /*------------------------------------------------ Class Functions --------------------------------------------------*/
1819: /*MC
1820: PetscLogObjectCreate - Log the creation of a `PetscObject`
1822: Synopsis:
1823: #include <petsclog.h>
1824: PetscErrorCode PetscLogObjectCreate(PetscObject h)
1826: Not Collective
1828: Input Parameters:
1829: . h - A `PetscObject`
1831: Level: developer
1833: Developer Note:
1834: Called internally by PETSc when creating objects: users do not need to call this directly.
1835: Notification of the object creation is sent to each `PetscLogHandler` that is running.
1837: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectDestroy()`
1838: M*/
1840: /*MC
1841: PetscLogObjectDestroy - Logs the destruction of a `PetscObject`
1843: Synopsis:
1844: #include <petsclog.h>
1845: PetscErrorCode PetscLogObjectDestroy(PetscObject h)
1847: Not Collective
1849: Input Parameters:
1850: . h - A `PetscObject`
1852: Level: developer
1854: Developer Note:
1855: Called internally by PETSc when destroying objects: users do not need to call this directly.
1856: Notification of the object creation is sent to each `PetscLogHandler` that is running.
1858: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectCreate()`
1859: M*/
1861: /*@
1862: PetscLogClassGetClassId - Returns the `PetscClassId` when given the class name.
1864: Not Collective
1866: Input Parameter:
1867: . name - The class name
1869: Output Parameter:
1870: . classid - The `PetscClassId` id, or -1 if no class with that name exists
1872: Level: intermediate
1874: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1875: @*/
1876: PetscErrorCode PetscLogClassGetClassId(const char name[], PetscClassId *classid)
1877: {
1878: PetscLogClass log_class;
1879: PetscLogClassInfo class_info;
1880: PetscLogState state;
1882: PetscFunctionBegin;
1883: *classid = -1;
1884: PetscCall(PetscLogGetState(&state));
1885: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1886: PetscCall(PetscLogStateGetClassFromName(state, name, &log_class));
1887: if (log_class < 0) {
1888: *classid = -1;
1889: PetscFunctionReturn(PETSC_SUCCESS);
1890: }
1891: PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1892: *classid = class_info.classid;
1893: PetscFunctionReturn(PETSC_SUCCESS);
1894: }
1896: /*@
1897: PetscLogClassIdGetName - Returns a `PetscClassId`'s name.
1899: Not Collective
1901: Input Parameter:
1902: . classid - A `PetscClassId`
1904: Output Parameter:
1905: . name - The class name
1907: Level: intermediate
1909: .seealso: [](ch_profiling), `PetscLogClassRegister()`, `PetscLogClassBegin()`, `PetscLogClassEnd()`
1910: @*/
1911: PetscErrorCode PetscLogClassIdGetName(PetscClassId classid, const char *name[])
1912: {
1913: PetscLogClass log_class;
1914: PetscLogClassInfo class_info;
1915: PetscLogState state;
1917: PetscFunctionBegin;
1918: PetscCall(PetscLogGetState(&state));
1919: PetscCall(PetscLogStateGetClassFromClassId(state, classid, &log_class));
1920: PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1921: *name = class_info.name;
1922: PetscFunctionReturn(PETSC_SUCCESS);
1923: }
1925: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1926: /*@
1927: PetscLogDump - Dumps logs of objects to a file. There is currently no utility to read the dump file.
1929: Collective on `PETSC_COMM_WORLD`
1931: Input Parameter:
1932: . sname - an optional file name
1934: Example Usage:
1935: .vb
1936: PetscInitialize(...);
1937: PetscLogDefaultBegin();
1938: // ... code ...
1939: PetscLogDump(filename);
1940: PetscFinalize();
1941: .ve
1943: Level: advanced
1945: Note:
1946: The default file name is Log.<rank> where <rank> is the MPI process rank. If no name is specified,
1947: this file will be used.
1949: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
1950: @*/
1951: PetscErrorCode PetscLogDump(const char sname[])
1952: {
1953: PetscLogHandler handler;
1955: PetscFunctionBegin;
1956: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1957: PetscCall(PetscLogHandlerDump(handler, sname));
1958: PetscFunctionReturn(PETSC_SUCCESS);
1959: }
1961: /*@
1962: PetscLogMPEDump - Dumps the MPE logging info to file for later use with Jumpshot.
1964: Collective on `PETSC_COMM_WORLD`
1966: Input Parameter:
1967: . sname - filename for the MPE logfile
1969: Level: advanced
1971: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogMPEBegin()`
1972: @*/
1973: PetscErrorCode PetscLogMPEDump(const char sname[])
1974: {
1975: PetscFunctionBegin;
1976: #if PetscDefined(HAVE_MPE)
1977: if (PetscBeganMPE) {
1978: char name[PETSC_MAX_PATH_LEN];
1980: PetscCall(PetscInfo(0, "Finalizing MPE.\n"));
1981: if (sname) {
1982: PetscCall(PetscStrncpy(name, sname, sizeof(name)));
1983: } else {
1984: PetscCall(PetscGetProgramName(name, sizeof(name)));
1985: }
1986: PetscCall(MPE_Finish_log(name));
1987: } else {
1988: PetscCall(PetscInfo(0, "Not finalizing MPE (not started by PETSc).\n"));
1989: }
1990: #else
1991: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe");
1992: #endif
1993: PetscFunctionReturn(PETSC_SUCCESS);
1994: }
1996: /*@
1997: PetscLogView - Prints a summary of the logging.
1999: Collective
2001: Input Parameter:
2002: . viewer - an ASCII viewer
2004: Options Database Keys:
2005: + -log_view viewer_specification - Views summary of the logging at the conclusion of the program, see `PetscOptionsCreateViewer()` for the format of `viewer_specification`
2006: . -log_view_memory (true|false) - Also display memory usage in each event
2007: . -log_view_gpu_time - Also display time in each event for GPU kernels (Note this may slow the computation)
2008: . -log_view_gpu_energy - Also display energy (estimated with power*gtime) in Joules for GPU kernels
2009: . -log_view_gpu_energy_meter - [Experimental] Also display energy (readings from energy meters) in Joules for GPU kernels.
2010: This option is ignored if `-log_view_gpu_energy` is provided.
2011: . -log_all [filename] - Saves a file `Log.rank` for each MPI process with details of each step of the computation, where
2012: `rank` is the rank of each MPI process
2013: - -log_trace [filename] - Displays a trace of what each process is doing
2015: Level: beginner
2017: Notes:
2018: It is possible to control the logging programmatically but we recommend using the options database approach whenever possible
2019: By default the summary is printed to stdout.
2021: Before calling this routine you must have called either `PetscLogDefaultBegin()` or `PetscLogNestedBegin()`
2023: If PETSc is configured with `--with-log=0` then this functionality is not available
2025: To view the nested XML format `filename.xml` first copy `${PETSC_DIR}/share/petsc/xml/performance_xml2html.xsl` to the current
2026: directory then open `filename.xml` with your browser. Specific notes for certain browsers
2027: .vb
2028: Firefox and Internet explorer - simply open the file
2029: Google Chrome - you must start up Chrome with the option `--allow-file-access-from-files`
2030: Safari - see https://ccm.net/faq/36342-safari-how-to-enable-local-file-access
2031: .ve
2032: or one can use the package <http://xmlsoft.org/XSLT/xsltproc2.html> to translate the xml file to html and then open it with
2033: your browser.
2034: Alternatively, use the script `${PETSC_DIR}/lib/petsc/bin/petsc-performance-view` to automatically open a new browser
2035: window and render the XML log file contents.
2037: The nested XML format was kindly donated by Koos Huijssen and Christiaan M. Klaij MARITIME RESEARCH INSTITUTE NETHERLANDS
2039: The Flame Graph output can be visualised using either the original Flame Graph script <https://github.com/brendangregg/FlameGraph>
2040: or using speedscope <https://www.speedscope.app>.
2041: Old XML profiles may be converted into this format using the script `${PETSC_DIR}/lib/petsc/bin/xml2flamegraph.py`.
2043: Example Usage:
2044: .vb
2045: -log_view :filename - Prints summary of log information to a file
2046: -log_view :filename.py:ascii_info_detail - Saves logging information from each process as a Python file
2047: -log_view :filename.xml:ascii_xml - Saves a summary of the logging information in a nested format (see above for how to view it)
2048: -log_view :filename.txt:ascii_flamegraph - Saves logging information in a format suitable for visualising as a Flame Graph (see above for how to view it)
2049: -log_view :filename.csv:ascii_csv - Saves logging information as a comma-separated values file
2050: .ve
2052: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogDump()`
2053: @*/
2054: PetscErrorCode PetscLogView(PetscViewer viewer)
2055: {
2056: PetscBool isascii;
2057: PetscViewerFormat format;
2058: int stage;
2059: PetscLogState state;
2060: PetscIntStack temp_stack;
2061: PetscLogHandler handler;
2062: PetscBool is_empty;
2064: PetscFunctionBegin;
2065: PetscCall(PetscLogGetState(&state));
2066: /* Pop off any stages the user forgot to remove */
2067: PetscCall(PetscIntStackCreate(&temp_stack));
2068: PetscCall(PetscLogStateGetCurrentStage(state, &stage));
2069: while (stage >= 0) {
2070: PetscCall(PetscLogStagePop());
2071: PetscCall(PetscIntStackPush(temp_stack, stage));
2072: PetscCall(PetscLogStateGetCurrentStage(state, &stage));
2073: }
2074: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
2075: PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Currently can only view logging to ASCII");
2076: PetscCall(PetscViewerGetFormat(viewer, &format));
2077: if (format == PETSC_VIEWER_ASCII_XML || format == PETSC_VIEWER_ASCII_FLAMEGRAPH) {
2078: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERNESTED, &handler));
2079: PetscCall(PetscLogHandlerView(handler, viewer));
2080: } else {
2081: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
2082: PetscCall(PetscLogHandlerView(handler, viewer));
2083: }
2084: PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
2085: while (!is_empty) {
2086: PetscCall(PetscIntStackPop(temp_stack, &stage));
2087: PetscCall(PetscLogStagePush(stage));
2088: PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
2089: }
2090: PetscCall(PetscIntStackDestroy(temp_stack));
2091: PetscFunctionReturn(PETSC_SUCCESS);
2092: }
2094: /*@
2095: PetscLogViewFromOptions - Processes command line options to determine if/how a `PetscLog` is to be viewed.
2097: Collective on `PETSC_COMM_WORLD`
2099: Options Database Key:
2100: . -log_view viewer_specification,viewer_specification - list of up to four specifications of viewers, see `PetscOptionsCreateViewer()` for their format
2102: Level: developer
2104: Note:
2105: This function has a different API and behavior than `PetscObjectViewFromOptions()`
2107: .seealso: [](ch_profiling), `PetscLogView()`
2108: @*/
2109: PetscErrorCode PetscLogViewFromOptions(void)
2110: {
2111: PetscInt n_max = PETSC_LOG_VIEW_FROM_OPTIONS_MAX;
2112: PetscViewer viewers[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2113: PetscViewerFormat formats[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2114: PetscBool flg;
2116: PetscFunctionBegin;
2117: PetscCall(PetscOptionsCreateViewers(PETSC_COMM_WORLD, NULL, NULL, "-log_view", &n_max, viewers, formats, &flg));
2118: /*
2119: PetscLogHandlerView_Default_Info() wants to be sure that the only objects still around are these viewers, so keep track of how many there are
2120: */
2121: PetscLogNumViewersCreated = n_max;
2122: for (PetscInt i = 0; i < n_max; i++) {
2123: PetscInt refct;
2125: PetscCall(PetscViewerPushFormat(viewers[i], formats[i]));
2126: PetscCall(PetscLogView(viewers[i]));
2127: PetscCall(PetscViewerPopFormat(viewers[i]));
2128: PetscCall(PetscObjectGetReference((PetscObject)viewers[i], &refct));
2129: PetscCall(PetscViewerDestroy(&viewers[i]));
2130: if (refct == 1) PetscLogNumViewersDestroyed++;
2131: }
2132: PetscLogNumViewersDestroyed = 0;
2133: PetscFunctionReturn(PETSC_SUCCESS);
2134: }
2136: PETSC_INTERN PetscErrorCode PetscLogHandlerNestedSetThreshold(PetscLogHandler, PetscLogDouble, PetscLogDouble *);
2138: /*@
2139: PetscLogSetThreshold - Set the threshold time for logging the events; this is a percentage out of 100, so 1. means any event
2140: that takes 1 or more percent of the time.
2142: Logically Collective on `PETSC_COMM_WORLD`
2144: Input Parameter:
2145: . newThresh - the threshold to use
2147: Output Parameter:
2148: . oldThresh - the previously set threshold value
2150: Options Database Key:
2151: . -log_threshold threshold - provide the threshold
2153: Example Usage:
2154: .vb
2155: PetscInitialize(...);
2156: PetscLogNestedBegin();
2157: PetscLogSetThreshold(0.1,&oldthresh);
2158: // ... code ...
2159: PetscLogView(viewer);
2160: PetscFinalize();
2161: .ve
2163: Level: advanced
2165: Note:
2166: This threshold is only used by the nested log handler
2168: .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`,
2169: `PetscLogNestedBegin()`
2170: @*/
2171: PetscErrorCode PetscLogSetThreshold(PetscLogDouble newThresh, PetscLogDouble *oldThresh)
2172: {
2173: PetscLogHandler handler;
2175: PetscFunctionBegin;
2176: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERNESTED, &handler));
2177: PetscCall(PetscLogHandlerNestedSetThreshold(handler, newThresh, oldThresh));
2178: PetscFunctionReturn(PETSC_SUCCESS);
2179: }
2181: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
2182: /*@
2183: PetscGetFlops - Returns the number of flops used on this processor
2184: since the program began.
2186: Not Collective
2188: Output Parameter:
2189: . flops - number of floating point operations
2191: Level: intermediate
2193: Notes:
2194: A global counter logs all PETSc flop counts. The user can use
2195: `PetscLogFlops()` to increment this counter to include flops for the
2196: application code.
2198: A separate counter `PetscLogGpuFlops()` logs the flops that occur on any GPU associated with this MPI rank
2200: .seealso: [](ch_profiling), `PetscLogGpuFlops()`, `PetscTime()`, `PetscLogFlops()`
2201: @*/
2202: PetscErrorCode PetscGetFlops(PetscLogDouble *flops)
2203: {
2204: PetscFunctionBegin;
2205: *flops = petsc_TotalFlops;
2206: PetscFunctionReturn(PETSC_SUCCESS);
2207: }
2209: /*@
2210: PetscLogObjectState - Record information about an object with the default log handler
2212: Not Collective
2214: Input Parameters:
2215: + obj - the `PetscObject`
2216: . format - a printf-style format string
2217: - ... - `printf()` arguments to format
2219: Level: developer
2221: .seealso: [](ch_profiling), `PetscLogObjectCreate()`, `PetscLogObjectDestroy()`, `PetscLogGetDefaultHandler()`
2222: @*/
2223: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
2224: {
2225: PetscFunctionBegin;
2226: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2227: PetscLogHandler h = PetscLogHandlers[i].handler;
2229: if (h) {
2230: va_list Argp;
2231: va_start(Argp, format);
2232: PetscCall(PetscLogHandlerLogObjectState_Internal(h, obj, format, Argp));
2233: va_end(Argp);
2234: }
2235: }
2236: PetscFunctionReturn(PETSC_SUCCESS);
2237: }
2239: /*MC
2240: PetscLogFlops - Adds floating point operations to the global counter.
2242: Synopsis:
2243: #include <petsclog.h>
2244: PetscErrorCode PetscLogFlops(PetscLogDouble f)
2246: Not Collective
2248: Input Parameter:
2249: . f - flop counter
2251: Example Usage:
2252: .vb
2253: PetscLogEvent USER_EVENT;
2255: PetscLogEventRegister("User event", 0, &USER_EVENT);
2256: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
2257: [code segment to monitor]
2258: PetscLogFlops(user_flops)
2259: PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
2260: .ve
2262: Level: intermediate
2264: Note:
2265: A global counter logs all PETSc flop counts. The user can use PetscLogFlops() to increment
2266: this counter to include flops for the application code.
2268: .seealso: [](ch_profiling), `PetscLogGpuFlops()`, `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscGetFlops()`
2269: M*/
2271: #if PetscDefined(HAVE_DEVICE)
2272: #include <petsc/private/deviceimpl.h>
2274: /*@
2275: PetscLogGpuTime - turn on the logging of GPU time for GPU kernels
2277: Options Database Key:
2278: . -log_view_gpu_time - provide the GPU times for all events in the `-log_view` output
2280: Level: advanced
2282: Notes:
2283: Turning on the timing of the GPU kernels can slow down the entire computation and should only
2284: be used when studying the performance of individual operations on GPU such as vector operations and
2285: matrix-vector operations.
2287: 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
2289: This routine should only be called once near the beginning of the program. Once it is started
2290: it cannot be turned off.
2292: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTimeBegin()`
2293: @*/
2294: PetscErrorCode PetscLogGpuTime(void)
2295: {
2296: PetscFunctionBegin;
2297: PetscCheck(petsc_gtime == 0.0, PETSC_COMM_SELF, PETSC_ERR_SUP, "GPU logging has already been turned on");
2298: PetscLogGpuTimeFlag = PETSC_TRUE;
2299: PetscFunctionReturn(PETSC_SUCCESS);
2300: }
2302: /*@
2303: PetscLogGpuTimeBegin - Start timer for device
2305: Level: intermediate
2307: Notes:
2308: When GPU is enabled, the timer is run on the GPU, it is a separate logging of time
2309: devoted to GPU computations (excluding kernel launch times).
2311: When GPU is not available, the timer is run on the CPU, it is a separate logging of
2312: time devoted to GPU computations (including kernel launch times).
2314: There is no need to call `WaitForCUDA()` or `WaitForHIP()` between `PetscLogGpuTimeBegin()` and
2315: `PetscLogGpuTimeEnd()`
2317: This timer should NOT include times for data transfers between the GPU and CPU, nor setup
2318: actions such as allocating space.
2320: The regular logging captures the time for data transfers and any CPU activities during the
2321: event. It is used to compute the flop rate on the GPU as it is actively engaged in running a
2322: kernel.
2324: Developer Notes:
2325: The GPU event timer captures the execution time of all the kernels launched in the default
2326: stream by the CPU between `PetscLogGpuTimeBegin()` and `PetscLogGpuTimeEnd()`.
2328: `PetscLogGpuTimeBegin()` and `PetscLogGpuTimeEnd()` insert the begin and end events into the
2329: default stream (stream 0). The device will record a time stamp for the event when it reaches
2330: that event in the stream. The function xxxEventSynchronize() is called in
2331: `PetscLogGpuTimeEnd()` to block CPU execution, but not continued GPU execution, until the
2332: timer event is recorded.
2334: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTime()`
2335: @*/
2336: PetscErrorCode PetscLogGpuTimeBegin(void)
2337: {
2338: PetscBool isActive;
2340: PetscFunctionBegin;
2341: PetscCall(PetscLogEventBeginIsActive(&isActive));
2342: if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2343: if (!PetscDefined(HAVE_KOKKOS_WITHOUT_GPU)) {
2344: PetscDeviceContext dctx;
2346: PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2347: PetscCall(PetscDeviceContextBeginTimer_Internal(dctx));
2348: } else {
2349: PetscCall(PetscTimeSubtract(&petsc_gtime));
2350: }
2351: PetscFunctionReturn(PETSC_SUCCESS);
2352: }
2354: /*@
2355: PetscLogGpuTimeEnd - Stop timer for device
2357: Level: intermediate
2359: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeBegin()`
2360: @*/
2361: PetscErrorCode PetscLogGpuTimeEnd(void)
2362: {
2363: PetscBool isActive;
2365: PetscFunctionBegin;
2366: PetscCall(PetscLogEventEndIsActive(&isActive));
2367: if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2368: if (!PetscDefined(HAVE_KOKKOS_WITHOUT_GPU)) {
2369: PetscDeviceContext dctx;
2370: PetscLogDouble elapsed;
2372: PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2373: PetscCall(PetscDeviceContextEndTimer_Internal(dctx, &elapsed));
2374: petsc_gtime += (elapsed / 1000.0);
2375: #if PetscDefined(HAVE_NVML)
2376: if (PetscLogGpuEnergyFlag) {
2377: PetscLogDouble power;
2378: PetscCall(PetscDeviceContextGetPower_Internal(dctx, &power));
2379: petsc_genergy += (power * elapsed / 1000000.0); // convert to Joules
2380: }
2381: #endif
2382: } else {
2383: PetscCall(PetscTimeAdd(&petsc_gtime));
2384: }
2385: PetscFunctionReturn(PETSC_SUCCESS);
2386: }
2388: /*@
2389: PetscLogGpuEnergy - turn on the logging of GPU energy (estimated with power*gtime) for GPU kernels
2391: Options Database Key:
2392: . -log_view_gpu_energy - provide the GPU energy consumption (estimated with power*gtime) for all events in the `-log_view` output
2394: Level: advanced
2396: Note:
2397: This option is mutually exclusive to `-log_view_gpu_energy_meter`.
2399: Developer Note:
2400: Requires configuring with `--with-cuda-nvml=1` (CUDA >= 12.2). The energy consumption is estimated as
2401: instant_power * gpu_kernel_time. Due to the delay in NVML power sampling, we read the instantaneous power draw at the end of each
2402: event using `nvmlDeviceGetFieldValues()` with the field ID `NVML_FI_DEV_POWER_INSTANT`.
2404: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuEnergyMeter()`
2405: @*/
2406: PetscErrorCode PetscLogGpuEnergy(void)
2407: {
2408: PetscFunctionBegin;
2409: PetscCheck(PetscDefined(HAVE_NVML), PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "-log_view_gpu_energy requires a CUDA build of PETSc configured with --with-cuda-nvml=1 (not used by default)");
2410: PetscCheck(petsc_genergy == 0.0, PETSC_COMM_SELF, PETSC_ERR_SUP, "GPU energy logging has already been turned on");
2411: PetscLogGpuEnergyFlag = PETSC_TRUE;
2412: PetscLogGpuEnergyMeterFlag = PETSC_FALSE;
2413: PetscFunctionReturn(PETSC_SUCCESS);
2414: }
2416: /*@
2417: PetscLogGpuEnergyMeter - turn on the logging of GPU energy (readings from energy meters) for GPU kernels
2419: Options Database Key:
2420: . -log_view_gpu_energy_meter - provide the GPU energy (readings from energy meters) consumption for all events in the `-log_view` output
2422: Level: advanced
2424: Note:
2425: This option is mutually exclusive to `-log_view_gpu_energy`.
2427: Developer Note:
2428: Requires configuring with `--with-cuda-nvml=1` (CUDA >= 12.2). The energy consumption is measured directly using the NVML API
2429: `nvmlDeviceGetTotalEnergyConsumption()`, which returns the total energy used by the GPU since the driver was last initialized.
2430: For newer GPUs, energy readings are updated every 20-100ms, so this approach may be inaccurate for short-duration GPU events.
2432: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuEnergyMeterEnd()`, `PetscLogGpuEnergyMeterBegin()`
2433: @*/
2434: PetscErrorCode PetscLogGpuEnergyMeter(void)
2435: {
2436: PetscFunctionBegin;
2437: PetscCheck(PetscDefined(HAVE_NVML), PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "-log_view_gpu_energy_meter requires a CUDA build of PETSc configured with --with-cuda-nvml=1 (not used by default)");
2438: PetscCheck(petsc_genergy == 0.0, PETSC_COMM_SELF, PETSC_ERR_SUP, "GPU energy logging has already been turned on");
2439: PetscLogGpuEnergyMeterFlag = PETSC_TRUE;
2440: PetscLogGpuEnergyFlag = PETSC_FALSE;
2441: PetscFunctionReturn(PETSC_SUCCESS);
2442: }
2444: /*@
2445: PetscLogGpuEnergyMeterBegin - Start energy meter for device
2447: Level: intermediate
2449: Notes:
2450: The GPU event energy meter captures the energy used by the GPU between `PetscLogGpuEnergyMeterBegin()` and `PetscLogGpuEnergyMeterEnd()`.
2452: `PetscLogGpuEnergyMeterBegin()` and `PetscLogGpuEnergyMeterEnd()` collect the energy readings using `nvmlDeviceGetTotalEnergyConsumption()`.
2453: The function `cupmStreamSynchronize()` is called before the energy query to ensure completion.
2455: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuEnergyMeterEnd()`, `PetscLogGpuEnergyMeter()`
2456: @*/
2457: PetscErrorCode PetscLogGpuEnergyMeterBegin(void)
2458: {
2459: PetscBool isActive;
2461: PetscFunctionBegin;
2462: PetscCall(PetscLogEventBeginIsActive(&isActive));
2463: if (!isActive || !PetscLogGpuEnergyMeterFlag) PetscFunctionReturn(PETSC_SUCCESS);
2464: if (!PetscDefined(HAVE_KOKKOS_WITHOUT_GPU)) {
2465: PetscDeviceContext dctx;
2467: PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2468: PetscCall(PetscDeviceContextBeginEnergyMeter_Internal(dctx));
2469: }
2470: PetscFunctionReturn(PETSC_SUCCESS);
2471: }
2473: /*@
2474: PetscLogGpuEnergyMeterEnd - Stop energy meter for device
2476: Level: intermediate
2478: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuEnergyMeterBegin()`
2479: @*/
2480: PetscErrorCode PetscLogGpuEnergyMeterEnd(void)
2481: {
2482: PetscBool isActive;
2484: PetscFunctionBegin;
2485: PetscCall(PetscLogEventEndIsActive(&isActive));
2486: if (!isActive || !PetscLogGpuEnergyMeterFlag) PetscFunctionReturn(PETSC_SUCCESS);
2487: if (!PetscDefined(HAVE_KOKKOS_WITHOUT_GPU)) {
2488: PetscDeviceContext dctx;
2489: PetscLogDouble energy;
2491: PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2492: PetscCall(PetscDeviceContextEndEnergyMeter_Internal(dctx, &energy));
2493: petsc_genergy_meter += (energy / 1000.0); // convert to Joules
2494: }
2495: PetscFunctionReturn(PETSC_SUCCESS);
2496: }
2497: #endif /* end of PETSC_HAVE_DEVICE */
2499: #endif /* PETSC_USE_LOG*/
2501: PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2502: PetscClassId PETSC_OBJECT_CLASSID = 0;
2504: static PetscBool PetscLogInitializeCalled = PETSC_FALSE;
2506: PETSC_INTERN PetscErrorCode PetscLogInitialize(void)
2507: {
2508: int stage;
2510: PetscFunctionBegin;
2511: if (PetscLogInitializeCalled) PetscFunctionReturn(PETSC_SUCCESS);
2512: PetscLogInitializeCalled = PETSC_TRUE;
2513: if (PetscDefined(USE_LOG)) {
2514: /* Setup default logging structures */
2515: PetscCall(PetscLogStateCreate(&petsc_log_state));
2516: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2517: if (PetscLogHandlers[i].handler) PetscCall(PetscLogHandlerSetState(PetscLogHandlers[i].handler, petsc_log_state));
2518: }
2519: PetscCall(PetscLogStateStageRegister(petsc_log_state, "Main Stage", &stage));
2520: PetscCall(PetscSpinlockCreate(&PetscLogSpinLock));
2521: #if PetscDefined(HAVE_THREADSAFETY)
2522: petsc_log_tid = 0;
2523: petsc_log_gid = 0;
2524: #endif
2526: /* All processors sync here for more consistent logging */
2527: PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
2528: PetscCall(PetscTime(&petsc_BaseTime));
2529: PetscCall(PetscLogStagePush(stage));
2530: }
2531: PetscFunctionReturn(PETSC_SUCCESS);
2532: }
2534: PETSC_INTERN PetscErrorCode PetscLogFinalize(void)
2535: {
2536: PetscFunctionBegin;
2537: if (PetscDefined(USE_LOG)) {
2538: /* Resetting phase */
2539: // pop remaining stages
2540: if (petsc_log_state) {
2541: while (petsc_log_state->current_stage >= 0) PetscCall(PetscLogStagePop());
2542: }
2543: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) PetscCall(PetscLogHandlerDestroy(&PetscLogHandlers[i].handler));
2544: PetscCall(PetscArrayzero(PetscLogHandlers, PETSC_LOG_HANDLER_MAX));
2545: PetscCall(PetscLogStateDestroy(&petsc_log_state));
2547: petsc_TotalFlops = 0.0;
2548: petsc_BaseTime = 0.0;
2549: petsc_TotalFlops = 0.0;
2550: petsc_send_ct = 0.0;
2551: petsc_recv_ct = 0.0;
2552: petsc_send_len = 0.0;
2553: petsc_recv_len = 0.0;
2554: petsc_isend_ct = 0.0;
2555: petsc_irecv_ct = 0.0;
2556: petsc_isend_len = 0.0;
2557: petsc_irecv_len = 0.0;
2558: petsc_wait_ct = 0.0;
2559: petsc_wait_any_ct = 0.0;
2560: petsc_wait_all_ct = 0.0;
2561: petsc_sum_of_waits_ct = 0.0;
2562: petsc_allreduce_ct = 0.0;
2563: petsc_gather_ct = 0.0;
2564: petsc_scatter_ct = 0.0;
2565: petsc_TotalFlops_th = 0.0;
2566: petsc_send_ct_th = 0.0;
2567: petsc_recv_ct_th = 0.0;
2568: petsc_send_len_th = 0.0;
2569: petsc_recv_len_th = 0.0;
2570: petsc_isend_ct_th = 0.0;
2571: petsc_irecv_ct_th = 0.0;
2572: petsc_isend_len_th = 0.0;
2573: petsc_irecv_len_th = 0.0;
2574: petsc_wait_ct_th = 0.0;
2575: petsc_wait_any_ct_th = 0.0;
2576: petsc_wait_all_ct_th = 0.0;
2577: petsc_sum_of_waits_ct_th = 0.0;
2578: petsc_allreduce_ct_th = 0.0;
2579: petsc_gather_ct_th = 0.0;
2580: petsc_scatter_ct_th = 0.0;
2582: petsc_ctog_ct = 0.0;
2583: petsc_gtoc_ct = 0.0;
2584: petsc_ctog_sz = 0.0;
2585: petsc_gtoc_sz = 0.0;
2586: petsc_gflops = 0.0;
2587: petsc_gtime = 0.0;
2588: petsc_genergy = 0.0;
2589: petsc_genergy_meter = 0.0;
2590: petsc_ctog_ct_th = 0.0;
2591: petsc_gtoc_ct_th = 0.0;
2592: petsc_ctog_sz_th = 0.0;
2593: petsc_gtoc_sz_th = 0.0;
2594: petsc_gflops_th = 0.0;
2595: petsc_gtime_th = 0.0;
2596: }
2597: PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2598: PETSC_OBJECT_CLASSID = 0;
2599: PetscLogInitializeCalled = PETSC_FALSE;
2600: PetscFunctionReturn(PETSC_SUCCESS);
2601: }
2603: /*@
2604: PetscClassIdRegister - Registers a new class name for objects and logging operations in an application code.
2606: Not Collective
2608: Input Parameter:
2609: . name - The class name
2611: Output Parameter:
2612: . oclass - The class id or classid
2614: Level: developer
2616: .seealso: [](ch_profiling), `PetscLogEventRegister()`
2617: @*/
2618: PetscErrorCode PetscClassIdRegister(const char name[], PetscClassId *oclass)
2619: {
2620: PetscFunctionBegin;
2621: *oclass = ++PETSC_LARGEST_CLASSID;
2622: #if PetscDefined(USE_LOG)
2623: {
2624: PetscLogState state;
2625: PetscLogClass logclass;
2627: PetscCall(PetscLogGetState(&state));
2628: if (state) PetscCall(PetscLogStateClassRegister(state, name, *oclass, &logclass));
2629: }
2630: #endif
2631: PetscFunctionReturn(PETSC_SUCCESS);
2632: }