mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-10-07 17:31:49 -04:00
fix(tools): wave_judge.py takes the wave dir from WAVE (default .run/t4)
This commit is contained in:
+14
-13
@@ -1,14 +1,15 @@
|
||||
#!/usr/bin/env python3
|
||||
"""T4 judge — per-arm whole-binary gate (G3/P9, exit codes checked per R53), tree reset between arms,
|
||||
"""Wave judge (tools/wave_judge.py; born as the T4 judge) — per-arm whole-binary gate (G3/P9, exit codes checked per R53), tree reset between arms,
|
||||
then the union (best arm per fn) gated once and left in the tree for the commit. Reads targets from
|
||||
.run/t4/targets.json and drafts from .run/t4/<arm>/<fn>.c. Writes .run/t4/judge.json.
|
||||
Usage: judge.py [arms...] (default haiku sonnet opus ds)"""
|
||||
import sys, os, json, glob, subprocess, shutil, time
|
||||
REPO = '/home/musashi/bfm-decomp'; os.chdir(REPO)
|
||||
WAVEDIR = os.environ.get('WAVE', '.run/t4') # the wave's dir: <WAVEDIR>/targets.json, <WAVEDIR>/<arm>/<fn>.c
|
||||
sys.path.insert(0, 'tools'); import corpus
|
||||
UNION = '--union' in sys.argv
|
||||
ARMS = [a for a in sys.argv[1:] if not a.startswith('--')] or ['haiku', 'sonnet', 'opus', 'ds']
|
||||
targets = json.load(open('.run/t4/targets.json'))
|
||||
targets = json.load(open(WAVEDIR + '/targets.json'))
|
||||
T = {t['name']: t for t in targets}
|
||||
def sh(cmd, timeout=3600):
|
||||
return subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
|
||||
@@ -22,10 +23,10 @@ def reset_tree():
|
||||
r = sh(['git', 'status', '--porcelain', '--', 'src/', 'config/'])
|
||||
assert not r.stdout.strip(), 'tree not clean after reset:\n' + r.stdout
|
||||
def stage(arm, fns):
|
||||
d = '.run/t4/stage_%s' % arm; shutil.rmtree(d, ignore_errors=True)
|
||||
d = WAVEDIR + '/stage_%s' % arm; shutil.rmtree(d, ignore_errors=True)
|
||||
n = 0
|
||||
for fn in fns:
|
||||
src = '.run/t4/%s/%s.c' % (arm, fn)
|
||||
src = WAVEDIR + '/%s/%s.c' % (arm, fn)
|
||||
if not os.path.exists(src) or os.path.getsize(src) == 0: continue
|
||||
b = T[fn]['binary']; os.makedirs('%s/%s' % (d, b), exist_ok=True)
|
||||
shutil.copy(src, '%s/%s/%s.c' % (d, b, fn)); n += 1
|
||||
@@ -34,10 +35,10 @@ def gate(arm, fns):
|
||||
before = open_fns()
|
||||
d, n = stage(arm, fns)
|
||||
if n == 0: return {}, 'no drafts'
|
||||
bins = ','.join(sorted({T[f]['binary'] for f in fns if os.path.exists('.run/t4/%s/%s.c' % (arm, f))}))
|
||||
bins = ','.join(sorted({T[f]['binary'] for f in fns if os.path.exists(WAVEDIR + '/%s/%s.c' % (arm, f))}))
|
||||
t0 = time.time()
|
||||
r = sh(['flock', '.run/auto/draw.lock', '.venv/bin/python', 'tools/sweep_parallel.py', '--drafts', d, '--only', bins, '-j', '4'], 7200)
|
||||
open('.run/t4/gate_%s.log' % arm, 'w').write(r.stdout + r.stderr)
|
||||
open(WAVEDIR + '/gate_%s.log' % arm, 'w').write(r.stdout + r.stderr)
|
||||
# banked = INCLUDE_ASM lines the gate removed (git diff; immune to corpus's per-process cache)
|
||||
d = sh(['git', 'diff', '-U0', '--', 'src/']).stdout
|
||||
import re as _re
|
||||
@@ -47,14 +48,14 @@ def gate(arm, fns):
|
||||
def main():
|
||||
reset_tree()
|
||||
res = {'arms': {}, 'fns': {}}
|
||||
if os.path.exists('.run/t4/judge.json'):
|
||||
old = json.load(open('.run/t4/judge.json')); res['arms'] = old.get('arms', {})
|
||||
if os.path.exists(WAVEDIR + '/judge.json'):
|
||||
old = json.load(open(WAVEDIR + '/judge.json')); res['arms'] = old.get('arms', {})
|
||||
for a, v in res['arms'].items():
|
||||
for f in v.get('banked', []): res['fns'].setdefault(f, []).append(a)
|
||||
for arm in ARMS:
|
||||
fns = [t['name'] for t in targets]
|
||||
banked, note = gate(arm, fns)
|
||||
res['arms'][arm] = {'banked': sorted(banked), 'n_banked': len(banked), 'drafts': sum(1 for f in fns if os.path.exists('.run/t4/%s/%s.c' % (arm, f))), 'note': note}
|
||||
res['arms'][arm] = {'banked': sorted(banked), 'n_banked': len(banked), 'drafts': sum(1 for f in fns if os.path.exists(WAVEDIR + '/%s/%s.c' % (arm, f))), 'note': note}
|
||||
print('%-7s banked %2d / %2d drafts (%s)' % (arm, len(banked), res['arms'][arm]['drafts'], note), flush=True)
|
||||
for f in banked: res['fns'].setdefault(f, []).append(arm)
|
||||
reset_tree()
|
||||
@@ -63,20 +64,20 @@ def main():
|
||||
pick = {}
|
||||
for f, arms in res['fns'].items():
|
||||
pick[f] = sorted(arms, key=lambda a: order.index(a) if a in order else 99)[0]
|
||||
ud = '.run/t4/stage_union'; shutil.rmtree(ud, ignore_errors=True)
|
||||
ud = WAVEDIR + '/stage_union'; shutil.rmtree(ud, ignore_errors=True)
|
||||
for f, a in pick.items():
|
||||
b = T[f]['binary']; os.makedirs('%s/%s' % (ud, b), exist_ok=True)
|
||||
shutil.copy('.run/t4/%s/%s.c' % (a, f), '%s/%s/%s.c' % (ud, b, f))
|
||||
shutil.copy(WAVEDIR + '/%s/%s.c' % (a, f), '%s/%s/%s.c' % (ud, b, f))
|
||||
if pick and UNION:
|
||||
bins = ','.join(sorted({T[f]['binary'] for f in pick}))
|
||||
r = sh(['flock', '.run/auto/draw.lock', '.venv/bin/python', 'tools/sweep_parallel.py', '--drafts', ud, '--only', bins, '-j', '4'], 7200)
|
||||
open('.run/t4/gate_union.log', 'w').write(r.stdout + r.stderr)
|
||||
open(WAVEDIR + '/gate_union.log', 'w').write(r.stdout + r.stderr)
|
||||
d = sh(['git', 'diff', '-U0', '--', 'src/']).stdout
|
||||
import re as _re
|
||||
removed = set(_re.findall(r'^-INCLUDE_ASM\("[^"]+",\s*(func_\w+)\);', d, _re.M))
|
||||
res['union'] = {'picked': pick, 'banked': sorted(f for f in pick if f in removed), 'rc': r.returncode}
|
||||
print('union: %d picked, %d banked (rc=%d) — LEFT IN TREE for the commit' % (len(pick), len(res['union']['banked']), r.returncode))
|
||||
json.dump(res, open('.run/t4/judge.json', 'w'), indent=1)
|
||||
json.dump(res, open(WAVEDIR + '/judge.json', 'w'), indent=1)
|
||||
# per-band table (R41: denominators)
|
||||
band = lambda n: '<=50' if n <= 50 else ('51-120' if n <= 120 else '>120')
|
||||
for arm in res['arms']:
|
||||
|
||||
Reference in New Issue
Block a user