Commit 5e7f45ac authored by Edgar Reehuis's avatar Edgar Reehuis
Browse files

Merge branch 'MarkerPulse-Qblox-backend' into 'main'

Marker pulse qblox backend

See merge request !628
parents cdf1f4ef 1b25a7b3
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
- Gettables - When `ScheduleGettable.get()` is called and the associated `InstrumentCoordinator` returns nothing (for example, if the hardware configuration was never set), this will no longer raise a KeyError from the xarray module. Instead, a more helpful error is raised before the data processing (!671).
- Qblox backend - Raise RuntimeWarning instead of NotImplementedError upon using `reference_magnitude` parameter (introduced in !652) (!684)
- Qblox backend - Compilation uses `math.isclose` instead of `numpy.isclose` in certain cases to improve compile time (!682)
- Qblox backend - Add `MarkerPulse` to pulse library, and implement Qblox backend compilation for this pulse (!628)

## 0.13.0 (2023-05-05)

+25 −0
Original line number Diff line number Diff line
@@ -202,6 +202,31 @@ emphasize-lines: 4,12,20
},
```

### Digital mode

The markers can be controlled by defining a digital I/O, and adding a `MarkerPulse` on this I/O.
A digital I/O is defined by adding a `"digital_output_n"` to the module configuration. `n` is the number of the digital output port.
For a digital I/O only a port is required, no clocks or other parameters are needed.

```{code-block} python
"qcm0": {
    "instrument_type": "QCM",
    "ref": "internal",
    "digital_output_0": {
        "portclock_configs": [
            {
                "port": "q0:switch",
            },
        ],   
    },
},
```

The `MarkerPulse` is defined by adding a `MarkerPulse` to the sequence in question. It takes the same parameters as any other pulse.
```{code-block} python
schedule.add(MarkerPulse(duration=52e-9, port="q0:switch"))
```

### Marker configuration

The markers can be configured by adding a `"marker_debug_mode_enable"` key to I/O configurations. If the value is set to True, the operations defined for this I/O will be accompanied by a 4 ns trigger pulse on the marker located next to the I/O port.
+3 −1
Original line number Diff line number Diff line
@@ -227,9 +227,11 @@ def set_pulse_and_acquisition_clock(
        operation_info = operation["pulse_info"] + operation["acquisition_info"]
        clocks_used = set([info["clock"] for info in operation_info])
        for clock in clocks_used:
            # In digital IO's clocks are non-existant, so we skip them.
            if clock == "digital":
                continue
            if clock in verified_clocks:
                continue

            # raises ValueError if no clock found;
            # enters if condition if clock only in device config
            if not _valid_clock_in_schedule(clock, device_cfg, schedule, operation):
+18 −10
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ from quantify_core.data.handling import gen_tuid, get_datadir
from quantify_scheduler.backends.qblox import (
    constants,
    driver_version_check,
    enums,
    helpers,
    instrument_compilers,
    q1asm_instructions,
@@ -308,6 +309,7 @@ class Sequencer:
        static_hw_properties: StaticHardwareProperties,
        connected_outputs: Optional[Union[Tuple[int], Tuple[int, int]]],
        connected_inputs: Optional[Union[Tuple[int], Tuple[int, int]]],
        io_mode: enums.IoMode,
        seq_settings: Dict[str, Any],
        latency_corrections: Dict[str, float],
        lo_name: Optional[str] = None,
@@ -387,6 +389,8 @@ class Sequencer:
            connected_inputs=connected_inputs,
        )

        self._io_mode = io_mode

        self.qasm_hook_func: Optional[Callable] = seq_settings.get(
            "qasm_hook_func", None
        )
@@ -425,17 +429,15 @@ class Sequencer:
        return self._settings.connected_inputs

    @property
    def io_mode(self) -> Literal["complex", "real", "imag"]:
    def io_mode(self) -> enums.IoMode:
        """
        Specifies whether the sequencer is using only path0 (real), path1 (imag) or
        both (complex).
        Return :class:`~.enums.IoMode` used by this sequencer.

        If real or imag, the sequencer is restricted to only using real valued data.
        If complex, the sequencer may also use complex data.
        If digital, the sequencer is restricted to only producing MarkerPulses.
        """
        if self._settings.connected_outputs is not None:
            return helpers.io_mode_from_ios(self._settings.connected_outputs)
        else:
            return helpers.io_mode_from_ios(self._settings.connected_inputs)
        return self._io_mode

    @property
    def portclock(self) -> Tuple[str, str]:
@@ -812,7 +814,6 @@ class Sequencer:

        qasm = QASMProgram(self.static_hw_properties, self.register_manager)
        qasm.set_marker(self.default_marker)
        qasm.emit(q1asm_instructions.UPDATE_PARAMETERS, constants.GRID_TIME)
        # program header
        qasm.emit(q1asm_instructions.WAIT_SYNC, constants.GRID_TIME)
        qasm.emit(q1asm_instructions.UPDATE_PARAMETERS, constants.GRID_TIME)
@@ -1303,8 +1304,9 @@ class QbloxBaseModule(ControlDeviceCompiler, ABC):
                portclock = (target["port"], target["clock"])

                if portclock in self._portclocks_with_data:
                    connected_outputs = helpers.output_name_to_outputs(io)
                    connected_inputs = helpers.input_name_to_inputs(io)
                    io_mode, connected_outputs, connected_inputs = helpers.get_io_info(
                        io
                    )
                    seq_idx = len(sequencers)
                    new_seq = Sequencer(
                        parent=self,
@@ -1313,6 +1315,7 @@ class QbloxBaseModule(ControlDeviceCompiler, ABC):
                        static_hw_properties=self.static_hw_properties,
                        connected_outputs=connected_outputs,
                        connected_inputs=connected_inputs,
                        io_mode=io_mode,
                        seq_settings=target,
                        latency_corrections=self.latency_corrections,
                        lo_name=lo_name,
@@ -1399,6 +1402,11 @@ class QbloxBaseModule(ControlDeviceCompiler, ABC):
                        seq.pulses = []

                    for pulse_strategy in strategies_for_pulses:
                        if seq.io_mode == enums.IoMode.DIGITAL:
                            # Digital mode always has one output.
                            pulse_strategy.operation_info.data[
                                "output"
                            ] = seq.connected_outputs[0]
                        seq.pulses.append(pulse_strategy)

        acq_data_list: List[OpInfo]
+13 −0
Original line number Diff line number Diff line
# Repository: https://gitlab.com/quantify-os/quantify-scheduler
# Licensed according to the LICENCE file on the main branch
"""Enums used by Qblox backend."""
from enum import Enum


class IoMode(str, Enum):
    """Enum for the IO mode of the Sequencer."""

    COMPLEX = "complex"
    REAL = "real"
    IMAG = "imag"
    DIGITAL = "digital"
Loading