コード例 #1
0
    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))
コード例 #2
0
    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))
コード例 #3
0
class ComplexGraph(unittest.TestCase):
    def setUp(self):
        """Constructs the following graph:
        +---------------------------+
        |             SAVE          |
        |   +-----+    ^            |
        +--->Add  +----+            |
            |to 10|        +----+   |
            |     +-------->    |   |
            +-----+        |ADD +---+
                     2 --->|    |
                           +----+
        """
        self.saver = StateSaver(int)

        with DeltaGraph() as graph:
            add_ph = placeholder_node_factory()
            b = return_2()
            self.int_node = add_until_10.call(num=add_ph)
            add_node = add_non_const(b, self.int_node.x)
            add_ph.specify_by_node(add_node)
            self.saver.save_and_exit(self.int_node.y)
        self.graph = graph
        self.runtime = DeltaPySimulator(self.graph)

    def test_run(self):
        """This graph should run, adding 2 to the number on every cycle."""
        self.runtime.run()
        self.assertEqual(self.saver.saved, [11])

    def test_graph_properties(self):
        self.graph.check()
コード例 #4
0
    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)
コード例 #5
0
    def test_top_serialisation(self):
        """If a port has type top serialisation should throw an error."""
        s = StateSaver()
        with DeltaGraph() as graph:
            s.save_and_exit(return_1_const())

        with self.assertRaises(DeltaTypeError):
            serialise_graph(graph)
コード例 #6
0
    def test_forked_return_non_const_to_non_const(self):
        """Non-constant node w/ forked return -> non-constant -> exit."""
        s = StateSaver(int)
        with DeltaGraph() as graph:
            val = return_12_non_const()
            s.save_and_exit(increment_non_const(val.x))

        DeltaPySimulator(graph).run()
        self.assertEqual(s.saved, [2])
コード例 #7
0
 def test_via_default_call(self):
     saver = StateSaver()
     with DeltaGraph() as graph:
         n1 = test_template1.call(9, 2)
         saver.save_and_exit(n1)
     self.assertEqual(len(n1.bodies), 3)
     self.assertIn("simple_add", n1.body.access_tags)
     DeltaPySimulator(graph).run()
     self.assertEqual([11], saver.saved)
コード例 #8
0
 def test_via_DeltaBlock(self):
     saver = StateSaver()
     with DeltaGraph() as graph:
         n1 = simple_add(4, 3)
         saver.save_and_exit(n1)
     self.assertEqual(len(n1.bodies), 3)
     self.assertIn("simple_add", n1.body.access_tags)
     DeltaPySimulator(graph).run()
     self.assertEqual([7], saver.saved)
コード例 #9
0
 def test_via_Interactive(self):
     saver = StateSaver()
     with DeltaGraph() as graph:
         n1 = broken_adder.call(a=1, b=3)
         saver.save_and_exit(n1)
     self.assertEqual(len(n1.bodies), 3)
     self.assertIn("broken_adder", n1.body.access_tags)
     DeltaPySimulator(graph).run()
     self.assertEqual([5], saver.saved)
コード例 #10
0
    def test_splitting_to_one_node_non_const(self):
        """Splitted output of a non-constant node and sent to another node's
        different inputs."""
        s = StateSaver(int)
        with DeltaGraph() as graph:
            val = return_1_non_const()
            s.save_and_exit(add_non_const(val, val))

        DeltaPySimulator(graph).run()
        self.assertEqual(s.saved, [2])
コード例 #11
0
 def test_via_DeltaMethodBlock(self):
     saver = StateSaver()
     cacher = OpCacher()
     with DeltaGraph() as graph:
         n1 = cacher.cached_add(1, 3)
         saver.save_and_exit(n1)
     self.assertEqual(len(n1.bodies), 4)
     self.assertIn("cached_add", n1.body.access_tags)
     DeltaPySimulator(graph).run()
     self.assertEqual([4], saver.saved)
コード例 #12
0
    def test_splitting_of_multiple_forked_non_const(self):
        """Multiple forked outputs of a non-constant node are splitted."""
        s = StateSaver(int)
        with DeltaGraph() as graph:
            val = return_12_non_const()
            s.save_and_exit(
                add_non_const(
                    add_non_const(add_non_const(val.x, val.x), val.y), val.y))

        DeltaPySimulator(graph).run()
        self.assertEqual(s.saved, [6])
コード例 #13
0
    def test_custom_name_interactive(self):
        saver = StateSaver(int)

        with DeltaGraph() as graph:
            r = send_5.call().out
            s = saver.save_and_exit(r)

        self.assertTrue(graph.check())
        self.assertEqual(len(r.out_ports), 1)

        port_under_test = r.out_ports[0]
        self.assertEqual(port_under_test.destination.node, s)
        self.assertEqual(port_under_test.port_type, Int(Size(32)))
        self.assertEqual(port_under_test.index, 'out')
