16467efc9SToby Isaac #include <petsc/private/logimpl.h> /*I "petscsys.h" I*/
26467efc9SToby Isaac #include <petsc/private/loghandlerimpl.h>
36467efc9SToby Isaac
46467efc9SToby Isaac typedef struct _n_PetscLogHandler_Trace *PetscLogHandler_Trace;
56467efc9SToby Isaac struct _n_PetscLogHandler_Trace {
66467efc9SToby Isaac FILE *petsc_tracefile;
76467efc9SToby Isaac size_t petsc_tracelevel;
86467efc9SToby Isaac char petsc_tracespace[128];
96467efc9SToby Isaac PetscLogDouble petsc_tracetime;
106467efc9SToby Isaac };
116467efc9SToby Isaac
PetscLogHandlerEventBegin_Trace(PetscLogHandler h,PetscLogEvent event,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4)126467efc9SToby Isaac static PetscErrorCode PetscLogHandlerEventBegin_Trace(PetscLogHandler h, PetscLogEvent event, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
136467efc9SToby Isaac {
146467efc9SToby Isaac PetscLogHandler_Trace tr = (PetscLogHandler_Trace)h->data;
156467efc9SToby Isaac PetscLogEventInfo event_info;
166467efc9SToby Isaac PetscLogDouble cur_time;
176467efc9SToby Isaac PetscMPIInt rank;
186467efc9SToby Isaac PetscLogState state;
196467efc9SToby Isaac PetscLogStage stage;
206467efc9SToby Isaac
216467efc9SToby Isaac PetscFunctionBegin;
226467efc9SToby Isaac if (!tr->petsc_tracetime) PetscCall(PetscTime(&tr->petsc_tracetime));
236467efc9SToby Isaac tr->petsc_tracelevel++;
246467efc9SToby Isaac PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)h), &rank));
256467efc9SToby Isaac PetscCall(PetscLogHandlerGetState(h, &state));
266467efc9SToby Isaac PetscCall(PetscLogStateGetCurrentStage(state, &stage));
276467efc9SToby Isaac /* Log performance info */
286467efc9SToby Isaac PetscCall(PetscTime(&cur_time));
296467efc9SToby Isaac PetscCall(PetscLogStateEventGetInfo(state, event, &event_info));
306467efc9SToby Isaac PetscCall(PetscFPrintf(PETSC_COMM_SELF, tr->petsc_tracefile, "%s[%d] %g Event begin: %s\n", tr->petsc_tracespace, rank, cur_time - tr->petsc_tracetime, event_info.name));
316467efc9SToby Isaac for (size_t i = 0; i < PetscMin(sizeof(tr->petsc_tracespace), 2 * tr->petsc_tracelevel); i++) tr->petsc_tracespace[i] = ' ';
326467efc9SToby Isaac tr->petsc_tracespace[PetscMin(127, 2 * tr->petsc_tracelevel)] = '\0';
336467efc9SToby Isaac PetscCall(PetscFFlush(tr->petsc_tracefile));
346467efc9SToby Isaac PetscFunctionReturn(PETSC_SUCCESS);
356467efc9SToby Isaac }
366467efc9SToby Isaac
PetscLogHandlerEventEnd_Trace(PetscLogHandler h,PetscLogEvent event,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4)376467efc9SToby Isaac static PetscErrorCode PetscLogHandlerEventEnd_Trace(PetscLogHandler h, PetscLogEvent event, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
386467efc9SToby Isaac {
396467efc9SToby Isaac PetscLogHandler_Trace tr = (PetscLogHandler_Trace)h->data;
406467efc9SToby Isaac PetscLogEventInfo event_info;
416467efc9SToby Isaac PetscLogDouble cur_time;
426467efc9SToby Isaac PetscLogState state;
436467efc9SToby Isaac PetscLogStage stage;
446467efc9SToby Isaac PetscMPIInt rank;
456467efc9SToby Isaac
466467efc9SToby Isaac PetscFunctionBegin;
476467efc9SToby Isaac tr->petsc_tracelevel--;
486467efc9SToby Isaac PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)h), &rank));
496467efc9SToby Isaac PetscCall(PetscLogHandlerGetState(h, &state));
506467efc9SToby Isaac PetscCall(PetscLogStateGetCurrentStage(state, &stage));
516467efc9SToby Isaac /* Log performance info */
526467efc9SToby Isaac for (size_t i = 0; i < PetscMin(sizeof(tr->petsc_tracespace), 2 * tr->petsc_tracelevel); i++) tr->petsc_tracespace[i] = ' ';
536467efc9SToby Isaac tr->petsc_tracespace[PetscMin(127, 2 * tr->petsc_tracelevel)] = '\0';
546467efc9SToby Isaac PetscCall(PetscTime(&cur_time));
556467efc9SToby Isaac PetscCall(PetscLogStateEventGetInfo(state, event, &event_info));
566467efc9SToby Isaac PetscCall(PetscFPrintf(PETSC_COMM_SELF, tr->petsc_tracefile, "%s[%d] %g Event end: %s\n", tr->petsc_tracespace, rank, cur_time - tr->petsc_tracetime, event_info.name));
576467efc9SToby Isaac PetscCall(PetscFFlush(tr->petsc_tracefile));
586467efc9SToby Isaac PetscFunctionReturn(PETSC_SUCCESS);
596467efc9SToby Isaac }
606467efc9SToby Isaac
PetscLogHandlerDestroy_Trace(PetscLogHandler h)616467efc9SToby Isaac static PetscErrorCode PetscLogHandlerDestroy_Trace(PetscLogHandler h)
626467efc9SToby Isaac {
636467efc9SToby Isaac PetscFunctionBegin;
646467efc9SToby Isaac PetscCall(PetscFree(h->data));
656467efc9SToby Isaac PetscFunctionReturn(PETSC_SUCCESS);
666467efc9SToby Isaac }
676467efc9SToby Isaac
686467efc9SToby Isaac /*MC
69294de794SToby Isaac PETSCLOGHANDLERTRACE - PETSCLOGHANDLERTRACE = "trace" - A
706467efc9SToby Isaac `PetscLogHandler` that collects data for PETSc's tracing log viewer.
71b665b14eSToby Isaac A log handler of this type is created and started by `PetscLogTraceBegin()`.
726467efc9SToby Isaac
736467efc9SToby Isaac Level: developer
746467efc9SToby Isaac
756467efc9SToby Isaac .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerCreateTrace()`
766467efc9SToby Isaac M*/
776467efc9SToby Isaac
PetscLogHandlerCreate_Trace(PetscLogHandler handler)786467efc9SToby Isaac PETSC_INTERN PetscErrorCode PetscLogHandlerCreate_Trace(PetscLogHandler handler)
796467efc9SToby Isaac {
806467efc9SToby Isaac PetscLogHandler_Trace tr;
816467efc9SToby Isaac
826467efc9SToby Isaac PetscFunctionBegin;
836467efc9SToby Isaac PetscCall(PetscNew(&tr));
846467efc9SToby Isaac handler->data = (void *)tr;
856467efc9SToby Isaac handler->ops->eventbegin = PetscLogHandlerEventBegin_Trace;
866467efc9SToby Isaac handler->ops->eventend = PetscLogHandlerEventEnd_Trace;
876467efc9SToby Isaac handler->ops->destroy = PetscLogHandlerDestroy_Trace;
886467efc9SToby Isaac PetscFunctionReturn(PETSC_SUCCESS);
896467efc9SToby Isaac }
906467efc9SToby Isaac
916467efc9SToby Isaac /*@C
926467efc9SToby Isaac PetscLogHandlerCreateTrace - Create a logger that traces events and stages to a given file descriptor
936467efc9SToby Isaac
94*cc4c1da9SBarry Smith Collective, No Fortran Support
956467efc9SToby Isaac
966467efc9SToby Isaac Input Parameters:
976467efc9SToby Isaac + comm - an MPI communicator
986467efc9SToby Isaac - file - a file descriptor
996467efc9SToby Isaac
1006467efc9SToby Isaac Output Parameters:
101294de794SToby Isaac . handler - a `PetscLogHandler of type `PETSCLOGHANDLERTRACE`
1026467efc9SToby Isaac
1036467efc9SToby Isaac Level: developer
1046467efc9SToby Isaac
1056467efc9SToby Isaac Notes:
1066467efc9SToby Isaac Most users can just use `PetscLogTraceBegin()` to create and immediately start (`PetscLogHandlerStart()`) a tracing log handler
1076467efc9SToby Isaac
1086467efc9SToby Isaac .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerTraceBegin()`
1096467efc9SToby Isaac @*/
PetscLogHandlerCreateTrace(MPI_Comm comm,FILE * file,PetscLogHandler * handler)1106467efc9SToby Isaac PetscErrorCode PetscLogHandlerCreateTrace(MPI_Comm comm, FILE *file, PetscLogHandler *handler)
1116467efc9SToby Isaac {
1126467efc9SToby Isaac PetscLogHandler h;
1136467efc9SToby Isaac PetscLogHandler_Trace tr;
1146467efc9SToby Isaac
1156467efc9SToby Isaac PetscFunctionBegin;
1166467efc9SToby Isaac PetscCall(PetscLogHandlerCreate(comm, handler));
1176467efc9SToby Isaac h = *handler;
118294de794SToby Isaac PetscCall(PetscLogHandlerSetType(h, PETSCLOGHANDLERTRACE));
119f4f49eeaSPierre Jolivet tr = (PetscLogHandler_Trace)h->data;
1206467efc9SToby Isaac tr->petsc_tracefile = file;
1216467efc9SToby Isaac PetscFunctionReturn(PETSC_SUCCESS);
1226467efc9SToby Isaac }
123