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 \
107: { \
108: NULL, NULL, NULL, NULL, NULL, NULL \
109: }
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:
248: Users should only need this if they create their own log handlers: handlers that are started
249: from the command line (such as `-log_view` and `-log_trace`) or from a function like
250: `PetscLogNestedBegin()` will automatically be started.
252: There is a limit of `PESC_LOG_HANDLER_MAX` handlers that can be active at one time.
254: To disconnect a handler from the global stream call `PetscLogHandlerStop()`.
256: When a log handler is started, stages that have already been pushed with `PetscLogStagePush()`,
257: will be pushed for the new log handler, but it will not be informed of any events that are
258: in progress. It is recommended to start any user-defined log handlers immediately following
259: before any user-defined stages are pushed.
261: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogHandlerStop()`
262: @*/
263: PetscErrorCode PetscLogHandlerStart(PetscLogHandler h)
264: {
265: PetscFunctionBegin;
266: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
267: if (PetscLogHandlers[i].handler == h) PetscFunctionReturn(PETSC_SUCCESS);
268: }
269: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
270: if (PetscLogHandlers[i].handler == NULL) {
271: PetscCall(PetscObjectReference((PetscObject)h));
272: PetscCall(PetscLogHandlerCopyToHot(h, &PetscLogHandlers[i]));
273: if (petsc_log_state) {
274: PetscLogStage stack_height;
275: PetscIntStack orig_stack, temp_stack;
277: PetscCall(PetscLogHandlerSetState(h, petsc_log_state));
278: stack_height = petsc_log_state->stage_stack->top + 1;
279: PetscCall(PetscIntStackCreate(&temp_stack));
280: orig_stack = petsc_log_state->stage_stack;
281: petsc_log_state->stage_stack = temp_stack;
282: petsc_log_state->current_stage = -1;
283: for (int s = 0; s < stack_height; s++) {
284: PetscLogStage stage = (PetscLogStage)orig_stack->stack[s];
285: PetscCall(PetscLogHandlerStagePush(h, stage));
286: PetscCall(PetscIntStackPush(temp_stack, stage));
287: petsc_log_state->current_stage = stage;
288: }
289: PetscCall(PetscIntStackDestroy(temp_stack));
290: petsc_log_state->stage_stack = orig_stack;
291: }
292: PetscFunctionReturn(PETSC_SUCCESS);
293: }
294: }
295: SETERRQ(PetscObjectComm((PetscObject)h), PETSC_ERR_ARG_WRONGSTATE, "%d log handlers already started, cannot start another", PETSC_LOG_HANDLER_MAX);
296: PetscFunctionReturn(PETSC_SUCCESS);
297: }
299: /*@
300: PetscLogHandlerStop - Disconnect a log handler from PETSc's global logging stream.
302: Logically collective
304: Input Parameters:
305: . h - a `PetscLogHandler`
307: Level: developer
309: Note:
310: After `PetscLogHandlerStop()`, the handler can still access the global logging state
311: with `PetscLogHandlerGetState()`, so that it can access the registry when post-processing
312: (for instance, in `PetscLogHandlerView()`),
314: When a log handler is stopped, the remaining stages will be popped before it is
315: disconnected from the log stream.
317: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogHandlerStart()`
318: @*/
319: PetscErrorCode PetscLogHandlerStop(PetscLogHandler h)
320: {
321: PetscFunctionBegin;
322: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
323: if (PetscLogHandlers[i].handler == h) {
324: if (petsc_log_state) {
325: PetscLogState state;
326: PetscLogStage stack_height;
327: PetscIntStack orig_stack, temp_stack;
329: PetscCall(PetscLogHandlerGetState(h, &state));
330: PetscCheck(state == petsc_log_state, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "Called PetscLogHandlerStop() for a PetscLogHander that was not started.");
331: stack_height = petsc_log_state->stage_stack->top + 1;
332: PetscCall(PetscIntStackCreate(&temp_stack));
333: orig_stack = petsc_log_state->stage_stack;
334: petsc_log_state->stage_stack = temp_stack;
335: for (int s = 0; s < stack_height; s++) {
336: PetscLogStage stage = (PetscLogStage)orig_stack->stack[s];
338: PetscCall(PetscIntStackPush(temp_stack, stage));
339: }
340: for (int s = 0; s < stack_height; s++) {
341: PetscLogStage stage;
342: PetscBool empty;
344: PetscCall(PetscIntStackPop(temp_stack, &stage));
345: PetscCall(PetscIntStackEmpty(temp_stack, &empty));
346: if (!empty) {
347: PetscCall(PetscIntStackTop(temp_stack, &petsc_log_state->current_stage));
348: } else petsc_log_state->current_stage = -1;
349: PetscCall(PetscLogHandlerStagePop(h, stage));
350: }
351: PetscCall(PetscIntStackDestroy(temp_stack));
352: petsc_log_state->stage_stack = orig_stack;
353: PetscCall(PetscIntStackTop(petsc_log_state->stage_stack, &petsc_log_state->current_stage));
354: }
355: PetscCall(PetscArrayzero(&PetscLogHandlers[i], 1));
356: PetscCall(PetscObjectDereference((PetscObject)h));
357: }
358: }
359: PetscFunctionReturn(PETSC_SUCCESS);
360: }
362: /*@C
363: PetscLogIsActive - Check if logging is currently in progress.
365: Not Collective
367: Output Parameter:
368: . isActive - `PETSC_TRUE` if logging is in progress, `PETSC_FALSE` otherwise
370: Level: beginner
372: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`
373: @*/
374: PetscErrorCode PetscLogIsActive(PetscBool *isActive)
375: {
376: PetscFunctionBegin;
377: *isActive = PETSC_FALSE;
378: if (petsc_log_state) {
379: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
380: if (PetscLogHandlers[i].handler) {
381: *isActive = PETSC_TRUE;
382: PetscFunctionReturn(PETSC_SUCCESS);
383: }
384: }
385: }
386: PetscFunctionReturn(PETSC_SUCCESS);
387: }
389: PETSC_UNUSED static PetscErrorCode PetscLogEventBeginIsActive(PetscBool *isActive)
390: {
391: PetscFunctionBegin;
392: *isActive = PETSC_FALSE;
393: if (petsc_log_state) {
394: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
395: if (PetscLogHandlers[i].eventBegin) {
396: *isActive = PETSC_TRUE;
397: PetscFunctionReturn(PETSC_SUCCESS);
398: }
399: }
400: }
401: PetscFunctionReturn(PETSC_SUCCESS);
402: }
404: PETSC_UNUSED static PetscErrorCode PetscLogEventEndIsActive(PetscBool *isActive)
405: {
406: PetscFunctionBegin;
407: *isActive = PETSC_FALSE;
408: if (petsc_log_state) {
409: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
410: if (PetscLogHandlers[i].eventEnd) {
411: *isActive = PETSC_TRUE;
412: PetscFunctionReturn(PETSC_SUCCESS);
413: }
414: }
415: }
416: PetscFunctionReturn(PETSC_SUCCESS);
417: }
419: PETSC_INTERN PetscErrorCode PetscLogTypeBegin(PetscLogHandlerType type)
420: {
421: PetscLogHandler handler;
423: PetscFunctionBegin;
424: PetscCall(PetscLogTryGetHandler(type, &handler));
425: if (handler) PetscFunctionReturn(PETSC_SUCCESS);
426: PetscCall(PetscLogHandlerCreate(PETSC_COMM_WORLD, &handler));
427: PetscCall(PetscLogHandlerSetType(handler, type));
428: PetscCall(PetscLogHandlerStart(handler));
429: PetscCall(PetscLogHandlerDestroy(&handler));
430: PetscFunctionReturn(PETSC_SUCCESS);
431: }
433: /*@C
434: PetscLogDefaultBegin - Turns on logging of objects and events using the default log handler. This logs flop
435: rates and object creation and should not slow programs down too much.
436: This routine may be called more than once.
438: Logically Collective on `PETSC_COMM_WORLD`
440: Options Database Key:
441: . -log_view [viewertype:filename:viewerformat] - Prints summary of flop and timing information to the
442: screen (for code configured with --with-log=1 (which is the default))
444: Example Usage:
445: .vb
446: PetscInitialize(...);
447: PetscLogDefaultBegin();
448: ... code ...
449: PetscLogView(viewer); or PetscLogDump();
450: PetscFinalize();
451: .ve
453: Level: advanced
455: Note:
456: `PetscLogView()` or `PetscLogDump()` actually cause the printing of
457: the logging information.
459: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`
460: @*/
461: PetscErrorCode PetscLogDefaultBegin(void)
462: {
463: PetscFunctionBegin;
464: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERDEFAULT));
465: PetscFunctionReturn(PETSC_SUCCESS);
466: }
468: /*@C
469: PetscLogTraceBegin - Begins trace logging. Every time a PETSc event
470: begins or ends, the event name is printed.
472: Logically Collective on `PETSC_COMM_WORLD`
474: Input Parameter:
475: . file - The file to print trace in (e.g. stdout)
477: Options Database Key:
478: . -log_trace [filename] - Begins `PetscLogTraceBegin()`
480: Level: intermediate
482: Notes:
483: `PetscLogTraceBegin()` prints the processor number, the execution time (sec),
484: then "Event begin:" or "Event end:" followed by the event name.
486: `PetscLogTraceBegin()` allows tracing of all PETSc calls, which is useful
487: to determine where a program is hanging without running in the
488: debugger. Can be used in conjunction with the -info option.
490: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogView()`, `PetscLogDefaultBegin()`
491: @*/
492: PetscErrorCode PetscLogTraceBegin(FILE *file)
493: {
494: PetscLogHandler handler;
495: PetscFunctionBegin;
496: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERTRACE, &handler));
497: if (handler) PetscFunctionReturn(PETSC_SUCCESS);
498: PetscCall(PetscLogHandlerCreateTrace(PETSC_COMM_WORLD, file, &handler));
499: PetscCall(PetscLogHandlerStart(handler));
500: PetscCall(PetscLogHandlerDestroy(&handler));
501: PetscFunctionReturn(PETSC_SUCCESS);
502: }
504: PETSC_INTERN PetscErrorCode PetscLogHandlerCreate_Nested(MPI_Comm, PetscLogHandler *);
506: /*@C
507: PetscLogNestedBegin - Turns on nested logging of objects and events. This logs flop
508: rates and object creation and should not slow programs down too much.
510: Logically Collective on `PETSC_COMM_WORLD`
512: Options Database Keys:
513: . -log_view :filename.xml:ascii_xml - Prints an XML summary of flop and timing information to the file
515: Example Usage:
516: .vb
517: PetscInitialize(...);
518: PetscLogNestedBegin();
519: ... code ...
520: PetscLogView(viewer);
521: PetscFinalize();
522: .ve
524: Level: advanced
526: .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`
527: @*/
528: PetscErrorCode PetscLogNestedBegin(void)
529: {
530: PetscFunctionBegin;
531: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERNESTED));
532: PetscFunctionReturn(PETSC_SUCCESS);
533: }
535: /*@C
536: PetscLogLegacyCallbacksBegin - Create and start a log handler from callbacks
537: matching the now deprecated function pointers `PetscLogPLB`, `PetscLogPLE`,
538: `PetscLogPHC`, `PetscLogPHD`.
540: Logically Collective on `PETSC_COMM_WORLD`
542: Input Parameters:
543: + PetscLogPLB - A callback that will be executed by `PetscLogEventBegin()` (or `NULL`)
544: . PetscLogPLE - A callback that will be executed by `PetscLogEventEnd()` (or `NULL`)
545: . PetscLogPHC - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`)
546: - PetscLogPHD - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`)
548: Calling sequence of `PetscLogPLB`:
549: + e - a `PetscLogEvent` that is beginning
550: . _i - deprecated, unused
551: . o1 - a `PetscObject` associated with `e` (or `NULL`)
552: . o2 - a `PetscObject` associated with `e` (or `NULL`)
553: . o3 - a `PetscObject` associated with `e` (or `NULL`)
554: - o4 - a `PetscObject` associated with `e` (or `NULL`)
556: Calling sequence of `PetscLogPLE`:
557: + e - a `PetscLogEvent` that is beginning
558: . _i - deprecated, unused
559: . o1 - a `PetscObject` associated with `e` (or `NULL`)
560: . o2 - a `PetscObject` associated with `e` (or `NULL`)
561: . o3 - a `PetscObject` associated with `e` (or `NULL`)
562: - o4 - a `PetscObject` associated with `e` (or `NULL`)
564: Calling sequence of `PetscLogPHC`:
565: . o - a `PetscObject` that has just been created
567: Calling sequence of `PetscLogPHD`:
568: . o - a `PetscObject` that is about to be destroyed
570: Level: advanced
572: Notes:
573: This is for transitioning from the deprecated function `PetscLogSet()` and should not be used in new code.
575: This should help migrate external log handlers to use `PetscLogHandler`, but
576: callbacks that depend on the deprecated `PetscLogStage` datatype will have to be
577: updated.
579: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerStart()`, `PetscLogState`
580: @*/
581: 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))
582: {
583: PetscLogHandler handler;
585: PetscFunctionBegin;
586: PetscCall(PetscLogHandlerCreateLegacy(PETSC_COMM_WORLD, PetscLogPLB, PetscLogPLE, PetscLogPHC, PetscLogPHD, &handler));
587: PetscCall(PetscLogHandlerStart(handler));
588: PetscCall(PetscLogHandlerDestroy(&handler));
589: PetscFunctionReturn(PETSC_SUCCESS);
590: }
592: #if defined(PETSC_HAVE_MPE)
593: #include <mpe.h>
594: static PetscBool PetscBeganMPE = PETSC_FALSE;
595: #endif
597: /*@C
598: PetscLogMPEBegin - Turns on MPE logging of events. This creates large log files and slows the
599: program down.
601: Collective on `PETSC_COMM_WORLD`
603: Options Database Key:
604: . -log_mpe - Prints extensive log information
606: Level: advanced
608: Note:
609: A related routine is `PetscLogDefaultBegin()` (with the options key `-log_view`), which is
610: intended for production runs since it logs only flop rates and object creation (and should
611: not significantly slow the programs).
613: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogDefaultBegin()`, `PetscLogEventActivate()`,
614: `PetscLogEventDeactivate()`
615: @*/
616: PetscErrorCode PetscLogMPEBegin(void)
617: {
618: PetscFunctionBegin;
619: #if defined(PETSC_HAVE_MPE)
620: /* Do MPE initialization */
621: if (!MPE_Initialized_logging()) { /* This function exists in mpich 1.1.2 and higher */
622: PetscCall(PetscInfo(0, "Initializing MPE.\n"));
623: PetscCall(MPE_Init_log());
625: PetscBeganMPE = PETSC_TRUE;
626: } else {
627: PetscCall(PetscInfo(0, "MPE already initialized. Not attempting to reinitialize.\n"));
628: }
629: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERMPE));
630: #else
631: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe");
632: #endif
633: PetscFunctionReturn(PETSC_SUCCESS);
634: }
636: #if defined(PETSC_HAVE_TAU_PERFSTUBS)
637: #include <../src/sys/perfstubs/timer.h>
638: #endif
640: /*@C
641: PetscLogPerfstubsBegin - Turns on logging of events using the perfstubs interface.
643: Collective on `PETSC_COMM_WORLD`
645: Options Database Key:
646: . -log_perfstubs - use an external log handler through the perfstubs interface
648: Level: advanced
650: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogEventActivate()`
651: @*/
652: PetscErrorCode PetscLogPerfstubsBegin(void)
653: {
654: PetscFunctionBegin;
655: #if defined(PETSC_HAVE_TAU_PERFSTUBS)
656: PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERPERFSTUBS));
657: #else
658: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without perfstubs support, reconfigure with --with-tau-perfstubs");
659: #endif
660: PetscFunctionReturn(PETSC_SUCCESS);
661: }
663: /*@
664: PetscLogActions - Determines whether actions are logged for the default log handler.
666: Not Collective
668: Input Parameter:
669: . flag - `PETSC_TRUE` if actions are to be logged
671: Options Database Key:
672: + -log_exclude_actions - (deprecated) Does nothing
673: - -log_include_actions - Turn on action logging
675: Level: intermediate
677: Note:
678: Logging of actions continues to consume more memory as the program
679: runs. Long running programs should consider turning this feature off.
681: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogGetDefaultHandler()`
682: @*/
683: PetscErrorCode PetscLogActions(PetscBool flag)
684: {
685: PetscFunctionBegin;
686: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
687: PetscLogHandler h = PetscLogHandlers[i].handler;
689: if (h) PetscCall(PetscLogHandlerSetLogActions(h, flag));
690: }
691: PetscFunctionReturn(PETSC_SUCCESS);
692: }
694: /*@
695: PetscLogObjects - Determines whether objects are logged for the graphical viewer.
697: Not Collective
699: Input Parameter:
700: . flag - `PETSC_TRUE` if objects are to be logged
702: Options Database Key:
703: + -log_exclude_objects - (deprecated) Does nothing
704: - -log_include_objects - Turns on object logging
706: Level: intermediate
708: Note:
709: Logging of objects continues to consume more memory as the program
710: runs. Long running programs should consider turning this feature off.
712: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogGetDefaultHandler()`
713: @*/
714: PetscErrorCode PetscLogObjects(PetscBool flag)
715: {
716: PetscFunctionBegin;
717: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
718: PetscLogHandler h = PetscLogHandlers[i].handler;
720: if (h) PetscCall(PetscLogHandlerSetLogObjects(h, flag));
721: }
722: PetscFunctionReturn(PETSC_SUCCESS);
723: }
725: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
726: /*@C
727: PetscLogStageRegister - Attaches a character string name to a logging stage.
729: Not Collective
731: Input Parameter:
732: . sname - The name to associate with that stage
734: Output Parameter:
735: . stage - The stage number or -1 if logging is not active (`PetscLogIsActive()`).
737: Level: intermediate
739: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`
740: @*/
741: PetscErrorCode PetscLogStageRegister(const char sname[], PetscLogStage *stage)
742: {
743: PetscLogState state;
745: PetscFunctionBegin;
746: *stage = -1;
747: PetscCall(PetscLogGetState(&state));
748: if (state) PetscCall(PetscLogStateStageRegister(state, sname, stage));
749: PetscFunctionReturn(PETSC_SUCCESS);
750: }
752: /*@C
753: PetscLogStagePush - This function pushes a stage on the logging stack. Events started and stopped until `PetscLogStagePop()` will be associated with the stage
755: Not Collective
757: Input Parameter:
758: . stage - The stage on which to log
760: Example Usage:
761: If the option -log_view is used to run the program containing the
762: following code, then 2 sets of summary data will be printed during
763: PetscFinalize().
764: .vb
765: PetscInitialize(int *argc,char ***args,0,0);
766: [stage 0 of code]
767: PetscLogStagePush(1);
768: [stage 1 of code]
769: PetscLogStagePop();
770: PetscBarrier(...);
771: [more stage 0 of code]
772: PetscFinalize();
773: .ve
775: Level: intermediate
777: Note:
778: Use `PetscLogStageRegister()` to register a stage.
780: .seealso: [](ch_profiling), `PetscLogStagePop()`, `PetscLogStageRegister()`, `PetscBarrier()`
781: @*/
782: PetscErrorCode PetscLogStagePush(PetscLogStage stage)
783: {
784: PetscLogState state;
786: PetscFunctionBegin;
787: PetscCall(PetscLogGetState(&state));
788: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
789: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
790: PetscLogHandler h = PetscLogHandlers[i].handler;
791: if (h) PetscCall(PetscLogHandlerStagePush(h, stage));
792: }
793: PetscCall(PetscLogStateStagePush(state, stage));
794: PetscFunctionReturn(PETSC_SUCCESS);
795: }
797: /*@C
798: PetscLogStagePop - This function pops a stage from the logging stack that was pushed with `PetscLogStagePush()`
800: Not Collective
802: Example Usage:
803: If the option -log_view is used to run the program containing the
804: following code, then 2 sets of summary data will be printed during
805: PetscFinalize().
806: .vb
807: PetscInitialize(int *argc,char ***args,0,0);
808: [stage 0 of code]
809: PetscLogStagePush(1);
810: [stage 1 of code]
811: PetscLogStagePop();
812: PetscBarrier(...);
813: [more stage 0 of code]
814: PetscFinalize();
815: .ve
817: Level: intermediate
819: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStageRegister()`, `PetscBarrier()`
820: @*/
821: PetscErrorCode PetscLogStagePop(void)
822: {
823: PetscLogState state;
824: PetscLogStage current_stage;
826: PetscFunctionBegin;
827: PetscCall(PetscLogGetState(&state));
828: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
829: current_stage = state->current_stage;
830: PetscCall(PetscLogStateStagePop(state));
831: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
832: PetscLogHandler h = PetscLogHandlers[i].handler;
833: if (h) PetscCall(PetscLogHandlerStagePop(h, current_stage));
834: }
835: PetscFunctionReturn(PETSC_SUCCESS);
836: }
838: /*@
839: PetscLogStageSetActive - Sets if a stage is used for `PetscLogEventBegin()` and `PetscLogEventEnd()`.
841: Not Collective
843: Input Parameters:
844: + stage - The stage
845: - isActive - The activity flag, `PETSC_TRUE` for logging, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
847: Level: intermediate
849: Note:
850: If this is set to `PETSC_FALSE` the logging acts as if the stage did not exist
852: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
853: @*/
854: PetscErrorCode PetscLogStageSetActive(PetscLogStage stage, PetscBool isActive)
855: {
856: PetscLogState state;
858: PetscFunctionBegin;
859: PetscCall(PetscLogGetState(&state));
860: if (state) PetscCall(PetscLogStateStageSetActive(state, stage, isActive));
861: PetscFunctionReturn(PETSC_SUCCESS);
862: }
864: /*@
865: PetscLogStageGetActive - Checks if a stage is used for `PetscLogEventBegin()` and `PetscLogEventEnd()`.
867: Not Collective
869: Input Parameter:
870: . stage - The stage
872: Output Parameter:
873: . isActive - The activity flag, `PETSC_TRUE` for logging, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
875: Level: intermediate
877: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
878: @*/
879: PetscErrorCode PetscLogStageGetActive(PetscLogStage stage, PetscBool *isActive)
880: {
881: PetscLogState state;
883: PetscFunctionBegin;
884: *isActive = PETSC_FALSE;
885: PetscCall(PetscLogGetState(&state));
886: if (state) PetscCall(PetscLogStateStageGetActive(state, stage, isActive));
887: PetscFunctionReturn(PETSC_SUCCESS);
888: }
890: /*@
891: PetscLogStageSetVisible - Determines stage visibility in `PetscLogView()`
893: Not Collective
895: Input Parameters:
896: + stage - The stage
897: - isVisible - The visibility flag, `PETSC_TRUE` to print, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
899: Level: intermediate
901: Developer Notes:
902: Visibility only affects the default log handler in `PetscLogView()`: stages that are
903: set to invisible are suppressed from output.
905: .seealso: [](ch_profiling), `PetscLogStageGetVisible()`, `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
906: @*/
907: PetscErrorCode PetscLogStageSetVisible(PetscLogStage stage, PetscBool isVisible)
909: {
910: PetscFunctionBegin;
911: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
912: PetscLogHandler h = PetscLogHandlers[i].handler;
914: if (h) PetscCall(PetscLogHandlerStageSetVisible(h, stage, isVisible));
915: }
916: PetscFunctionReturn(PETSC_SUCCESS);
917: }
919: /*@
920: PetscLogStageGetVisible - Returns stage visibility in `PetscLogView()`
922: Not Collective
924: Input Parameter:
925: . stage - The stage
927: Output Parameter:
928: . isVisible - The visibility flag, `PETSC_TRUE` to print, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)
930: Level: intermediate
932: .seealso: [](ch_profiling), `PetscLogStageSetVisible()`, `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
933: @*/
934: PetscErrorCode PetscLogStageGetVisible(PetscLogStage stage, PetscBool *isVisible)
935: {
936: PetscLogHandler handler;
938: PetscFunctionBegin;
939: *isVisible = PETSC_FALSE;
940: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
941: if (handler) { PetscCall(PetscLogHandlerStageGetVisible(handler, stage, isVisible)); }
942: PetscFunctionReturn(PETSC_SUCCESS);
943: }
945: /*@C
946: PetscLogStageGetId - Returns the stage id when given the stage name.
948: Not Collective
950: Input Parameter:
951: . name - The stage name
953: Output Parameter:
954: . stage - The stage, , or -1 if no stage with that name exists
956: Level: intermediate
958: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
959: @*/
960: PetscErrorCode PetscLogStageGetId(const char name[], PetscLogStage *stage)
961: {
962: PetscLogState state;
964: PetscFunctionBegin;
965: *stage = -1;
966: PetscCall(PetscLogGetState(&state));
967: if (state) PetscCall(PetscLogStateGetStageFromName(state, name, stage));
968: PetscFunctionReturn(PETSC_SUCCESS);
969: }
971: /*@C
972: PetscLogStageGetName - Returns the stage name when given the stage id.
974: Not Collective
976: Input Parameter:
977: . stage - The stage
979: Output Parameter:
980: . name - The stage name
982: Level: intermediate
984: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
985: @*/
986: PetscErrorCode PetscLogStageGetName(PetscLogStage stage, const char **name)
987: {
988: PetscLogStageInfo stage_info;
989: PetscLogState state;
991: PetscFunctionBegin;
992: *name = NULL;
993: PetscCall(PetscLogGetState(&state));
994: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
995: PetscCall(PetscLogStateStageGetInfo(state, stage, &stage_info));
996: *name = stage_info.name;
997: PetscFunctionReturn(PETSC_SUCCESS);
998: }
1000: /*------------------------------------------------ Event Functions --------------------------------------------------*/
1002: /*@C
1003: PetscLogEventRegister - Registers an event name for logging operations
1005: Not Collective
1007: Input Parameters:
1008: + name - The name associated with the event
1009: - classid - The classid associated to the class for this event, obtain either with
1010: `PetscClassIdRegister()` or use a predefined one such as `KSP_CLASSID`, `SNES_CLASSID`, the predefined ones
1011: are only available in C code
1013: Output Parameter:
1014: . event - The event id for use with `PetscLogEventBegin()` and `PetscLogEventEnd()`.
1016: Example Usage:
1017: .vb
1018: PetscLogEvent USER_EVENT;
1019: PetscClassId classid;
1020: PetscLogDouble user_event_flops;
1021: PetscClassIdRegister("class name",&classid);
1022: PetscLogEventRegister("User event name",classid,&USER_EVENT);
1023: PetscLogEventBegin(USER_EVENT,0,0,0,0);
1024: [code segment to monitor]
1025: PetscLogFlops(user_event_flops);
1026: PetscLogEventEnd(USER_EVENT,0,0,0,0);
1027: .ve
1029: Level: intermediate
1031: Notes:
1032: PETSc automatically logs library events if the code has been
1033: configured with --with-log (which is the default) and
1034: -log_view or -log_all is specified. `PetscLogEventRegister()` is
1035: intended for logging user events to supplement this PETSc
1036: information.
1038: PETSc can gather data for use with the utilities Jumpshot
1039: (part of the MPICH distribution). If PETSc has been compiled
1040: with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
1041: MPICH), the user can employ another command line option, -log_mpe,
1042: to create a logfile, "mpe.log", which can be visualized
1043: Jumpshot.
1045: The classid is associated with each event so that classes of events
1046: can be disabled simultaneously, such as all matrix events. The user
1047: can either use an existing classid, such as `MAT_CLASSID`, or create
1048: their own as shown in the example.
1050: If an existing event with the same name exists, its event handle is
1051: returned instead of creating a new event.
1053: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogFlops()`,
1054: `PetscLogEventActivate()`, `PetscLogEventDeactivate()`, `PetscClassIdRegister()`
1055: @*/
1056: PetscErrorCode PetscLogEventRegister(const char name[], PetscClassId classid, PetscLogEvent *event)
1057: {
1058: PetscLogState state;
1060: PetscFunctionBegin;
1061: *event = -1;
1062: PetscCall(PetscLogGetState(&state));
1063: if (state) PetscCall(PetscLogStateEventRegister(state, name, classid, event));
1064: PetscFunctionReturn(PETSC_SUCCESS);
1065: }
1067: /*@
1068: PetscLogEventSetCollective - Indicates that a particular event is collective.
1070: Not Collective
1072: Input Parameters:
1073: + event - The event id
1074: - collective - Boolean flag indicating whether a particular event is collective
1076: Level: developer
1078: Notes:
1079: New events returned from `PetscLogEventRegister()` are collective by default.
1081: Collective events are handled specially if the -log_sync is used. In that case the logging saves information about
1082: two parts of the event; the time for all the MPI ranks to synchronize and then the time for the actual computation/communication
1083: to be performed. This option is useful to debug imbalance within the computations or communications
1085: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventRegister()`
1086: @*/
1087: PetscErrorCode PetscLogEventSetCollective(PetscLogEvent event, PetscBool collective)
1088: {
1089: PetscLogState state;
1091: PetscFunctionBegin;
1092: PetscCall(PetscLogGetState(&state));
1093: if (state) PetscCall(PetscLogStateEventSetCollective(state, event, collective));
1094: PetscFunctionReturn(PETSC_SUCCESS);
1095: }
1097: /*
1098: PetscLogClassSetActiveAll - Activate or inactivate logging for all events associated with a PETSc object class in every stage.
1100: Not Collective
1102: Input Parameters:
1103: + classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1104: - isActive - if `PETSC_FALSE`, events associated with this class will not be send to log handlers.
1106: Level: developer
1108: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventActivateAll()`, `PetscLogStageSetActive()`, `PetscLogEventActivateClass()`
1109: */
1110: static PetscErrorCode PetscLogClassSetActiveAll(PetscClassId classid, PetscBool isActive)
1111: {
1112: PetscLogState state;
1114: PetscFunctionBegin;
1115: PetscCall(PetscLogGetState(&state));
1116: if (state) PetscCall(PetscLogStateClassSetActiveAll(state, classid, isActive));
1117: PetscFunctionReturn(PETSC_SUCCESS);
1118: }
1120: /*@
1121: PetscLogEventIncludeClass - Activates event logging for a PETSc object class in every stage.
1123: Not Collective
1125: Input Parameter:
1126: . classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1128: Level: developer
1130: .seealso: [](ch_profiling), `PetscLogEventActivateClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1131: @*/
1132: PetscErrorCode PetscLogEventIncludeClass(PetscClassId classid)
1133: {
1134: PetscFunctionBegin;
1135: PetscCall(PetscLogClassSetActiveAll(classid, PETSC_TRUE));
1136: PetscFunctionReturn(PETSC_SUCCESS);
1137: }
1139: /*@
1140: PetscLogEventExcludeClass - Deactivates event logging for a PETSc object class in every stage.
1142: Not Collective
1144: Input Parameter:
1145: . classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1147: Level: developer
1149: Note:
1150: If a class is excluded then events associated with that class are not logged.
1152: .seealso: [](ch_profiling), `PetscLogEventDeactivateClass()`, `PetscLogEventActivateClass()`, `PetscLogEventDeactivate()`, `PetscLogEventActivate()`
1153: @*/
1154: PetscErrorCode PetscLogEventExcludeClass(PetscClassId classid)
1155: {
1156: PetscFunctionBegin;
1157: PetscCall(PetscLogClassSetActiveAll(classid, PETSC_FALSE));
1158: PetscFunctionReturn(PETSC_SUCCESS);
1159: }
1161: /*
1162: PetscLogEventSetActive - Activate or inactivate logging for an event in a given stage
1164: Not Collective
1166: Input Parameters:
1167: + stage - A registered `PetscLogStage` (or `PETSC_DEFAULT` for the current stage)
1168: . event - A `PetscLogEvent`
1169: - isActive - If `PETSC_FALSE`, activity from this event (`PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventSync()`) will not be sent to log handlers during this stage
1171: Usage:
1172: .vb
1173: PetscLogEventSetActive(VEC_SetValues, PETSC_FALSE);
1174: [code where you do not want to log VecSetValues()]
1175: PetscLogEventSetActive(VEC_SetValues, PETSC_TRUE);
1176: [code where you do want to log VecSetValues()]
1177: .ve
1179: Level: advanced
1181: Note:
1182: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
1183: or an event number obtained with `PetscLogEventRegister()`.
1185: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1186: */
1187: static PetscErrorCode PetscLogEventSetActive(PetscLogStage stage, PetscLogEvent event, PetscBool isActive)
1188: {
1189: PetscLogState state;
1191: PetscFunctionBegin;
1192: PetscCall(PetscLogGetState(&state));
1193: if (state) PetscCall(PetscLogStateEventSetActive(state, stage, event, isActive));
1194: PetscFunctionReturn(PETSC_SUCCESS);
1195: }
1197: /*@
1198: PetscLogEventActivate - Indicates that a particular event should be logged.
1200: Not Collective
1202: Input Parameter:
1203: . event - The event id
1205: Example Usage:
1206: .vb
1207: PetscLogEventDeactivate(VEC_SetValues);
1208: [code where you do not want to log VecSetValues()]
1209: PetscLogEventActivate(VEC_SetValues);
1210: [code where you do want to log VecSetValues()]
1211: .ve
1213: Level: advanced
1215: Note:
1216: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
1217: or an event number obtained with `PetscLogEventRegister()`.
1219: .seealso: [](ch_profiling), `PetscLogEventDeactivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1220: @*/
1221: PetscErrorCode PetscLogEventActivate(PetscLogEvent event)
1222: {
1223: PetscFunctionBegin;
1224: PetscCall(PetscLogEventSetActive(PETSC_DEFAULT, event, PETSC_TRUE));
1225: PetscFunctionReturn(PETSC_SUCCESS);
1226: }
1228: /*@
1229: PetscLogEventDeactivate - Indicates that a particular event should not be logged.
1231: Not Collective
1233: Input Parameter:
1234: . event - The event id
1236: Example Usage:
1237: .vb
1238: PetscLogEventDeactivate(VEC_SetValues);
1239: [code where you do not want to log VecSetValues()]
1240: PetscLogEventActivate(VEC_SetValues);
1241: [code where you do want to log VecSetValues()]
1242: .ve
1244: Level: advanced
1246: Note:
1247: The event may be either a pre-defined PETSc event (found in
1248: include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1250: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1251: @*/
1252: PetscErrorCode PetscLogEventDeactivate(PetscLogEvent event)
1253: {
1254: PetscFunctionBegin;
1255: PetscCall(PetscLogEventSetActive(PETSC_DEFAULT, event, PETSC_FALSE));
1256: PetscFunctionReturn(PETSC_SUCCESS);
1257: }
1259: /*@
1260: PetscLogEventDeactivatePush - Indicates that a particular event should not be logged until `PetscLogEventDeactivatePop()` is called
1262: Not Collective
1264: Input Parameter:
1265: . event - The event id
1267: Example Usage:
1268: .vb
1269: PetscLogEventDeactivatePush(VEC_SetValues);
1270: [code where you do not want to log VecSetValues()]
1271: PetscLogEventDeactivatePop(VEC_SetValues);
1272: [code where you do want to log VecSetValues()]
1273: .ve
1275: Level: advanced
1277: Note:
1278: The event may be either a pre-defined PETSc event (found in
1279: include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1281: 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.
1283: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivate()`, `PetscLogEventDeactivatePop()`
1284: @*/
1285: PetscErrorCode PetscLogEventDeactivatePush(PetscLogEvent event)
1286: {
1287: PetscFunctionBegin;
1288: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1289: PetscLogHandler h = PetscLogHandlers[i].handler;
1291: if (h) PetscCall(PetscLogHandlerEventDeactivatePush(h, PETSC_DEFAULT, event));
1292: }
1293: PetscFunctionReturn(PETSC_SUCCESS);
1294: }
1296: /*@
1297: PetscLogEventDeactivatePop - Indicates that a particular event should again be logged after the logging was turned off with `PetscLogEventDeactivatePush()`
1299: Not Collective
1301: Input Parameter:
1302: . event - The event id
1304: Example Usage:
1305: .vb
1306: PetscLogEventDeactivatePush(VEC_SetValues);
1307: [code where you do not want to log VecSetValues()]
1308: PetscLogEventDeactivatePop(VEC_SetValues);
1309: [code where you do want to log VecSetValues()]
1310: .ve
1312: Level: advanced
1314: Note:
1315: The event may be either a pre-defined PETSc event (found in
1316: include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).
1318: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`
1319: @*/
1320: PetscErrorCode PetscLogEventDeactivatePop(PetscLogEvent event)
1321: {
1322: PetscFunctionBegin;
1323: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1324: PetscLogHandler h = PetscLogHandlers[i].handler;
1326: if (h) PetscCall(PetscLogHandlerEventDeactivatePop(h, PETSC_DEFAULT, event));
1327: }
1328: PetscFunctionReturn(PETSC_SUCCESS);
1329: }
1331: /*@
1332: PetscLogEventSetActiveAll - Turns on logging of all events
1334: Not Collective
1336: Input Parameters:
1337: + event - The event id
1338: - isActive - The activity flag determining whether the event is logged
1340: Level: advanced
1342: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1343: @*/
1344: PetscErrorCode PetscLogEventSetActiveAll(PetscLogEvent event, PetscBool isActive)
1345: {
1346: PetscLogState state;
1348: PetscFunctionBegin;
1349: PetscCall(PetscLogGetState(&state));
1350: if (state) PetscCall(PetscLogStateEventSetActiveAll(state, event, isActive));
1351: PetscFunctionReturn(PETSC_SUCCESS);
1352: }
1354: /*
1355: PetscLogClassSetActive - Activates event logging for a PETSc object class for the current stage
1357: Not Collective
1359: Input Parameters:
1360: + stage - A registered `PetscLogStage` (or `PETSC_DEFAULT` for the current stage)
1361: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1362: - isActive - If `PETSC_FALSE`, events associated with this class are not sent to log handlers.
1364: Level: developer
1366: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventActivate()`, `PetscLogEventActivateAll()`, `PetscLogStageSetActive()`
1367: */
1368: static PetscErrorCode PetscLogClassSetActive(PetscLogStage stage, PetscClassId classid, PetscBool isActive)
1369: {
1370: PetscLogState state;
1372: PetscFunctionBegin;
1373: PetscCall(PetscLogGetState(&state));
1374: if (state) PetscCall(PetscLogStateClassSetActive(state, stage, classid, isActive));
1375: PetscFunctionReturn(PETSC_SUCCESS);
1376: }
1378: /*@
1379: PetscLogEventActivateClass - Activates event logging for a PETSc object class for the current stage
1381: Not Collective
1383: Input Parameter:
1384: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1386: Level: developer
1388: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1389: @*/
1390: PetscErrorCode PetscLogEventActivateClass(PetscClassId classid)
1391: {
1392: PetscFunctionBegin;
1393: PetscCall(PetscLogClassSetActive(PETSC_DEFAULT, classid, PETSC_TRUE));
1394: PetscFunctionReturn(PETSC_SUCCESS);
1395: }
1397: /*@
1398: PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class for the current stage
1400: Not Collective
1402: Input Parameter:
1403: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1405: Level: developer
1407: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventActivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1408: @*/
1409: PetscErrorCode PetscLogEventDeactivateClass(PetscClassId classid)
1410: {
1411: PetscFunctionBegin;
1412: PetscCall(PetscLogClassSetActive(PETSC_DEFAULT, classid, PETSC_FALSE));
1413: PetscFunctionReturn(PETSC_SUCCESS);
1414: }
1416: /*MC
1417: PetscLogEventSync - Synchronizes the beginning of a user event.
1419: Synopsis:
1420: #include <petsclog.h>
1421: PetscErrorCode PetscLogEventSync(PetscLogEvent e, MPI_Comm comm)
1423: Collective
1425: Input Parameters:
1426: + e - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1427: - comm - an MPI communicator
1429: Example Usage:
1430: .vb
1431: PetscLogEvent USER_EVENT;
1433: PetscLogEventRegister("User event", 0, &USER_EVENT);
1434: PetscLogEventSync(USER_EVENT, PETSC_COMM_WORLD);
1435: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1436: [code segment to monitor]
1437: PetscLogEventEnd(USER_EVENT, 0, 0, 0 , 0);
1438: .ve
1440: Level: developer
1442: Note:
1443: This routine should be called only if there is not a `PetscObject` available to pass to
1444: `PetscLogEventBegin()`.
1446: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`
1447: M*/
1449: /*MC
1450: PetscLogEventBegin - Logs the beginning of a user event.
1452: Synopsis:
1453: #include <petsclog.h>
1454: PetscErrorCode PetscLogEventBegin(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
1456: Not Collective
1458: Input Parameters:
1459: + e - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1460: . o1 - object associated with the event, or `NULL`
1461: . o2 - object associated with the event, or `NULL`
1462: . o3 - object associated with the event, or `NULL`
1463: - o4 - object associated with the event, or `NULL`
1465: Fortran Synopsis:
1466: void PetscLogEventBegin(int e, PetscErrorCode ierr)
1468: Example Usage:
1469: .vb
1470: PetscLogEvent USER_EVENT;
1472: PetscLogDouble user_event_flops;
1473: PetscLogEventRegister("User event",0, &USER_EVENT);
1474: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1475: [code segment to monitor]
1476: PetscLogFlops(user_event_flops);
1477: PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
1478: .ve
1480: Level: intermediate
1482: Developer Note:
1483: `PetscLogEventBegin()` and `PetscLogEventBegin()` return error codes instead of explicitly
1484: handling the errors that occur in the macro directly because other packages that use this
1485: macros have used them in their own functions or methods that do not return error codes and it
1486: would be disruptive to change the current behavior.
1488: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventEnd()`, `PetscLogFlops()`
1489: M*/
1491: /*MC
1492: PetscLogEventEnd - Log the end of a user event.
1494: Synopsis:
1495: #include <petsclog.h>
1496: PetscErrorCode PetscLogEventEnd(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
1498: Not Collective
1500: Input Parameters:
1501: + e - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1502: . o1 - object associated with the event, or `NULL`
1503: . o2 - object associated with the event, or `NULL`
1504: . o3 - object associated with the event, or `NULL`
1505: - o4 - object associated with the event, or `NULL`
1507: Fortran Synopsis:
1508: void PetscLogEventEnd(int e, PetscErrorCode ierr)
1510: Example Usage:
1511: .vb
1512: PetscLogEvent USER_EVENT;
1514: PetscLogDouble user_event_flops;
1515: PetscLogEventRegister("User event", 0, &USER_EVENT);
1516: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1517: [code segment to monitor]
1518: PetscLogFlops(user_event_flops);
1519: PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
1520: .ve
1522: Level: intermediate
1524: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogFlops()`
1525: M*/
1527: /*@C
1528: PetscLogStageGetPerfInfo - Return the performance information about the given stage
1530: Input Parameters:
1531: . stage - The stage number or `PETSC_DETERMINE` for the current stage
1533: Output Parameter:
1534: . info - This structure is filled with the performance information
1536: Level: intermediate
1538: Notes:
1539: This is a low level routine used by the logging functions in PETSc.
1541: A `PETSCLOGHANDLERDEFAULT` must be running for this to work, having been started either with
1542: `PetscLogDefaultBegin()` or from the command line wth `-log_view`. If it was not started,
1543: all performance statistics in `info` will be zeroed.
1545: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1546: @*/
1547: PetscErrorCode PetscLogStageGetPerfInfo(PetscLogStage stage, PetscEventPerfInfo *info)
1548: {
1549: PetscLogHandler handler;
1550: PetscEventPerfInfo *event_info;
1552: PetscFunctionBegin;
1553: PetscAssertPointer(info, 2);
1554: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1555: if (handler) {
1556: PetscCall(PetscLogHandlerGetStagePerfInfo(handler, stage, &event_info));
1557: *info = *event_info;
1558: } else {
1559: PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogStageGetPerfInfo() returning zeros\n"));
1560: PetscCall(PetscMemzero(info, sizeof(*info)));
1561: }
1562: PetscFunctionReturn(PETSC_SUCCESS);
1563: }
1565: /*@C
1566: PetscLogEventGetPerfInfo - Return the performance information about the given event in the given stage
1568: Input Parameters:
1569: + stage - The stage number or `PETSC_DETERMINE` for the current stage
1570: - event - The event number
1572: Output Parameter:
1573: . info - This structure is filled with the performance information
1575: Level: intermediate
1577: Note:
1578: This is a low level routine used by the logging functions in PETSc
1580: A `PETSCLOGHANDLERDEFAULT` must be running for this to work, having been started either with
1581: `PetscLogDefaultBegin()` or from the command line wth `-log_view`. If it was not started,
1582: all performance statistics in `info` will be zeroed.
1584: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1585: @*/
1586: PetscErrorCode PetscLogEventGetPerfInfo(PetscLogStage stage, PetscLogEvent event, PetscEventPerfInfo *info)
1587: {
1588: PetscLogHandler handler;
1589: PetscEventPerfInfo *event_info;
1591: PetscFunctionBegin;
1592: PetscAssertPointer(info, 3);
1593: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1594: if (handler) {
1595: PetscCall(PetscLogHandlerGetEventPerfInfo(handler, stage, event, &event_info));
1596: *info = *event_info;
1597: } else {
1598: PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogEventGetPerfInfo() returning zeros\n"));
1599: PetscCall(PetscMemzero(info, sizeof(*info)));
1600: }
1601: PetscFunctionReturn(PETSC_SUCCESS);
1602: }
1604: /*@C
1605: PetscLogEventSetDof - Set the nth number of degrees of freedom of a numerical problem associated with this event
1607: Not Collective
1609: Input Parameters:
1610: + event - The event id to log
1611: . n - The dof index, in [0, 8)
1612: - dof - The number of dofs
1614: Options Database Key:
1615: . -log_view - Activates log summary
1617: Level: developer
1619: Note:
1620: This is to enable logging of convergence
1622: .seealso: `PetscLogEventSetError()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1623: @*/
1624: PetscErrorCode PetscLogEventSetDof(PetscLogEvent event, PetscInt n, PetscLogDouble dof)
1625: {
1626: PetscFunctionBegin;
1627: PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1628: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1629: PetscLogHandler h = PetscLogHandlers[i].handler;
1631: if (h) {
1632: PetscEventPerfInfo *event_info;
1634: PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1635: if (event_info) event_info->dof[n] = dof;
1636: }
1637: }
1638: PetscFunctionReturn(PETSC_SUCCESS);
1639: }
1641: /*@C
1642: PetscLogEventSetError - Set the nth error associated with a numerical problem associated with this event
1644: Not Collective
1646: Input Parameters:
1647: + event - The event id to log
1648: . n - The error index, in [0, 8)
1649: - error - The error
1651: Options Database Key:
1652: . -log_view - Activates log summary
1654: Level: developer
1656: Notes:
1657: This is to enable logging of convergence, and enable users to interpret the errors as they wish. For example,
1658: as different norms, or as errors for different fields
1660: This is a low level routine used by the logging functions in PETSc
1662: .seealso: `PetscLogEventSetDof()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1663: @*/
1664: PetscErrorCode PetscLogEventSetError(PetscLogEvent event, PetscInt n, PetscLogDouble error)
1665: {
1666: PetscFunctionBegin;
1667: PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1668: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1669: PetscLogHandler h = PetscLogHandlers[i].handler;
1671: if (h) {
1672: PetscEventPerfInfo *event_info;
1674: PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1675: if (event_info) event_info->errors[n] = error;
1676: }
1677: }
1678: PetscFunctionReturn(PETSC_SUCCESS);
1679: }
1681: /*@C
1682: PetscLogEventGetId - Returns the event id when given the event name.
1684: Not Collective
1686: Input Parameter:
1687: . name - The event name
1689: Output Parameter:
1690: . event - The event, or -1 if no event with that name exists
1692: Level: intermediate
1694: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1695: @*/
1696: PetscErrorCode PetscLogEventGetId(const char name[], PetscLogEvent *event)
1697: {
1698: PetscLogState state;
1700: PetscFunctionBegin;
1701: *event = -1;
1702: PetscCall(PetscLogGetState(&state));
1703: if (state) PetscCall(PetscLogStateGetEventFromName(state, name, event));
1704: PetscFunctionReturn(PETSC_SUCCESS);
1705: }
1707: /*@C
1708: PetscLogEventGetName - Returns the event name when given the event id.
1710: Not Collective
1712: Input Parameter:
1713: . event - The event
1715: Output Parameter:
1716: . name - The event name
1718: Level: intermediate
1720: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
1721: @*/
1722: PetscErrorCode PetscLogEventGetName(PetscLogEvent event, const char **name)
1723: {
1724: PetscLogEventInfo event_info;
1725: PetscLogState state;
1727: PetscFunctionBegin;
1728: *name = NULL;
1729: PetscCall(PetscLogGetState(&state));
1730: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1731: PetscCall(PetscLogStateEventGetInfo(state, event, &event_info));
1732: *name = event_info.name;
1733: PetscFunctionReturn(PETSC_SUCCESS);
1734: }
1736: /*@
1737: 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.
1739: Not collective
1741: Level: advanced
1743: Notes:
1744: 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()`).
1746: Other log handlers (such as the nested handler, `PetscLogNestedBegin()`) will ignore this function.
1748: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsResume()`, `PetscLogGetDefaultHandler()`
1749: @*/
1750: PetscErrorCode PetscLogEventsPause(void)
1751: {
1752: PetscFunctionBegin;
1753: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1754: PetscLogHandler h = PetscLogHandlers[i].handler;
1756: if (h) PetscCall(PetscLogHandlerEventsPause(h));
1757: }
1758: PetscFunctionReturn(PETSC_SUCCESS);
1759: }
1761: /*@
1762: PetscLogEventsResume - Return logging to normal behavior after it was paused with `PetscLogEventsPause()`.
1764: Not collective
1766: Level: advanced
1768: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsPause()`, `PetscLogGetDefaultHandler()`
1769: @*/
1770: PetscErrorCode PetscLogEventsResume(void)
1771: {
1772: PetscFunctionBegin;
1773: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1774: PetscLogHandler h = PetscLogHandlers[i].handler;
1776: if (h) PetscCall(PetscLogHandlerEventsResume(h));
1777: }
1778: PetscFunctionReturn(PETSC_SUCCESS);
1779: }
1781: /*------------------------------------------------ Class Functions --------------------------------------------------*/
1783: /*MC
1784: PetscLogObjectCreate - Log the creation of a `PetscObject`
1786: Synopsis:
1787: #include <petsclog.h>
1788: PetscErrorCode PetscLogObjectCreate(PetscObject h)
1790: Not Collective
1792: Input Parameters:
1793: . h - A `PetscObject`
1795: Level: developer
1797: Developer Note:
1798: Called internally by PETSc when creating objects: users do not need to call this directly.
1799: Notification of the object creation is sent to each `PetscLogHandler` that is running.
1801: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectDestroy()`
1802: M*/
1804: /*MC
1805: PetscLogObjectDestroy - Logs the destruction of a `PetscObject`
1807: Synopsis:
1808: #include <petsclog.h>
1809: PetscErrorCode PetscLogObjectDestroy(PetscObject h)
1811: Not Collective
1813: Input Parameters:
1814: . h - A `PetscObject`
1816: Level: developer
1818: Developer Note:
1819: Called internally by PETSc when destroying objects: users do not need to call this directly.
1820: Notification of the object creation is sent to each `PetscLogHandler` that is running.
1822: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectCreate()`
1823: M*/
1825: /*@C
1826: PetscLogClassGetClassId - Returns the `PetscClassId` when given the class name.
1828: Not Collective
1830: Input Parameter:
1831: . name - The class name
1833: Output Parameter:
1834: . classid - The `PetscClassId` id, or -1 if no class with that name exists
1836: Level: intermediate
1838: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1839: @*/
1840: PetscErrorCode PetscLogClassGetClassId(const char name[], PetscClassId *classid)
1841: {
1842: PetscLogClass log_class;
1843: PetscLogClassInfo class_info;
1844: PetscLogState state;
1846: PetscFunctionBegin;
1847: *classid = -1;
1848: PetscCall(PetscLogGetState(&state));
1849: if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1850: PetscCall(PetscLogStateGetClassFromName(state, name, &log_class));
1851: if (log_class < 0) {
1852: *classid = -1;
1853: PetscFunctionReturn(PETSC_SUCCESS);
1854: }
1855: PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1856: *classid = class_info.classid;
1857: PetscFunctionReturn(PETSC_SUCCESS);
1858: }
1860: /*@C
1861: PetscLogClassIdGetName - Returns a `PetscClassId`'s name.
1863: Not Collective
1865: Input Parameter:
1866: . classid - A `PetscClassId`
1868: Output Parameter:
1869: . name - The class name
1871: Level: intermediate
1873: .seealso: [](ch_profiling), `PetscLogClassRegister()`, `PetscLogClassBegin()`, `PetscLogClassEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadClass()`
1874: @*/
1875: PetscErrorCode PetscLogClassIdGetName(PetscClassId classid, const char **name)
1876: {
1877: PetscLogClass log_class;
1878: PetscLogClassInfo class_info;
1879: PetscLogState state;
1881: PetscFunctionBegin;
1882: PetscCall(PetscLogGetState(&state));
1883: PetscCall(PetscLogStateGetClassFromClassId(state, classid, &log_class));
1884: PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1885: *name = class_info.name;
1886: PetscFunctionReturn(PETSC_SUCCESS);
1887: }
1889: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1890: /*@C
1891: PetscLogDump - Dumps logs of objects to a file. This file is intended to
1892: be read by bin/petscview. This program no longer exists.
1894: Collective on `PETSC_COMM_WORLD`
1896: Input Parameter:
1897: . sname - an optional file name
1899: Example Usage:
1900: .vb
1901: PetscInitialize(...);
1902: PetscLogDefaultBegin();
1903: // ... code ...
1904: PetscLogDump(filename);
1905: PetscFinalize();
1906: .ve
1908: Level: advanced
1910: Note:
1911: The default file name is Log.<rank> where <rank> is the MPI process rank. If no name is specified,
1912: this file will be used.
1914: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
1915: @*/
1916: PetscErrorCode PetscLogDump(const char sname[])
1917: {
1918: PetscLogHandler handler;
1920: PetscFunctionBegin;
1921: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1922: PetscCall(PetscLogHandlerDump(handler, sname));
1923: PetscFunctionReturn(PETSC_SUCCESS);
1924: }
1926: /*@C
1927: PetscLogMPEDump - Dumps the MPE logging info to file for later use with Jumpshot.
1929: Collective on `PETSC_COMM_WORLD`
1931: Input Parameter:
1932: . sname - filename for the MPE logfile
1934: Level: advanced
1936: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogMPEBegin()`
1937: @*/
1938: PetscErrorCode PetscLogMPEDump(const char sname[])
1939: {
1940: PetscFunctionBegin;
1941: #if defined(PETSC_HAVE_MPE)
1942: if (PetscBeganMPE) {
1943: char name[PETSC_MAX_PATH_LEN];
1945: PetscCall(PetscInfo(0, "Finalizing MPE.\n"));
1946: if (sname) {
1947: PetscCall(PetscStrncpy(name, sname, sizeof(name)));
1948: } else {
1949: PetscCall(PetscGetProgramName(name, sizeof(name)));
1950: }
1951: PetscCall(MPE_Finish_log(name));
1952: } else {
1953: PetscCall(PetscInfo(0, "Not finalizing MPE (not started by PETSc).\n"));
1954: }
1955: #else
1956: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe");
1957: #endif
1958: PetscFunctionReturn(PETSC_SUCCESS);
1959: }
1961: /*@C
1962: PetscLogView - Prints a summary of the logging.
1964: Collective
1966: Input Parameter:
1967: . viewer - an ASCII viewer
1969: Options Database Keys:
1970: + -log_view [:filename] - Prints summary of log information
1971: . -log_view :filename.py:ascii_info_detail - Saves logging information from each process as a Python file
1972: . -log_view :filename.xml:ascii_xml - Saves a summary of the logging information in a nested format (see below for how to view it)
1973: . -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)
1974: . -log_view_memory - Also display memory usage in each event
1975: . -log_view_gpu_time - Also display time in each event for GPU kernels (Note this may slow the computation)
1976: . -log_all - Saves a file Log.rank for each MPI rank with details of each step of the computation
1977: - -log_trace [filename] - Displays a trace of what each process is doing
1979: Level: beginner
1981: Notes:
1982: It is possible to control the logging programmatically but we recommend using the options database approach whenever possible
1983: By default the summary is printed to stdout.
1985: Before calling this routine you must have called either PetscLogDefaultBegin() or PetscLogNestedBegin()
1987: If PETSc is configured with --with-logging=0 then this functionality is not available
1989: To view the nested XML format filename.xml first copy ${PETSC_DIR}/share/petsc/xml/performance_xml2html.xsl to the current
1990: directory then open filename.xml with your browser. Specific notes for certain browsers
1991: .vb
1992: Firefox and Internet explorer - simply open the file
1993: Google Chrome - you must start up Chrome with the option --allow-file-access-from-files
1994: Safari - see https://ccm.net/faq/36342-safari-how-to-enable-local-file-access
1995: .ve
1996: or one can use the package <http://xmlsoft.org/XSLT/xsltproc2.html> to translate the xml file to html and then open it with
1997: your browser.
1998: Alternatively, use the script ${PETSC_DIR}/lib/petsc/bin/petsc-performance-view to automatically open a new browser
1999: window and render the XML log file contents.
2001: The nested XML format was kindly donated by Koos Huijssen and Christiaan M. Klaij MARITIME RESEARCH INSTITUTE NETHERLANDS
2003: The Flame Graph output can be visualised using either the original Flame Graph script <https://github.com/brendangregg/FlameGraph>
2004: or using speedscope <https://www.speedscope.app>.
2005: Old XML profiles may be converted into this format using the script ${PETSC_DIR}/lib/petsc/bin/xml2flamegraph.py.
2007: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogDump()`
2008: @*/
2009: PetscErrorCode PetscLogView(PetscViewer viewer)
2010: {
2011: PetscBool isascii;
2012: PetscViewerFormat format;
2013: int stage;
2014: PetscLogState state;
2015: PetscIntStack temp_stack;
2016: PetscLogHandler handler;
2017: PetscBool is_empty;
2019: PetscFunctionBegin;
2020: PetscCall(PetscLogGetState(&state));
2021: /* Pop off any stages the user forgot to remove */
2022: PetscCall(PetscIntStackCreate(&temp_stack));
2023: PetscCall(PetscLogStateGetCurrentStage(state, &stage));
2024: while (stage >= 0) {
2025: PetscCall(PetscLogStagePop());
2026: PetscCall(PetscIntStackPush(temp_stack, stage));
2027: PetscCall(PetscLogStateGetCurrentStage(state, &stage));
2028: }
2029: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
2030: PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Currently can only view logging to ASCII");
2031: PetscCall(PetscViewerGetFormat(viewer, &format));
2032: if (format == PETSC_VIEWER_ASCII_XML || format == PETSC_VIEWER_ASCII_FLAMEGRAPH) {
2033: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERNESTED, &handler));
2034: PetscCall(PetscLogHandlerView(handler, viewer));
2035: } else {
2036: PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
2037: PetscCall(PetscLogHandlerView(handler, viewer));
2038: }
2039: PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
2040: while (!is_empty) {
2041: PetscCall(PetscIntStackPop(temp_stack, &stage));
2042: PetscCall(PetscLogStagePush(stage));
2043: PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
2044: }
2045: PetscCall(PetscIntStackDestroy(temp_stack));
2046: PetscFunctionReturn(PETSC_SUCCESS);
2047: }
2049: /*@C
2050: PetscLogViewFromOptions - Processes command line options to determine if/how a `PetscLog` is to be viewed.
2052: Collective on `PETSC_COMM_WORLD`
2054: Level: developer
2056: .seealso: [](ch_profiling), `PetscLogView()`
2057: @*/
2058: PetscErrorCode PetscLogViewFromOptions(void)
2059: {
2060: PetscInt n_max = PETSC_LOG_VIEW_FROM_OPTIONS_MAX;
2061: PetscViewer viewers[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2062: PetscViewerFormat formats[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2063: PetscBool flg;
2065: PetscFunctionBegin;
2066: PetscCall(PetscOptionsGetViewers(PETSC_COMM_WORLD, NULL, NULL, "-log_view", &n_max, viewers, formats, &flg));
2067: for (PetscInt i = 0; i < n_max; i++) {
2068: PetscCall(PetscViewerPushFormat(viewers[i], formats[i]));
2069: PetscCall(PetscLogView(viewers[i]));
2070: PetscCall(PetscViewerPopFormat(viewers[i]));
2071: PetscCall(PetscViewerDestroy(&(viewers[i])));
2072: }
2073: PetscFunctionReturn(PETSC_SUCCESS);
2074: }
2076: PETSC_INTERN PetscErrorCode PetscLogHandlerNestedSetThreshold(PetscLogHandler, PetscLogDouble, PetscLogDouble *);
2078: /*@
2079: PetscLogSetThreshold - Set the threshold time for logging the events; this is a percentage out of 100, so 1. means any event
2080: that takes 1 or more percent of the time.
2082: Logically Collective on `PETSC_COMM_WORLD`
2084: Input Parameter:
2085: . newThresh - the threshold to use
2087: Output Parameter:
2088: . oldThresh - the previously set threshold value
2090: Options Database Keys:
2091: . -log_view :filename.xml:ascii_xml - Prints an XML summary of flop and timing information to the file
2093: Example Usage:
2094: .vb
2095: PetscInitialize(...);
2096: PetscLogNestedBegin();
2097: PetscLogSetThreshold(0.1,&oldthresh);
2098: // ... code ...
2099: PetscLogView(viewer);
2100: PetscFinalize();
2101: .ve
2103: Level: advanced
2105: Note:
2106: This threshold is only used by the nested log handler
2108: .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`,
2109: `PetscLogNestedBegin()`
2110: @*/
2111: PetscErrorCode PetscLogSetThreshold(PetscLogDouble newThresh, PetscLogDouble *oldThresh)
2112: {
2113: PetscLogHandler handler;
2115: PetscFunctionBegin;
2116: PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERNESTED, &handler));
2117: PetscCall(PetscLogHandlerNestedSetThreshold(handler, newThresh, oldThresh));
2118: PetscFunctionReturn(PETSC_SUCCESS);
2119: }
2121: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
2122: /*@C
2123: PetscGetFlops - Returns the number of flops used on this processor
2124: since the program began.
2126: Not Collective
2128: Output Parameter:
2129: . flops - number of floating point operations
2131: Level: intermediate
2133: Notes:
2134: A global counter logs all PETSc flop counts. The user can use
2135: `PetscLogFlops()` to increment this counter to include flops for the
2136: application code.
2138: A separate counter `PetscLogGpuFlops()` logs the flops that occur on any GPU associated with this MPI rank
2140: .seealso: [](ch_profiling), `PetscLogGpuFlops()`, `PetscTime()`, `PetscLogFlops()`
2141: @*/
2142: PetscErrorCode PetscGetFlops(PetscLogDouble *flops)
2143: {
2144: PetscFunctionBegin;
2145: *flops = petsc_TotalFlops;
2146: PetscFunctionReturn(PETSC_SUCCESS);
2147: }
2149: /*@C
2150: PetscLogObjectState - Record information about an object with the default log handler
2152: Not Collective
2154: Input Parameters:
2155: + obj - the `PetscObject`
2156: . format - a printf-style format string
2157: - ... - printf arguments to format
2159: Level: developer
2161: .seealso: [](ch_profiling), `PetscLogObjectCreate()`, `PetscLogObjectDestroy()`, `PetscLogGetDefaultHandler()`
2162: @*/
2163: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
2164: {
2165: PetscFunctionBegin;
2166: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2167: PetscLogHandler h = PetscLogHandlers[i].handler;
2169: if (h) {
2170: va_list Argp;
2171: va_start(Argp, format);
2172: PetscCall(PetscLogHandlerLogObjectState_Internal(h, obj, format, Argp));
2173: va_end(Argp);
2174: }
2175: }
2176: PetscFunctionReturn(PETSC_SUCCESS);
2177: }
2179: /*MC
2180: PetscLogFlops - Adds floating point operations to the global counter.
2182: Synopsis:
2183: #include <petsclog.h>
2184: PetscErrorCode PetscLogFlops(PetscLogDouble f)
2186: Not Collective
2188: Input Parameter:
2189: . f - flop counter
2191: Example Usage:
2192: .vb
2193: PetscLogEvent USER_EVENT;
2195: PetscLogEventRegister("User event", 0, &USER_EVENT);
2196: PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
2197: [code segment to monitor]
2198: PetscLogFlops(user_flops)
2199: PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
2200: .ve
2202: Level: intermediate
2204: Note:
2205: A global counter logs all PETSc flop counts. The user can use PetscLogFlops() to increment
2206: this counter to include flops for the application code.
2208: .seealso: [](ch_profiling), `PetscLogGpuFlops()`, `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscGetFlops()`
2209: M*/
2211: /*MC
2212: PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice) to get accurate
2213: timings
2215: Synopsis:
2216: #include <petsclog.h>
2217: void PetscPreLoadBegin(PetscBool flag, char *name);
2219: Not Collective
2221: Input Parameters:
2222: + flag - `PETSC_TRUE` to run twice, `PETSC_FALSE` to run once, may be overridden with command
2223: line option `-preload true|false`
2224: - name - name of first stage (lines of code timed separately with `-log_view`) to be preloaded
2226: Example Usage:
2227: .vb
2228: PetscPreLoadBegin(PETSC_TRUE, "first stage");
2229: // lines of code
2230: PetscPreLoadStage("second stage");
2231: // lines of code
2232: PetscPreLoadEnd();
2233: .ve
2235: Level: intermediate
2237: Note:
2238: Only works in C/C++, not Fortran
2240: Flags available within the macro\:
2241: + PetscPreLoadingUsed - `PETSC_TRUE` if we are or have done preloading
2242: . PetscPreLoadingOn - `PETSC_TRUE` if it is CURRENTLY doing preload
2243: . PetscPreLoadIt - `0` for the first computation (with preloading turned off it is only
2244: `0`) `1` for the second
2245: - PetscPreLoadMax - number of times it will do the computation, only one when preloading is
2246: turned on
2248: The first two variables are available throughout the program, the second two only between the
2249: `PetscPreLoadBegin()` and `PetscPreLoadEnd()`
2251: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
2252: M*/
2254: /*MC
2255: PetscPreLoadEnd - End a segment of code that may be preloaded (run twice) to get accurate
2256: timings
2258: Synopsis:
2259: #include <petsclog.h>
2260: void PetscPreLoadEnd(void);
2262: Not Collective
2264: Example Usage:
2265: .vb
2266: PetscPreLoadBegin(PETSC_TRUE, "first stage");
2267: // lines of code
2268: PetscPreLoadStage("second stage");
2269: // lines of code
2270: PetscPreLoadEnd();
2271: .ve
2273: Level: intermediate
2275: Note:
2276: Only works in C/C++ not Fortran
2278: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadStage()`
2279: M*/
2281: /*MC
2282: PetscPreLoadStage - Start a new segment of code to be timed separately to get accurate timings
2284: Synopsis:
2285: #include <petsclog.h>
2286: void PetscPreLoadStage(char *name);
2288: Not Collective
2290: Example Usage:
2291: .vb
2292: PetscPreLoadBegin(PETSC_TRUE,"first stage");
2293: // lines of code
2294: PetscPreLoadStage("second stage");
2295: // lines of code
2296: PetscPreLoadEnd();
2297: .ve
2299: Level: intermediate
2301: Note:
2302: Only works in C/C++ not Fortran
2304: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`
2305: M*/
2307: #if PetscDefined(HAVE_DEVICE)
2308: #include <petsc/private/deviceimpl.h>
2310: /*@C
2311: PetscLogGpuTime - turn on the logging of GPU time for GPU kernels
2313: Options Database Key:
2314: . -log_view_gpu_time - provide the GPU times for all events in the `-log_view` output
2316: Level: advanced
2318: Notes:
2319: Turning on the timing of the GPU kernels can slow down the entire computation and should only
2320: be used when studying the performance of individual operations on GPU such as vector operations and
2321: matrix-vector operations.
2323: 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
2325: This routine should only be called once near the beginning of the program. Once it is started
2326: it cannot be turned off.
2328: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTimeBegin()`
2329: @*/
2330: PetscErrorCode PetscLogGpuTime(void)
2331: {
2332: PetscFunctionBegin;
2333: PetscCheck(petsc_gtime == 0.0, PETSC_COMM_SELF, PETSC_ERR_SUP, "GPU logging has already been turned on");
2334: PetscLogGpuTimeFlag = PETSC_TRUE;
2335: PetscFunctionReturn(PETSC_SUCCESS);
2336: }
2338: /*@C
2339: PetscLogGpuTimeBegin - Start timer for device
2341: Level: intermediate
2343: Notes:
2344: When CUDA or HIP is enabled, the timer is run on the GPU, it is a separate logging of time
2345: devoted to GPU computations (excluding kernel launch times).
2347: When CUDA or HIP is not available, the timer is run on the CPU, it is a separate logging of
2348: time devoted to GPU computations (including kernel launch times).
2350: There is no need to call WaitForCUDA() or WaitForHIP() between `PetscLogGpuTimeBegin()` and
2351: `PetscLogGpuTimeEnd()`
2353: This timer should NOT include times for data transfers between the GPU and CPU, nor setup
2354: actions such as allocating space.
2356: The regular logging captures the time for data transfers and any CPU activities during the
2357: event. It is used to compute the flop rate on the GPU as it is actively engaged in running a
2358: kernel.
2360: Developer Notes:
2361: The GPU event timer captures the execution time of all the kernels launched in the default
2362: stream by the CPU between `PetscLogGpuTimeBegin()` and `PetsLogGpuTimeEnd()`.
2364: `PetscLogGpuTimeBegin()` and `PetsLogGpuTimeEnd()` insert the begin and end events into the
2365: default stream (stream 0). The device will record a time stamp for the event when it reaches
2366: that event in the stream. The function xxxEventSynchronize() is called in
2367: `PetsLogGpuTimeEnd()` to block CPU execution, but not continued GPU execution, until the
2368: timer event is recorded.
2370: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTime()`
2371: @*/
2372: PetscErrorCode PetscLogGpuTimeBegin(void)
2373: {
2374: PetscBool isActive;
2376: PetscFunctionBegin;
2377: PetscCall(PetscLogEventBeginIsActive(&isActive));
2378: if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2379: if (PetscDefined(HAVE_DEVICE)) {
2380: PetscDeviceContext dctx;
2382: PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2383: PetscCall(PetscDeviceContextBeginTimer_Internal(dctx));
2384: } else {
2385: PetscCall(PetscTimeSubtract(&petsc_gtime));
2386: }
2387: PetscFunctionReturn(PETSC_SUCCESS);
2388: }
2390: /*@C
2391: PetscLogGpuTimeEnd - Stop timer for device
2393: Level: intermediate
2395: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeBegin()`
2396: @*/
2397: PetscErrorCode PetscLogGpuTimeEnd(void)
2398: {
2399: PetscBool isActive;
2401: PetscFunctionBegin;
2402: PetscCall(PetscLogEventEndIsActive(&isActive));
2403: if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2404: if (PetscDefined(HAVE_DEVICE)) {
2405: PetscDeviceContext dctx;
2406: PetscLogDouble elapsed;
2408: PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2409: PetscCall(PetscDeviceContextEndTimer_Internal(dctx, &elapsed));
2410: petsc_gtime += (elapsed / 1000.0);
2411: } else {
2412: PetscCall(PetscTimeAdd(&petsc_gtime));
2413: }
2414: PetscFunctionReturn(PETSC_SUCCESS);
2415: }
2417: #endif /* end of PETSC_HAVE_DEVICE */
2419: #endif /* PETSC_USE_LOG*/
2421: /* -- Utility functions for logging from Fortran -- */
2423: PETSC_EXTERN PetscErrorCode PetscASend(int count, int datatype)
2424: {
2425: PetscFunctionBegin;
2426: #if PetscDefined(USE_LOG)
2427: PetscCall(PetscAddLogDouble(&petsc_send_ct, &petsc_send_ct_th, 1));
2428: #if !defined(MPIUNI_H) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO)
2429: PetscCall(PetscMPITypeSize(count, MPI_Type_f2c((MPI_Fint)datatype), &petsc_send_len, &petsc_send_len_th));
2430: #endif
2431: #endif
2432: PetscFunctionReturn(PETSC_SUCCESS);
2433: }
2435: PETSC_EXTERN PetscErrorCode PetscARecv(int count, int datatype)
2436: {
2437: PetscFunctionBegin;
2438: #if PetscDefined(USE_LOG)
2439: PetscCall(PetscAddLogDouble(&petsc_recv_ct, &petsc_recv_ct_th, 1));
2440: #if !defined(MPIUNI_H) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO)
2441: PetscCall(PetscMPITypeSize(count, MPI_Type_f2c((MPI_Fint)datatype), &petsc_recv_len, &petsc_recv_len_th));
2442: #endif
2443: #endif
2444: PetscFunctionReturn(PETSC_SUCCESS);
2445: }
2447: PETSC_EXTERN PetscErrorCode PetscAReduce(void)
2448: {
2449: PetscFunctionBegin;
2450: if (PetscDefined(USE_LOG)) PetscCall(PetscAddLogDouble(&petsc_allreduce_ct, &petsc_allreduce_ct_th, 1));
2451: PetscFunctionReturn(PETSC_SUCCESS);
2452: }
2454: PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2455: PetscClassId PETSC_OBJECT_CLASSID = 0;
2457: static PetscBool PetscLogInitializeCalled = PETSC_FALSE;
2459: PETSC_INTERN PetscErrorCode PetscLogInitialize(void)
2460: {
2461: int stage;
2463: PetscFunctionBegin;
2464: if (PetscLogInitializeCalled) PetscFunctionReturn(PETSC_SUCCESS);
2465: PetscLogInitializeCalled = PETSC_TRUE;
2466: if (PetscDefined(USE_LOG)) {
2467: /* Setup default logging structures */
2468: PetscCall(PetscLogStateCreate(&petsc_log_state));
2469: for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2470: if (PetscLogHandlers[i].handler) PetscCall(PetscLogHandlerSetState(PetscLogHandlers[i].handler, petsc_log_state));
2471: }
2472: PetscCall(PetscLogStateStageRegister(petsc_log_state, "Main Stage", &stage));
2473: PetscCall(PetscSpinlockCreate(&PetscLogSpinLock));
2474: #if defined(PETSC_HAVE_THREADSAFETY)
2475: petsc_log_tid = 0;
2476: petsc_log_gid = 0;
2477: #endif
2479: /* All processors sync here for more consistent logging */
2480: PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
2481: PetscCall(PetscTime(&petsc_BaseTime));
2482: PetscCall(PetscLogStagePush(stage));
2483: }
2484: PetscFunctionReturn(PETSC_SUCCESS);
2485: }
2487: PETSC_INTERN PetscErrorCode PetscLogFinalize(void)
2488: {
2489: PetscFunctionBegin;
2490: if (PetscDefined(USE_LOG)) {
2491: /* Resetting phase */
2492: // pop remaining stages
2493: if (petsc_log_state) {
2494: while (petsc_log_state->current_stage >= 0) { PetscCall(PetscLogStagePop()); }
2495: }
2496: for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) PetscCall(PetscLogHandlerDestroy(&PetscLogHandlers[i].handler));
2497: PetscCall(PetscArrayzero(PetscLogHandlers, PETSC_LOG_HANDLER_MAX));
2498: PetscCall(PetscLogStateDestroy(&petsc_log_state));
2500: petsc_TotalFlops = 0.0;
2501: petsc_BaseTime = 0.0;
2502: petsc_TotalFlops = 0.0;
2503: petsc_send_ct = 0.0;
2504: petsc_recv_ct = 0.0;
2505: petsc_send_len = 0.0;
2506: petsc_recv_len = 0.0;
2507: petsc_isend_ct = 0.0;
2508: petsc_irecv_ct = 0.0;
2509: petsc_isend_len = 0.0;
2510: petsc_irecv_len = 0.0;
2511: petsc_wait_ct = 0.0;
2512: petsc_wait_any_ct = 0.0;
2513: petsc_wait_all_ct = 0.0;
2514: petsc_sum_of_waits_ct = 0.0;
2515: petsc_allreduce_ct = 0.0;
2516: petsc_gather_ct = 0.0;
2517: petsc_scatter_ct = 0.0;
2518: petsc_TotalFlops_th = 0.0;
2519: petsc_send_ct_th = 0.0;
2520: petsc_recv_ct_th = 0.0;
2521: petsc_send_len_th = 0.0;
2522: petsc_recv_len_th = 0.0;
2523: petsc_isend_ct_th = 0.0;
2524: petsc_irecv_ct_th = 0.0;
2525: petsc_isend_len_th = 0.0;
2526: petsc_irecv_len_th = 0.0;
2527: petsc_wait_ct_th = 0.0;
2528: petsc_wait_any_ct_th = 0.0;
2529: petsc_wait_all_ct_th = 0.0;
2530: petsc_sum_of_waits_ct_th = 0.0;
2531: petsc_allreduce_ct_th = 0.0;
2532: petsc_gather_ct_th = 0.0;
2533: petsc_scatter_ct_th = 0.0;
2535: petsc_ctog_ct = 0.0;
2536: petsc_gtoc_ct = 0.0;
2537: petsc_ctog_sz = 0.0;
2538: petsc_gtoc_sz = 0.0;
2539: petsc_gflops = 0.0;
2540: petsc_gtime = 0.0;
2541: petsc_ctog_ct_th = 0.0;
2542: petsc_gtoc_ct_th = 0.0;
2543: petsc_ctog_sz_th = 0.0;
2544: petsc_gtoc_sz_th = 0.0;
2545: petsc_gflops_th = 0.0;
2546: petsc_gtime_th = 0.0;
2547: }
2548: PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2549: PETSC_OBJECT_CLASSID = 0;
2550: PetscLogInitializeCalled = PETSC_FALSE;
2551: PetscFunctionReturn(PETSC_SUCCESS);
2552: }
2554: /*@C
2555: PetscClassIdRegister - Registers a new class name for objects and logging operations in an application code.
2557: Not Collective
2559: Input Parameter:
2560: . name - The class name
2562: Output Parameter:
2563: . oclass - The class id or classid
2565: Level: developer
2567: .seealso: [](ch_profiling), `PetscLogEventRegister()`
2568: @*/
2569: PetscErrorCode PetscClassIdRegister(const char name[], PetscClassId *oclass)
2570: {
2571: PetscFunctionBegin;
2572: *oclass = ++PETSC_LARGEST_CLASSID;
2573: #if defined(PETSC_USE_LOG)
2574: {
2575: PetscLogState state;
2576: PetscLogClass logclass;
2578: PetscCall(PetscLogGetState(&state));
2579: if (state) PetscCall(PetscLogStateClassRegister(state, name, *oclass, &logclass));
2580: }
2581: #endif
2582: PetscFunctionReturn(PETSC_SUCCESS);
2583: }