85 lines
5.5 KiB
Python
85 lines
5.5 KiB
Python
# coding: utf-8
|
|
from pathlib import Path
|
|
import importlib.util,json,hashlib,shutil,subprocess,sys,time
|
|
R=Path('/Users/korizatou114/Projects/とりにく工房ゲーム制作部');A=R/'artifacts/original-completion-2026-10-02';O=A/'p23-02-native-hot-loop-numeric-r328';P=A/'p23-02-native-guest-bulk-candidate-r313-r02/source/tree_core.hpp';C=A/'p23-02-native-hot-loop-candidate-r326/source/tree_core.hpp'
|
|
assert not O.exists() and shutil.disk_usage(A).free>=528*1048576;O.mkdir()
|
|
def pin(p):return dict(path=str(p),bytes=p.stat().st_size,sha256=hashlib.sha256(p.read_bytes()).hexdigest())
|
|
old=json.loads((A/'p23-02-native-bridge-build-r76/input.json').read_text());compiler=Path(old['compiler_pins']['clang++']['path']);assert pin(compiler)==old['compiler_pins']['clang++']
|
|
cpp='''#include <random>
|
|
#include <sstream>
|
|
#include <cassert>
|
|
#define the_tree_native original_numeric
|
|
#include "'''+str(P)+'''"
|
|
#undef the_tree_native
|
|
#define the_tree_native candidate_numeric
|
|
#include "'''+str(C)+'''"
|
|
#undef the_tree_native
|
|
using I=std::int64_t;
|
|
struct E {I neighbor,cost;};
|
|
std::string vec(const std::vector<I>& a) {std::ostringstream out;for(auto x:a)out<<x<<",";return out.str();}
|
|
template<class T> std::string result(const T &r,const std::vector<I>& calls) {
|
|
return r.status+"|"+vec(r.costs)+"|"+vec(r.parents)+"|"+vec(r.discovered)+"|"+vec(r.parent_discovered)+"|"+vec(r.settled)+"|"+vec(calls);
|
|
}
|
|
int main(int argc,char **argv) {
|
|
if(argc!=2)return 98; std::ofstream corpus(argv[1]);if(!corpus)return 98;
|
|
std::uint64_t cases=0;bool passed=true;
|
|
auto run=[&](I n,I start,const std::vector<I>& goals,const std::vector<std::vector<E>>& graph) {
|
|
std::vector<I> old_calls,new_calls;
|
|
auto old_provider=[&](I current) {old_calls.push_back(current);std::vector<original_numeric::Edge> r;for(auto e:graph[current])r.push_back({e.neighbor,e.cost});return r;};
|
|
auto new_provider=[&](I current) {new_calls.push_back(current);std::vector<candidate_numeric::Edge> r;for(auto e:graph[current])r.push_back({e.neighbor,e.cost});return r;};
|
|
auto old=original_numeric::search(n,start,goals,old_provider);
|
|
auto now=candidate_numeric::search(n,start,goals,new_provider);
|
|
const auto a=result(old,old_calls),b=result(now,new_calls);passed=passed && a==b;
|
|
corpus<<cases<<"\\t"<<n<<","<<start<<":"<<vec(goals)<<":";
|
|
for(const auto& row:graph) {for(auto e:row)corpus<<e.neighbor<<","<<e.cost<<";";corpus<<"/";}
|
|
corpus<<"\\t"<<a<<"\\t"<<b<<"\\n";++cases;
|
|
};
|
|
// Exhaustive directed 3-node binary graphs, including self-loops and all goal subsets.
|
|
for(I mask=0;mask<512;++mask) {
|
|
std::vector<std::vector<E>> g(3);for(I a=0;a<3;++a)for(I b=0;b<3;++b)if(mask&(I(1)<<(a*3+b)))g[a].push_back({b,1});
|
|
for(I start=0;start<3;++start)for(I target=0;target<8;++target) {std::vector<I> goals;for(I i=0;i<3;++i)if(target&(I(1)<<i))goals.push_back(i);run(3,start,goals,g);}
|
|
}
|
|
std::mt19937_64 rng(0x54524545333238ULL);
|
|
for(I test=0;test<4096;++test) {
|
|
I n=1+rng()%24;std::vector<std::vector<E>> g(n);
|
|
for(I i=0;i<n;++i)for(I j=0,count=rng()%6;j<count;++j) {
|
|
I node=rng()%(n+2)-1;I cost=1+rng()%12;
|
|
if(test%23==0)cost=0;if(test%29==0)cost=-1;if(test%31==0)cost=std::numeric_limits<I>::max();
|
|
g[i].push_back({node,cost});
|
|
}
|
|
std::vector<I> goals;for(I i=0,count=rng()%8;i<count;++i)goals.push_back(rng()%(n+2)-1);
|
|
run(n,rng()%(n+2)-1,goals,g);
|
|
}
|
|
// Explicit signed64 overflow, duplicate ties/edges, unknown goals and invalid starts.
|
|
const I maximum=std::numeric_limits<I>::max();
|
|
run(3,0,{2},{{{1,maximum}},{{2,1}}, {}});
|
|
run(4,0,{3,3,99},{{{2,1},{1,1},{1,1}},{{3,2}},{{3,2}}, {}});
|
|
run(0,-1,{},{});run(1,1,{0},{{}});
|
|
corpus.close();if(!corpus)return 98;
|
|
std::cout<<"NUMERIC_DIFFERENTIAL "<<cases<<" "<<(passed?"PASS":"FAIL")<<"\\n";
|
|
return passed?0:1;
|
|
}
|
|
'''
|
|
(O/'oracle.cpp').write_text(cpp);exe=O/'oracle';plan=[[str(compiler),'-std=c++17','-O2','-o',str(exe),str(O/'oracle.cpp')],[str(exe),str(O/'corpus.tsv')]]
|
|
protected={str(p):pin(p) for p in [P,C,compiler,Path(__file__),O/'oracle.cpp']};(O/'input.json').write_text(json.dumps(dict(pins=protected,argv=plan,case_count=16388,timeout_seconds=30,growth_cap_bytes=16*1048576,Godot_runs=0,unit_accepted=False),indent=2)+'\n')
|
|
rows=[];error=None
|
|
try:
|
|
for i,argv in enumerate(plan):
|
|
assert shutil.disk_usage(A).free>=528*1048576;start=time.monotonic()
|
|
process=subprocess.Popen(argv,stdout=subprocess.PIPE,stderr=subprocess.PIPE,start_new_session=True)
|
|
try:out,err=process.communicate(timeout=30)
|
|
except BaseException:
|
|
if process.poll() is None:process.terminate()
|
|
try:process.wait(timeout=3)
|
|
except subprocess.TimeoutExpired:process.kill();process.wait(timeout=3)
|
|
raise
|
|
(O/('phase%d.stdout'%i)).write_bytes(out);(O/('phase%d.stderr'%i)).write_bytes(err)
|
|
rows.append(dict(pid=process.pid,argv=argv,exit_code=process.returncode,seconds=time.monotonic()-start,ended=process.poll() is not None,foreign_signals=0))
|
|
assert process.returncode==0 and not err
|
|
assert sum(p.stat().st_size for p in O.rglob('*') if p.is_file())<=16*1048576
|
|
assert (O/'phase1.stdout').read_text()=='NUMERIC_DIFFERENTIAL 16388 PASS\n'
|
|
for path,p in protected.items():assert pin(Path(path))==p
|
|
except BaseException as ex:error=repr(ex)
|
|
(O/'execution.json').write_text(json.dumps(dict(passed=error is None,error=error,phases=rows,all_inputs_preserved=all(pin(Path(k))==v for k,v in protected.items()),corpus=pin(O/'corpus.tsv') if (O/'corpus.tsv').exists() else None,unit_accepted=False,performance_accepted=False),indent=2)+'\n')
|
|
print(json.dumps(dict(passed=error is None,error=error,phases=rows,corpus_bytes=(O/'corpus.tsv').stat().st_size if (O/'corpus.tsv').exists() else None)))
|