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