Esempio n. 1
0
    def test_measure_arg_postselect(self):
        """Test measurement with argument and postselection converts"""
        # create a test program
        prog = Program(1)

        with prog.context as q:
            ops.MeasureHomodyne(0.43, select=0.543) | q[0]

        bb = io.to_blackbird(prog)
        expected = {
            "op": "MeasureHomodyne",
            "modes": [0],
            "args": [],
            "kwargs": {
                "phi": 0.43,
                "select": 0.543
            },
        }

        assert bb.operations[0] == expected

        # repeat with kwargs only
        prog = Program(1)

        with prog.context as q:
            ops.MeasureHomodyne(phi=0.43, select=0.543) | q[0]

        bb = io.to_blackbird(prog)
        assert bb.operations[0] == expected
Esempio n. 2
0
    def test_metadata_run_options(self):
        """Test run options correctly converts"""
        prog = Program(4, name="test_program")
        bb = io.to_blackbird(prog.compile(compiler="gaussian", shots=1024))

        assert bb.name == "test_program"
        assert bb.version == "1.0"
        assert bb.target["name"] == "gaussian"
        assert bb.target["options"] == {"shots": 1024}
Esempio n. 3
0
    def test_program_with_options(self):
        """Test that program with options is correctly converted"""
        # create a test program
        sf_prog = Program(4, name="test_program")
        sf_prog.run_options = {"shots": 2}
        sf_prog.backend_options = {"cutoff_dim": 5}
        xir_prog = io.to_xir(sf_prog)

        assert xir_prog.options == {"_name_": "test_program", "cutoff_dim": 5, "shots": 2}
def from_blackbird(bb: blackbird.BlackbirdProgram) -> Program:
    """Convert a Blackbird program to a Strawberry Fields program.

    Args:
        bb (blackbird.BlackbirdProgram): the input Blackbird program object

    Returns:
        Program: corresponding Strawberry Fields program

    Raises:
        NameError: if an applied quantum operation is not defined in Strawberry Fields
    """
    # create a SF program
    prog = Program(max(bb.modes) + 1, name=bb.name)

    # append the quantum operations
    with prog.context as q:
        for op in bb.operations:
            # check if operation name is in the list of
            # defined StrawberryFields operations.
            # This is used by checking against the ops.py __all__
            # module attribute, which contains the names
            # of all defined quantum operations
            if op["op"] in ops.__all__:
                # get the quantum operation from the sf.ops module
                gate = getattr(ops, op["op"])
            else:
                raise NameError("Quantum operation {} not defined!".format(
                    op["op"]))

            # create the list of regrefs
            regrefs = [q[i] for i in op["modes"]]

            if "args" in op and "kwargs" in op:
                # the gate has arguments
                args = op["args"]
                kwargs = op["kwargs"]

                # Convert symbolic expressions in args/kwargs containing measured and free parameters to
                # symbolic expressions containing the corresponding MeasuredParameter and FreeParameter instances.
                args = sfpar.par_convert(args, prog)
                vals = sfpar.par_convert(kwargs.values(), prog)
                kwargs = dict(zip(kwargs.keys(), vals))
                gate(*args, **kwargs) | regrefs  # pylint:disable=expression-not-assigned
            else:
                # the gate has no arguments
                gate | regrefs  # pylint:disable=expression-not-assigned,pointless-statement

    prog._target = bb.target["name"]

    if "shots" in bb.target["options"]:
        prog.run_options["shots"] = bb.target["options"]["shots"]

    if "cutoff_dim" in bb.target["options"]:
        prog.backend_options["cutoff_dim"] = bb.target["options"]["cutoff_dim"]

    return prog
Esempio n. 5
0
    def test_free_par_str(self):
        """Test a FreeParameter with some transformations converts properly"""
        prog = Program(2)
        r, alpha = prog.params('r', 'alpha')
        with prog.context as q:
            ops.Sgate(r) | q[0]
            ops.Zgate(3 * pf.log(-alpha)) | q[1]

        bb = io.to_blackbird(prog)
        assert bb.operations[0] == {"op": "Sgate", "modes": [0], "args": ['{r}', 0.0], "kwargs": {}}
        assert bb.operations[1] == {"op": "Zgate", "modes": [1], "args": ['3*log(-{alpha})'], "kwargs": {}}
