import copy import unittest import numpy as np import engineering_inputs as e def inputs(): return dict(tick=np.array([0, 4, 5, 17, 18, 18, 19, 499, 500, 999], np.int32), neuron_idx=np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 166699], np.int32)) def spec(): return dict(name='unchanged', kind='fullgraph', steps=1000, dt_ms=.1, duration_ms=100., apl_delay_steps=18, record_history=False, training=False, model={'threshold_mv': -45, 'w_syn_mv_per_anatomical_synapse': .275}, apl={'gain': .01}, budget_root='/project/old', output_budget_bytes=2048, graph_dir='/project/frozen-graph', seed=1073741825) class ExactInputs(unittest.TestCase): def test_exact_boundaries_reconstruct_all_requests(self): original = inputs() intervals = [(0, 5), (5, 18), (18, 19), (19, 500), (500, 1000)] parts = [e.slice_requests(original, 1000, *span) for span in intervals] report = e.verify_partition(original, 1000, intervals, parts) self.assertTrue(report['complete']) self.assertEqual(parts[2]['tick'].tolist(), [0, 0]) self.assertEqual(parts[-1]['tick'].tolist(), [0, 499]) self.assertEqual(report['random_draws'], 0) for value in parts: for key in original: self.assertFalse(np.shares_memory(original[key], value[key])) def test_empty_intervals_are_explicit_not_lost(self): original = inputs() intervals = [(0, 20), (20, 499), (499, 1000)] parts = [e.slice_requests(original, 1000, *span) for span in intervals] self.assertEqual(len(parts[1]['tick']), 0) self.assertTrue(e.verify_partition(original, 1000, intervals, parts)['complete']) def test_bad_requests_never_silently_fixed(self): for mut in ('dtype', 'duplicate', 'order', 'bounds', 'shape', 'extra'): req = inputs() if mut == 'dtype': req['tick'] = req['tick'].astype(np.int64) elif mut == 'duplicate': req['tick'][1], req['neuron_idx'][1] = 0, 1 elif mut == 'order': req['tick'][1] = 10 elif mut == 'bounds': req['neuron_idx'][-1] = 166700 elif mut == 'shape': req['tick'] = req['tick'][:-1] else: req['seed'] = 1 with self.subTest(mut=mut), self.assertRaises(ValueError): e.slice_requests(req, 1000, 0, 1000) def test_partition_gap_overlap_changed_input_and_missing_tail_rejected(self): req = inputs() spans = [(0, 500), (500, 1000)] parts = [e.slice_requests(req, 1000, *x) for x in spans] for bad in ([(0, 500), (501, 1000)], [(0, 500), (499, 1000)], [(0, 500)]): with self.assertRaises(ValueError): e.verify_partition(req, 1000, bad, parts[:len(bad)]) parts[0]['neuron_idx'][0] = 123 with self.assertRaisesRegex(ValueError, 'changes actual requests'): e.verify_partition(req, 1000, spans, parts) def test_fresh_prefix_and_continued_specs_preserve_original(self): original = spec() before = copy.deepcopy(original) for start, stop, parent in ((0, 1000, None), (0, 18, None), (18, 19, 'a' * 64)): derived, audit = e.derive_spec(original, start=start, stop=stop, budget_root='/project/new', output_budget_bytes=8 * 1024**3, parent_sha=parent) self.assertEqual(original, before) self.assertEqual(derived['model'], original['model']) self.assertEqual(derived['apl'], original['apl']) self.assertIsNot(derived['model'], original['model']) self.assertEqual(derived['max_steps'], 1000) self.assertEqual(derived['steps'], stop - start) self.assertTrue(audit['all_other_fields_unchanged']) if start: self.assertEqual(derived['global_tick_offset'], start) def test_invalid_continuation_root_and_duration_rejected(self): for root in ('/project/old/sub', '/project', 'relative', '/project/../old', '//project/old', '//project/new'): with self.assertRaises(ValueError): e.derive_spec(spec(), start=0, stop=1000, budget_root=root, output_budget_bytes=10) for start, stop, parent in ((1, 20, None), (0, 10, 'a'*64), (True, 10, None), (0, 1001, None)): with self.assertRaises(ValueError): e.derive_spec(spec(), start=start, stop=stop, budget_root='/project/new', output_budget_bytes=10, parent_sha=parent) original = spec(); original['duration_ms'] = 1. with self.assertRaises(ValueError): e.derive_spec(original, start=0, stop=10, budget_root='/project/new', output_budget_bytes=10) def test_original_clock_type_and_no_within_trial_update_match_runtime(self): for key, value in (('apl_delay_steps', 18.), ('apl_delay_steps', True), ('within_trial_weight_updates', True), ('budget_root', '//project/old')): original = spec(); original[key] = value with self.subTest(key=key, value=value), self.assertRaises(ValueError): e.derive_spec(original, start=0, stop=10, budget_root='/project/new', output_budget_bytes=10) def test_overlay_is_declaration_translation_not_self_authorized_learned(self): original = dict(schema='phase4am-overlay-v1', overlay_name='zero', training=False, fixed_for_whole_trial=True, overlay_sha256='b'*64, mask_path='/project/mask.npy', mask_sha256=e.MASK_SHA, base_candidate_path='/project/base.npy', base_candidate_sha256='c'*64, aj_model_dir='/project/apl-timing-lab-v1', old_extra_field='preserved in original only') before = copy.deepcopy(original) result = e.adapt_overlay_manifest(original, '/project/overlay.py') self.assertEqual(original, before) self.assertEqual(result['schema'], 'phase4an-overlay-v1') self.assertNotIn('old_extra_field', result) self.assertEqual(result['overlay_sha256'], original['overlay_sha256']) for key, val in (('overlay_name', 'learned'), ('mask_sha256', 'd'*64), ('training', True), ('base_candidate_path', 'local')): bad = dict(original); bad[key] = val with self.subTest(key=key), self.assertRaises(ValueError): e.adapt_overlay_manifest(bad, '/project/overlay.py') if __name__ == '__main__': unittest.main()