Ejemplo n.º 1
0
    def test_gate_not_defined(self):
        """Test unknown gate raises error"""
        xir_prog = xir.Program()
        xir_prog.add_statement(xir.Statement("np", [1, 2, 3], (0,)))

        with pytest.raises(NameError, match="operation 'np' not defined"):
            io.to_program(xir_prog)
Ejemplo n.º 2
0
    def test_empty_program(self):
        """Test empty program raises error"""
        xir_prog = xir.Program()

        with pytest.raises(
            ValueError, match="is empty and cannot be transformed into a Strawberry Fields program"
        ):
            io.to_program(xir_prog)
Ejemplo n.º 3
0
    def test_tdm_program(self):
        """Test converting a TDM XIR program to a TDMProgram"""

        xir_prog = xir.Program()

        xir_prog.add_statement(xir.Statement("Sgate", [0.7, 0], (1,)))
        xir_prog.add_statement(xir.Statement("BSgate", ["p0", 0.0], (0, 1)))
        xir_prog.add_statement(xir.Statement("Rgate", ["p1"], (1,)))
        xir_prog.add_statement(xir.Statement("MeasureHomodyne", {"phi": "p2"}, (0,)))

        xir_prog.add_constant("p0", [1, 2])
        xir_prog.add_constant("p1", [3, 4])
        xir_prog.add_constant("p2", [5, 6])

        xir_prog.add_option("_type_", "tdm")
        xir_prog.add_option("N", [2])
        xir_prog.add_option("shots", 3)
        sf_prog = io.to_program(xir_prog)

        assert isinstance(sf_prog, TDMProgram)

        assert sf_prog.run_options == {"shots": 3}

        assert len(sf_prog) == 4
        assert sf_prog.circuit
        assert sf_prog.circuit[0].op.__class__.__name__ == "Sgate"
        assert sf_prog.circuit[0].op.p[0] == 0.7
        assert sf_prog.circuit[0].op.p[1] == 0
        assert sf_prog.circuit[0].reg[0].ind == 1

        assert sf_prog.circuit[1].op.__class__.__name__ == "BSgate"
        assert sf_prog.circuit[1].op.p[0] == FreeParameter("p0")
        assert sf_prog.circuit[1].op.p[1] == 0.0
        assert sf_prog.circuit[1].reg[0].ind == 0
        assert sf_prog.circuit[1].reg[1].ind == 1

        assert sf_prog.circuit[2].op.__class__.__name__ == "Rgate"
        assert sf_prog.circuit[2].op.p[0] == FreeParameter("p1")
        assert sf_prog.circuit[2].reg[0].ind == 1

        assert sf_prog.circuit[3].op.__class__.__name__ == "MeasureHomodyne"
        assert sf_prog.circuit[3].op.p[0] == FreeParameter("p2")
        assert sf_prog.circuit[3].reg[0].ind == 0

        assert sf_prog.concurr_modes == 2
        assert sf_prog.timebins == 2
        assert sf_prog.spatial_modes == 1
        assert sf_prog.free_params == {
            "p0": FreeParameter("p0"),
            "p1": FreeParameter("p1"),
            "p2": FreeParameter("p2"),
        }
        assert all(sf_prog.tdm_params[0] == np.array([1, 2]))
        assert all(sf_prog.tdm_params[1] == np.array([3, 4]))
        assert all(sf_prog.tdm_params[2] == np.array([5, 6]))
Ejemplo n.º 4
0
    def test_gate_no_arg(self):
        """Test gate with no argument converts"""
        xir_prog = xir.Program()
        xir_prog.add_statement(xir.Statement("Vacuum", [], (0,)))

        sf_prog = io.to_program(xir_prog)

        assert len(sf_prog) == 1
        assert sf_prog.circuit
        assert sf_prog.circuit[0].op.__class__.__name__ == "Vacuum"
        assert sf_prog.circuit[0].reg[0].ind == 0
Ejemplo n.º 5
0
    def test_gate_kwarg(self):
        """Test gate with keyword argument converts"""
        xir_prog = xir.Program()
        xir_prog.add_statement(xir.Statement("Dgate", {"r": 0.54, "phi": 0}, (0,)))

        sf_prog = io.to_program(xir_prog)

        assert len(sf_prog) == 1
        assert sf_prog.circuit
        assert sf_prog.circuit[0].op.__class__.__name__ == "Dgate"
        assert sf_prog.circuit[0].op.p[0] == 0.54
        assert sf_prog.circuit[0].reg[0].ind == 0
Ejemplo n.º 6
0
    def test_program_with_options(self):
        """Test program with options raises error"""
        xir_prog = xir.Program()
        xir_prog.add_statement(xir.Statement("Vacuum", [], (0,)))

        xir_prog.add_option("cutoff_dim", 5)
        xir_prog.add_option("shots", 3)

        sf_prog = io.to_program(xir_prog)

        assert sf_prog.run_options == {"shots": 3}
        assert sf_prog.backend_options == {"cutoff_dim": 5}
