/* Standalone R288/position16 experiment. Never linked into production. */ #include "real_skip.h" #include #include "real_skip_core.inc" int rr_original_scope,rr_replaying; unsigned long long rr_native_calls; static unsigned long long visits,attempts,successes,rejects,commits,fallbacks,reject_reason[NREASONS]; static unsigned long long eval_audits,entry_audits,exit_audits,rollback_checks; static unsigned long long appends_total,relocations,count_different,paths[4]; static uint64_t frequency,path_ticks,original_ticks,validation_ticks,overlay_ticks,commit_ticks,fallback_ticks,baseline_ticks,baseline_start; static size_t metadata_min=(size_t)-1,metadata_max; static int force_every; #if RR_AUDIT /* Pointer identities are compared as owner bindings, never as cross-process addresses. * Padding is excluded; every declared numerical field is copied byte-for-byte. */ typedef struct { unsigned long long jacobian; int color,stage,status,saved_errno,flags,rounding; unsigned sse; double t,output,y[NSTATES],dy[NSTATES],w[NOUTPUTS]; size_t count,capacity,memo_capacity; int recording; unsigned long evaluations[NATIVE_JACOBIAN_SCALAR_KINDS],reuses[NATIVE_JACOBIAN_SCALAR_KINDS]; NativePropertyState states[SR_STATES]; NativePipeCache pipes[SR_PIPES]; NativeJacobianGasMemo gases[MODEL_JACOBIAN_GAS_COUNT]; NativeJacobianGasStats gas_stats; } Audit; static FILE *audit_file,*matrix_file; static Audit actual,expected; static NativeJacobianScalarEntry baseline_entries[MODEL_JACOBIAN_SCALAR_COUNT],expected_entries[MODEL_JACOBIAN_SCALAR_COUNT]; static NativeJacobianScalars *memo_owner; static SRContext before_reject,after_reject; static void audit_fail(const char *where,const void *a,const void *b,size_t n){ size_t offset=0;while(offset=offsetof(Audit,n)&&off=offsetof(Audit,states)&&off=state_fields[i].offset && local=offsetof(Audit,pipes)&&off=pipe_fields[i].offset && localcount>SR_STATES || p->capacity!=SR_STATES || p->temperatures || !p->jacobian || p->jacobian->capacity!=MODEL_JACOBIAN_SCALAR_COUNT)fatal("audit context schema"); NativeJacobianScalars *m=p->jacobian; if(stage==3 && lp_color<0)memo_owner=m; else if(m!=memo_owner)fatal("memo owner lifetime"); if(m->recording!=(lp_color<0))fatal("memo recording lifetime"); if(workspace && (m!=&workspace->scalars || m->entries!=workspace->scalar_entries))fatal("workspace memo binding"); actual.count=p->count;actual.capacity=p->capacity;actual.memo_capacity=m->capacity;actual.recording=m->recording; memcpy(actual.evaluations,m->evaluations,sizeof(actual.evaluations));memcpy(actual.reuses,m->reuses,sizeof(actual.reuses)); for(size_t s=0;scount;s++){ if(p->states[s].jacobian!=m || p->states[s].temperatures)fatal("entry memo/observer binding"); for(size_t k=0;kstates[s]+state_fields[k].offset,state_fields[k].size); } for(int s=0;sstats; for(int i=0;igases[i],*dst=&actual.gases[i]; uintptr_t id=src->kernel==NULL?0:src->kernel==native_medium_gas_context?1:src->kernel==native_polytropic_gas_context?2:999; if(id==999)fatal("unknown gas memo kernel"); memcpy(&dst->kernel,&id,sizeof(id));memcpy(dst->inputs,src->inputs,sizeof(dst->inputs));dst->value=src->value;dst->medium_kind=src->medium_kind;dst->valid=src->valid; } } if(stage==3 && lp_color<0){ memcpy(baseline_entries,m->entries,sizeof(baseline_entries)); if(RR_SKIP){if(fread(expected_entries,1,sizeof(expected_entries),audit_file)!=sizeof(expected_entries))fatal("memo audit EOF");if(memcmp(expected_entries,baseline_entries,sizeof(baseline_entries)))audit_fail("memo_entries",expected_entries,baseline_entries,sizeof(baseline_entries));} else if(fwrite(baseline_entries,1,sizeof(baseline_entries),audit_file)!=sizeof(baseline_entries))fatal("memo audit write"); }else if(memcmp(baseline_entries,m->entries,sizeof(baseline_entries)))audit_fail("memo_readonly",baseline_entries,m->entries,sizeof(baseline_entries)); if(RR_SKIP){ if(fread(&expected,1,sizeof(expected),audit_file)!=sizeof(expected))fatal("audit EOF"); if(memcmp(&expected,&actual,sizeof(actual))){size_t i=0;while(((unsigned char*)&expected)[i]==((unsigned char*)&actual)[i])i++;audit_fail(audit_field(i),&expected,&actual,sizeof(actual));} }else if(fwrite(&actual,1,sizeof(actual),audit_file)!=sizeof(actual))fatal("audit write"); restore_environment(&env);errno=saved_errno; } void rr_eval_exit(double t,const double *y,const double *dy,const double *w,int result,NativePropertyCache *p,NativePipeCache *pipes,ModelJacobianWorkspace *workspace){ audit_context(3,t,y,dy,w,result,0,p,pipes,workspace);eval_audits++; } void rr_matrix(double t,const double *y,const double *matrix){ int e=errno;SREnvironment env;save_environment(&env); if(fwrite(&t,8,1,matrix_file)!=1 || fwrite(y,8,NSTATES,matrix_file)!=NSTATES || fwrite(matrix,8,NSTATES*NSTATES,matrix_file)!=NSTATES*NSTATES)fatal("matrix write"); restore_environment(&env);errno=e; } #endif void rr_start(void){ LARGE_INTEGER f;QueryPerformanceFrequency(&f);frequency=(uint64_t)f.QuadPart; #if RR_AUDIT audit_file=fopen(RR_SKIP?getenv("RR_EXPECTED"):"audit.bin",RR_SKIP?"rb":"wb");matrix_file=fopen("jacobians.bin","wb"); if(!audit_file || !matrix_file)fatal("open audit files"); setvbuf(audit_file,NULL,_IOFBF,1024*1024);setvbuf(matrix_file,NULL,_IOFBF,1024*1024); const char *s=getenv("RR_FORCE_REJECT_EVERY");force_every=s?atoi(s):0; #endif } void rr_jacobian(void){jac++;plan.ready=0;} void rr_record_begin(NativePropertyCache *p,NativePipeCache *pipes,const double *x){ baseline_start=lp_tick(); if(RR_SKIP){ax_bind(p,pipes);ax_begin(jac,-1,16,0,x,4);} } void rr_record_end(double output){if(RR_SKIP)ax_end(&output,1);baseline_ticks+=lp_tick()-baseline_start;} /* The translated write set is prepared before touching live storage. */ typedef struct {void *destination;const void *source;size_t size;int kind;unsigned mask;} Patch; static Patch patches[SR_EVENTS]; static NativeJacobianScalars *patch_owner; static NativePropertyTemperatures *patch_observer; static int build_patch(NativePropertyCache *p,NativePipeCache *pipes,const int *map){ int n=0;patch_owner=p->jacobian;patch_observer=NULL; for(int i=0;itype==ALLOCATE){item.destination=&p->count;item.kind=1;} else if(e->type==SCALAR){item.destination=&p->jacobian->reuses[e->slot];item.kind=2;} else if(e->type==WRITE_PIPE){item.destination=(char*)&pipes[e->slot]+e->offset;item.source=e->data;item.size=e->size;} else if(e->type==WRITE_STATE || e->type==WRITE_OR){ item.destination=(char*)&p->states[map[e->slot]]+e->offset;item.source=e->data;item.size=e->size; if(e->type==WRITE_OR){item.kind=3;item.mask=e->mask;} else if(e->offset==(int)offsetof(NativePropertyState,jacobian))item.source=&patch_owner; else if(e->offset==(int)offsetof(NativePropertyState,temperatures))item.source=&patch_observer; }else continue; patches[n++]=item; } return n; } static void commit(int n){ for(int i=0;ikind==1)(*(size_t*)p->destination)++; else if(p->kind==2)(*(unsigned long*)p->destination)++; else if(p->kind==3)(*(unsigned*)p->destination)|=p->mask; else memcpy(p->destination,p->source,p->size); } } double rr_execute(NativePropertyCache *p,NativePipeCache *pipes,const double *x,SROperation original){ visits++; #if RR_AUDIT audit_context(1,0,NULL,NULL,NULL,1,0,p,pipes,NULL);entry_audits++; #endif uint64_t start=lp_tick(),tick;double output; if(RR_SKIP){ attempts++;bound=p;bound_pipes=pipes;position=16;probe_entry_count=p->count;rr_replaying=1; int reason=OK,mapping[SR_STATES],appends=0; count_different+=(p->count!=plan.entry_count); tick=lp_tick(); if(p->count>SR_STATES || p->capacity>SR_STATES || p->count>p->capacity)reason=CAPACITY; else if(!p->jacobian || !p->jacobian->entries || p->jacobian->capacity>MODEL_JACOBIAN_SCALAR_COUNT)reason=MEMO_BINDING; else from_live(&overlay,p,pipes); overlay_ticks+=lp_tick()-tick; #if RR_AUDIT from_live(&before_reject,p,pipes); #endif tick=lp_tick();phase=CANDIDATE; double saved_output=plan.output; if(force_every && (attempts-1)%(unsigned)force_every==0)plan.output=NAN; if(!reason)reason=replay_overlay(&overlay,x,mapping,&appends); plan.output=saved_output;phase=OFF;validation_ticks+=lp_tick()-tick; if(!reason){ tick=lp_tick();int n=build_patch(p,pipes,mapping);overlay_ticks+=lp_tick()-tick; tick=lp_tick();commit(n);output=plan.output;commit_ticks+=lp_tick()-tick; commits++;successes++;appends_total+=appends;paths[plan.path]++; int relocated=0;for(int i=0;i=0 && mapping[i]!=i)relocated=1; relocations+=relocated; size_t bytes=sizeof(plan)-sizeof(plan.events)+(size_t)plan.n*sizeof(Event); if(bytesmetadata_max)metadata_max=bytes; }else{ rejects++;reject_reason[reason]++;rr_replaying=0; #if RR_AUDIT from_live(&after_reject,p,pipes); if(compare_contexts(&before_reject,&after_reject))fatal("reject altered live context"); rollback_checks++; #endif tick=lp_tick();rr_original_scope=1;output=original(p,pipes,x);rr_original_scope=0;fallback_ticks+=lp_tick()-tick;fallbacks++; } rr_replaying=0; }else{ tick=lp_tick();rr_original_scope=1;output=original(p,pipes,x);rr_original_scope=0;original_ticks+=lp_tick()-tick; } path_ticks+=lp_tick()-start; #if RR_AUDIT audit_context(2,0,NULL,NULL,NULL,1,output,p,pipes,NULL);exit_audits++; #endif return output; } void rr_finish(void){ #if RR_AUDIT if(RR_SKIP && fgetc(audit_file)!=EOF)fatal("unconsumed audit records"); fclose(audit_file);fclose(matrix_file); #endif FILE *f=fopen("real-skip.json","wb");if(!f)fatal("summary"); fprintf(f,"{\"targetVisits\":%llu,\"candidateAttempts\":%llu,\"semanticSuccess\":%llu,\"realSkips\":%llu,\"rejects\":%llu,\"fallbackExecutions\":%llu,\"nativeOriginalExecutions\":%llu,\"commits\":%llu,\"referenceExecutions\":0,\"mismatches\":0,\"evaluationAudits\":%llu,\"targetEntryAudits\":%llu,\"targetExitAudits\":%llu,\"rollbackChecks\":%llu,",visits,attempts,successes,successes,rejects,fallbacks,rr_native_calls,commits,eval_audits,entry_audits,exit_audits,rollback_checks); fprintf(f,"\"pathSeconds\":%.12g,\"originalSeconds\":%.12g,\"validationSeconds\":%.12g,\"overlayPatchSeconds\":%.12g,\"commitSeconds\":%.12g,\"fallbackSeconds\":%.12g,\"baselineRecordSeconds\":%.12g,",(double)path_ticks/frequency,(double)original_ticks/frequency,(double)validation_ticks/frequency,(double)overlay_ticks/frequency,(double)commit_ticks/frequency,(double)fallback_ticks/frequency,(double)baseline_ticks/frequency); fprintf(f,"\"countDifferent\":%llu,\"slotRelocationTrials\":%llu,\"appends\":%llu,\"paths\":[%llu,%llu,%llu,%llu],\"metadataMin\":%llu,\"metadataMax\":%llu,\"metadataReserved\":%llu,\"overlayBytes\":%llu,\"patchReserved\":%llu,\"rejectReasons\":{",count_different,relocations,appends_total,paths[0],paths[1],paths[2],paths[3],(unsigned long long)(metadata_min==(size_t)-1?0:metadata_min),(unsigned long long)metadata_max,(unsigned long long)sizeof(plan),(unsigned long long)sizeof(overlay),(unsigned long long)sizeof(patches)); for(int i=1;i1?",":"",reasons[i],reject_reason[i]); fputs("}}\n",f);fclose(f); }