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: PetscLogState petsc_log_state = NULL;
106: #define PETSC_LOG_HANDLER_HOT_BLANK {NULL, NULL, NULL, NULL, NULL, NULL}
108: PetscLogHandlerHot PetscLogHandlers[PETSC_LOG_HANDLER_MAX] = {
109: PETSC_LOG_HANDLER_HOT_BLANK,
110: PETSC_LOG_HANDLER_HOT_BLANK,
111: PETSC_LOG_HANDLER_HOT_BLANK,
112: PETSC_LOG_HANDLER_HOT_BLANK,
113: };
115: #undef PETSC_LOG_HANDLERS_HOT_BLANK
117: #if defined(PETSC_USE_LOG)
118: #include <../src/sys/logging/handler/impls/default/logdefault.h>
120: #if defined(PETSC_HAVE_THREADSAFETY)
121: PetscErrorCode PetscAddLogDouble(PetscLogDouble *tot, PetscLogDouble *tot_th, PetscLogDouble tmp)
122: {
123: *tot_th += tmp;
124: PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
125: *tot += tmp;
126: PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
127: return PETSC_SUCCESS;
128: }
130: PetscErrorCode PetscAddLogDoubleCnt(PetscLogDouble *cnt, PetscLogDouble *tot, PetscLogDouble *cnt_th, PetscLogDouble *tot_th, PetscLogDouble tmp)
131: {
132: *cnt_th = *cnt_th + 1;
133: *tot_th += tmp;
134: PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
135: *tot += (PetscLogDouble)tmp;
136: *cnt += *cnt + 1;
137: PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
138: return PETSC_SUCCESS;
139: }
141: #endif
143: static PetscErrorCode PetscLogTryGetHandler(PetscLogHandlerType type, PetscLogHandler *handler)
144: {
145: PetscFunctionBegin;
146: PetscAssertPointer(handler, 2);
147: *handler = NULL;
148: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
149: PetscLogHandler h = PetscLogHandlers[i].handler;
150: if (h) {
151: PetscBool match;
153: PetscCall(PetscObjectTypeCompare((PetscObject)h, type, &match));
154: if (match) {
155: *handler = PetscLogHandlers[i].handler;
156: PetscFunctionReturn(PETSC_SUCCESS);
157: }
158: }
159: }
160: PetscFunctionReturn(PETSC_SUCCESS);
161: }
163: /*@
164: PetscLogGetDefaultHandler - Get the default log handler if it is running.
166: Not collective
168: Output Parameter:
169: . handler - the default `PetscLogHandler`, or `NULL` if it is not running.
171: Level: developer
173: Notes:
174: The default handler is started with `PetscLogDefaultBegin()`,
175: if the options flags `-log_all` or `-log_view` is given without arguments,
176: or for `-log_view :output:format` if `format` is not `ascii_xml` or `ascii_flamegraph`.
178: .seealso: [](ch_profiling)
179: @*/
180: PetscErrorCode PetscLogGetDefaultHandler(PetscLogHandler *handler)
181: {
182: PetscFunctionBegin;
183: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, handler));
184: PetscFunctionReturn(PETSC_SUCCESS);
185: }
187: static PetscErrorCode PetscLogGetHandler(PetscLogHandlerType type, PetscLogHandler *handler)
188: {
189: PetscFunctionBegin;
190: PetscAssertPointer(handler, 2);
191: PetscCall(PetscLogTryGetHandler(type, handler));
192: PetscCheck(*handler != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "A PetscLogHandler of type %s has not been started.", type);
193: PetscFunctionReturn(PETSC_SUCCESS);
194: }
196: /*@
197: PetscLogGetState - Get the `PetscLogState` for PETSc's global logging, used
198: by all default log handlers (`PetscLogDefaultBegin()`,
199: `PetscLogNestedBegin()`, `PetscLogTraceBegin()`, `PetscLogMPEBegin()`,
200: `PetscLogPerfstubsBegin()`).
202: Collective on `PETSC_COMM_WORLD`
204: Output Parameter:
205: . state - The `PetscLogState` changed by registrations (such as
206: `PetscLogEventRegister()`) and actions (such as `PetscLogEventBegin()` or
207: `PetscLogStagePush()`), or `NULL` if logging is not active
209: Level: developer
211: .seealso: [](ch_profiling), `PetscLogState`
212: @*/
213: PetscErrorCode PetscLogGetState(PetscLogState *state)
214: {
215: PetscFunctionBegin;
216: PetscAssertPointer(state, 1);
217: *state = petsc_log_state;
218: PetscFunctionReturn(PETSC_SUCCESS);
219: }
221: static PetscErrorCode PetscLogHandlerCopyToHot(PetscLogHandler h, PetscLogHandlerHot *hot)
222: {
223: PetscFunctionBegin;
224: hot->handler = h;
225: hot->eventBegin = h->ops->eventbegin;
226: hot->eventEnd = h->ops->eventend;
227: hot->eventSync = h->ops->eventsync;
228: hot->objectCreate = h->ops->objectcreate;
229: hot->objectDestroy = h->ops->objectdestroy;
230: PetscFunctionReturn(PETSC_SUCCESS);
231: }
233: /*@
234: PetscLogHandlerStart - Connect a log handler to PETSc's global logging stream and state.
236: Logically collective
238: Input Parameters:
239: . h - a `PetscLogHandler`
241: Level: developer
243: Notes:
244: Users should only need this if they create their own log handlers: handlers that are started
245: from the command line (such as `-log_view` and `-log_trace`) or from a function like
246: `PetscLogNestedBegin()` will automatically be started.
248: There is a limit of `PESC_LOG_HANDLER_MAX` handlers that can be active at one time.
250: To disconnect a handler from the global stream call `PetscLogHandlerStop()`.
252: When a log handler is started, stages that have already been pushed with `PetscLogStagePush()`,
253: will be pushed for the new log handler, but it will not be informed of any events that are
254: in progress. It is recommended to start any user-defined log handlers immediately following
255: `PetscInitialize()` before any user-defined stages are pushed.
257: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogHandlerStop()`, `PetscInitialize()`
258: @*/
259: PetscErrorCode PetscLogHandlerStart(PetscLogHandler h)
260: {
261: PetscFunctionBegin;
262: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
263: if (PetscLogHandlers[i].handler == h) PetscFunctionReturn(PETSC_SUCCESS);
264: }
265: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
266: if (PetscLogHandlers[i].handler == NULL) {
267: PetscCall(PetscObjectReference((PetscObject)h));
268: PetscCall(PetscLogHandlerCopyToHot(h, &PetscLogHandlers[i]));
269: if (petsc_log_state) {
270: PetscLogStage stack_height;
271: PetscIntStack orig_stack, temp_stack;
273: PetscCall(PetscLogHandlerSetState(h, petsc_log_state));
274: stack_height = petsc_log_state->stage_stack->top + 1;
275: PetscCall(PetscIntStackCreate(&temp_stack));
276: orig_stack = petsc_log_state->stage_stack;
277: petsc_log_state->stage_stack = temp_stack;
278: petsc_log_state->current_stage = -1;
279: for (int s = 0; s < stack_height; s++) {
280: PetscLogStage stage = orig_stack->stack[s];
281: PetscCall(PetscLogHandlerStagePush(h, stage));
282: PetscCall(PetscIntStackPush(temp_stack, stage));
283: petsc_log_state->current_stage = stage;
284: }
285: PetscCall(PetscIntStackDestroy(temp_stack));
286: petsc_log_state->stage_stack = orig_stack;
287: }
288: PetscFunctionReturn(PETSC_SUCCESS);
289: }
290: }
291: SETERRQ(PetscObjectComm((PetscObject)h), PETSC_ERR_ARG_WRONGSTATE, "%d log handlers already started, cannot start another", PETSC_LOG_HANDLER_MAX);
292: PetscFunctionReturn(PETSC_SUCCESS);
293: }
295: /*@
296: PetscLogHandlerStop - Disconnect a log handler from PETSc's global logging stream.
298: Logically collective
300: Input Parameters:
301: . h - a `PetscLogHandler`
303: Level: developer
305: Note:
306: After `PetscLogHandlerStop()`, the handler can still access the global logging state
307: with `PetscLogHandlerGetState()`, so that it can access the registry when post-processing
308: (for instance, in `PetscLogHandlerView()`),
310: When a log handler is stopped, the remaining stages will be popped before it is
311: disconnected from the log stream.
313: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogHandlerStart()`
314: @*/
315: PetscErrorCode PetscLogHandlerStop(PetscLogHandler h)
316: {
317: PetscFunctionBegin;
318: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
319: if (PetscLogHandlers[i].handler == h) {
320: if (petsc_log_state) {
321: PetscLogState state;
322: PetscLogStage stack_height;
323: PetscIntStack orig_stack, temp_stack;
325: PetscCall(PetscLogHandlerGetState(h, &state));
326: PetscCheck(state == petsc_log_state, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "Called PetscLogHandlerStop() for a PetscLogHander that was not started.");
327: stack_height = petsc_log_state->stage_stack->top + 1;
328: PetscCall(PetscIntStackCreate(&temp_stack));
329: orig_stack = petsc_log_state->stage_stack;
330: petsc_log_state->stage_stack = temp_stack;
331: for (int s = 0; s < stack_height; s++) {
332: PetscLogStage stage = orig_stack->stack[s];
334: PetscCall(PetscIntStackPush(temp_stack, stage));
335: }
336: for (int s = 0; s < stack_height; s++) {
337: PetscLogStage stage;
338: PetscBool empty;
340: PetscCall(PetscIntStackPop(temp_stack, &stage));
341: PetscCall(PetscIntStackEmpty(temp_stack, &empty));
342: if (!empty) {
343: PetscCall(PetscIntStackTop(temp_stack, &petsc_log_state->current_stage));
344: } else petsc_log_state->current_stage = -1;
345: PetscCall(PetscLogHandlerStagePop(h, stage));
346: }
347: PetscCall(PetscIntStackDestroy(temp_stack));
348: petsc_log_state->stage_stack = orig_stack;
349: PetscCall(PetscIntStackTop(petsc_log_state->stage_stack, &petsc_log_state->current_stage));
350: }
351: PetscCall(PetscArrayzero(&PetscLogHandlers[i], 1));
352: PetscCall(PetscObjectDereference((PetscObject)h));
353: }
354: }
355: PetscFunctionReturn(PETSC_SUCCESS);
356: }
358: /*@
359: PetscLogIsActive - Check if logging is currently in progress.
361: Not Collective
363: Output Parameter:
364: . isActive - `PETSC_TRUE` if logging is in progress, `PETSC_FALSE` otherwise
366: Level: beginner
368: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`
369: @*/
370: PetscErrorCode PetscLogIsActive(PetscBool *isActive)
371: {
372: PetscFunctionBegin;
373: *isActive = PETSC_FALSE;
374: if (petsc_log_state) {
375: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
376: if (PetscLogHandlers[i].handler) {
377: *isActive = PETSC_TRUE;
378: PetscFunctionReturn(PETSC_SUCCESS);
379: }
380: }
381: }
382: PetscFunctionReturn(PETSC_SUCCESS);
383: }
385: PETSC_UNUSED static PetscErrorCode PetscLogEventBeginIsActive(PetscBool *isActive)
386: {
387: PetscFunctionBegin;
388: *isActive = PETSC_FALSE;
389: if (petsc_log_state) {
390: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
391: if (PetscLogHandlers[i].eventBegin) {
392: *isActive = PETSC_TRUE;
393: PetscFunctionReturn(PETSC_SUCCESS);
394: }
395: }
396: }
397: PetscFunctionReturn(PETSC_SUCCESS);
398: }
400: PETSC_UNUSED static PetscErrorCode PetscLogEventEndIsActive(PetscBool *isActive)
401: {
402: PetscFunctionBegin;
403: *isActive = PETSC_FALSE;
404: if (petsc_log_state) {
405: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
406: if (PetscLogHandlers[i].eventEnd) {
407: *isActive = PETSC_TRUE;
408: PetscFunctionReturn(PETSC_SUCCESS);
409: }
410: }
411: }
412: PetscFunctionReturn(PETSC_SUCCESS);
413: }
415: PETSC_INTERN PetscErrorCode PetscLogTypeBegin(PetscLogHandlerType type)
416: {
417: PetscLogHandler handler;
419: PetscFunctionBegin;
420: PetscCall(PetscLogTryGetHandler(type, &handler));
421: if (handler) PetscFunctionReturn(PETSC_SUCCESS);
422: PetscCall(PetscLogHandlerCreate(PETSC_COMM_WORLD, &handler));
423: PetscCall(PetscLogHandlerSetType(handler, type));
424: PetscCall(PetscLogHandlerStart(handler));
425: PetscCall(PetscLogHandlerDestroy(&handler));
426: PetscFunctionReturn(PETSC_SUCCESS);
427: }
429: /*@
430: PetscLogDefaultBegin - Turns on logging of objects and events using the default log handler. This logs flop
431: rates and object creation and should not slow programs down too much.
432: This routine may be called more than once.
434: Logically Collective on `PETSC_COMM_WORLD`
436: Options Database Key:
437: . -log_view [viewertype:filename:viewerformat] - Prints summary of flop and timing information to the
438: screen (for code configured with --with-log=1 (which is the default))
440: Example Usage:
441: .vb
442: PetscInitialize(...);
443: PetscLogDefaultBegin();
444: ... code ...
445: PetscLogView(viewer); or PetscLogDump();
446: PetscFinalize();
447: .ve
449: Level: advanced
451: Note:
452: `PetscLogView()` or `PetscLogDump()` actually cause the printing of
453: the logging information.
455: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`
456: @*/
457: PetscErrorCode PetscLogDefaultBegin(void)
458: {
459: PetscFunctionBegin;
460: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERDEFAULT));
461: PetscFunctionReturn(PETSC_SUCCESS);
462: }
464: /*@C
465: PetscLogTraceBegin - Begins trace logging. Every time a PETSc event
466: begins or ends, the event name is printed.
468: Logically Collective on `PETSC_COMM_WORLD`, No Fortran Support
470: Input Parameter:
471: . file - The file to print trace in (e.g. stdout)
473: Options Database Key:
474: . -log_trace [filename] - Begins `PetscLogTraceBegin()`
476: Level: intermediate
478: Notes:
479: `PetscLogTraceBegin()` prints the processor number, the execution time (sec),
480: then "Event begin:" or "Event end:" followed by the event name.
482: `PetscLogTraceBegin()` allows tracing of all PETSc calls, which is useful
483: to determine where a program is hanging without running in the
484: debugger. Can be used in conjunction with the -info option.
486: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogView()`, `PetscLogDefaultBegin()`
487: @*/
488: PetscErrorCode PetscLogTraceBegin(FILE *file)
489: {
490: PetscLogHandler handler;
492: PetscFunctionBegin;
493: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERTRACE, &handler));
494: if (handler) PetscFunctionReturn(PETSC_SUCCESS);
495: PetscCall(PetscLogHandlerCreateTrace(PETSC_COMM_WORLD, file, &handler));
496: PetscCall(PetscLogHandlerStart(handler));
497: PetscCall(PetscLogHandlerDestroy(&handler));
498: PetscFunctionReturn(PETSC_SUCCESS);
499: }
501: PETSC_INTERN PetscErrorCode PetscLogHandlerCreate_Nested(MPI_Comm, PetscLogHandler *);
503: /*@
504: PetscLogNestedBegin - Turns on nested logging of objects and events. This logs flop
505: rates and object creation and should not slow programs down too much.
507: Logically Collective on `PETSC_COMM_WORLD`, No Fortran Support
509: Options Database Keys:
510: . -log_view :filename.xml:ascii_xml - Prints an XML summary of flop and timing information to the file
512: Example Usage:
513: .vb
514: PetscInitialize(...);
515: PetscLogNestedBegin();
516: ... code ...
517: PetscLogView(viewer);
518: PetscFinalize();
519: .ve
521: Level: advanced
523: .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`
524: @*/
525: PetscErrorCode PetscLogNestedBegin(void)
526: {
527: PetscFunctionBegin;
528: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERNESTED));
529: PetscFunctionReturn(PETSC_SUCCESS);
530: }
532: /*@C
533: PetscLogLegacyCallbacksBegin - Create and start a log handler from callbacks
534: matching the now deprecated function pointers `PetscLogPLB`, `PetscLogPLE`,
535: `PetscLogPHC`, `PetscLogPHD`.
537: Logically Collective on `PETSC_COMM_WORLD`
539: Input Parameters:
540: + PetscLogPLB - A callback that will be executed by `PetscLogEventBegin()` (or `NULL`)
541: . PetscLogPLE - A callback that will be executed by `PetscLogEventEnd()` (or `NULL`)
542: . PetscLogPHC - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`)
543: - PetscLogPHD - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`)
545: Calling sequence of `PetscLogPLB`:
546: + e - a `PetscLogEvent` that is beginning
547: . _i - deprecated, unused
548: . o1 - a `PetscObject` associated with `e` (or `NULL`)
549: . o2 - a `PetscObject` associated with `e` (or `NULL`)
550: . o3 - a `PetscObject` associated with `e` (or `NULL`)
551: - o4 - a `PetscObject` associated with `e` (or `NULL`)
553: Calling sequence of `PetscLogPLE`:
554: + e - a `PetscLogEvent` that is beginning
555: . _i - deprecated, unused
556: . o1 - a `PetscObject` associated with `e` (or `NULL`)
557: . o2 - a `PetscObject` associated with `e` (or `NULL`)
558: . o3 - a `PetscObject` associated with `e` (or `NULL`)
559: - o4 - a `PetscObject` associated with `e` (or `NULL`)
561: Calling sequence of `PetscLogPHC`:
562: . o - a `PetscObject` that has just been created
564: Calling sequence of `PetscLogPHD`:
565: . o - a `PetscObject` that is about to be destroyed
567: Level: advanced
569: Notes:
570: This is for transitioning from the deprecated function `PetscLogSet()` and should not be used in new code.
572: This should help migrate external log handlers to use `PetscLogHandler`, but
573: callbacks that depend on the deprecated `PetscLogStage` datatype will have to be
574: updated.
576: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerStart()`, `PetscLogState`
577: @*/
578: 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))
579: {
580: PetscLogHandler handler;
582: PetscFunctionBegin;
583: PetscCall(PetscLogHandlerCreateLegacy(PETSC_COMM_WORLD, PetscLogPLB, PetscLogPLE, PetscLogPHC, PetscLogPHD, &handler));
584: PetscCall(PetscLogHandlerStart(handler));
585: PetscCall(PetscLogHandlerDestroy(&handler));
586: PetscFunctionReturn(PETSC_SUCCESS);
587: }
589: #if defined(PETSC_HAVE_MPE)
590: #include <mpe.h>
591: static PetscBool PetscBeganMPE = PETSC_FALSE;
592: #endif
594: /*@C
595: PetscLogMPEBegin - Turns on MPE logging of events. This creates large log files and slows the
596: program down.
598: Collective on `PETSC_COMM_WORLD`, No Fortran Support
600: Options Database Key:
601: . -log_mpe - Prints extensive log information
603: Level: advanced
605: Note:
606: A related routine is `PetscLogDefaultBegin()` (with the options key `-log_view`), which is
607: intended for production runs since it logs only flop rates and object creation (and should
608: not significantly slow the programs).
610: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogDefaultBegin()`, `PetscLogEventActivate()`,
611: `PetscLogEventDeactivate()`
612: @*/
613: PetscErrorCode PetscLogMPEBegin(void)
614: {
615: PetscFunctionBegin;
616: #if defined(PETSC_HAVE_MPE)
617: /* Do MPE initialization */
618: if (!MPE_Initialized_logging()) { /* This function exists in mpich 1.1.2 and higher */
619: PetscCall(PetscInfo(0, "Initializing MPE.\n"));
620: PetscCall(MPE_Init_log());
622: PetscBeganMPE = PETSC_TRUE;
623: } else {
624: PetscCall(PetscInfo(0, "MPE already initialized. Not attempting to reinitialize.\n"));
625: }
626: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERMPE));
627: #else
628: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe");
629: #endif
630: PetscFunctionReturn(PETSC_SUCCESS);
631: }
633: #if defined(PETSC_HAVE_TAU_PERFSTUBS)
634: #include <../src/sys/perfstubs/timer.h>
635: #endif
637: /*@C
638: PetscLogPerfstubsBegin - Turns on logging of events using the perfstubs interface.
640: Collective on `PETSC_COMM_WORLD`, No Fortran Support
642: Options Database Key:
643: . -log_perfstubs - use an external log handler through the perfstubs interface
645: Level: advanced
647: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogEventActivate()`
648: @*/
649: PetscErrorCode PetscLogPerfstubsBegin(void)
650: {
651: PetscFunctionBegin;
652: #if defined(PETSC_HAVE_TAU_PERFSTUBS)
653: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERPERFSTUBS));
654: #else
655: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without perfstubs support, reconfigure with --with-tau-perfstubs");
656: #endif
657: PetscFunctionReturn(PETSC_SUCCESS);
658: }
660: /*@
661: PetscLogActions - Determines whether actions are logged for the default log handler.
663: Not Collective
665: Input Parameter:
666: . flag - `PETSC_TRUE` if actions are to be logged
668: Options Database Key:
669: + -log_exclude_actions - (deprecated) Does nothing
670: - -log_include_actions - Turn on action logging
672: Level: intermediate
674: Note:
675: Logging of actions continues to consume more memory as the program
676: runs. Long running programs should consider turning this feature off.
678: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogGetDefaultHandler()`
679: @*/
680: PetscErrorCode PetscLogActions(PetscBool flag)
681: {
682: PetscFunctionBegin;
683: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
684: PetscLogHandler h = PetscLogHandlers[i].handler;
686: if (h) PetscCall(PetscLogHandlerSetLogActions(h, flag));
687: }
688: PetscFunctionReturn(PETSC_SUCCESS);
689: }
691: /*@
692: PetscLogObjects - Determines whether objects are logged for the graphical viewer.
694: Not Collective
696: Input Parameter:
697: . flag - `PETSC_TRUE` if objects are to be logged
699: Options Database Key:
700: + -log_exclude_objects - (deprecated) Does nothing
701: - -log_include_objects - Turns on object logging
703: Level: intermediate
705: Note:
706: Logging of objects continues to consume more memory as the program
707: runs. Long running programs should consider turning this feature off.
709: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogGetDefaultHandler()`
710: @*/
711: PetscErrorCode PetscLogObjects(PetscBool flag)
712: {
713: PetscFunctionBegin;
714: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
715: PetscLogHandler h = PetscLogHandlers[i].handler;
717: if (h) PetscCall(PetscLogHandlerSetLogObjects(h, flag));
718: }
719: PetscFunctionReturn(PETSC_SUCCESS);
720: }
722: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
723: /*@
724: PetscLogStageRegister - Attaches a character string name to a logging stage.
726: Not Collective
728: Input Parameter:
729: . sname - The name to associate with that stage
731: Output Parameter:
732: . stage - The stage number or -1 if logging is not active (`PetscLogIsActive()`).
734: Level: intermediate
736: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`
737: @*/
738: PetscErrorCode PetscLogStageRegister(const char sname[], PetscLogStage *stage)
739: {
740: PetscLogState state;
742: PetscFunctionBegin;
743: *stage = -1;
744: PetscCall(PetscLogGetState(&state));
745: if (state) PetscCall(PetscLogStateStageRegister(state, sname, stage));
746: PetscFunctionReturn(PETSC_SUCCESS);
747: }
749: /*@
750: PetscLogStagePush - This function pushes a stage on the logging stack. Events started and stopped until `PetscLogStagePop()` will be associated with the stage
752: Not Collective
754: Input Parameter:
755: . stage - The stage on which to log
757: Example Usage:
758: If the option -log_view is used to run the program containing the
759: following code, then 2 sets of summary data will be printed during
760: PetscFinalize().
761: .vb
762: PetscInitialize(int *argc,char ***args,0,0);
763: [stage 0 of code]
764: PetscLogStagePush(1);
765: [stage 1 of code]
766: PetscLogStagePop();
767: PetscBarrier(...);
768: [more stage 0 of code]
769: PetscFinalize();
770: .ve
772: Level: intermediate
774: Note:
775: Use `PetscLogStageRegister()` to register a stage.
777: .seealso: [](ch_profiling), `PetscLogStagePop()`, `PetscLogStageRegister()`, `PetscBarrier()`
778: @*/
779: PetscErrorCode PetscLogStagePush(PetscLogStage stage)
780: {
781: PetscLogState state;
783: PetscFunctionBegin;
784: PetscCall(PetscLogGetState(&state));
785: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
786: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
787: PetscLogHandler h = PetscLogHandlers[i].handler;
788: if (h) PetscCall(PetscLogHandlerStagePush(h, stage));
789: }
790: PetscCall(PetscLogStateStagePush(state, stage));
791: PetscFunctionReturn(PETSC_SUCCESS);
792: }
794: /*@
795: PetscLogStagePop - This function pops a stage from the logging stack that was pushed with `PetscLogStagePush()`
797: Not Collective
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: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStageRegister()`, `PetscBarrier()`
817: @*/
818: PetscErrorCode PetscLogStagePop(void)
819: {
820: PetscLogState state;
821: PetscLogStage current_stage;
823: PetscFunctionBegin;
824: PetscCall(PetscLogGetState(&state));
825: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
826: current_stage = state->current_stage;
827: PetscCall(PetscLogStateStagePop(state));
828: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
829: PetscLogHandler h = PetscLogHandlers[i].handler;
830: if (h) PetscCall(PetscLogHandlerStagePop(h, current_stage));
831: }
832: PetscFunctionReturn(PETSC_SUCCESS);
833: }
835: /*@
836: PetscLogStageSetActive - Sets if a stage is used for `PetscLogEventBegin()` and `PetscLogEventEnd()`.
838: Not Collective
840: Input Parameters:
841: + stage - The stage
842: - isActive - The activity flag, `PETSC_TRUE` for logging, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
844: Level: intermediate
846: Note:
847: If this is set to `PETSC_FALSE` the logging acts as if the stage did not exist
849: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
850: @*/
851: PetscErrorCode PetscLogStageSetActive(PetscLogStage stage, PetscBool isActive)
852: {
853: PetscLogState state;
855: PetscFunctionBegin;
856: PetscCall(PetscLogGetState(&state));
857: if (state) PetscCall(PetscLogStateStageSetActive(state, stage, isActive));
858: PetscFunctionReturn(PETSC_SUCCESS);
859: }
861: /*@
862: PetscLogStageGetActive - Checks if a stage is used for `PetscLogEventBegin()` and `PetscLogEventEnd()`.
864: Not Collective
866: Input Parameter:
867: . stage - The stage
869: Output Parameter:
870: . isActive - The activity flag, `PETSC_TRUE` for logging, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
872: Level: intermediate
874: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
875: @*/
876: PetscErrorCode PetscLogStageGetActive(PetscLogStage stage, PetscBool *isActive)
877: {
878: PetscLogState state;
880: PetscFunctionBegin;
881: *isActive = PETSC_FALSE;
882: PetscCall(PetscLogGetState(&state));
883: if (state) PetscCall(PetscLogStateStageGetActive(state, stage, isActive));
884: PetscFunctionReturn(PETSC_SUCCESS);
885: }
887: /*@
888: PetscLogStageSetVisible - Determines stage visibility in `PetscLogView()`
890: Not Collective
892: Input Parameters:
893: + stage - The stage
894: - isVisible - The visibility flag, `PETSC_TRUE` to print, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
896: Level: intermediate
898: Developer Notes:
899: Visibility only affects the default log handler in `PetscLogView()`: stages that are
900: set to invisible are suppressed from output.
902: .seealso: [](ch_profiling), `PetscLogStageGetVisible()`, `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
903: @*/
904: PetscErrorCode PetscLogStageSetVisible(PetscLogStage stage, PetscBool isVisible)
906: {
907: PetscFunctionBegin;
908: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
909: PetscLogHandler h = PetscLogHandlers[i].handler;
911: if (h) PetscCall(PetscLogHandlerStageSetVisible(h, stage, isVisible));
912: }
913: PetscFunctionReturn(PETSC_SUCCESS);
914: }
916: /*@
917: PetscLogStageGetVisible - Returns stage visibility in `PetscLogView()`
919: Not Collective
921: Input Parameter:
922: . stage - The stage
924: Output Parameter:
925: . isVisible - The visibility flag, `PETSC_TRUE` to print, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
927: Level: intermediate
929: .seealso: [](ch_profiling), `PetscLogStageSetVisible()`, `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
930: @*/
931: PetscErrorCode PetscLogStageGetVisible(PetscLogStage stage, PetscBool *isVisible)
932: {
933: PetscLogHandler handler;
935: PetscFunctionBegin;
936: *isVisible = PETSC_FALSE;
937: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
938: if (handler) { PetscCall(PetscLogHandlerStageGetVisible(handler, stage, isVisible)); }
939: PetscFunctionReturn(PETSC_SUCCESS);
940: }
942: /*@
943: PetscLogStageGetId - Returns the stage id when given the stage name.
945: Not Collective
947: Input Parameter:
948: . name - The stage name
950: Output Parameter:
951: . stage - The stage, , or -1 if no stage with that name exists
953: Level: intermediate
955: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
956: @*/
957: PetscErrorCode PetscLogStageGetId(const char name[], PetscLogStage *stage)
958: {
959: PetscLogState state;
961: PetscFunctionBegin;
962: *stage = -1;
963: PetscCall(PetscLogGetState(&state));
964: if (state) PetscCall(PetscLogStateGetStageFromName(state, name, stage));
965: PetscFunctionReturn(PETSC_SUCCESS);
966: }
968: /*@
969: PetscLogStageGetName - Returns the stage name when given the stage id.
971: Not Collective
973: Input Parameter:
974: . stage - The stage
976: Output Parameter:
977: . name - The stage name
979: Level: intermediate
981: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
982: @*/
983: PetscErrorCode PetscLogStageGetName(PetscLogStage stage, const char *name[])
984: {
985: PetscLogStageInfo stage_info;
986: PetscLogState state;
988: PetscFunctionBegin;
989: *name = NULL;
990: PetscCall(PetscLogGetState(&state));
991: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
992: PetscCall(PetscLogStateStageGetInfo(state, stage, &stage_info));
993: *name = stage_info.name;
994: PetscFunctionReturn(PETSC_SUCCESS);
995: }
997: /*------------------------------------------------ Event Functions --------------------------------------------------*/
999: /*@
1000: PetscLogEventRegister - Registers an event name for logging operations
1002: Not Collective
1004: Input Parameters:
1005: + name - The name associated with the event
1006: - classid - The classid associated to the class for this event, obtain either with
1007: `PetscClassIdRegister()` or use a predefined one such as `KSP_CLASSID`, `SNES_CLASSID`, the predefined ones
1008: are only available in C code
1010: Output Parameter:
1011: . event - The event id for use with `PetscLogEventBegin()` and `PetscLogEventEnd()`.
1013: Example Usage:
1014: .vb
1015: PetscLogEvent USER_EVENT;
1016: PetscClassId classid;
1017: PetscLogDouble user_event_flops;
1018: PetscClassIdRegister("class name",&classid);
1019: PetscLogEventRegister("User event name",classid,&USER_EVENT);
1020: PetscLogEventBegin(USER_EVENT,0,0,0,0);
1021: [code segment to monitor]
1022: PetscLogFlops(user_event_flops);
1023: PetscLogEventEnd(USER_EVENT,0,0,0,0);
1024: .ve
1026: Level: intermediate
1028: Notes:
1029: PETSc automatically logs library events if the code has been
1030: configured with --with-log (which is the default) and
1031: -log_view or -log_all is specified. `PetscLogEventRegister()` is
1032: intended for logging user events to supplement this PETSc
1033: information.
1035: PETSc can gather data for use with the utilities Jumpshot
1036: (part of the MPICH distribution). If PETSc has been compiled
1037: with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
1038: MPICH), the user can employ another command line option, -log_mpe,
1039: to create a logfile, "mpe.log", which can be visualized
1040: Jumpshot.
1042: The classid is associated with each event so that classes of events
1043: can be disabled simultaneously, such as all matrix events. The user
1044: can either use an existing classid, such as `MAT_CLASSID`, or create
1045: their own as shown in the example.
1047: If an existing event with the same name exists, its event handle is
1048: returned instead of creating a new event.
1050: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogFlops()`,
1051: `PetscLogEventActivate()`, `PetscLogEventDeactivate()`, `PetscClassIdRegister()`
1052: @*/
1053: PetscErrorCode PetscLogEventRegister(const char name[], PetscClassId classid, PetscLogEvent *event)
1054: {
1055: PetscLogState state;
1057: PetscFunctionBegin;
1058: *event = -1;
1059: PetscCall(PetscLogGetState(&state));
1060: if (state) PetscCall(PetscLogStateEventRegister(state, name, classid, event));
1061: PetscFunctionReturn(PETSC_SUCCESS);
1062: }
1064: /*@
1065: PetscLogEventSetCollective - Indicates that a particular event is collective.
1067: Logically Collective
1069: Input Parameters:
1070: + event - The event id
1071: - collective - `PetscBool` indicating whether a particular event is collective
1073: Level: developer
1075: Notes:
1076: New events returned from `PetscLogEventRegister()` are collective by default.
1078: Collective events are handled specially if the command line option `-log_sync` is used. In that case the logging saves information about
1079: two parts of the event; the time for all the MPI ranks to synchronize and then the time for the actual computation/communication
1080: to be performed. This option is useful to debug imbalance within the computations or communications.
1082: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventRegister()`
1083: @*/
1084: PetscErrorCode PetscLogEventSetCollective(PetscLogEvent event, PetscBool collective)
1085: {
1086: PetscLogState state;
1088: PetscFunctionBegin;
1089: PetscCall(PetscLogGetState(&state));
1090: if (state) PetscCall(PetscLogStateEventSetCollective(state, event, collective));
1091: PetscFunctionReturn(PETSC_SUCCESS);
1092: }
1094: /*
1095: PetscLogClassSetActiveAll - Activate or inactivate logging for all events associated with a PETSc object class in every stage.
1097: Not Collective
1099: Input Parameters:
1100: + classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1101: - isActive - if `PETSC_FALSE`, events associated with this class will not be send to log handlers.
1103: Level: developer
1105: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventActivateAll()`, `PetscLogStageSetActive()`, `PetscLogEventActivateClass()`
1106: */
1107: static PetscErrorCode PetscLogClassSetActiveAll(PetscClassId classid, PetscBool isActive)
1108: {
1109: PetscLogState state;
1111: PetscFunctionBegin;
1112: PetscCall(PetscLogGetState(&state));
1113: if (state) PetscCall(PetscLogStateClassSetActiveAll(state, classid, isActive));
1114: PetscFunctionReturn(PETSC_SUCCESS);
1115: }
1117: /*@
1118: PetscLogEventIncludeClass - Activates event logging for a PETSc object class in every stage.
1120: Not Collective
1122: Input Parameter:
1123: . classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1125: Level: developer
1127: .seealso: [](ch_profiling), `PetscLogEventActivateClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1128: @*/
1129: PetscErrorCode PetscLogEventIncludeClass(PetscClassId classid)
1130: {
1131: PetscFunctionBegin;
1132: PetscCall(PetscLogClassSetActiveAll(classid, PETSC_TRUE));
1133: PetscFunctionReturn(PETSC_SUCCESS);
1134: }
1136: /*@
1137: PetscLogEventExcludeClass - Deactivates event logging for a PETSc object class in every stage.
1139: Not Collective
1141: Input Parameter:
1142: . classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1144: Level: developer
1146: Note:
1147: If a class is excluded then events associated with that class are not logged.
1149: .seealso: [](ch_profiling), `PetscLogEventDeactivateClass()`, `PetscLogEventActivateClass()`, `PetscLogEventDeactivate()`, `PetscLogEventActivate()`
1150: @*/
1151: PetscErrorCode PetscLogEventExcludeClass(PetscClassId classid)
1152: {
1153: PetscFunctionBegin;
1154: PetscCall(PetscLogClassSetActiveAll(classid, PETSC_FALSE));
1155: PetscFunctionReturn(PETSC_SUCCESS);
1156: }
1158: /*
1159: PetscLogEventSetActive - Activate or inactivate logging for an event in a given stage
1161: Not Collective
1163: Input Parameters:
1164: + stage - A registered `PetscLogStage` (or `PETSC_DEFAULT` for the current stage)
1165: . event - A `PetscLogEvent`
1166: - isActive - If `PETSC_FALSE`, activity from this event (`PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventSync()`) will not be sent to log handlers during this stage
1168: Usage:
1169: .vb
1170: PetscLogEventSetActive(VEC_SetValues, PETSC_FALSE);
1171: [code where you do not want to log VecSetValues()]
1172: PetscLogEventSetActive(VEC_SetValues, PETSC_TRUE);
1173: [code where you do want to log VecSetValues()]
1174: .ve
1176: Level: advanced
1178: Note:
1179: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
1180: or an event number obtained with `PetscLogEventRegister()`.
1182: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1183: */
1184: static PetscErrorCode PetscLogEventSetActive(PetscLogStage stage, PetscLogEvent event, PetscBool isActive)
1185: {
1186: PetscLogState state;
1188: PetscFunctionBegin;
1189: PetscCall(PetscLogGetState(&state));
1190: if (state) PetscCall(PetscLogStateEventSetActive(state, stage, event, isActive));
1191: PetscFunctionReturn(PETSC_SUCCESS);
1192: }
1194: /*@
1195: PetscLogEventActivate - Indicates that a particular event should be logged.
1197: Not Collective
1199: Input Parameter:
1200: . event - The event id
1202: Example Usage:
1203: .vb
1204: PetscLogEventDeactivate(VEC_SetValues);
1205: [code where you do not want to log VecSetValues()]
1206: PetscLogEventActivate(VEC_SetValues);
1207: [code where you do want to log VecSetValues()]
1208: .ve
1210: Level: advanced
1212: Note:
1213: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
1214: or an event number obtained with `PetscLogEventRegister()`.
1216: .seealso: [](ch_profiling), `PetscLogEventDeactivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1217: @*/
1218: PetscErrorCode PetscLogEventActivate(PetscLogEvent event)
1219: {
1220: PetscFunctionBegin;
1221: PetscCall(PetscLogEventSetActive(PETSC_DEFAULT, event, PETSC_TRUE));
1222: PetscFunctionReturn(PETSC_SUCCESS);
1223: }
1225: /*@
1226: PetscLogEventDeactivate - Indicates that a particular event should not be logged.
1228: Not Collective
1230: Input Parameter:
1231: . event - The event id
1233: Example Usage:
1234: .vb
1235: PetscLogEventDeactivate(VEC_SetValues);
1236: [code where you do not want to log VecSetValues()]
1237: PetscLogEventActivate(VEC_SetValues);
1238: [code where you do want to log VecSetValues()]
1239: .ve
1241: Level: advanced
1243: Note:
1244: The event may be either a pre-defined PETSc event (found in
1245: include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1247: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1248: @*/
1249: PetscErrorCode PetscLogEventDeactivate(PetscLogEvent event)
1250: {
1251: PetscFunctionBegin;
1252: PetscCall(PetscLogEventSetActive(PETSC_DEFAULT, event, PETSC_FALSE));
1253: PetscFunctionReturn(PETSC_SUCCESS);
1254: }
1256: /*@
1257: PetscLogEventDeactivatePush - Indicates that a particular event should not be logged until `PetscLogEventDeactivatePop()` is called
1259: Not Collective
1261: Input Parameter:
1262: . event - The event id
1264: Example Usage:
1265: .vb
1266: PetscLogEventDeactivatePush(VEC_SetValues);
1267: [code where you do not want to log VecSetValues()]
1268: PetscLogEventDeactivatePop(VEC_SetValues);
1269: [code where you do want to log VecSetValues()]
1270: .ve
1272: Level: advanced
1274: Note:
1275: The event may be either a pre-defined PETSc event (found in
1276: include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1278: 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.
1280: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivate()`, `PetscLogEventDeactivatePop()`
1281: @*/
1282: PetscErrorCode PetscLogEventDeactivatePush(PetscLogEvent event)
1283: {
1284: PetscFunctionBegin;
1285: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1286: PetscLogHandler h = PetscLogHandlers[i].handler;
1288: if (h) PetscCall(PetscLogHandlerEventDeactivatePush(h, PETSC_DEFAULT, event));
1289: }
1290: PetscFunctionReturn(PETSC_SUCCESS);
1291: }
1293: /*@
1294: PetscLogEventDeactivatePop - Indicates that a particular event should again be logged after the logging was turned off with `PetscLogEventDeactivatePush()`
1296: Not Collective
1298: Input Parameter:
1299: . event - The event id
1301: Example Usage:
1302: .vb
1303: PetscLogEventDeactivatePush(VEC_SetValues);
1304: [code where you do not want to log VecSetValues()]
1305: PetscLogEventDeactivatePop(VEC_SetValues);
1306: [code where you do want to log VecSetValues()]
1307: .ve
1309: Level: advanced
1311: Note:
1312: The event may be either a pre-defined PETSc event (found in
1313: include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1315: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`
1316: @*/
1317: PetscErrorCode PetscLogEventDeactivatePop(PetscLogEvent event)
1318: {
1319: PetscFunctionBegin;
1320: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1321: PetscLogHandler h = PetscLogHandlers[i].handler;
1323: if (h) PetscCall(PetscLogHandlerEventDeactivatePop(h, PETSC_DEFAULT, event));
1324: }
1325: PetscFunctionReturn(PETSC_SUCCESS);
1326: }
1328: /*@
1329: PetscLogEventSetActiveAll - Turns on logging of all events
1331: Not Collective
1333: Input Parameters:
1334: + event - The event id
1335: - isActive - The activity flag determining whether the event is logged
1337: Level: advanced
1339: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1340: @*/
1341: PetscErrorCode PetscLogEventSetActiveAll(PetscLogEvent event, PetscBool isActive)
1342: {
1343: PetscLogState state;
1345: PetscFunctionBegin;
1346: PetscCall(PetscLogGetState(&state));
1347: if (state) PetscCall(PetscLogStateEventSetActiveAll(state, event, isActive));
1348: PetscFunctionReturn(PETSC_SUCCESS);
1349: }
1351: /*
1352: PetscLogClassSetActive - Activates event logging for a PETSc object class for the current stage
1354: Not Collective
1356: Input Parameters:
1357: + stage - A registered `PetscLogStage` (or `PETSC_DEFAULT` for the current stage)
1358: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1359: - isActive - If `PETSC_FALSE`, events associated with this class are not sent to log handlers.
1361: Level: developer
1363: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventActivate()`, `PetscLogEventActivateAll()`, `PetscLogStageSetActive()`
1364: */
1365: static PetscErrorCode PetscLogClassSetActive(PetscLogStage stage, PetscClassId classid, PetscBool isActive)
1366: {
1367: PetscLogState state;
1369: PetscFunctionBegin;
1370: PetscCall(PetscLogGetState(&state));
1371: if (state) PetscCall(PetscLogStateClassSetActive(state, stage, classid, isActive));
1372: PetscFunctionReturn(PETSC_SUCCESS);
1373: }
1375: /*@
1376: PetscLogEventActivateClass - Activates event logging for a PETSc object class for the current stage
1378: Not Collective
1380: Input Parameter:
1381: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1383: Level: developer
1385: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1386: @*/
1387: PetscErrorCode PetscLogEventActivateClass(PetscClassId classid)
1388: {
1389: PetscFunctionBegin;
1390: PetscCall(PetscLogClassSetActive(PETSC_DEFAULT, classid, PETSC_TRUE));
1391: PetscFunctionReturn(PETSC_SUCCESS);
1392: }
1394: /*@
1395: PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class for the current stage
1397: Not Collective
1399: Input Parameter:
1400: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1402: Level: developer
1404: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventActivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1405: @*/
1406: PetscErrorCode PetscLogEventDeactivateClass(PetscClassId classid)
1407: {
1408: PetscFunctionBegin;
1409: PetscCall(PetscLogClassSetActive(PETSC_DEFAULT, classid, PETSC_FALSE));
1410: PetscFunctionReturn(PETSC_SUCCESS);
1411: }
1413: /*MC
1414: PetscLogEventSync - Synchronizes the beginning of a user event.
1416: Synopsis:
1417: #include <petsclog.h>
1418: PetscErrorCode PetscLogEventSync(PetscLogEvent e, MPI_Comm comm)
1420: Collective
1422: Input Parameters:
1423: + e - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1424: - comm - an MPI communicator
1426: Example Usage:
1427: .vb
1428: PetscLogEvent USER_EVENT;
1430: PetscLogEventRegister("User event", 0, &USER_EVENT);
1431: PetscLogEventSync(USER_EVENT, PETSC_COMM_WORLD);
1432: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1433: [code segment to monitor]
1434: PetscLogEventEnd(USER_EVENT, 0, 0, 0 , 0);
1435: .ve
1437: Level: developer
1439: Note:
1440: This routine should be called only if there is not a `PetscObject` available to pass to
1441: `PetscLogEventBegin()`.
1443: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`
1444: M*/
1446: /*MC
1447: PetscLogEventBegin - Logs the beginning of a user event.
1449: Synopsis:
1450: #include <petsclog.h>
1451: PetscErrorCode PetscLogEventBegin(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
1453: Not Collective
1455: Input Parameters:
1456: + e - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1457: . o1 - object associated with the event, or `NULL`
1458: . o2 - object associated with the event, or `NULL`
1459: . o3 - object associated with the event, or `NULL`
1460: - o4 - object associated with the event, or `NULL`
1462: Fortran Synopsis:
1463: void PetscLogEventBegin(int e, PetscErrorCode ierr)
1465: Example Usage:
1466: .vb
1467: PetscLogEvent USER_EVENT;
1469: PetscLogDouble user_event_flops;
1470: PetscLogEventRegister("User event",0, &USER_EVENT);
1471: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1472: [code segment to monitor]
1473: PetscLogFlops(user_event_flops);
1474: PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
1475: .ve
1477: Level: intermediate
1479: Developer Note:
1480: `PetscLogEventBegin()` and `PetscLogEventBegin()` return error codes instead of explicitly
1481: handling the errors that occur in the macro directly because other packages that use this
1482: macros have used them in their own functions or methods that do not return error codes and it
1483: would be disruptive to change the current behavior.
1485: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventEnd()`, `PetscLogFlops()`
1486: M*/
1488: /*MC
1489: PetscLogEventEnd - Log the end of a user event.
1491: Synopsis:
1492: #include <petsclog.h>
1493: PetscErrorCode PetscLogEventEnd(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
1495: Not Collective
1497: Input Parameters:
1498: + e - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1499: . o1 - object associated with the event, or `NULL`
1500: . o2 - object associated with the event, or `NULL`
1501: . o3 - object associated with the event, or `NULL`
1502: - o4 - object associated with the event, or `NULL`
1504: Fortran Synopsis:
1505: void PetscLogEventEnd(int e, PetscErrorCode ierr)
1507: Example Usage:
1508: .vb
1509: PetscLogEvent USER_EVENT;
1511: PetscLogDouble user_event_flops;
1512: PetscLogEventRegister("User event", 0, &USER_EVENT);
1513: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1514: [code segment to monitor]
1515: PetscLogFlops(user_event_flops);
1516: PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
1517: .ve
1519: Level: intermediate
1521: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogFlops()`
1522: M*/
1524: /*@C
1525: PetscLogStageGetPerfInfo - Return the performance information about the given stage
1527: No Fortran Support
1529: Input Parameters:
1530: . stage - The stage number or `PETSC_DETERMINE` for the current stage
1532: Output Parameter:
1533: . info - This structure is filled with the performance information
1535: Level: intermediate
1537: Notes:
1538: This is a low level routine used by the logging functions in PETSc.
1540: A `PETSCLOGHANDLERDEFAULT` must be running for this to work, having been started either with
1541: `PetscLogDefaultBegin()` or from the command line with `-log_view`. If it was not started,
1542: all performance statistics in `info` will be zeroed.
1544: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1545: @*/
1546: PetscErrorCode PetscLogStageGetPerfInfo(PetscLogStage stage, PetscEventPerfInfo *info)
1547: {
1548: PetscLogHandler handler;
1549: PetscEventPerfInfo *event_info;
1551: PetscFunctionBegin;
1552: PetscAssertPointer(info, 2);
1553: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1554: if (handler) {
1555: PetscCall(PetscLogHandlerGetStagePerfInfo(handler, stage, &event_info));
1556: *info = *event_info;
1557: } else {
1558: PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogStageGetPerfInfo() returning zeros\n"));
1559: PetscCall(PetscMemzero(info, sizeof(*info)));
1560: }
1561: PetscFunctionReturn(PETSC_SUCCESS);
1562: }
1564: /*@C
1565: PetscLogEventGetPerfInfo - Return the performance information about the given event in the given stage
1567: No Fortran Support
1569: Input Parameters:
1570: + stage - The stage number or `PETSC_DETERMINE` for the current stage
1571: - event - The event number
1573: Output Parameter:
1574: . info - This structure is filled with the performance information
1576: Level: intermediate
1578: Note:
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 PetscLogEventGetPerfInfo(PetscLogStage stage, PetscLogEvent event, PetscEventPerfInfo *info)
1588: {
1589: PetscLogHandler handler;
1590: PetscEventPerfInfo *event_info;
1592: PetscFunctionBegin;
1593: PetscAssertPointer(info, 3);
1594: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1595: if (handler) {
1596: PetscCall(PetscLogHandlerGetEventPerfInfo(handler, stage, event, &event_info));
1597: *info = *event_info;
1598: } else {
1599: PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogEventGetPerfInfo() returning zeros\n"));
1600: PetscCall(PetscMemzero(info, sizeof(*info)));
1601: }
1602: PetscFunctionReturn(PETSC_SUCCESS);
1603: }
1605: /*@
1606: PetscLogEventSetDof - Set the nth number of degrees of freedom of a numerical problem associated with this event
1608: Not Collective
1610: Input Parameters:
1611: + event - The event id to log
1612: . n - The dof index, in [0, 8)
1613: - dof - The number of dofs
1615: Options Database Key:
1616: . -log_view - Activates log summary
1618: Level: developer
1620: Note:
1621: This is to enable logging of convergence
1623: .seealso: `PetscLogEventSetError()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1624: @*/
1625: PetscErrorCode PetscLogEventSetDof(PetscLogEvent event, PetscInt n, PetscLogDouble dof)
1626: {
1627: PetscFunctionBegin;
1628: PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1629: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1630: PetscLogHandler h = PetscLogHandlers[i].handler;
1632: if (h) {
1633: PetscEventPerfInfo *event_info;
1635: PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1636: if (event_info) event_info->dof[n] = dof;
1637: }
1638: }
1639: PetscFunctionReturn(PETSC_SUCCESS);
1640: }
1642: /*@
1643: PetscLogEventSetError - Set the nth error associated with a numerical problem associated with this event
1645: Not Collective
1647: Input Parameters:
1648: + event - The event id to log
1649: . n - The error index, in [0, 8)
1650: - error - The error
1652: Options Database Key:
1653: . -log_view - Activates log summary
1655: Level: developer
1657: Notes:
1658: This is to enable logging of convergence, and enable users to interpret the errors as they wish. For example,
1659: as different norms, or as errors for different fields
1661: This is a low level routine used by the logging functions in PETSc
1663: .seealso: `PetscLogEventSetDof()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1664: @*/
1665: PetscErrorCode PetscLogEventSetError(PetscLogEvent event, PetscInt n, PetscLogDouble error)
1666: {
1667: PetscFunctionBegin;
1668: PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1669: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1670: PetscLogHandler h = PetscLogHandlers[i].handler;
1672: if (h) {
1673: PetscEventPerfInfo *event_info;
1675: PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1676: if (event_info) event_info->errors[n] = error;
1677: }
1678: }
1679: PetscFunctionReturn(PETSC_SUCCESS);
1680: }
1682: /*@
1683: PetscLogEventGetId - Returns the event id when given the event name.
1685: Not Collective
1687: Input Parameter:
1688: . name - The event name
1690: Output Parameter:
1691: . event - The event, or -1 if no event with that name exists
1693: Level: intermediate
1695: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1696: @*/
1697: PetscErrorCode PetscLogEventGetId(const char name[], PetscLogEvent *event)
1698: {
1699: PetscLogState state;
1701: PetscFunctionBegin;
1702: *event = -1;
1703: PetscCall(PetscLogGetState(&state));
1704: if (state) PetscCall(PetscLogStateGetEventFromName(state, name, event));
1705: PetscFunctionReturn(PETSC_SUCCESS);
1706: }
1708: /*@
1709: PetscLogEventGetName - Returns the event name when given the event id.
1711: Not Collective
1713: Input Parameter:
1714: . event - The event
1716: Output Parameter:
1717: . name - The event name
1719: Level: intermediate
1721: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
1722: @*/
1723: PetscErrorCode PetscLogEventGetName(PetscLogEvent event, const char *name[])
1724: {
1725: PetscLogEventInfo event_info;
1726: PetscLogState state;
1728: PetscFunctionBegin;
1729: *name = NULL;
1730: PetscCall(PetscLogGetState(&state));
1731: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1732: PetscCall(PetscLogStateEventGetInfo(state, event, &event_info));
1733: *name = event_info.name;
1734: PetscFunctionReturn(PETSC_SUCCESS);
1735: }
1737: /*@
1738: 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.
1740: Not collective
1742: Level: advanced
1744: Notes:
1745: 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()`).
1747: Other log handlers (such as the nested handler, `PetscLogNestedBegin()`) will ignore this function.
1749: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsResume()`, `PetscLogGetDefaultHandler()`
1750: @*/
1751: PetscErrorCode PetscLogEventsPause(void)
1752: {
1753: PetscFunctionBegin;
1754: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1755: PetscLogHandler h = PetscLogHandlers[i].handler;
1757: if (h) PetscCall(PetscLogHandlerEventsPause(h));
1758: }
1759: PetscFunctionReturn(PETSC_SUCCESS);
1760: }
1762: /*@
1763: PetscLogEventsResume - Return logging to normal behavior after it was paused with `PetscLogEventsPause()`.
1765: Not collective
1767: Level: advanced
1769: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsPause()`, `PetscLogGetDefaultHandler()`
1770: @*/
1771: PetscErrorCode PetscLogEventsResume(void)
1772: {
1773: PetscFunctionBegin;
1774: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1775: PetscLogHandler h = PetscLogHandlers[i].handler;
1777: if (h) PetscCall(PetscLogHandlerEventsResume(h));
1778: }
1779: PetscFunctionReturn(PETSC_SUCCESS);
1780: }
1782: /*------------------------------------------------ Class Functions --------------------------------------------------*/
1784: /*MC
1785: PetscLogObjectCreate - Log the creation of a `PetscObject`
1787: Synopsis:
1788: #include <petsclog.h>
1789: PetscErrorCode PetscLogObjectCreate(PetscObject h)
1791: Not Collective
1793: Input Parameters:
1794: . h - A `PetscObject`
1796: Level: developer
1798: Developer Note:
1799: Called internally by PETSc when creating objects: users do not need to call this directly.
1800: Notification of the object creation is sent to each `PetscLogHandler` that is running.
1802: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectDestroy()`
1803: M*/
1805: /*MC
1806: PetscLogObjectDestroy - Logs the destruction of a `PetscObject`
1808: Synopsis:
1809: #include <petsclog.h>
1810: PetscErrorCode PetscLogObjectDestroy(PetscObject h)
1812: Not Collective
1814: Input Parameters:
1815: . h - A `PetscObject`
1817: Level: developer
1819: Developer Note:
1820: Called internally by PETSc when destroying objects: users do not need to call this directly.
1821: Notification of the object creation is sent to each `PetscLogHandler` that is running.
1823: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectCreate()`
1824: M*/
1826: /*@
1827: PetscLogClassGetClassId - Returns the `PetscClassId` when given the class name.
1829: Not Collective
1831: Input Parameter:
1832: . name - The class name
1834: Output Parameter:
1835: . classid - The `PetscClassId` id, or -1 if no class with that name exists
1837: Level: intermediate
1839: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1840: @*/
1841: PetscErrorCode PetscLogClassGetClassId(const char name[], PetscClassId *classid)
1842: {
1843: PetscLogClass log_class;
1844: PetscLogClassInfo class_info;
1845: PetscLogState state;
1847: PetscFunctionBegin;
1848: *classid = -1;
1849: PetscCall(PetscLogGetState(&state));
1850: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1851: PetscCall(PetscLogStateGetClassFromName(state, name, &log_class));
1852: if (log_class < 0) {
1853: *classid = -1;
1854: PetscFunctionReturn(PETSC_SUCCESS);
1855: }
1856: PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1857: *classid = class_info.classid;
1858: PetscFunctionReturn(PETSC_SUCCESS);
1859: }
1861: /*@C
1862: PetscLogClassIdGetName - Returns a `PetscClassId`'s name.
1864: Not Collective
1866: Input Parameter:
1867: . classid - A `PetscClassId`
1869: Output Parameter:
1870: . name - The class name
1872: Level: intermediate
1874: .seealso: [](ch_profiling), `PetscLogClassRegister()`, `PetscLogClassBegin()`, `PetscLogClassEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadClass()`
1875: @*/
1876: PetscErrorCode PetscLogClassIdGetName(PetscClassId classid, const char **name)
1877: {
1878: PetscLogClass log_class;
1879: PetscLogClassInfo class_info;
1880: PetscLogState state;
1882: PetscFunctionBegin;
1883: PetscCall(PetscLogGetState(&state));
1884: PetscCall(PetscLogStateGetClassFromClassId(state, classid, &log_class));
1885: PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1886: *name = class_info.name;
1887: PetscFunctionReturn(PETSC_SUCCESS);
1888: }
1890: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1891: /*@
1892: PetscLogDump - Dumps logs of objects to a file. This file is intended to
1893: be read by bin/petscview. This program no longer exists.
1895: Collective on `PETSC_COMM_WORLD`
1897: Input Parameter:
1898: . sname - an optional file name
1900: Example Usage:
1901: .vb
1902: PetscInitialize(...);
1903: PetscLogDefaultBegin();
1904: // ... code ...
1905: PetscLogDump(filename);
1906: PetscFinalize();
1907: .ve
1909: Level: advanced
1911: Note:
1912: The default file name is Log.<rank> where <rank> is the MPI process rank. If no name is specified,
1913: this file will be used.
1915: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
1916: @*/
1917: PetscErrorCode PetscLogDump(const char sname[])
1918: {
1919: PetscLogHandler handler;
1921: PetscFunctionBegin;
1922: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1923: PetscCall(PetscLogHandlerDump(handler, sname));
1924: PetscFunctionReturn(PETSC_SUCCESS);
1925: }
1927: /*@
1928: PetscLogMPEDump - Dumps the MPE logging info to file for later use with Jumpshot.
1930: Collective on `PETSC_COMM_WORLD`
1932: Input Parameter:
1933: . sname - filename for the MPE logfile
1935: Level: advanced
1937: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogMPEBegin()`
1938: @*/
1939: PetscErrorCode PetscLogMPEDump(const char sname[])
1940: {
1941: PetscFunctionBegin;
1942: #if defined(PETSC_HAVE_MPE)
1943: if (PetscBeganMPE) {
1944: char name[PETSC_MAX_PATH_LEN];
1946: PetscCall(PetscInfo(0, "Finalizing MPE.\n"));
1947: if (sname) {
1948: PetscCall(PetscStrncpy(name, sname, sizeof(name)));
1949: } else {
1950: PetscCall(PetscGetProgramName(name, sizeof(name)));
1951: }
1952: PetscCall(MPE_Finish_log(name));
1953: } else {
1954: PetscCall(PetscInfo(0, "Not finalizing MPE (not started by PETSc).\n"));
1955: }
1956: #else
1957: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe");
1958: #endif
1959: PetscFunctionReturn(PETSC_SUCCESS);
1960: }
1962: /*@
1963: PetscLogView - Prints a summary of the logging.
1965: Collective
1967: Input Parameter:
1968: . viewer - an ASCII viewer
1970: Options Database Keys:
1971: + -log_view [:filename] - Prints summary of log information
1972: . -log_view :filename.py:ascii_info_detail - Saves logging information from each process as a Python file
1973: . -log_view :filename.xml:ascii_xml - Saves a summary of the logging information in a nested format (see below for how to view it)
1974: . -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)
1975: . -log_view_memory - Also display memory usage in each event
1976: . -log_view_gpu_time - Also display time in each event for GPU kernels (Note this may slow the computation)
1977: . -log_all - Saves a file Log.rank for each MPI rank with details of each step of the computation
1978: - -log_trace [filename] - Displays a trace of what each process is doing
1980: Level: beginner
1982: Notes:
1983: It is possible to control the logging programmatically but we recommend using the options database approach whenever possible
1984: By default the summary is printed to stdout.
1986: Before calling this routine you must have called either PetscLogDefaultBegin() or PetscLogNestedBegin()
1988: If PETSc is configured with --with-logging=0 then this functionality is not available
1990: To view the nested XML format filename.xml first copy ${PETSC_DIR}/share/petsc/xml/performance_xml2html.xsl to the current
1991: directory then open filename.xml with your browser. Specific notes for certain browsers
1992: .vb
1993: Firefox and Internet explorer - simply open the file
1994: Google Chrome - you must start up Chrome with the option --allow-file-access-from-files
1995: Safari - see https://ccm.net/faq/36342-safari-how-to-enable-local-file-access
1996: .ve
1997: or one can use the package <http://xmlsoft.org/XSLT/xsltproc2.html> to translate the xml file to html and then open it with
1998: your browser.
1999: Alternatively, use the script ${PETSC_DIR}/lib/petsc/bin/petsc-performance-view to automatically open a new browser
2000: window and render the XML log file contents.
2002: The nested XML format was kindly donated by Koos Huijssen and Christiaan M. Klaij MARITIME RESEARCH INSTITUTE NETHERLANDS
2004: The Flame Graph output can be visualised using either the original Flame Graph script <https://github.com/brendangregg/FlameGraph>
2005: or using speedscope <https://www.speedscope.app>.
2006: Old XML profiles may be converted into this format using the script ${PETSC_DIR}/lib/petsc/bin/xml2flamegraph.py.
2008: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogDump()`
2009: @*/
2010: PetscErrorCode PetscLogView(PetscViewer viewer)
2011: {
2012: PetscBool isascii;
2013: PetscViewerFormat format;
2014: int stage;
2015: PetscLogState state;
2016: PetscIntStack temp_stack;
2017: PetscLogHandler handler;
2018: PetscBool is_empty;
2020: PetscFunctionBegin;
2021: PetscCall(PetscLogGetState(&state));
2022: /* Pop off any stages the user forgot to remove */
2023: PetscCall(PetscIntStackCreate(&temp_stack));
2024: PetscCall(PetscLogStateGetCurrentStage(state, &stage));
2025: while (stage >= 0) {
2026: PetscCall(PetscLogStagePop());
2027: PetscCall(PetscIntStackPush(temp_stack, stage));
2028: PetscCall(PetscLogStateGetCurrentStage(state, &stage));
2029: }
2030: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
2031: PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Currently can only view logging to ASCII");
2032: PetscCall(PetscViewerGetFormat(viewer, &format));
2033: if (format == PETSC_VIEWER_ASCII_XML || format == PETSC_VIEWER_ASCII_FLAMEGRAPH) {
2034: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERNESTED, &handler));
2035: PetscCall(PetscLogHandlerView(handler, viewer));
2036: } else {
2037: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
2038: PetscCall(PetscLogHandlerView(handler, viewer));
2039: }
2040: PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
2041: while (!is_empty) {
2042: PetscCall(PetscIntStackPop(temp_stack, &stage));
2043: PetscCall(PetscLogStagePush(stage));
2044: PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
2045: }
2046: PetscCall(PetscIntStackDestroy(temp_stack));
2047: PetscFunctionReturn(PETSC_SUCCESS);
2048: }
2050: /*@C
2051: PetscLogViewFromOptions - Processes command line options to determine if/how a `PetscLog` is to be viewed.
2053: Collective on `PETSC_COMM_WORLD`
2055: Level: developer
2057: .seealso: [](ch_profiling), `PetscLogView()`
2058: @*/
2059: PetscErrorCode PetscLogViewFromOptions(void)
2060: {
2061: PetscInt n_max = PETSC_LOG_VIEW_FROM_OPTIONS_MAX;
2062: PetscViewer viewers[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2063: PetscViewerFormat formats[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2064: PetscBool flg;
2066: PetscFunctionBegin;
2067: PetscCall(PetscOptionsCreateViewers(PETSC_COMM_WORLD, NULL, NULL, "-log_view", &n_max, viewers, formats, &flg));
2068: for (PetscInt i = 0; i < n_max; i++) {
2069: PetscCall(PetscViewerPushFormat(viewers[i], formats[i]));
2070: PetscCall(PetscLogView(viewers[i]));
2071: PetscCall(PetscViewerPopFormat(viewers[i]));
2072: PetscCall(PetscViewerDestroy(&viewers[i]));
2073: }
2074: PetscFunctionReturn(PETSC_SUCCESS);
2075: }
2077: PETSC_INTERN PetscErrorCode PetscLogHandlerNestedSetThreshold(PetscLogHandler, PetscLogDouble, PetscLogDouble *);
2079: /*@
2080: PetscLogSetThreshold - Set the threshold time for logging the events; this is a percentage out of 100, so 1. means any event
2081: that takes 1 or more percent of the time.
2083: Logically Collective on `PETSC_COMM_WORLD`
2085: Input Parameter:
2086: . newThresh - the threshold to use
2088: Output Parameter:
2089: . oldThresh - the previously set threshold value
2091: Options Database Keys:
2092: . -log_view :filename.xml:ascii_xml - Prints an XML summary of flop and timing information to the file
2094: Example Usage:
2095: .vb
2096: PetscInitialize(...);
2097: PetscLogNestedBegin();
2098: PetscLogSetThreshold(0.1,&oldthresh);
2099: // ... code ...
2100: PetscLogView(viewer);
2101: PetscFinalize();
2102: .ve
2104: Level: advanced
2106: Note:
2107: This threshold is only used by the nested log handler
2109: .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`,
2110: `PetscLogNestedBegin()`
2111: @*/
2112: PetscErrorCode PetscLogSetThreshold(PetscLogDouble newThresh, PetscLogDouble *oldThresh)
2113: {
2114: PetscLogHandler handler;
2116: PetscFunctionBegin;
2117: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERNESTED, &handler));
2118: PetscCall(PetscLogHandlerNestedSetThreshold(handler, newThresh, oldThresh));
2119: PetscFunctionReturn(PETSC_SUCCESS);
2120: }
2122: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
2123: /*@
2124: PetscGetFlops - Returns the number of flops used on this processor
2125: since the program began.
2127: Not Collective
2129: Output Parameter:
2130: . flops - number of floating point operations
2132: Level: intermediate
2134: Notes:
2135: A global counter logs all PETSc flop counts. The user can use
2136: `PetscLogFlops()` to increment this counter to include flops for the
2137: application code.
2139: A separate counter `PetscLogGpuFlops()` logs the flops that occur on any GPU associated with this MPI rank
2141: .seealso: [](ch_profiling), `PetscLogGpuFlops()`, `PetscTime()`, `PetscLogFlops()`
2142: @*/
2143: PetscErrorCode PetscGetFlops(PetscLogDouble *flops)
2144: {
2145: PetscFunctionBegin;
2146: *flops = petsc_TotalFlops;
2147: PetscFunctionReturn(PETSC_SUCCESS);
2148: }
2150: /*@C
2151: PetscLogObjectState - Record information about an object with the default log handler
2153: Not Collective
2155: Input Parameters:
2156: + obj - the `PetscObject`
2157: . format - a printf-style format string
2158: - ... - printf arguments to format
2160: Level: developer
2162: .seealso: [](ch_profiling), `PetscLogObjectCreate()`, `PetscLogObjectDestroy()`, `PetscLogGetDefaultHandler()`
2163: @*/
2164: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
2165: {
2166: PetscFunctionBegin;
2167: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2168: PetscLogHandler h = PetscLogHandlers[i].handler;
2170: if (h) {
2171: va_list Argp;
2172: va_start(Argp, format);
2173: PetscCall(PetscLogHandlerLogObjectState_Internal(h, obj, format, Argp));
2174: va_end(Argp);
2175: }
2176: }
2177: PetscFunctionReturn(PETSC_SUCCESS);
2178: }
2180: /*MC
2181: PetscLogFlops - Adds floating point operations to the global counter.
2183: Synopsis:
2184: #include <petsclog.h>
2185: PetscErrorCode PetscLogFlops(PetscLogDouble f)
2187: Not Collective
2189: Input Parameter:
2190: . f - flop counter
2192: Example Usage:
2193: .vb
2194: PetscLogEvent USER_EVENT;
2196: PetscLogEventRegister("User event", 0, &USER_EVENT);
2197: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
2198: [code segment to monitor]
2199: PetscLogFlops(user_flops)
2200: PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
2201: .ve
2203: Level: intermediate
2205: Note:
2206: A global counter logs all PETSc flop counts. The user can use PetscLogFlops() to increment
2207: this counter to include flops for the application code.
2209: .seealso: [](ch_profiling), `PetscLogGpuFlops()`, `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscGetFlops()`
2210: M*/
2212: /*MC
2213: PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice) to get accurate
2214: timings
2216: Synopsis:
2217: #include <petsclog.h>
2218: void PetscPreLoadBegin(PetscBool flag, char *name);
2220: Not Collective
2222: Input Parameters:
2223: + flag - `PETSC_TRUE` to run twice, `PETSC_FALSE` to run once, may be overridden with command
2224: line option `-preload true|false`
2225: - name - name of first stage (lines of code timed separately with `-log_view`) to be preloaded
2227: Example Usage:
2228: .vb
2229: PetscPreLoadBegin(PETSC_TRUE, "first stage");
2230: // lines of code
2231: PetscPreLoadStage("second stage");
2232: // lines of code
2233: PetscPreLoadEnd();
2234: .ve
2236: Level: intermediate
2238: Note:
2239: Only works in C/C++, not Fortran
2241: Flags available within the macro\:
2242: + PetscPreLoadingUsed - `PETSC_TRUE` if we are or have done preloading
2243: . PetscPreLoadingOn - `PETSC_TRUE` if it is CURRENTLY doing preload
2244: . PetscPreLoadIt - `0` for the first computation (with preloading turned off it is only
2245: `0`) `1` for the second
2246: - PetscPreLoadMax - number of times it will do the computation, only one when preloading is
2247: turned on
2249: The first two variables are available throughout the program, the second two only between the
2250: `PetscPreLoadBegin()` and `PetscPreLoadEnd()`
2252: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
2253: M*/
2255: /*MC
2256: PetscPreLoadEnd - End a segment of code that may be preloaded (run twice) to get accurate
2257: timings
2259: Synopsis:
2260: #include <petsclog.h>
2261: void PetscPreLoadEnd(void);
2263: Not Collective
2265: Example Usage:
2266: .vb
2267: PetscPreLoadBegin(PETSC_TRUE, "first stage");
2268: // lines of code
2269: PetscPreLoadStage("second stage");
2270: // lines of code
2271: PetscPreLoadEnd();
2272: .ve
2274: Level: intermediate
2276: Note:
2277: Only works in C/C++ not Fortran
2279: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadStage()`
2280: M*/
2282: /*MC
2283: PetscPreLoadStage - Start a new segment of code to be timed separately to get accurate timings
2285: Synopsis:
2286: #include <petsclog.h>
2287: void PetscPreLoadStage(char *name);
2289: Not Collective
2291: Example Usage:
2292: .vb
2293: PetscPreLoadBegin(PETSC_TRUE,"first stage");
2294: // lines of code
2295: PetscPreLoadStage("second stage");
2296: // lines of code
2297: PetscPreLoadEnd();
2298: .ve
2300: Level: intermediate
2302: Note:
2303: Only works in C/C++ not Fortran
2305: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`
2306: M*/
2308: #if PetscDefined(HAVE_DEVICE)
2309: #include <petsc/private/deviceimpl.h>
2311: /*@
2312: PetscLogGpuTime - turn on the logging of GPU time for GPU kernels
2314: Options Database Key:
2315: . -log_view_gpu_time - provide the GPU times for all events in the `-log_view` output
2317: Level: advanced
2319: Notes:
2320: Turning on the timing of the GPU kernels can slow down the entire computation and should only
2321: be used when studying the performance of individual operations on GPU such as vector operations and
2322: matrix-vector operations.
2324: 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
2326: This routine should only be called once near the beginning of the program. Once it is started
2327: it cannot be turned off.
2329: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTimeBegin()`
2330: @*/
2331: PetscErrorCode PetscLogGpuTime(void)
2332: {
2333: PetscFunctionBegin;
2334: PetscCheck(petsc_gtime == 0.0, PETSC_COMM_SELF, PETSC_ERR_SUP, "GPU logging has already been turned on");
2335: PetscLogGpuTimeFlag = PETSC_TRUE;
2336: PetscFunctionReturn(PETSC_SUCCESS);
2337: }
2339: /*@
2340: PetscLogGpuTimeBegin - Start timer for device
2342: Level: intermediate
2344: Notes:
2345: When GPU is enabled, the timer is run on the GPU, it is a separate logging of time
2346: devoted to GPU computations (excluding kernel launch times).
2348: When GPU is not available, the timer is run on the CPU, it is a separate logging of
2349: time devoted to GPU computations (including kernel launch times).
2351: There is no need to call WaitForCUDA() or WaitForHIP() between `PetscLogGpuTimeBegin()` and
2352: `PetscLogGpuTimeEnd()`
2354: This timer should NOT include times for data transfers between the GPU and CPU, nor setup
2355: actions such as allocating space.
2357: The regular logging captures the time for data transfers and any CPU activities during the
2358: event. It is used to compute the flop rate on the GPU as it is actively engaged in running a
2359: kernel.
2361: Developer Notes:
2362: The GPU event timer captures the execution time of all the kernels launched in the default
2363: stream by the CPU between `PetscLogGpuTimeBegin()` and `PetsLogGpuTimeEnd()`.
2365: `PetscLogGpuTimeBegin()` and `PetsLogGpuTimeEnd()` insert the begin and end events into the
2366: default stream (stream 0). The device will record a time stamp for the event when it reaches
2367: that event in the stream. The function xxxEventSynchronize() is called in
2368: `PetsLogGpuTimeEnd()` to block CPU execution, but not continued GPU execution, until the
2369: timer event is recorded.
2371: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTime()`
2372: @*/
2373: PetscErrorCode PetscLogGpuTimeBegin(void)
2374: {
2375: PetscBool isActive;
2377: PetscFunctionBegin;
2378: PetscCall(PetscLogEventBeginIsActive(&isActive));
2379: if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2380: #if defined(PETSC_HAVE_DEVICE) && !defined(PETSC_HAVE_KOKKOS_WITHOUT_GPU)
2381: {
2382: PetscDeviceContext dctx;
2384: PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2385: PetscCall(PetscDeviceContextBeginTimer_Internal(dctx));
2386: }
2387: #else
2388: PetscCall(PetscTimeSubtract(&petsc_gtime));
2389: #endif
2390: PetscFunctionReturn(PETSC_SUCCESS);
2391: }
2393: /*@
2394: PetscLogGpuTimeEnd - Stop timer for device
2396: Level: intermediate
2398: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeBegin()`
2399: @*/
2400: PetscErrorCode PetscLogGpuTimeEnd(void)
2401: {
2402: PetscBool isActive;
2404: PetscFunctionBegin;
2405: PetscCall(PetscLogEventEndIsActive(&isActive));
2406: if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2407: #if defined(PETSC_HAVE_DEVICE) && !defined(PETSC_HAVE_KOKKOS_WITHOUT_GPU)
2408: {
2409: PetscDeviceContext dctx;
2410: PetscLogDouble elapsed;
2412: PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2413: PetscCall(PetscDeviceContextEndTimer_Internal(dctx, &elapsed));
2414: petsc_gtime += (elapsed / 1000.0);
2415: }
2416: #else
2417: PetscCall(PetscTimeAdd(&petsc_gtime));
2418: #endif
2419: PetscFunctionReturn(PETSC_SUCCESS);
2420: }
2422: #endif /* end of PETSC_HAVE_DEVICE */
2424: #endif /* PETSC_USE_LOG*/
2426: /* -- Utility functions for logging from Fortran -- */
2428: PETSC_EXTERN PetscErrorCode PetscASend(int count, int datatype)
2429: {
2430: PetscFunctionBegin;
2431: #if PetscDefined(USE_LOG)
2432: PetscCall(PetscAddLogDouble(&petsc_send_ct, &petsc_send_ct_th, 1));
2433: #if !defined(MPIUNI_H) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO)
2434: PetscCall(PetscMPITypeSize(count, MPI_Type_f2c((MPI_Fint)datatype), &petsc_send_len, &petsc_send_len_th));
2435: #endif
2436: #endif
2437: PetscFunctionReturn(PETSC_SUCCESS);
2438: }
2440: PETSC_EXTERN PetscErrorCode PetscARecv(int count, int datatype)
2441: {
2442: PetscFunctionBegin;
2443: #if PetscDefined(USE_LOG)
2444: PetscCall(PetscAddLogDouble(&petsc_recv_ct, &petsc_recv_ct_th, 1));
2445: #if !defined(MPIUNI_H) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO)
2446: PetscCall(PetscMPITypeSize(count, MPI_Type_f2c((MPI_Fint)datatype), &petsc_recv_len, &petsc_recv_len_th));
2447: #endif
2448: #endif
2449: PetscFunctionReturn(PETSC_SUCCESS);
2450: }
2452: PETSC_EXTERN PetscErrorCode PetscAReduce(void)
2453: {
2454: PetscFunctionBegin;
2455: if (PetscDefined(USE_LOG)) PetscCall(PetscAddLogDouble(&petsc_allreduce_ct, &petsc_allreduce_ct_th, 1));
2456: PetscFunctionReturn(PETSC_SUCCESS);
2457: }
2459: PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2460: PetscClassId PETSC_OBJECT_CLASSID = 0;
2462: static PetscBool PetscLogInitializeCalled = PETSC_FALSE;
2464: PETSC_INTERN PetscErrorCode PetscLogInitialize(void)
2465: {
2466: int stage;
2468: PetscFunctionBegin;
2469: if (PetscLogInitializeCalled) PetscFunctionReturn(PETSC_SUCCESS);
2470: PetscLogInitializeCalled = PETSC_TRUE;
2471: if (PetscDefined(USE_LOG)) {
2472: /* Setup default logging structures */
2473: PetscCall(PetscLogStateCreate(&petsc_log_state));
2474: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2475: if (PetscLogHandlers[i].handler) PetscCall(PetscLogHandlerSetState(PetscLogHandlers[i].handler, petsc_log_state));
2476: }
2477: PetscCall(PetscLogStateStageRegister(petsc_log_state, "Main Stage", &stage));
2478: PetscCall(PetscSpinlockCreate(&PetscLogSpinLock));
2479: #if defined(PETSC_HAVE_THREADSAFETY)
2480: petsc_log_tid = 0;
2481: petsc_log_gid = 0;
2482: #endif
2484: /* All processors sync here for more consistent logging */
2485: PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
2486: PetscCall(PetscTime(&petsc_BaseTime));
2487: PetscCall(PetscLogStagePush(stage));
2488: }
2489: PetscFunctionReturn(PETSC_SUCCESS);
2490: }
2492: PETSC_INTERN PetscErrorCode PetscLogFinalize(void)
2493: {
2494: PetscFunctionBegin;
2495: if (PetscDefined(USE_LOG)) {
2496: /* Resetting phase */
2497: // pop remaining stages
2498: if (petsc_log_state) {
2499: while (petsc_log_state->current_stage >= 0) { PetscCall(PetscLogStagePop()); }
2500: }
2501: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) PetscCall(PetscLogHandlerDestroy(&PetscLogHandlers[i].handler));
2502: PetscCall(PetscArrayzero(PetscLogHandlers, PETSC_LOG_HANDLER_MAX));
2503: PetscCall(PetscLogStateDestroy(&petsc_log_state));
2505: petsc_TotalFlops = 0.0;
2506: petsc_BaseTime = 0.0;
2507: petsc_TotalFlops = 0.0;
2508: petsc_send_ct = 0.0;
2509: petsc_recv_ct = 0.0;
2510: petsc_send_len = 0.0;
2511: petsc_recv_len = 0.0;
2512: petsc_isend_ct = 0.0;
2513: petsc_irecv_ct = 0.0;
2514: petsc_isend_len = 0.0;
2515: petsc_irecv_len = 0.0;
2516: petsc_wait_ct = 0.0;
2517: petsc_wait_any_ct = 0.0;
2518: petsc_wait_all_ct = 0.0;
2519: petsc_sum_of_waits_ct = 0.0;
2520: petsc_allreduce_ct = 0.0;
2521: petsc_gather_ct = 0.0;
2522: petsc_scatter_ct = 0.0;
2523: petsc_TotalFlops_th = 0.0;
2524: petsc_send_ct_th = 0.0;
2525: petsc_recv_ct_th = 0.0;
2526: petsc_send_len_th = 0.0;
2527: petsc_recv_len_th = 0.0;
2528: petsc_isend_ct_th = 0.0;
2529: petsc_irecv_ct_th = 0.0;
2530: petsc_isend_len_th = 0.0;
2531: petsc_irecv_len_th = 0.0;
2532: petsc_wait_ct_th = 0.0;
2533: petsc_wait_any_ct_th = 0.0;
2534: petsc_wait_all_ct_th = 0.0;
2535: petsc_sum_of_waits_ct_th = 0.0;
2536: petsc_allreduce_ct_th = 0.0;
2537: petsc_gather_ct_th = 0.0;
2538: petsc_scatter_ct_th = 0.0;
2540: petsc_ctog_ct = 0.0;
2541: petsc_gtoc_ct = 0.0;
2542: petsc_ctog_sz = 0.0;
2543: petsc_gtoc_sz = 0.0;
2544: petsc_gflops = 0.0;
2545: petsc_gtime = 0.0;
2546: petsc_ctog_ct_th = 0.0;
2547: petsc_gtoc_ct_th = 0.0;
2548: petsc_ctog_sz_th = 0.0;
2549: petsc_gtoc_sz_th = 0.0;
2550: petsc_gflops_th = 0.0;
2551: petsc_gtime_th = 0.0;
2552: }
2553: PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2554: PETSC_OBJECT_CLASSID = 0;
2555: PetscLogInitializeCalled = PETSC_FALSE;
2556: PetscFunctionReturn(PETSC_SUCCESS);
2557: }
2559: /*@
2560: PetscClassIdRegister - Registers a new class name for objects and logging operations in an application code.
2562: Not Collective
2564: Input Parameter:
2565: . name - The class name
2567: Output Parameter:
2568: . oclass - The class id or classid
2570: Level: developer
2572: .seealso: [](ch_profiling), `PetscLogEventRegister()`
2573: @*/
2574: PetscErrorCode PetscClassIdRegister(const char name[], PetscClassId *oclass)
2575: {
2576: PetscFunctionBegin;
2577: *oclass = ++PETSC_LARGEST_CLASSID;
2578: #if defined(PETSC_USE_LOG)
2579: {
2580: PetscLogState state;
2581: PetscLogClass logclass;
2583: PetscCall(PetscLogGetState(&state));
2584: if (state) PetscCall(PetscLogStateClassRegister(state, name, *oclass, &logclass));
2585: }
2586: #endif
2587: PetscFunctionReturn(PETSC_SUCCESS);
2588: }