xref: /petsc/src/sys/logging/handler/impls/perfstubs/logperfstubs.c (revision ccf0b5c1967b48da6c1c972ce7215de9b66fafa5)
1*ccf0b5c1SToby Isaac #include <petsc/private/logimpl.h> /*I "petscsys.h" I*/
2*ccf0b5c1SToby Isaac #include <petsc/private/loghandlerimpl.h>
3*ccf0b5c1SToby Isaac #include <../src/sys/perfstubs/timer.h>
4*ccf0b5c1SToby Isaac 
5*ccf0b5c1SToby Isaac typedef struct _n_PetscEventPS {
6*ccf0b5c1SToby Isaac   void *timer;
7*ccf0b5c1SToby Isaac   int   depth;
8*ccf0b5c1SToby Isaac } PetscEventPS;
9*ccf0b5c1SToby Isaac 
10*ccf0b5c1SToby Isaac PETSC_LOG_RESIZABLE_ARRAY(PSArray, PetscEventPS, void *, NULL, NULL, NULL)
11*ccf0b5c1SToby Isaac 
12*ccf0b5c1SToby Isaac typedef struct _n_PetscLogHandler_Perfstubs *PetscLogHandler_Perfstubs;
13*ccf0b5c1SToby Isaac 
14*ccf0b5c1SToby Isaac struct _n_PetscLogHandler_Perfstubs {
15*ccf0b5c1SToby Isaac   PetscLogPSArray events;
16*ccf0b5c1SToby Isaac   PetscLogPSArray stages;
17*ccf0b5c1SToby Isaac   PetscBool       started_perfstubs;
18*ccf0b5c1SToby Isaac };
19*ccf0b5c1SToby Isaac 
20*ccf0b5c1SToby Isaac static PetscErrorCode PetscLogHandlerContextCreate_Perfstubs(PetscLogHandler_Perfstubs *ps_p)
21*ccf0b5c1SToby Isaac {
22*ccf0b5c1SToby Isaac   PetscLogHandler_Perfstubs ps;
23*ccf0b5c1SToby Isaac 
24*ccf0b5c1SToby Isaac   PetscFunctionBegin;
25*ccf0b5c1SToby Isaac   PetscCall(PetscNew(ps_p));
26*ccf0b5c1SToby Isaac   ps = *ps_p;
27*ccf0b5c1SToby Isaac   PetscCall(PetscLogPSArrayCreate(128, &ps->events));
28*ccf0b5c1SToby Isaac   PetscCall(PetscLogPSArrayCreate(8, &ps->stages));
29*ccf0b5c1SToby Isaac   PetscFunctionReturn(PETSC_SUCCESS);
30*ccf0b5c1SToby Isaac }
31*ccf0b5c1SToby Isaac 
32*ccf0b5c1SToby Isaac static PetscErrorCode PetscLogHandlerDestroy_Perfstubs(PetscLogHandler h)
33*ccf0b5c1SToby Isaac {
34*ccf0b5c1SToby Isaac   PetscInt                  num_events, num_stages;
35*ccf0b5c1SToby Isaac   PetscLogHandler_Perfstubs ps = (PetscLogHandler_Perfstubs)h->data;
36*ccf0b5c1SToby Isaac 
37*ccf0b5c1SToby Isaac   PetscFunctionBegin;
38*ccf0b5c1SToby Isaac   PetscCall(PetscLogPSArrayGetSize(ps->events, &num_events, NULL));
39*ccf0b5c1SToby Isaac   for (PetscInt i = 0; i < num_events; i++) {
40*ccf0b5c1SToby Isaac     PetscEventPS event = {NULL, 0};
41*ccf0b5c1SToby Isaac 
42*ccf0b5c1SToby Isaac     PetscCall(PetscLogPSArrayGet(ps->events, i, &event));
43*ccf0b5c1SToby Isaac     PetscStackCallExternalVoid("ps_timer_destroy_", ps_timer_destroy_(event.timer));
44*ccf0b5c1SToby Isaac   }
45*ccf0b5c1SToby Isaac   PetscCall(PetscLogPSArrayDestroy(&ps->events));
46*ccf0b5c1SToby Isaac 
47*ccf0b5c1SToby Isaac   PetscCall(PetscLogPSArrayGetSize(ps->stages, &num_stages, NULL));
48*ccf0b5c1SToby Isaac   for (PetscInt i = 0; i < num_stages; i++) {
49*ccf0b5c1SToby Isaac     PetscEventPS stage = {NULL, 0};
50*ccf0b5c1SToby Isaac 
51*ccf0b5c1SToby Isaac     PetscCall(PetscLogPSArrayGet(ps->stages, i, &stage));
52*ccf0b5c1SToby Isaac     PetscStackCallExternalVoid("ps_timer_destroy_", ps_timer_destroy_(stage.timer));
53*ccf0b5c1SToby Isaac   }
54*ccf0b5c1SToby Isaac   PetscCall(PetscLogPSArrayDestroy(&ps->stages));
55*ccf0b5c1SToby Isaac 
56*ccf0b5c1SToby Isaac   if (ps->started_perfstubs) PetscStackCallExternalVoid("ps_finalize_", ps_finalize_());
57*ccf0b5c1SToby Isaac   PetscCall(PetscFree(ps));
58*ccf0b5c1SToby Isaac   PetscFunctionReturn(PETSC_SUCCESS);
59*ccf0b5c1SToby Isaac }
60*ccf0b5c1SToby Isaac 
61*ccf0b5c1SToby Isaac static PetscErrorCode PetscLogHandlerPSUpdateEvents(PetscLogHandler h)
62*ccf0b5c1SToby Isaac {
63*ccf0b5c1SToby Isaac   PetscLogHandler_Perfstubs ps = (PetscLogHandler_Perfstubs)h->data;
64*ccf0b5c1SToby Isaac   PetscLogState             state;
65*ccf0b5c1SToby Isaac   PetscInt                  num_events, num_events_old;
66*ccf0b5c1SToby Isaac 
67*ccf0b5c1SToby Isaac   PetscFunctionBegin;
68*ccf0b5c1SToby Isaac   PetscCall(PetscLogHandlerGetState(h, &state));
69*ccf0b5c1SToby Isaac   PetscCall(PetscLogStateGetNumEvents(state, &num_events));
70*ccf0b5c1SToby Isaac   PetscCall(PetscLogPSArrayGetSize(ps->events, &num_events_old, NULL));
71*ccf0b5c1SToby Isaac   for (PetscInt i = num_events_old; i < num_events; i++) {
72*ccf0b5c1SToby Isaac     PetscLogEventInfo event_info = {NULL, -1, PETSC_FALSE};
73*ccf0b5c1SToby Isaac     PetscEventPS      ps_event   = {NULL, 0};
74*ccf0b5c1SToby Isaac 
75*ccf0b5c1SToby Isaac     PetscCall(PetscLogStateEventGetInfo(state, (PetscLogEvent)i, &event_info));
76*ccf0b5c1SToby Isaac     PetscStackCallExternalVoid("ps_timer_create_", ps_event.timer = ps_timer_create_(event_info.name));
77*ccf0b5c1SToby Isaac     ps_event.depth = 0;
78*ccf0b5c1SToby Isaac     PetscCall(PetscLogPSArrayPush(ps->events, ps_event));
79*ccf0b5c1SToby Isaac   }
80*ccf0b5c1SToby Isaac   PetscFunctionReturn(PETSC_SUCCESS);
81*ccf0b5c1SToby Isaac }
82*ccf0b5c1SToby Isaac 
83*ccf0b5c1SToby Isaac static PetscErrorCode PetscLogHandlerPSUpdateStages(PetscLogHandler h)
84*ccf0b5c1SToby Isaac {
85*ccf0b5c1SToby Isaac   PetscLogHandler_Perfstubs ps = (PetscLogHandler_Perfstubs)h->data;
86*ccf0b5c1SToby Isaac   PetscLogState             state;
87*ccf0b5c1SToby Isaac   PetscInt                  num_stages, num_stages_old;
88*ccf0b5c1SToby Isaac 
89*ccf0b5c1SToby Isaac   PetscFunctionBegin;
90*ccf0b5c1SToby Isaac   PetscCall(PetscLogHandlerGetState(h, &state));
91*ccf0b5c1SToby Isaac   PetscCall(PetscLogStateGetNumStages(state, &num_stages));
92*ccf0b5c1SToby Isaac   PetscCall(PetscLogPSArrayGetSize(ps->stages, &num_stages_old, NULL));
93*ccf0b5c1SToby Isaac   for (PetscInt i = num_stages_old; i < num_stages; i++) {
94*ccf0b5c1SToby Isaac     PetscLogStageInfo stage_info = {NULL};
95*ccf0b5c1SToby Isaac     PetscEventPS      ps_stage   = {NULL, 0};
96*ccf0b5c1SToby Isaac 
97*ccf0b5c1SToby Isaac     PetscCall(PetscLogStateStageGetInfo(state, (PetscLogStage)i, &stage_info));
98*ccf0b5c1SToby Isaac     PetscStackCallExternalVoid("ps_timer_create_", ps_stage.timer = ps_timer_create_(stage_info.name));
99*ccf0b5c1SToby Isaac     ps_stage.depth = 0;
100*ccf0b5c1SToby Isaac     PetscCall(PetscLogPSArrayPush(ps->stages, ps_stage));
101*ccf0b5c1SToby Isaac   }
102*ccf0b5c1SToby Isaac   PetscFunctionReturn(PETSC_SUCCESS);
103*ccf0b5c1SToby Isaac }
104*ccf0b5c1SToby Isaac 
105*ccf0b5c1SToby Isaac static PetscErrorCode PetscLogHandlerEventBegin_Perfstubs(PetscLogHandler handler, PetscLogEvent event, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
106*ccf0b5c1SToby Isaac {
107*ccf0b5c1SToby Isaac   PetscLogHandler_Perfstubs ps       = (PetscLogHandler_Perfstubs)handler->data;
108*ccf0b5c1SToby Isaac   PetscEventPS              ps_event = {NULL, 0};
109*ccf0b5c1SToby Isaac 
110*ccf0b5c1SToby Isaac   PetscFunctionBegin;
111*ccf0b5c1SToby Isaac   if (event >= ps->events->num_entries) PetscCall(PetscLogHandlerPSUpdateEvents(handler));
112*ccf0b5c1SToby Isaac   PetscCall(PetscLogPSArrayGet(ps->events, event, &ps_event));
113*ccf0b5c1SToby Isaac   ps_event.depth++;
114*ccf0b5c1SToby Isaac   PetscCall(PetscLogPSArraySet(ps->events, event, ps_event));
115*ccf0b5c1SToby Isaac   if (ps_event.depth == 1 && ps_event.timer != NULL) PetscStackCallExternalVoid("ps_timer_start_", ps_timer_start_(ps_event.timer));
116*ccf0b5c1SToby Isaac   PetscFunctionReturn(PETSC_SUCCESS);
117*ccf0b5c1SToby Isaac }
118*ccf0b5c1SToby Isaac 
119*ccf0b5c1SToby Isaac static PetscErrorCode PetscLogHandlerEventEnd_Perfstubs(PetscLogHandler handler, PetscLogEvent event, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
120*ccf0b5c1SToby Isaac {
121*ccf0b5c1SToby Isaac   PetscLogHandler_Perfstubs ps       = (PetscLogHandler_Perfstubs)handler->data;
122*ccf0b5c1SToby Isaac   PetscEventPS              ps_event = {NULL, 0};
123*ccf0b5c1SToby Isaac 
124*ccf0b5c1SToby Isaac   PetscFunctionBegin;
125*ccf0b5c1SToby Isaac   if (event >= ps->events->num_entries) PetscCall(PetscLogHandlerPSUpdateEvents(handler));
126*ccf0b5c1SToby Isaac   PetscCall(PetscLogPSArrayGet(ps->events, event, &ps_event));
127*ccf0b5c1SToby Isaac   ps_event.depth--;
128*ccf0b5c1SToby Isaac   PetscCall(PetscLogPSArraySet(ps->events, event, ps_event));
129*ccf0b5c1SToby Isaac   if (ps_event.depth == 0 && ps_event.timer != NULL) PetscStackCallExternalVoid("ps_timer_stop_", ps_timer_stop_(ps_event.timer));
130*ccf0b5c1SToby Isaac   PetscFunctionReturn(PETSC_SUCCESS);
131*ccf0b5c1SToby Isaac }
132*ccf0b5c1SToby Isaac 
133*ccf0b5c1SToby Isaac static PetscErrorCode PetscLogHandlerStagePush_Perfstubs(PetscLogHandler handler, PetscLogStage stage)
134*ccf0b5c1SToby Isaac {
135*ccf0b5c1SToby Isaac   PetscLogHandler_Perfstubs ps       = (PetscLogHandler_Perfstubs)handler->data;
136*ccf0b5c1SToby Isaac   PetscEventPS              ps_event = {NULL, 0};
137*ccf0b5c1SToby Isaac 
138*ccf0b5c1SToby Isaac   PetscFunctionBegin;
139*ccf0b5c1SToby Isaac   if (stage >= ps->stages->num_entries) PetscCall(PetscLogHandlerPSUpdateStages(handler));
140*ccf0b5c1SToby Isaac   PetscCall(PetscLogPSArrayGet(ps->stages, stage, &ps_event));
141*ccf0b5c1SToby Isaac   if (ps_event.timer != NULL) PetscStackCallExternalVoid("ps_timer_start_", ps_timer_start_(ps_event.timer));
142*ccf0b5c1SToby Isaac   PetscFunctionReturn(PETSC_SUCCESS);
143*ccf0b5c1SToby Isaac }
144*ccf0b5c1SToby Isaac 
145*ccf0b5c1SToby Isaac static PetscErrorCode PetscLogHandlerStagePop_Perfstubs(PetscLogHandler handler, PetscLogStage stage)
146*ccf0b5c1SToby Isaac {
147*ccf0b5c1SToby Isaac   PetscLogHandler_Perfstubs ps       = (PetscLogHandler_Perfstubs)handler->data;
148*ccf0b5c1SToby Isaac   PetscEventPS              ps_event = {NULL, 0};
149*ccf0b5c1SToby Isaac 
150*ccf0b5c1SToby Isaac   PetscFunctionBegin;
151*ccf0b5c1SToby Isaac   if (stage >= ps->stages->num_entries) PetscCall(PetscLogHandlerPSUpdateStages(handler));
152*ccf0b5c1SToby Isaac   PetscCall(PetscLogPSArrayGet(ps->stages, stage, &ps_event));
153*ccf0b5c1SToby Isaac   if (ps_event.timer != NULL) PetscStackCallExternalVoid("ps_timer_stop_", ps_timer_stop_(ps_event.timer));
154*ccf0b5c1SToby Isaac   PetscFunctionReturn(PETSC_SUCCESS);
155*ccf0b5c1SToby Isaac }
156*ccf0b5c1SToby Isaac 
157*ccf0b5c1SToby Isaac /*MC
158*ccf0b5c1SToby Isaac   PETSC_LOG_HANDLER_PERFSTUBS - PETSC_LOG_HANDLER_PERFSTUBS = "perfstubs" -  A
159*ccf0b5c1SToby Isaac   `PetscLogHandler` that collects data for the PerfStubs/TAU instrumentation
160*ccf0b5c1SToby Isaac   library.
161*ccf0b5c1SToby Isaac 
162*ccf0b5c1SToby Isaac   Level: developer
163*ccf0b5c1SToby Isaac 
164*ccf0b5c1SToby Isaac .seealso: [](ch_profiling), `PetscLogHandler`
165*ccf0b5c1SToby Isaac M*/
166*ccf0b5c1SToby Isaac 
167*ccf0b5c1SToby Isaac PETSC_INTERN PetscErrorCode PetscLogHandlerCreate_Perfstubs(PetscLogHandler handler)
168*ccf0b5c1SToby Isaac {
169*ccf0b5c1SToby Isaac   PetscBool                 started_perfstubs;
170*ccf0b5c1SToby Isaac   PetscLogHandler_Perfstubs lps;
171*ccf0b5c1SToby Isaac 
172*ccf0b5c1SToby Isaac   PetscFunctionBegin;
173*ccf0b5c1SToby Isaac   if (perfstubs_initialized == PERFSTUBS_UNKNOWN) {
174*ccf0b5c1SToby Isaac     PetscStackCallExternalVoid("ps_initialize_", ps_initialize_());
175*ccf0b5c1SToby Isaac     started_perfstubs = PETSC_TRUE;
176*ccf0b5c1SToby Isaac   } else {
177*ccf0b5c1SToby Isaac     started_perfstubs = PETSC_FALSE;
178*ccf0b5c1SToby Isaac   }
179*ccf0b5c1SToby Isaac   PetscCheck(perfstubs_initialized == PERFSTUBS_SUCCESS, PetscObjectComm((PetscObject)handler), PETSC_ERR_LIB, "perfstubs could not be initialized");
180*ccf0b5c1SToby Isaac   PetscCall(PetscLogHandlerContextCreate_Perfstubs(&lps));
181*ccf0b5c1SToby Isaac   lps->started_perfstubs   = started_perfstubs;
182*ccf0b5c1SToby Isaac   handler->data            = (void *)lps;
183*ccf0b5c1SToby Isaac   handler->ops->destroy    = PetscLogHandlerDestroy_Perfstubs;
184*ccf0b5c1SToby Isaac   handler->ops->eventbegin = PetscLogHandlerEventBegin_Perfstubs;
185*ccf0b5c1SToby Isaac   handler->ops->eventend   = PetscLogHandlerEventEnd_Perfstubs;
186*ccf0b5c1SToby Isaac   handler->ops->stagepush  = PetscLogHandlerStagePush_Perfstubs;
187*ccf0b5c1SToby Isaac   handler->ops->stagepop   = PetscLogHandlerStagePop_Perfstubs;
188*ccf0b5c1SToby Isaac   PetscFunctionReturn(PETSC_SUCCESS);
189*ccf0b5c1SToby Isaac }
190