Files
SystemSimulationApp/tests/manual/context_access_diag.c
T
ljz 7611f13208 修复循环信号与事件采样并接入 LSTP 接触定位,补充八路验证及复用实验
相较上一版 Jacobian 确定性复用更新,本次补齐事件边界一致性、结果两侧采样及接触事件定位;保留已有物性复用和组件力学公式。

- 统一 UD00 信号求值与下一事件查询的绝对时间边界,修复循环边界浮点舍入导致的阶段错位、重复或漏报,并覆盖零时长、多阶段及长周期场景。
- 引入原生输出语义 v2:保留规则网格真实时间,补充内部时间事件和状态事件的左邻及事件后采样,按保存时间、状态和离散模式重放结果。
- 两条代码生成路径均发出 LSTP 接触描述,默认定位间隙过零及非负力模式的力截断;仅在接受事件时更新防重复记录,增加 contactEvents 诊断计数。
- 补充 MASS/LSTP 独立事件实验、八路全曲线与驱动阶段配对评估,以及 Amesim 不连续点输出对照和力差定位报告;MASS 新增释放机制仍保留为独立实验。
- 保存局部 probe、context 访问与回退、shadow replay、R288 real skip/typed replay 及阀门数值尾部诊断工具和报告;未证明净收益的实验不启用为生产默认优化。
- 更新原生运行说明和元件建模规范,补充信号边界、输出语义、接触事件和实验依赖回归测试。

验证:五组专项回归共 34 项全部通过;37 个待提交 Python 文件语法检查通过;git diff --cached --check 通过。
2026-09-17 23:50:13 +08:00

70 lines
5.1 KiB
C

