Actual source code: logperfstubs.c

  1: #include <petsc/private/logimpl.h>
  2: #include <petsc/private/loghandlerimpl.h>
  3: #include <../src/sys/perfstubs/timer.h>

  5: typedef struct _n_PetscEventPS {
  6:   void *timer;
  7:   int   depth;
  8: } PetscEventPS;

 10: PETSC_LOG_RESIZABLE_ARRAY(PSArray, PetscEventPS, void *, NULL, NULL, NULL)

 12: typedef struct _n_PetscLogHandler_Perfstubs *PetscLogHandler_Perfstubs;

 14: struct _n_PetscLogHandler_Perfstubs {
 15:   PetscLogPSArray events;
 16:   PetscLogPSArray stages;
 17:   PetscBool       started_perfstubs;
 18: };

 20: static PetscErrorCode PetscLogHandlerContextCreate_Perfstubs(PetscLogHandler_Perfstubs *ps_p)
 21: {
 22:   PetscLogHandler_Perfstubs ps;

 24:   PetscFunctionBegin;
 25:   PetscCall(PetscNew(ps_p));
 26:   ps = *ps_p;
 27:   PetscCall(PetscLogPSArrayCreate(128, &ps->events));
 28:   PetscCall(PetscLogPSArrayCreate(8, &ps->stages));
 29:   PetscFunctionReturn(PETSC_SUCCESS);
 30: }

 32: static PetscErrorCode PetscLogHandlerDestroy_Perfstubs(PetscLogHandler h)
 33: {
 34:   PetscInt                  num_events, num_stages;
 35:   PetscLogHandler_Perfstubs ps = (PetscLogHandler_Perfstubs)h->data;

 37:   PetscFunctionBegin;
 38:   PetscCall(PetscLogPSArrayGetSize(ps->events, &num_events, NULL));
 39:   for (PetscInt i = 0; i < num_events; i++) {
 40:     PetscEventPS event = {NULL, 0};

 42:     PetscCall(PetscLogPSArrayGet(ps->events, i, &event));
 43:     PetscStackCallExternalVoid("ps_timer_destroy_", ps_timer_destroy_(event.timer));
 44:   }
 45:   PetscCall(PetscLogPSArrayDestroy(&ps->events));

 47:   PetscCall(PetscLogPSArrayGetSize(ps->stages, &num_stages, NULL));
 48:   for (PetscInt i = 0; i < num_stages; i++) {
 49:     PetscEventPS stage = {NULL, 0};

 51:     PetscCall(PetscLogPSArrayGet(ps->stages, i, &stage));
 52:     PetscStackCallExternalVoid("ps_timer_destroy_", ps_timer_destroy_(stage.timer));
 53:   }
 54:   PetscCall(PetscLogPSArrayDestroy(&ps->stages));

 56:   if (ps->started_perfstubs) PetscStackCallExternalVoid("ps_finalize_", ps_finalize_());
 57:   PetscCall(PetscFree(ps));
 58:   PetscFunctionReturn(PETSC_SUCCESS);
 59: }

 61: static PetscErrorCode PetscLogHandlerPSUpdateEvents(PetscLogHandler h)
 62: {
 63:   PetscLogHandler_Perfstubs ps = (PetscLogHandler_Perfstubs)h->data;
 64:   PetscLogState             state;
 65:   PetscInt                  num_events, num_events_old;

 67:   PetscFunctionBegin;
 68:   PetscCall(PetscLogHandlerGetState(h, &state));
 69:   PetscCall(PetscLogStateGetNumEvents(state, &num_events));
 70:   PetscCall(PetscLogPSArrayGetSize(ps->events, &num_events_old, NULL));
 71:   for (PetscInt i = num_events_old; i < num_events; i++) {
 72:     PetscLogEventInfo event_info = {NULL, -1, PETSC_FALSE};
 73:     PetscEventPS      ps_event   = {NULL, 0};
 74:     PetscLogEvent     ei;

 76:     PetscCall(PetscMPIIntCast(i, &ei));
 77:     PetscCall(PetscLogStateEventGetInfo(state, ei, &event_info));
 78:     PetscStackCallExternalVoid("ps_timer_create_", ps_event.timer = ps_timer_create_(event_info.name));
 79:     ps_event.depth = 0;
 80:     PetscCall(PetscLogPSArrayPush(ps->events, ps_event));
 81:   }
 82:   PetscFunctionReturn(PETSC_SUCCESS);
 83: }

 85: static PetscErrorCode PetscLogHandlerPSUpdateStages(PetscLogHandler h)
 86: {
 87:   PetscLogHandler_Perfstubs ps = (PetscLogHandler_Perfstubs)h->data;
 88:   PetscLogState             state;
 89:   PetscInt                  num_stages, num_stages_old;

 91:   PetscFunctionBegin;
 92:   PetscCall(PetscLogHandlerGetState(h, &state));
 93:   PetscCall(PetscLogStateGetNumStages(state, &num_stages));
 94:   PetscCall(PetscLogPSArrayGetSize(ps->stages, &num_stages_old, NULL));
 95:   for (PetscInt i = num_stages_old; i < num_stages; i++) {
 96:     PetscLogStageInfo stage_info = {NULL};
 97:     PetscEventPS      ps_stage   = {NULL, 0};
 98:     PetscLogEvent     si;

100:     PetscCall(PetscMPIIntCast(i, &si));
101:     PetscCall(PetscLogStateStageGetInfo(state, si, &stage_info));
102:     PetscStackCallExternalVoid("ps_timer_create_", ps_stage.timer = ps_timer_create_(stage_info.name));
103:     ps_stage.depth = 0;
104:     PetscCall(PetscLogPSArrayPush(ps->stages, ps_stage));
105:   }
106:   PetscFunctionReturn(PETSC_SUCCESS);
107: }

