qibolab.instruments.zhinst package#
Submodules#
qibolab.instruments.zhinst.executor module#
Executing pulse sequences on a Zurich Instruments devices.
- qibolab.instruments.zhinst.executor.COMPILER_SETTINGS = {'HDAWG_MIN_PLAYWAVE_HINT': 64, 'HDAWG_MIN_PLAYZERO_HINT': 64, 'SHFSG_MIN_PLAYWAVE_HINT': 32, 'SHFSG_MIN_PLAYZERO_HINT': 32}#
Translating to Zurich ExecutionParameters.
- class qibolab.instruments.zhinst.executor.ZhPort(name: tuple[str, str], offset: float = 0.0, power_range: int = 0)[source]#
Bases:
Port
- class qibolab.instruments.zhinst.executor.SubSequence(measurements: list[tuple[str, qibolab.instruments.zhinst.pulse.ZhPulse]], control_sequence: dict[str, list[qibolab.instruments.zhinst.pulse.ZhPulse]])[source]#
Bases:
object
A subsequence is a slice (in time) of a sequence that contains at most one measurement per qubit.
When the driver is asked to execute a sequence, it will first split it into sub-sequences. This is needed so that we can create a separate laboneq section for each measurement (multiple measurements per section are not allowed). When splitting a sequence, it is assumed that 1. a measurement operation can be parallel (in time) to another measurement operation (i.e. measuring multiple qubits simultaneously), but other channels (e.g. drive) do not contain any pulses parallel to measurements, 2. ith measurement on some channel is in the same subsequence as the ith measurement (if any) on another measurement channel, 3. all measurements in one subsequence happen at the same time.
- measurements: list[tuple[str, qibolab.instruments.zhinst.pulse.ZhPulse]]#
- control_sequence: dict[str, list[qibolab.instruments.zhinst.pulse.ZhPulse]]#
- class qibolab.instruments.zhinst.executor.Zurich(name, device_setup, time_of_flight=0.0, smearing=0.0)[source]#
Bases:
Controller
Driver for a collection of ZI instruments that are automatically synchronized via ZSync protocol.
- signal_map#
Signals to lines mapping
- calibration#
Zurich calibration object)
- session#
Zurich device parameters for connection
- smearing#
Parameters read from the runcard not part of ExecutionParameters
- results#
Zurich experiment definitions
- acquisition_type#
To store if the AcquisitionType.SPECTROSCOPY needs to be enabled by parsing the sequence
- sequence#
Zurich pulse sequence
- sub_sequences: list[SubSequence]#
Sub sequences between each measurement
- property sampling_rate#
Sampling rate of control electronics in giga samples per second (GSps).
- calibration_step(qubits, couplers, options)[source]#
Zurich general pre experiment calibration definitions.
Change to get frequencies from sequence
- register_readout_line(qubit, intermediate_frequency, options)[source]#
Registers qubit measure and acquire lines to calibration and signal map.
Note
To allow debugging with and oscilloscope, just set the following:
self.calibration[f"/logical_signal_groups/q{q}/measure_line"] = lo.SignalCalibration( ..., local_oscillator=lo.Oscillator( ... frequency=0.0, ), ..., port_mode=lo.PortMode.LF, ..., )
- register_drive_line(qubit, intermediate_frequency)[source]#
Registers qubit drive line to calibration and signal map.
- register_couplerflux_line(coupler)[source]#
Registers qubit flux line to calibration and signal map.
- run_exp()[source]#
Compilation settings, compilation step, execution step and data retrival - Save a experiment Python object: self.experiment.save(“saved_exp”) - Save a experiment compiled experiment (): self.exp.save(“saved_exp”) # saving compiled experiment
- static frequency_from_pulses(qubits, sequence)[source]#
Gets the frequencies from the pulses to the qubits.
- create_sub_sequences(qubits: list[qibolab.qubits.Qubit]) tuple[list[qibolab.instruments.zhinst.executor.SubSequence], set[str]] [source]#
Create subsequences based on locations of measurements.
Returns list of subsequences and a set of channel names that were not split
- experiment_flow(qubits: dict[str, qibolab.qubits.Qubit], couplers: dict[str, qibolab.couplers.Coupler], sequence: PulseSequence, options: ExecutionParameters)[source]#
Create the experiment object for the devices, following the steps separated one on each method:
Translation, Calibration, Experiment Definition.
- sequence_zh(sequence: PulseSequence, qubits: dict[str, qibolab.qubits.Qubit]) dict[str, list[qibolab.instruments.zhinst.pulse.ZhPulse]] [source]#
Convert Qibo sequence to a sequence where all pulses are replaced with ZhPulse instances.
The resulting object is a dictionary mapping from channel name to corresponding sequence of ZhPulse instances
- set_calibration_for_rt_sweep(exp: Experiment) None [source]#
Set laboneq calibration of parameters that are to be swept in real- time.
- set_instrument_nodes_for_nt_sweep(exp: Experiment, sweeper: Sweeper) None [source]#
In some cases there is no straightforward way to sweep a parameter.
In these cases we achieve sweeping by directly manipulating the instrument nodes
- get_channel_node_path(channel_name: str) str [source]#
Return the path of the instrument node corresponding to the given channel.
- select_exp(exp, qubits, exp_options)[source]#
Build Zurich Experiment selecting the relevant sections.
- static play_sweep(exp, channel_name, pulse)[source]#
Play Zurich pulse when a single sweeper is involved.
- sweep(qubits, couplers, sequence: PulseSequence, options, *sweepers)[source]#
Play pulse and sweepers sequence.
qibolab.instruments.zhinst.pulse module#
Wrapper for qibolab and laboneq pulses and sweeps.
- qibolab.instruments.zhinst.pulse.select_pulse(pulse: Pulse)[source]#
Return laboneq pulse object corresponding to the given qibolab pulse.
- class qibolab.instruments.zhinst.pulse.ZhPulse(pulse)[source]#
Bases:
object
Wrapper data type that holds a qibolab pulse, the corresponding laboneq pulse object, and any sweeps associated with this pulse.
- zhpulse#
Laboneq pulse.
- zhsweepers: list[tuple[qibolab.sweeper.Parameter, laboneq.dsl.parameter.SweepParameter]]#
Parameters to be swept, along with their laboneq sweep parameter definitions.
qibolab.instruments.zhinst.sweep module#
Pre-execution processing of sweeps.
- qibolab.instruments.zhinst.sweep.classify_sweepers(sweepers: Iterable[Sweeper]) tuple[list[qibolab.sweeper.Sweeper], list[qibolab.sweeper.Sweeper]] [source]#
Divide sweepers into two lists: 1. sweeps that can be done in the laboneq near-time sweep loop, 2. sweeps that can be done in real-time (i.e. on hardware)
- class qibolab.instruments.zhinst.sweep.ProcessedSweeps(sweepers: Iterable[Sweeper], qubits: dict[str, qibolab.qubits.Qubit])[source]#
Bases:
object
Data type that centralizes and allows extracting information about given sweeps.
In laboneq, sweeps are represented with the help of SweepParameter instances. When adding pulses to a laboneq experiment, some properties can be set to be an instance of SweepParameter instead of a fixed numeric value. In case of channel property sweeps, either the relevant calibration property or the instrument node directly can be set ot a SweepParameter instance. Parts of the laboneq experiment that define the sweep loops refer to SweepParameter instances as well. These should be linkable to instances that are either set to a pulse property, a channel calibration or instrument node. To achieve this, we use the exact same SweepParameter instance in both places. This class takes care of creating these SweepParameter instances and giving access to them in a consistent way (i.e. whenever they need to be the same instance they will be the same instance). When constructing sweep loops you may ask from this class to provide all the SweepParameter instances related to a given qibolab Sweeper (parallel sweeps). Later, when adding pulses or setting channel properties, you may ask from this class to provide all SweepParameter instances related to a given pulse or channel, and you will get parameters that are linkable to the ones in the sweep loop definition
- sweeps_for_pulse(pulse: Pulse) list[tuple[qibolab.sweeper.Parameter, laboneq.dsl.parameter.SweepParameter]] [source]#
- sweeps_for_channel(ch: str) list[tuple[qibolab.sweeper.Parameter, laboneq.dsl.parameter.SweepParameter]] [source]#
qibolab.instruments.zhinst.util module#
Utility methods.
- qibolab.instruments.zhinst.util.measure_channel_name(qubit: Qubit) str [source]#
Construct and return a name for qubit’s measure channel.
FIXME: We cannot use channel name directly, because currently channels are named after wires, and due to multiplexed readout multiple qubits have the same channel name for their readout. Should be fixed once channels are refactored.
- qibolab.instruments.zhinst.util.acquire_channel_name(qubit: Qubit) str [source]#
Construct and return a name for qubit’s acquire channel.
FIXME: We cannot use acquire channel name, because qibolab does not have a concept of acquire channel. This function shall be removed once all channel refactoring is done.