xref: /petsc/src/sys/logging/handler/impls/trace/logtrace.c (revision 4ad8454beace47809662cdae21ee081016eaa39a)
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 
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 
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 
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 
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
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 @*/
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