Bind synthetic edge cases and GPU comparisons to original CPU oracle

This commit is contained in:
Digital Drosophila Archive
2026-10-01 14:34:22 +08:00
parent 2191deef54
commit 906e6f17c0
3 changed files with 213 additions and 7 deletions
@@ -0,0 +1,49 @@
"""Read-only rehash of the saved Phase4AR shutdown inventory and registered sources."""
import argparse
from datetime import datetime, timezone
import hashlib
import json
from pathlib import Path
import subprocess
import time
INVENTORY = Path('/home/qishizhe/phase4ar-user-shutdown-20260930T203113Z/saved-files.sha256.jsonl')
INVENTORY_SHA = 'd7b675b0d0d4647d8fe2fcf9616b9a599e5bc3c15565e604e0d66a046afb835a'
REG = Path('/data/digital-drosophila/experiments/phase4ar-normal-conditioning/protocol/preregistered.json')
REG_SHA = 'b63e6281b6505ca3b60acb467dd0b3fae274cf513dcbfd653649ba52e9ba9740'
def sha(path):
h = hashlib.sha256()
with Path(path).open('rb') as f:
for chunk in iter(lambda: f.read(8 << 20), b''): h.update(chunk)
return h.hexdigest()
p = argparse.ArgumentParser()
p.add_argument('--output', type=Path, required=True)
a = p.parse_args()
assert not a.output.exists() and a.output.parent.is_dir()
start = time.perf_counter()
assert sha(INVENTORY) == INVENTORY_SHA and sha(REG) == REG_SHA
records = [json.loads(line) for line in INVENTORY.read_text().splitlines()]
differences = []
for row in records:
path = Path(row['path'])
if not path.is_file() or path.stat().st_size != row['bytes'] or sha(path) != row['sha256']:
differences.append(str(path))
reg = json.loads(REG.read_text())
source_mismatches = [path for path, expected in reg['source_sha256'].items() if sha(path) != expected]
head = subprocess.check_output(['git', '-C', '/data/digital-drosophila', 'rev-parse', 'HEAD'], text=True).strip()
status = subprocess.check_output(['git', '-C', '/data/digital-drosophila', 'status', '--porcelain'], text=True)
summary = dict(status='PASS' if not differences and not source_mismatches and status == '' else 'FAIL',
created_utc=datetime.now(timezone.utc).isoformat(), files_checked=len(records),
bytes_checked=sum(r['bytes'] for r in records), inventory_sha256=INVENTORY_SHA,
registration_sha256=REG_SHA, registered_science_commit=reg['source_code_commit'],
sources_checked=len(reg['source_sha256']), file_mismatches=differences,
source_mismatches=source_mismatches, original_git_head=head, original_git_status=status,
wall_seconds=time.perf_counter()-start,
scope='Saved Phase4AR experiment/control files and registered source files; NOT a new Phase1-4AQ numerical regression',
training_epochs_cpu_verified_unchanged=1033, probes_completed_unchanged=138,
original_experiment_resumed=False)
with a.output.open('x') as f: json.dump(summary, f, indent=2)
print(json.dumps(summary), flush=True)
raise SystemExit(0 if summary['status'] == 'PASS' else 1)
@@ -97,9 +97,16 @@ def load_fixtures(manifests):
common_identity = identity common_identity = identity
assert common_identity == identity, 'Full KC/mask/base identity differs across fixtures' assert common_identity == identity, 'Full KC/mask/base identity differs across fixtures'
assert len(a['kc']) == 4064 and len(a['candidate_edge_id']) == 14232 assert len(a['kc']) == 4064 and len(a['candidate_edge_id']) == 14232
source_pins = read(npz.parent / 'reference-sources.json') sources_path = npz.parent / 'reference-sources.json'
for info in source_pins.values(): assert sha(sources_path) == m['files'][sources_path.relative_to(root).as_posix()]['sha256']
assert sha(info['path']) == info['sha256'], 'Reference source changed' source_pins = read(sources_path)
expected_sources = dict(
conditioning_update_source='96efff678cff910654eb08e86f1a17789e4e5589e340345f419c7027a7d547e2',
eligibility_bridge_source='174fb8d14619189e74b095e77a6db18b14c93046dc431c0b55710a5aa2dd2e61',
phase4j_source='abb4574da85f00bd9ef61024c65993ef81d42651ff8d8d63c15dd69c6222471e')
assert set(source_pins) == set(expected_sources)
for role, info in source_pins.items():
assert info['sha256'] == expected_sources[role] and sha(info['path']) == info['sha256'], 'Reference source changed'
# Extract constants from the authenticated original bridge, without import/exec. # Extract constants from the authenticated original bridge, without import/exec.
import ast import ast
bridge = source_pins['eligibility_bridge_source'] bridge = source_pins['eligibility_bridge_source']
@@ -118,6 +125,33 @@ def load_fixtures(manifests):
assert fixtures assert fixtures
return fixtures, common_identity return fixtures, common_identity
def check_rejections(manifests, backend, rule):
reports = []
for path in manifests:
for case in read(path).get('invalid_cases', []):
root = path.parent
npz, command = contained(root, case['npz']), contained(root, case['command'])
assert sha(npz) == case['npz_sha256'] and sha(command) == case['command_sha256']
with np.load(npz, allow_pickle=False) as z:
a = {k: z[k].copy() for k in z.files}
c = read(command)
commands = [] if c['us_tick'] is None else [c['us_tick']]
stage = 'prepare'
try:
prepared = prepare_events(a['step'], a['neuron_idx'], a['kc'], c['steps'], commands,
n_neurons=c['n_neurons'])
stage = 'run'
backend.run(prepared, a['candidate_sources'], a['candidate_compartments'],
c['compartment'], a['delta_before'], a['base_candidate'],
d=c['d_command'], frozen=c['frozen'], **rule)
except ValueError as error:
assert stage == case['stage'], 'Rejected at a different validation boundary'
reports.append(dict(case_name=case['case_name'], rejected=True,
stage=stage, expected_exception=case['expected_exception'], message=str(error)))
else:
raise AssertionError('Candidate accepted invalid case: ' + case['case_name'])
return reports
def main(args): def main(args):
assert os.environ.get('CUDA_VISIBLE_DEVICES') == args.uuid, 'Use one explicit physical UUID per process' assert os.environ.get('CUDA_VISIBLE_DEVICES') == args.uuid, 'Use one explicit physical UUID per process'
assert args.output.is_absolute() and not args.output.exists() assert args.output.is_absolute() and not args.output.exists()
@@ -193,11 +227,14 @@ def main(args):
median_ms=1000 * report['summaries']['replay_wall_including_preparation_and_comparison_seconds']['median'])), flush=True) median_ms=1000 * report['summaries']['replay_wall_including_preparation_and_comparison_seconds']['median'])), flush=True)
# Recheck original exported files at the end, not just at read time. # Recheck original exported files at the end, not just at read time.
load_fixtures(args.manifest) load_fixtures(args.manifest)
rejections = check_rejections(args.manifest, backend, fixtures[0]['rule'])
save(args.output / 'invalid-input-rejections.json', rejections)
result = dict(status='PASS-ELIGIBILITY-UPDATE-REPLAY-EQUIVALENCE', fixtures=len(reports), result = dict(status='PASS-ELIGIBILITY-UPDATE-REPLAY-EQUIVALENCE', fixtures=len(reports),
device=device, candidate_commit=commit, all_fixture_repeats_bitwise_exact=True, device=device, candidate_commit=commit, all_fixture_repeats_bitwise_exact=True,
observed_cuda_pool_reserved_peak_bytes=peak_reserved, gpu_after=gpu_snapshot(args.uuid), observed_cuda_pool_reserved_peak_bytes=peak_reserved, gpu_after=gpu_snapshot(args.uuid),
queues_after=idle_queues(), wall_seconds=time.perf_counter()-started, queues_after=idle_queues(), wall_seconds=time.perf_counter()-started,
original_experiment_resumed=False, brain_simulation_tested=False, original_experiment_resumed=False, brain_simulation_tested=False,
rejected_invalid_cases=len(rejections),
full_training_speedup_measured=False, learning_success_claimed=False, full_training_speedup_measured=False, learning_success_claimed=False,
coverage_limit='available prefix + fixed synthetic edge cases, not all registered conditions', coverage_limit='available prefix + fixed synthetic edge cases, not all registered conditions',
files={p.name: sha(p) for p in sorted(args.output.iterdir()) if p.is_file()}) files={p.name: sha(p) for p in sorted(args.output.iterdir()) if p.is_file()})
@@ -156,9 +156,113 @@ def fixed_cases(template):
'Synthetic generation changed an anatomical array: ' + name) 'Synthetic generation changed an anatomical array: ' + name)
original.require(not np.any((item['arrays']['delta_before'] == 0) original.require(not np.any((item['arrays']['delta_before'] == 0)
& np.signbit(item['arrays']['delta_before'])), 'Synthetic delta has negative zero') & np.signbit(item['arrays']['delta_before'])), 'Synthetic delta has negative zero')
cases[4]['trace_command_steps'] = [0, 900, 1199]
cases[4]['tags'].append('multiple-US-snapshots')
return cases return cases
def supplemental_worker(directory):
"""Fresh original CPU process for multiple snapshots or rejection evidence."""
original.cpu_environment()
import numpy as np
directory = original.unlinked(directory)
sources = original.read(directory / 'reference-sources.json')
expected = dict(conditioning_update_source=original.U_SHA,
eligibility_bridge_source=original.BRIDGE_SHA, phase4j_source=original.J_SHA)
original.require(set(sources) == set(expected), 'Supplemental source roles differ')
for role, sha in expected.items():
original.require(sources[role]['sha256'] == sha, 'Supplemental frozen source differs')
original.check(sources[role]['path'], sha)
if (directory / 'trace-command-steps.json').exists():
arrays = original.load_npz(directory / 'inputs.npz')
command = original.read(directory / 'command.json')
commands = original.read(directory / 'trace-command-steps.json')
bridge = original.load_verified_source('_synthetic_original_bridge',
sources['eligibility_bridge_source']['path'], original.BRIDGE_SHA)
trace = bridge.trace_from_events(arrays['step'], arrays['neuron_idx'], arrays['kc'],
command['steps'], commands, phase4j_source=sources['phase4j_source']['path'],
backend='torch', n_neurons=command['n_neurons'])
sole = original.load_npz(directory / 'reference.npz')
original.require(original.array_evidence(trace.final) == original.array_evidence(sole['reference_final_trace'])
and original.array_evidence(trace.last_command_trace)
== original.array_evidence(sole['reference_sampled_trace']),
'Multiple-US last sample or final differs from original single-US U reference')
original.save_npz(directory / 'multiple-reference.npz', dict(reference_snapshots=trace.snapshots,
reference_command_steps=trace.command_steps, reference_sampled_trace=trace.last_command_trace,
reference_final_trace=trace.final))
import torch
original.require(not torch.cuda.is_initialized(), 'Supplemental CPU oracle initialized CUDA')
original.save(directory / 'multiple-reference.json', dict(complete=True, trace_audit=trace.audit,
source_pins=sources, numpy_version=np.__version__, torch_version=torch.__version__,
final_and_last_sample_match_original_U=True, brain_executed=False, weights_installed=False))
return
cases = original.read(directory / 'invalid-selection.json')
update = original.load_verified_source('_synthetic_rejection_original_U',
sources['conditioning_update_source']['path'], original.U_SHA)
records = []
for item in cases:
arrays = original.load_npz(directory / item['npz'])
command = original.read(directory / item['command'])
try:
update.update_epoch(**arrays, **command,
bridge_source=sources['eligibility_bridge_source']['path'],
phase4j_source=sources['phase4j_source']['path'])
except ValueError as error:
records.append(dict(case_name=item['case_name'], rejected=True, exception='ValueError', message=str(error)))
else:
raise ValueError('Original U unexpectedly accepted invalid case: ' + item['case_name'])
original.save(directory / 'original-rejections.json', dict(complete=True, cases=records,
source_pins=sources, brain_executed=False, weights_installed=False))
def export_invalid(output, valid_case, sources):
import numpy as np
directory = output / 'invalid'
directory.mkdir()
original.save(directory / 'reference-sources.json', sources)
definitions = [('duplicate-events', 'prepare'), ('unsorted-events', 'prepare'),
('out-of-range-tick', 'prepare'), ('negative-zero-delta', 'run'),
('non-kc-candidate-source', 'run'), ('unsorted-kc', 'prepare')]
records = []
for index, (name, stage) in enumerate(definitions):
arrays = {key: value.copy() for key, value in valid_case['arrays'].items()}
if name == 'duplicate-events':
arrays['step'] = np.array([0, 0], np.int32)
arrays['neuron_idx'] = np.full(2, arrays['kc'][0], np.int32)
elif name == 'unsorted-events':
arrays['step'] = np.array([1, 0], np.int32)
arrays['neuron_idx'] = np.full(2, arrays['kc'][0], np.int32)
elif name == 'out-of-range-tick':
arrays['step'] = np.array([STEPS], np.int32)
arrays['neuron_idx'] = np.array([arrays['kc'][0]], np.int32)
elif name == 'negative-zero-delta':
arrays['delta_before'][0] = np.float32(-0.)
elif name == 'non-kc-candidate-source':
arrays['candidate_sources'][0] = int(np.flatnonzero(
~np.isin(np.arange(N_NEURONS, dtype=np.int32), arrays['kc']))[0])
elif name == 'unsorted-kc':
arrays['kc'] = arrays['kc'][::-1].copy()
npz = f'{index:02d}-{name}.npz'
command = f'{index:02d}-{name}.json'
original.save_npz(directory / npz, arrays)
original.save(directory / command, valid_case['command'])
records.append(dict(case_name=name, npz=npz, command=command, stage=stage,
expected_exception='ValueError', npz_sha256=original.digest(directory / npz),
command_sha256=original.digest(directory / command)))
original.save(directory / 'invalid-selection.json', records)
original.run_cpu([sys.executable, '-B', str(Path(__file__).absolute()), '--supplemental-worker', str(directory)],
directory, 'original-rejection')
evidence = original.read(directory / 'original-rejections.json')
original.require(evidence['complete'] is True and len(evidence['cases']) == len(records),
'Original rejection coverage incomplete')
for record, result in zip(records, evidence['cases']):
original.require(record['case_name'] == result['case_name'] and result['rejected'] is True,
'Original rejection identity differs')
record.update(npz='invalid/' + record['npz'], command='invalid/' + record['command'],
original_oracle_rejection=result)
return records
def export(template, output, metadata=None, manifest_path=None): def export(template, output, metadata=None, manifest_path=None):
original.cpu_environment() original.cpu_environment()
started = time.perf_counter() started = time.perf_counter()
@@ -195,6 +299,11 @@ def export(template, output, metadata=None, manifest_path=None):
for name in original.OUTPUT_ARRAYS: for name in original.OUTPUT_ARRAYS:
original.require(original.array_evidence(reference['reference_' + name]) == receipt['outputs'][name], original.require(original.array_evidence(reference['reference_' + name]) == receipt['outputs'][name],
'Synthetic reference output/receipt differs: ' + name) 'Synthetic reference output/receipt differs: ' + name)
if 'trace_command_steps' in item:
original.save(directory / 'trace-command-steps.json', item['trace_command_steps'])
original.run_cpu([sys.executable, '-B', str(Path(__file__).absolute()),
'--supplemental-worker', str(directory)], directory, 'multiple-reference')
reference.update(original.load_npz(directory / 'multiple-reference.npz'))
original.save_npz(directory / 'fixture.npz', {**item['arrays'], **reference}) original.save_npz(directory / 'fixture.npz', {**item['arrays'], **reference})
record = dict(fixture_id=fixture_id, kind='synthetic', name=item['name'], tags=item['tags'], record = dict(fixture_id=fixture_id, kind='synthetic', name=item['name'], tags=item['tags'],
npz=f'{fixture_id}/fixture.npz', command=f'{fixture_id}/command.json', npz=f'{fixture_id}/fixture.npz', command=f'{fixture_id}/command.json',
@@ -208,9 +317,13 @@ def export(template, output, metadata=None, manifest_path=None):
reference_timing=timing, reference_subprocess_wall_seconds=seconds, reference_timing=timing, reference_subprocess_wall_seconds=seconds,
input_arrays={name: original.array_evidence(value) for name, value in item['arrays'].items()}, input_arrays={name: original.array_evidence(value) for name, value in item['arrays'].items()},
output_arrays={name: original.array_evidence(value) for name, value in reference.items()}) output_arrays={name: original.array_evidence(value) for name, value in reference.items()})
if 'trace_command_steps' in item:
record['snapshot_scope'] = 'Original Torch bridge multiple-US snapshots; last sample matches original U single final-US output'
record['command_steps'] = item['trace_command_steps']
original.save(directory / 'fixture.json', record) original.save(directory / 'fixture.json', record)
fixtures.append(record) fixtures.append(record)
print(original.canonical(dict(fixture=fixture_id, kind='synthetic', complete=True)), flush=True) print(original.canonical(dict(fixture=fixture_id, kind='synthetic', complete=True)), flush=True)
invalid_cases = export_invalid(output, cases[5], sources)
for path, pin in pins.items(): for path, pin in pins.items():
original.check(path, pin) original.check(path, pin)
original.check(Path(__file__).absolute(), own) original.check(Path(__file__).absolute(), own)
@@ -220,6 +333,7 @@ def export(template, output, metadata=None, manifest_path=None):
exporter_source=dict(path=str(Path(__file__).absolute()), **own), exporter_source=dict(path=str(Path(__file__).absolute()), **own),
original_helper_source=dict(path=str(Path(original.__file__).absolute()), **helper), original_helper_source=dict(path=str(Path(original.__file__).absolute()), **helper),
created_utc=datetime.now(timezone.utc).isoformat(), fixtures=fixtures, fixture_count=len(fixtures), created_utc=datetime.now(timezone.utc).isoformat(), fixtures=fixtures, fixture_count=len(fixtures),
invalid_cases=invalid_cases, invalid_case_count=len(invalid_cases),
selection_sha256=original.digest(output / 'selection.json'), selection_sha256=original.digest(output / 'selection.json'),
template_binding_sha256=original.digest(output / 'template-binding.json'), template_binding_sha256=original.digest(output / 'template-binding.json'),
total_export_seconds=time.perf_counter() - started, original_files_modified=False, total_export_seconds=time.perf_counter() - started, original_files_modified=False,
@@ -233,10 +347,16 @@ def export(template, output, metadata=None, manifest_path=None):
if __name__ == '__main__': if __name__ == '__main__':
parser = argparse.ArgumentParser(description=__doc__) parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--template', type=Path, required=True) parser.add_argument('--template', type=Path)
parser.add_argument('--metadata', type=Path) parser.add_argument('--metadata', type=Path)
parser.add_argument('--manifest', type=Path) parser.add_argument('--manifest', type=Path)
parser.add_argument('--output', type=Path, required=True) parser.add_argument('--output', type=Path)
parser.add_argument('--supplemental-worker', type=Path, help=argparse.SUPPRESS)
args = parser.parse_args() args = parser.parse_args()
if args.supplemental_worker:
original.require(not any((args.template, args.output, args.metadata, args.manifest)), 'Do not combine worker/export modes')
supplemental_worker(args.supplemental_worker)
else:
original.require(args.template is not None and args.output is not None, '--template and --output are required')
result = export(args.template, args.output, args.metadata, args.manifest) result = export(args.template, args.output, args.metadata, args.manifest)
print(original.canonical(dict(complete=True, output=str(args.output), fixtures=result['fixture_count'])), flush=True) print(original.canonical(dict(complete=True, output=str(args.output), fixtures=result['fixture_count'])), flush=True)