예제 #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))
    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"))
예제 #3
0
    def test_node_serialisation_duplicate_bodies(self):
        """If two blocks share the same body only keep one copy."""
        with DeltaGraph() as test_graph:
            self.func(2, 3)
            self.func(4, 5)

        _, prog = serialize_graph(test_graph)

        self.assertEqual(len(prog.bodies), 5)
        self.assertEqual(prog.nodes[2].bodies[0], prog.nodes[5].bodies[0])
    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"])
예제 #5
0
    def test_const_exit(self):
        """DeltaRuntimeExit cannot be raised in constant nodes."""
        with DeltaGraph() as test_graph:
            const_exit(a=5)

        _, program = serialize_graph(test_graph)

        with PythonatorEnv(program.bodies) as env:
            self.build_artifacts = env.pythonate(
                program.nodes[1], program.nodes[1].bodies[0]
            )

        with self.assertRaises(ValueError):
            asyncio.run(self.build_artifacts["cpp"].data)
    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"))
예제 #7
0
    def test_migen_node(self):
        with DeltaGraph() as test_graph:
            c1 = DUT1(tb_num_iter=2000, name='counter1').call(i1=return_1000())
            print_then_exit(c1.o1)

        _, serialised = serialize_graph(test_graph)

        top_v = BuildArtifact(
            name=f"{serialised.nodes[1].name}",
            data=serialised.bodies[1].migen.verilog.encode("utf-8"))

        with VerilatorEnv() as env:
            build_artifacts = env.verilate(top_v)

        asyncio.run(self.assert_build_correct(build_artifacts))
예제 #8
0
    def test_splitter_serialisation(self):
        """Splitter nodes should be added when serialising."""
        @DeltaBlock(allow_const=False)
        def add(a: int, b: int) -> int:
            return a + b

        with DeltaGraph() as test_graph:
            a = add(2, 3)
            self.func(a, 4)
            self.func(a, 5)

        _, prog = serialize_graph(test_graph)

        splitter_body = dill.loads(prog.bodies[-1].python.dillImpl)
        self.assertEqual(type(splitter_body), PyFuncBody)
        self.assertEqual(len(prog.nodes), 8)
예제 #9
0
    def test_qiskit_serialisation(self):
        """Test Qiskit nodes serialization/deserialization.
        """

        with DeltaGraph() as test_graph:
            HardwareAbstractionLayerNode(
                QiskitQuantumSimulator(register_size=2)).accept_command(
                    hal_command=0x4000000)

        data, _ = serialize_graph(test_graph)
        g_capnp = deserialize_graph(data)

        # Checking that we are investigating the right node.
        self.assertEqual(g_capnp.nodes[1].name.split("_")[0], "accept")
        body = g_capnp.bodies[1].python.dillImpl
        node = dill.loads(body)
        node.eval(hal_command=0x4000000)
예제 #10
0
 def assert_correct_file_serialisation(self, files):
     _, prog = serialize_graph(self.graph, files=files)
     if len(files) == 0:
         self.assertEqual(prog.files, b'')
     else:
         with tempfile.TemporaryDirectory() as zip_dir:
             filename = os.path.join(zip_dir, "df_zip.zip")
             with open(filename, "wb") as df_zip:
                 df_zip.write(prog.files)
             with zipfile.ZipFile(filename, "r") as df_zip:
                 file_list = set([
                     file for pattern in files
                     for file in glob.glob(pattern)
                 ])
                 self.assertEqual(len(file_list), len(df_zip.namelist()))
                 for file in file_list:
                     self.assertIn(file, df_zip.namelist())
                     with open(file, "rb") as content:
                         self.assertEqual(content.read(), df_zip.read(file))
예제 #11
0
    def test_serialisation(self):
        """Serialize/deserialize a graph.

        .. note::
            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.
        """
        with DeltaGraph() as graph:
            self.func(40, 2)

        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_capnp.json'),
                  'r') as file:
            self.assertEqual(g_capnp, json.load(file))
