Example #1
0
    def test_different_targets(self):
        """Test that different targets in layout and spec raises an error."""
        layout_different_target = inspect.cleandoc("""
            name mock
            version 1.0
            target banana

            S2gate({squeezing_amplitude_0}, 0.0) | [0, 1]
            MZgate({phase_0}, {phase_1}) | [0, 1]
            MeasureFock() | [0, 1]
            """)
        device_dict_different_target = {
            "target": "pawpaw",
            "layout": layout_different_target,
            "modes": 2,
            "compiler": ["Xcov"],
            "gate_parameters": {
                "squeezing_amplitude_0": [0, 1],
                "phase_0": [0, [0, 6.3]],
                "phase_1": [[0.5, 1.4]],
            },
        }
        with pytest.raises(
                ValueError,
                match=
                "Target in specification 'pawpaw' differs from the target in layout 'banana'.",
        ):
            Device(spec=device_dict_different_target)
Example #2
0
    def test_initialization(self):
        """Test that the device spec class initializes correctly."""
        device = Device(spec=device_spec, cert=device_certificate)

        assert device.target == "abc"
        assert device.layout == device_spec["layout"]
        assert device.modes == device_spec["modes"]
        assert device.compiler == device_spec["compiler"]
        assert device.certificate == device_certificate
def get_device():
    """Builds a dummy Borealis ``sf.Device`` from device spec and certificate

    Returns:
        obj: a dummy ``sf.Device`` object
    """
    device_spec = get_device_spec()
    device_cert = get_device_cert()
    return Device(spec=device_spec, cert=device_cert)
def test_make_squeezing_compatible(sq_input):
    """Tests whether squeezing values are correctly matched to the ones allowed
    by the hardware

    Args:
        sq_input (str): specifies the user input for the squeezing
    """

    # the allowed squeezing values
    sq_zero = 0
    sq_low = np.random.uniform(low=0.100, high=0.399)
    sq_medium = np.random.uniform(low=0.400, high=0.699)
    sq_high = np.random.uniform(low=0.700, high=1.000)

    modes = 300
    gate_args = get_random_gate_args(modes=modes)

    # replace Sgate parameter array with string if user input is string
    if sq_input != "user_array":
        gate_args["Sgate"] = sq_input

    device_spec = get_device_spec()
    device_cert = get_device_cert()

    # update the ``device_cert`` with the random values obtained above
    device_cert["squeezing_parameters_mean"]["low"] = sq_low
    device_cert["squeezing_parameters_mean"]["medium"] = sq_medium
    device_cert["squeezing_parameters_mean"]["high"] = sq_high

    device = Device(spec=device_spec, cert=device_cert)

    gate_args_out = make_squeezing_compatible(gate_args=gate_args,
                                              device=device)
    r_out = gate_args_out["Sgate"]

    # are the new squeezing values hardware-compatible?
    are_gate_args_legal(
        gate_args=gate_args_out,
        device=device,
        delays=None,
        assert_arg_length=False,
        assert_squeezing=True,
        assert_beamsplitters=False,
        assert_phase_gates=False,
    )

    # if a global squeezing level has been defined (instead of a squeezing
    # array), have the values been assigned correctly?
    if sq_input != "user_array":
        allowed_values_dict = {
            "zero": sq_zero,
            "low": sq_low,
            "medium": sq_medium,
            "high": sq_high,
        }
        assert r_out == [allowed_values_dict[sq_input]] * modes
Example #5
0
 def test_gate_parameters_none(self, params):
     """Test that any parameters a valid when gate_parameters is None"""
     device_dict = {
         "target": "abc",
         "layout": mock_layout,
         "modes": 2,
         "compiler": ["Xcov"],
         "gate_parameters": None,
     }
     Device(spec=device_dict).validate_parameters(**params)
