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 test_placeholder_input(self): template_3 = NodeTemplate(inputs=[('a', int)]) with DeltaGraph() as graph: a = placeholder_node_factory() template_3.call(a=a) a.specify_by_func(self.func_for_placeholder) self.assertTrue(graph.check())
def test_template_input_raises_exception(self): @DeltaBlock() def add(a: int, b: int) -> int: return a + b template_1 = NodeTemplate(inputs=[('a', bool)]) with self.assertRaises(DeltaTypeError): with DeltaGraph() as graph: template_1.call(a=add(a=1, b=2)) graph.check()
def test_multi_output(self): """Test that a multi-output pure template is allowed """ template_o = NodeTemplate(outputs=[('a', int), ('b', bool)]) template_i = NodeTemplate(inputs=[('a', int), ('b', bool)]) with DeltaGraph() as graph: forked_input = template_o.call() template_i.call(a=forked_input.a, b=forked_input.b) self.assertTrue(graph.check())
def test_multi_input_from_same(self): template_2 = NodeTemplate(inputs=[('a', int), ('b', bool)]) @DeltaBlock(outputs=[('a', int), ('b', bool)]) def add_1_true(n: int): return n + 1, True with DeltaGraph() as graph: forked_input = add_1_true(n=5) template_2.call(a=forked_input.a, b=forked_input.b) self.assertTrue(graph.check())
def test_forked_input(self): ForkedReturnT, ForkedReturn = make_forked_return({'a': int, 'b': bool}) template_2 = NodeTemplate(inputs=[('a', int), ('b', bool)]) @DeltaBlock() def add_1_true(n: int) -> ForkedReturnT: return ForkedReturn(a=n + 1, b=True) with DeltaGraph() as graph: forked_input = add_1_true(n=5) template_2.call(a=forked_input.a, b=forked_input.b) self.assertTrue(graph.check())
def test_partial_arg_types(self): template_4 = NodeTemplate(inputs=[('a', int), ('b', bool)]) @DeltaBlock() def bool_and(a: bool, b: bool) -> bool: return a and b with DeltaGraph() as graph: a = placeholder_node_factory() template_4.call(a=a, b=bool_and(a=True, b=False)) a.specify_by_func(self.func_for_placeholder) self.assertTrue(graph.check())
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_template_node_capnp(self): """Test serialisation of nodes with no body. """ template = NodeTemplate(inputs=[('a', int), ('b', int)], outputs=[('output', int)], name="temp-test") with DeltaGraph() as test_graph: template.call(a=1, b=2) data, _ = serialise_graph(test_graph) g_capnp = deserialise_graph(data) for n in g_capnp.nodes: if n.name.split("_")[1] == 'temp-test': node = n break self.assertEqual(node.name.split("_")[0], 'template') self.assertEqual(len(node.bodies), 0)
def test_migen_template(self): migen_template = NodeTemplate([('a', int)], [('out', int)]) with DeltaGraph("test_migen_template") 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=migen_template.call(a=c1.o1)) print_then_exit(c2.o1) self.check_build(test_graph)
def test_add_method(self): test_template1 = NodeTemplate(name="test_1", inputs=[('a', int), ('b', int)], outputs=int) with DeltaGraph(): n1 = test_template1.call(2, 3) self.assertEqual(len(n1.bodies), 0) n1.add_body(OpCacher2().cached_add) self.assertEqual(len(n1.bodies), 1) self.assertIn('cached_add', n1.body.access_tags)
def test_add_migen(self): test_template1 = NodeTemplate(name="test_1", inputs=[('a', DOptional(int)), ('b', DOptional(int))]) test_template1.add_constructor(AMigenNode2()) with DeltaGraph(): n1 = test_template1.call(2, 3) self.assertEqual(len(n1.bodies), 1) self.assertIn(PyMigenBody, n1.body.access_tags)
def test_add_func(self): test_template1 = NodeTemplate(name="test_1", inputs=[('n1', int), ('n2', int)], outputs=[('output', int)]) with DeltaGraph(): n1 = test_template1.call(2, 3) self.assertEqual(len(n1.bodies), 0) n1.add_body(add_non_const) self.assertEqual(len(n1.bodies), 1) self.assertIn('add_non_const', n1.body.access_tags)
def test_add_multiple(self): test_template1 = NodeTemplate(name="test_1", inputs=[('n1', int), ('n2', int)], outputs=[('output', int)]) with DeltaGraph(): n1 = test_template1.call(2, 3) self.assertEqual(len(n1.bodies), 0) n1.add_body(OpCacher2().cached_add) n1.add_body(add_non_const) self.assertEqual(len(n1.bodies), 2) self.assertIn('cached_add', n1.body.access_tags)
def test_add_invalid_body(self): test_template1 = NodeTemplate(name="test_1", inputs=[('a', int), ('b', int)], outputs=int) @DeltaBlock(allow_const=False) def simple_add_to_bool(a: int, b: int) -> bool: return bool(a + b) with DeltaGraph(): n1 = test_template1.call(2, 3) with self.assertRaises(ValueError): n1.add_body(simple_add_to_bool)
def test_add_func(self): test_template1 = NodeTemplate(name="test_1", inputs=[('a', int), ('b', int)], outputs=int) @DeltaBlock(allow_const=False) def simple_add(a: int, b: int) -> int: return a + b with DeltaGraph(): n1 = test_template1.call(2, 3) self.assertEqual(len(n1.bodies), 0) n1.add_body(simple_add) self.assertEqual(len(n1.bodies), 1) self.assertIn('simple_add', n1.body.access_tags)
def test_add_func(self): test_template_a = NodeTemplate(name="test_1", inputs=[('a', int), ('b', int)], outputs=[('output', int)]) @DeltaBlock(allow_const=False) def simple_add_2(a: int, b: int) -> int: return a + b test_template_a.add_constructor(simple_add_2) with DeltaGraph(): n1 = test_template_a.call(2, 3) self.assertEqual(len(n1.bodies), 1) self.assertIn('simple_add_2', n1.body.access_tags)
def test_add_migen(self): test_template1 = NodeTemplate(name="test_1", inputs=[('a', DOptional(int)), ('b', DOptional(int))]) class AMigenNode(MigenNodeTemplate): def migen_body(self, template): template.add_pa_in_port('a', DOptional(int)) template.add_pa_in_port('b', DOptional(int)) with DeltaGraph(): n1 = test_template1.call(a=2, b=3) self.assertEqual(len(n1.bodies), 0) n1.add_body(AMigenNode()) self.assertEqual(len(n1.bodies), 1) self.assertIn(PyMigenBody, n1.body.access_tags)
def test_add_interactive(self): test_template1 = NodeTemplate(name="test_1", inputs=[('a', int), ('b', int)], outputs=int) @Interactive(inputs=[('a', int), ('b', int)], outputs=int) def broken_adder_2(node: RealNode): a = node.receive('a') b = node.receive('b') node.send(a + b + 1) test_template1.add_constructor(broken_adder_2) with DeltaGraph(): n1 = test_template1.call(2, 3) self.assertEqual(len(n1.bodies), 1) self.assertIn('broken_adder_2', n1.body.access_tags)
def test_add_with_existing_same_template(self): """Test for when the constructor we are adding is already on the ``NodeTemplate``. The constructor should not be added twice. """ test_template_g = NodeTemplate(name="test_1", inputs=[('a', int), ('b', int)], outputs=[('output', int)]) @DeltaBlock(template=test_template_g, allow_const=False) def simple_add_2(a: int, b: int) -> int: return a + b test_template_g.add_constructor(simple_add_2) with DeltaGraph(): n1 = test_template_g.call(2, 3) self.assertEqual(len(n1.bodies), 1) self.assertIn('simple_add_2', n1.body.access_tags)
def test_add_with_existing_other_template(self): """Test for when the constructor we are adding is already associated with some other ``NodeTemplate``. """ test_template_e = NodeTemplate(name="test_1", inputs=[('a', int), ('b', int)], outputs=[('output', int)]) test_template_f = NodeTemplate(name="test_2", inputs=[('a', int), ('b', int)], outputs=[('output', int)]) @DeltaBlock(template=test_template_f, allow_const=False) def simple_add_2(a: int, b: int) -> int: return a + b test_template_e.add_constructor(simple_add_2) with DeltaGraph(): n1 = test_template_e.call(2, 3) self.assertEqual(len(n1.bodies), 1) self.assertIn('simple_add_2', n1.body.access_tags)
class TestBodySelection(unittest.TestCase): async def assert_tag_from_py_script(self, build_artifact, tag): built = await asyncio.wait_for(build_artifact.data, timeout=None) python_string = built.decode("utf-8") + "\nprint(body.access_tags[0])" p = subprocess.run([r"python"], input=str.encode(python_string), stdout=subprocess.PIPE, check=False) output = p.stdout.decode() self.assertEqual(output, tag + "\n") def setUp(self): self.test_template = NodeTemplate(name="TestTemplate", inputs=[('a', int), ('b', int)]) @DeltaBlock(template=self.test_template, allow_const=False, tags=["func_1"]) def func_1(a: int, b: int) -> Void: print("func_1") raise DeltaRuntimeExit @DeltaBlock(template=self.test_template, allow_const=False, tags=["func_2", "preferred"]) def func_2(a: int, b: int) -> Void: print("func_2") raise DeltaRuntimeExit @DeltaBlock(template=self.test_template, allow_const=False, tags=["func_3", "excluded"]) def func_3(a: int, b: int) -> Void: print("func_3") raise DeltaRuntimeExit def test_select_preferred_node_body(self): with DeltaGraph() as graph: n = self.test_template.call(1, 2) # start on a body different form the desired n.select_body(preferred=["func_1"]) _, self.program = serialize_graph(graph) node_bodies, _, _ = generate_wiring(self.program, 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_no_select_excluded_node_body(self): with DeltaGraph() as graph: n = self.test_template.call(1, 2) # start on a body different form the desired n.select_body(preferred=["excluded"]) _, 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")) def test_select_preferred_excluded_node_body(self): with DeltaGraph() as graph: n = self.test_template.call(1, 2) # start on a body different form the desired n.select_body(preferred=["func_1"]) _, self.program = serialize_graph(graph) node_bodies, _, _ = generate_wiring(self.program, preferred_body_tags=["preferred"], excluded_body_tags=["excluded"]) self.assertEqual(len(node_bodies), 1) asyncio.run(self.assert_tag_from_py_script(node_bodies[0], "func_2")) 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_all_body_exclusion_error(self): with DeltaGraph() as graph: n = self.test_template.call(1, 2) _, self.program = serialize_graph(graph) with self.assertRaises(AttributeError): node_bodies, _, _ = generate_wiring( self.program, excluded_body_tags=["func_1", "func_2", "func_3"])
def test_template_outport_name_clash(self): forked_template = NodeTemplate(outputs=[('send', int), ('y', int)]) with self.assertRaises(NameError): with DeltaGraph(): forked_template.call()