def test_splitting_non_const_non_const(self): s = dl.lib.StateSaver(int, verbose=True) with dl.DeltaGraph() as graph: val = return_1_2_non_const() s.save_and_exit( add_non_const( add_non_const(add_non_const(val.x, val.x), val.y), val.y)) self.check_executes_graph(graph, "saving 6\n")
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_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_splitting_non_const_non_const(self): """Non-const -> non-const -> exit.""" s = dl.lib.StateSaver(int, verbose=True) with dl.DeltaGraph() as graph: val = return_1_non_const() s.save_and_exit(add_non_const(val, val)) self.check_executes_graph(graph, "saving 2\n")
def test_splitting_const_const(self): """Const -> const -> exit.""" s = dl.lib.StateSaver(int, verbose=True) with dl.DeltaGraph() as graph: val = return_1_const() out = add_non_const(increment_const(val), increment_const(val)) s.save_and_exit(out) self.check_executes_graph(graph, "saving 4\n")
def test_one_migen_node_with_2_outs(self): """One PyMigenBody with 2 out ports produces what we expect.""" s = dl.lib.StateSaver(int, verbose=True) with dl.DeltaGraph() as graph: counter = MigenDUT().call(40, 2) s.save_and_exit( add_non_const(counter.out1, multiplier(counter.out2))) self.check_executes_graph(graph, "saving 5042\n")
def test_splitter_serialisation(self): """Splitter nodes should be added when serialising.""" with DeltaGraph() as test_graph: a = add_non_const(2, 3) self.func(a, 4) self.func(a, 5) _, prog = serialise_graph(test_graph) splitter_body = dill.loads(prog.bodies[-1].python.dillImpl) self.assertEqual(type(splitter_body), PyFuncBody) self.assertEqual(len(prog.nodes), 8)
def test_complex_networkx_graph(self): with DeltaGraph() as complex_graph: ph = placeholder_node_factory() n = add_non_const(1, ph) print_node = print_until_10(n=n) ph.specify_by_node(print_node) networkx_graph = complex_graph.get_networkx_graph() self.assertEqual(node_cnt(networkx_graph.nodes()), Counter({'node': 1, 'add_non_const': 1, 'print_until_10': 1})) self.assertEqual(edge_cnt(networkx_graph.edges()), Counter({('node', 'add_non_const'): 1, ('add_non_const', 'print_until_10'): 1, ('print_until_10', 'add_non_const'): 1}))
def test_simple_networkx_graph(self): s = StateSaver(int) with DeltaGraph() as graph: n = add_non_const(3, 4) s.save_and_exit(n) networkx_graph = graph.get_networkx_graph() self.assertEqual(node_cnt(networkx_graph.nodes()), Counter({'node': 2, 'add_non_const': 1, 'save_and_exit': 1})) self.assertEqual(edge_cnt(networkx_graph.edges()), Counter({('node', 'add_non_const'): 2, ('add_non_const', 'save_and_exit'): 1}))
def test_one_migen_node_with_separate_ctrl_on_output_valid(self): """One PyMigenBody with 2 optional output ports produces the correct valid values (for the different ports). The migen node should be generating a sequence of outputs (1, None), (None, 2), (3, None) etc... """ checker = dl.lib.StateSaver(int, condition=lambda x: x == 3, verbose=True) with dl.DeltaGraph() as graph: alt = AlternatingOutputsMigen().call(1) my_adder = add_non_const(alt.out_a, alt.out_b) # Checking that we have received a 1 and a 2 checker.save_and_exit_if(my_adder) self.check_executes_graph(graph, "saving 3\n")
def test_simple_folding_const_inputs(self): """Test that nodes producing constants are constant nodes.""" with DeltaGraph() as graph: n1 = add_const(4, 3) n2 = add_non_const(4, 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 turned to a constant node as well self.assertIsInstance(n1.body, PyConstBody) # this one would have done so as well, but we disallowed it self.assertIsInstance(n2.body, PyFuncBody) self.assertTrue(graph.check())
def test_simple_folding_non_const_inputs(self): """Test that nodes with non constant inputs cannot fold to become constant. """ with DeltaGraph() as graph: n1 = add_const(4, forward_non_const(3)) n2 = add_non_const(4, forward_non_const(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_integration(self): """Constructs the following graph: +---------------------------+ | SAVE | | +-----+ ^ | +--->Add +----+ | |to 10| +----+ | | +--------> | | +-----+ |ADD +---+ 2 --->| | +----+ """ s = dl.lib.StateSaver(int, verbose=True) with dl.DeltaGraph() as graph: add_ph = dl.placeholder_node_factory() b = return_2_const() int_node = add_until_10.call(num=add_ph) add_node = add_non_const(b, int_node.x) add_ph.specify_by_node(add_node) s.save_and_exit(int_node.y) self.check_executes_graph(graph, "saving 11\n")