예제 #12
0
    def test_template_node_capnp(self):
        """Test serialisation of nodes with no body.
        """
        template = NodeTemplate(inputs=[('a', int), ('b', int)],
                                outputs=int,
                                name="temp-test")

        with DeltaGraph() as test_graph:
            template.call(a=1, b=2)

        data, _ = serialize_graph(test_graph)
        g_capnp = deserialize_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)
예제 #13
0
    def test_pythonate(self):
        """Build artifacts and check the compiled code is correct."""
        with DeltaGraph() as test_graph:
            print_then_exit(
                n=interactive_func.call(num=add(a=2, b=3), val=4, opt=4)
            )

        _, program = serialize_graph(test_graph)

        for node in program.nodes:
            if "add" in node.name:
                with PythonatorEnv(program.bodies) as env:
                    self.build_artifacts = env.pythonate(node, node.bodies[0])
                asyncio.run(self.assert_build_correct("add"))

            elif "interactive" in node.name:
                with PythonatorEnv(program.bodies) as env:
                    self.build_artifacts = env.pythonate(node, node.bodies[0])
                asyncio.run(self.assert_build_correct("interactive"))
예제 #14
0
    def test_node_serialisation(self):
        """Generate graph and check serialisation is correct."""
        with DeltaGraph() as test_graph:
            self.func(2, 3)

        _, prog = serialize_graph(test_graph)

        self.assertEqual("_".join(prog.nodes[2].name.split("_")[:-1]),
                         "add_print_exit")

        self.assertEqual(prog.nodes[2].bodies[0], 2)

        self.assertEqual(prog.nodes[2].inPorts[0].name, "a")
        self.assertEqual(dill.loads(prog.nodes[2].inPorts[0].type),
                         as_delta_type(int))
        self.assertEqual(prog.nodes[2].inPorts[0].optional, True)

        self.assertEqual(prog.nodes[2].inPorts[1].name, "b")
        self.assertEqual(dill.loads(prog.nodes[2].inPorts[1].type),
                         as_delta_type(int))
        self.assertEqual(prog.nodes[2].inPorts[1].optional, True)

        self.assertEqual(len(prog.nodes[2].inPorts), 2)
        self.assertEqual(len(prog.nodes[2].outPorts), 0)

        self.assertEqual(prog.bodies[2].python.dillImpl,
                         test_graph.nodes[2].body.as_serialized)

        self.assertEqual(len(prog.graph), 2)

        self.assertEqual(prog.graph[0].srcNode, 0)
        self.assertEqual(prog.graph[0].srcOutPort, 0)
        self.assertEqual(prog.graph[0].destNode, 2)
        self.assertEqual(prog.graph[0].destInPort, 0)
        self.assertEqual(prog.graph[0].direct, False)

        self.assertEqual(prog.graph[1].srcNode, 1)
        self.assertEqual(prog.graph[1].srcOutPort, 0)
        self.assertEqual(prog.graph[1].destNode, 2)
        self.assertEqual(prog.graph[1].destInPort, 1)
        self.assertEqual(prog.graph[1].direct, False)
예제 #15
0
    def test_multi_body_serialisation(self):
        """Tests a graph with a multi-body node is serialised and matches
        a target capnp file.
        """
        with DeltaGraph() as graph:
            n1 = self.func(40, 2)

        @DeltaBlock(allow_const=False)
        def simple_add_2(a: DOptional(int), b: DOptional(int)):
            raise DeltaRuntimeExit

        n1.add_body(simple_add_2)

        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_multibody_capnp.json'),
                  'r') as file:
            self.assertEqual(g_capnp, json.load(file))
예제 #16
0
    def test_interactive_serialisation(self):
        """Interactive nodes have their own serialised body type.

        This is to distinguish their bodies from Python bodies, as they
        take different inputs.
        """
        @Interactive(inputs=[('a', int), ('b', int)], outputs=Void)
        def add(node) -> int:
            a = node.receive('a')
            b = node.receive('b')
            print(a + b)
            raise DeltaRuntimeExit

        with DeltaGraph() as test_graph:
            a = add.call(a=2, b=3)

        _, prog = serialize_graph(test_graph)

        self.assertEqual(prog.bodies[2].which(), 'interactive')
        interactive_body = prog.bodies[2].interactive.dillImpl
        self.assertEqual(interactive_body, a.body.as_serialized)
