Iterative measurements of ScheduleGettable with multiple acquisitions are not possible
Problem
MeasurementControl
fails when executing a schedule with more than one acquisition using the ScheduleGettable
. This happens only in iterative mode. However, doing the same measurement in batched mode with batch_size = 1 succeeds.
Possible Solution
I think the output-array evaluation of ScheduleGettable in iterative mode does not work as intended.
Minimal error reproducing example
import numpy as np
import os
from qcodes.instrument.parameter import ManualParameter
from quantify_core.data.handling import get_datadir, set_datadir
from quantify_core.measurement.control import MeasurementControl
from quantify_core.utilities import general
from quantify_scheduler.gettables import ScheduleGettable
from quantify_scheduler.instrument_coordinator.components.qblox import ClusterComponent
from quantify_scheduler.schedules.schedule import Schedule
from quantify_scheduler.device_under_test.quantum_device import QuantumDevice
from quantify_scheduler.device_under_test.transmon_element import BasicTransmonElement
from quantify_scheduler.instrument_coordinator import InstrumentCoordinator
from quantify_scheduler.operations.gate_library import Reset, Rxy, Measure
from quantify_scheduler.operations.pulse_library import IdlePulse
set_datadir("data")
hardware_config = {
"config_type": "quantify_scheduler.backends.qblox_backend.QbloxHardwareCompilationConfig",
"hardware_description": {
"cluster0": {
"instrument_type": "Cluster",
"modules": {
"1": {"instrument_type": "QRM"},
},
"sequence_to_file": False,
"ref": "internal",
# "ip": "10.1.60.150",
}
},
"hardware_options": {
"modulation_frequencies": {
"q0:mw-q0.01": {"lo_freq": 8e9},
"q0:res-q0.ro": {"lo_freq": 8e9},
},
},
"connectivity": {
"graph": [
["cluster0.module1.complex_output_0", "q0:res"],
["cluster0.module1.complex_input_0", "q0:res"],
]
},
}
meas_ctrl = MeasurementControl("meas_ctrl")
instrument_coordinator = InstrumentCoordinator(name="instrument_coordinator")
q0 = BasicTransmonElement("q0")
quantum_device = QuantumDevice(name="quantum_device")
quantum_device.add_element(q0)
quantum_device.instr_measurement_control(meas_ctrl.name)
quantum_device.instr_instrument_coordinator(instrument_coordinator.name)
quantum_device.hardware_config.set(hardware_config)
q0.clock_freqs.readout.set(0)
def two_measurement_sched(sweep_param, qubit: str, repetitions: int = 128) -> Schedule:
sched = Schedule("two_meas_sched", repetitions=repetitions)
sched.add(Reset(qubit))
sched.add(IdlePulse(duration=sweep_param))
sched.add(Measure(qubit, acq_index=0), label=f"meas_{0}")
sched.add(Measure(qubit, acq_index=1), label=f"meas_{1}")
return sched
from qblox_instruments import Cluster
from qblox_instruments.types import ClusterType
cluster = Cluster("cluster0", dummy_cfg={1: ClusterType.CLUSTER_QRM_RF})
ic_cluster = ClusterComponent(cluster)
instrument_coordinator.add_component(ic_cluster)
spec_param = ManualParameter("sweep_param", initial_value=0, unit="s")
schedule_kwargs = {
"sweep_param": spec_param,
"qubit": "q0",
}
spec_gettable = ScheduleGettable(
quantum_device=quantum_device,
schedule_function=two_measurement_sched,
schedule_kwargs=schedule_kwargs,
real_imag=False,
)
params = np.arange(1e-6, 2e-6, 0.1e-6)
meas_ctrl.settables(spec_param)
meas_ctrl.setpoints(params)
meas_ctrl.gettables(spec_gettable)
label = f"Example measurement {quantum_device.name}"
dset = meas_ctrl.run(label)
raises
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[1], line 95
93 meas_ctrl.gettables(spec_gettable)
94 label = f"Example measurement {quantum_device.name}"
---> 95 dset = meas_ctrl.run(label)
96 # spec_gettable.get()
File ~/miniforge3/envs/dev/lib/python3.12/site-packages/quantify_core/measurement/control.py:554, in MeasurementControl.run(self, name, soft_avg, lazy_set, save_data)
552 if self.verbose():
553 print("Starting iterative measurement...")
--> 554 self._run_iterative(lazy_set)
555 except KeyboardInterrupt:
556 print("\nInterrupt signaled, exiting gracefully...")
File ~/miniforge3/envs/dev/lib/python3.12/site-packages/quantify_core/measurement/control.py:669, in MeasurementControl._run_iterative(self, lazy_set)
667 self._dataarray_cache = {}
668 for idx in range(len(self._setpoints[0])):
--> 669 self._iterative_set_and_get(
670 [spt[idx] for spt in self._setpoints],
671 self._curr_setpoint_idx(),
672 lazy_set,
673 )
674 self._nr_acquired_values += 1
675 self._update()
File ~/miniforge3/envs/dev/lib/python3.12/site-packages/quantify_core/measurement/control.py:803, in MeasurementControl._iterative_set_and_get(self, setpoints, idx, lazy_set)
800 batched = gpar.batched
801 real_imag = gpar.real_imag
--> 803 new_data = self._process_acquired_data(
804 new_data_raw, batched, real_imag
805 ) # can return (N, M)
806 else:
807 new_data = new_data_raw
File ~/miniforge3/envs/dev/lib/python3.12/site-packages/quantify_core/measurement/control.py:433, in MeasurementControl._process_acquired_data(cls, acquired_data, batched, real_imag)
430 vals = acq_channel_data.to_numpy().reshape((-1,))
432 if not batched and len(vals) != 1:
--> 433 raise ValueError(
434 f"For iterative mode, only one value is expected for each "
435 f"acquisition channel. Got {len(vals)} values for acquisition "
436 f"channel '{acq_channel}' instead."
437 )
438 return_data.extend(cls._reshape_data(acq_protocol, vals, real_imag))
440 logger.debug(f"Returning {len(return_data)} values.")
ValueError: For iterative mode, only one value is expected for each acquisition channel. Got 2 values for acquisition channel '0' instead.
Edited by Robert Sokolewicz