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 Note: 84 Most users well not need to set a state explicitly: the global logging state (`PetscLogGetState()`) is set when calling `PetscLogHandlerStart()` 85 86 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogEventBegin()`, `PetscLogHandlerStart()` 87 @*/ 88 PetscErrorCode PetscLogHandlerSetState(PetscLogHandler h, PetscLogState state) 89 { 90 PetscFunctionBegin; 91 PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1); 92 if (state) { 93 PetscAssertPointer(state, 2); 94 state->refct++; 95 } 96 PetscCall(PetscLogStateDestroy(&h->state)); 97 h->state = state; 98 PetscFunctionReturn(PETSC_SUCCESS); 99 } 100 101 /*@ 102 PetscLogHandlerGetState - Get the logging state that provides the stream of events and stages for a log handler. 103 104 Logically collective 105 106 Input Parameter: 107 . h - the `PetscLogHandler` 108 109 Output Parameter: 110 . state - the `PetscLogState` 111 112 Level: developer 113 114 Note: 115 For a log handler started with `PetscLogHandlerStart()`, this will be the PETSc global logging state (`PetscLogGetState()`) 116 117 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogEventBegin()`, `PetscLogHandlerStart()` 118 @*/ 119 PetscErrorCode PetscLogHandlerGetState(PetscLogHandler h, PetscLogState *state) 120 { 121 PetscFunctionBegin; 122 PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1); 123 PetscAssertPointer(state, 2); 124 *state = h->state; 125 PetscFunctionReturn(PETSC_SUCCESS); 126 } 127 128 /*@ 129 PetscLogHandlerEventBegin - Record the beginning of an event in a log handler 130 131 Not collective 132 133 Input Parameters: 134 + h - the `PetscLogHandler` 135 . e - a registered `PetscLogEvent` 136 . o1 - `PetscObject` associated with the event (may be `NULL`) 137 . o2 - `PetscObject` associated with the event (may be `NULL`) 138 . o3 - `PetscObject` associated with the event (may be `NULL`) 139 - o4 - `PetscObject` associated with the event (may be `NULL`) 140 141 Level: developer 142 143 Note: 144 Most users will use `PetscLogEventBegin()`, which will call this function for all handlers registered with `PetscLogHandlerStart()` 145 146 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventSync()`, `PetscLogHandlerEventEnd()`, `PetscLogHandlerEventSync()` 147 @*/ 148 PetscErrorCode PetscLogHandlerEventBegin(PetscLogHandler h, PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) 149 { 150 PetscFunctionBegin; 151 PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1); 152 PetscTryTypeMethod(h, eventbegin, e, o1, o2, o3, o4); 153 PetscFunctionReturn(PETSC_SUCCESS); 154 } 155 156 /*@ 157 PetscLogHandlerEventEnd - Record the end of an event in a log handler 158 159 Not collective 160 161 Input Parameters: 162 + h - the `PetscLogHandler` 163 . e - a registered `PetscLogEvent` 164 . o1 - `PetscObject` associated with the event (may be `NULL`) 165 . o2 - `PetscObject` associated with the event (may be `NULL`) 166 . o3 - `PetscObject` associated with the event (may be `NULL`) 167 - o4 - `PetscObject` associated with the event (may be `NULL`) 168 169 Level: developer 170 171 Note: 172 Most users will use `PetscLogEventEnd()`, which will call this function for all handlers registered with `PetscLogHandlerStart()` 173 174 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventSync()`, `PetscLogHandlerEventBegin()`, `PetscLogHandlerEventSync()` 175 @*/ 176 PetscErrorCode PetscLogHandlerEventEnd(PetscLogHandler h, PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) 177 { 178 PetscFunctionBegin; 179 PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1); 180 PetscTryTypeMethod(h, eventend, e, o1, o2, o3, o4); 181 PetscFunctionReturn(PETSC_SUCCESS); 182 } 183 184 /*@ 185 PetscLogHandlerEventSync - Synchronize a logging event 186 187 Collective over comm 188 189 Input Parameters: 190 + h - the `PetscLogHandler` 191 . e - a registered `PetscLogEvent` 192 - comm - the communicator over which to synchronize `e` 193 194 Level: developer 195 196 Note: 197 Most users will use `PetscLogEventSync()`, which will call this function for all handlers registered with `PetscLogHandlerStart()` 198 199 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventSync()`, `PetscLogHandlerEventBegin()`, `PetscLogHandlerEventEnd()` 200 @*/ 201 PetscErrorCode PetscLogHandlerEventSync(PetscLogHandler h, PetscLogEvent e, MPI_Comm comm) 202 { 203 MPI_Comm h_comm; 204 PetscMPIInt size; 205 206 PetscFunctionBegin; 207 PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1); 208 PetscCall(PetscObjectGetComm((PetscObject)h, &h_comm)); 209 PetscCallMPI(MPI_Comm_size(comm, &size)); 210 if (comm == MPI_COMM_NULL || size == 1) PetscFunctionReturn(PETSC_SUCCESS); // nothing to sync 211 if (PetscDefined(USE_DEBUG)) { 212 PetscMPIInt h_comm_world, compare; 213 PetscCallMPI(MPI_Comm_compare(h_comm, PETSC_COMM_WORLD, &h_comm_world)); 214 PetscCallMPI(MPI_Comm_compare(h_comm, comm, &compare)); 215 // only synchronze if h->comm and comm have the same processes or h->comm is PETSC_COMM_WORLD 216 PetscCheck(h_comm_world != MPI_UNEQUAL || compare != MPI_UNEQUAL, comm, PETSC_ERR_SUP, "PetscLogHandlerSync does not support arbitrary mismatched communicators"); 217 } 218 PetscTryTypeMethod(h, eventsync, e, comm); 219 PetscFunctionReturn(PETSC_SUCCESS); 220 } 221 222 /*@ 223 PetscLogHandlerObjectCreate - Record the creation of an object in a log handler. 224 225 Not collective 226 227 Input Parameters: 228 + h - the `PetscLogHandler` 229 - obj - a newly created `PetscObject` 230 231 Level: developer 232 233 Notes: 234 Most users will use `PetscLogObjectCreate()`, which will call this function for all handlers registered with `PetscLogHandlerStart()`. 235 236 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectCreate()`, `PetscLogObjectDestroy()`, `PetscLogHandlerObjectDestroy()` 237 @*/ 238 PetscErrorCode PetscLogHandlerObjectCreate(PetscLogHandler h, PetscObject obj) 239 { 240 PetscFunctionBegin; 241 PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1); 242 PetscTryTypeMethod(h, objectcreate, obj); 243 PetscFunctionReturn(PETSC_SUCCESS); 244 } 245 246 /*@ 247 PetscLogHandlerObjectDestroy - Record the destruction of an object in a log handler. 248 249 Not collective 250 251 Input Parameters: 252 + h - the `PetscLogHandler` 253 - obj - a newly created `PetscObject` 254 255 Level: developer 256 257 Notes: 258 Most users will use `PetscLogObjectDestroy()`, which will call this function for all handlers registered with `PetscLogHandlerStart()`. 259 260 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectCreate()`, `PetscLogObjectDestroy()`, `PetscLogHandlerObjectCreate()` 261 @*/ 262 PetscErrorCode PetscLogHandlerObjectDestroy(PetscLogHandler h, PetscObject obj) 263 { 264 PetscFunctionBegin; 265 PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1); 266 PetscTryTypeMethod(h, objectdestroy, obj); 267 PetscFunctionReturn(PETSC_SUCCESS); 268 } 269 270 /*@ 271 PetscLogHandlerStagePush - Begin a new logging stage in a log handler. 272 273 Not collective 274 275 Input Parameters: 276 + h - the `PetscLogHandler` 277 - stage - a registered `PetscLogStage` 278 279 Level: developer 280 281 Notes: 282 Most users will use `PetscLogStagePush()`, which will call this function for all handlers registered with `PetscLogHandlerStart()`. 283 284 This function is called right before the stage is pushed for the handler's `PetscLogState`, so `PetscLogStateGetCurrentStage()` 285 can be used to see what the previous stage was. 286 287 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogHandlerStagePop()` 288 @*/ 289 PetscErrorCode PetscLogHandlerStagePush(PetscLogHandler h, PetscLogStage stage) 290 { 291 PetscFunctionBegin; 292 PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1); 293 PetscTryTypeMethod(h, stagepush, stage); 294 PetscFunctionReturn(PETSC_SUCCESS); 295 } 296 297 /*@ 298 PetscLogHandlerStagePop - End the current logging stage in a log handler. 299 300 Not collective 301 302 Input Parameters: 303 + h - the `PetscLogHandler` 304 - stage - a registered `PetscLogStage` 305 306 Level: developer 307 308 Notes: 309 Most users will use `PetscLogStagePop()`, which will call this function for all handlers registered with `PetscLogHandlerStart()`. 310 311 This function is called right after the stage is popped for the handler's `PetscLogState`, so `PetscLogStateGetCurrentStage()` 312 can be used to see what the next stage will be. 313 314 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogHandlerStagePush()` 315 @*/ 316 PetscErrorCode PetscLogHandlerStagePop(PetscLogHandler h, PetscLogStage stage) 317 { 318 PetscFunctionBegin; 319 PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1); 320 PetscTryTypeMethod(h, stagepop, stage); 321 PetscFunctionReturn(PETSC_SUCCESS); 322 } 323 324 /*@ 325 PetscLogHandlerView - View the data recorded in a log handler. 326 327 Collective 328 329 Input Parameters: 330 + h - the `PetscLogHandler` 331 - viewer - the `PetscViewer` 332 333 Level: developer 334 335 .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogView()` 336 @*/ 337 PetscErrorCode PetscLogHandlerView(PetscLogHandler h, PetscViewer viewer) 338 { 339 PetscFunctionBegin; 340 PetscValidHeaderSpecific(h, PETSCLOGHANDLER_CLASSID, 1); 341 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 342 PetscTryTypeMethod(h, view, viewer); 343 PetscFunctionReturn(PETSC_SUCCESS); 344 } 345