예제 #17
0
    def test_projectQ_serialisation(self):
        """Test ProjectQ nodes serialization/deserialization.

        ProjectQ can't be fully serialized, we need to exclude from dill the
        engine (C++ libraries). This test is to guarantee that when we
        deserialize everything works as expected.
        """

        with DeltaGraph() as test_graph:
            HardwareAbstractionLayerNode(
                ProjectqQuantumSimulator(register_size=2)).accept_command(
                    hal_command=0x4000000)

        data, _ = serialize_graph(test_graph)
        g_capnp = deserialize_graph(data)

        # Checking that we are investigating the right node.
        self.assertEqual(g_capnp.nodes[1].name.split("_")[0], "accept")
        body = g_capnp.bodies[1].python.dillImpl

        node = dill.loads(body)
        node.eval(hal_command=0x4000000)
예제 #18
0
    def test_node_serialisation_multi_body_node(self):
        """If two blocks share the same body only keep one copy."""
        with DeltaGraph() as test_graph:
            n1 = self.func(2, 3)

        @DeltaBlock(allow_const=False)
        def over_complex_add(a: DOptional(int), b: DOptional(int)):
            raise DeltaRuntimeExit

        @Interactive(inputs=[('a', DOptional(int)), ('b', DOptional(int))])
        def broken_adder(node: RealNode):
            node.receive('a')
            node.receive('b')
            raise DeltaRuntimeExit

        n1.add_body(AMigenNode())
        n1.add_body(over_complex_add)
        n1.add_body(OpCacher().cached_add)
        n1.add_body(broken_adder)

        _, prog = serialize_graph(test_graph)

        self.assertEqual(len(prog.nodes[2].bodies), 5)
예제 #19
0
                    build_repo + "/" + main_cpp_file)

        shutil.copy("/workdir/demos/deltaflow_on_artiq/" + sc_hal_hpp_file,
                    build_repo + "/" + sc_hal_hpp_file)

        shutil.copy(
            "/workdir/demos/deltaflow_on_artiq/" + projectq_hal_hpp_file,
            build_repo + "/" + projectq_hal_hpp_file)

        shutil.copy("/workdir/demos/deltaflow_on_artiq/" + hal_py_file,
                    build_repo + "/" + hal_py_file)
    except FileExistsError:
        pass

    graph, _ = rabi_demo.get_graph()
    dotdf_bytes, program = serialize_graph(graph, name=program_name)

    node_bodies, node_inits, wiring = generate_wiring(program)

    # write artifacts to build repository
    for build_artifact_name, build_artifact_data in wiring.items():
        print(f"writing: {build_artifact_name} into {build_repo}")
        with open(build_repo + f"/{build_artifact_name}", "wb") as f:
            write(build_artifact_data, f)

    # write python bodies to build repository
    for py_build_artifact in node_bodies:
        print(f"py_build_artifact: {py_build_artifact}")
        print(f"py_build_artifact: {type(py_build_artifact)}")
        with open(build_repo + f"/{py_build_artifact.name}", "wb") as f:
            write(py_build_artifact, f)
예제 #20
0
 def check_build(self, test_graph):
     """Build SystemC program and run tests."""
     _, program = serialize_graph(test_graph)
     _, _, wiring = generate_wiring(program)
     asyncio.run(self.assert_build_correct(wiring, test_graph.name))
예제 #21
0
 def assert_correct_reqs_serialisation(self, reqs):
     _, prog = serialize_graph(self.graph, requirements=reqs)
     reqs = set(reqs)
     self.assertEqual(len(prog.requirements), len(reqs))
     for requirement in reqs:
         self.assertIn(requirement, prog.requirements)