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 <noreply@anthropic.com>
This commit is contained in:
parent
d797df9dea
commit
4126404ae8
1 changed files with 14 additions and 4 deletions
|
|
@ -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/<seed>/day/<day bytes>", 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
|
||||
|
|
|
|||
Loading…
Reference in a new issue