109: static PetscErrorCode PetscLogHandlerEventBegin_Perfstubs(PetscLogHandler handler, PetscLogEvent event, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
110: {
111:   PetscLogHandler_Perfstubs ps       = (PetscLogHandler_Perfstubs)handler->data;
112:   PetscEventPS              ps_event = {NULL, 0};

114:   PetscFunctionBegin;
115:   if (event >= ps->events->num_entries) PetscCall(PetscLogHandlerPSUpdateEvents(handler));
116:   PetscCall(PetscLogPSArrayGet(ps->events, event, &ps_event));
117:   ps_event.depth++;
118:   PetscCall(PetscLogPSArraySet(ps->events, event, ps_event));
119:   if (ps_event.depth == 1 && ps_event.timer != NULL) PetscStackCallExternalVoid("ps_timer_start_", ps_timer_start_(ps_event.timer));
120:   PetscFunctionReturn(PETSC_SUCCESS);
121: }

123: static PetscErrorCode PetscLogHandlerEventEnd_Perfstubs(PetscLogHandler handler, PetscLogEvent event, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
124: {
125:   PetscLogHandler_Perfstubs ps       = (PetscLogHandler_Perfstubs)handler->data;
126:   PetscEventPS              ps_event = {NULL, 0};

128:   PetscFunctionBegin;
129:   if (event >= ps->events->num_entries) PetscCall(PetscLogHandlerPSUpdateEvents(handler));
130:   PetscCall(PetscLogPSArrayGet(ps->events, event, &ps_event));
131:   ps_event.depth--;
132:   PetscCall(PetscLogPSArraySet(ps->events, event, ps_event));
133:   if (ps_event.depth == 0 && ps_event.timer != NULL) PetscStackCallExternalVoid("ps_timer_stop_", ps_timer_stop_(ps_event.timer));
134:   PetscFunctionReturn(PETSC_SUCCESS);
135: }

137: static PetscErrorCode PetscLogHandlerStagePush_Perfstubs(PetscLogHandler handler, PetscLogStage stage)
138: {
139:   PetscLogHandler_Perfstubs ps       = (PetscLogHandler_Perfstubs)handler->data;
140:   PetscEventPS              ps_event = {NULL, 0};

142:   PetscFunctionBegin;
143:   if (stage >= ps->stages->num_entries) PetscCall(PetscLogHandlerPSUpdateStages(handler));
144:   PetscCall(PetscLogPSArrayGet(ps->stages, stage, &ps_event));
145:   if (ps_event.timer != NULL) PetscStackCallExternalVoid("ps_timer_start_", ps_timer_start_(ps_event.timer));
146:   PetscFunctionReturn(PETSC_SUCCESS);
147: }

149: static PetscErrorCode PetscLogHandlerStagePop_Perfstubs(PetscLogHandler handler, PetscLogStage stage)
150: {
151:   PetscLogHandler_Perfstubs ps       = (PetscLogHandler_Perfstubs)handler->data;
152:   PetscEventPS              ps_event = {NULL, 0};

154:   PetscFunctionBegin;
155:   if (stage >= ps->stages->num_entries) PetscCall(PetscLogHandlerPSUpdateStages(handler));
156:   PetscCall(PetscLogPSArrayGet(ps->stages, stage, &ps_event));
157:   if (ps_event.timer != NULL) PetscStackCallExternalVoid("ps_timer_stop_", ps_timer_stop_(ps_event.timer));
158:   PetscFunctionReturn(PETSC_SUCCESS);
159: }

161: /*MC
162:   PETSCLOGHANDLERPERFSTUBS - PETSCLOGHANDLERPERFSTUBS = "perfstubs" -  A
163:   `PetscLogHandler` that collects data for the PerfStubs/TAU instrumentation
164:   library.  A log handler of this type is created and started by
165:   `PetscLogPerfstubsBegin()`.

167:   Level: developer

169: .seealso: [](ch_profiling), `PetscLogHandler`
170: M*/

172: PETSC_INTERN PetscErrorCode PetscLogHandlerCreate_Perfstubs(PetscLogHandler handler)
173: {
174:   PetscBool                 started_perfstubs;
175:   PetscLogHandler_Perfstubs lps;

177:   PetscFunctionBegin;
178:   if (perfstubs_initialized == PERFSTUBS_UNKNOWN) {
179:     PetscStackCallExternalVoid("ps_initialize_", ps_initialize_());
180:     started_perfstubs = PETSC_TRUE;
181:   } else {
182:     started_perfstubs = PETSC_FALSE;
183:   }
184:   PetscCheck(perfstubs_initialized == PERFSTUBS_SUCCESS, PetscObjectComm((PetscObject)handler), PETSC_ERR_LIB, "perfstubs could not be initialized");
185:   PetscCall(PetscLogHandlerContextCreate_Perfstubs(&lps));
186:   lps->started_perfstubs   = started_perfstubs;
187:   handler->data            = (void *)lps;
188:   handler->ops->destroy    = PetscLogHandlerDestroy_Perfstubs;
189:   handler->ops->eventbegin = PetscLogHandlerEventBegin_Perfstubs;
190:   handler->ops->eventend   = PetscLogHandlerEventEnd_Perfstubs;
191:   handler->ops->stagepush  = PetscLogHandlerStagePush_Perfstubs;
192:   handler->ops->stagepop   = PetscLogHandlerStagePop_Perfstubs;
193:   PetscFunctionReturn(PETSC_SUCCESS);
194: }