/* No numerical work lives here. Runtime selection is outside the hot model. */ #include "local_probe_profile.h" #include #include #include /* PROFILE_TABLES */ PfBucket pf_buckets[LP_NC+2][PF_CATEGORIES],*pf_current; uint64_t pf_previous_tick; unsigned pf_row; int pf_coarse; static uint64_t evaluations[LP_NC+2]; uint64_t pf_operations[LP_NC][2]; static uint64_t calls,sampled,sampled_ticks,frequency,total_events; static uint64_t sampled_qpc_ticks,tsc_start,tsc_end,clock_t0; static double clock_q0; static unsigned stride=16,offset,seed=1; static FILE *matrix; static const char *names[PF_CATEGORIES]={"other","perturbation_amount","state_copy_perturb", "matrix_zero","difference_matrix_write","baseline_compute","initialization","gas_state_preparation", "schedule_retained","schedule_context_fallback","context_compare","snapshot_capture_save", "context_output_restore","node_energy","port_outputs","mechanical_equations", "gas_mass_energy","remaining_outputs","pipe_diagnostics","finite_check","schedule_dispatch","whole_probe_fallback"}; void pf_initialize(void){ LARGE_INTEGER f;QueryPerformanceFrequency(&f);frequency=(uint64_t)f.QuadPart; unsigned a,b,c,d; if(!__get_cpuid(0x80000007,&a,&b,&c,&d) || !(d&(1u<<8))){fprintf(stderr,"invariant TSC required for diagnostic clock\n");abort();} uint64_t q0=lp_tick();clock_t0=pf_clock();uint64_t q1=lp_tick();clock_q0=((double)q0+(double)q1)/2; const char *s=getenv("PROBE_PROFILE_STRIDE"),*o=getenv("PROBE_PROFILE_OFFSET"),*v=getenv("PROBE_PROFILE_MATRICES"); const char *coarse=getenv("PROBE_PROFILE_COARSE");pf_coarse=coarse?atoi(coarse):0; if(s)stride=(unsigned)strtoul(s,NULL,0); if(o)offset=(unsigned)strtoul(o,NULL,0); seed=offset+1; if(v && atoi(v)){matrix=fopen("jacobians.bin","wb");if(!matrix)abort();setvbuf(matrix,NULL,_IOFBF,1024*1024);} } int pf_select(void){ /* One randomly positioned callback per consecutive stratum. The offset is reproducible, and avoids locking onto a recurring Newton/event pattern. */ unsigned pos=(unsigned)(calls++% (stride?stride:1)); if(!stride)return 0; if(!pos){seed^=seed<<13;seed^=seed>>17;seed^=seed<<5;offset=seed%stride;} if(pos!=offset)return 0; pf_row=0;return 1; } void pf_eval_count(void){evaluations[pf_row]++;} void pf_open(void){pf_current=&pf_buckets[0][PF_OTHER];tsc_start=pf_clock();pf_previous_tick=tsc_start;} void pf_close(void){tsc_end=pf_clock();pf_current->ticks+=tsc_end-pf_previous_tick;} void pf_flush(uint64_t start,uint64_t end){ sampled++;sampled_qpc_ticks+=end-start;sampled_ticks+=tsc_end-tsc_start; } void pf_validate_matrix(double t,const double *y,const double *m){ if(matrix){fwrite(&t,8,1,matrix);fwrite(y,8,NSTATES,matrix);fwrite(m,8,NSTATES*NSTATES,matrix);} } static void array(FILE *f,const uint64_t *a,int n){fputc('[',f);for(int i=0;i=2){fprintf(f,",\"operations\":");array(f,pf_operations[r-2],2);}fputc('}',f); for(int c=0;c