コード例 #14
0
    def test_default_name_func_block(self):
        saver = StateSaver(int)

        with DeltaGraph() as graph:
            r = return_5_default_name().output
            s = saver.save_and_exit(r)

        self.assertTrue(graph.check())
        self.assertEqual(len(r.out_ports), 1)

        port_under_test = r.out_ports[0]
        self.assertEqual(port_under_test.destination.node, s)
        self.assertEqual(port_under_test.port_type, Int(Size(32)))
        self.assertEqual(port_under_test.index, 'output')
コード例 #15
0
    def test_one_migen_node_with_2_outs(self):
        """One PyMigenBody with 2 out ports produces what we expect."""
        s = StateSaver(int, verbose=True)

        with DeltaGraph() as graph:
            counter = TestMigen(tb_num_iter=2000,
                                name='counter',
                                lvl=logging.INFO).call(in1=40, in2=2)
            s.save_and_exit(adder(counter.out1, multiplier(counter.out2)))

        rt = DeltaPySimulator(graph)
        rt.run()

        self.assertEqual(s.saved, [5042])
コード例 #16
0
    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}))
コード例 #17
0
    def test_custom_name_method_block(self):
        saver = StateSaver(int)
        m = MethodReturner()

        with DeltaGraph() as graph:
            r = m.return_5_m().out
            s = saver.save_and_exit(r)

        self.assertTrue(graph.check())
        self.assertEqual(len(r.out_ports), 1)

        port_under_test = r.out_ports[0]
        self.assertEqual(port_under_test.destination.node, s)
        self.assertEqual(port_under_test.port_type, Int(Size(32)))
        self.assertEqual(port_under_test.index, 'out')
コード例 #18
0
    def test_select_different_from_constructor(self):
        """Test that it is possible to select a different body than the
        one associated with the used constructor.
        """
        saver = StateSaver()
        with DeltaGraph() as graph:
            n1 = simple_add(1, 3)
            saver.save_and_exit(n1)

        graph.select_bodies(preferred=["broken_adder"])
        self.assertEqual(len(n1.bodies), 3)
        self.assertIn("broken_adder", n1.body.access_tags)

        DeltaPySimulator(graph).run()
        self.assertEqual([5], saver.saved)
コード例 #19
0
    def test_multiple_nodes_same_template(self):
        """Test that the same NodeTemplate can be used to create
        multiple distinct nodes for the same graph.
        """
        saver = StateSaver()
        with DeltaGraph() as graph:
            n1 = over_complex_add(1, 3)
            n2 = simple_add(4, n1)
            saver.save_and_exit(n2)

        self.assertEqual(len(n1.bodies), 3)
        self.assertEqual(len(n2.bodies), 3)
        self.assertIn("over_complex_add", n1.body.access_tags)
        self.assertIn("simple_add", n2.body.access_tags)

        DeltaPySimulator(graph).run()
        self.assertEqual([8], saver.saved)
コード例 #20
0
    def test_serialise_state_saver(self):
        """Serialise a state saver and load it in a new instance."""
        saver = StateSaver(t=int, verbose=True)
        with DeltaGraph():
            saver_node = saver.save(return_2_const())
        saver_body = saver_node.body.as_serialised
        python_string = textwrap.dedent(f"""
            import dill
            saver_body = dill.loads({saver_body})
            saver_body.eval(5)
            """)
        p = subprocess.run([r"python"],
                           input=str.encode(python_string),
                           stdout=subprocess.PIPE,
                           check=False)
        output = p.stdout.decode()

        self.assertEqual(output, "saving 5\n")
コード例 #21
0
class MigenInteractiveCommsTest(unittest.TestCase):
    def setUp(self):

        self.saver = StateSaver(int)

    def test_migen_trigger_fails(self):
        """Assert that when the `test_bench_no_trigger` node sends data, the
        ouput of the migen node is 0 due to the data not loading into output
        signal properly.
        """

        with DeltaGraph() as graph:

            test_bench_output = test_bench_no_trigger.call()

            c1 = TestMigenNode(tb_num_iter=10).call(
                inp=test_bench_output.inp, trigger=test_bench_output.trigger)

            self.saver.save_and_exit(c1.out)

        rt = DeltaPySimulator(graph)
        rt.run()

        self.assertEqual(self.saver.saved[0], 0)

    def test_migen_trigger_succeeds(self):
        """Assert that when the `test_bench_ye_trigger` node sends data, the
        ouput of the migen node is 15 since the data signal is available on the
        particular clock cycle that loads in the data.
        """

        with DeltaGraph() as graph:

            test_bench_output = test_bench_yes_trigger.call()

            c1 = TestMigenNode(tb_num_iter=10).call(
                inp=test_bench_output.inp, trigger=test_bench_output.trigger)

            self.saver.save_and_exit(c1.out)

        rt = DeltaPySimulator(graph)
        rt.run()

        self.assertEqual(self.saver.saved[0], 15)