Esempio n. 6
0
 def test_pre_measure_eng(self, tol):
     """Test that the pre_measure method operates as expected by initializing the engine
     correctly"""
     dev = qml.device("strawberryfields.gbs", wires=4, cutoff_dim=3)
     prog = Program(4)
     op1 = GraphEmbed(0.1767767 * np.ones((4, 4)), mean_photon_per_mode=0.25)
     prog.append(op1, prog.register)
     dev.prog = prog
     dev.pre_measure()
     assert dev.eng.backend_name == "gaussian"
     assert dev.eng.backend_options == {"cutoff_dim": 3}
Esempio n. 7
0
    def test_free_par_str(self):
        """Test a FreeParameter with some transformations converts properly"""
        sf_prog = Program(2)
        r, alpha = sf_prog.params("r", "alpha")
        with sf_prog.context as q:
            ops.Sgate(r) | q[0]
            ops.Zgate(3 * pf.log(-alpha)) | q[1]

        xir_prog = io.to_xir(sf_prog)

        expected = [("Sgate", ["r", 0.0], (0,)), ("Zgate", ["3*log(-alpha)"], (1,))]
        assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected
Esempio n. 8
0
    def test_pre_measure_state_and_samples(self, tol):
        """Test that the pre_measure method operates as expected in analytic mode by generating the
        correct output state and not generating samples"""
        dev = qml.device("strawberryfields.gbs", wires=4, cutoff_dim=3)
        prog = Program(4)
        op1 = GraphEmbed(0.1767767 * np.ones((4, 4)), mean_photon_per_mode=0.25)
        prog.append(op1, prog.register)
        dev.prog = prog
        dev.pre_measure()

        assert np.allclose(dev.state.displacement(), np.zeros(4))
        assert np.allclose(dev.state.cov(), target_cov, atol=tol)
        assert dev.samples.size == 0
Esempio n. 9
0
    def test_metadata(self):
        """Test metadata correctly converts"""
        # create a test program
        prog = Program(4, name="test_program")
        bb = io.to_blackbird(prog)

        assert bb.name == "test_program"
        assert bb.version == "1.0"
        assert bb.target["name"] is None

        bb = io.to_blackbird(prog.compile(compiler="gaussian"))

        assert bb.name == "test_program"
        assert bb.version == "1.0"
        assert bb.target["name"] == "gaussian"
Esempio n. 10
0
    def test_decomposition_operation_compiled(self):
        """Test decomposition operation gets decomposed if compiled"""
        # create a test program
        prog = Program(1)

        with prog.context as q:
            ops.Pgate(0.43) | q[0]

        bb = io.to_blackbird(prog)
        expected = {"op": "Pgate", "modes": [0], "args": [0.43], "kwargs": {}}
        assert bb.operations[0] == expected

        bb = io.to_blackbird(prog.compile(compiler="gaussian"))
        assert bb.operations[0]["op"] == "Sgate"
        assert bb.operations[1]["op"] == "Rgate"
Esempio n. 11
0
    def test_pre_measure_state_and_samples_non_analytic(self, tol):
        """Test that the pre_measure method operates as expected in non-analytic mode by
        generating the correct output state and samples of the right shape"""
        dev = qml.device("strawberryfields.gbs", wires=4, cutoff_dim=3, analytic=False, shots=2)
        prog = Program(4)
        op1 = GraphEmbed(0.1767767 * np.ones((4, 4)), mean_photon_per_mode=0.25)
        op2 = MeasureFock()
        prog.append(op1, prog.register)
        prog.append(op2, prog.register)
        dev.prog = prog
        dev.pre_measure()

        assert np.allclose(dev.state.displacement(), np.zeros(4))
        assert np.allclose(dev.state.cov(), target_cov, atol=tol)
        assert dev.samples.shape == (2, 4)
