Actual source code: logtrace.c

  1: #include <petsc/private/logimpl.h>
  2: #include <petsc/private/loghandlerimpl.h>

  4: typedef struct _n_PetscLogHandler_Trace *PetscLogHandler_Trace;
  5: struct _n_PetscLogHandler_Trace {
  6:   FILE          *petsc_tracefile;
  7:   size_t         petsc_tracelevel;
  8:   char           petsc_tracespace[128];
  9:   PetscLogDouble petsc_tracetime;
 10: };

 12: static PetscErrorCode PetscLogHandlerEventBegin_Trace(PetscLogHandler h, PetscLogEvent event, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
 13: {
 14:   PetscLogHandler_Trace tr = (PetscLogHandler_Trace)h->data;
 15:   PetscLogEventInfo     event_info;
 16:   PetscLogDouble        cur_time;
 17:   PetscMPIInt           rank;
 18:   PetscLogState         state;
 19:   PetscLogStage         stage;

 21:   PetscFunctionBegin;
 22:   if (!tr->petsc_tracetime) PetscCall(PetscTime(&tr->petsc_tracetime));
 23:   tr->petsc_tracelevel++;
 24:   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)h), &rank));
 25:   PetscCall(PetscLogHandlerGetState(h, &state));
 26:   PetscCall(PetscLogStateGetCurrentStage(state, &stage));
 27:   /* Log performance info */
 28:   PetscCall(PetscTime(&cur_time));
 29:   PetscCall(PetscLogStateEventGetInfo(state, event, &event_info));
 30:   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));
 31:   for (size_t i = 0; i < PetscMin(sizeof(tr->petsc_tracespace), 2 * tr->petsc_tracelevel); i++) tr->petsc_tracespace[i] = ' ';
 32:   tr->petsc_tracespace[PetscMin(127, 2 * tr->petsc_tracelevel)] = '\0';
 33:   PetscCall(PetscFFlush(tr->petsc_tracefile));
 34:   PetscFunctionReturn(PETSC_SUCCESS);
 35: }

 37: static PetscErrorCode PetscLogHandlerEventEnd_Trace(PetscLogHandler h, PetscLogEvent event, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
 38: {
 39:   PetscLogHandler_Trace tr = (PetscLogHandler_Trace)h->data;
 40:   PetscLogEventInfo     event_info;
 41:   PetscLogDouble        cur_time;
 42:   PetscLogState         state;
 43:   PetscLogStage         stage;
 44:   PetscMPIInt           rank;

 46:   PetscFunctionBegin;
 47:   tr->petsc_tracelevel--;
 48:   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)h), &rank));
 49:   PetscCall(PetscLogHandlerGetState(h, &state));
 50:   PetscCall(PetscLogStateGetCurrentStage(state, &stage));
 51:   /* Log performance info */
 52:   for (size_t i = 0; i < PetscMin(sizeof(tr->petsc_tracespace), 2 * tr->petsc_tracelevel); i++) tr->petsc_tracespace[i] = ' ';
 53:   tr->petsc_tracespace[PetscMin(127, 2 * tr->petsc_tracelevel)] = '\0';
 54:   PetscCall(PetscTime(&cur_time));
 55:   PetscCall(PetscLogStateEventGetInfo(state, event, &event_info));
 56:   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));
 57:   PetscCall(PetscFFlush(tr->petsc_tracefile));
 58:   PetscFunctionReturn(PETSC_SUCCESS);
 59: }

 61: static PetscErrorCode PetscLogHandlerDestroy_Trace(PetscLogHandler h)
 62: {
 63:   PetscFunctionBegin;
 64:   PetscCall(PetscFree(h->data));
 65:   PetscFunctionReturn(PETSC_SUCCESS);
 66: }

 68: /*MC
 69:   PETSCLOGHANDLERTRACE - PETSCLOGHANDLERTRACE = "trace" -  A
 70:   `PetscLogHandler` that collects data for PETSc's tracing log viewer.
 71:   A log handler of this type is created and started by `PetscLogTraceBegin()`.

 73:   Level: developer

 75: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerCreateTrace()`
 76: M*/

 78: PETSC_INTERN PetscErrorCode PetscLogHandlerCreate_Trace(PetscLogHandler handler)
 79: {
 80:   PetscLogHandler_Trace tr;

 82:   PetscFunctionBegin;
 83:   PetscCall(PetscNew(&tr));
 84:   handler->data            = (void *)tr;
 85:   handler->ops->eventbegin = PetscLogHandlerEventBegin_Trace;
 86:   handler->ops->eventend   = PetscLogHandlerEventEnd_Trace;
 87:   handler->ops->destroy    = PetscLogHandlerDestroy_Trace;
 88:   PetscFunctionReturn(PETSC_SUCCESS);
 89: }

 91: /*@C
 92:   PetscLogHandlerCreateTrace - Create a logger that traces events and stages to a given file descriptor

 94:   Collective, No Fortran Support

 96:   Input Parameters:
 97: + comm - an MPI communicator
 98: - file - a file descriptor

100:   Output Parameters:
101: . handler - a `PetscLogHandler of type `PETSCLOGHANDLERTRACE`

103:   Level: developer

105:   Notes:
106:   Most users can just use `PetscLogTraceBegin()` to create and immediately start (`PetscLogHandlerStart()`) a tracing log handler

108: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerTraceBegin()`
109: @*/
110: PetscErrorCode PetscLogHandlerCreateTrace(MPI_Comm comm, FILE *file, PetscLogHandler *handler)
111: {
112:   PetscLogHandler       h;
113:   PetscLogHandler_Trace tr;

115:   PetscFunctionBegin;
116:   PetscCall(PetscLogHandlerCreate(comm, handler));
117:   h = *handler;
118:   PetscCall(PetscLogHandlerSetType(h, PETSCLOGHANDLERTRACE));
119:   tr                  = (PetscLogHandler_Trace)h->data;
120:   tr->petsc_tracefile = file;
121:   PetscFunctionReturn(PETSC_SUCCESS);
122: }