Commit 40a95f8b authored by Edgar Reehuis's avatar Edgar Reehuis
Browse files

Qblox backend - Extend `to_grid_time` to check for integer multiple of 1ns

parent 0ab10b7e
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
- Qblox backend - Fix playback on both outputs of a QCM-RF (!742)
- Waveforms - Fix such that `interpolated_complex_waveform` does not extrapolate except for rounding errors. (!710)
- Docs - Fix broken list bullets on Read-the-Docs by enforcing `sphinx-rtd-theme>=1.2.2` (!743)
- Qblox backend - `to_grid_time` helper function extended to alert user in case of time value not an integer multiple of nanosecond (tolerance 1 picosecond) (!751)

## 0.15.0 (2023-07-13)

+25 −12
Original line number Diff line number Diff line
@@ -364,13 +364,21 @@ def to_grid_time(time: float, grid_time_ns: int = constants.GRID_TIME) -> int:
    :
        The integer valued nanosecond time.
    """
    time_ns = int(round(time * 1e9))
    if time_ns % grid_time_ns != 0:
    time_ns_float = time * 1e9
    time_ns = int(round(time_ns_float))

    tolerance = 1e-3
    if (
        not math.isclose(time_ns_float, time_ns, abs_tol=tolerance, rel_tol=0)
        or time_ns % grid_time_ns != 0
    ):
        raise ValueError(
            f"Attempting to use a time interval of {time_ns} ns. "
            f"Attempting to use a time value of {time_ns_float} ns."
            f" Please ensure that the durations of operations and wait times between"
            f" operations are multiples of {grid_time_ns} ns."
            f" operations are multiples of {grid_time_ns} ns"
            f" (tolerance: {tolerance:.0e} ns)."
        )

    return time_ns


@@ -393,8 +401,18 @@ def is_multiple_of_grid_time(
    :
        If it the time is a multiple of the grid time.
    """
    time_ns = int(round(time * 1e9))
    return time_ns % grid_time_ns == 0

    try:
        _ = to_grid_time(time=time, grid_time_ns=grid_time_ns)
    except ValueError:
        return False

    return True


def is_within_grid_time(a, b):
    tolerance = 0.5e-9 * constants.GRID_TIME
    return math.isclose(a, b, abs_tol=tolerance, rel_tol=0)


def get_nco_phase_arguments(phase_deg: float) -> int:
@@ -1434,8 +1452,3 @@ def generate_hardware_config(compilation_config: CompilationConfig):
                    )

    return hardware_config


def is_within_grid_time(a, b):
    tolerance = 0.5e-9 * constants.GRID_TIME
    return math.isclose(a, b, abs_tol=tolerance, rel_tol=0)
+37 −5
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ from quantify_scheduler.backends.qblox.helpers import (
    generate_port_clock_to_device_map,
    generate_uuid_from_wf_data,
    generate_waveform_data,
    is_multiple_of_grid_time,
    is_within_grid_time,
    to_grid_time,
)
@@ -1350,11 +1351,42 @@ def test_expand_from_normalised_range():
        )


def test_to_grid_time():
    time_ns = to_grid_time(8e-9)
    assert time_ns == 8
    with pytest.raises(ValueError):
        to_grid_time(7e-9)
@pytest.mark.parametrize(
    "time, expected_time_ns",
    [(4e-9, 4), (8.001e-9, 8), (4.0008e-9, 4)],
)
def test_to_grid_time(time, expected_time_ns):
    assert to_grid_time(time) == expected_time_ns


@pytest.mark.parametrize(
    "time",
    [7e-9, 10e-9, 8.01e-9, 4.009e-9],
)
def test_to_grid_time_raises(time):
    with pytest.raises(ValueError) as error:
        to_grid_time(time)

    assert (
        "Please ensure that the durations of operations"
        " and wait times between operations are multiples of 4 ns" in str(error)
    )


@pytest.mark.parametrize(
    "time, expected",
    [
        (5e-9, False),
        (11e-9, False),
        (8.002e-9, False),
        (4.009e-9, False),
        (12e-9, True),
        (8.001e-9, True),
        (4.0008e-9, True),
    ],
)
def test_is_multiple_of_grid_time(time, expected):
    assert is_multiple_of_grid_time(time) is expected


def test_is_within_grid_time_even_if_floating_point_error():