xref: /petsc/src/sys/logging/handler/interface/loghandler.c (revision 856bee69f0e0908e75ff837867b1777dfb1ced96)
1 
2 #include <petscviewer.h>
3 #include <petsc/private/logimpl.h> /*I "petscsys.h" I*/
4 #include <petsc/private/loghandlerimpl.h>
5 
6 /*@
7   PetscLogHandlerCreate - Create a log handler for profiling events and stages.  PETSc
8   provides several implementations of `PetscLogHandler` that interface to different ways to
9   summarize or visualize profiling data: see `PetscLogHandlerType` for a list.
10 
11   Collective
12 
13   Input Parameter:
14 . comm - the communicator for synchronizing and viewing events with this handler
15 
16   Output Parameter:
17 . handler - the `PetscLogHandler`
18 
19   Level: developer
20 
21   Notes:
22   This does not put the handler in use in PETSc's global logging system: use `PetscLogHandlerStart()` after creation.
23 
24   See `PetscLogHandler` for example usage.
25 
26 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerSetType()`, `PetscLogHandlerStart()`, `PetscLogHandlerStop()`
27 @*/
28 PetscErrorCode PetscLogHandlerCreate(MPI_Comm comm, PetscLogHandler *handler)
29 {
30   PetscLogHandler h;
31 
32   PetscFunctionBegin;
33   *handler = NULL;
34   PetscCall(PetscLogHandlerPackageInitialize());
35   // We do not use PetscHeaderCreate() here because having PetscLogObjectCreate() run for PetscLogHandler would be very fragile
36   PetscCall(PetscNew(&h));
37   PetscCall(PetscHeaderCreate_Private((PetscObject)(h), PETSCLOGHANDLER_CLASSID, "PetscLogHandler", "Profile events, stages, and objects", "Profiling", comm, (PetscObjectDestroyFunction)PetscLogHandlerDestroy, (PetscObjectViewFunction)PetscLogHandlerView));
38   *handler = h;
39   PetscFunctionReturn(PETSC_SUCCESS);
40 }
41 
42 /*@
43   PetscLogHandlerDestroy - Destroy a `PetscLogHandler`
44 
45   Logically collective
46 
47   Input Parameter:
48 . handler - handler to be destroyed
49 
50   Level: developer
51 
52 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerCreate()`
53 @*/
54 PetscErrorCode PetscLogHandlerDestroy(PetscLogHandler *handler)
55 {
56   PetscLogHandler h;
57 
58   PetscFunctionBegin;
59   if (!*handler) PetscFunctionReturn(PETSC_SUCCESS);
60   h        = *handler;
61   *handler = NULL;
62   PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1);
63   if (--((PetscObject)h)->refct > 0) PetscFunctionReturn(PETSC_SUCCESS);
64   PetscTryTypeMethod(h, destroy);
65   PetscCall(PetscLogStateDestroy(&h->state));
66   // We do not use PetscHeaderDestroy() because having PetscLogObjectDestroy() run for PetscLgoHandler would be very fragile
67   PetscCall(PetscHeaderDestroy_Private((PetscObject)(h), PETSC_FALSE));
68   PetscCall(PetscFree(h));
69   PetscFunctionReturn(PETSC_SUCCESS);
70 }
71 
72 /*@
73   PetscLogHandlerSetState - Set the logging state that provides the stream of events and stages for a log handler.
74 
75   Logically collective
76 
77   Input Parameters:
78 + h     - the `PetscLogHandler`
79 - state - the `PetscLogState`
80 
81   Level: developer
82 
83 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`
84 @*/
85 PetscErrorCode PetscLogHandlerSetState(PetscLogHandler h, PetscLogState state)
86 {
87   PetscFunctionBegin;
88   PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1);
89   if (state) {
90     PetscAssertPointer(state, 2);
91     state->refct++;
92   }
93   PetscCall(PetscLogStateDestroy(&h->state));
94   h->state = state;
95   PetscFunctionReturn(PETSC_SUCCESS);
96 }
97 
98 /*@
99   PetscLogHandlerGetState - Get the logging state that provides the stream of events and stages for a log handler.
100 
101   Logically collective
102 
103   Input Parameter:
104 . h - the `PetscLogHandler`
105 
106   Output Parameter:
107 . state - the `PetscLogState`
108 
109   Level: developer
110 
111 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`
112 @*/
113 PetscErrorCode PetscLogHandlerGetState(PetscLogHandler h, PetscLogState *state)
114 {
115   PetscFunctionBegin;
116   PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1);
117   PetscAssertPointer(state, 2);
118   *state = h->state;
119   PetscFunctionReturn(PETSC_SUCCESS);
120 }
121 
122 /*@
123   PetscLogHandlerEventBegin - Record the beginning of an event in a log handler
124 
125   Not collective
126 
127   Input Parameters:
128 + h  - the `PetscLogHandler`
129 . e  - a registered `PetscLogEvent`
130 . o1 - `PetscObject` associated with the event (may be `NULL`)
131 . o2 - `PetscObject` associated with the event (may be `NULL`)
132 . o3 - `PetscObject` associated with the event (may be `NULL`)
133 - o4 - `PetscObject` associated with the event (may be `NULL`)
134 
135   Level: developer
136 
137 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerEventEnd()`, `PetscLogHandlerEventSync()`
138 @*/
139 PetscErrorCode PetscLogHandlerEventBegin(PetscLogHandler h, PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
140 {
141   PetscFunctionBegin;
142   PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1);
143   PetscTryTypeMethod(h, eventbegin, e, o1, o2, o3, o4);
144   PetscFunctionReturn(PETSC_SUCCESS);
145 }
146 
147 /*@
148   PetscLogHandlerEventEnd - Record the end of an event in a log handler
149 
150   Not collective
151 
152   Input Parameters:
153 + h  - the `PetscLogHandler`
154 . e  - a registered `PetscLogEvent`
155 . o1 - `PetscObject` associated with the event (may be `NULL`)
156 . o2 - `PetscObject` associated with the event (may be `NULL`)
157 . o3 - `PetscObject` associated with the event (may be `NULL`)
158 - o4 - `PetscObject` associated with the event (may be `NULL`)
159 
160   Level: developer
161 
162 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerEventBegin()`, `PetscLogHandlerEventSync()`
163 @*/
164 PetscErrorCode PetscLogHandlerEventEnd(PetscLogHandler h, PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
165 {
166   PetscFunctionBegin;
167   PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1);
168   PetscTryTypeMethod(h, eventend, e, o1, o2, o3, o4);
169   PetscFunctionReturn(PETSC_SUCCESS);
170 }
171 
172 /*@
173   PetscLogHandlerEventSync - Synchronize a logging event
174 
175   Collective over comm
176 
177   Input Parameters:
178 + h    - the `PetscLogHandler`
179 . e    - a registered `PetscLogEvent`
180 - comm - the communicator over which to synchronize `e`
181 
182   Level: developer
183 
184 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerEventBegin()`, `PetscLogHandlerEventEnd()`
185 @*/
186 PetscErrorCode PetscLogHandlerEventSync(PetscLogHandler h, PetscLogEvent e, MPI_Comm comm)
187 {
188   MPI_Comm    h_comm;
189   PetscMPIInt size;
190 
191   PetscFunctionBegin;
192   PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1);
193   PetscCall(PetscObjectGetComm((PetscObject)h, &h_comm));
194   PetscCallMPI(MPI_Comm_size(comm, &size));
195   if (comm == MPI_COMM_NULL || size == 1) PetscFunctionReturn(PETSC_SUCCESS); // nothing to sync
196   if (PetscDefined(USE_DEBUG)) {
197     PetscMPIInt h_comm_world, compare;
198     PetscCallMPI(MPI_Comm_compare(h_comm, PETSC_COMM_WORLD, &h_comm_world));
199     PetscCallMPI(MPI_Comm_compare(h_comm, comm, &compare));
200     // only synchronze if h->comm and comm have the same processes or h->comm is PETSC_COMM_WORLD
201     PetscCheck(h_comm_world != MPI_UNEQUAL || compare != MPI_UNEQUAL, comm, PETSC_ERR_SUP, "PetscLogHandlerSync does not support arbitrary mismatched communicators");
202   }
203   PetscTryTypeMethod(h, eventsync, e, comm);
204   PetscFunctionReturn(PETSC_SUCCESS);
205 }
206 
207 /*@
208   PetscLogHandlerObjectCreate - Record the creation of an object in a log handler.
209 
210   Not collective
211 
212   Input Parameters:
213 + h   - the `PetscLogHandler`
214 - obj - a newly created `PetscObject`
215 
216   Level: developer
217 
218 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerObjectDestroy()`
219 @*/
220 PetscErrorCode PetscLogHandlerObjectCreate(PetscLogHandler h, PetscObject obj)
221 {
222   PetscFunctionBegin;
223   PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1);
224   PetscTryTypeMethod(h, objectcreate, obj);
225   PetscFunctionReturn(PETSC_SUCCESS);
226 }
227 
228 /*@
229   PetscLogHandlerObjectDestroy - Record the destruction of an object in a log handler.
230 
231   Not collective
232 
233   Input Parameters:
234 + h   - the `PetscLogHandler`
235 - obj - a newly created `PetscObject`
236 
237   Level: developer
238 
239 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerObjectCreate()`
240 @*/
241 PetscErrorCode PetscLogHandlerObjectDestroy(PetscLogHandler h, PetscObject obj)
242 {
243   PetscFunctionBegin;
244   PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1);
245   PetscTryTypeMethod(h, objectdestroy, obj);
246   PetscFunctionReturn(PETSC_SUCCESS);
247 }
248 
249 /*@
250   PetscLogHandlerStagePush - Begin a new logging stage in a log handler.
251 
252   Not collective
253 
254   Input Parameters:
255 + h     - the `PetscLogHandler`
256 - stage - a registered `PetscLogStage`
257 
258   Level: developer
259 
260   Notes:
261   This function is called right before the stage is pushed for the handler's `PetscLogState`, so `PetscLogStateGetCurrentStage()`
262   can be used to see what the previous stage was.
263 
264 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerStagePop()`
265 @*/
266 PetscErrorCode PetscLogHandlerStagePush(PetscLogHandler h, PetscLogStage stage)
267 {
268   PetscFunctionBegin;
269   PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1);
270   PetscTryTypeMethod(h, stagepush, stage);
271   PetscFunctionReturn(PETSC_SUCCESS);
272 }
273 
274 /*@
275   PetscLogHandlerStagePop - End the current logging stage in a log handler.
276 
277   Not collective
278 
279   Input Parameters:
280 + h     - the `PetscLogHandler`
281 - stage - a registered `PetscLogStage`
282 
283   Level: developer
284 
285   Notes:
286   This function is called right after the stage is popped for the handler's `PetscLogState`, so `PetscLogStateGetCurrentStage()`
287   can be used to see what the next stage will be.
288 
289 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerStagePush()`
290 @*/
291 PetscErrorCode PetscLogHandlerStagePop(PetscLogHandler h, PetscLogStage stage)
292 {
293   PetscFunctionBegin;
294   PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1);
295   PetscTryTypeMethod(h, stagepop, stage);
296   PetscFunctionReturn(PETSC_SUCCESS);
297 }
298 
299 /*@
300   PetscLogHandlerView - View the data recorded in a log handler.
301 
302   Collective
303 
304   Input Parameters:
305 + h      - the `PetscLogHandler`
306 - viewer - the `PetscViewer`
307 
308   Level: developer
309 
310 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogView()`
311 @*/
312 PetscErrorCode PetscLogHandlerView(PetscLogHandler h, PetscViewer viewer)
313 {
314   PetscFunctionBegin;
315   PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1);
316   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
317   PetscTryTypeMethod(h, view, viewer);
318   PetscFunctionReturn(PETSC_SUCCESS);
319 }
320