/* Access events are primary evidence; snapshots are only the replay oracle. */
#include "context_access_diag.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
static FILE *ax_file;
static NativePropertyCache *ax_cache;
static NativePipeCache *ax_pipes;
static int ax_active,ax_pending;
static unsigned long long ax_id;
static void hex(const void *p,size_t n){const unsigned char *b=p;for(size_t i=0;i<n;i++)fprintf(ax_file,"%02x",b[i]);}
static void blob(const char *name,const void *p,size_t n){fprintf(ax_file,"\"%s\":\"",name);hex(p,n);fputc('"',ax_file);}
static void snapshot(const char *phase){
fprintf(ax_file,"{\"event\":\"snapshot\",\"phase\":\"%s\",\"count\":%llu,",phase,(unsigned long long)ax_cache->count);
blob("context",ax_cache,sizeof(*ax_cache));fputc(',',ax_file);
blob("states",ax_cache->states,ax_cache->count*sizeof(*ax_cache->states));fputc(',',ax_file);
blob("pipes",ax_pipes,40*sizeof(*ax_pipes));fputs("}\n",ax_file);
}
static int locate(const void *ptr,size_t n,const char **domain,size_t *offset){
uintptr_t p=(uintptr_t)ptr;
const void *bases[]={ax_cache,ax_cache?ax_cache->states:NULL,ax_pipes};
size_t sizes[]={sizeof(*ax_cache),ax_cache?ax_cache->capacity*sizeof(*ax_cache->states):0,40*sizeof(*ax_pipes)};
const char *names[]={"context","states","pipes"};
for(int i=0;i<3;i++)if(bases[i] && p>=(uintptr_t)bases[i] && p-(uintptr_t)bases[i]+n<=sizes[i]){
*domain=names[i];*offset=p-(uintptr_t)bases[i];return 1;
}
return 0;
}
void ax_access(const char *action,const void *p,size_t n,const char *field,const char *fn){
if(!ax_active){return;}const char *domain;size_t offset;
if(!locate(p,n,&domain,&offset))return;
fprintf(ax_file,"{\"event\":\"%s\",\"domain\":\"%s\",\"offset\":%llu,\"field\":\"%s\",\"function\":\"%s\",",action,domain,(unsigned long long)offset,field,fn);
blob("value",p,n);fputs("}\n",ax_file);
}
void ax_bind(NativePropertyCache *p,NativePipeCache *pipes){ax_cache=p;ax_pipes=pipes;}
void ax_begin(unsigned long long jac,int group,int pos,double t,const double *inputs,int n){
ax_active=(pos==52 && (group==-1 || group==18)) || (pos==16 && (group==-1 || group==6));
if(!ax_active){return;}
if(!ax_file){ax_file=fopen("access.jsonl","wb");if(!ax_file)abort();setvbuf(ax_file,NULL,_IOFBF,1024*1024);}
ax_pending=1;
fprintf(ax_file,"{\"event\":\"begin\",\"id\":%llu,\"jac\":%llu,\"group\":%d,\"position\":%d,\"t\":%.17g,\"stateSize\":%llu,\"pipeSize\":%llu,",++ax_id,jac,group,pos,t,(unsigned long long)sizeof(NativePropertyState),(unsigned long long)sizeof(NativePipeCache));
blob("inputs",inputs,n*sizeof(double));fputs("}\n",ax_file);snapshot("entry");
}
void ax_end(const double *outputs,int n){if(!ax_active){return;}snapshot("exit");fputs("{\"event\":\"end\",\"completed\":true,",ax_file);blob("outputs",outputs,n*sizeof(double));fputs("}\n",ax_file);ax_active=0;}
void ax_result(int result){if(ax_pending){fprintf(ax_file,"{\"event\":\"eval_return\",\"result\":%d}\n",result);ax_pending=0;}}
void ax_finish(void){if(ax_file){fclose(ax_file);ax_file=NULL;}}
void ax_query(const char *kind,const NativeMedium *m,double p,double second){
if(!ax_active){return;}double key[]={p,second,m->R,m->cp,m->Tref,m->slope,m->mu,m->muT,m->S};
fprintf(ax_file,"{\"event\":\"query\",\"kind\":\"%s\",\"mediumKind\":%d,\"count\":%llu,",kind,m->real_helium,(unsigned long long)ax_cache->count);
blob("key",key,sizeof(key));fputs("}\n",ax_file);
}
void ax_match(const char *kind,NativePropertyState *s){if(!ax_active){return;}fprintf(ax_file,"{\"event\":\"match\",\"kind\":\"%s\",\"hit\":%s,\"slot\":%lld}\n",kind,s?"true":"false",s?(long long)(s-ax_cache->states):-1LL);}
void ax_new(NativePropertyCache *cache,NativePropertyState *s,int valid){
if(!ax_active){return;}const char *domain;size_t offset;int stored=locate(s,sizeof(*s),&domain,&offset) && !strcmp(domain,"states");
fprintf(ax_file,"{\"event\":\"allocate\",\"validInput\":%s,\"slot\":%lld,\"countAfter\":%llu,\"capacity\":%llu,\"branch\":\"%s\"}\n",valid?"true":"false",stored?(long long)(offset/sizeof(*s)):-1LL,(unsigned long long)(cache?cache->count:0),(unsigned long long)(cache?cache->capacity:0),stored?"append":"scratch");
}
unsigned ax_test(NativePropertyState *s,unsigned mask,const char *fn){
unsigned value=s->valid&mask;
if(ax_active){
const char *domain;size_t offset;
int stored=locate(s,sizeof(*s),&domain,&offset) && !strcmp(domain,"states");
fprintf(ax_file,"{\"event\":\"valid_test\",\"slot\":%lld,\"mask\":%u,\"value\":%u,\"function\":\"%s\"}\n",stored?(long long)(offset/sizeof(*s)):-1LL,mask,value,fn);
}
return value;
}
void ax_scalar(const char *action,NativeJacobianScalars *cache,int kind,int medium,const double *inputs,size_t n,int hit,const double *value){
if(!ax_active){return;}fprintf(ax_file,"{\"event\":\"scalar_%s\",\"kind\":%d,\"mediumKind\":%d,\"hit\":%d,\"recording\":%d,\"capacity\":%llu,",action,kind,medium,hit,cache?cache->recording:-1,(unsigned long long)(cache?cache->capacity:0));
blob("key",inputs,n*sizeof(double));if(value){fputc(',',ax_file);blob("value",value,sizeof(double));}fputs("}\n",ax_file);
}