Esempio n. 12
0
 def test_complex_first_argument_error(self, gate):
     """Test that passing a complex parameter to gates that previously accepted
     complex parameters raises an error."""
     with pytest.raises(ValueError, match="cannot be complex"):
         prog = Program(1)
         with prog.context as q:
             gate(0.2 + 1j) | q
Esempio n. 13
0
 def _setup_eng(num_subsystems, **kwargs):
     """Factory function"""
     prog = Program(num_subsystems)
     setup_backend_pars.update(kwargs)  # override defaults with kwargs
     eng = Engine(backend=setup_backend_pars['backend_name'],
                  **setup_backend_pars)
     return eng, prog
Esempio n. 14
0
 def _setup_eng(num_subsystems, **kwargs):
     """Factory function"""
     prog = Program(num_subsystems)
     backend, backend_options = setup_backend_pars
     backend_options.update(kwargs)  # override defaults with kwargs
     eng = LocalEngine(backend=backend, backend_options=backend_options)
     return eng, prog
Esempio n. 15
0
    def test_decomposition_operation_compiled(self):
        """Test decomposition operation gets decomposed if compiled"""
        # create a test program
        sf_prog = Program(1)

        with sf_prog.context as q:
            ops.Pgate(0.43) | q[0]

        xir_prog = io.to_xir(sf_prog)

        expected = [("Pgate", [0.43], (0,))]
        assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected

        xir_prog = io.to_xir(sf_prog.compile(compiler="gaussian"))

        assert xir_prog.statements[0].name == "Sgate"
        assert xir_prog.statements[1].name == "Rgate"
Esempio n. 16
0
    def test_empty_program(self):
        """Test that an empty program is correctly converted"""
        # create a test program
        sf_prog = Program(4, name="")
        xir_prog = io.to_xir(sf_prog)

        assert xir_prog.serialize() == ""
        assert xir_prog.version == "0.1.0"
Esempio n. 17
0
    def test_catstate_complex_error(self):
        """Test that passing a complex parameter to gates that previously accepted
        complex parameters raises an error."""
        with pytest.raises(ValueError, match="cannot be complex"):
            prog = Program(1)
            with prog.context as q:
                ops.Catstate(0.2 + 1j) | q

            eng = Engine("fock", backend_options={"cutoff_dim": 5})
            res = eng.run(prog)
Esempio n. 18
0
    def test_measured_par_str(self):
        """Test a MeasuredParameter with some transformations converts properly"""
        prog = Program(2)
        with prog.context as q:
            ops.Sgate(0.43) | q[0]
            ops.MeasureX | q[0]
            ops.Zgate(2 * pf.sin(q[0].par)) | q[1]

        bb = io.to_blackbird(prog)
        expected = {"op": "Zgate", "modes": [1], "args": ["2*sin(q0)"], "kwargs": {}}
        assert bb.operations[-1] == expected
Esempio n. 19
0
    def test_regref_no_func_str(self):
        """Test a regreftransform with no function string raises exception"""
        prog = Program(2)

        with prog.context as q:
            ops.Sgate(0.43) | q[0]
            ops.MeasureX | q[0]
            ops.Zgate(ops.RR(q[0], lambda x: 2 * x)) | q[1]

        with pytest.raises(ValueError, match="not supported by Blackbird"):
            io.to_blackbird(prog)
Esempio n. 20
0
def test_tf_batch_in_gates_previously_supporting_complex(gate):
    """Test if gates that previously accepted complex arguments support the input of TF tensors in
    batch form"""
    tf = pytest.importorskip("tensorflow")

    batch_size = 2
    prog = Program(1)
    eng = Engine(backend="tf",
                 backend_options={
                     "cutoff_dim": 3,
                     "batch_size": batch_size
                 })

    theta = prog.params("theta")
    _theta = tf.Variable([0.1] * batch_size)

    with prog.context as q:
        gate(theta) | q[0]

    eng.run(prog, args={"theta": _theta})
Esempio n. 21
0
    def test_two_mode_gate(self):
        """Test two mode gate converts"""
        sf_prog = Program(4)

        with sf_prog.context as q:
            ops.BSgate(0.54, -0.324) | (q[3], q[0])

        xir_prog = io.to_xir(sf_prog)

        expected = [("BSgate", [0.54, -0.324], (3, 0))]
        assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected
