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}; 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 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 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 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 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 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 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