Ejemplo n.º 7
0
    def test_gate_arg(self):
        """Test gate with arguments converts"""
        xir_prog = xir.Program()
        xir_prog.add_statement(xir.Statement("Sgate", [0.54, 0.12], (0,)))

        sf_prog = io.to_program(xir_prog)

        assert len(sf_prog) == 1
        assert sf_prog.circuit
        assert sf_prog.circuit[0].op.__class__.__name__ == "Sgate"
        assert sf_prog.circuit[0].op.p[0] == 0.54
        assert sf_prog.circuit[0].op.p[1] == 0.12
        assert sf_prog.circuit[0].reg[0].ind == 0
Ejemplo n.º 8
0
    def test_gate_multimode(self):
        """Test multimode gate converts"""
        xir_prog = xir.Program()
        xir_prog.add_statement(xir.Statement("BSgate", {"theta": 0.54, "phi": np.pi}, (0, 2)))

        sf_prog = io.to_program(xir_prog)

        assert len(sf_prog) == 1
        assert sf_prog.circuit
        assert sf_prog.circuit[0].op.__class__.__name__ == "BSgate"
        assert sf_prog.circuit[0].op.p[0] == 0.54
        assert sf_prog.circuit[0].op.p[1] == np.pi
        assert sf_prog.circuit[0].reg[0].ind == 0
        assert sf_prog.circuit[0].reg[1].ind == 2
Ejemplo n.º 9
0
    def test_gate_not_defined_tdm(self):
        """Test unknown gate in a TDM program raises error"""
        xir_prog = xir.Program()

        xir_prog.add_constant("p0", [1, 2])
        xir_prog.add_constant("p1", [3, 4])
        xir_prog.add_constant("p2", [5, 6])

        xir_prog.add_option("_type_", "tdm")
        xir_prog.add_option("N", [2])

        xir_prog.add_statement(xir.Statement("np", [1, 2, 3], (0,)))

        with pytest.raises(NameError, match="operation 'np' not defined"):
            io.to_program(xir_prog)
Ejemplo n.º 10
0
def to_xir(prog: Program, **kwargs) -> xir.Program:
    """Convert a Strawberry Fields Program to an XIR Program.

    Args:
        prog (Program): the Strawberry Fields program

    Keyword Args:
        add_decl (bool): Whether gate and output declarations should be added to
            the XIR program. Default is ``False``.

    Returns:
        xir.Program
    """
    xir_prog = xir.Program()
    add_decl = kwargs.get("add_decl", False)

    if isinstance(prog, TDMProgram):
        xir_prog.add_option("_type_", "tdm")
        xir_prog.add_option("N", prog.N)
        for i, p in enumerate(prog.tdm_params):
            xir_prog.add_constant(f"p{i}", _listr(p))

    if prog.name:
        xir_prog.add_option("_name_", prog.name)
    if prog.target:
        xir_prog.add_option("target", prog.target)  # pylint: disable=protected-access
    if "cutoff_dim" in prog.backend_options:
        xir_prog.add_option("cutoff_dim", prog.backend_options["cutoff_dim"])
    if "shots" in prog.run_options:
        xir_prog.add_option("shots", prog.run_options["shots"])

    # fill in the quantum circuit
    for cmd in prog.circuit or []:

        name = cmd.op.__class__.__name__
        wires = tuple(i.ind for i in cmd.reg)

        if "Measure" in name:
            if add_decl:
                output_decl = xir.Declaration(name, type_="out", wires=wires)
                xir_prog.add_declaration(output_decl)

            params = {}
            if cmd.op.p:
                # argument is quadrature phase
                a = cmd.op.p[0]
                if a in getattr(prog, "loop_vars", ()):
                    params["phi"] = a.name
                else:
                    params["phi"] = a

            # special case to take into account 'select' keyword argument
            if cmd.op.select is not None:
                params["select"] = cmd.op.select

            if name == "MeasureFock":
                # special case to take into account 'dark_counts' keyword argument
                if cmd.op.dark_counts is not None:
                    params["dark_counts"] = cmd.op.dark_counts
        else:
            if add_decl:
                if name not in [
                        gdecl.name for gdecl in xir_prog.declarations["gate"]
                ]:
                    params = [f"p{i}" for i, _ in enumerate(cmd.op.p)]
                    gate_decl = xir.Declaration(name,
                                                type_="gate",
                                                params=params,
                                                wires=tuple(range(len(wires))))
                    xir_prog.add_declaration(gate_decl)

            params = []
            for i, a in enumerate(cmd.op.p):
                if sfpar.par_is_symbolic(a):
                    # try to evaluate symbolic parameter
                    try:
                        a = sfpar.par_evaluate(a)
                    except sfpar.ParameterError:
                        # if a tdm param
                        if a in getattr(prog, "loop_vars", ()):
                            a = a.name
                        # if a pure symbol (free parameter), convert to string
                        elif a.is_symbol:
                            a = a.name
                        # else, assume it's a symbolic function and replace all free parameters
                        # with string representations
                        else:
                            symbolic_func = a.copy()
                            for s in symbolic_func.free_symbols:
                                symbolic_func = symbolic_func.subs(s, s.name)
                            a = str(symbolic_func)

                elif isinstance(a, str):
                    pass
                elif isinstance(a, Iterable):
                    # if an iterable, make sure it only consists of lists and Python types
                    a = _listr(a)
                params.append(a)

        op = xir.Statement(name, params, wires)
        xir_prog.add_statement(op)

    return xir_prog