def test_migen_serialisation(self): """Serialise/deserialise a graph with a node with a PyMigenBody. Notes ----- The content of the bodies depends on the environment, i.e. how the test is executed. For this reason we just compare the structure of the graph here. """ DeltaGraph.clean_stack() datapath = os.path.join('deltalanguage', 'test', 'data') s = StateSaver(int) example_migen = MigenDUT(name='counter', vcd_name="/workdir/MigenDUT.vcd") with DeltaGraph() as graph: example_migen_out = example_migen.call(40, 2) s.save_and_exit( add_non_const(example_migen_out.out1, multiplier(example_migen_out.out2))) data, _ = serialise_graph(graph) self.assertEqual(type(data), bytes) g_capnp = deserialise_graph(data).to_dict() assert_capnp_content_types(self, g_capnp) with open(os.path.join(datapath, 'graph_with_migen_capnp.json'), 'r') as file: self.assertEqual(g_capnp, json.load(file))
def test_Array(self): # primitive elements are properly handled # int are passed as Int, not UInt self.check([1, 2, 3], Array(Int(), Size(3))) # for floats use a dot # might be a potential problem, due to python silent type downcasting self.check([1.0, 2.0, 3.0], Array(Float(), Size(3))) # bool are passed as Bool, not Int self.check([True, False, False], Array(Bool(), Size(3))) # encapsulation of compound types self.check([[1, 2, 3], [4, 5, 6]], Array(Array(Int(), Size(3)), Size(2))) # mixed types self.check([(1, 2, 3), (4, 5, 6)], Array(Tuple([int, int, int]), Size(2))) self.check(["hello", "world"], Array(Str(Size(5)), Size(2))) self.assertTrue( DeltaGraph.check_wire(Raw(Array(int, Size(2))), Raw(Array(int, Size(2))))) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(Raw(Array(int, Size(2))), Raw(Array(int, Size(3))))
def test_neq_type_diff(self): g1 = DeltaGraph() n1 = RealNode(g1, [], OrderedDict([('a', int)]), OrderedDict()) in_p_1 = InPort('a', int, n1, 0) g2 = DeltaGraph() n2 = RealNode(g2, [], OrderedDict([('a', float)]), OrderedDict()) in_p_2 = InPort('a', float, n2, 0) self.assertNotEqual(in_p_1, in_p_2)
def test_Record(self): """Only strict typing.""" self.assertTrue(DeltaGraph.check_wire(Record(RecBI), Record(RecBI))) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(Record(RecBI), Record(RecIB)) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(Record(RecBIS), Record(RecBI))
def setUp(self): DeltaGraph.clean_stack() @DeltaBlock(allow_const=False) def add_print_exit(a: Optional(int), b: Optional(int)) -> Void: print(a + b) raise DeltaRuntimeExit self.func = add_print_exit self.datapath = os.path.join('deltalanguage', 'test', 'data')
def test_Tuple(self): """Only strict typing.""" self.assertTrue( DeltaGraph.check_wire(Tuple([int, bool]), Tuple([int, bool]))) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(Tuple([int, bool]), Tuple([bool, int])) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(Tuple([int, bool]), Tuple([int, bool, bool]))
def test_Array(self): """Only strict typing.""" self.assertTrue( DeltaGraph.check_wire(Array(int, Size(8)), Array(int, Size(8)))) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(Array(int, Size(10)), Array(int, Size(8))) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(Array(int, Size(8)), Array(int, Size(10)))
def test_eq(self): g1 = DeltaGraph() n1 = RealNode(g1, [], OrderedDict([('a', int)]), OrderedDict()) in_p_1 = InPort('a', int, n1, 0) self.assertEqual(in_p_1, in_p_1) g2 = DeltaGraph() n2 = RealNode(g2, [], OrderedDict([('a', int)]), OrderedDict()) in_p_2 = InPort('a', int, n2, 0) self.assertEqual(in_p_1, in_p_2)
def test_Complex(self): """Only 64 and 128 bits are supported.""" for bits in (64, 128): for _ in range(1000): self.check_complex( random.uniform(-1, 1) + random.uniform(-1, 1) * 1j, Complex(Size(bits))) self.assertTrue(DeltaGraph.check_wire(Raw(complex), Raw(complex))) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(Raw(Complex(Size(64))), Raw(Complex(Size(128))))
def test_UInt(self): """Only 8, 16, 32 and 64 bits are supported.""" for bits in (8, 16, 32, 64): self.check(0, UInt(Size(bits))) self.check(2**bits - 1, UInt(Size(bits))) for _ in range(1000): self.check(random.randint(0, 2**bits - 1), UInt(Size(bits))) self.assertTrue( DeltaGraph.check_wire(Raw(UInt(Size(32))), Raw(UInt(Size(32))))) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(Raw(UInt(Size(32))), Raw(UInt(Size(64))))
def test_Float(self): """Only 32 and 64 bits are supported.""" precision_dict = {32: -23, 64: -52} for bits, precision in precision_dict.items(): for _ in range(1000): self.check_float(random.uniform(-1, 1), Float(Size(bits))) self.check(1 + 2**precision, Float(Size(bits))) self.assertTrue(DeltaGraph.check_wire(Raw(float), Raw(float))) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(Raw(Float(Size(32))), Raw(Float(Size(64))))
def test_DInt(self): """Only 8, 16, 32 and 64 bits are supported.""" for bits in (8, 16, 32, 64): self.check(-2**(bits-1), DInt(DSize(bits))) self.check(2**(bits-1) - 1, DInt(DSize(bits))) for _ in range(1000): self.check(random.randint(-2**(bits-1), 2**(bits-1) - 1), DInt(DSize(bits))) self.assertTrue(DeltaGraph.check_wire(DRaw(int), DRaw(int))) with self.assertRaises(DeltaTypeError): DeltaGraph.check_wire(DRaw(DInt(DSize(32))), DRaw(DInt(DSize(64))))
def test_neq_dest_diff(self): g1 = DeltaGraph() n1 = RealNode(g1, [], OrderedDict(), OrderedDict([('out_a', int)])) dest_n_1 = RealNode(g1, [], OrderedDict([('a', int)]), OrderedDict()) dest_1 = InPort('a', int, dest_n_1, 0) out_p_1 = OutPort('out_a', int, dest_1, n1) g2 = DeltaGraph() n2 = RealNode(g2, [], OrderedDict(), OrderedDict([('out_a', int)])) dest_n_2 = RealNode(g2, [], OrderedDict([('a', int)]), OrderedDict()) dest_2 = InPort('b', int, dest_n_2, 0) out_p_2 = OutPort('out_a', int, dest_2, n2) self.assertNotEqual(out_p_1, out_p_2)
def simple_graph(): """Define a simple graph with just 2 nodes.""" with DeltaGraph() as my_graph: one_int = return_4() printer(one_int) return my_graph
def test_forked_interactive_naming(self): """Test that checks a forked Interactive raises an error if the fork names clash with node attributes """ with self.assertRaises(NameError): with DeltaGraph(): interactive_forked.call()
def test_migen(self): with DeltaGraph("test_migen_wiring") as test_graph: c1 = DUT1(tb_num_iter=2000, name='counter1').call(i1=return_1000()) c2 = DUT1(tb_num_iter=2000, name='counter2').call(i1=c1.o1) print_then_exit(c2.o1) self.check_build(test_graph)
def test_python_template(self): py_template = NodeTemplate([('a', int), ('b', int)], [('out', int)]) with DeltaGraph("test_python_template") as test_graph: print_then_exit(py_template.call(a=1, b=2)) self.check_build(test_graph)
def test_cannot_fold_through_semi_const_multi_body(self): """If a node has both constant and non-constant bodies, then this node cannot be folded. .. note:: This behaviors might change so only the selected body (during execution) will define if the node can/cannot be folded. """ with DeltaGraph() as graph: n1 = add_const(4, foo_semi_const_1_t(3)) n2 = add_non_const(4, foo_semi_const_1_t(2)) # nodes producing constants are turned to constant nodes for node in graph.find_node_by_name('node'): self.assertIsInstance(node.body, PyConstBody) # this one is a non-constant one now self.assertIsInstance(n1.body, PyFuncBody) # this one is still a non-constant self.assertIsInstance(n2.body, PyFuncBody) self.assertTrue(graph.check())
def test_template_input_raises_exception(self): template_1 = NodeTemplate(inputs=[('a', bool)]) with self.assertRaises(DeltaTypeError): with DeltaGraph() as graph: template_1.call(a=add_const(1, 2)) graph.check()
def setUp(self): r"""Build the graph ``` / saver1 / placeholder -- saver2 \ \ saver3 ``` """ with DeltaGraph() as my_graph: saver1 = StateSaver(bool) saver2 = StateSaver(bool) saver3 = StateSaver(bool) val = placeholder_node_factory() saver1.save(val) saver2.save(val) saver3.save(val) def true() -> bool: return True val.specify_by_func(true) self.graph = my_graph self.savers = [saver1, saver2, saver3]
def test_const_selfloop(self): with DeltaGraph() as graph: p = placeholder_node_factory() p.specify_by_node(forward_const(p)) for node in graph.nodes: self.assertIsInstance(node.body, PyFuncBody)
def setUp(self): # obligatory and optional ports g = DeltaGraph() out_port_obl = OutPort( 'out', Int(), InPort(None, Int(), None, 0), RealNode(g, [], name='node_name'), ) out_port_opt = OutPort( 'out', Int(), InPort(None, Optional(Int()), None, 0), RealNode(g, [], name='node_name'), ) # 4 types of queues self.delta_queue_obl = DeltaQueue(out_port_obl) self.delta_queue_opt = DeltaQueue(out_port_opt) self.const_queue_obl = ConstQueue(out_port_obl) self.const_queue_opt = ConstQueue(out_port_opt) # test messages self.msg1 = QueueMessage(1) self.msg2 = QueueMessage(2) self.msg_with_none = QueueMessage(None) self.msg_unpackable = QueueMessage("abcde") # these messages should be received self.msg1_answer = QueueMessage(1) self.msg2_answer = QueueMessage(2) self.msg_with_none_answer = QueueMessage(None)
def test_serialisation(self): """Serialize/deserialize a graph with a node with a PyMigenBody. Notes ----- The content of the bodies depends on the environment, i.e. how the test is executed. For this reason we just compare the structure of the graph here. """ s = StateSaver(int) example_migen = TestMigen(tb_num_iter=2000, name='counter', lvl=logging.INFO, vcd_name="/workdir/TestMigen.vcd") with DeltaGraph() as graph: example_migen_out = example_migen.call(in1=40, in2=2) s.save_and_exit( adder(example_migen_out.out1, multiplier(example_migen_out.out2))) data, _ = serialize_graph(graph) self.assertEqual(type(data), bytes) g_capnp = deserialize_graph(data).to_dict() assert_capnp_content_types(self, g_capnp) with open(os.path.join(self.datapath, 'graph_with_migen_capnp.json'), 'r') as file: self.assertEqual(g_capnp, json.load(file))
def test_merge_use_in_graph(self): """Test to ensure in params must match when associating constructors with a NodeTemplate. """ test_template3 = NodeTemplate(name="test_3", inputs=[('a', int), ('b', int)], outputs=[('output', int)]) @DeltaBlock(template=test_template3, allow_const=False) def _simple_add_2(a: int, b: int) -> int: return a + b test_template2 = NodeTemplate(name="test_2", inputs=[('a', int), ('b', int)], outputs=[('output', int)]) @DeltaBlock(template=test_template2, allow_const=False) def simple_add_3(a: int, b: int) -> int: return a + b test_template3.merge(test_template2) saver = StateSaver() with DeltaGraph() as graph: n1 = simple_add_3(4, 73) saver.save_and_exit(n1) self.assertEqual(len(n1.bodies), 2) graph.select_bodies(preferred=['_simple_add_2']) self.assertIn("_simple_add_2", n1.body.access_tags) DeltaPySimulator(graph).run() self.assertEqual([77], saver.saved)
def test_selection_exclusion_preference(self): @DeltaBlock(template=self.test_template, allow_const=False, tags=["func_4", "excluded, preferred"]) def func_4(a: int, b: int) -> Void: print("func_4") raise DeltaRuntimeExit with DeltaGraph() as graph: n = self.test_template.call(1, 2) # start on a body different form the desired n.select_body(preferred=["func_4"]) _, self.program = serialize_graph(graph) node_bodies, _, _ = generate_wiring(self.program, excluded_body_tags=["excluded"]) self.assertEqual(len(node_bodies), 1) asyncio.run(self.assert_tag_from_py_script(node_bodies[0], "func_1")) node_bodies, _, _ = generate_wiring(self.program, excluded_body_tags=["excluded"], preferred_body_tags=["preferred"]) self.assertEqual(len(node_bodies), 1) asyncio.run(self.assert_tag_from_py_script(node_bodies[0], "func_2"))
def test_method(self): foo = Foo() with DeltaGraph() as test_graph: foo.add_set_x(a=4, b=5) rt = DeltaPySimulator(test_graph) rt.run() self.assertEqual(foo.x, 9)
def test_placeholder_method(self): foo = Foo() with DeltaGraph() as test_graph: n = placeholder_node_factory(a=4, b=5) n.specify_by_method(Foo.add_set_x, foo, node_key="node") rt = DeltaPySimulator(test_graph) rt.run() self.assertEqual(foo.x, 9)
def test_forked_block_naming(self): """Test that checks a forked DeltaBlock raises an error if the fork names clash with node attributes """ with self.assertRaises(NameError): with DeltaGraph(): forked_block()
def test_forked_placeholder_naming(self): """Test that checks a forked placeholder raises an error if the fork names clash with node attributes """ with self.assertRaises(NameError): with DeltaGraph(): p = placeholder_node_factory() p.specify_by_func(forked_block)
def test_forked_method_block_naming(self): """Test that checks a forked DeltaMethodBLock raises an error if the fork names clash with node attributes """ with self.assertRaises(NameError): instance = ForkNameTestClass() with DeltaGraph(): instance.forked_method_block()