#include "solver_profile.h" #include #include #include #ifdef _WIN32 #include #endif static struct { unsigned long long calls; double inclusive, exclusive; } totals[P_COUNT]; static unsigned long long counters[C_COUNT], errors; static ProfileScope *parent; static double profile_now(void) { #ifdef _WIN32 static LARGE_INTEGER frequency; LARGE_INTEGER value; if(!frequency.QuadPart) QueryPerformanceFrequency(&frequency); QueryPerformanceCounter(&value); return (double)value.QuadPart/(double)frequency.QuadPart; #else struct timespec value; clock_gettime(CLOCK_MONOTONIC,&value); return value.tv_sec+value.tv_nsec*1e-9; #endif } ProfileScope profile_begin(int id) { ProfileScope s={.id=id,.active=1,.parent=parent}; s.start=profile_now();return s; } void profile_link(ProfileScope *s) {parent=s;} void profile_end(ProfileScope *s) { if(!s->active)return; double elapsed=profile_now()-s->start; if(parent!=s || elapsedchildren) {fputs("Invalid profiling scope\n",stderr);exit(74);} totals[s->id].calls++; totals[s->id].inclusive+=elapsed; totals[s->id].exclusive+=elapsed-s->children; parent=s->parent; if(parent)parent->children+=elapsed; s->active=0; } void profile_add(int id,int status,long int value) { if(status || value<0)errors++; else counters[id]+=(unsigned long long)value; } void profile_dump(void) { const char *path=getenv("NATIVE_SOLVER_PROFILE"); if(!path || parent) {fputs("Missing profile destination or unclosed scope\n",stderr);exit(74);} FILE *f=fopen(path,"wb");if(!f){perror(path);exit(73);} const char *names[]={"total","integration","cvode_controller","rhs","nonlinear_residual", "jacobian","jacobian_probe","linear_setup","numerical_factorization","linear_solve", "newton","event_detection","accepted_property_checks","sampling","append","flush", "output_replay","result_encoding","poll"}; const char *count_names[]={"accepted_steps","residual_evaluations","linear_rhs_evaluations", "jacobian_evaluations","linear_setups","error_test_failures","newton_iterations", "newton_failures","nonlinear_step_failures","counter_segments","jacobian_reuses", "jacobian_refresh_setups","linear_setup_failures","LU_factorization_failures", "LU_solve_failures","event_model_evaluations","scheduled_boundary_count"}; fprintf(f,"{\"version\":1,\"counterErrors\":%llu,\"counters\":{",errors); for(int i=0;i