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 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 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 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 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 946467efc9SToby Isaac Collective 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 @*/ 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)); 119*f4f49eeaSPierre Jolivet tr = (PetscLogHandler_Trace)h->data; 1206467efc9SToby Isaac tr->petsc_tracefile = file; 1216467efc9SToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 1226467efc9SToby Isaac } 123