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 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 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 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}; 74ccf0b5c1SToby Isaac 75ccf0b5c1SToby Isaac PetscCall(PetscLogStateEventGetInfo(state, (PetscLogEvent)i, &event_info)); 76ccf0b5c1SToby Isaac PetscStackCallExternalVoid("ps_timer_create_", ps_event.timer = ps_timer_create_(event_info.name)); 77ccf0b5c1SToby Isaac ps_event.depth = 0; 78ccf0b5c1SToby Isaac PetscCall(PetscLogPSArrayPush(ps->events, ps_event)); 79ccf0b5c1SToby Isaac } 80ccf0b5c1SToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 81ccf0b5c1SToby Isaac } 82ccf0b5c1SToby Isaac 83ccf0b5c1SToby Isaac static PetscErrorCode PetscLogHandlerPSUpdateStages(PetscLogHandler h) 84ccf0b5c1SToby Isaac { 85ccf0b5c1SToby Isaac PetscLogHandler_Perfstubs ps = (PetscLogHandler_Perfstubs)h->data; 86ccf0b5c1SToby Isaac PetscLogState state; 87ccf0b5c1SToby Isaac PetscInt num_stages, num_stages_old; 88ccf0b5c1SToby Isaac 89ccf0b5c1SToby Isaac PetscFunctionBegin; 90ccf0b5c1SToby Isaac PetscCall(PetscLogHandlerGetState(h, &state)); 91ccf0b5c1SToby Isaac PetscCall(PetscLogStateGetNumStages(state, &num_stages)); 92ccf0b5c1SToby Isaac PetscCall(PetscLogPSArrayGetSize(ps->stages, &num_stages_old, NULL)); 93ccf0b5c1SToby Isaac for (PetscInt i = num_stages_old; i < num_stages; i++) { 94ccf0b5c1SToby Isaac PetscLogStageInfo stage_info = {NULL}; 95ccf0b5c1SToby Isaac PetscEventPS ps_stage = {NULL, 0}; 96ccf0b5c1SToby Isaac 97ccf0b5c1SToby Isaac PetscCall(PetscLogStateStageGetInfo(state, (PetscLogStage)i, &stage_info)); 98ccf0b5c1SToby Isaac PetscStackCallExternalVoid("ps_timer_create_", ps_stage.timer = ps_timer_create_(stage_info.name)); 99ccf0b5c1SToby Isaac ps_stage.depth = 0; 100ccf0b5c1SToby Isaac PetscCall(PetscLogPSArrayPush(ps->stages, ps_stage)); 101ccf0b5c1SToby Isaac } 102ccf0b5c1SToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 103ccf0b5c1SToby Isaac } 104ccf0b5c1SToby Isaac 105ccf0b5c1SToby Isaac static PetscErrorCode PetscLogHandlerEventBegin_Perfstubs(PetscLogHandler handler, PetscLogEvent event, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) 106ccf0b5c1SToby Isaac { 107ccf0b5c1SToby Isaac PetscLogHandler_Perfstubs ps = (PetscLogHandler_Perfstubs)handler->data; 108ccf0b5c1SToby Isaac PetscEventPS ps_event = {NULL, 0}; 109ccf0b5c1SToby Isaac 110ccf0b5c1SToby Isaac PetscFunctionBegin; 111ccf0b5c1SToby Isaac if (event >= ps->events->num_entries) PetscCall(PetscLogHandlerPSUpdateEvents(handler)); 112ccf0b5c1SToby Isaac PetscCall(PetscLogPSArrayGet(ps->events, event, &ps_event)); 113ccf0b5c1SToby Isaac ps_event.depth++; 114ccf0b5c1SToby Isaac PetscCall(PetscLogPSArraySet(ps->events, event, ps_event)); 115ccf0b5c1SToby Isaac if (ps_event.depth == 1 && ps_event.timer != NULL) PetscStackCallExternalVoid("ps_timer_start_", ps_timer_start_(ps_event.timer)); 116ccf0b5c1SToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 117ccf0b5c1SToby Isaac } 118ccf0b5c1SToby Isaac 119ccf0b5c1SToby Isaac static PetscErrorCode PetscLogHandlerEventEnd_Perfstubs(PetscLogHandler handler, PetscLogEvent event, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) 120ccf0b5c1SToby Isaac { 121ccf0b5c1SToby Isaac PetscLogHandler_Perfstubs ps = (PetscLogHandler_Perfstubs)handler->data; 122ccf0b5c1SToby Isaac PetscEventPS ps_event = {NULL, 0}; 123ccf0b5c1SToby Isaac 124ccf0b5c1SToby Isaac PetscFunctionBegin; 125ccf0b5c1SToby Isaac if (event >= ps->events->num_entries) PetscCall(PetscLogHandlerPSUpdateEvents(handler)); 126ccf0b5c1SToby Isaac PetscCall(PetscLogPSArrayGet(ps->events, event, &ps_event)); 127ccf0b5c1SToby Isaac ps_event.depth--; 128ccf0b5c1SToby Isaac PetscCall(PetscLogPSArraySet(ps->events, event, ps_event)); 129ccf0b5c1SToby Isaac if (ps_event.depth == 0 && ps_event.timer != NULL) PetscStackCallExternalVoid("ps_timer_stop_", ps_timer_stop_(ps_event.timer)); 130ccf0b5c1SToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 131ccf0b5c1SToby Isaac } 132ccf0b5c1SToby Isaac 133ccf0b5c1SToby Isaac static PetscErrorCode PetscLogHandlerStagePush_Perfstubs(PetscLogHandler handler, PetscLogStage stage) 134ccf0b5c1SToby Isaac { 135ccf0b5c1SToby Isaac PetscLogHandler_Perfstubs ps = (PetscLogHandler_Perfstubs)handler->data; 136ccf0b5c1SToby Isaac PetscEventPS ps_event = {NULL, 0}; 137ccf0b5c1SToby Isaac 138ccf0b5c1SToby Isaac PetscFunctionBegin; 139ccf0b5c1SToby Isaac if (stage >= ps->stages->num_entries) PetscCall(PetscLogHandlerPSUpdateStages(handler)); 140ccf0b5c1SToby Isaac PetscCall(PetscLogPSArrayGet(ps->stages, stage, &ps_event)); 141ccf0b5c1SToby Isaac if (ps_event.timer != NULL) PetscStackCallExternalVoid("ps_timer_start_", ps_timer_start_(ps_event.timer)); 142ccf0b5c1SToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 143ccf0b5c1SToby Isaac } 144ccf0b5c1SToby Isaac 145ccf0b5c1SToby Isaac static PetscErrorCode PetscLogHandlerStagePop_Perfstubs(PetscLogHandler handler, PetscLogStage stage) 146ccf0b5c1SToby Isaac { 147ccf0b5c1SToby Isaac PetscLogHandler_Perfstubs ps = (PetscLogHandler_Perfstubs)handler->data; 148ccf0b5c1SToby Isaac PetscEventPS ps_event = {NULL, 0}; 149ccf0b5c1SToby Isaac 150ccf0b5c1SToby Isaac PetscFunctionBegin; 151ccf0b5c1SToby Isaac if (stage >= ps->stages->num_entries) PetscCall(PetscLogHandlerPSUpdateStages(handler)); 152ccf0b5c1SToby Isaac PetscCall(PetscLogPSArrayGet(ps->stages, stage, &ps_event)); 153ccf0b5c1SToby Isaac if (ps_event.timer != NULL) PetscStackCallExternalVoid("ps_timer_stop_", ps_timer_stop_(ps_event.timer)); 154ccf0b5c1SToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 155ccf0b5c1SToby Isaac } 156ccf0b5c1SToby Isaac 157ccf0b5c1SToby Isaac /*MC 158*294de794SToby Isaac PETSCLOGHANDLERPERFSTUBS - PETSCLOGHANDLERPERFSTUBS = "perfstubs" - A 159ccf0b5c1SToby Isaac `PetscLogHandler` that collects data for the PerfStubs/TAU instrumentation 160b665b14eSToby Isaac library. A log handler of this type is created and started by 161b665b14eSToby Isaac `PetscLogPerfstubsBegin()`. 162ccf0b5c1SToby Isaac 163ccf0b5c1SToby Isaac Level: developer 164ccf0b5c1SToby Isaac 165ccf0b5c1SToby Isaac .seealso: [](ch_profiling), `PetscLogHandler` 166ccf0b5c1SToby Isaac M*/ 167ccf0b5c1SToby Isaac 168ccf0b5c1SToby Isaac PETSC_INTERN PetscErrorCode PetscLogHandlerCreate_Perfstubs(PetscLogHandler handler) 169ccf0b5c1SToby Isaac { 170ccf0b5c1SToby Isaac PetscBool started_perfstubs; 171ccf0b5c1SToby Isaac PetscLogHandler_Perfstubs lps; 172ccf0b5c1SToby Isaac 173ccf0b5c1SToby Isaac PetscFunctionBegin; 174ccf0b5c1SToby Isaac if (perfstubs_initialized == PERFSTUBS_UNKNOWN) { 175ccf0b5c1SToby Isaac PetscStackCallExternalVoid("ps_initialize_", ps_initialize_()); 176ccf0b5c1SToby Isaac started_perfstubs = PETSC_TRUE; 177ccf0b5c1SToby Isaac } else { 178ccf0b5c1SToby Isaac started_perfstubs = PETSC_FALSE; 179ccf0b5c1SToby Isaac } 180ccf0b5c1SToby Isaac PetscCheck(perfstubs_initialized == PERFSTUBS_SUCCESS, PetscObjectComm((PetscObject)handler), PETSC_ERR_LIB, "perfstubs could not be initialized"); 181ccf0b5c1SToby Isaac PetscCall(PetscLogHandlerContextCreate_Perfstubs(&lps)); 182ccf0b5c1SToby Isaac lps->started_perfstubs = started_perfstubs; 183ccf0b5c1SToby Isaac handler->data = (void *)lps; 184ccf0b5c1SToby Isaac handler->ops->destroy = PetscLogHandlerDestroy_Perfstubs; 185ccf0b5c1SToby Isaac handler->ops->eventbegin = PetscLogHandlerEventBegin_Perfstubs; 186ccf0b5c1SToby Isaac handler->ops->eventend = PetscLogHandlerEventEnd_Perfstubs; 187ccf0b5c1SToby Isaac handler->ops->stagepush = PetscLogHandlerStagePush_Perfstubs; 188ccf0b5c1SToby Isaac handler->ops->stagepop = PetscLogHandlerStagePop_Perfstubs; 189ccf0b5c1SToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 190ccf0b5c1SToby Isaac } 191