Esempio n. 22
0
    def test_measure_noarg(self):
        """Test measurement with no argument converts"""
        # create a test program
        prog = Program(1)

        with prog.context as q:
            ops.MeasureFock() | q[0]

        bb = io.to_blackbird(prog)
        expected = {"op": "MeasureFock", "modes": [0], "args": [], "kwargs": {}}

        assert bb.operations[0] == expected
Esempio n. 23
0
    def test_gate_noarg(self):
        """Test gate with no argument converts"""
        # create a test program
        sf_prog = Program(1)

        with sf_prog.context as q:
            ops.Vac | q[0]

        xir_prog = io.to_xir(sf_prog)

        expected = [("Vacuum", [], (0,))]
        assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected
Esempio n. 24
0
    def test_gate_arg(self):
        """Test gate with argument converts"""
        # create a test program
        sf_prog = Program(2)

        with sf_prog.context as q:
            ops.Sgate(0.54, 0.324) | q[1]

        xir_prog = io.to_xir(sf_prog)

        expected = [("Sgate", [0.54, 0.324], (1,))]
        assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected
Esempio n. 25
0
    def test_measure_arg(self):
        """Test measurement with argument converts"""
        # create a test program
        sf_prog = Program(1)

        with sf_prog.context as q:
            ops.MeasureHomodyne(0.43) | q[0]

        xir_prog = io.to_xir(sf_prog)

        expected = [("MeasureHomodyne", {"phi": 0.43}, (0,))]
        assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected
Esempio n. 26
0
    def test_gate_noarg(self):
        """Test gate with no argument converts"""
        # create a test program
        prog = Program(1)

        with prog.context as q:
            ops.Vac | q[0]

        bb = io.to_blackbird(prog)
        expected = {"op": "Vacuum", "modes": [0], "args": [], "kwargs": {}}

        assert bb.operations[0] == expected
Esempio n. 27
0
    def test_measure_postselect(self):
        """Test measurement with postselection"""
        # create a test program
        sf_prog = Program(1)

        with sf_prog.context as q:
            ops.MeasureFock(select=2) | q[0]

        xir_prog = io.to_xir(sf_prog)

        expected = [("MeasureFock", {"select": [2]}, (0,))]
        assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected
Esempio n. 28
0
    def test_measure_darkcounts(self):
        """Test measurement with dark counts"""
        # create a test program
        sf_prog = Program(1)

        with sf_prog.context as q:
            ops.MeasureFock(dark_counts=2) | q[0]

        xir_prog = io.to_xir(sf_prog)

        expected = [("MeasureFock", {"dark_counts": [2]}, (0,))]
        assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected
Esempio n. 29
0
def test_tf_batch_complex_raise(gate):
    """Test if an error is raised if complex TF tensors with a batch dimension are input for gates
    that previously accepted complex arguments"""
    tf = pytest.importorskip("tensorflow")

    batch_size = 2
    prog = Program(1)
    eng = Engine(backend="tf",
                 backend_options={
                     "cutoff_dim": 3,
                     "batch_size": batch_size
                 })

    theta = prog.params("theta")
    _theta = tf.Variable([0.1j] * batch_size)

    with prog.context as q:
        gate(theta) | q[0]

    with pytest.raises(ValueError, match="cannot be complex"):
        eng.run(prog, args={"theta": _theta})
Esempio n. 30
0
    def test_measure_arg_postselect(self):
        """Test measurement with argument and postselection converts"""
        # create a test program
        sf_prog = Program(1)

        with sf_prog.context as q:
            ops.MeasureHomodyne(0.43, select=0.543) | q[0]

        xir_prog = io.to_xir(sf_prog)

        expected = [("MeasureHomodyne", {"phi": 0.43, "select": 0.543}, (0,))]
        assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected

        # repeat with kwargs only
        sf_prog = Program(1)

        with sf_prog.context as q:
            ops.MeasureHomodyne(phi=0.43, select=0.543) | q[0]

        xir_prog = io.to_xir(sf_prog)
        assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected