Пример #1
0
    def test_program_sequence(self, eng, monkeypatch):
        """Test that program run_options are successively
        updated if a sequence of programs is executed."""
        bb_script = """\
        name test_program
        version 1.0
        target gaussian (shots=100)
        Pgate(0.54) | 0
        MeasureX | 0
        """
        bb = blackbird.loads(bb_script)
        prog1 = io.to_program(bb)

        bb_script = """\
        name test_program
        version 1.0
        target gaussian (shots=1024)
        Pgate(0.54) | 0
        MeasureX | 0
        """
        bb = blackbird.loads(bb_script)
        prog2 = io.to_program(bb)

        assert prog1.run_options == {"shots": 100}
        assert prog2.run_options == {"shots": 1024}

        with monkeypatch.context() as m:
            m.setattr("strawberryfields.engine.BaseEngine._run", dummy_run)
            results = eng.run([prog1, prog2])

        assert results.run_options == prog2.run_options
Пример #2
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)
Пример #3
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)
Пример #4
0
    def test_empty_program(self):
        """Test empty program raises error"""

        bb_script = """\
        name test_program
        version 1.0
        """

        bb = blackbird.loads(bb_script)

        with pytest.raises(ValueError, match="contains no quantum operations"):
            io.to_program(bb)
Пример #5
0
    def test_gate_not_defined(self):
        """Test unknown gate raises error"""

        bb_script = """\
        name test_program
        version 1.0

        np | [0, 1]
        """

        bb = blackbird.loads(bb_script)

        with pytest.raises(NameError, match="operation np not defined"):
            io.to_program(bb)
Пример #6
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)
Пример #7
0
    def test_gate_measured_par(self):
        """Test a gate with a MeasuredParameter argument."""

        bb_script = """\
        name test_program
        version 1.0

        MeasureX | 0
        Dgate(q0) | 1
        Rgate(2*q0) | 2
        """
        bb = blackbird.loads(bb_script)
        prog = io.to_program(bb)

        assert len(prog) == 3

        cmd = prog.circuit[1]
        assert cmd.op.__class__.__name__ == "Dgate"
        p = cmd.op.p[0]
        assert isinstance(p, MeasuredParameter)
        assert p.regref.ind == 0
        assert cmd.reg[0].ind == 1

        cmd = prog.circuit[2]
        assert cmd.op.__class__.__name__ == "Rgate"
        p = cmd.op.p[0]
        assert par_is_symbolic(p)  # symbolic expression
        assert cmd.reg[0].ind == 2
    def test_exact_template(self, tol):
        """Test compilation works for the exact circuit"""
        bb = blackbird.loads(X8_01.circuit)
        bb = bb(
            squeezing_amplitude_0=SQ_AMPLITUDE,
            squeezing_amplitude_1=SQ_AMPLITUDE,
            squeezing_amplitude_2=SQ_AMPLITUDE,
            squeezing_amplitude_3=SQ_AMPLITUDE,
            phase_0=0,
            phase_1=1,
            phase_2=2,
            phase_3=3,
            phase_4=4,
            phase_5=5,
            phase_6=6,
            phase_7=7,
            phase_8=8,
            phase_9=9,
            phase_10=10,
            phase_11=11,
            final_phase_0=1.24,
            final_phase_1=-0.54,
            final_phase_2=4.12,
            final_phase_3=0,
            final_phase_4=1.24,
            final_phase_5=-0.54,
            final_phase_6=4.12,
            final_phase_7=0,
        )

        expected = to_program(bb)
        res = expected.compile("Xunitary")
        print("hello")
        assert program_equivalence(res, expected, atol=tol, compare_params=False)
Пример #9
0
    def test_valid_compilation(self):
        """Test setting compilation target using the target keyword"""
        bb_script = """\
        name test_program
        version 1.0
        target gaussian
        Pgate(0.54) | 0
        """

        bb = blackbird.loads(bb_script)
        prog = io.to_program(bb)

        assert len(prog) == 1
        assert prog.circuit[0].op.__class__.__name__ == "Pgate"
        assert prog.circuit[0].reg[0].ind == 0
        assert prog.backend == 'gaussian'

        # after compilation
        prog = prog.compile('gaussian')

        assert len(prog) == 2
        assert prog.circuit[0].op.__class__.__name__ == "Sgate"
        assert prog.circuit[0].reg[0].ind == 0
        assert prog.circuit[1].op.__class__.__name__ == "Rgate"
        assert prog.circuit[1].reg[0].ind == 0
Пример #10
0
    def test_exact_template(self, chip, tol):
        """Test compilation works for the exact circuit"""
        bb = blackbird.loads(chip.circuit)
        bb = bb(
            squeezing_amplitude_0=SQ_AMPLITUDE,
            squeezing_amplitude_1=SQ_AMPLITUDE,
            squeezing_amplitude_2=SQ_AMPLITUDE,
            squeezing_amplitude_3=SQ_AMPLITUDE,
            squeezing_amplitude_4=SQ_AMPLITUDE,
            squeezing_amplitude_5=SQ_AMPLITUDE,
            phase_0=0,
            phase_1=1,
            phase_2=2,
            phase_3=3,
            phase_4=4,
            phase_5=5,
            phase_6=6,
            phase_7=7,
            phase_8=8,
            phase_9=9,
            phase_10=10,
            phase_11=11,
            phase_12=12,
            phase_13=13,
            phase_14=14,
            phase_15=15,
            phase_16=16,
            phase_17=17,
            phase_18=18,
            phase_19=19,
            phase_20=20,
            phase_21=21,
            phase_22=22,
            phase_23=23,
            phase_24=24,
            phase_25=25,
            phase_26=26,
            phase_27=27,
            phase_28=28,
            phase_29=29,
            final_phase_0=1.24,
            final_phase_1=-0.54,
            final_phase_2=4.12,
            final_phase_3=0,
            final_phase_4=1.24,
            final_phase_5=-0.54,
            final_phase_6=4.12,
            final_phase_7=0,
            final_phase_8=1.24,
            final_phase_9=-0.54,
            final_phase_10=4.12,
            final_phase_11=0,

        )

        expected = to_program(bb)
        res = expected.compile(chip.short_name)

        assert program_equivalence(res, expected, atol=tol)
    def test_tdm_program(self):
        """Test converting a tdm bb_script to a TDMProgram"""

        bb_script = textwrap.dedent("""\
        name None
        version 1.0
        type tdm (temporal_modes=3)

        int array p0 =
            1, 2
        int array p1 =
            3, 4
        int array p2 =
            5, 6

        Sgate(0.7, 0) | 1
        BSgate(p0, 0.0) | [0, 1]
        Rgate(p1) | 1
        MeasureHomodyne(phi=p2) | 0
        """)

        bb = blackbird.loads(bb_script)
        prog = io.to_program(bb)
        assert isinstance(prog, TDMProgram)

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

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

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

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

        assert prog.concurr_modes == 2
        assert prog.timebins == 2
        assert prog.spatial_modes == 1
        assert prog.free_params == {
            "p0": FreeParameter("p0"),
            "p1": FreeParameter("p1"),
            "p2": FreeParameter("p2"),
        }
        assert all(prog.tdm_params[0] == np.array([1, 2]))
        assert all(prog.tdm_params[1] == np.array([3, 4]))
        assert all(prog.tdm_params[2] == np.array([5, 6]))
Пример #12
0
    def test_gate_not_defined_tdm(self):
        """Test unknown gate raises error for tdm program"""

        bb_script = textwrap.dedent("""\
        name test_program
        version 1.0
        type tdm (temporal_modes= 12)

        int array p42 =
            1, 3, 5

        np | [0, 1]
        """)

        bb = blackbird.loads(bb_script)

        with pytest.raises(NameError, match="operation np not defined"):
            io.to_program(bb)
Пример #13
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]))
Пример #14
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
Пример #15
0
 def test_invalid_compilation(self):
     """Test an invalid compilation target raises error on attempted compilation"""
     bb_script = """\
      name test_program
      version 1.0
      target gaussian
      Kgate(0.54) | 0
      """
     bb = blackbird.loads(bb_script)
     with pytest.raises(CircuitError,
                        match="cannot be used with the target"):
         prog = io.to_program(bb)
Пример #16
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}
Пример #17
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
Пример #18
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
Пример #19
0
    def test_metadata(self):
        """Test metadata converts"""

        bb_script = """\
        name test_program
        version 1.0
        Vac | 0
        """

        bb = blackbird.loads(bb_script)
        prog = io.to_program(bb)

        assert prog.name == bb.name
Пример #20
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
Пример #21
0
    def compile(self, seq, registers):
        """Compiles the Borealis circuit by inserting missing phase gates due to loop offsets.

        Args:
            seq (Sequence[Command]): quantum circuit to modify
            registers (Sequence[RegRefs]): quantum registers

        Returns:
            List[Command]: modified circuit

        Raises:
            CircuitError: the given circuit cannot be validated to belong to this circuit class
        """
        # keep track of whether a loop offset has been set by the user (True)
        # or by the compiler (False), for
        self._user_offsets: List[bool] = []

        if self.circuit:
            bb = blackbird.loads(self.circuit)
            program = sio.to_program(bb)
            circuit = program.circuit or []

            for i, cmds in enumerate(zip(circuit, seq)):
                wires_0 = {m.ind for m in cmds[0].reg}
                wires_1 = {m.ind for m in cmds[1].reg}

                ops_not_equal = type(cmds[0].op) != type(cmds[1].op) or wires_0 != wires_1

                # if the operation in the device spec is _not_ a loop offset and differs from the
                # user set value, the topology cannot be made to match the device layout by
                # just inserting loop offsets.
                if self._is_loop_offset(cmds[0].op):
                    if ops_not_equal:
                        seq.insert(i, cmds[0])
                        self._user_offsets.append(False)
                    else:
                        self._user_offsets.append(True)
                elif ops_not_equal:
                    raise CircuitError(
                        "Compilation not possible due to incompatible topologies. Expected loop "
                        f"offset gate or '{type(cmds[0].op).__name__}' on mode(s) {wires_0}, got "
                        f"'{type(cmds[1].op).__name__}' on mode(s) {wires_1}."
                    )

            seq.extend(circuit[len(seq) :])

        # pass the circuit sequence to the general TMD compiler to make sure that
        # it corresponds to the correct device layout in the specification
        return super().compile(seq, registers)
Пример #22
0
    def create_program(self, **parameters: complex):
        """Create a Strawberry Fields program matching the low-level Blackbird
        layout of the device.

        Gate arguments should be passed as keyword arguments, with names
        correspond to those present in the Blackbird circuit layout. Parameters not
        present will be assumed to have a value of 0.

        **Example**

        Device specifications can be retrieved from the API by using the
        :class:`xcc.Device` and :class:`xcc.Connection` classes:

        >>> spec.create_program(squeezing_amplitude_0=0.43)
        <strawberryfields.program.Program at 0x7fd37e27ff50>

        Keyword Args:
            Supported parameter values for the specific device

        Returns:
            strawberryfields.program.Program: program compiled to the device
        """
        if not self.layout:
            raise ValueError(
                "Cannot create program. Specification is missing a circuit layout."
            )

        try:
            bb = blackbird.loads(self.layout)
        except BlackbirdSyntaxError as e:
            raise BlackbirdSyntaxError(
                "Layout is not formatted correctly.") from e
        self.validate_parameters(**parameters)

        if self.gate_parameters:
            # determine parameter value if not provided
            extra_params = set(self.gate_parameters) - set(parameters)

            for p in extra_params:
                # Set parameter value as the first allowed
                # value in the gate parameters dictionary.
                parameters[p] = self.gate_parameters[p].ranges[0].x

        # evaluate the blackbird template
        bb = bb(**parameters)
        prog = to_program(bb)
        prog.compile(compiler=self.default_compiler)

        return prog
Пример #23
0
    def test_gate_no_arg(self):
        """Test gate with no argument converts"""

        bb_script = """\
        name test_program
        version 1.0
        Vac | 0
        """

        bb = blackbird.loads(bb_script)
        prog = io.to_program(bb)

        assert len(prog) == 1
        assert prog.circuit[0].op.__class__.__name__ == "Vacuum"
        assert prog.circuit[0].reg[0].ind == 0
Пример #24
0
    def test_gate_arg(self):
        """Test gate with arguments converts"""

        bb_script = """\
        name test_program
        version 1.0
        Sgate(0.54, 0.12) | 0
        """

        bb = blackbird.loads(bb_script)
        prog = io.to_program(bb)

        assert len(prog) == 1
        assert prog.circuit[0].op.__class__.__name__ == "Sgate"
        assert prog.circuit[0].op.p[0].x == 0.54
        assert prog.circuit[0].op.p[1].x == 0.12
        assert prog.circuit[0].reg[0].ind == 0