Example #6
0
 def test_gate_parameters(self):
     """Test that gate_parameters outputs the correctly parsed parameters"""
     true_params = {
         "squeezing_amplitude_0":
         Ranges([0], [1], variable_name="squeezing_amplitude_0"),
         "phase_0":
         Ranges([0], [0, 6.3], variable_name="phase_0"),
         "phase_1":
         Ranges([0.5, 1.4], variable_name="phase_1"),
     }
     spec_params = Device(spec=device_spec).gate_parameters
     assert true_params == spec_params
Example #7
0
 def test_invalid_spec(self):
     """Test that error is raised when a specification with missing entries is supplied"""
     invalid_spec = {
         "target": "abc",
         "modes": 2,
         "compiler": ["Xcov"],
     }
     with pytest.raises(
             ValueError,
             match=
             r"missing the following keys: \['gate_parameters', 'layout'\]"
     ):
         Device(spec=invalid_spec)
def test_loop_phase_from_device():
    """Tests if loop phases are correctly obtained from ``sf.Device``"""
    device_spec = get_device_spec()
    device_cert = get_device_cert()

    loop_phases = np.random.uniform(low=0, high=2 * pi, size=3).tolist()

    device_cert["loop_phases"] = loop_phases

    device = Device(spec=device_spec, cert=device_cert)

    loop_phases_out = loop_phase_from_device(device=device)

    assert np.allclose(loop_phases, loop_phases_out)
Example #9
0
    def test_create_program(self):
        """Test that the program creation works"""
        circuit = [
            "S2gate(0, 0) | (q[0], q[1])",
            "MZgate(1.23, 0.5) | (q[0], q[1])",
            "MeasureFock | (q[0], q[1])",
        ]

        params = {"phase_0": 1.23}
        prog = Device(spec=device_spec).create_program(**params)

        assert prog.target is None
        assert prog.name == "mock"
        assert prog.circuit
        assert [str(cmd) for cmd in prog.circuit] == circuit
Example #10
0
    def device(self) -> Device:
        """The representation of the target device.

        Returns:
            .strawberryfields.Device: the target device representation

        Raises:
            requests.exceptions.RequestException: if there was an issue fetching
                the device specifications or the device certificate from the Xanadu Cloud
        """
        if self._device is None:
            device = xcc.Device(target=self.target, connection=self.connection)
            self._device = Device(spec=device.specification,
                                  cert=device.certificate)
        return self._device
Example #11
0
    def test_create_program_no_layout(self):
        """Test that the program creation raises an error if the device spec contains no layout"""

        params = {"phase_0": 1.23}
        device_dict_no_layout = {
            "target": "abc",
            "layout": None,
            "modes": 2,
            "compiler": ["Xcov"],
            "gate_parameters": {
                "squeezing_amplitude_0": [0, 1],
                "phase_0": [0, [0, 6.3]],
                "phase_1": [[0.5, 1.4]],
            },
        }
        with pytest.raises(ValueError, match="missing a circuit layout"):
            Device(spec=device_dict_no_layout).create_program(**params)
Example #12
0
 def device(self):
     return Device(spec=mock_device_dict)
Example #13
0
 def test_invalid_parameter_value(self, params):
     """Test that error is raised when an invalid parameter value is supplied"""
     with pytest.raises(ValueError, match="has invalid value"):
         Device(spec=device_spec).create_program(**params)
Example #14
0
 def test_invalid_parameters_value(self):
     """Test that invalid parameter values raise an error in validate_parameters"""
     with pytest.raises(ValueError, match=r"has invalid value"):
         Device(spec=device_spec).validate_parameters(phase_0=123)
Example #15
0
 def test_invalid_parameter(self):
     """Test that invalid parameter names raise an error in validate_parameters"""
     with pytest.raises(ValueError,
                        match=r"not a valid parameter for this device"):
         Device(spec=device_spec).validate_parameters(phase_42=0)
