From 4126404ae8fdb140f027dcd54501d7e204b8802e Mon Sep 17 00:00:00 2001 From: igneum-labs <337424239+igneum-labs@users.noreply.github.com> Date: Thu, 8 Oct 2026 22:02:08 +0000 Subject: [PATCH] p01-vectors: the pack the worker holds is read from its ready line and every other segment is prepared (phase 3 on a worker started on the day D pack refused every day D+1 job at 22:56 UK: missing 1,048,576, no disagreement); the self-test's phase 3 runs on a day D worker Co-Authored-By: Claude Fable 5.1 --- tools/ci/p01-vectors.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/tools/ci/p01-vectors.py b/tools/ci/p01-vectors.py index ea9f9da25..a7d128b3d 100755 --- a/tools/ci/p01-vectors.py +++ b/tools/ci/p01-vectors.py @@ -86,7 +86,16 @@ def run(a): # jobs it can, never sends a job on a segment before that segment's prepared line, and when it has nothing to send it polls # the worker with a line a second (the worker answers "info ignored", or the prepared line first). One prepare is in flight at # a time (the worker refuses a second while one runs). A worker without prepare support cannot be driven across a boundary. - held = {i: (i == 0 and not a.prepare_first) for i in range(len(seg_fields))} + # the pack the worker holds is read from its ready line ("pack igneum-epoch//day/", the CUDA and OpenCL + # workers started on --pack); a segment on any other day is prepared, whichever phase (phase 3's worker started on the + # day D pack refused every day D+1 job as a day-seed mismatch at 22:56 UK: missing 1,048,576, no disagreement). A ready + # line without a pack label means the worker holds the first segment's pack unless --prepare-first says it holds none. + rt = ready.split(); resident = next((t for t in rt[1:] if 'igneum-epoch/' in t and '/day/' in t), None) + def holds(f): + if a.prepare_first: return False + if resident is None: return f is seg_fields[0][2] + return resident.endswith('/day/' + f[1]) and ('/' + f[0] + '/') in resident + held = {i: holds(seg_fields[i][2]) for i in range(len(seg_fields))} to_prepare = [i for i in range(len(seg_fields)) if not held[i]]; in_flight = None; prepare_sent = None; prepare_lines = [] if to_prepare and ' prepare 0' in ready: p.kill(); return {'error': f'the worker has no prepare support (ready line: {ready}); a pack by prepare or a day switch needs it'}, 2 def send_prepare(): @@ -166,7 +175,8 @@ def self_test(): # a fake worker: hashes nonce n as (n * 0x9e3779b97f4a7c15) mod 2^64; nonce 7 wrong when WRONG=1; nonce 9 never answered when DROP=1 w = os.path.join(d, 'worker.py') open(w, 'w').write('''import sys, os -print("ready fake-gpu 0 prepare " + ("0" if os.environ.get("NOPREPARE") == "1" else "1"), flush=True) +res0 = os.environ.get("RESIDENT", "cc" * 19) +print("ready fake-gpu 0 pack " + ("igneum-epoch/" + "aa" * 32 + "/day/" + res0 if res0 != "none" else "none") + " prepare " + ("0" if os.environ.get("NOPREPARE") == "1" else "1"), flush=True) pending_prepare = None; prep_lines_left = 0 resident = {os.environ.get("RESIDENT", "cc" * 19)} # the pack's day (the real worker starts on its --pack); another day needs prepare first, as the real worker (day seed mismatch otherwise) for line in sys.stdin: @@ -214,8 +224,8 @@ for line in sys.stdin: r = subprocess.run([sys.executable, __file__, '--worker', sys.executable, '--worker-arg', w, '--job-context', jc, '--phase', str(phase), '--job-nonces', '8', '--out', out] + list(extra), capture_output=True, text=True, env=e, timeout=120) return r.returncode, (json.load(open(out)) if os.path.exists(out) else {}), r.stdout + r.stderr for ph, s0, pid in ((1, 0, '0x1'), (3, 32, '0x2')): - rc, ev, o = gojc(ph, f'jc{ph}', env={'RESIDENT': 'dd' * 19} if ph == 3 else None) # phase 3's worker starts on the day D+1 pack - if not (rc == 0 and ev.get('verdict') == 'PASS' and ev['nonces'] == {'start': s0, 'count': 16} and ev['segments'][0]['program_id'] == pid and 'boundary' not in ev): print(f"self-test failed: phase {ph} of the job context was not a PASS on its range and pack: rc={rc} {ev.get('nonces')} {ev.get('segments')} {o[-200:]}"); fails = 1 + rc, ev, o = gojc(ph, f'jc{ph}') # the worker holds the day D pack in every phase, as the pods run it; phase 3 needs the day D+1 prepare + if not (rc == 0 and ev.get('verdict') == 'PASS' and ev['nonces'] == {'start': s0, 'count': 16} and ev['segments'][0]['program_id'] == pid and 'boundary' not in ev and (ph == 1) == ('prepare_lines' not in ev)): print(f"self-test failed: phase {ph} of the job context was not a PASS on its range and pack: rc={rc} {ev.get('nonces')} {ev.get('segments')} {o[-200:]}"); fails = 1 rc, ev, o = gojc(2, 'jc2') b = ev.get('boundary', {}) if not (rc == 0 and ev.get('verdict') == 'PASS' and ev['nonces'] == {'start': 16, 'count': 16} and b.get('nonce') == 24 and b.get('program_id_before') == '0x1' and b.get('program_id_after') == '0x2' and b.get('switched') is True and len(ev['segments']) == 2): print(f"self-test failed: phase 2 did not switch pack at the boundary nonce 24 with the boundary block: rc={rc} {b} {o[-200:]}"); fails = 1