Пример #25
0
    def test_gate_kwarg(self):
        """Test gate with keyword argument converts"""

        bb_script = """\
        name test_program
        version 1.0

        Dgate(0.54, 0) | 0
        """

        bb = blackbird.loads(bb_script)
        prog = io.to_program(bb)

        assert len(prog) == 1
        assert prog.circuit[0].op.__class__.__name__ == "Dgate"
        assert prog.circuit[0].op.p[0] == 0.54
        assert prog.circuit[0].reg[0].ind == 0
    def test_gate_free_par(self):
        """Test a FreeParameter with some transformations converts properly"""

        bb_script = """\
        name test_program
        version 1.0

        Dgate(1-{ALPHA}, 0) | 0     # keyword arg, compound expr
        Rgate(theta={foo_bar1}) | 0  # keyword arg, atomic
        Dgate({ALPHA}**2, 0) | 0        # positional arg, compound expr
        Rgate({foo_bar2}) | 0        # positional arg, atomic
        """
        bb = blackbird.loads(bb_script)
        prog = io.to_program(bb)

        assert prog.free_params.keys() == set(
            ["foo_bar1", "foo_bar2", "ALPHA"])
        assert len(prog) == 4
        assert prog.circuit

        cmd = prog.circuit[0]
        assert cmd.op.__class__.__name__ == "Dgate"
        p = cmd.op.p[0]
        assert par_is_symbolic(p)
        assert cmd.reg[0].ind == 0

        cmd = prog.circuit[1]
        assert cmd.op.__class__.__name__ == "Rgate"
        p = cmd.op.p[0]
        assert isinstance(p, FreeParameter)
        assert p.name == "foo_bar1"
        assert cmd.reg[0].ind == 0

        cmd = prog.circuit[2]
        assert cmd.op.__class__.__name__ == "Dgate"
        p = cmd.op.p[0]
        assert par_is_symbolic(p)
        assert cmd.reg[0].ind == 0

        cmd = prog.circuit[3]
        assert cmd.op.__class__.__name__ == "Rgate"
        p = cmd.op.p[0]
        assert isinstance(p, FreeParameter)
        assert p.name == "foo_bar2"
        assert cmd.reg[0].ind == 0
    def test_exact_template(self, tol):
        """Test compilation works for the exact circuit"""
        bb = blackbird.loads(Chip0Specs.circuit)
        bb = bb(
            squeezing_amplitude_0=0.43,
            squeezing_amplitude_1=0.65,
            external_phase_0=0.54,
            internal_phase_0=-0.23,
            final_phase_0=1.24,
            final_phase_1=-0.54,
            final_phase_2=4.12,
            final_phase_3=0,
        )

        expected = to_program(bb)
        res = expected.compile("chip0")

        assert program_equivalence(res, expected, atol=tol)
Пример #28
0
    def test_shots(self, eng, monkeypatch):
        """Test that passing shots correctly propagates to an engine run"""
        bb_script = """\
        name test_program
        version 1.0
        target gaussian (shots=100)
        Pgate(0.54) | 0
        MeasureX | 0
        """
        bb = blackbird.loads(bb_script)
        prog = io.to_program(bb)

        assert prog.run_options == {"shots": 100}

        with monkeypatch.context() as m:
            m.setattr("strawberryfields.engine.BaseEngine._run", dummy_run)
            results = eng.run(prog)

        assert results.run_options == {"shots": 100}
Пример #29
0
    def test_gate_multimode(self):
        """Test multimode gate converts"""

        bb_script = """\
        name test_program
        version 1.0

        BSgate(theta=0.54, phi=pi) | [0, 2]
        """

        bb = blackbird.loads(bb_script)
        prog = io.to_program(bb)

        assert len(prog) == 1
        assert prog.circuit[0].op.__class__.__name__ == "BSgate"
        assert prog.circuit[0].op.p[0] == 0.54
        assert prog.circuit[0].op.p[1] == np.pi
        assert prog.circuit[0].reg[0].ind == 0
        assert prog.circuit[0].reg[1].ind == 2
Пример #30
0
    def test_shots_overwritten(self, eng, monkeypatch):
        """Test if run_options are passed to eng.run, they
        overwrite those stored in the compiled program"""
        bb_script = """\
        name test_program
        version 1.0
        target gaussian (shots=100)
        Pgate(0.54) | 0
        MeasureX | 0
        """
        bb = blackbird.loads(bb_script)
        prog = io.to_program(bb)

        assert prog.run_options == {"shots": 100}

        with monkeypatch.context() as m:
            m.setattr("strawberryfields.engine.BaseEngine._run", dummy_run)
            results = eng.run(prog, shots=1000)

        assert results.run_options == {"shots": 1000}