Measurements supported in scheduler
Last update: 2021-07-27
Summary 2021-07-26
This is a summary of the related issues and problems to resolve. Currently based on discussions between @caenrigen and myself.
Supporting measurements
Currently, the thinking of how to use quantify scheduler is described by the experiment flow !161 (merged) . A central concept here is the ScheduleGettable. This is intended to be a generic gettable. In the current implementation, there is only the ScheduleVectorAcquisitionGettable (!109 (closed) to be superseded by !161 (merged)) .
problems preventing us from just implementing it
There are a few problems with the ScheduleVectorAcquisitionGettable:
- hardcoded acquisition protocol.
- uses only a single bin.
- averages are an argument to the gettable.
This results in different issues/problems to resolve:
-
how to determine the acquisition protocol -> add multiple
Measurementoperations on the gate level, coupled to different acquisition protocols + add one genericMeasurementoperation at the quantum circuit layer. The circuit-> device compilation will then fill in the missing information. Issue to be spawned. -
how to determine the bins/acq_channels. The problem here is that the gettable needs to know this information before the schedule itself is generated. This means that a solution to address this either needs to find a way to fix these values beforehand, or we need to adapt the measurement control to accept "fancier" return types of a gettable. Note that if we go for this second solution this problem also propagates to the instrument coordinator, which needs to have a way to determine what registers to read out/what modes to configure before executing the schedule. To address the second issue, we will likely want to add some metadata to the schedule so that the IC can easily determine how to configure the hardware and what to read back and return when retrieving acquisition. This information can be added during the compilation step. The changes to measurement control will possibly require some minor changes to the data format if we want to make this future compatible (gettable returns array+metadata, we should make this xarrays for now enforce same length).
-
hardware averages are currently an argument to the Gettable. In reality, these should also be retrieved from the schedule (metadata). It makes sense for this to be a configurable parameter used in the device to hardware backend compilation step, i.e., be part of the configuration files and therefore managed by the QuantumDevice object (also not implemented yet).
Next steps
Here we tried to write down what the problems are and some first thoughts on the solutions. @caenrigen will pick this up and produce a design.
Meeting notes from session on 2021-07-27
Present: Adriaan, Damien, Jordy, Jules, Victor
Topic: Designing the experiment flow (triggered by missing support for binning) Meeting overview:
- Victor showed a summary of what the ideal desired high-level interfaces of running an experiment should be.
- Some discussions happened while going through Victor's pseudo-code. Some decisions where made as a results of the discussion.
- Whiteboard session on the experiment data type and shape allowed us to converge on what we want it to look like in terms of how the data is indexed.
Desired high-level interfaces as a notebook (presented by Victor):
High level questions:
-
How to specify the acquisition protocol in schedules at the quantum gate level? -
How are the bins and acq channels specified in the schedule at the quantum gate level? -
What does the ScheduleGettablereturn looks like? -
What does the return of the InstrumentCoordinator/InstrumentCoordinatorComponentlooks like, i.e., the interface expected by theScheduleGettable? -
What the data looks like when stored in the quantify dataset?
Measure operation at gate-level
class Measure(Operation):
"""A projective measurement in the Z-basis."""
def __init__(
self,
*qubits: str,
acq_index: Union[Tuple[int, ...], int] = None,
acq_protocol: acquisition_library.Protocols = acquisition_library.Protocols.AUTO
# acq_channel is not possible to be passed to the abstract measurement, makes no sense at gate-level
):
pass
- NB: The values indexed by a specific (
acq_index,acq_channel) pair can be complex (e.g. I,Q data)- We are not sure what is the support status of this in quantify dataset, xarray and the
hdf5backend we use.
- We are not sure what is the support status of this in quantify dataset, xarray and the
Schedule generating function
A relatively simple schedule but uses at least two qubits to force us to design in a general enough way.
def t1_2q_sched(
times: Union[np.ndarray, float],
q0: str,
q1: str,
repetitions: int = 1,
) -> Schedule:
"""
Generate a schedule for performing a :math:`T_1` experiment to measure the qubit
relaxation time simulatneously for two qubits.
"""
# ensure times is an iterable when passing floats.
times = np.asarray(times)
times = times.reshape(times.shape or (1,))
schedule = Schedule("T1", repetitions)
for i, tau in enumerate(times):
schedule.add(Reset(q0, q1), label=f"Reset {i}")
schedule.add(X(q0), label=f"pi {i}")
schedule.add(X(q1), ref_pt="start", label=f"pi {i}")
schedule.add(
Measure(q0, q1, acq_index=i), # or (2 * i, 2 * i + 1) ???
ref_pt="start",
rel_time=tau,
label=f"Measurement {i}"
)
return schedule
Measure operation details
Abstract Measurement:
Compilation steps have to resolve the acquisition protocol based on the configuration file(s), which have to be generated by the QuantumDevice/DeviceElements where the user manages the qcodes Parameters.
Measure(
"q0",
"q1",
acq_index=i, # ??? (2 * i, 2 * i + 1)
acq_protocol=acquisition_library.Procotols.AUTO # not necessary to specify
)
Measurement with predetermined acquisition protocol:
Measure(
"q0",
"q1",
acq_index=i, # ??? (2 * i, 2 * i + 1)
acq_protocol=acquisition_library.Procotols.SSB_INTEGRATION_COMPLEX # overrides acquisiton protocol choice
)
Note that no other information is to be specified, all the required information for the specific acqusition protocol is to be added by the compilation steps.
Running the experiments
from qcodes.instrument.parameter import ManualParameter
tau = ManualParameter("tau", label=r"Delay time", initial_value=0, unit="s")
repetitions = ManualParameter("repetitions", label=r"Repetitions", initial_value=1024, unit="")
# Not imeplemented yet, but we can use the config files to get started
device = QuantumDevice(name="quantum_sample") # contains references to e.g. `TransmonElement`s
ScheduleGettable
sched_kwargs = dict(
times=tau, # Parameter
q0="q0",
q1="q1",
repetitions=repetitions # Parameter, could be `device.repetitions`
)
t1_gettable = ScheduleGettable( # Not implemented yet
device=device, # know the name of the IntrumentCoordinator and can find it (.find_instrument)
schedule_function=t1_q2_schedule,
schedule_kwargs=sched_kwargs
# it is intentional that we do not have a lot of arguments in here
)
VERY IMPORTANT
In general, at this point the gettable will not know yet what it will be returning to the measurement control because the compilation had not been executed yet (which is triggered by the MeasurementControl)!
assert t1_gettable.unit is None # details to be figured out, e.g. is the attribute not present at all or does it have a `None` value
assert t1_gettable.label is None
MeasurementControl
from quantify_core.measurement import MeasurementControl
meas_ctrl = MeasurementControl("meas_ctrl")
times = np.linspace(0, 60e-6, 25)
meas_ctrl.settables(tau)
meas_ctrl.setpoints(times)
meas_ctrl.gettables(t1_gettable)
label = f"T1 experiment {qubit_name}"
dataset = meas_ctrl.run(label)
Run analysis
from quantify_core.analysis.t1_analysis import T1Analysis
analysis = T1Analysis(label=label).run()
Ideal high-level user-interface ends here.
ScheduleGettable return type/shape ??? (still Victor's pre-meeting notebook)
- Datapoints
- Single point, e.g.,
1.2 - 1D array,
[0.1, 0.5, 1.0, ...] - n * 1D array, equivalent to multiple gettable (or single getable returning several columns)
[[0.1, 0.5, ...], [0.2, 0.7, ...], [0.3, 0.9, ...]] - n * 1D * 3D/4D
<---This is the pretty complicated case
- Single point, e.g.,
- Metadata/attributes per
acq_channel/acq_index-> Used to figure out how to store the data in the dataset- label for each
acq_channel - units for each
acq_channel
- label for each
Potential candicate: xarray.DataArray (or even xarray.Dataset)
- Is a datapoints-container with
attrsdict. - Might require enforcing conventions on top of
xarray(it is not fully custom data structure, similarly to the issue with dimensions and coordinates that we have in quantify dataset).
White board session
Data type/shape, tables that we draw on the whiteboard:
| NB please read the information in all cells! |
(settable) | q0, NB: ideally we want a single complex-valued column |
q0 (not necessarily a qubit, but serves to make it tangible) |
q1 | q1 |
|---|---|---|---|---|---|
| The columns are addressed by acq_channel
|
x0 |
y0 |
y1 |
y2 |
y3 |
| attr["name"] | "tau" |
"q0_I" |
"q0_Q" |
"q1_I" |
"q1_Q" |
| attr["unit"] | "s" |
"V" |
"V" |
"V" |
"V" |
| The rows are addressed by the acq_index
|
0 | ||||
| 4e-6 | |||||
| 8e-6 | a potentially multi-dimensional data entry that will require an object such as xarray.DataArray orxarray.Dataset |
||||
| 20e-6 | In current implementation we support only the ability to store averaged IQ values (e.g. each cell is the average of 1024 single shots) |
||||
| 50e-6 | |||||
| 100e-6 | |||||
| ... |
(table generated with https://www.tablesgenerator.com/markdown_tables)
InstrumentCoordinator <-> ScheduleGettable interface
To be defined and iterated upon.
Post meeting notes (from 2021-07-27 meeting)
Notes author: Victor
Decisions
- The
ScheduleGettablewill have defined attributes at the start of the measurement but the values of these attributes (required to build the dataset) might be available only after getting measured data from theScheduleGettable. - We have a unique
acq_indexonly peracq_channel, i.e. addressing a datapoint requires an(acq_channel, acq_index)pair. -
acq_channelsare intergers and we do not enforce any rules on the numbering and order. - The binning mode is a global setting per schedule so that we keep it simple for now.
- What are the "dimensions" of the data in a supported experiment: 4-dimensional data indexed as follows
[acq_index, acq_channel, repetition_index, trace_sample]. Note that some of the dimensions can be "collapsed" by an aquisition protocol to 3-dimensional or 2-dimensional data.- A relatively simple case is
[acq_index, acq_channel]where we have only one singleacq_channel(e.g. T1 experiment on one single qubit with "collapsed"trace_indexinto a single (I,Q) complex value and "collapsed"repetition_indexby hardware averages).
- A relatively simple case is
- We are inclined to use
xarrayobejcts to return data from theSchedulerGettable. - Calibration points will be regular datapoints and we flag them somehow as being special calibration points with some attribute on the respective
xarray.DataArrayindicating theacq_indexfor those (the setpoints might have to beNaNs).
Issues (It only seems a short list)
-
Can a complex-valued xarray.DataArraybe stored and retrieved back from the quantify dataset?- A: Yes, we have solved this problem already in quantify-core!114 (merged)
- The missing parts are:
-
data.handling.initialize_datasetneeds to fill the newxarray.DataArrays with the correctdtypewhen creating the dataset (this function is called by MC and thedtypewill have to passed around similarly how the"unit"is). - The plotting monitor is required to automatically convert the dataset into a dataset with float columns only (preferably allow to plot either real+imaginary or magnitude+phase for each complex column).
-
- Are
xarrayobjects enough to solve the interfaces for the dataflow? - How does the specific implementation looks like? --> We have to prototype, iterate and converge
Ideas for prototyping:
- Use a staircase schedule to test everything. The following cases seem to be within the scope of current 2-3 week "sprint":
- Simple case: One output connected to the input.
- (Victor proposes) A bit less simple: One complex output connected to the input.
- (Victor proposes) More advanced case: Two complex inputs connected to two complex outputs.
Concerns to address later:
There are many things that popped up during the meeting and there are certainly many more. But we need to keep a limited scope given the timelines.
- How to override any (or several) particular arguemnts of a pulse-level operation from a gate-level operation. In other words, how do you generalize
acq_protocolargument that we plan to have for theMeasureoperation, for any operation (e.g. X180 in a Rabi). - Acquisition protocols at the momento are not able to deal with/return the results of several acquisition protocols, e.g., Averaged value on I-Q plane and the binary
0/1thresholded value. - How we we store the data from the line above?
- Dealing with several columns in the measurement/dataset that do not have the same length. E.g. q0 measured 10 times and q2 measured 20 times.