C内核流量计算方法优化,前端文件名称读取优化
This commit is contained in:
1 parent
5d5a2e1843
commit
808c484f5b
94 files changed
+20163
-4418
No files matched your search
@@ -0,0 +1,91 @@
|
||||
"""Compare identical native models with the old fixed-point, previous and current pipe solvers.
|
||||
|
||||
Run with Python 3.12 from the repository; generated programs/results stay in --output-dir.
|
||||
The baseline ref is an explicit Git revision, never a frozen numerical result substituted for execution.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import argparse
|
||||
from hashlib import sha256
|
||||
import json
|
||||
from pathlib import Path
|
||||
import statistics
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
sys.path.insert(0, str(ROOT))
|
||||
from app.main import compile_system_xml_network
|
||||
from app.simulation.backends import simulation_config
|
||||
from app.simulation.native_codegen import build as builder
|
||||
from app.simulation.native_codegen.compiler import compile_native_program
|
||||
from app.simulation.native_codegen.input import load_input
|
||||
from app.simulation.native_codegen.runner import execute_native
|
||||
|
||||
OLD_ITERATION = '''double rough_limit=pipe_rough_limit(rr);
|
||||
double base=area*p*cm/sqrt(T),q=sqrt(d/(length*.02))*base;
|
||||
for(int i=0;i<(kind==0?64:16);i++) {
|
||||
double next=sqrt(d/(length*pipe_friction_prepared(4*fabs(q)/den,rr,rough_limit)))*base;
|
||||
if(fabs(next-q)<=fmax(1e-12,fabs(q)*1e-9)) return sign*next;
|
||||
q=.5*(q+next);
|
||||
}
|
||||
return sign*q;'''
|
||||
NEW_CALL = '''double base=area*p*cm/sqrt(T),K=pow(4*base/den,2)*d/length;
|
||||
return sign*native_pipe_resistance(K,rr,den/4,NULL)*den/4;'''
|
||||
|
||||
|
||||
def main():
|
||||
parser=argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('input',type=Path)
|
||||
parser.add_argument('--output-dir',type=Path,required=True)
|
||||
parser.add_argument('--baseline-ref',default='5d5a2e1')
|
||||
parser.add_argument('--runs',type=int,default=3)
|
||||
args=parser.parse_args()
|
||||
if args.runs<1:parser.error('--runs must be positive')
|
||||
out=args.output_dir.resolve();out.mkdir(parents=True,exist_ok=True)
|
||||
if (out/'summary.json').exists():parser.error('Choose a fresh output directory')
|
||||
revision=subprocess.check_output(['git','rev-parse',args.baseline_ref],cwd=ROOT,text=True).strip()
|
||||
xml,doc=load_input(args.input)
|
||||
program=compile_native_program(compile_system_xml_network(doc))
|
||||
config=simulation_config(doc.simulation)
|
||||
(out/'input.xml').write_bytes(xml)
|
||||
(out/('input'+args.input.suffix)).write_bytes(args.input.read_bytes())
|
||||
paths=subprocess.check_output(['git','ls-tree','-r','--name-only',revision,'native'],cwd=ROOT,text=True).splitlines()
|
||||
variants={}
|
||||
original_native=builder.NATIVE
|
||||
try:
|
||||
for variant in ('fixed-point','previous-newton','guarded-newton'):
|
||||
directory=out/variant
|
||||
for name in paths:
|
||||
if variant=='guarded-newton':data=(ROOT/name).read_bytes()
|
||||
else:data=subprocess.check_output(['git','show',f'{revision}:{name}'],cwd=ROOT)
|
||||
target=directory/name;target.parent.mkdir(parents=True,exist_ok=True);target.write_bytes(data)
|
||||
if variant=='fixed-point':
|
||||
target=directory/'native/components/kernels.c';source=target.read_text()
|
||||
if source.count(NEW_CALL)!=1:raise ValueError('Baseline pipe flow layout does not match the audited fixed-point substitution')
|
||||
target.write_text(source.replace(NEW_CALL,OLD_ITERATION))
|
||||
builder.NATIVE=directory/'native'
|
||||
variants[variant]=builder.build_native(program,cache_dir=out/'cache')
|
||||
finally:builder.NATIVE=original_native
|
||||
rows=[]
|
||||
for index in range(args.runs+1):
|
||||
order=list(variants)
|
||||
if index%2:order.reverse()
|
||||
for variant in order:
|
||||
data=execute_native(variants[variant],config,doc.simulation.sample_step,
|
||||
run_dir=out/variant/('warmup' if index==0 else f'run-{index}'),timeout=120)
|
||||
row={key:value for key,value in data.items() if key not in ('series','final','finalState')}
|
||||
row.update(variant=variant,run=index)
|
||||
rows.append(row);print(json.dumps(row,ensure_ascii=False),flush=True)
|
||||
if not data['success']:raise RuntimeError(f'{variant} did not complete: {data["message"]}')
|
||||
summary={'baselineRef':revision,'input':str(args.input.resolve()),
|
||||
'inputSha256':sha256(args.input.read_bytes()).hexdigest(),'xmlSha256':sha256(xml).hexdigest(),
|
||||
'settings':vars(config),'sampleStep':doc.simulation.sample_step,'rows':rows,
|
||||
'variants':{name:{'sourceSha256':sha256((out/name/'native/components/kernels.c').read_bytes()).hexdigest(),
|
||||
'buildKey':build.manifest['buildKey'],
|
||||
'medianSolveSeconds':statistics.median(row['solveSeconds'] for row in rows if row['variant']==name and row['run']>0),
|
||||
'medianProcessSeconds':statistics.median(row['processWallSeconds'] for row in rows if row['variant']==name and row['run']>0)}
|
||||
for name,build in variants.items()}}
|
||||
(out/'summary.json').write_text(json.dumps(summary,ensure_ascii=False,indent=2)+'\n')
|
||||
print(json.dumps(summary['variants'],ensure_ascii=False,indent=2))
|
||||
|
||||
if __name__=='__main__':main()
|
||||
Reference in new issue
Block a user