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