143 lines
11 KiB
Python
143 lines
11 KiB
Python
#!/usr/bin/env python3
|
|
"""Fail-closed Phase 4O-A synthesis, frozen checks, and SHA-256 sealing."""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import shutil
|
|
from pathlib import Path
|
|
|
|
from phase4h_audit import verify_checksum
|
|
from phase4k import dataset_checks,seal
|
|
from phase4m import frozen_checks,frozen_hashes
|
|
from phase4n import load_config
|
|
from phase4o_a import EXP,MODEL,ROOT,save,sha
|
|
|
|
|
|
def read(path): return json.loads(path.read_text())
|
|
|
|
|
|
def frozen_integrity():
|
|
ncfg,mcfg,cfg,_=load_config(ROOT/'models/male-cns-lif/credit-assignment-v1/phase4n.yaml')
|
|
checks={}
|
|
for label,root,rel in [
|
|
('Phase4M experiment',Path(mcfg['experiment_root']),'manifests/checksums.sha256'),
|
|
('Phase4M model',Path(mcfg['model_root']),'checksums.sha256'),
|
|
('Phase4N experiment',Path(ncfg['experiment_root']),'manifests/checksums.sha256'),
|
|
('Phase4N model',Path(ncfg['model_root']),'checksums.sha256')]:
|
|
checks[label]=verify_checksum(root,root/rel)
|
|
earlier=frozen_checks(cfg)
|
|
datasets=dataset_checks(cfg)
|
|
current=frozen_hashes(cfg)
|
|
saved=read(Path(mcfg['experiment_root'])/'audit/final-summary.json')['integrity']['after']
|
|
report={'Phase4C_to_4L':earlier,'Phase4M_4N':checks,'Phase1_to_3B':datasets,
|
|
'frozen_input_hashes_unchanged':current==saved,
|
|
'all_static_checks_passed':bool(earlier['all_passed'] and datasets['all_passed'] and
|
|
all(x['passed'] for x in checks.values()) and current==saved)}
|
|
save(EXP/'audit/frozen-integrity-final.json',report)
|
|
return report
|
|
|
|
|
|
def main():
|
|
matrix=read(EXP/'phase4c-replay/summary.json')
|
|
replay=read(EXP/'eligibility-replay/event-replay-summary.json')
|
|
targeted=read(EXP/'eligibility-replay/targeted-summary.json')
|
|
atomic=read(EXP/'atomic/real-edge-subset.json')
|
|
backend=read(EXP/'binary-audit/loaded-backend.json')
|
|
environment=read(EXP/'environment/runtime-environment.json')
|
|
modes={p.stem:read(p) for p in sorted((EXP/'divergence').glob('mode-*.json'))}
|
|
matched=next(x for x in modes.values() if x['mode']=='instrumentation-on' and x['repeat']==1)
|
|
divergent=next(x for x in modes.values() if x['mode']=='instrumentation-on' and x['repeat']==0)
|
|
def state(run,step,when):
|
|
return next(x for x in run['state_window'] if x['step']==step and x['when']==when)
|
|
state_report={'first_observed_spike_event_divergence_step':6625,
|
|
'first_observed_divergent_neuron_idx':3942,
|
|
'biological_time_ms':662.5,
|
|
'pre_step_6625_matched':{k:state(matched,6625,'before')[k] for k in ('voltage','g','arrival_buffer','refractory')},
|
|
'pre_step_6625_divergent':{k:state(divergent,6625,'before')[k] for k in ('voltage','g','arrival_buffer','refractory')},
|
|
'matched_after_step_6625_voltage':state(matched,6625,'after')['voltage'],
|
|
'divergent_after_step_6625_voltage':state(divergent,6625,'after')['voltage'],
|
|
'matched_spiked_step_6625':bool(state(matched,6625,'after')['focus_spiked']),
|
|
'divergent_spiked_step_6625':bool(state(divergent,6625,'after')['focus_spiked']),
|
|
'matched_spiked_step_6626':bool(state(matched,6626,'after')['focus_spiked']),
|
|
'tracked_neuron_state_already_differs_by_step':6619,
|
|
'first_global_floating_state_divergence_exactly_located':False,
|
|
'classification':'FLOAT-ORDER-THRESHOLD-BIFURCATION'}
|
|
save(EXP/'divergence/first-divergence-forensic.json',state_report)
|
|
source=ROOT/'models/male-cns-lif/runtime-v1'
|
|
old_build=ROOT/'experiments/phase4c-runtime/compiler-reports/extension-build'
|
|
new_build=EXP/'compiler-reports/extension-build'
|
|
binary={'frozen_runtime_source_sha256':{x:sha(source/x) for x in ('phase4c.py','phase4c_ext.cpp','phase4c_ext.cu','phase4c.yaml')},
|
|
'historical_extension_sha256':sha(old_build/'male_cns_lif_runtime_v1_ext.so'),
|
|
'current_loaded_extension_sha256':backend['binary_sha256'],
|
|
'binary_bytewise_same':sha(old_build/'male_cns_lif_runtime_v1_ext.so')==backend['binary_sha256'],
|
|
'historical_build_ninja_sha256':sha(old_build/'build.ninja'),
|
|
'current_build_ninja_sha256':sha(new_build/'build.ninja'),
|
|
'toolkit_path_historical':'/usr/local/cuda-12.6',
|
|
'toolkit_path_current':'/usr/local/cuda',
|
|
'toolkit_realpath_current':'/usr/local/cuda-12.6',
|
|
'source_and_arch_flags_unchanged_except_absolute_build_paths':True,
|
|
'interpretation':'ELF hashes differ; build manifests differ in absolute source/toolkit paths while /usr/local/cuda resolves to CUDA 12.6. No proof that binary difference caused the stochastic bifurcation.'}
|
|
save(EXP/'binary-audit/runtime-binary-diff-report.json',binary)
|
|
rows=read(EXP/'phase4c-replay/reproducibility-matrix.json')
|
|
rng={'input_generator_before_first_unique_hashes_by_trial':{},'input_generator_after_trial_unique_hashes_by_trial':{}}
|
|
for trial in matrix['trial_summary']:
|
|
subset=[x for x in rows if x['trial']==trial]
|
|
rng['input_generator_before_first_unique_hashes_by_trial'][trial]=len({x['rng_before_first_timestep']['input_generator'] for x in subset})
|
|
rng['input_generator_after_trial_unique_hashes_by_trial'][trial]=len({x['rng_after_trial']['input_generator'] for x in subset})
|
|
rng['mechanosensory_input_generator_states_identical_in_all_10_repeats']=rng['input_generator_before_first_unique_hashes_by_trial']['mechanosensory-50hz']==1 and rng['input_generator_after_trial_unique_hashes_by_trial']['mechanosensory-50hz']==1
|
|
save(EXP/'rng/summary.json',rng)
|
|
integrity=frozen_integrity()
|
|
# Frozen Phase4C spike 49/50 and frozen Phase4M eligibility 498/500 each
|
|
# independently fail the conjunctive Part A gate. No Part B is executed.
|
|
gate={'five_phase4c_trials_10_of_10_spike_events_exact':matrix['all_spike_events_exact'],
|
|
'five_phase4c_trials_10_of_10_per_neuron_counts_exact':matrix['all_counts_exact'],
|
|
'mechanosensory_divergence_absent':matrix['trial_summary']['mechanosensory-50hz']['event_exact']==10,
|
|
'phase4m_500_eligibility_5_complete_repeats_exact_to_frozen':replay['all_exact_to_frozen_phase4m'],
|
|
'event_sequence_repeated_exactly_5_of_5':replay['same_event_and_update_sequence_5_of_5'],
|
|
'instrumentation_independence':False,
|
|
'logging_independence_proven':False,
|
|
'backend_identity_fixed':True,
|
|
'frozen_static_integrity':integrity['all_static_checks_passed']}
|
|
passed=all(gate[k] for k in ('five_phase4c_trials_10_of_10_spike_events_exact','five_phase4c_trials_10_of_10_per_neuron_counts_exact',
|
|
'mechanosensory_divergence_absent','phase4m_500_eligibility_5_complete_repeats_exact_to_frozen',
|
|
'instrumentation_independence','logging_independence_proven','backend_identity_fixed','frozen_static_integrity'))
|
|
result={'phase':'4O-A','status':'PASS-RUNTIME-DETERMINISM-RECOVERED' if passed else 'FAIL-RUNTIME-DETERMINISM',
|
|
'phase4o_b_executed':False,'deterministic_runtime_candidate_generated':False,
|
|
'phase4c_repeat_matrix':matrix['trial_summary'],
|
|
'first_divergence':state_report,
|
|
'root_cause':'Concurrent GPU scatter_add_ floating reduction order varies on real CSR fan-out; a few-ULP g/V difference at neuron 3942 crosses the -45 mV threshold one timestep earlier. Exact first floating-state operation before step 6619 is not located.',
|
|
'atomic_real_event_subset':{k:atomic[k] for k in ('fanout_edges','targets_with_multiple_concurrent_writes','maximum_same_target_writes','targets_with_nonidentical_atomic_sum_across_100_repeats','max_atomic_sum_range_mv')},
|
|
'eligibility_replay':{'same_sequence_5_of_5':replay['same_event_and_update_sequence_5_of_5'],
|
|
'frozen_exact_count_by_repeat':replay['frozen_exact_count_by_repeat'],
|
|
'mismatch_seed_pairing':[[51202,40],[51203,39]],
|
|
'mismatch_KC_neuron_idx':78836,
|
|
'mismatch_trace_absolute_error':0.12266039848327637,
|
|
'targeted_GPU':targeted,
|
|
'cause':'KC spike at step 899 versus step 904 around the step-900 external US. Offline event ordering and trace update are repeat-exact; upstream LIF trajectory bifurcates.'},
|
|
'RNG':rng,'backend':backend,'binary_audit':binary,'environment':{'torch':environment['torch'],'cuda_runtime':environment['cuda_runtime'],
|
|
'nvcc':environment['nvcc']['stdout'],'driver_gpu':environment['nvidia_smi']['stdout']},
|
|
'mode_matrix':{k:{x:v for x,v in m.items() if x not in ('state_window','backend')} for k,m in modes.items()},
|
|
'part_a_gate':gate,'frozen_static_integrity':integrity['all_static_checks_passed'],
|
|
'limitations':['A single exact first global floating-state divergence operation was not localized; tracked neuron 3942 already differs at step 6619.',
|
|
'Historical Phase4M training KC events were not sealed, so the two historical event timelines cannot be directly replayed byte-for-byte.',
|
|
'Logging OFF has final-state/count comparison only; no event sequence was recorded by design.'],
|
|
'part_b_not_started_reason':'Part A conjunctive PASS gate failed; eligibility-v3 calibration, learning controls and candidates are prohibited.'}
|
|
save(EXP/'audit/final-summary.json',result)
|
|
if Path(__file__).resolve() != (MODEL/'phase4o_finalize.py').resolve():
|
|
shutil.copy2(Path(__file__),MODEL/'phase4o_finalize.py')
|
|
if Path(__file__).with_name('phase4o.yaml').resolve() != (MODEL/'phase4o.yaml').resolve():
|
|
shutil.copy2(Path(__file__).with_name('phase4o.yaml'),MODEL/'phase4o.yaml')
|
|
save(MODEL/'VERSION.json',{'name':'MaleCNS-runtime-credit-v1-audit','phase':'4O-A','status':result['status'],
|
|
'runtime_v2_deterministic_candidate_generated':False,'eligibility_v3_experimental_started':False,
|
|
'frozen_runtime_v1_overwritten':False,'summary_sha256':sha(EXP/'audit/final-summary.json')})
|
|
seal(MODEL,MODEL/'MANIFEST.json',MODEL/'checksums.sha256')
|
|
seal(EXP,EXP/'manifests/manifest.json',EXP/'manifests/checksums.sha256')
|
|
own={'model':verify_checksum(MODEL,MODEL/'checksums.sha256')['passed'],
|
|
'experiment':verify_checksum(EXP,EXP/'manifests/checksums.sha256')['passed']}
|
|
print(json.dumps({'status':result['status'],'part_B_executed':False,'phase4c':matrix['trial_summary'],
|
|
'eligibility_5_repeats':replay['frozen_exact_count_by_repeat'],
|
|
'static_integrity':integrity['all_static_checks_passed'],'own_sha256':own},indent=2),flush=True)
|
|
|
|
|
|
if __name__=='__main__':main()
|