Beispiel #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
def test_two_dimensional_cluster_denmark():
    """
    Two-dimensional temporal-mode cluster state as demonstrated in https://arxiv.org/pdf/1906.08709
    """
    np.random.seed(42)
    sq_r = 3
    delay1 = 1  # number of timebins in the short delay line
    delay2 = 12  # number of timebins in the long delay line
    n = 200  # number of timebins
    shots = 10
    # first half of cluster state measured in X, second half in P

    theta_A = [0] * int(n / 2) + [np.pi / 2] * int(
        n / 2)  # measurement angles for detector A
    theta_B = theta_A  # measurement angles for detector B

    # 2D cluster
    prog = tdmprogram.TDMProgram([1, delay2 + delay1 + 1])
    with prog.context(theta_A, theta_B, shift="default") as (p, q):
        ops.Sgate(sq_r, 0) | q[0]
        ops.Sgate(sq_r, 0) | q[delay2 + delay1 + 1]
        ops.Rgate(np.pi / 2) | q[delay2 + delay1 + 1]
        ops.BSgate(np.pi / 4, np.pi) | (q[delay2 + delay1 + 1], q[0])
        ops.BSgate(np.pi / 4, np.pi) | (q[delay2 + delay1], q[0])
        ops.BSgate(np.pi / 4, np.pi) | (q[delay1], q[0])
        ops.MeasureHomodyne(p[1]) | q[0]
        ops.MeasureHomodyne(p[0]) | q[delay1]
    eng = sf.Engine("gaussian")
    result = eng.run(prog, shots=shots)
    reshaped_samples = result.samples

    for sh in range(shots):
        X_A = reshaped_samples[sh][0][:n // 2]  # X samples from detector A
        P_A = reshaped_samples[sh][0][n // 2:]  # P samples from detector A
        X_B = reshaped_samples[sh][1][:n // 2]  # X samples from detector B
        P_B = reshaped_samples[sh][1][n // 2:]  # P samples from detector B

        # nullifiers defined in https://arxiv.org/pdf/1906.08709.pdf, Eqs. (1) and (2)
        N = delay2
        ntot = len(X_A) - delay2 - 1
        nX = np.array([
            X_A[k] + X_B[k] - X_A[k + 1] - X_B[k + 1] - X_A[k + N] +
            X_B[k + N] - X_A[k + N + 1] + X_B[k + N + 1] for k in range(ntot)
        ])
        nP = np.array([
            P_A[k] + P_B[k] + P_A[k + 1] + P_B[k + 1] - P_A[k + N] +
            P_B[k + N] + P_A[k + N + 1] - P_B[k + N + 1] for k in range(ntot)
        ])
        nXvar = np.var(nX)
        nPvar = np.var(nP)

        assert np.allclose(nXvar,
                           4 * sf.hbar * np.exp(-2 * sq_r),
                           rtol=5 / np.sqrt(ntot))
        assert np.allclose(nPvar,
                           4 * sf.hbar * np.exp(-2 * sq_r),
                           rtol=5 / np.sqrt(ntot))
def test_one_dimensional_cluster_tokyo():
    """
    One-dimensional temporal-mode cluster state as demonstrated in
    https://aip.scitation.org/doi/pdf/10.1063/1.4962732
    """
    np.random.seed(42)
    sq_r = 5

    n = 10  # for an n-mode cluster state
    shots = 3

    # first half of cluster state measured in X, second half in P
    theta1 = [0] * int(n / 2) + [np.pi / 2] * int(
        n / 2)  # measurement angles for detector A
    theta2 = theta1  # measurement angles for detector B

    prog = tdmprogram.TDMProgram(N=[1, 2])
    with prog.context(theta1, theta2, shift="default") as (p, q):
        ops.Sgate(sq_r, 0) | q[0]
        ops.Sgate(sq_r, 0) | q[2]
        ops.Rgate(np.pi / 2) | q[0]
        ops.BSgate(np.pi / 4) | (q[0], q[2])
        ops.BSgate(np.pi / 4) | (q[0], q[1])
        ops.MeasureHomodyne(p[0]) | q[0]
        ops.MeasureHomodyne(p[1]) | q[1]
    eng = sf.Engine("gaussian")

    result = eng.run(prog, shots=shots)
    reshaped_samples = result.samples

    for sh in range(shots):
        X_A = reshaped_samples[sh][0][:n // 2]  # X samples from detector A
        P_A = reshaped_samples[sh][0][n // 2:]  # P samples from detector A
        X_B = reshaped_samples[sh][1][:n // 2]  # X samples from detector B
        P_B = reshaped_samples[sh][1][n // 2:]  # P samples from detector B

        # nullifiers defined in https://aip.scitation.org/doi/pdf/10.1063/1.4962732, Eqs. (1a) and (1b)
        ntot = len(X_A) - 1
        nX = np.array(
            [X_A[i] + X_B[i] + X_A[i + 1] - X_B[i + 1] for i in range(ntot)])
        nP = np.array(
            [P_A[i] + P_B[i] - P_A[i + 1] + P_B[i + 1] for i in range(ntot)])

        nXvar = np.var(nX)
        nPvar = np.var(nP)

        assert np.allclose(nXvar,
                           2 * sf.hbar * np.exp(-2 * sq_r),
                           rtol=5 / np.sqrt(n))
        assert np.allclose(nPvar,
                           2 * sf.hbar * np.exp(-2 * sq_r),
                           rtol=5 / np.sqrt(n))
    def test_teleportation_fidelity(self, setup_eng):
        """Test teleportation algorithm gives correct fid when using operations"""
        eng, prog = setup_eng(3)
        with prog.context as q:
            prepare_state(0.5 + 0.2j) | q[0]
            entangle_states() | (q[1], q[2])
            ops.BSgate(np.pi / 4, 0) | (q[0], q[1])
            ops.MeasureHomodyne(0, select=0) | q[0]
            ops.MeasureHomodyne(np.pi / 2, select=0) | q[1]

        state = eng.run(prog).state
        fidelity = state.fidelity_coherent([0, 0, 0.5 + 0.2j])
        assert np.allclose(fidelity, 1, atol=0.1, rtol=0)
    def test_delays_tdmprogram_with_several_spatial_modes(self):
        """Test that error is raised when calculating the delays of a TDM program with more than
        one spatial mode"""

        prog = TDMProgram(N=[1, 2])
        with prog.context([0, np.pi / 2], [0, np.pi / 2]) as (p, q):
            ops.Sgate(4) | q[0]
            ops.Sgate(4) | q[2]
            ops.MeasureHomodyne(p[0]) | q[0]
            ops.MeasureHomodyne(p[1]) | q[1]

        with pytest.raises(
            NotImplementedError,
            match="Calculating delays for programs with more than one spatial mode is not implemented.",
        ):
            prog.get_delays()
    def test_cropping_tdmprogram_with_several_spatial_modes(self):
        """Test that error is raised when cropping samples from a TDM program with more than
        one spatial mode"""

        prog = TDMProgram(N=[1, 2])
        with prog.context([0, np.pi / 2], [0, np.pi / 2]) as (p, q):
            ops.Sgate(4) | q[0]
            ops.Sgate(4) | q[2]
            ops.MeasureHomodyne(p[0]) | q[0]
            ops.MeasureHomodyne(p[1]) | q[1]

        with pytest.raises(
            NotImplementedError,
            match="Cropping vacuum modes for programs with more than one spatial mode is not implemented.",
        ):
            prog.get_crop_value()
    def test_unroll_shots(self):
        """Test unrolling program several times using different number of shots."""
        n = 2
        shots = 2

        prog = sf.TDMProgram(N=2)
        with prog.context([0] * n, [0] * n, [0] * n) as (p, q):
            ops.Sgate(0.5643, 0) | q[1]
            ops.BSgate(p[0]) | (q[1], q[0])
            ops.Rgate(p[1]) | q[1]
            ops.MeasureHomodyne(p[2]) | q[0]

        prog_length = len(prog.circuit)
        assert prog_length == 4

        prog.unroll(shots=shots)
        assert len(prog.circuit) == n * shots * prog_length

        # unroll once more with the same number of shots to cover caching
        prog.unroll(shots=shots)
        assert len(prog.circuit) == n * shots * prog_length

        # unroll once more with a different number of shots
        shots = 3
        prog.unroll(shots=shots)
        assert len(prog.circuit) == n * shots * prog_length

        prog.roll()
        assert len(prog.circuit) == prog_length
Beispiel #8
0
    def test_homodyne_measurement_vacuum_phi(self, setup_eng, tol):
        """Homodyne measurements leave the mode in the vacuum state"""
        eng, prog = setup_eng(2)
        with prog.context as q:
            ops.Coherent(a, b) | q[0]
            ops.MeasureHomodyne(c) | q[0]

        eng.run(prog)
        assert np.all(eng.backend.is_vacuum(tol))
    def test_teleportation_fidelity(self, setup_eng, pure):
        """Test teleportation algorithm gives correct fid when using operations"""
        eng, q = setup_eng(3)
        tol = 0.1
        cutoff = 10

        eng.reset(pure=pure, cutoff_dim=cutoff)  # overwrite default cutoff

        with eng:
            prepare_state(0.5 + 0.2j) | q[0]
            entangle_states() | (q[1], q[2])
            ops.BSgate(np.pi / 4, 0) | (q[0], q[1])
            ops.MeasureHomodyne(0, select=0) | q[0]
            ops.MeasureHomodyne(np.pi / 2, select=0) | q[1]

        state = eng.run()
        fidelity = state.fidelity_coherent([0, 0, 0.5 + 0.2j])
        assert np.allclose(fidelity, 1, atol=0.1, rtol=0)
    def test_shots_default(self):
        """Test that default shots (1) is used"""
        prog = sf.TDMProgram(2)
        eng = sf.Engine("gaussian")

        with prog.context([1, 2], [3, 4]) as (p, q):
            ops.Sgate(p[0]) | q[0]
            ops.MeasureHomodyne(p[1]) | q[0]

        results = eng.run(prog)
        assert results.samples.shape[0] == 1
Beispiel #11
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
    def test_shots_run_options(self):
        """Test that run_options takes precedence over default"""
        prog = sf.TDMProgram(2)
        eng = sf.Engine("gaussian")

        with prog.context([1, 2], [3, 4]) as (p, q):
            ops.Sgate(p[0]) | q[0]
            ops.MeasureHomodyne(p[1]) | q[0]

        prog.run_options = {"shots": 5}
        results = eng.run(prog)
        assert results.samples.shape[0] == 5
Beispiel #13
0
    def test_generate_code_tdm(self):
        """Test generating code for a TDM program with an engine"""
        prog = sf.TDMProgram(N=[2, 3])
        eng = sf.Engine("gaussian")

        with prog.context([np.pi, 3 * np.pi / 2, 0], [1, 0.5, np.pi], [0, 0, 0]) as (p, q):
            ops.Sgate(0.123, np.pi / 4) | q[2]
            ops.BSgate(p[0]) | (q[1], q[2])
            ops.Rgate(p[1]) | q[2]
            ops.MeasureHomodyne(p[0]) | q[0]
            ops.MeasureHomodyne(p[2]) | q[2]

        results = eng.run(prog)

        code = io.generate_code(prog, eng)

        code_list = code.split("\n")
        expected = prog_txt_tdm.split("\n")

        for i, row in enumerate(code_list):
            assert row == expected[i]
Beispiel #14
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
def test_single_parameter_list_program():
    """Test that a TDMProgram with a single parameter list works."""
    prog = sf.TDMProgram(2)
    eng = sf.Engine("gaussian")

    with prog.context([1, 2]) as (p, q):
        ops.Sgate(p[0]) | q[0]
        ops.MeasureHomodyne(p[0]) | q[0]

    eng.run(prog)

    assert isinstance(prog.loop_vars, Iterable)
    assert prog.parameters == {'p0': [1, 2]}
 def compile_test_program(device, args=(-1, 1, 2, 3)):
     """Compiles a test program with the given gate arguments."""
     alpha = [args[1]]
     beta = [args[2]]
     gamma = [args[3]]
     prog = tdmprogram.TDMProgram(N=2)
     with prog.context(alpha, beta, gamma) as (p, q):
         ops.Sgate(args[0]) | q[
             1]  # Note that the Sgate has a second parameter that is non-zero
         ops.Rgate(p[0]) | q[0]
         ops.BSgate(p[1]) | (q[0], q[1])
         ops.MeasureHomodyne(p[2]) | q[0]
     prog.compile(device=device, compiler=device.compiler)
    def test_shots_passed(self):
        """Test that shots supplied via eng.run takes precedence over
        run_options and that run_options isn't changed"""
        prog = sf.TDMProgram(2)
        eng = sf.Engine("gaussian")

        with prog.context([1, 2], [3, 4]) as (p, q):
            ops.Sgate(p[0]) | q[0]
            ops.MeasureHomodyne(p[1]) | q[0]

        prog.run_options = {"shots": 5}
        results = eng.run(prog, shots=2)
        assert results.samples.shape[0] == 2
        assert prog.run_options["shots"] == 5
    def test_homodyne(self, setup_eng, tol):
        """Test that homodyne detection on a TMS state
        returns post-selected value."""
        x = 0.2
        r = 5

        eng, prog = setup_eng(2)

        with prog.context as q:
            ops.S2gate(r) | q
            ops.MeasureHomodyne(0, select=x) | q[0]

        eng.run(prog)
        assert np.allclose(q[0].val, x, atol=tol, rtol=0)
Beispiel #19
0
    def test_tdm_program(self):
        prog = TDMProgram(2)

        with prog.context([1, 2], [3, 4], [5, 6]) as (p, q):
            ops.Sgate(0.7, 0) | q[1]
            ops.BSgate(p[0]) | (q[0], q[1])
            ops.Rgate(p[1]) | q[1]
            ops.MeasureHomodyne(p[2]) | q[0]

        bb = io.to_blackbird(prog)

        assert bb.operations[0] == {
            'kwargs': {},
            'args': [0.7, 0],
            'op': 'Sgate',
            'modes': [1]
        }
        assert bb.operations[1] == {
            'kwargs': {},
            'args': ['p0', 0.0],
            'op': 'BSgate',
            'modes': [0, 1]
        }
        assert bb.operations[2] == {
            'kwargs': {},
            'args': ['p1'],
            'op': 'Rgate',
            'modes': [1]
        }
        assert bb.operations[3] == {
            'kwargs': {
                'phi': 'p2'
            },
            'args': [],
            'op': 'MeasureHomodyne',
            'modes': [0]
        }

        assert bb.programtype == {
            'name': 'tdm',
            'options': {
                'temporal_modes': 2
            }
        }
        assert list(bb._var.keys()) == ["p0", "p1", "p2"]
        assert np.all(bb._var["p0"] == np.array([[1, 2]]))
        assert np.all(bb._var["p1"] == np.array([[3, 4]]))
        assert np.all(bb._var["p2"] == np.array([[5, 6]]))
        assert bb.modes == [0, 1]
Beispiel #20
0
def prog():
    prog = Program(4, name="test_program")

    with prog.context as q:
        # state preparation
        ops.Vac | q[1]
        ops.Squeezed(0.12) | q[2]

        # one mode gates
        ops.Sgate(1) | q[0]
        ops.Dgate(np.abs(0.54 + 0.5j), np.angle(0.54 + 0.5j)) | q[1]

        # two mode gates
        ops.S2gate(0.543, -0.12) | (q[0], q[3])

        # decomposition
        ops.Interferometer(U) | q

        # measurement
        ops.MeasureX | q[0]
        ops.MeasureHomodyne(0.43, select=0.32) | q[2]
        ops.MeasureHomodyne(phi=0.43, select=0.32) | q[2]

    return prog
    def test_passing_list_of_tdmprograms(self):
        """Test that error is raised when passing a list containing TDM programs"""
        prog = tdmprogram.TDMProgram(N=2)
        with prog.context([1, 1], [1, 1], [1, 1]) as (p, q):
            ops.Sgate(0, 0) | q[1]
            ops.BSgate(p[0]) | (q[0], q[1])
            ops.Rgate(p[1]) | q[1]
            ops.MeasureHomodyne(p[2]) | q[0]

        eng = sf.Engine("gaussian")

        with pytest.raises(
                NotImplementedError,
                match="Lists of TDM programs are not currently supported"):
            eng.run([prog, prog])
    def test_tdm_program(self):
        """Test TDM program converts properly"""
        prog = TDMProgram(2)

        with prog.context([1, 2], [3, 4], [5, 6]) as (p, q):
            ops.Sgate(0.7, 0) | q[1]
            ops.BSgate(p[0]) | (q[0], q[1])
            ops.Rgate(p[1]) | q[1]
            ops.MeasureHomodyne(p[2]) | q[0]

        bb = io.to_blackbird(prog)

        assert bb.operations[0] == {
            "kwargs": {},
            "args": [0.7, 0],
            "op": "Sgate",
            "modes": [1]
        }
        assert bb.operations[1] == {
            "kwargs": {},
            "args": ["p0", 0.0],
            "op": "BSgate",
            "modes": [0, 1],
        }
        assert bb.operations[2] == {
            "kwargs": {},
            "args": ["p1"],
            "op": "Rgate",
            "modes": [1]
        }
        assert bb.operations[3] == {
            "kwargs": {},
            "args": ["p2"],
            "op": "MeasureHomodyne",
            "modes": [0],
        }

        assert bb.programtype == {
            "name": "tdm",
            "options": {
                "temporal_modes": 2
            }
        }
        assert list(bb._var.keys()) == ["p0", "p1", "p2"]
        assert np.all(bb._var["p0"] == np.array([[1, 2]]))
        assert np.all(bb._var["p1"] == np.array([[3, 4]]))
        assert np.all(bb._var["p2"] == np.array([[5, 6]]))
        assert bb.modes == {0, 1}
    def test_measure_arg(self):
        """Test measurement with argument converts"""
        # create a test program
        prog = Program(1)

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

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

        assert bb.operations[0] == expected
 def test_tdm_wrong_modes(self):
     """Test the correct error is raised when the tdm circuit registers don't match the device spec"""
     sq_r = 0.5643
     c = 2
     alpha = [np.pi / 4, 0] * c
     phi = [0, np.pi / 2] * c
     theta = [0, 0] + [np.pi / 2, np.pi / 2]
     prog = tdmprogram.TDMProgram(N=2)
     with prog.context(alpha, phi, theta) as (p, q):
         ops.Sgate(sq_r) | q[1]
         ops.BSgate(p[0]) | (q[0], q[1])  # The order should be (q[1], q[0])
         ops.Rgate(p[1]) | q[1]
         ops.MeasureHomodyne(p[2]) | q[0]
     eng = sf.Engine("gaussian")
     with pytest.raises(sf.program_utils.CircuitError,
                        match="due to incompatible mode ordering."):
         prog.compile(device=device, compiler="TD2")
    def test_shots_with_timebins_non_multiple_of_concurrent_modes(self):
        """Test that multiple shots work when having the number of timebins be
        a non-multiple of the number of concurrent modes"""
        theta = [0] * 3
        shots = 2

        prog = sf.TDMProgram(N=2)
        with prog.context(theta) as (p, q):
            ops.Xgate(50) | q[1]
            ops.MeasureHomodyne(p[0]) | q[0]
        eng = sf.Engine("gaussian")
        res = eng.run(prog, shots=shots)
        samples = res.samples

        expected = np.array([[[0, 50, 50]], [[50, 50, 50]]])

        assert np.allclose(samples, expected, atol=4)
 def test_tdm_wrong_parameter_second_argument(self):
     """Test the correct error is raised when the tdm circuit explicit parameters are not within the allowed ranges"""
     sq_r = 0.5643
     c = 2
     alpha = [np.pi / 4, 0] * c
     phi = [0, np.pi / 2] * c
     theta = [0, 0] + [np.pi / 2, np.pi / 2]
     prog = tdmprogram.TDMProgram(N=2)
     with prog.context(alpha, phi, theta) as (p, q):
         ops.Sgate(sq_r, 0.4) | q[
             1]  # Note that the Sgate has a second parameter that is non-zero
         ops.BSgate(p[0]) | (q[1], q[0])
         ops.Rgate(p[1]) | q[1]
         ops.MeasureHomodyne(p[2]) | q[0]
     eng = sf.Engine("gaussian")
     with pytest.raises(sf.program_utils.CircuitError,
                        match="due to incompatible parameter."):
         prog.compile(device=device, compiler="TD2")
def singleloop_program(r, alpha, phi, theta):
    """Single delay loop with program.

    Args:
        r (float): squeezing parameter
        alpha (Sequence[float]): beamsplitter angles
        phi (Sequence[float]): rotation angles
        theta (Sequence[float]): homodyne measurement angles
    Returns:
        (array): homodyne samples from the single loop simulation
    """
    prog = tdmprogram.TDMProgram(N=2)
    with prog.context(alpha, phi, theta) as (p, q):
        ops.Sgate(r, 0) | q[1]
        ops.BSgate(p[0]) | (q[1], q[0])
        ops.Rgate(p[1]) | q[1]
        ops.MeasureHomodyne(p[2]) | q[0]
    return prog
    def test_unroll(self):
        """Test unrolling program."""
        n = 2

        prog = sf.TDMProgram(N=2)
        with prog.context([0] * n, [0] * n, [0] * n) as (p, q):
            ops.Sgate(0.5643, 0) | q[1]
            ops.BSgate(p[0]) | (q[1], q[0])
            ops.Rgate(p[1]) | q[1]
            ops.MeasureHomodyne(p[2]) | q[0]

        prog_length = len(prog.circuit)
        assert prog_length == 4

        prog.unroll()
        assert len(prog.circuit) == n * prog_length

        prog.roll()
        assert len(prog.circuit) == prog_length
Beispiel #29
0
    def test_tdm_wrong_modes(self):
        """Test the correct error is raised when the tdm circuit registers don't match the device spec"""
        sq_r = 0.5643
        c = 2
        alpha = [np.pi / 4, 0] * c
        phi = [0, np.pi / 2] * c
        theta = [0.0, 0.0] + [np.pi / 2, np.pi / 2]
        prog = TDMProgram(N=2)
        with prog.context(alpha, phi, theta) as (p, q):
            ops.Sgate(sq_r) | q[1]
            ops.BSgate(p[0]) | (q[0], q[1])  # The order should be (q[1], q[0])
            ops.Rgate(p[1]) | q[1]
            ops.MeasureHomodyne(p[2]) | q[0]

        reset_compiler(self.target)

        with pytest.raises(CircuitError,
                           match=f"cannot be used with the compiler 'TDM"):
            prog.compile(device=self.device, compiler="TDM")
 def test_tdm_wrong_layout(self):
     """Test the correct error is raised when the tdm circuit gates don't match the device spec"""
     sq_r = 0.5643
     c = 2
     alpha = [np.pi / 4, 0] * c
     phi = [0, np.pi / 2] * c
     theta = [0, 0] + [np.pi / 2, np.pi / 2]
     prog = tdmprogram.TDMProgram(N=2)
     with prog.context(alpha, phi, theta) as (p, q):
         ops.Dgate(sq_r) | q[1]  # Here one should have an Sgate
         ops.BSgate(p[0]) | (q[1], q[0])
         ops.Rgate(p[1]) | q[1]
         ops.MeasureHomodyne(p[2]) | q[0]
     eng = sf.Engine("gaussian")
     with pytest.raises(
             sf.program_utils.CircuitError,
             match="The gates or the order of gates used in the Program",
     ):
         prog.compile(device=device, compiler="TD2")