Example #16
0
        "phase_8": [0, [0, 6.283185307179586]],
        "phase_9": [0, [0, 6.283185307179586]],
        "phase_10": [0, [0, 6.283185307179586]],
        "phase_11": [0, [0, 6.283185307179586]],
        "final_phase_0": [0, [0, 6.283185307179586]],
        "final_phase_1": [0, [0, 6.283185307179586]],
        "final_phase_2": [0, [0, 6.283185307179586]],
        "final_phase_3": [0, [0, 6.283185307179586]],
        "final_phase_4": [0, [0, 6.283185307179586]],
        "final_phase_5": [0, [0, 6.283185307179586]],
        "final_phase_6": [0, [0, 6.283185307179586]],
        "final_phase_7": [0, [0, 6.283185307179586]],
    },
}

X8_device = Device(spec=X8_spec)

borealis_layout = inspect.cleandoc("""
    name template_borealis
    version 1.0
    target borealis (shots=1)
    type tdm (temporal_modes=259, copies=1)

    float array p0[1, 259] =
        {s}
    float array p1[1, 259] =
        {r0}
    float array p2[1, 259] =
        {bs0}
    float array p3[1, 259] =
        {loop1_phase}
Example #17
0
 def test_unknown_parameter(self, params):
     """Test that error is raised when an unknown parameter is supplied"""
     with pytest.raises(ValueError,
                        match="not a valid parameter for this device"):
         Device(spec=device_spec).create_program(**params)
def test_make_phases_compatible():
    """Tests if user-defined phases have been successfully changed such that
    they are hardware-compatible _after_ loop-offset compensation
    """

    modes = 216
    gate_args = get_random_gate_args(modes=modes)

    device_spec = get_device_spec()
    device_cert = get_device_cert()

    # the loop phases
    loop_phases = np.random.uniform(low=0, high=2 * pi, size=3).tolist()

    # update the ``device_cert`` with the random values obtained above
    device_cert["loop_phases"] = loop_phases

    device = Device(spec=device_spec, cert=device_cert)

    gate_args_out = make_phases_compatible(gate_args=gate_args, device=device)

    # the compatible phase-gate arguments
    phi_0_out = gate_args_out["loops"][0]["Rgate"]
    phi_1_out = gate_args_out["loops"][1]["Rgate"]
    phi_2_out = gate_args_out["loops"][2]["Rgate"]

    # the phase range supported by the modulators
    phi_min = device_spec["gate_parameters"]["r0"][0][0]
    phi_max = device_spec["gate_parameters"]["r0"][0][1]

    # obtain the actual phases after loop-offset compensation
    phi_0_actual, phi_1_actual, phi_2_actual = compensate_loop_offsets(
        phi_args=[phi_0_out, phi_1_out, phi_2_out],
        phi_loop=loop_phases,
        delays=[1, 6, 36],
        phi_range=[phi_min, phi_max],
    )

    # save actual (loop-offset compensated) phases to new ``gate_args`` dict
    gate_args_actual = copy.deepcopy(gate_args_out)
    gate_args_actual["loops"][0]["Rgate"] = phi_0_actual
    gate_args_actual["loops"][1]["Rgate"] = phi_1_actual
    gate_args_actual["loops"][2]["Rgate"] = phi_2_actual

    # photon-number statistics obtained by gate arguments that have been made
    # hardware compatible (without the presence of loop offsets)
    mean_n_wished, cov_n_wished = get_photon_number_moments(
        gate_args_out, device)

    # photon-number statistics obtained by loop-offset compensated phases in the
    # presence of loop offsets
    mean_n_actual, cov_n_actual = get_photon_number_moments(
        gate_args_actual, device, phi_loop=loop_phases)

    # are the offset-compensated phase-gate arguments hardware-compatible?
    are_gate_args_legal(
        gate_args=gate_args_out,
        device=device,
        delays=[1, 6, 36],
        assert_arg_length=False,
        assert_squeezing=False,
        assert_beamsplitters=False,
        assert_phase_gates=True,
    )

    # do we arrive at the same photon-number statistics after loop-offset
    # compensation?
    assert np.allclose(mean_n_wished, mean_n_actual)
    assert np.allclose(cov_n_wished, cov_n_actual)
Example #19
0
 def test_valid_parameters(self, params):
     """Test that valid parameters pass the validate_parameters validation"""
     Device(spec=device_spec).validate_parameters(**params)