Download tests/test_machine.py from AEUPH/hdcstorage: direct link, hf CLI and curl.
- Browser
- Download file 7.89 kB
-
https://huggingface.co/AEUPH/hdcstorage/resolve/main/tests/test_machine.py
- Command line
-
hf download hf://AEUPH/hdcstorage/tests/test_machine.py
-
curl -L -o test_machine.py https://huggingface.co/AEUPH/hdcstorage/resolve/main/tests/test_machine.py
7.89 kB
| """End-to-end tests for the HDC machine.""" | |
| import os | |
| import sys | |
| import unittest | |
| sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | |
| from hdc.assembler import assemble # noqa: E402 | |
| from hdc.interpreter import Machine # noqa: E402 | |
| from hdc.memory import HDCStorage # noqa: E402 | |
| D = 2000 | |
| def build(src, **kw): | |
| prog = assemble(src, d=D) | |
| machine = Machine(storage=HDCStorage(d=D), d=D, **kw) | |
| machine.load(prog) | |
| return machine | |
| class TestArithmetic(unittest.TestCase): | |
| def test_add_and_out(self): | |
| m = build( | |
| """ | |
| ldi R0, 5 | |
| ldi R1, 37 | |
| add R2, R0, R1 | |
| out R2 | |
| halt | |
| """ | |
| ) | |
| result = m.run() | |
| self.assertEqual(result["status"], "halted") | |
| self.assertEqual(result["output"], ["42"]) | |
| self.assertEqual(m.get_int(2), 42) | |
| def test_bitwise_ops(self): | |
| m = build( | |
| """ | |
| ldi R0, 12 | |
| ldi R1, 10 | |
| and R2, R0, R1 | |
| or R3, R0, R1 | |
| xor R4, R0, R1 | |
| not R5, R0 | |
| shl R6, R0, 2 | |
| shr R7, R0, 2 | |
| halt | |
| """ | |
| ) | |
| m.run() | |
| self.assertEqual(m.get_int(2), 12 & 10) | |
| self.assertEqual(m.get_int(3), 12 | 10) | |
| self.assertEqual(m.get_int(4), 12 ^ 10) | |
| self.assertEqual(m.get_int(5), ~12) | |
| self.assertEqual(m.get_int(6), 48) | |
| self.assertEqual(m.get_int(7), 3) | |
| def test_sub_negatives(self): | |
| m = build("ldi R0, 3\n ldi R1, 10\n sub R2, R0, R1\n out R2\n halt") | |
| self.assertEqual(m.run()["output"], ["-7"]) | |
| class TestControlFlow(unittest.TestCase): | |
| def test_counting_loop_with_cmp_jnz(self): | |
| m = build( | |
| """ | |
| ldi R0, 0 | |
| ldi R1, 1 | |
| ldi R2, 4 | |
| loop: | |
| add R0, R0, R1 | |
| cmp R0, R2 | |
| jnz loop | |
| out R0 | |
| halt | |
| """ | |
| ) | |
| result = m.run() | |
| self.assertEqual(result["output"], ["4"]) | |
| self.assertTrue(result["flag_z"]) | |
| def test_call_ret_and_push_pop(self): | |
| m = build( | |
| """ | |
| ldi R0, 7 | |
| push R0 | |
| call sub1 | |
| pop R2 | |
| out R2 | |
| out R3 | |
| halt | |
| sub1: | |
| ldi R3, 11 | |
| ret | |
| """ | |
| ) | |
| result = m.run() | |
| self.assertEqual(result["output"], ["7", "11"]) | |
| self.assertEqual(result["stack_depth"], 0) | |
| def test_jmp_skips_code(self): | |
| m = build( | |
| """ | |
| ldi R0, 1 | |
| jmp past | |
| ldi R0, 99 | |
| past: | |
| out R0 | |
| halt | |
| """ | |
| ) | |
| self.assertEqual(m.run()["output"], ["1"]) | |
| def test_step_advances_one_cell(self): | |
| m = build("ldi R0, 5\n ldi R1, 6\n halt") | |
| m.step() | |
| self.assertEqual(m.pc, 1) | |
| self.assertEqual(m.steps, 1) | |
| self.assertEqual(m.get_int(0), 5) | |
| self.assertEqual(len(m.trace), 1) | |
| self.assertEqual(m.trace[0].op, "LDI") | |
| class TestHyperdimensionalOps(unittest.TestCase): | |
| def test_bind_then_unbind_recovers_register(self): | |
| m = build( | |
| """ | |
| ldi R0, 5 | |
| ldi R1, 37 | |
| bind R2, R0, R1 | |
| bind R3, R2, R1 | |
| sim R4, R3, R0 | |
| out R4 | |
| halt | |
| """ | |
| ) | |
| m.run() | |
| # XOR binding is self-inverse, so the round trip is exact | |
| self.assertEqual(m.regs[3], m.regs[0]) | |
| self.assertEqual(m.get_int(4), 1000) | |
| self.assertEqual(m.output, ["1000"]) | |
| def test_bind_and_bundle_differ(self): | |
| m = build( | |
| """ | |
| ldi R0, 5 | |
| ldi R1, 37 | |
| bind R2, R0, R1 | |
| bundle R3, R0, R1 | |
| cmp R2, R3 | |
| halt | |
| """ | |
| ) | |
| m.run() | |
| self.assertNotEqual(m.regs[2], m.regs[3]) | |
| def test_permute_is_deterministic_and_decorrelating(self): | |
| m = build( | |
| """ | |
| ldi R0, 5 | |
| ldi R1, 37 | |
| bind R2, R0, R1 | |
| permute R3, R2, 5 | |
| permute R4, R2, 5 | |
| sim R5, R3, R4 | |
| sim R6, R3, R2 | |
| halt | |
| """ | |
| ) | |
| m.run() | |
| # same rotation of the same vector is bit-identical | |
| self.assertEqual(m.regs[3], m.regs[4]) | |
| self.assertEqual(m.get_int(5), 1000) | |
| # a rotation by 5 is near-orthogonal to its original | |
| self.assertLess(abs(m.get_int(6)), 300) | |
| def test_popcount(self): | |
| m = build("ldi R0, 1\n popc R1, R0\n halt") | |
| m.run() | |
| from hdc.hypervec import popcount | |
| self.assertEqual(m.get_int(1), popcount(m.regs[0])) | |
| class TestStorageOps(unittest.TestCase): | |
| def test_store_load_roundtrip(self): | |
| m = build( | |
| """ | |
| .name box | |
| ldi R0, 99 | |
| store box, R0 | |
| load R1, box | |
| out R1 | |
| halt | |
| """ | |
| ) | |
| self.assertEqual(m.run()["output"], ["99"]) | |
| self.assertEqual(m.storage.read("box"), m.regs[0]) | |
| self.assertEqual(m.get_int(1), 99) | |
| def test_recall_finds_stored_cell(self): | |
| m = build( | |
| """ | |
| .name probe | |
| ldi R0, 7 | |
| store probe, R0 | |
| recall R1, R0, 1 | |
| halt | |
| """ | |
| ) | |
| m.run() | |
| self.assertTrue(m.last_recall) | |
| self.assertEqual(m.last_recall[0][0], "probe") | |
| self.assertEqual(m.last_recall[0][2], 1.0) | |
| def test_memstat(self): | |
| m = build("memstat R0\n halt") | |
| m.run() | |
| self.assertEqual(m.get_int(0), len(m.storage)) | |
| def test_program_cells_live_in_storage(self): | |
| m = build("ldi R0, 1\n halt") | |
| self.assertEqual(m.prog_len, 2) | |
| for pc in range(m.prog_len): | |
| self.assertIn("code/%d" % pc, m.storage) | |
| class TestTraps(unittest.TestCase): | |
| def test_break_pauses_then_resumes(self): | |
| m = build( | |
| """ | |
| ldi R0, 1 | |
| break | |
| ldi R0, 2 | |
| out R0 | |
| halt | |
| """ | |
| ) | |
| result = m.run() | |
| self.assertEqual(result["status"], "break") | |
| self.assertEqual(result["output"], []) | |
| self.assertEqual(m.pc, 1) | |
| m.skip_break = True | |
| result = m.run() | |
| self.assertEqual(result["status"], "halted") | |
| self.assertEqual(result["output"], ["2"]) | |
| def test_tool_without_registry_faults_not_raises(self): | |
| m = build( | |
| """ | |
| .tool hdc.similarity | |
| ldi R0, 1 | |
| tool R1, R0, R0, hdc.similarity | |
| halt | |
| """ | |
| ) | |
| result = m.run() | |
| self.assertEqual(result["status"], "error") | |
| self.assertTrue(result["halted"]) | |
| def test_ret_on_empty_stack_faults(self): | |
| m = build("ret\n halt") | |
| result = m.run() | |
| self.assertEqual(result["status"], "error") | |
| class TestInspection(unittest.TestCase): | |
| def test_disasm_marks_current_cell(self): | |
| m = build("ldi R0, 1\n out R0\n halt") | |
| m.step() | |
| text = m.disasm(0, 3) | |
| self.assertIn("=>", text) | |
| self.assertIn("OUT", text) | |
| def test_regs_text_lists_registers(self): | |
| m = build("ldi R0, 5\n halt") | |
| m.run() | |
| text = m.regs_text() | |
| self.assertIn("R0", text) | |
| self.assertIn("R15", text) | |
| def test_reset_clears_state(self): | |
| m = build("ldi R0, 5\n out R0\n halt") | |
| m.run() | |
| self.assertEqual(m.output, ["5"]) | |
| m.reset() | |
| self.assertEqual(m.output, []) | |
| self.assertEqual(m.pc, 0) | |
| self.assertEqual(m.steps, 0) | |
| self.assertEqual(m.get_int(0), 0) | |
| if __name__ == "__main__": | |
| unittest.main() | |