xref: /petsc/src/sys/logging/handler/impls/trace/logtrace.c (revision 1ed6e3ff8437baa411029a28c2b08f047df9ad9a)
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