1 #include <petsc/private/logimpl.h> /*I "petscsys.h" I*/
2 #include <petsc/private/loghandlerimpl.h>
3
4 typedef struct _n_PetscLogHandler_Trace *PetscLogHandler_Trace;
5 struct _n_PetscLogHandler_Trace {
6 FILE *petsc_tracefile;
7 size_t petsc_tracelevel;
8 char petsc_tracespace[128];
9 PetscLogDouble petsc_tracetime;
10 };
11
PetscLogHandlerEventBegin_Trace(PetscLogHandler h,PetscLogEvent event,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4)12 static PetscErrorCode PetscLogHandlerEventBegin_Trace(PetscLogHandler h, PetscLogEvent event, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
13 {
14 PetscLogHandler_Trace tr = (PetscLogHandler_Trace)h->data;
15 PetscLogEventInfo event_info;
16 PetscLogDouble cur_time;
17 PetscMPIInt rank;
18 PetscLogState state;
19 PetscLogStage stage;
20
21 PetscFunctionBegin;
22 if (!tr->petsc_tracetime) PetscCall(PetscTime(&tr->petsc_tracetime));
23 tr->petsc_tracelevel++;
24 PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)h), &rank));
25 PetscCall(PetscLogHandlerGetState(h, &state));
26 PetscCall(PetscLogStateGetCurrentStage(state, &stage));
27 /* Log performance info */
28 PetscCall(PetscTime(&cur_time));
29 PetscCall(PetscLogStateEventGetInfo(state, event, &event_info));
30 PetscCall(PetscFPrintf(PETSC_COMM_SELF, tr->petsc_tracefile, "%s[%d] %g Event begin: %s\n", tr->petsc_tracespace, rank, cur_time - tr->petsc_tracetime, event_info.name));
31 for (size_t i = 0; i < PetscMin(sizeof(tr->petsc_tracespace), 2 * tr->petsc_tracelevel); i++) tr->petsc_tracespace[i] = ' ';
32 tr->petsc_tracespace[PetscMin(127, 2 * tr->petsc_tracelevel)] = '\0';
33 PetscCall(PetscFFlush(tr->petsc_tracefile));
34 PetscFunctionReturn(PETSC_SUCCESS);
35 }
36
PetscLogHandlerEventEnd_Trace(PetscLogHandler h,PetscLogEvent event,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4)37 static PetscErrorCode PetscLogHandlerEventEnd_Trace(PetscLogHandler h, PetscLogEvent event, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
38 {
39 PetscLogHandler_Trace tr = (PetscLogHandler_Trace)h->data;
40 PetscLogEventInfo event_info;
41 PetscLogDouble cur_time;
42 PetscLogState state;
43 PetscLogStage stage;
44 PetscMPIInt rank;
45
46 PetscFunctionBegin;
47 tr->petsc_tracelevel--;
48 PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)h), &rank));
49 PetscCall(PetscLogHandlerGetState(h, &state));
50 PetscCall(PetscLogStateGetCurrentStage(state, &stage));
51 /* Log performance info */
52 for (size_t i = 0; i < PetscMin(sizeof(tr->petsc_tracespace), 2 * tr->petsc_tracelevel); i++) tr->petsc_tracespace[i] = ' ';
53 tr->petsc_tracespace[PetscMin(127, 2 * tr->petsc_tracelevel)] = '\0';
54 PetscCall(PetscTime(&cur_time));
55 PetscCall(PetscLogStateEventGetInfo(state, event, &event_info));
56 PetscCall(PetscFPrintf(PETSC_COMM_SELF, tr->petsc_tracefile, "%s[%d] %g Event end: %s\n", tr->petsc_tracespace, rank, cur_time - tr->petsc_tracetime, event_info.name));
57 PetscCall(PetscFFlush(tr->petsc_tracefile));
58 PetscFunctionReturn(PETSC_SUCCESS);
59 }
60
PetscLogHandlerDestroy_Trace(PetscLogHandler h)61 static PetscErrorCode PetscLogHandlerDestroy_Trace(PetscLogHandler h)
62 {
63 PetscFunctionBegin;
64 PetscCall(PetscFree(h->data));
65 PetscFunctionReturn(PETSC_SUCCESS);
66 }
67
68 /*MC
69 PETSCLOGHANDLERTRACE - PETSCLOGHANDLERTRACE = "trace" - A
70 `PetscLogHandler` that collects data for PETSc's tracing log viewer.
71 A log handler of this type is created and started by `PetscLogTraceBegin()`.
72
73 Level: developer
74
75 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerCreateTrace()`
76 M*/
77
PetscLogHandlerCreate_Trace(PetscLogHandler handler)78 PETSC_INTERN PetscErrorCode PetscLogHandlerCreate_Trace(PetscLogHandler handler)
79 {
80 PetscLogHandler_Trace tr;
81
82 PetscFunctionBegin;
83 PetscCall(PetscNew(&tr));
84 handler->data = (void *)tr;
85 handler->ops->eventbegin = PetscLogHandlerEventBegin_Trace;
86 handler->ops->eventend = PetscLogHandlerEventEnd_Trace;
87 handler->ops->destroy = PetscLogHandlerDestroy_Trace;
88 PetscFunctionReturn(PETSC_SUCCESS);
89 }
90
91 /*@C
92 PetscLogHandlerCreateTrace - Create a logger that traces events and stages to a given file descriptor
93
94 Collective, No Fortran Support
95
96 Input Parameters:
97 + comm - an MPI communicator
98 - file - a file descriptor
99
100 Output Parameters:
101 . handler - a `PetscLogHandler of type `PETSCLOGHANDLERTRACE`
102
103 Level: developer
104
105 Notes:
106 Most users can just use `PetscLogTraceBegin()` to create and immediately start (`PetscLogHandlerStart()`) a tracing log handler
107
108 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerTraceBegin()`
109 @*/
PetscLogHandlerCreateTrace(MPI_Comm comm,FILE * file,PetscLogHandler * handler)110 PetscErrorCode PetscLogHandlerCreateTrace(MPI_Comm comm, FILE *file, PetscLogHandler *handler)
111 {
112 PetscLogHandler h;
113 PetscLogHandler_Trace tr;
114
115 PetscFunctionBegin;
116 PetscCall(PetscLogHandlerCreate(comm, handler));
117 h = *handler;
118 PetscCall(PetscLogHandlerSetType(h, PETSCLOGHANDLERTRACE));
119 tr = (PetscLogHandler_Trace)h->data;
120 tr->petsc_tracefile = file;
121 PetscFunctionReturn(PETSC_SUCCESS);
122 }
123