コード例 #22
0
    def test_splitting_of_one_forked_non_const(self):
        """One of forked outputs of a non-constant node is splitted."""
        s1 = StateSaver(int)
        s2 = StateSaver(int)
        with DeltaGraph() as graph:
            val = return_12_non_const()
            val_x = val.x
            s1.save(val_x)
            s2.save_and_exit(val_x)

        rt = DeltaPySimulator(graph)
        rt.run()
        self.assertEqual(s2.saved, [1])
コード例 #23
0
    def setUp(self):
        """Constructs the following graph:
        +---------------------------+
        |             SAVE          |
        |   +-----+    ^            |
        +--->Add  +----+            |
            |to 10|        +----+   |
            |     +-------->    |   |
            +-----+        |ADD +---+
                     2 --->|    |
                           +----+
        """
        self.saver = StateSaver(int)

        with DeltaGraph() as graph:
            add_ph = placeholder_node_factory()
            b = return_2()
            self.int_node = add_until_10.call(num=add_ph)
            add_node = add_non_const(b, self.int_node.x)
            add_ph.specify_by_node(add_node)
            self.saver.save_and_exit(self.int_node.y)
        self.graph = graph
        self.runtime = DeltaPySimulator(self.graph)
コード例 #24
0
    def test_default_name_func_block(self):
        saver = StateSaver(int)

        with self.assertRaises(ValueError):
            with DeltaGraph():
                saver.save_and_exit(return_5_9())
コード例 #25
0
    def setUp(self):

        self.saver = StateSaver(int)
コード例 #26
0
    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]
コード例 #27
0
    def setUp(self):
        r"""Build the graph
        ```
                     / saver1
                    /
            return_1 -- saver2
                    \
                     \ saver3
        ```
        """
        with DeltaGraph() as my_graph:
            saver1 = StateSaver(int)
            saver2 = StateSaver(int)
            saver3 = StateSaver(int)

            val = return_1()
            saver1.save(val)
            saver2.save(val)
            saver3.save(val)

        self.graph = my_graph
        self.savers = [saver1, saver2, saver3]
コード例 #28
0
 def setUp(self):
     """Set up a simple graph"""
     saver = StateSaver(int)
     with DeltaGraph() as test_graph:
         saver.save_and_exit(return_1_const())
     self.graph = test_graph
コード例 #29
0
    def test_can_save_to_tempfile(self):
        """Test StateSaver can save to a file."""
        st = [(k, k**2) for k in range(5)]
        # Note the conversion to a list as the json format doesn't care
        # for tuples.
        st_expected = "\n".join(repr(list(x)) for x in st)

        items = [
            ((int, int), (42, 100), "[42, 100]"),
            ((int, int), st, st_expected),
            (str, "Hello", '"Hello"'),
            (bool, True, "true"),
            (float, 3.91, "3.91"),
            (Tuple([int, int]), (1, 2), "[1, 2]"),
            (Union([int, float]), 90, "90"),
            (Union([int, float]), 90.0, "90.0"),
            (complex, 1j, '{"real": 0.0, "imaginary": 1.0}'),
            (SimpleRecord, SimpleRecord(x=1, y=True), '{"x": 1, "y": true}'),
            (
                ComplexRecord,
                ComplexRecord(x=1 + 2j),
                '{"x": {"real": 1.0, "imaginary": 2.0}}'
            ),
            (
                NestedRecord,
                NestedRecord(x=3, y=SimpleRecord(x=1, y=True)),
                '{"x": 3, "y": {"x": 1, "y": true}}'
            ),
            (
                ArrayRecord,
                ArrayRecord(x=[ComplexRecord(x=-1+4j)]),
                '{"x": [{"x": {"real": -1.0, "imaginary": 4.0}}]}'
            )
        ]

        for i, item in enumerate(items):
            t, data, expected = item
            with self.subTest(i=i):
                with tempfile.NamedTemporaryFile(mode="w+") as f:
                    s = StateSaver(t, verbose=True, filename=f.name)

                    @DeltaBlock(allow_const=False)
                    def save_things_node() -> object:
                        # If it's a list, save them independently, otherwise
                        # it's just one thing.
                        if type(data) == list:
                            for d in data:
                                s.save(d)
                        else:
                            s.save(data)
                        raise DeltaRuntimeExit

                    with DeltaGraph() as graph:
                        save_things_node()

                    rt = DeltaPySimulator(graph)
                    rt.run()

                    f.seek(0)

                    contents = f.read()
                    self.assertEqual(contents, f"{expected}\n")