Actual source code: plog.c
1: /*
2: PETSc code to log object creation and destruction and PETSc events.
4: This provides the public API used by the rest of PETSc and by users.
6: These routines use a private API that is not used elsewhere in PETSc and is not
7: accessible to users. The private API is defined in logimpl.h and the utils directory.
9: ***
11: This file, and only this file, is for functions that interact with the global logging state
12: */
13: #include <petsc/private/logimpl.h>
14: #include <petsc/private/loghandlerimpl.h>
15: #include <petsctime.h>
16: #include <petscviewer.h>
17: #include <petscdevice.h>
18: #include <petsc/private/deviceimpl.h>
20: #if defined(PETSC_HAVE_THREADSAFETY)
22: PetscInt petsc_log_gid = -1; /* Global threadId counter */
23: PETSC_TLS PetscInt petsc_log_tid = -1; /* Local threadId */
25: /* shared variables */
26: PetscSpinlock PetscLogSpinLock;
28: PetscInt PetscLogGetTid(void)
29: {
30: if (petsc_log_tid < 0) {
31: PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
32: petsc_log_tid = ++petsc_log_gid;
33: PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
34: }
35: return petsc_log_tid;
36: }
38: #endif
40: /* Global counters */
41: PetscLogDouble petsc_BaseTime = 0.0;
42: PetscLogDouble petsc_TotalFlops = 0.0; /* The number of flops */
43: PetscLogDouble petsc_send_ct = 0.0; /* The number of sends */
44: PetscLogDouble petsc_recv_ct = 0.0; /* The number of receives */
45: PetscLogDouble petsc_send_len = 0.0; /* The total length of all sent messages */
46: PetscLogDouble petsc_recv_len = 0.0; /* The total length of all received messages */
47: PetscLogDouble petsc_isend_ct = 0.0; /* The number of immediate sends */
48: PetscLogDouble petsc_irecv_ct = 0.0; /* The number of immediate receives */
49: PetscLogDouble petsc_isend_len = 0.0; /* The total length of all immediate send messages */
50: PetscLogDouble petsc_irecv_len = 0.0; /* The total length of all immediate receive messages */
51: PetscLogDouble petsc_wait_ct = 0.0; /* The number of waits */
52: PetscLogDouble petsc_wait_any_ct = 0.0; /* The number of anywaits */
53: PetscLogDouble petsc_wait_all_ct = 0.0; /* The number of waitalls */
54: PetscLogDouble petsc_sum_of_waits_ct = 0.0; /* The total number of waits */
55: PetscLogDouble petsc_allreduce_ct = 0.0; /* The number of reductions */
56: PetscLogDouble petsc_gather_ct = 0.0; /* The number of gathers and gathervs */
57: PetscLogDouble petsc_scatter_ct = 0.0; /* The number of scatters and scattervs */
59: /* Thread Local storage */
60: PETSC_TLS PetscLogDouble petsc_TotalFlops_th = 0.0;
61: PETSC_TLS PetscLogDouble petsc_send_ct_th = 0.0;
62: PETSC_TLS PetscLogDouble petsc_recv_ct_th = 0.0;
63: PETSC_TLS PetscLogDouble petsc_send_len_th = 0.0;
64: PETSC_TLS PetscLogDouble petsc_recv_len_th = 0.0;
65: PETSC_TLS PetscLogDouble petsc_isend_ct_th = 0.0;
66: PETSC_TLS PetscLogDouble petsc_irecv_ct_th = 0.0;
67: PETSC_TLS PetscLogDouble petsc_isend_len_th = 0.0;
68: PETSC_TLS PetscLogDouble petsc_irecv_len_th = 0.0;
69: PETSC_TLS PetscLogDouble petsc_wait_ct_th = 0.0;
70: PETSC_TLS PetscLogDouble petsc_wait_any_ct_th = 0.0;
71: PETSC_TLS PetscLogDouble petsc_wait_all_ct_th = 0.0;
72: PETSC_TLS PetscLogDouble petsc_sum_of_waits_ct_th = 0.0;
73: PETSC_TLS PetscLogDouble petsc_allreduce_ct_th = 0.0;
74: PETSC_TLS PetscLogDouble petsc_gather_ct_th = 0.0;
75: PETSC_TLS PetscLogDouble petsc_scatter_ct_th = 0.0;
77: PetscLogDouble petsc_ctog_ct = 0.0; /* The total number of CPU to GPU copies */
78: PetscLogDouble petsc_gtoc_ct = 0.0; /* The total number of GPU to CPU copies */
79: PetscLogDouble petsc_ctog_sz = 0.0; /* The total size of CPU to GPU copies */
80: PetscLogDouble petsc_gtoc_sz = 0.0; /* The total size of GPU to CPU copies */
81: PetscLogDouble petsc_ctog_ct_scalar = 0.0; /* The total number of CPU to GPU copies */
82: PetscLogDouble petsc_gtoc_ct_scalar = 0.0; /* The total number of GPU to CPU copies */
83: PetscLogDouble petsc_ctog_sz_scalar = 0.0; /* The total size of CPU to GPU copies */
84: PetscLogDouble petsc_gtoc_sz_scalar = 0.0; /* The total size of GPU to CPU copies */
85: PetscLogDouble petsc_gflops = 0.0; /* The flops done on a GPU */
86: PetscLogDouble petsc_gtime = 0.0; /* The time spent on a GPU */
88: PETSC_TLS PetscLogDouble petsc_ctog_ct_th = 0.0;
89: PETSC_TLS PetscLogDouble petsc_gtoc_ct_th = 0.0;
90: PETSC_TLS PetscLogDouble petsc_ctog_sz_th = 0.0;
91: PETSC_TLS PetscLogDouble petsc_gtoc_sz_th = 0.0;
92: PETSC_TLS PetscLogDouble petsc_ctog_ct_scalar_th = 0.0;
93: PETSC_TLS PetscLogDouble petsc_gtoc_ct_scalar_th = 0.0;
94: PETSC_TLS PetscLogDouble petsc_ctog_sz_scalar_th = 0.0;
95: PETSC_TLS PetscLogDouble petsc_gtoc_sz_scalar_th = 0.0;
96: PETSC_TLS PetscLogDouble petsc_gflops_th = 0.0;
97: PETSC_TLS PetscLogDouble petsc_gtime_th = 0.0;
99: PetscBool PetscLogMemory = PETSC_FALSE;
100: PetscBool PetscLogSyncOn = PETSC_FALSE;
102: PetscBool PetscLogGpuTimeFlag = PETSC_FALSE;
104: PetscInt PetscLogNumViewersCreated = 0;
105: PetscInt PetscLogNumViewersDestroyed = 0;
107: PetscLogState petsc_log_state = NULL;
109: #define PETSC_LOG_HANDLER_HOT_BLANK {NULL, NULL, NULL, NULL, NULL, NULL}
111: PetscLogHandlerHot PetscLogHandlers[PETSC_LOG_HANDLER_MAX] = {
112: PETSC_LOG_HANDLER_HOT_BLANK,
113: PETSC_LOG_HANDLER_HOT_BLANK,
114: PETSC_LOG_HANDLER_HOT_BLANK,
115: PETSC_LOG_HANDLER_HOT_BLANK,
116: };
118: #undef PETSC_LOG_HANDLERS_HOT_BLANK
120: #if defined(PETSC_USE_LOG)
121: #include <../src/sys/logging/handler/impls/default/logdefault.h>
123: #if defined(PETSC_HAVE_THREADSAFETY)
124: PetscErrorCode PetscAddLogDouble(PetscLogDouble *tot, PetscLogDouble *tot_th, PetscLogDouble tmp)
125: {
126: *tot_th += tmp;
127: PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
128: *tot += tmp;
129: PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
130: return PETSC_SUCCESS;
131: }
133: PetscErrorCode PetscAddLogDoubleCnt(PetscLogDouble *cnt, PetscLogDouble *tot, PetscLogDouble *cnt_th, PetscLogDouble *tot_th, PetscLogDouble tmp)
134: {
135: *cnt_th = *cnt_th + 1;
136: *tot_th += tmp;
137: PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
138: *tot += (PetscLogDouble)tmp;
139: *cnt += *cnt + 1;
140: PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
141: return PETSC_SUCCESS;
142: }
144: #endif
146: static PetscErrorCode PetscLogTryGetHandler(PetscLogHandlerType type, PetscLogHandler *handler)
147: {
148: PetscFunctionBegin;
149: PetscAssertPointer(handler, 2);
150: *handler = NULL;
151: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
152: PetscLogHandler h = PetscLogHandlers[i].handler;
153: if (h) {
154: PetscBool match;
156: PetscCall(PetscObjectTypeCompare((PetscObject)h, type, &match));
157: if (match) {
158: *handler = PetscLogHandlers[i].handler;
159: PetscFunctionReturn(PETSC_SUCCESS);
160: }
161: }
162: }
163: PetscFunctionReturn(PETSC_SUCCESS);
164: }
166: /*@
167: PetscLogGetDefaultHandler - Get the default log handler if it is running.
169: Not collective
171: Output Parameter:
172: . handler - the default `PetscLogHandler`, or `NULL` if it is not running.
174: Level: developer
176: Notes:
177: The default handler is started with `PetscLogDefaultBegin()`,
178: if the options flags `-log_all` or `-log_view` is given without arguments,
179: or for `-log_view :output:format` if `format` is not `ascii_xml` or `ascii_flamegraph`.
181: .seealso: [](ch_profiling)
182: @*/
183: PetscErrorCode PetscLogGetDefaultHandler(PetscLogHandler *handler)
184: {
185: PetscFunctionBegin;
186: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, handler));
187: PetscFunctionReturn(PETSC_SUCCESS);
188: }
190: static PetscErrorCode PetscLogGetHandler(PetscLogHandlerType type, PetscLogHandler *handler)
191: {
192: PetscFunctionBegin;
193: PetscAssertPointer(handler, 2);
194: PetscCall(PetscLogTryGetHandler(type, handler));
195: PetscCheck(*handler != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "A PetscLogHandler of type %s has not been started.", type);
196: PetscFunctionReturn(PETSC_SUCCESS);
197: }
199: /*@
200: PetscLogGetState - Get the `PetscLogState` for PETSc's global logging, used
201: by all default log handlers (`PetscLogDefaultBegin()`,
202: `PetscLogNestedBegin()`, `PetscLogTraceBegin()`, `PetscLogMPEBegin()`,
203: `PetscLogPerfstubsBegin()`).
205: Collective on `PETSC_COMM_WORLD`
207: Output Parameter:
208: . state - The `PetscLogState` changed by registrations (such as
209: `PetscLogEventRegister()`) and actions (such as `PetscLogEventBegin()` or
210: `PetscLogStagePush()`), or `NULL` if logging is not active
212: Level: developer
214: .seealso: [](ch_profiling), `PetscLogState`
215: @*/
216: PetscErrorCode PetscLogGetState(PetscLogState *state)
217: {
218: PetscFunctionBegin;
219: PetscAssertPointer(state, 1);
220: *state = petsc_log_state;
221: PetscFunctionReturn(PETSC_SUCCESS);
222: }
224: static PetscErrorCode PetscLogHandlerCopyToHot(PetscLogHandler h, PetscLogHandlerHot *hot)
225: {
226: PetscFunctionBegin;
227: hot->handler = h;
228: hot->eventBegin = h->ops->eventbegin;
229: hot->eventEnd = h->ops->eventend;
230: hot->eventSync = h->ops->eventsync;
231: hot->objectCreate = h->ops->objectcreate;
232: hot->objectDestroy = h->ops->objectdestroy;
233: PetscFunctionReturn(PETSC_SUCCESS);
234: }
236: /*@
237: PetscLogHandlerStart - Connect a log handler to PETSc's global logging stream and state.
239: Logically collective
241: Input Parameters:
242: . h - a `PetscLogHandler`
244: Level: developer
246: Notes:
247: Users should only need this if they create their own log handlers: handlers that are started
248: from the command line (such as `-log_view` and `-log_trace`) or from a function like
249: `PetscLogNestedBegin()` will automatically be started.
251: There is a limit of `PESC_LOG_HANDLER_MAX` handlers that can be active at one time.
253: To disconnect a handler from the global stream call `PetscLogHandlerStop()`.
255: When a log handler is started, stages that have already been pushed with `PetscLogStagePush()`,
256: will be pushed for the new log handler, but it will not be informed of any events that are
257: in progress. It is recommended to start any user-defined log handlers immediately following
258: `PetscInitialize()` before any user-defined stages are pushed.
260: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogHandlerStop()`, `PetscInitialize()`
261: @*/
262: PetscErrorCode PetscLogHandlerStart(PetscLogHandler h)
263: {
264: PetscFunctionBegin;
265: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
266: if (PetscLogHandlers[i].handler == h) PetscFunctionReturn(PETSC_SUCCESS);
267: }
268: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
269: if (PetscLogHandlers[i].handler == NULL) {
270: PetscCall(PetscObjectReference((PetscObject)h));
271: PetscCall(PetscLogHandlerCopyToHot(h, &PetscLogHandlers[i]));
272: if (petsc_log_state) {
273: PetscLogStage stack_height;
274: PetscIntStack orig_stack, temp_stack;
276: PetscCall(PetscLogHandlerSetState(h, petsc_log_state));
277: stack_height = petsc_log_state->stage_stack->top + 1;
278: PetscCall(PetscIntStackCreate(&temp_stack));
279: orig_stack = petsc_log_state->stage_stack;
280: petsc_log_state->stage_stack = temp_stack;
281: petsc_log_state->current_stage = -1;
282: for (int s = 0; s < stack_height; s++) {
283: PetscLogStage stage = orig_stack->stack[s];
284: PetscCall(PetscLogHandlerStagePush(h, stage));
285: PetscCall(PetscIntStackPush(temp_stack, stage));
286: petsc_log_state->current_stage = stage;
287: }
288: PetscCall(PetscIntStackDestroy(temp_stack));
289: petsc_log_state->stage_stack = orig_stack;
290: }
291: PetscFunctionReturn(PETSC_SUCCESS);
292: }
293: }
294: SETERRQ(PetscObjectComm((PetscObject)h), PETSC_ERR_ARG_WRONGSTATE, "%d log handlers already started, cannot start another", PETSC_LOG_HANDLER_MAX);
295: PetscFunctionReturn(PETSC_SUCCESS);
296: }
298: /*@
299: PetscLogHandlerStop - Disconnect a log handler from PETSc's global logging stream.
301: Logically collective
303: Input Parameters:
304: . h - a `PetscLogHandler`
306: Level: developer
308: Note:
309: After `PetscLogHandlerStop()`, the handler can still access the global logging state
310: with `PetscLogHandlerGetState()`, so that it can access the registry when post-processing
311: (for instance, in `PetscLogHandlerView()`),
313: When a log handler is stopped, the remaining stages will be popped before it is
314: disconnected from the log stream.
316: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogHandlerStart()`
317: @*/
318: PetscErrorCode PetscLogHandlerStop(PetscLogHandler h)
319: {
320: PetscFunctionBegin;
321: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
322: if (PetscLogHandlers[i].handler == h) {
323: if (petsc_log_state) {
324: PetscLogState state;
325: PetscLogStage stack_height;
326: PetscIntStack orig_stack, temp_stack;
328: PetscCall(PetscLogHandlerGetState(h, &state));
329: PetscCheck(state == petsc_log_state, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "Called PetscLogHandlerStop() for a PetscLogHander that was not started.");
330: stack_height = petsc_log_state->stage_stack->top + 1;
331: PetscCall(PetscIntStackCreate(&temp_stack));
332: orig_stack = petsc_log_state->stage_stack;
333: petsc_log_state->stage_stack = temp_stack;
334: for (int s = 0; s < stack_height; s++) {
335: PetscLogStage stage = orig_stack->stack[s];
337: PetscCall(PetscIntStackPush(temp_stack, stage));
338: }
339: for (int s = 0; s < stack_height; s++) {
340: PetscLogStage stage;
341: PetscBool empty;
343: PetscCall(PetscIntStackPop(temp_stack, &stage));
344: PetscCall(PetscIntStackEmpty(temp_stack, &empty));
345: if (!empty) PetscCall(PetscIntStackTop(temp_stack, &petsc_log_state->current_stage));
346: else petsc_log_state->current_stage = -1;
347: PetscCall(PetscLogHandlerStagePop(h, stage));
348: }
349: PetscCall(PetscIntStackDestroy(temp_stack));
350: petsc_log_state->stage_stack = orig_stack;
351: PetscCall(PetscIntStackTop(petsc_log_state->stage_stack, &petsc_log_state->current_stage));
352: }
353: PetscCall(PetscArrayzero(&PetscLogHandlers[i], 1));
354: PetscCall(PetscObjectDereference((PetscObject)h));
355: }
356: }
357: PetscFunctionReturn(PETSC_SUCCESS);
358: }
360: /*@
361: PetscLogIsActive - Check if logging (profiling) is currently in progress.
363: Not Collective
365: Output Parameter:
366: . isActive - `PETSC_TRUE` if logging is in progress, `PETSC_FALSE` otherwise
368: Level: beginner
370: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`
371: @*/
372: PetscErrorCode PetscLogIsActive(PetscBool *isActive)
373: {
374: PetscFunctionBegin;
375: *isActive = PETSC_FALSE;
376: if (petsc_log_state) {
377: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
378: if (PetscLogHandlers[i].handler) {
379: *isActive = PETSC_TRUE;
380: PetscFunctionReturn(PETSC_SUCCESS);
381: }
382: }
383: }
384: PetscFunctionReturn(PETSC_SUCCESS);
385: }
387: PETSC_UNUSED static PetscErrorCode PetscLogEventBeginIsActive(PetscBool *isActive)
388: {
389: PetscFunctionBegin;
390: *isActive = PETSC_FALSE;
391: if (petsc_log_state) {
392: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
393: if (PetscLogHandlers[i].eventBegin) {
394: *isActive = PETSC_TRUE;
395: PetscFunctionReturn(PETSC_SUCCESS);
396: }
397: }
398: }
399: PetscFunctionReturn(PETSC_SUCCESS);
400: }
402: PETSC_UNUSED static PetscErrorCode PetscLogEventEndIsActive(PetscBool *isActive)
403: {
404: PetscFunctionBegin;
405: *isActive = PETSC_FALSE;
406: if (petsc_log_state) {
407: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
408: if (PetscLogHandlers[i].eventEnd) {
409: *isActive = PETSC_TRUE;
410: PetscFunctionReturn(PETSC_SUCCESS);
411: }
412: }
413: }
414: PetscFunctionReturn(PETSC_SUCCESS);
415: }
417: PETSC_INTERN PetscErrorCode PetscLogTypeBegin(PetscLogHandlerType type)
418: {
419: PetscLogHandler handler;
421: PetscFunctionBegin;
422: PetscCall(PetscLogTryGetHandler(type, &handler));
423: if (handler) PetscFunctionReturn(PETSC_SUCCESS);
424: PetscCall(PetscLogHandlerCreate(PETSC_COMM_WORLD, &handler));
425: PetscCall(PetscLogHandlerSetType(handler, type));
426: PetscCall(PetscLogHandlerStart(handler));
427: PetscCall(PetscLogHandlerDestroy(&handler));
428: PetscFunctionReturn(PETSC_SUCCESS);
429: }
431: /*@
432: PetscLogDefaultBegin - Turns on logging (profiling) of PETSc code using the default log handler (profiler). This logs time, flop
433: rates, and object creation and should not slow programs down too much.
435: Logically Collective on `PETSC_COMM_WORLD`
437: Options Database Key:
438: . -log_view [viewertype:filename:viewerformat] - Prints summary of flop and timing (profiling) information to the
439: screen (for PETSc configured with `--with-log=1` (which is the default)).
440: This option must be provided before `PetscInitialize()`.
442: Example Usage:
443: .vb
444: PetscInitialize(...);
445: PetscLogDefaultBegin();
446: ... code ...
447: PetscLogView(viewer); or PetscLogDump();
448: PetscFinalize();
449: .ve
451: Level: advanced
453: Notes:
454: `PetscLogView()` or `PetscLogDump()` actually cause the printing of
455: the logging information.
457: This routine may be called more than once.
459: To provide the `-log_view` option in your source code you must call PetscCall(PetscOptionsSetValue(NULL, "-log_view", NULL));
460: before you call `PetscInitialize()`
462: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`
463: @*/
464: PetscErrorCode PetscLogDefaultBegin(void)
465: {
466: PetscFunctionBegin;
467: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERDEFAULT));
468: PetscFunctionReturn(PETSC_SUCCESS);
469: }
471: /*@C
472: PetscLogTraceBegin - Begins trace logging. Every time a PETSc event
473: begins or ends, the event name is printed.
475: Logically Collective on `PETSC_COMM_WORLD`, No Fortran Support
477: Input Parameter:
478: . file - The file to print trace in (e.g. stdout)
480: Options Database Key:
481: . -log_trace [filename] - Begins `PetscLogTraceBegin()`
483: Level: intermediate
485: Notes:
486: `PetscLogTraceBegin()` prints the processor number, the execution time (sec),
487: then "Event begin:" or "Event end:" followed by the event name.
489: `PetscLogTraceBegin()` allows tracing of all PETSc calls, which is useful
490: to determine where a program is hanging without running in the
491: debugger. Can be used in conjunction with the -info option.
493: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogView()`, `PetscLogDefaultBegin()`
494: @*/
495: PetscErrorCode PetscLogTraceBegin(FILE *file)
496: {
497: PetscLogHandler handler;
499: PetscFunctionBegin;
500: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERTRACE, &handler));
501: if (handler) PetscFunctionReturn(PETSC_SUCCESS);
502: PetscCall(PetscLogHandlerCreateTrace(PETSC_COMM_WORLD, file, &handler));
503: PetscCall(PetscLogHandlerStart(handler));
504: PetscCall(PetscLogHandlerDestroy(&handler));
505: PetscFunctionReturn(PETSC_SUCCESS);
506: }
508: PETSC_INTERN PetscErrorCode PetscLogHandlerCreate_Nested(MPI_Comm, PetscLogHandler *);
510: /*@
511: PetscLogNestedBegin - Turns on nested logging of objects and events. This logs flop
512: rates and object creation and should not slow programs down too much.
514: Logically Collective on `PETSC_COMM_WORLD`, No Fortran Support
516: Options Database Keys:
517: . -log_view :filename.xml:ascii_xml - Prints an XML summary of flop and timing information to the file
519: Example Usage:
520: .vb
521: PetscInitialize(...);
522: PetscLogNestedBegin();
523: ... code ...
524: PetscLogView(viewer);
525: PetscFinalize();
526: .ve
528: Level: advanced
530: .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`
531: @*/
532: PetscErrorCode PetscLogNestedBegin(void)
533: {
534: PetscFunctionBegin;
535: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERNESTED));
536: PetscFunctionReturn(PETSC_SUCCESS);
537: }
539: /*@C
540: PetscLogLegacyCallbacksBegin - Create and start a log handler from callbacks
541: matching the now deprecated function pointers `PetscLogPLB`, `PetscLogPLE`,
542: `PetscLogPHC`, `PetscLogPHD`.
544: Logically Collective on `PETSC_COMM_WORLD`
546: Input Parameters:
547: + PetscLogPLB - A callback that will be executed by `PetscLogEventBegin()` (or `NULL`)
548: . PetscLogPLE - A callback that will be executed by `PetscLogEventEnd()` (or `NULL`)
549: . PetscLogPHC - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`)
550: - PetscLogPHD - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`)
552: Calling sequence of `PetscLogPLB`:
553: + e - a `PetscLogEvent` that is beginning
554: . _i - deprecated, unused
555: . o1 - a `PetscObject` associated with `e` (or `NULL`)
556: . o2 - a `PetscObject` associated with `e` (or `NULL`)
557: . o3 - a `PetscObject` associated with `e` (or `NULL`)
558: - o4 - a `PetscObject` associated with `e` (or `NULL`)
560: Calling sequence of `PetscLogPLE`:
561: + e - a `PetscLogEvent` that is beginning
562: . _i - deprecated, unused
563: . o1 - a `PetscObject` associated with `e` (or `NULL`)
564: . o2 - a `PetscObject` associated with `e` (or `NULL`)
565: . o3 - a `PetscObject` associated with `e` (or `NULL`)
566: - o4 - a `PetscObject` associated with `e` (or `NULL`)
568: Calling sequence of `PetscLogPHC`:
569: . o - a `PetscObject` that has just been created
571: Calling sequence of `PetscLogPHD`:
572: . o - a `PetscObject` that is about to be destroyed
574: Level: advanced
576: Notes:
577: This is for transitioning from the deprecated function `PetscLogSet()` and should not be used in new code.
579: This should help migrate external log handlers to use `PetscLogHandler`, but
580: callbacks that depend on the deprecated `PetscLogStage` datatype will have to be
581: updated.
583: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerStart()`, `PetscLogState`
584: @*/
585: 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))
586: {
587: PetscLogHandler handler;
589: PetscFunctionBegin;
590: PetscCall(PetscLogHandlerCreateLegacy(PETSC_COMM_WORLD, PetscLogPLB, PetscLogPLE, PetscLogPHC, PetscLogPHD, &handler));
591: PetscCall(PetscLogHandlerStart(handler));
592: PetscCall(PetscLogHandlerDestroy(&handler));
593: PetscFunctionReturn(PETSC_SUCCESS);
594: }
596: #if defined(PETSC_HAVE_MPE)
597: #include <mpe.h>
598: static PetscBool PetscBeganMPE = PETSC_FALSE;
599: #endif
601: /*@C
602: PetscLogMPEBegin - Turns on MPE logging of events. This creates large log files and slows the
603: program down.
605: Collective on `PETSC_COMM_WORLD`, No Fortran Support
607: Options Database Key:
608: . -log_mpe - Prints extensive log information
610: Level: advanced
612: Note:
613: A related routine is `PetscLogDefaultBegin()` (with the options key `-log_view`), which is
614: intended for production runs since it logs only flop rates and object creation (and should
615: not significantly slow the programs).
617: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogDefaultBegin()`, `PetscLogEventActivate()`,
618: `PetscLogEventDeactivate()`
619: @*/
620: PetscErrorCode PetscLogMPEBegin(void)
621: {
622: PetscFunctionBegin;
623: #if defined(PETSC_HAVE_MPE)
624: /* Do MPE initialization */
625: if (!MPE_Initialized_logging()) { /* This function exists in mpich 1.1.2 and higher */
626: PetscCall(PetscInfo(0, "Initializing MPE.\n"));
627: PetscCall(MPE_Init_log());
629: PetscBeganMPE = PETSC_TRUE;
630: } else {
631: PetscCall(PetscInfo(0, "MPE already initialized. Not attempting to reinitialize.\n"));
632: }
633: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERMPE));
634: #else
635: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe");
636: #endif
637: PetscFunctionReturn(PETSC_SUCCESS);
638: }
640: #if defined(PETSC_HAVE_TAU_PERFSTUBS)
641: #include <../src/sys/perfstubs/timer.h>
642: #endif
644: /*@C
645: PetscLogPerfstubsBegin - Turns on logging of events using the perfstubs interface.
647: Collective on `PETSC_COMM_WORLD`, No Fortran Support
649: Options Database Key:
650: . -log_perfstubs - use an external log handler through the perfstubs interface
652: Level: advanced
654: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogEventActivate()`
655: @*/
656: PetscErrorCode PetscLogPerfstubsBegin(void)
657: {
658: PetscFunctionBegin;
659: #if defined(PETSC_HAVE_TAU_PERFSTUBS)
660: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERPERFSTUBS));
661: #else
662: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without perfstubs support, reconfigure with --with-tau-perfstubs");
663: #endif
664: PetscFunctionReturn(PETSC_SUCCESS);
665: }
667: /*@
668: PetscLogActions - Determines whether actions are logged for the default log handler.
670: Not Collective
672: Input Parameter:
673: . flag - `PETSC_TRUE` if actions are to be logged
675: Options Database Key:
676: + -log_exclude_actions - (deprecated) Does nothing
677: - -log_include_actions - Turn on action logging
679: Level: intermediate
681: Note:
682: Logging of actions continues to consume more memory as the program
683: runs. Long running programs should consider turning this feature off.
685: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogGetDefaultHandler()`
686: @*/
687: PetscErrorCode PetscLogActions(PetscBool flag)
688: {
689: PetscFunctionBegin;
690: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
691: PetscLogHandler h = PetscLogHandlers[i].handler;
693: if (h) PetscCall(PetscLogHandlerSetLogActions(h, flag));
694: }
695: PetscFunctionReturn(PETSC_SUCCESS);
696: }
698: /*@
699: PetscLogObjects - Determines whether objects are logged for the graphical viewer.
701: Not Collective
703: Input Parameter:
704: . flag - `PETSC_TRUE` if objects are to be logged
706: Options Database Key:
707: + -log_exclude_objects - (deprecated) Does nothing
708: - -log_include_objects - Turns on object logging
710: Level: intermediate
712: Note:
713: Logging of objects continues to consume more memory as the program
714: runs. Long running programs should consider turning this feature off.
716: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogGetDefaultHandler()`
717: @*/
718: PetscErrorCode PetscLogObjects(PetscBool flag)
719: {
720: PetscFunctionBegin;
721: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
722: PetscLogHandler h = PetscLogHandlers[i].handler;
724: if (h) PetscCall(PetscLogHandlerSetLogObjects(h, flag));
725: }
726: PetscFunctionReturn(PETSC_SUCCESS);
727: }
729: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
730: /*@
731: PetscLogStageRegister - Attaches a character string name to a logging stage.
733: Not Collective
735: Input Parameter:
736: . sname - The name to associate with that stage
738: Output Parameter:
739: . stage - The stage number or -1 if logging is not active (`PetscLogIsActive()`).
741: Level: intermediate
743: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`
744: @*/
745: PetscErrorCode PetscLogStageRegister(const char sname[], PetscLogStage *stage)
746: {
747: PetscLogState state;
749: PetscFunctionBegin;
750: *stage = -1;
751: PetscCall(PetscLogGetState(&state));
752: if (state) PetscCall(PetscLogStateStageRegister(state, sname, stage));
753: PetscFunctionReturn(PETSC_SUCCESS);
754: }
756: /*@
757: PetscLogStagePush - This function pushes a stage on the logging stack. Events started and stopped until `PetscLogStagePop()` will be associated with the stage
759: Not Collective
761: Input Parameter:
762: . stage - The stage on which to log
764: Example Usage:
765: If the option -log_view is used to run the program containing the
766: following code, then 2 sets of summary data will be printed during
767: PetscFinalize().
768: .vb
769: PetscInitialize(int *argc,char ***args,0,0);
770: [stage 0 of code]
771: PetscLogStagePush(1);
772: [stage 1 of code]
773: PetscLogStagePop();
774: PetscBarrier(...);
775: [more stage 0 of code]
776: PetscFinalize();
777: .ve
779: Level: intermediate
781: Note:
782: Use `PetscLogStageRegister()` to register a stage.
784: .seealso: [](ch_profiling), `PetscLogStagePop()`, `PetscLogStageRegister()`, `PetscBarrier()`
785: @*/
786: PetscErrorCode PetscLogStagePush(PetscLogStage stage)
787: {
788: PetscLogState state;
790: PetscFunctionBegin;
791: PetscCall(PetscLogGetState(&state));
792: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
793: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
794: PetscLogHandler h = PetscLogHandlers[i].handler;
795: if (h) PetscCall(PetscLogHandlerStagePush(h, stage));
796: }
797: PetscCall(PetscLogStateStagePush(state, stage));
798: PetscFunctionReturn(PETSC_SUCCESS);
799: }
801: /*@
802: PetscLogStagePop - This function pops a stage from the logging stack that was pushed with `PetscLogStagePush()`
804: Not Collective
806: Example Usage:
807: If the option -log_view is used to run the program containing the
808: following code, then 2 sets of summary data will be printed during
809: PetscFinalize().
810: .vb
811: PetscInitialize(int *argc,char ***args,0,0);
812: [stage 0 of code]
813: PetscLogStagePush(1);
814: [stage 1 of code]
815: PetscLogStagePop();
816: PetscBarrier(...);
817: [more stage 0 of code]
818: PetscFinalize();
819: .ve
821: Level: intermediate
823: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStageRegister()`, `PetscBarrier()`
824: @*/
825: PetscErrorCode PetscLogStagePop(void)
826: {
827: PetscLogState state;
828: PetscLogStage current_stage;
830: PetscFunctionBegin;
831: PetscCall(PetscLogGetState(&state));
832: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
833: current_stage = state->current_stage;
834: PetscCall(PetscLogStateStagePop(state));
835: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
836: PetscLogHandler h = PetscLogHandlers[i].handler;
837: if (h) PetscCall(PetscLogHandlerStagePop(h, current_stage));
838: }
839: PetscFunctionReturn(PETSC_SUCCESS);
840: }
842: /*@
843: PetscLogStageSetActive - Sets if a stage is used for `PetscLogEventBegin()` and `PetscLogEventEnd()`.
845: Not Collective
847: Input Parameters:
848: + stage - The stage
849: - isActive - The activity flag, `PETSC_TRUE` for logging, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
851: Level: intermediate
853: Note:
854: If this is set to `PETSC_FALSE` the logging acts as if the stage did not exist
856: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
857: @*/
858: PetscErrorCode PetscLogStageSetActive(PetscLogStage stage, PetscBool isActive)
859: {
860: PetscLogState state;
862: PetscFunctionBegin;
863: PetscCall(PetscLogGetState(&state));
864: if (state) PetscCall(PetscLogStateStageSetActive(state, stage, isActive));
865: PetscFunctionReturn(PETSC_SUCCESS);
866: }
868: /*@
869: PetscLogStageGetActive - Checks if a stage is used for `PetscLogEventBegin()` and `PetscLogEventEnd()`.
871: Not Collective
873: Input Parameter:
874: . stage - The stage
876: Output Parameter:
877: . isActive - The activity flag, `PETSC_TRUE` for logging, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
879: Level: intermediate
881: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
882: @*/
883: PetscErrorCode PetscLogStageGetActive(PetscLogStage stage, PetscBool *isActive)
884: {
885: PetscLogState state;
887: PetscFunctionBegin;
888: *isActive = PETSC_FALSE;
889: PetscCall(PetscLogGetState(&state));
890: if (state) PetscCall(PetscLogStateStageGetActive(state, stage, isActive));
891: PetscFunctionReturn(PETSC_SUCCESS);
892: }
894: /*@
895: PetscLogStageSetVisible - Determines stage visibility in `PetscLogView()`
897: Not Collective
899: Input Parameters:
900: + stage - The stage
901: - isVisible - The visibility flag, `PETSC_TRUE` to print, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
903: Level: intermediate
905: Developer Notes:
906: Visibility only affects the default log handler in `PetscLogView()`: stages that are
907: set to invisible are suppressed from output.
909: .seealso: [](ch_profiling), `PetscLogStageGetVisible()`, `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
910: @*/
911: PetscErrorCode PetscLogStageSetVisible(PetscLogStage stage, PetscBool isVisible)
913: {
914: PetscFunctionBegin;
915: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
916: PetscLogHandler h = PetscLogHandlers[i].handler;
918: if (h) PetscCall(PetscLogHandlerStageSetVisible(h, stage, isVisible));
919: }
920: PetscFunctionReturn(PETSC_SUCCESS);
921: }
923: /*@
924: PetscLogStageGetVisible - Returns stage visibility in `PetscLogView()`
926: Not Collective
928: Input Parameter:
929: . stage - The stage
931: Output Parameter:
932: . isVisible - The visibility flag, `PETSC_TRUE` to print, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
934: Level: intermediate
936: .seealso: [](ch_profiling), `PetscLogStageSetVisible()`, `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
937: @*/
938: PetscErrorCode PetscLogStageGetVisible(PetscLogStage stage, PetscBool *isVisible)
939: {
940: PetscLogHandler handler;
942: PetscFunctionBegin;
943: *isVisible = PETSC_FALSE;
944: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
945: if (handler) PetscCall(PetscLogHandlerStageGetVisible(handler, stage, isVisible));
946: PetscFunctionReturn(PETSC_SUCCESS);
947: }
949: /*@
950: PetscLogStageGetId - Returns the stage id when given the stage name.
952: Not Collective
954: Input Parameter:
955: . name - The stage name
957: Output Parameter:
958: . stage - The stage, , or -1 if no stage with that name exists
960: Level: intermediate
962: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
963: @*/
964: PetscErrorCode PetscLogStageGetId(const char name[], PetscLogStage *stage)
965: {
966: PetscLogState state;
968: PetscFunctionBegin;
969: *stage = -1;
970: PetscCall(PetscLogGetState(&state));
971: if (state) PetscCall(PetscLogStateGetStageFromName(state, name, stage));
972: PetscFunctionReturn(PETSC_SUCCESS);
973: }
975: /*@
976: PetscLogStageGetName - Returns the stage name when given the stage id.
978: Not Collective
980: Input Parameter:
981: . stage - The stage
983: Output Parameter:
984: . name - The stage name
986: Level: intermediate
988: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
989: @*/
990: PetscErrorCode PetscLogStageGetName(PetscLogStage stage, const char *name[])
991: {
992: PetscLogStageInfo stage_info;
993: PetscLogState state;
995: PetscFunctionBegin;
996: *name = NULL;
997: PetscCall(PetscLogGetState(&state));
998: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
999: PetscCall(PetscLogStateStageGetInfo(state, stage, &stage_info));
1000: *name = stage_info.name;
1001: PetscFunctionReturn(PETSC_SUCCESS);
1002: }
1004: /*------------------------------------------------ Event Functions --------------------------------------------------*/
1006: /*@
1007: PetscLogEventRegister - Registers an event name for logging operations
1009: Not Collective
1011: Input Parameters:
1012: + name - The name associated with the event
1013: - classid - The classid associated to the class for this event, obtain either with
1014: `PetscClassIdRegister()` or use a predefined one such as `KSP_CLASSID`, `SNES_CLASSID`, the predefined ones
1015: are only available in C code
1017: Output Parameter:
1018: . event - The event id for use with `PetscLogEventBegin()` and `PetscLogEventEnd()`.
1020: Example Usage:
1021: .vb
1022: PetscLogEvent USER_EVENT;
1023: PetscClassId classid;
1024: PetscLogDouble user_event_flops;
1025: PetscClassIdRegister("class name",&classid);
1026: PetscLogEventRegister("User event name",classid,&USER_EVENT);
1027: PetscLogEventBegin(USER_EVENT,0,0,0,0);
1028: [code segment to monitor]
1029: PetscLogFlops(user_event_flops);
1030: PetscLogEventEnd(USER_EVENT,0,0,0,0);
1031: .ve
1033: Level: intermediate
1035: Notes:
1036: PETSc automatically logs library events if the code has been
1037: configured with --with-log (which is the default) and
1038: -log_view or -log_all is specified. `PetscLogEventRegister()` is
1039: intended for logging user events to supplement this PETSc
1040: information.
1042: PETSc can gather data for use with the utilities Jumpshot
1043: (part of the MPICH distribution). If PETSc has been compiled
1044: with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
1045: MPICH), the user can employ another command line option, -log_mpe,
1046: to create a logfile, "mpe.log", which can be visualized
1047: Jumpshot.
1049: The classid is associated with each event so that classes of events
1050: can be disabled simultaneously, such as all matrix events. The user
1051: can either use an existing classid, such as `MAT_CLASSID`, or create
1052: their own as shown in the example.
1054: If an existing event with the same name exists, its event handle is
1055: returned instead of creating a new event.
1057: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogFlops()`,
1058: `PetscLogEventActivate()`, `PetscLogEventDeactivate()`, `PetscClassIdRegister()`
1059: @*/
1060: PetscErrorCode PetscLogEventRegister(const char name[], PetscClassId classid, PetscLogEvent *event)
1061: {
1062: PetscLogState state;
1064: PetscFunctionBegin;
1065: *event = -1;
1066: PetscCall(PetscLogGetState(&state));
1067: if (state) PetscCall(PetscLogStateEventRegister(state, name, classid, event));
1068: PetscFunctionReturn(PETSC_SUCCESS);
1069: }
1071: /*@
1072: PetscLogEventSetCollective - Indicates that a particular event is collective.
1074: Logically Collective
1076: Input Parameters:
1077: + event - The event id
1078: - collective - `PetscBool` indicating whether a particular event is collective
1080: Level: developer
1082: Notes:
1083: New events returned from `PetscLogEventRegister()` are collective by default.
1085: Collective events are handled specially if the command line option `-log_sync` is used. In that case the logging saves information about
1086: two parts of the event; the time for all the MPI ranks to synchronize and then the time for the actual computation/communication
1087: to be performed. This option is useful to debug imbalance within the computations or communications.
1089: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventRegister()`
1090: @*/
1091: PetscErrorCode PetscLogEventSetCollective(PetscLogEvent event, PetscBool collective)
1092: {
1093: PetscLogState state;
1095: PetscFunctionBegin;
1096: PetscCall(PetscLogGetState(&state));
1097: if (state) PetscCall(PetscLogStateEventSetCollective(state, event, collective));
1098: PetscFunctionReturn(PETSC_SUCCESS);
1099: }
1101: /*
1102: PetscLogClassSetActiveAll - Activate or inactivate logging for all events associated with a PETSc object class in every stage.
1104: Not Collective
1106: Input Parameters:
1107: + classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1108: - isActive - if `PETSC_FALSE`, events associated with this class will not be send to log handlers.
1110: Level: developer
1112: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventActivateAll()`, `PetscLogStageSetActive()`, `PetscLogEventActivateClass()`
1113: */
1114: static PetscErrorCode PetscLogClassSetActiveAll(PetscClassId classid, PetscBool isActive)
1115: {
1116: PetscLogState state;
1118: PetscFunctionBegin;
1119: PetscCall(PetscLogGetState(&state));
1120: if (state) PetscCall(PetscLogStateClassSetActiveAll(state, classid, isActive));
1121: PetscFunctionReturn(PETSC_SUCCESS);
1122: }
1124: /*@
1125: PetscLogEventIncludeClass - Activates event logging for a PETSc object class in every stage.
1127: Not Collective
1129: Input Parameter:
1130: . classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1132: Level: developer
1134: .seealso: [](ch_profiling), `PetscLogEventActivateClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1135: @*/
1136: PetscErrorCode PetscLogEventIncludeClass(PetscClassId classid)
1137: {
1138: PetscFunctionBegin;
1139: PetscCall(PetscLogClassSetActiveAll(classid, PETSC_TRUE));
1140: PetscFunctionReturn(PETSC_SUCCESS);
1141: }
1143: /*@
1144: PetscLogEventExcludeClass - Deactivates event logging for a PETSc object class in every stage.
1146: Not Collective
1148: Input Parameter:
1149: . classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1151: Level: developer
1153: Note:
1154: If a class is excluded then events associated with that class are not logged.
1156: .seealso: [](ch_profiling), `PetscLogEventDeactivateClass()`, `PetscLogEventActivateClass()`, `PetscLogEventDeactivate()`, `PetscLogEventActivate()`
1157: @*/
1158: PetscErrorCode PetscLogEventExcludeClass(PetscClassId classid)
1159: {
1160: PetscFunctionBegin;
1161: PetscCall(PetscLogClassSetActiveAll(classid, PETSC_FALSE));
1162: PetscFunctionReturn(PETSC_SUCCESS);
1163: }
1165: /*
1166: PetscLogEventSetActive - Activate or inactivate logging for an event in a given stage
1168: Not Collective
1170: Input Parameters:
1171: + stage - A registered `PetscLogStage` (or `PETSC_DEFAULT` for the current stage)
1172: . event - A `PetscLogEvent`
1173: - isActive - If `PETSC_FALSE`, activity from this event (`PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventSync()`) will not be sent to log handlers during this stage
1175: Usage:
1176: .vb
1177: PetscLogEventSetActive(VEC_SetValues, PETSC_FALSE);
1178: [code where you do not want to log VecSetValues()]
1179: PetscLogEventSetActive(VEC_SetValues, PETSC_TRUE);
1180: [code where you do want to log VecSetValues()]
1181: .ve
1183: Level: advanced
1185: Note:
1186: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
1187: or an event number obtained with `PetscLogEventRegister()`.
1189: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1190: */
1191: static PetscErrorCode PetscLogEventSetActive(PetscLogStage stage, PetscLogEvent event, PetscBool isActive)
1192: {
1193: PetscLogState state;
1195: PetscFunctionBegin;
1196: PetscCall(PetscLogGetState(&state));
1197: if (state) PetscCall(PetscLogStateEventSetActive(state, stage, event, isActive));
1198: PetscFunctionReturn(PETSC_SUCCESS);
1199: }
1201: /*@
1202: PetscLogEventActivate - Indicates that a particular event should be logged.
1204: Not Collective
1206: Input Parameter:
1207: . event - The event id
1209: Example Usage:
1210: .vb
1211: PetscLogEventDeactivate(VEC_SetValues);
1212: [code where you do not want to log VecSetValues()]
1213: PetscLogEventActivate(VEC_SetValues);
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), `PetscLogEventDeactivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1224: @*/
1225: PetscErrorCode PetscLogEventActivate(PetscLogEvent event)
1226: {
1227: PetscFunctionBegin;
1228: PetscCall(PetscLogEventSetActive(PETSC_DEFAULT, event, PETSC_TRUE));
1229: PetscFunctionReturn(PETSC_SUCCESS);
1230: }
1232: /*@
1233: PetscLogEventDeactivate - Indicates that a particular event should not be logged.
1235: Not Collective
1237: Input Parameter:
1238: . event - The event id
1240: Example Usage:
1241: .vb
1242: PetscLogEventDeactivate(VEC_SetValues);
1243: [code where you do not want to log VecSetValues()]
1244: PetscLogEventActivate(VEC_SetValues);
1245: [code where you do want to log VecSetValues()]
1246: .ve
1248: Level: advanced
1250: Note:
1251: The event may be either a pre-defined PETSc event (found in
1252: include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1254: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1255: @*/
1256: PetscErrorCode PetscLogEventDeactivate(PetscLogEvent event)
1257: {
1258: PetscFunctionBegin;
1259: PetscCall(PetscLogEventSetActive(PETSC_DEFAULT, event, PETSC_FALSE));
1260: PetscFunctionReturn(PETSC_SUCCESS);
1261: }
1263: /*@
1264: PetscLogEventDeactivatePush - Indicates that a particular event should not be logged until `PetscLogEventDeactivatePop()` is called
1266: Not Collective
1268: Input Parameter:
1269: . event - The event id
1271: Example Usage:
1272: .vb
1273: PetscLogEventDeactivatePush(VEC_SetValues);
1274: [code where you do not want to log VecSetValues()]
1275: PetscLogEventDeactivatePop(VEC_SetValues);
1276: [code where you do want to log VecSetValues()]
1277: .ve
1279: Level: advanced
1281: Note:
1282: The event may be either a pre-defined PETSc event (found in
1283: include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1285: 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.
1287: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivate()`, `PetscLogEventDeactivatePop()`
1288: @*/
1289: PetscErrorCode PetscLogEventDeactivatePush(PetscLogEvent event)
1290: {
1291: PetscFunctionBegin;
1292: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1293: PetscLogHandler h = PetscLogHandlers[i].handler;
1295: if (h) PetscCall(PetscLogHandlerEventDeactivatePush(h, PETSC_DEFAULT, event));
1296: }
1297: PetscFunctionReturn(PETSC_SUCCESS);
1298: }
1300: /*@
1301: PetscLogEventDeactivatePop - Indicates that a particular event should again be logged after the logging was turned off with `PetscLogEventDeactivatePush()`
1303: Not Collective
1305: Input Parameter:
1306: . event - The event id
1308: Example Usage:
1309: .vb
1310: PetscLogEventDeactivatePush(VEC_SetValues);
1311: [code where you do not want to log VecSetValues()]
1312: PetscLogEventDeactivatePop(VEC_SetValues);
1313: [code where you do want to log VecSetValues()]
1314: .ve
1316: Level: advanced
1318: Note:
1319: The event may be either a pre-defined PETSc event (found in
1320: include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1322: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`
1323: @*/
1324: PetscErrorCode PetscLogEventDeactivatePop(PetscLogEvent event)
1325: {
1326: PetscFunctionBegin;
1327: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1328: PetscLogHandler h = PetscLogHandlers[i].handler;
1330: if (h) PetscCall(PetscLogHandlerEventDeactivatePop(h, PETSC_DEFAULT, event));
1331: }
1332: PetscFunctionReturn(PETSC_SUCCESS);
1333: }
1335: /*@
1336: PetscLogEventSetActiveAll - Turns on logging of all events
1338: Not Collective
1340: Input Parameters:
1341: + event - The event id
1342: - isActive - The activity flag determining whether the event is logged
1344: Level: advanced
1346: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1347: @*/
1348: PetscErrorCode PetscLogEventSetActiveAll(PetscLogEvent event, PetscBool isActive)
1349: {
1350: PetscLogState state;
1352: PetscFunctionBegin;
1353: PetscCall(PetscLogGetState(&state));
1354: if (state) PetscCall(PetscLogStateEventSetActiveAll(state, event, isActive));
1355: PetscFunctionReturn(PETSC_SUCCESS);
1356: }
1358: /*
1359: PetscLogClassSetActive - Activates event logging for a PETSc object class for the current stage
1361: Not Collective
1363: Input Parameters:
1364: + stage - A registered `PetscLogStage` (or `PETSC_DEFAULT` for the current stage)
1365: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1366: - isActive - If `PETSC_FALSE`, events associated with this class are not sent to log handlers.
1368: Level: developer
1370: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventActivate()`, `PetscLogEventActivateAll()`, `PetscLogStageSetActive()`
1371: */
1372: static PetscErrorCode PetscLogClassSetActive(PetscLogStage stage, PetscClassId classid, PetscBool isActive)
1373: {
1374: PetscLogState state;
1376: PetscFunctionBegin;
1377: PetscCall(PetscLogGetState(&state));
1378: if (state) PetscCall(PetscLogStateClassSetActive(state, stage, classid, isActive));
1379: PetscFunctionReturn(PETSC_SUCCESS);
1380: }
1382: /*@
1383: PetscLogEventActivateClass - Activates event logging for a PETSc object class for the current stage
1385: Not Collective
1387: Input Parameter:
1388: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1390: Level: developer
1392: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1393: @*/
1394: PetscErrorCode PetscLogEventActivateClass(PetscClassId classid)
1395: {
1396: PetscFunctionBegin;
1397: PetscCall(PetscLogClassSetActive(PETSC_DEFAULT, classid, PETSC_TRUE));
1398: PetscFunctionReturn(PETSC_SUCCESS);
1399: }
1401: /*@
1402: PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class for the current stage
1404: Not Collective
1406: Input Parameter:
1407: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1409: Level: developer
1411: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventActivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1412: @*/
1413: PetscErrorCode PetscLogEventDeactivateClass(PetscClassId classid)
1414: {
1415: PetscFunctionBegin;
1416: PetscCall(PetscLogClassSetActive(PETSC_DEFAULT, classid, PETSC_FALSE));
1417: PetscFunctionReturn(PETSC_SUCCESS);
1418: }
1420: /*MC
1421: PetscLogEventSync - Synchronizes the beginning of a user event.
1423: Synopsis:
1424: #include <petsclog.h>
1425: PetscErrorCode PetscLogEventSync(PetscLogEvent e, MPI_Comm comm)
1427: Collective
1429: Input Parameters:
1430: + e - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1431: - comm - an MPI communicator
1433: Example Usage:
1434: .vb
1435: PetscLogEvent USER_EVENT;
1437: PetscLogEventRegister("User event", 0, &USER_EVENT);
1438: PetscLogEventSync(USER_EVENT, PETSC_COMM_WORLD);
1439: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1440: [code segment to monitor]
1441: PetscLogEventEnd(USER_EVENT, 0, 0, 0 , 0);
1442: .ve
1444: Level: developer
1446: Note:
1447: This routine should be called only if there is not a `PetscObject` available to pass to
1448: `PetscLogEventBegin()`.
1450: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`
1451: M*/
1453: /*MC
1454: PetscLogEventBegin - Logs the beginning of a user event.
1456: Synopsis:
1457: #include <petsclog.h>
1458: PetscErrorCode PetscLogEventBegin(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
1460: Not Collective
1462: Input Parameters:
1463: + e - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1464: . o1 - object associated with the event, or `NULL`
1465: . o2 - object associated with the event, or `NULL`
1466: . o3 - object associated with the event, or `NULL`
1467: - o4 - object associated with the event, or `NULL`
1469: Fortran Synopsis:
1470: void PetscLogEventBegin(int e, PetscErrorCode ierr)
1472: Example Usage:
1473: .vb
1474: PetscLogEvent USER_EVENT;
1476: PetscLogDouble user_event_flops;
1477: PetscLogEventRegister("User event",0, &USER_EVENT);
1478: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1479: [code segment to monitor]
1480: PetscLogFlops(user_event_flops);
1481: PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
1482: .ve
1484: Level: intermediate
1486: Developer Note:
1487: `PetscLogEventBegin()` and `PetscLogEventBegin()` return error codes instead of explicitly
1488: handling the errors that occur in the macro directly because other packages that use this
1489: macros have used them in their own functions or methods that do not return error codes and it
1490: would be disruptive to change the current behavior.
1492: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventEnd()`, `PetscLogFlops()`
1493: M*/
1495: /*MC
1496: PetscLogEventEnd - Log the end of a user event.
1498: Synopsis:
1499: #include <petsclog.h>
1500: PetscErrorCode PetscLogEventEnd(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
1502: Not Collective
1504: Input Parameters:
1505: + e - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1506: . o1 - object associated with the event, or `NULL`
1507: . o2 - object associated with the event, or `NULL`
1508: . o3 - object associated with the event, or `NULL`
1509: - o4 - object associated with the event, or `NULL`
1511: Fortran Synopsis:
1512: void PetscLogEventEnd(int e, PetscErrorCode ierr)
1514: Example Usage:
1515: .vb
1516: PetscLogEvent USER_EVENT;
1518: PetscLogDouble user_event_flops;
1519: PetscLogEventRegister("User event", 0, &USER_EVENT);
1520: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1521: [code segment to monitor]
1522: PetscLogFlops(user_event_flops);
1523: PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
1524: .ve
1526: Level: intermediate
1528: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogFlops()`
1529: M*/
1531: /*@C
1532: PetscLogStageGetPerfInfo - Return the performance information about the given stage
1534: No Fortran Support
1536: Input Parameters:
1537: . stage - The stage number or `PETSC_DETERMINE` for the current stage
1539: Output Parameter:
1540: . info - This structure is filled with the performance information
1542: Level: intermediate
1544: Notes:
1545: This is a low level routine used by the logging functions in PETSc.
1547: A `PETSCLOGHANDLERDEFAULT` must be running for this to work, having been started either with
1548: `PetscLogDefaultBegin()` or from the command line with `-log_view`. If it was not started,
1549: all performance statistics in `info` will be zeroed.
1551: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1552: @*/
1553: PetscErrorCode PetscLogStageGetPerfInfo(PetscLogStage stage, PetscEventPerfInfo *info)
1554: {
1555: PetscLogHandler handler;
1556: PetscEventPerfInfo *event_info;
1558: PetscFunctionBegin;
1559: PetscAssertPointer(info, 2);
1560: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1561: if (handler) {
1562: PetscCall(PetscLogHandlerGetStagePerfInfo(handler, stage, &event_info));
1563: *info = *event_info;
1564: } else {
1565: PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogStageGetPerfInfo() returning zeros\n"));
1566: PetscCall(PetscMemzero(info, sizeof(*info)));
1567: }
1568: PetscFunctionReturn(PETSC_SUCCESS);
1569: }
1571: /*@C
1572: PetscLogEventGetPerfInfo - Return the performance information about the given event in the given stage
1574: No Fortran Support
1576: Input Parameters:
1577: + stage - The stage number or `PETSC_DETERMINE` for the current stage
1578: - event - The event number
1580: Output Parameter:
1581: . info - This structure is filled with the performance information
1583: Level: intermediate
1585: Note:
1586: This is a low level routine used by the logging functions in PETSc
1588: A `PETSCLOGHANDLERDEFAULT` must be running for this to work, having been started either with
1589: `PetscLogDefaultBegin()` or from the command line with `-log_view`. If it was not started,
1590: all performance statistics in `info` will be zeroed.
1592: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1593: @*/
1594: PetscErrorCode PetscLogEventGetPerfInfo(PetscLogStage stage, PetscLogEvent event, PetscEventPerfInfo *info)
1595: {
1596: PetscLogHandler handler;
1597: PetscEventPerfInfo *event_info;
1599: PetscFunctionBegin;
1600: PetscAssertPointer(info, 3);
1601: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1602: if (handler) {
1603: PetscCall(PetscLogHandlerGetEventPerfInfo(handler, stage, event, &event_info));
1604: *info = *event_info;
1605: } else {
1606: PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogEventGetPerfInfo() returning zeros\n"));
1607: PetscCall(PetscMemzero(info, sizeof(*info)));
1608: }
1609: PetscFunctionReturn(PETSC_SUCCESS);
1610: }
1612: /*@
1613: PetscLogEventSetDof - Set the nth number of degrees of freedom of a numerical problem associated with this event
1615: Not Collective
1617: Input Parameters:
1618: + event - The event id to log
1619: . n - The dof index, in [0, 8)
1620: - dof - The number of dofs
1622: Options Database Key:
1623: . -log_view - Activates log summary
1625: Level: developer
1627: Note:
1628: This is to enable logging of convergence
1630: .seealso: `PetscLogEventSetError()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1631: @*/
1632: PetscErrorCode PetscLogEventSetDof(PetscLogEvent event, PetscInt n, PetscLogDouble dof)
1633: {
1634: PetscFunctionBegin;
1635: PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1636: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1637: PetscLogHandler h = PetscLogHandlers[i].handler;
1639: if (h) {
1640: PetscEventPerfInfo *event_info;
1642: PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1643: if (event_info) event_info->dof[n] = dof;
1644: }
1645: }
1646: PetscFunctionReturn(PETSC_SUCCESS);
1647: }
1649: /*@
1650: PetscLogEventSetError - Set the nth error associated with a numerical problem associated with this event
1652: Not Collective
1654: Input Parameters:
1655: + event - The event id to log
1656: . n - The error index, in [0, 8)
1657: - error - The error
1659: Options Database Key:
1660: . -log_view - Activates log summary
1662: Level: developer
1664: Notes:
1665: This is to enable logging of convergence, and enable users to interpret the errors as they wish. For example,
1666: as different norms, or as errors for different fields
1668: This is a low level routine used by the logging functions in PETSc
1670: .seealso: `PetscLogEventSetDof()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1671: @*/
1672: PetscErrorCode PetscLogEventSetError(PetscLogEvent event, PetscInt n, PetscLogDouble error)
1673: {
1674: PetscFunctionBegin;
1675: PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1676: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1677: PetscLogHandler h = PetscLogHandlers[i].handler;
1679: if (h) {
1680: PetscEventPerfInfo *event_info;
1682: PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1683: if (event_info) event_info->errors[n] = error;
1684: }
1685: }
1686: PetscFunctionReturn(PETSC_SUCCESS);
1687: }
1689: /*@
1690: PetscLogEventGetId - Returns the event id when given the event name.
1692: Not Collective
1694: Input Parameter:
1695: . name - The event name
1697: Output Parameter:
1698: . event - The event, or -1 if no event with that name exists
1700: Level: intermediate
1702: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1703: @*/
1704: PetscErrorCode PetscLogEventGetId(const char name[], PetscLogEvent *event)
1705: {
1706: PetscLogState state;
1708: PetscFunctionBegin;
1709: *event = -1;
1710: PetscCall(PetscLogGetState(&state));
1711: if (state) PetscCall(PetscLogStateGetEventFromName(state, name, event));
1712: PetscFunctionReturn(PETSC_SUCCESS);
1713: }
1715: /*@
1716: PetscLogEventGetName - Returns the event name when given the event id.
1718: Not Collective
1720: Input Parameter:
1721: . event - The event
1723: Output Parameter:
1724: . name - The event name
1726: Level: intermediate
1728: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
1729: @*/
1730: PetscErrorCode PetscLogEventGetName(PetscLogEvent event, const char *name[])
1731: {
1732: PetscLogEventInfo event_info;
1733: PetscLogState state;
1735: PetscFunctionBegin;
1736: *name = NULL;
1737: PetscCall(PetscLogGetState(&state));
1738: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1739: PetscCall(PetscLogStateEventGetInfo(state, event, &event_info));
1740: *name = event_info.name;
1741: PetscFunctionReturn(PETSC_SUCCESS);
1742: }
1744: /*@
1745: 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.
1747: Not collective
1749: Level: advanced
1751: Notes:
1752: 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()`).
1754: Other log handlers (such as the nested handler, `PetscLogNestedBegin()`) will ignore this function.
1756: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsResume()`, `PetscLogGetDefaultHandler()`
1757: @*/
1758: PetscErrorCode PetscLogEventsPause(void)
1759: {
1760: PetscFunctionBegin;
1761: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1762: PetscLogHandler h = PetscLogHandlers[i].handler;
1764: if (h) PetscCall(PetscLogHandlerEventsPause(h));
1765: }
1766: PetscFunctionReturn(PETSC_SUCCESS);
1767: }
1769: /*@
1770: PetscLogEventsResume - Return logging to normal behavior after it was paused with `PetscLogEventsPause()`.
1772: Not collective
1774: Level: advanced
1776: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsPause()`, `PetscLogGetDefaultHandler()`
1777: @*/
1778: PetscErrorCode PetscLogEventsResume(void)
1779: {
1780: PetscFunctionBegin;
1781: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1782: PetscLogHandler h = PetscLogHandlers[i].handler;
1784: if (h) PetscCall(PetscLogHandlerEventsResume(h));
1785: }
1786: PetscFunctionReturn(PETSC_SUCCESS);
1787: }
1789: /*------------------------------------------------ Class Functions --------------------------------------------------*/
1791: /*MC
1792: PetscLogObjectCreate - Log the creation of a `PetscObject`
1794: Synopsis:
1795: #include <petsclog.h>
1796: PetscErrorCode PetscLogObjectCreate(PetscObject h)
1798: Not Collective
1800: Input Parameters:
1801: . h - A `PetscObject`
1803: Level: developer
1805: Developer Note:
1806: Called internally by PETSc when creating objects: users do not need to call this directly.
1807: Notification of the object creation is sent to each `PetscLogHandler` that is running.
1809: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectDestroy()`
1810: M*/
1812: /*MC
1813: PetscLogObjectDestroy - Logs the destruction of a `PetscObject`
1815: Synopsis:
1816: #include <petsclog.h>
1817: PetscErrorCode PetscLogObjectDestroy(PetscObject h)
1819: Not Collective
1821: Input Parameters:
1822: . h - A `PetscObject`
1824: Level: developer
1826: Developer Note:
1827: Called internally by PETSc when destroying objects: users do not need to call this directly.
1828: Notification of the object creation is sent to each `PetscLogHandler` that is running.
1830: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectCreate()`
1831: M*/
1833: /*@
1834: PetscLogClassGetClassId - Returns the `PetscClassId` when given the class name.
1836: Not Collective
1838: Input Parameter:
1839: . name - The class name
1841: Output Parameter:
1842: . classid - The `PetscClassId` id, or -1 if no class with that name exists
1844: Level: intermediate
1846: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1847: @*/
1848: PetscErrorCode PetscLogClassGetClassId(const char name[], PetscClassId *classid)
1849: {
1850: PetscLogClass log_class;
1851: PetscLogClassInfo class_info;
1852: PetscLogState state;
1854: PetscFunctionBegin;
1855: *classid = -1;
1856: PetscCall(PetscLogGetState(&state));
1857: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1858: PetscCall(PetscLogStateGetClassFromName(state, name, &log_class));
1859: if (log_class < 0) {
1860: *classid = -1;
1861: PetscFunctionReturn(PETSC_SUCCESS);
1862: }
1863: PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1864: *classid = class_info.classid;
1865: PetscFunctionReturn(PETSC_SUCCESS);
1866: }
1868: /*@C
1869: PetscLogClassIdGetName - Returns a `PetscClassId`'s name.
1871: Not Collective
1873: Input Parameter:
1874: . classid - A `PetscClassId`
1876: Output Parameter:
1877: . name - The class name
1879: Level: intermediate
1881: .seealso: [](ch_profiling), `PetscLogClassRegister()`, `PetscLogClassBegin()`, `PetscLogClassEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadClass()`
1882: @*/
1883: PetscErrorCode PetscLogClassIdGetName(PetscClassId classid, const char **name)
1884: {
1885: PetscLogClass log_class;
1886: PetscLogClassInfo class_info;
1887: PetscLogState state;
1889: PetscFunctionBegin;
1890: PetscCall(PetscLogGetState(&state));
1891: PetscCall(PetscLogStateGetClassFromClassId(state, classid, &log_class));
1892: PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1893: *name = class_info.name;
1894: PetscFunctionReturn(PETSC_SUCCESS);
1895: }
1897: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1898: /*@
1899: PetscLogDump - Dumps logs of objects to a file. This file is intended to
1900: be read by bin/petscview. This program no longer exists.
1902: Collective on `PETSC_COMM_WORLD`
1904: Input Parameter:
1905: . sname - an optional file name
1907: Example Usage:
1908: .vb
1909: PetscInitialize(...);
1910: PetscLogDefaultBegin();
1911: // ... code ...
1912: PetscLogDump(filename);
1913: PetscFinalize();
1914: .ve
1916: Level: advanced
1918: Note:
1919: The default file name is Log.<rank> where <rank> is the MPI process rank. If no name is specified,
1920: this file will be used.
1922: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
1923: @*/
1924: PetscErrorCode PetscLogDump(const char sname[])
1925: {
1926: PetscLogHandler handler;
1928: PetscFunctionBegin;
1929: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1930: PetscCall(PetscLogHandlerDump(handler, sname));
1931: PetscFunctionReturn(PETSC_SUCCESS);
1932: }
1934: /*@
1935: PetscLogMPEDump - Dumps the MPE logging info to file for later use with Jumpshot.
1937: Collective on `PETSC_COMM_WORLD`
1939: Input Parameter:
1940: . sname - filename for the MPE logfile
1942: Level: advanced
1944: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogMPEBegin()`
1945: @*/
1946: PetscErrorCode PetscLogMPEDump(const char sname[])
1947: {
1948: PetscFunctionBegin;
1949: #if defined(PETSC_HAVE_MPE)
1950: if (PetscBeganMPE) {
1951: char name[PETSC_MAX_PATH_LEN];
1953: PetscCall(PetscInfo(0, "Finalizing MPE.\n"));
1954: if (sname) {
1955: PetscCall(PetscStrncpy(name, sname, sizeof(name)));
1956: } else {
1957: PetscCall(PetscGetProgramName(name, sizeof(name)));
1958: }
1959: PetscCall(MPE_Finish_log(name));
1960: } else {
1961: PetscCall(PetscInfo(0, "Not finalizing MPE (not started by PETSc).\n"));
1962: }
1963: #else
1964: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe");
1965: #endif
1966: PetscFunctionReturn(PETSC_SUCCESS);
1967: }
1969: /*@
1970: PetscLogView - Prints a summary of the logging.
1972: Collective
1974: Input Parameter:
1975: . viewer - an ASCII viewer
1977: Options Database Keys:
1978: + -log_view [:filename] - Prints summary of log information
1979: . -log_view :filename.py:ascii_info_detail - Saves logging information from each process as a Python file
1980: . -log_view :filename.xml:ascii_xml - Saves a summary of the logging information in a nested format (see below for how to view it)
1981: . -log_view :filename.txt:ascii_flamegraph - Saves logging information in a format suitable for visualising as a Flame Graph (see below for how to view it)
1982: . -log_view_memory - Also display memory usage in each event
1983: . -log_view_gpu_time - Also display time in each event for GPU kernels (Note this may slow the computation)
1984: . -log_all - Saves a file Log.rank for each MPI rank with details of each step of the computation
1985: - -log_trace [filename] - Displays a trace of what each process is doing
1987: Level: beginner
1989: Notes:
1990: It is possible to control the logging programmatically but we recommend using the options database approach whenever possible
1991: By default the summary is printed to stdout.
1993: Before calling this routine you must have called either PetscLogDefaultBegin() or PetscLogNestedBegin()
1995: If PETSc is configured with --with-logging=0 then this functionality is not available
1997: To view the nested XML format filename.xml first copy ${PETSC_DIR}/share/petsc/xml/performance_xml2html.xsl to the current
1998: directory then open filename.xml with your browser. Specific notes for certain browsers
1999: .vb
2000: Firefox and Internet explorer - simply open the file
2001: Google Chrome - you must start up Chrome with the option --allow-file-access-from-files
2002: Safari - see https://ccm.net/faq/36342-safari-how-to-enable-local-file-access
2003: .ve
2004: or one can use the package <http://xmlsoft.org/XSLT/xsltproc2.html> to translate the xml file to html and then open it with
2005: your browser.
2006: Alternatively, use the script ${PETSC_DIR}/lib/petsc/bin/petsc-performance-view to automatically open a new browser
2007: window and render the XML log file contents.
2009: The nested XML format was kindly donated by Koos Huijssen and Christiaan M. Klaij MARITIME RESEARCH INSTITUTE NETHERLANDS
2011: The Flame Graph output can be visualised using either the original Flame Graph script <https://github.com/brendangregg/FlameGraph>
2012: or using speedscope <https://www.speedscope.app>.
2013: Old XML profiles may be converted into this format using the script ${PETSC_DIR}/lib/petsc/bin/xml2flamegraph.py.
2015: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogDump()`
2016: @*/
2017: PetscErrorCode PetscLogView(PetscViewer viewer)
2018: {
2019: PetscBool isascii;
2020: PetscViewerFormat format;
2021: int stage;
2022: PetscLogState state;
2023: PetscIntStack temp_stack;
2024: PetscLogHandler handler;
2025: PetscBool is_empty;
2027: PetscFunctionBegin;
2028: PetscCall(PetscLogGetState(&state));
2029: /* Pop off any stages the user forgot to remove */
2030: PetscCall(PetscIntStackCreate(&temp_stack));
2031: PetscCall(PetscLogStateGetCurrentStage(state, &stage));
2032: while (stage >= 0) {
2033: PetscCall(PetscLogStagePop());
2034: PetscCall(PetscIntStackPush(temp_stack, stage));
2035: PetscCall(PetscLogStateGetCurrentStage(state, &stage));
2036: }
2037: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
2038: PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Currently can only view logging to ASCII");
2039: PetscCall(PetscViewerGetFormat(viewer, &format));
2040: if (format == PETSC_VIEWER_ASCII_XML || format == PETSC_VIEWER_ASCII_FLAMEGRAPH) {
2041: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERNESTED, &handler));
2042: PetscCall(PetscLogHandlerView(handler, viewer));
2043: } else {
2044: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
2045: PetscCall(PetscLogHandlerView(handler, viewer));
2046: }
2047: PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
2048: while (!is_empty) {
2049: PetscCall(PetscIntStackPop(temp_stack, &stage));
2050: PetscCall(PetscLogStagePush(stage));
2051: PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
2052: }
2053: PetscCall(PetscIntStackDestroy(temp_stack));
2054: PetscFunctionReturn(PETSC_SUCCESS);
2055: }
2057: /*@C
2058: PetscLogViewFromOptions - Processes command line options to determine if/how a `PetscLog` is to be viewed.
2060: Collective on `PETSC_COMM_WORLD`
2062: Level: developer
2064: .seealso: [](ch_profiling), `PetscLogView()`
2065: @*/
2066: PetscErrorCode PetscLogViewFromOptions(void)
2067: {
2068: PetscInt n_max = PETSC_LOG_VIEW_FROM_OPTIONS_MAX;
2069: PetscViewer viewers[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2070: PetscViewerFormat formats[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2071: PetscBool flg;
2073: PetscFunctionBegin;
2074: PetscCall(PetscOptionsCreateViewers(PETSC_COMM_WORLD, NULL, NULL, "-log_view", &n_max, viewers, formats, &flg));
2075: /*
2076: PetscLogHandlerView_Default_Info() wants to be sure that the only objects still around are these viewers, so keep track of how many there are
2077: */
2078: PetscLogNumViewersCreated = n_max;
2079: for (PetscInt i = 0; i < n_max; i++) {
2080: PetscInt refct;
2082: PetscCall(PetscViewerPushFormat(viewers[i], formats[i]));
2083: PetscCall(PetscLogView(viewers[i]));
2084: PetscCall(PetscViewerPopFormat(viewers[i]));
2085: PetscCall(PetscObjectGetReference((PetscObject)viewers[i], &refct));
2086: PetscCall(PetscViewerDestroy(&viewers[i]));
2087: if (refct == 1) PetscLogNumViewersDestroyed++;
2088: }
2089: PetscLogNumViewersDestroyed = 0;
2090: PetscFunctionReturn(PETSC_SUCCESS);
2091: }
2093: PETSC_INTERN PetscErrorCode PetscLogHandlerNestedSetThreshold(PetscLogHandler, PetscLogDouble, PetscLogDouble *);
2095: /*@
2096: PetscLogSetThreshold - Set the threshold time for logging the events; this is a percentage out of 100, so 1. means any event
2097: that takes 1 or more percent of the time.
2099: Logically Collective on `PETSC_COMM_WORLD`
2101: Input Parameter:
2102: . newThresh - the threshold to use
2104: Output Parameter:
2105: . oldThresh - the previously set threshold value
2107: Options Database Keys:
2108: . -log_view :filename.xml:ascii_xml - Prints an XML summary of flop and timing information to the file
2110: Example Usage:
2111: .vb
2112: PetscInitialize(...);
2113: PetscLogNestedBegin();
2114: PetscLogSetThreshold(0.1,&oldthresh);
2115: // ... code ...
2116: PetscLogView(viewer);
2117: PetscFinalize();
2118: .ve
2120: Level: advanced
2122: Note:
2123: This threshold is only used by the nested log handler
2125: .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`,
2126: `PetscLogNestedBegin()`
2127: @*/
2128: PetscErrorCode PetscLogSetThreshold(PetscLogDouble newThresh, PetscLogDouble *oldThresh)
2129: {
2130: PetscLogHandler handler;
2132: PetscFunctionBegin;
2133: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERNESTED, &handler));
2134: PetscCall(PetscLogHandlerNestedSetThreshold(handler, newThresh, oldThresh));
2135: PetscFunctionReturn(PETSC_SUCCESS);
2136: }
2138: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
2139: /*@
2140: PetscGetFlops - Returns the number of flops used on this processor
2141: since the program began.
2143: Not Collective
2145: Output Parameter:
2146: . flops - number of floating point operations
2148: Level: intermediate
2150: Notes:
2151: A global counter logs all PETSc flop counts. The user can use
2152: `PetscLogFlops()` to increment this counter to include flops for the
2153: application code.
2155: A separate counter `PetscLogGpuFlops()` logs the flops that occur on any GPU associated with this MPI rank
2157: .seealso: [](ch_profiling), `PetscLogGpuFlops()`, `PetscTime()`, `PetscLogFlops()`
2158: @*/
2159: PetscErrorCode PetscGetFlops(PetscLogDouble *flops)
2160: {
2161: PetscFunctionBegin;
2162: *flops = petsc_TotalFlops;
2163: PetscFunctionReturn(PETSC_SUCCESS);
2164: }
2166: /*@C
2167: PetscLogObjectState - Record information about an object with the default log handler
2169: Not Collective
2171: Input Parameters:
2172: + obj - the `PetscObject`
2173: . format - a printf-style format string
2174: - ... - printf arguments to format
2176: Level: developer
2178: .seealso: [](ch_profiling), `PetscLogObjectCreate()`, `PetscLogObjectDestroy()`, `PetscLogGetDefaultHandler()`
2179: @*/
2180: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
2181: {
2182: PetscFunctionBegin;
2183: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2184: PetscLogHandler h = PetscLogHandlers[i].handler;
2186: if (h) {
2187: va_list Argp;
2188: va_start(Argp, format);
2189: PetscCall(PetscLogHandlerLogObjectState_Internal(h, obj, format, Argp));
2190: va_end(Argp);
2191: }
2192: }
2193: PetscFunctionReturn(PETSC_SUCCESS);
2194: }
2196: /*MC
2197: PetscLogFlops - Adds floating point operations to the global counter.
2199: Synopsis:
2200: #include <petsclog.h>
2201: PetscErrorCode PetscLogFlops(PetscLogDouble f)
2203: Not Collective
2205: Input Parameter:
2206: . f - flop counter
2208: Example Usage:
2209: .vb
2210: PetscLogEvent USER_EVENT;
2212: PetscLogEventRegister("User event", 0, &USER_EVENT);
2213: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
2214: [code segment to monitor]
2215: PetscLogFlops(user_flops)
2216: PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
2217: .ve
2219: Level: intermediate
2221: Note:
2222: A global counter logs all PETSc flop counts. The user can use PetscLogFlops() to increment
2223: this counter to include flops for the application code.
2225: .seealso: [](ch_profiling), `PetscLogGpuFlops()`, `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscGetFlops()`
2226: M*/
2228: /*MC
2229: PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice) to get accurate
2230: timings
2232: Synopsis:
2233: #include <petsclog.h>
2234: void PetscPreLoadBegin(PetscBool flag, char *name);
2236: Not Collective
2238: Input Parameters:
2239: + flag - `PETSC_TRUE` to run twice, `PETSC_FALSE` to run once, may be overridden with command
2240: line option `-preload true|false`
2241: - name - name of first stage (lines of code timed separately with `-log_view`) to be preloaded
2243: Example Usage:
2244: .vb
2245: PetscPreLoadBegin(PETSC_TRUE, "first stage");
2246: // lines of code
2247: PetscPreLoadStage("second stage");
2248: // lines of code
2249: PetscPreLoadEnd();
2250: .ve
2252: Level: intermediate
2254: Note:
2255: Only works in C/C++, not Fortran
2257: Flags available within the macro\:
2258: + PetscPreLoadingUsed - `PETSC_TRUE` if we are or have done preloading
2259: . PetscPreLoadingOn - `PETSC_TRUE` if it is CURRENTLY doing preload
2260: . PetscPreLoadIt - `0` for the first computation (with preloading turned off it is only
2261: `0`) `1` for the second
2262: - PetscPreLoadMax - number of times it will do the computation, only one when preloading is
2263: turned on
2265: The first two variables are available throughout the program, the second two only between the
2266: `PetscPreLoadBegin()` and `PetscPreLoadEnd()`
2268: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
2269: M*/
2271: /*MC
2272: PetscPreLoadEnd - End a segment of code that may be preloaded (run twice) to get accurate
2273: timings
2275: Synopsis:
2276: #include <petsclog.h>
2277: void PetscPreLoadEnd(void);
2279: Not Collective
2281: Example Usage:
2282: .vb
2283: PetscPreLoadBegin(PETSC_TRUE, "first stage");
2284: // lines of code
2285: PetscPreLoadStage("second stage");
2286: // lines of code
2287: PetscPreLoadEnd();
2288: .ve
2290: Level: intermediate
2292: Note:
2293: Only works in C/C++ not Fortran
2295: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadStage()`
2296: M*/
2298: /*MC
2299: PetscPreLoadStage - Start a new segment of code to be timed separately to get accurate timings
2301: Synopsis:
2302: #include <petsclog.h>
2303: void PetscPreLoadStage(char *name);
2305: Not Collective
2307: Example Usage:
2308: .vb
2309: PetscPreLoadBegin(PETSC_TRUE,"first stage");
2310: // lines of code
2311: PetscPreLoadStage("second stage");
2312: // lines of code
2313: PetscPreLoadEnd();
2314: .ve
2316: Level: intermediate
2318: Note:
2319: Only works in C/C++ not Fortran
2321: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`
2322: M*/
2324: #if PetscDefined(HAVE_DEVICE)
2325: #include <petsc/private/deviceimpl.h>
2327: /*@
2328: PetscLogGpuTime - turn on the logging of GPU time for GPU kernels
2330: Options Database Key:
2331: . -log_view_gpu_time - provide the GPU times for all events in the `-log_view` output
2333: Level: advanced
2335: Notes:
2336: Turning on the timing of the GPU kernels can slow down the entire computation and should only
2337: be used when studying the performance of individual operations on GPU such as vector operations and
2338: matrix-vector operations.
2340: If this option is not used then times for most of the events in the `-log_view` output will be listed as Nan, indicating the times are not available
2342: This routine should only be called once near the beginning of the program. Once it is started
2343: it cannot be turned off.
2345: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTimeBegin()`
2346: @*/
2347: PetscErrorCode PetscLogGpuTime(void)
2348: {
2349: PetscFunctionBegin;
2350: PetscCheck(petsc_gtime == 0.0, PETSC_COMM_SELF, PETSC_ERR_SUP, "GPU logging has already been turned on");
2351: PetscLogGpuTimeFlag = PETSC_TRUE;
2352: PetscFunctionReturn(PETSC_SUCCESS);
2353: }
2355: /*@
2356: PetscLogGpuTimeBegin - Start timer for device
2358: Level: intermediate
2360: Notes:
2361: When GPU is enabled, the timer is run on the GPU, it is a separate logging of time
2362: devoted to GPU computations (excluding kernel launch times).
2364: When GPU is not available, the timer is run on the CPU, it is a separate logging of
2365: time devoted to GPU computations (including kernel launch times).
2367: There is no need to call WaitForCUDA() or WaitForHIP() between `PetscLogGpuTimeBegin()` and
2368: `PetscLogGpuTimeEnd()`
2370: This timer should NOT include times for data transfers between the GPU and CPU, nor setup
2371: actions such as allocating space.
2373: The regular logging captures the time for data transfers and any CPU activities during the
2374: event. It is used to compute the flop rate on the GPU as it is actively engaged in running a
2375: kernel.
2377: Developer Notes:
2378: The GPU event timer captures the execution time of all the kernels launched in the default
2379: stream by the CPU between `PetscLogGpuTimeBegin()` and `PetscLogGpuTimeEnd()`.
2381: `PetscLogGpuTimeBegin()` and `PetscLogGpuTimeEnd()` insert the begin and end events into the
2382: default stream (stream 0). The device will record a time stamp for the event when it reaches
2383: that event in the stream. The function xxxEventSynchronize() is called in
2384: `PetscLogGpuTimeEnd()` to block CPU execution, but not continued GPU execution, until the
2385: timer event is recorded.
2387: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTime()`
2388: @*/
2389: PetscErrorCode PetscLogGpuTimeBegin(void)
2390: {
2391: PetscBool isActive;
2393: PetscFunctionBegin;
2394: PetscCall(PetscLogEventBeginIsActive(&isActive));
2395: if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2396: #if defined(PETSC_HAVE_DEVICE) && !defined(PETSC_HAVE_KOKKOS_WITHOUT_GPU)
2397: {
2398: PetscDeviceContext dctx;
2400: PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2401: PetscCall(PetscDeviceContextBeginTimer_Internal(dctx));
2402: }
2403: #else
2404: PetscCall(PetscTimeSubtract(&petsc_gtime));
2405: #endif
2406: PetscFunctionReturn(PETSC_SUCCESS);
2407: }
2409: /*@
2410: PetscLogGpuTimeEnd - Stop timer for device
2412: Level: intermediate
2414: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeBegin()`
2415: @*/
2416: PetscErrorCode PetscLogGpuTimeEnd(void)
2417: {
2418: PetscBool isActive;
2420: PetscFunctionBegin;
2421: PetscCall(PetscLogEventEndIsActive(&isActive));
2422: if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2423: #if defined(PETSC_HAVE_DEVICE) && !defined(PETSC_HAVE_KOKKOS_WITHOUT_GPU)
2424: {
2425: PetscDeviceContext dctx;
2426: PetscLogDouble elapsed;
2428: PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2429: PetscCall(PetscDeviceContextEndTimer_Internal(dctx, &elapsed));
2430: petsc_gtime += (elapsed / 1000.0);
2431: }
2432: #else
2433: PetscCall(PetscTimeAdd(&petsc_gtime));
2434: #endif
2435: PetscFunctionReturn(PETSC_SUCCESS);
2436: }
2438: #endif /* end of PETSC_HAVE_DEVICE */
2440: #endif /* PETSC_USE_LOG*/
2442: /* -- Utility functions for logging from Fortran -- */
2444: PETSC_EXTERN PetscErrorCode PetscASend(int count, int datatype)
2445: {
2446: PetscFunctionBegin;
2447: #if PetscDefined(USE_LOG)
2448: PetscCall(PetscAddLogDouble(&petsc_send_ct, &petsc_send_ct_th, 1));
2449: #if !defined(MPIUNI_H) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO)
2450: PetscCall(PetscMPITypeSize(count, MPI_Type_f2c((MPI_Fint)datatype), &petsc_send_len, &petsc_send_len_th));
2451: #endif
2452: #endif
2453: PetscFunctionReturn(PETSC_SUCCESS);
2454: }
2456: PETSC_EXTERN PetscErrorCode PetscARecv(int count, int datatype)
2457: {
2458: PetscFunctionBegin;
2459: #if PetscDefined(USE_LOG)
2460: PetscCall(PetscAddLogDouble(&petsc_recv_ct, &petsc_recv_ct_th, 1));
2461: #if !defined(MPIUNI_H) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO)
2462: PetscCall(PetscMPITypeSize(count, MPI_Type_f2c((MPI_Fint)datatype), &petsc_recv_len, &petsc_recv_len_th));
2463: #endif
2464: #endif
2465: PetscFunctionReturn(PETSC_SUCCESS);
2466: }
2468: PETSC_EXTERN PetscErrorCode PetscAReduce(void)
2469: {
2470: PetscFunctionBegin;
2471: if (PetscDefined(USE_LOG)) PetscCall(PetscAddLogDouble(&petsc_allreduce_ct, &petsc_allreduce_ct_th, 1));
2472: PetscFunctionReturn(PETSC_SUCCESS);
2473: }
2475: PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2476: PetscClassId PETSC_OBJECT_CLASSID = 0;
2478: static PetscBool PetscLogInitializeCalled = PETSC_FALSE;
2480: PETSC_INTERN PetscErrorCode PetscLogInitialize(void)
2481: {
2482: int stage;
2484: PetscFunctionBegin;
2485: if (PetscLogInitializeCalled) PetscFunctionReturn(PETSC_SUCCESS);
2486: PetscLogInitializeCalled = PETSC_TRUE;
2487: if (PetscDefined(USE_LOG)) {
2488: /* Setup default logging structures */
2489: PetscCall(PetscLogStateCreate(&petsc_log_state));
2490: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2491: if (PetscLogHandlers[i].handler) PetscCall(PetscLogHandlerSetState(PetscLogHandlers[i].handler, petsc_log_state));
2492: }
2493: PetscCall(PetscLogStateStageRegister(petsc_log_state, "Main Stage", &stage));
2494: PetscCall(PetscSpinlockCreate(&PetscLogSpinLock));
2495: #if defined(PETSC_HAVE_THREADSAFETY)
2496: petsc_log_tid = 0;
2497: petsc_log_gid = 0;
2498: #endif
2500: /* All processors sync here for more consistent logging */
2501: PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
2502: PetscCall(PetscTime(&petsc_BaseTime));
2503: PetscCall(PetscLogStagePush(stage));
2504: }
2505: PetscFunctionReturn(PETSC_SUCCESS);
2506: }
2508: PETSC_INTERN PetscErrorCode PetscLogFinalize(void)
2509: {
2510: PetscFunctionBegin;
2511: if (PetscDefined(USE_LOG)) {
2512: /* Resetting phase */
2513: // pop remaining stages
2514: if (petsc_log_state) {
2515: while (petsc_log_state->current_stage >= 0) PetscCall(PetscLogStagePop());
2516: }
2517: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) PetscCall(PetscLogHandlerDestroy(&PetscLogHandlers[i].handler));
2518: PetscCall(PetscArrayzero(PetscLogHandlers, PETSC_LOG_HANDLER_MAX));
2519: PetscCall(PetscLogStateDestroy(&petsc_log_state));
2521: petsc_TotalFlops = 0.0;
2522: petsc_BaseTime = 0.0;
2523: petsc_TotalFlops = 0.0;
2524: petsc_send_ct = 0.0;
2525: petsc_recv_ct = 0.0;
2526: petsc_send_len = 0.0;
2527: petsc_recv_len = 0.0;
2528: petsc_isend_ct = 0.0;
2529: petsc_irecv_ct = 0.0;
2530: petsc_isend_len = 0.0;
2531: petsc_irecv_len = 0.0;
2532: petsc_wait_ct = 0.0;
2533: petsc_wait_any_ct = 0.0;
2534: petsc_wait_all_ct = 0.0;
2535: petsc_sum_of_waits_ct = 0.0;
2536: petsc_allreduce_ct = 0.0;
2537: petsc_gather_ct = 0.0;
2538: petsc_scatter_ct = 0.0;
2539: petsc_TotalFlops_th = 0.0;
2540: petsc_send_ct_th = 0.0;
2541: petsc_recv_ct_th = 0.0;
2542: petsc_send_len_th = 0.0;
2543: petsc_recv_len_th = 0.0;
2544: petsc_isend_ct_th = 0.0;
2545: petsc_irecv_ct_th = 0.0;
2546: petsc_isend_len_th = 0.0;
2547: petsc_irecv_len_th = 0.0;
2548: petsc_wait_ct_th = 0.0;
2549: petsc_wait_any_ct_th = 0.0;
2550: petsc_wait_all_ct_th = 0.0;
2551: petsc_sum_of_waits_ct_th = 0.0;
2552: petsc_allreduce_ct_th = 0.0;
2553: petsc_gather_ct_th = 0.0;
2554: petsc_scatter_ct_th = 0.0;
2556: petsc_ctog_ct = 0.0;
2557: petsc_gtoc_ct = 0.0;
2558: petsc_ctog_sz = 0.0;
2559: petsc_gtoc_sz = 0.0;
2560: petsc_gflops = 0.0;
2561: petsc_gtime = 0.0;
2562: petsc_ctog_ct_th = 0.0;
2563: petsc_gtoc_ct_th = 0.0;
2564: petsc_ctog_sz_th = 0.0;
2565: petsc_gtoc_sz_th = 0.0;
2566: petsc_gflops_th = 0.0;
2567: petsc_gtime_th = 0.0;
2568: }
2569: PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2570: PETSC_OBJECT_CLASSID = 0;
2571: PetscLogInitializeCalled = PETSC_FALSE;
2572: PetscFunctionReturn(PETSC_SUCCESS);
2573: }
2575: /*@
2576: PetscClassIdRegister - Registers a new class name for objects and logging operations in an application code.
2578: Not Collective
2580: Input Parameter:
2581: . name - The class name
2583: Output Parameter:
2584: . oclass - The class id or classid
2586: Level: developer
2588: .seealso: [](ch_profiling), `PetscLogEventRegister()`
2589: @*/
2590: PetscErrorCode PetscClassIdRegister(const char name[], PetscClassId *oclass)
2591: {
2592: PetscFunctionBegin;
2593: *oclass = ++PETSC_LARGEST_CLASSID;
2594: #if defined(PETSC_USE_LOG)
2595: {
2596: PetscLogState state;
2597: PetscLogClass logclass;
2599: PetscCall(PetscLogGetState(&state));
2600: if (state) PetscCall(PetscLogStateClassRegister(state, name, *oclass, &logclass));
2601: }
2602: #endif
2603: PetscFunctionReturn(PETSC_SUCCESS);
2604: }