qibolab.instruments.qblox package#

Submodules#

qibolab.instruments.qblox.acquisition module#

qibolab.instruments.qblox.acquisition.demodulate(input_i, input_q, frequency)[source]#

Demodulates and integrates the acquired pulse.

class qibolab.instruments.qblox.acquisition.AveragedAcquisition(results: dict, duration: int, frequency: int, i: List[float] | None = None, q: List[float] | None = None)[source]#

Bases: object

Software Demodulation.

Every readout pulse triggers an acquisition, where the 16384 i and q samples of the waveform acquired by the ADC are saved into a dedicated memory within the FPGA. This is what qblox calls scoped acquisition. The results of multiple shots are averaged in this memory, and cannot be retrieved independently. The resulting waveforms averages (i and q) are then demodulated and integrated in software (and finally divided by the number of samples). Since Software Demodulation relies on the data of the scoped acquisition and that data is the average of all acquisitions, only one readout pulse per qubit is supported, so that the averages all correspond to reading the same quantum state.

results: dict#

Data returned by qblox acquisition.

duration: int#

Duration of the readout pulse.

frequency: int#

Frequency of the readout pulse used for demodulation.

i: List[float] | None = None#
q: List[float] | None = None#
property scope#
property raw_i#

Average of the i waveforms for every readout pulse.

property raw_q#

Average of the q waveforms for every readout pulse.

property data#

Acquisition data to be returned to the platform.

Ignores the data available in acquisition results and returns only i and q voltages.

class qibolab.instruments.qblox.acquisition.DemodulatedAcquisition(scope: dict, bins: dict, duration: int)[source]#

Bases: object

Hardware Demodulation.

With hardware demodulation activated, the FPGA can demodulate, integrate (average over time), and classify each shot individually, saving the results on separate bins. The raw data of each acquisition continues to be averaged as with software modulation, so there is no way to access the raw data of each shot (unless executed one shot at a time). The FPGA uses fixed point arithmetic for the demodulation and integration; if the power level of the signal at the input port is low (the minimum resolution of the ADC is 240uV) rounding precission errors can accumulate and render wrong results. It is advisable to have a power level at least higher than 5mV.

scope: dict#

Data returned by scope qblox acquisition.

bins: dict#

Binned acquisition data returned by qblox.

duration: int#

Duration of the readout pulse.

property raw#
property integration#
property shots_i#

I-component after demodulating and integrating every shot waveform.

property shots_q#

Q-component after demodulating and integrating every shot waveform.

property raw_i#

Average of the raw i waveforms for every readout pulse.

property raw_q#

Average of the raw q waveforms for every readout pulse.

property classified#

List with the results of demodulating, integrating and classifying every shot.

qibolab.instruments.qblox.cluster_qcm_bb module#

Qblox Cluster QCM driver.

class qibolab.instruments.qblox.cluster_qcm_bb.QcmBb(name: str, address: str)[source]#

Bases: ClusterModule

Qblox Cluster Qubit Control Module Baseband driver.

Qubit Control Module (QCM) is an arbitratry wave generator with two DACs connected to four output ports. It can sinthesise either four independent real signals or two complex signals, using ports 0 and 2 to output the i(in-phase) component and ports 1 and 3 the q(quadrature) component. The sampling rate of its DAC is 1 GSPS. https://www.qblox.com/cluster

The class aims to simplify the configuration of the instrument, exposing only those parameters most frequencly used and hiding other more complex components.

A reference to the underlying qblox_instruments.qcodes_drivers.qcm_qrm.QRM_QCM object is provided via the attribute device, allowing the advanced user to gain access to the features that are not exposed directly by the class.

In order to accelerate the execution, the instrument settings are cached, so that the communication with the instrument only happens when the parameters change. This caching is done with the method _set_device_parameter(target, *parameters, value).

ports:
    o1:
        channel                      : L4-1
        gain                         : 0.2 # -1.0<=v<=1.0
        offset                       : 0   # -2.5<=v<=2.5
    o2:
        channel                      : L4-2
        gain                         : 0.2 # -1.0<=v<=1.0
        offset                       : 0   # -2.5<=v<=2.5
    o3:
        channel                      : L4-3
        gain                         : 0.2 # -1.0<=v<=1.0
        offset                       : 0   # -2.5<=v<=2.5
    o4:
        channel                      : L4-4
        gain                         : 0.2 # -1.0<=v<=1.0
        offset                       : 0   # -2.5<=v<=2.5
name#

A unique name given to the instrument.

Type:

str

address#

IP_address:module_number (the IP address of the cluster and the module number)

Type:

str

device#

A reference to the underlying qblox_instruments.qcodes_drivers.qcm_qrm.QcmQrm object. It can be used to access other features not directly exposed by this wrapper. https://qblox-qblox-instruments.readthedocs-hosted.com/en/master/api_reference/qcm_qrm.html

Type:

QbloxQrmQcm

ports = A dictionary giving access to the output ports objects.
  • ports[‘o1’]

  • ports[‘o2’]

  • ports[‘o3’]

  • ports[‘o4’]

  • ports[‘oX’].channel (int | str): the id of the refrigerator channel the port is connected to.

  • ports[‘oX’].gain (float): (mapped to qrm.sequencers[0].gain_awg_path0 and qrm.sequencers[0].gain_awg_path1)

    Sets the gain on both paths of the output port.

  • ports[‘oX’].offset (float): (mapped to qrm.outX_offset)

    Sets the offset on the output port.

  • ports[‘oX’].hardware_mod_en (bool): (mapped to qrm.sequencers[0].mod_en_awg) Enables pulse

    modulation in hardware. When set to False, pulse modulation is done at the host computer and a modulated pulse waveform should be uploaded to the instrument. When set to True, the envelope of the pulse should be uploaded to the instrument and it modulates it in real time by its FPGA using the sequencer nco (numerically controlled oscillator).

  • ports[‘oX’].nco_freq (int): (mapped to qrm.sequencers[0].nco_freq) # TODO mapped, but not configurable from the runcard

  • ports[‘oX’].nco_phase_offs = (mapped to qrm.sequencers[0].nco_phase_offs) # TODO mapped, but not configurable from the runcard

    • Sequencer 0 is always the first sequencer used to synthesise pulses on port o1.

    • Sequencer 1 is always the first sequencer used to synthesise pulses on port o2.

    • Sequencer 2 is always the first sequencer used to synthesise pulses on port o3.

    • Sequencer 3 is always the first sequencer used to synthesise pulses on port o4.

    • Sequencer 4 to 6 are used as needed to sinthesise simultaneous pulses on the same channel or when the memory of the default sequencers rans out.

DEFAULT_SEQUENCERS = {'o1': 0, 'o2': 1, 'o3': 2, 'o4': 3}#
FREQUENCY_LIMIT = 500000000.0#
OUT_PORT_PATH = {0: 'I', 1: 'Q', 2: 'I', 3: 'Q'}#
connect(cluster: Cluster | None = None)[source]#

Connects to the instrument using the instrument settings in the runcard.

Once connected, it creates port classes with properties mapped to various instrument parameters, and initialises the the underlying device parameters. It uploads to the module the port settings loaded from the runcard.

setup(**settings)[source]#

Cache the settings of the runcard and instantiate the ports of the module.

Parameters:

**settings

dict = A dictionary of settings loaded from the runcard:

  • settings[oX][‘offset’] (float): [-2.5 - 2.5 V] offset in volts applied to the output port.

  • settings[oX][‘hardware_mod_en’] (bool): enables Hardware Modulation. In this mode, pulses are modulated to the intermediate frequency using the numerically controlled oscillator within the fpga. It only requires the upload of the pulse envelope waveform. At the moment this param is not loaded but is always set to True.

get_if(pulse)[source]#

Returns the intermediate frequency needed to synthesise a pulse based on the port lo frequency.

process_pulse_sequence(qubits: dict, instrument_pulses: PulseSequence, navgs: int, nshots: int, repetition_duration: int, sweepers=None)[source]#

Processes a list of pulses, generating the waveforms and sequence program required by the instrument to synthesise them.

The output of the process is a list of sequencers used for each port, configured with the information required to play the sequence. The following features are supported:

  • overlapping pulses

  • hardware modulation

  • software modulation, with support for arbitrary pulses

  • real-time sweepers of

    • pulse frequency (requires hardware modulation)

    • pulse relative phase (requires hardware modulation)

    • pulse amplitude

    • pulse start

    • pulse duration

    • port gain

    • port offset

  • sequencer memory optimisation (waveforms cache)

  • extended waveform memory with the use of multiple sequencers

  • pulses of up to 8192 pairs of i, q samples

  • intrument parameters cache

Parameters:
  • instrument_pulses (PulseSequence) – A collection of Pulse objects to be played by the instrument.

  • navgs (int) – The number of times the sequence of pulses should be executed averaging the results.

  • nshots (int) – The number of times the sequence of pulses should be executed without averaging.

  • repetition_duration (int) – The total duration of the pulse sequence execution plus the reset/relaxation time.

  • sweepers (list(Sweeper)) – A list of Sweeper objects to be implemented.

upload()[source]#

Uploads waveforms and programs of all sequencers and arms them in preparation for execution.

This method should be called after process_pulse_sequence(). It configures certain parameters of the instrument based on the needs of resources determined while processing the pulse sequence.

play_sequence()[source]#

Executes the sequence of instructions.

disconnect()[source]#

Stops all sequencers, disconnect all the outputs from the AWG paths of the sequencers.

qibolab.instruments.qblox.cluster_qcm_rf module#

Qblox Cluster QCM-RF driver.

class qibolab.instruments.qblox.cluster_qcm_rf.QcmRf(name: str, address: str)[source]#

Bases: ClusterModule

Qblox Cluster Qubit Control Module RF driver.

Qubit Control Module RF (QCM-RF) is an instrument that integrates an arbitratry wave generator, with a local oscillator and a mixer. It has two output ports Each port has a path0 and path1 for the i(in-phase) and q(quadrature) components of the RF signal. The sampling rate of its ADC/DAC is 1 GSPS. https://www.qblox.com/cluster

The class aims to simplify the configuration of the instrument, exposing only those parameters most frequencly used and hiding other more complex components.

A reference to the underlying qblox_instruments.qcodes_drivers.qcm_qrm.QRM_QCM object is provided via the attribute device, allowing the advanced user to gain access to the features that are not exposed directly by the class.

In order to accelerate the execution, the instrument settings are cached, so that the communication with the instrument only happens when the parameters change. This caching is done with the method _set_device_parameter(target, *parameters, value).

ports:
    o1:                     # output port settings
        channel                      : L3-11
        attenuation                  : 24               # (dB) 0 to 60, must be multiple of 2
        lo_enabled                   : true
        lo_frequency                 : 4_042_590_000    # (Hz) from 2e9 to 18e9
        gain                         : 0.17             # for path0 and path1 -1.0<=v<=1.0
    o2:
        channel                      : L3-12
        attenuation                  : 24               # (dB) 0 to 60, must be multiple of 2
        lo_enabled                   : true
        lo_frequency                 : 5_091_155_529    # (Hz) from 2e9 to 18e9
        gain                         : 0.28             # for path0 and path1 -1.0<=v<=1.0
name#

A unique name given to the instrument.

Type:

str

address#

IP_address:module_number (the IP address of the cluster and the module number)

Type:

str

device#

A reference to the underlying qblox_instruments.qcodes_drivers.qcm_qrm.QcmQrm object. It can be used to access other features not directly exposed by this wrapper. https://qblox-qblox-instruments.readthedocs-hosted.com/en/master/api_reference/qcm_qrm.html

Type:

QcmQrm

ports = A dictionary giving access to the output ports objects.
  • ports[‘o1’]

  • ports[‘o2’]

  • ports[‘o1’].channel (int | str): the id of the refrigerator channel the port is connected to.

  • ports[‘o1’].attenuation (int): (mapped to qrm.out0_att) Controls the attenuation applied to the output port. Must be a multiple of 2

  • ports[‘o1’].lo_enabled (bool): (mapped to qrm.out0_in0_lo_en) Enables or disables the local oscillator.

  • ports[‘o1’].lo_frequency (int): (mapped to qrm.out0_in0_lo_freq) Sets the frequency of the local oscillator.

  • ports[‘o1’].gain (float): (mapped to qrm.sequencers[0].gain_awg_path0 and qrm.sequencers[0].gain_awg_path1) Sets the gain on both paths of the output port.

  • ports[‘o1’].hardware_mod_en (bool): (mapped to qrm.sequencers[0].mod_en_awg) Enables pulse modulation in hardware. When set to False, pulse modulation is done at the host computer and a modulated pulse waveform should be uploaded to the instrument. When set to True, the envelope of the pulse should be uploaded to the instrument and it modulates it in real time by its FPGA using the sequencer nco (numerically controlled oscillator).

  • ports[‘o1’].nco_freq (int): (mapped to qrm.sequencers[0].nco_freq) # TODO mapped, but not configurable from the runcard

  • ports[‘o1’].nco_phase_offs = (mapped to qrm.sequencers[0].nco_phase_offs) # TODO mapped, but not configurable from the runcard

  • ports[‘o2’].channel (int | str): the id of the refrigerator channel the port is connected to.

  • ports[‘o2’].attenuation (int): (mapped to qrm.out1_att) Controls the attenuation applied to the output port. Must be a multiple of 2

  • ports[‘o2’].lo_enabled (bool): (mapped to qrm.out1_lo_en) Enables or disables the local oscillator.

  • ports[‘o2’].lo_frequency (int): (mapped to qrm.out1_lo_freq) Sets the frequency of the local oscillator.

  • ports[‘o2’].gain (float): (mapped to qrm.sequencers[1].gain_awg_path0 and qrm.sequencers[0].gain_awg_path1) Sets the gain on both paths of the output port.

  • ports[‘o2’].hardware_mod_en (bool): (mapped to qrm.sequencers[1].mod_en_awg) Enables pulse modulation in hardware. When set to False, pulse modulation is done at the host computer and a modulated pulse waveform should be uploaded to the instrument. When set to True, the envelope of the pulse should be uploaded to the instrument and it modulates it in real time by its FPGA using the sequencer nco (numerically controlled oscillator).

  • ports[‘o2’].nco_freq (int): (mapped to qrm.sequencers[1].nco_freq) # TODO mapped, but not configurable from the runcard

  • ports[‘o2’].nco_phase_offs = (mapped to qrm.sequencers[1].nco_phase_offs) # TODO mapped, but not configurable from the runcard

    • Sequencer 0 is always the first sequencer used to synthesise pulses on port o1.

    • Sequencer 1 is always the first sequencer used to synthesise pulses on port o2.

    • Sequencer 2 to 6 are used as needed to sinthesise simultaneous pulses on the same channel or when the memory of the default sequencers rans out.

channels#

A list of the channels to which the instrument is connected.

Type:

list

DEFAULT_SEQUENCERS = {'o1': 0, 'o2': 1}#
FREQUENCY_LIMIT = 500000000.0#
connect(cluster: Cluster | None = None)[source]#

Connects to the instrument using the instrument settings in the runcard.

Once connected, it creates port classes with properties mapped to various instrument parameters, and initialises the the underlying device parameters. It uploads to the module the port settings loaded from the runcard.

setup(**settings)[source]#

Cache the settings of the runcard and instantiate the ports of the module.

Parameters:

**settings

dict = A dictionary of settings loaded from the runcard:

  • settings[‘o1’][‘attenuation’] (int): [0 to 60 dBm, in multiples of 2] attenuation at the output.

  • settings[‘o1’][‘lo_frequency’] (int): [2_000_000_000 to 18_000_000_000 Hz] local oscillator frequency.

  • settings[‘o1’][‘hardware_mod_en’] (bool): enables Hardware Modulation. In this mode, pulses are modulated to the intermediate frequency using the numerically controlled oscillator within the fpga. It only requires the upload of the pulse envelope waveform. At the moment this param is not loaded but is always set to True.

  • settings[‘o2’][‘attenuation’] (int): [0 to 60 dBm, in multiples of 2] attenuation at the output.

  • settings[‘o2’][‘lo_frequency’] (int): [2_000_000_000 to 18_000_000_000 Hz] local oscillator frequency.

  • settings[‘o2’][‘hardware_mod_en’] (bool): enables Hardware Modulation. In this mode, pulses are modulated to the intermediate frequency using the numerically controlled oscillator within the fpga. It only requires the upload of the pulse envelope waveform. At the moment this param is not loaded but is always set to True.

get_if(pulse)[source]#

Returns the intermediate frequency needed to synthesise a pulse based on the port lo frequency.

process_pulse_sequence(qubits: dict, instrument_pulses: PulseSequence, navgs: int, nshots: int, repetition_duration: int, sweepers=None)[source]#

Processes a sequence of pulses and sweepers, generating the waveforms and program required by the instrument to synthesise them.

The output of the process is a list of sequencers used for each port, configured with the information required to play the sequence. The following features are supported:

  • overlapping pulses

  • hardware modulation

  • software modulation, with support for arbitrary pulses

  • real-time sweepers of

    • pulse frequency (requires hardware modulation)

    • pulse relative phase (requires hardware modulation)

    • pulse amplitude

    • pulse start

    • pulse duration

    • port gain

    • port offset

  • sequencer memory optimisation (waveforms cache)

  • extended waveform memory with the use of multiple sequencers

  • pulses of up to 8192 pairs of i, q samples

  • intrument parameters cache

Parameters:
  • instrument_pulses (PulseSequence) – A collection of Pulse objects to be played by the instrument.

  • navgs (int) – The number of times the sequence of pulses should be executed averaging the results.

  • nshots (int) – The number of times the sequence of pulses should be executed without averaging.

  • repetition_duration (int) – The total duration of the pulse sequence execution plus the reset/relaxation time.

  • sweepers (list(Sweeper)) – A list of Sweeper objects to be implemented.

upload()[source]#

Uploads waveforms and programs of all sequencers and arms them in preparation for execution.

This method should be called after process_pulse_sequence(). It configures certain parameters of the instrument based on the needs of resources determined while processing the pulse sequence.

play_sequence()[source]#

Plays the sequence of pulses.

Starts the sequencers needed to play the sequence of pulses.

disconnect()[source]#

Stops all sequencers, disconnect all the outputs from the AWG paths of the sequencers.

qibolab.instruments.qblox.cluster_qrm_rf module#

Qblox Cluster QRM-RF driver.

class qibolab.instruments.qblox.cluster_qrm_rf.QrmRf(name: str, address: str)[source]#

Bases: ClusterModule

Qblox Cluster Qubit Readout Module RF driver.

Qubit Readout Module RF (QRM-RF) is an instrument that integrates an arbitrary wave generator, a digitizer, a local oscillator and a mixer. It has one output and one input port. Each port has a path0 and path1 for the i(in-phase) and q(quadrature) components of the RF signal. The sampling rate of its ADC/DAC is 1 GSPS. https://www.qblox.com/cluster

The class aims to simplify the configuration of the instrument, exposing only those parameters most frequently used and hiding other more complex settings.

A reference to the underlying qblox_instruments.qcodes_drivers.qcm_qrm.QRM_QCM object is provided via the attribute device, allowing the advanced user to gain access to the features that are not exposed directly by the class.

In order to accelerate the execution, the instrument settings are cached, so that the communication with the instrument only happens when the parameters change. This caching is done with the method _set_device_parameter(target, *parameters, value).

ports:
    o1:                                             # output port settings
        channel                     : L3-25a
        attenuation                 : 30                # (dB) 0 to 60, must be multiple of 2
        lo_enabled                  : true
        lo_frequency                : 6_000_000_000     # (Hz) from 2e9 to 18e9
        gain                        : 1                 # for path0 and path1 -1.0<=v<=1.0
    i1:                                             # input port settings
        channel                     : L2-5a
        acquisition_hold_off        : 130               # minimum 4ns
        acquisition_duration        : 1800

classification_parameters:
    0: # qubit id
        rotation_angle              : 0                 # in degrees 0.0<=v<=360.0
        threshold                   : 0                 # in V
    1:
        rotation_angle              : 194.272
        threshold                   : 0.011197
    2:
        rotation_angle              : 104.002
        threshold                   : 0.012745
name#

A unique name given to the instrument.

Type:

str

address#

IP_address:module_number; the IP address of the cluster and the module number.

Type:

str

device#

A reference to the underlying qblox_instruments.qcodes_drivers.qcm_qrm.QcmQrm object. It can be used to access other features not directly exposed by this wrapper. https://qblox-qblox-instruments.readthedocs-hosted.com/en/master/api_reference/qcm_qrm.html

Type:

QcmQrm

ports = A dictionary giving access to the input and output ports objects.
  • ports[‘o1’]: Output port

  • ports[‘i1’]: Input port

  • ports[‘o1’].channel (int | str): the id of the refrigerator channel the output port o1 is connected to.

  • ports[‘o1’].attenuation (int): (mapped to qrm.out0_att) Controls the attenuation applied to the output port. It must be a multiple of 2.

  • ports[‘o1’].lo_enabled (bool): (mapped to qrm.out0_in0_lo_en) Enables or disables the local oscillator.

  • ports[‘o1’].lo_frequency (int): (mapped to qrm.out0_in0_lo_freq) Sets the frequency of the local oscillator.

  • ports[‘o1’].gain (float): (mapped to qrm.sequencers[0].gain_awg_path0 and qrm.sequencers[0].gain_awg_path1) Sets the gain on both paths of the output port.

  • ports[‘o1’].hardware_mod_en (bool): (mapped to qrm.sequencers[0].mod_en_awg) Enables pulse modulation in hardware. When set to False, pulse modulation is done in software, at the host computer, and the modulated pulse waveform is uploaded to the instrument. When set to True, the envelope of the pulse is uploaded to the instrument and it is modulated in real time by the FPGA of the instrument, using the sequencer nco (numerically controlled oscillator).

  • ports[‘o1’].nco_freq (int): (mapped to qrm.sequencers[0].nco_freq). Mapped, but not configurable from the runcard.

  • ports[‘o1’].nco_phase_offs = (mapped to qrm.sequencers[0].nco_phase_offs). Mapped, but not configurable from the runcard.

  • ports[‘i1’].channel (int | str): the id of the refrigerator channel the input port o1 is connected to.

  • ports[‘i1’].acquisition_hold_off (int): Delay between the moment the readout pulse starts to be played and the start of the acquisition, in ns. It must be > 0 and multiple of 4.

  • ports[‘i1’].acquisition_duration (int): (mapped to qrm.sequencers[0].integration_length_acq) Duration of the pulse acquisition, in ns. It must be > 0 and multiple of 4.

  • ports[‘i1’].hardware_demod_en (bool): (mapped to qrm.sequencers[0].demod_en_acq) Enables demodulation and integration of the acquired pulses in hardware. When set to False, the filtration, demodulation and integration of the acquired pulses is done at the host computer. When set to True, the demodulation, integration and discretization of the pulse is done in real time at the FPGA of the instrument.

    • Sequencer 0 is used always for acquisitions and it is the first sequencer used to synthesise pulses.

    • Sequencer 1 to 6 are used as needed to synthesise simultaneous pulses on the same channel (required in multiplexed readout) or when the memory of the default sequencers rans out.

classification_parameters#

A dictionary containing the parameters needed classify the state of each qubit. from a single shot measurement:

Type:

dict

qubit_id#

the id of the qubit rotation_angle (float): 0 # in degrees 0.0<=v<=360.0. The angle of the rotation applied at the origin of the i q plane, that put the centroids of the state |0> and state |1> in a horizontal line. The rotation puts the centroid of state |1> to the right side of centroid of state |0>.

Type:

dict

threshold#

0 # in V. The real component of the point along the horizontal line connecting both state centroids (after being rotated), that maximises the fidelity of the classification.

Type:

float

channels#

A list of the channels to which the instrument is connected.

Type:

list

DEFAULT_SEQUENCERS: dict = {'i1': 0, 'o1': 0}#
FREQUENCY_LIMIT = 500000000.0#
connect(cluster: Cluster | None = None)[source]#

Connects to the instrument using the instrument settings in the runcard.

Once connected, it creates port classes with properties mapped to various instrument parameters, and initialises the the underlying device parameters. It uploads to the module the port settings loaded from the runcard.

setup(**settings)[source]#

Cache the settings of the runcard and instantiate the ports of the module.

Parameters:

**settings

dict = A dictionary of settings loaded from the runcard:

  • settings[‘o1’][‘attenuation’] (int): [0 to 60 dBm, in multiples of 2] attenuation at the output.

  • settings[‘o1’][‘lo_enabled’] (bool): enable or disable local oscillator for up-conversion.

  • settings[‘o1’][‘lo_frequency’] (int): [2_000_000_000 to 18_000_000_000 Hz] local oscillator frequency.

  • settings[‘o1’][‘hardware_mod_en’] (bool): enables Hardware Modulation. In this mode, pulses are modulated to the intermediate frequency using the numerically controlled oscillator within the fpga. It only requires the upload of the pulse envelope waveform. At the moment this param is not loaded but is always set to True.

  • settings[‘i1’][‘hardware_demod_en’] (bool): enables Hardware Demodulation. In this mode, the sequencers of the fpga demodulate, integrate and classify the results for every shot. Once integrated, the i and q values and the result of the classification requires much less memory, so they can be stored for every shot in separate bins and retrieved later. Hardware Demodulation also allows making multiple readouts on the same qubit at different points in the circuit, which is not possible with Software Demodulation. At the moment this param is not loaded but is always set to True.

  • settings[‘i1’][‘acquisition_hold_off’] (int): [0 to 16834 ns, in multiples of 4] the time between the moment the start of the readout pulse begins to be played, and the start of the acquisition. This is used to account for the time of flight of the pulses from the output port to the input port.

  • settings[‘i1’][‘acquisition_duration’] (int): [0 to 8192 ns] the duration of the acquisition. It is limited by the amount of memory available in the fpga to store i q samples.

get_if(pulse: Pulse)[source]#

Returns the intermediate frequency needed to synthesise a pulse based on the port lo frequency.

process_pulse_sequence(qubits: dict, instrument_pulses: PulseSequence, navgs: int, nshots: int, repetition_duration: int, sweepers=None)[source]#

Processes a sequence of pulses and sweepers, generating the waveforms and program required by the instrument to synthesise them.

The output of the process is a list of sequencers used for each port, configured with the information required to play the sequence. The following features are supported:

  • multiplexed readout of up to 6 qubits

  • overlapping pulses

  • hardware modulation, demodulation, and classification

  • software modulation, with support for arbitrary pulses

  • software demodulation

  • binned acquisition

  • real-time sweepers of

    • pulse frequency (requires hardware modulation)

    • pulse relative phase (requires hardware modulation)

    • pulse amplitude

    • pulse start

    • pulse duration

    • port gain

    • port offset

  • multiple readouts for the same qubit (sequence unrolling)

  • pulses of up to 8192 pairs of i, q samples

  • sequencer memory optimisation (waveforms cache)

  • extended waveform memory with the use of multiple sequencers

  • intrument parameters cache

Parameters:
  • instrument_pulses (PulseSequence) – A collection of Pulse objects to be played by the instrument.

  • navgs (int) – The number of times the sequence of pulses should be executed averaging the results.

  • nshots (int) – The number of times the sequence of pulses should be executed without averaging.

  • repetition_duration (int) – The total duration of the pulse sequence execution plus the reset/relaxation time.

  • sweepers (list(Sweeper)) – A list of Sweeper objects to be implemented.

upload()[source]#

Uploads waveforms and programs of all sequencers and arms them in preparation for execution.

This method should be called after process_pulse_sequence(). It configures certain parameters of the instrument based on the needs of resources determined while processing the pulse sequence.

play_sequence()[source]#

Plays the sequence of pulses.

Starts the sequencers needed to play the sequence of pulses.

acquire()[source]#

Retrieves the readout results.

The results returned vary depending on whether demodulation is performed in software or hardware. See qibolab.instruments.qblox.acquisition.AveragedAcquisition and qibolab.instruments.qblox.acquisition.DemodulatedAcquisition for more details

disconnect()[source]#

Stops all sequencers, disconnect all the outputs from the AWG paths of the sequencers and disconnect all the inputs from the acquisition paths of the sequencers.

qibolab.instruments.qblox.controller module#

qibolab.instruments.qblox.controller.MAX_NUM_BINS = 98304#

Maximum number of bins that should be used per sequencer in a readout module.

One sequencer can have up to 2 ** 17 bins, however the 6 sequencers in module allocate bins from a shared memory, and this memory is smaller than 6 * 2 ** 17. Hence, if all sequencers are used at once, each cannot support 2 ** 17 bins. In fact, the total bin memory for the module is 3 * (2 ** 17 + 2 ** 16). This means up to three sequencers used at once can support 2 ** 17 bins each, but four or more sequencers cannot. So the limitation on the number of bins technically depends on the number of sequencers used, but to keep things simple we limit ourselves to max number of bins that works regardless of situation.

class qibolab.instruments.qblox.controller.QbloxController(name, address: str, modules, internal_reference_clock: bool = True)[source]#

Bases: Controller

A controller to manage qblox devices.

is_connected#

.

Type:

bool

modules#

A dictionay with the qblox modules connected to the experiment.

Type:

dict

property sampling_rate#

Sampling rate of control electronics in giga samples per second (GSps).

connect()[source]#

Connects to the modules.

disconnect()[source]#

Disconnects all modules.

play(qubits, couplers, sequence, options)[source]#

Play a pulse sequence and retrieve feedback.

Returns:

(Dict[ResultType]) mapping the serial of the readout pulses used to the acquired qibolab.result.ExecutionResults object.

sweep(qubits: dict, couplers: dict, sequence: PulseSequence, options: ExecutionParameters, *sweepers)[source]#

Executes a sequence of pulses while sweeping one or more parameters.

The parameters to be swept are defined in qibolab.sweeper.Sweeper object. :param sequence: The sequence of pulses to execute. :type sequence: qibolab.pulses.PulseSequence :param options: Object holding the execution options. :type options: qibolab.platforms.platform.ExecutionParameters :param sweepers: A list of Sweeper objects defining parameter sweeps. :type sweepers: list(Sweeper)

qibolab.instruments.qblox.debug module#

qibolab.instruments.qblox.debug.print_readable_snapshot(device, file, update: bool = False, max_chars: int = 80) None[source]#

Prints a readable version of the snapshot. The readable snapshot includes the name, value and unit of each parameter. A convenience function to quickly get an overview of the status of an instrument.

Parameters:
  • update – If True, update the state by querying the instrument. If False, just use the latest values in memory. This argument gets passed to the snapshot function.

  • max_chars – the maximum number of characters per line. The readable snapshot will be cropped if this value is exceeded. Defaults to 80 to be consistent with default terminal width.

qibolab.instruments.qblox.module module#

Qblox Cluster QCM driver.

class qibolab.instruments.qblox.module.ClusterModule(name: str, address: str)[source]#

Bases: Instrument

This class defines common features shared by all Qblox modules (QCM-BB, QCM-RF, QRM-RF).

It serves as a foundational class, unifying the behavior of the three distinct modules. All module-specific classes are intended to inherit from this base class.

DEFAULT_SEQUENCERS_VALUES = {'cont_mode_en_awg_path0': False, 'cont_mode_en_awg_path1': False, 'cont_mode_waveform_idx_awg_path0': 0, 'cont_mode_waveform_idx_awg_path1': 0, 'marker_ovr_en': True, 'marker_ovr_value': 15, 'mixer_corr_gain_ratio': 1, 'mixer_corr_phase_offset_degree': 0, 'offset_awg_path0': 0, 'offset_awg_path1': 0, 'sync_en': False, 'upsample_rate_awg_path0': 0, 'upsample_rate_awg_path1': 0}#
ports(name: str, out: bool = True)[source]#

Adds an entry to the dictionary self._ports with key ‘name’ and value a QbloxOutputPort (or QbloxInputPort if out=False) object. To the object is assigned the provided name, and the port_number is automatically determined based on the number of ports of the same type inside self._ports.

Returns this port object.

Example: >>> qrm_module = QrmRf(“qrm_rf”, f”{IP_ADDRESS}:{SLOT_IDX}”) >>> output_port = qrm_module.add_port(“o1”) >>> input_port = qrm_module.add_port(“i1”, out=False) >>> qrm_module.ports {

‘o1’: QbloxOutputPort(module=qrm_module, port_number=0, port_name=’o1’), ‘i1’: QbloxInputPort(module=qrm_module, port_number=0, port_name=’i1’)

}

qibolab.instruments.qblox.port module#

class qibolab.instruments.qblox.port.QbloxOutputPort_Settings(attenuation: int = 60, offset: float = 0.0, hardware_mod_en: bool = True, nco_freq: int = 0, nco_phase_offs: float = 0, lo_enabled: bool = True, lo_frequency: int = 2000000000)[source]#

Bases: object

attenuation: int = 60#
offset: float = 0.0#
hardware_mod_en: bool = True#
nco_freq: int = 0#
nco_phase_offs: float = 0#
lo_enabled: bool = True#
lo_frequency: int = 2000000000#
class qibolab.instruments.qblox.port.QbloxInputPort_Settings(channel: str = None, acquisition_hold_off: int = 0, acquisition_duration: int = 1000, hardware_demod_en: bool = True)[source]#

Bases: object

channel: str = None#
acquisition_hold_off: int = 0#
acquisition_duration: int = 1000#
hardware_demod_en: bool = True#
class qibolab.instruments.qblox.port.QbloxOutputPort(module, port_number: int, port_name: str | None = None)[source]#

Bases: Port

qibolab.instruments.port.Port interface implementation for Qblox instruments.

property attenuation: str#

Attenuation that is applied to this port.

property offset#

DC offset that is applied to this port.

property hardware_mod_en#

Flag to enable hardware modulation.

property nco_freq#

nco_freq that is applied to this port.

property nco_phase_offs#

nco_phase_offs that is applied to this port.

property lo_enabled#

Flag to enable local oscillator.

property lo_frequency#

Local oscillator frequency for the given port.

class qibolab.instruments.qblox.port.QbloxInputPort(module, port_number: int, port_name: str | None = None)[source]#

Bases: object

property hardware_demod_en#

Flag to enable hardware demodulation.

property acquisition_duration#

Duration of the pulse acquisition, in ns.

It must be > 0 and multiple of 4.

qibolab.instruments.qblox.q1asm module#

A library to support generating qblox q1asm programs.

class qibolab.instruments.qblox.q1asm.Program[source]#

Bases: object

A class to represent a sequencer q1asm assembly program.

A q1asm program is made of blocks of code (qibolab.instruments.qblox.qblox_q1asm.Block). Real time registers (variables) are necessary to implement sweeps in real time. This class keeps track of the registers used and has a method to provide the next available register.

MAX_REGISTERS = 64#
next_register()[source]#

Provides the number of the next available register.

add_blocks(*blocks)[source]#

Adds a qibolab.instruments.qblox.qblox_q1asm.Block of code to the list of blocks.

class qibolab.instruments.qblox.q1asm.Block(name='')[source]#

Bases: object

A class to represent a block of q1asm assembly code.

A block is comprised of code lines. .. attribute:: name

A name for the block of code.

type:

str

lines#

A list of lines of code (code, comment, indentation level).

Type:

list(tupple)

GLOBAL_INDENTATION_LEVEL = 3#
SPACES_PER_LEVEL = 4#
SPACES_BEFORE_COMMENT = 4#
property indentation#
append(line, comment='', level=0)[source]#
prepend(line, comment='', level=0)[source]#
append_spacer()[source]#
class qibolab.instruments.qblox.q1asm.Register(program: Program, name: str = '')[source]#

Bases: object

A class to represent a q1asm program register.

Registers are used as variables in real time FPGA code. .. attribute:: name

a name to identify the register

type:

str

property name#
qibolab.instruments.qblox.q1asm.wait_block(wait_time: int, register: Register, force_multiples_of_four: bool = False)[source]#

Generates blocks of code to implement long delays.

Parameters:
  • wait_time (int) – the total time to wait.

  • register (qibolab.instruments.qblox.qblox_q1asm.Register) – the register used to loop

  • force_multiples_of_four (bool) – a flag that forces the delay to be a multiple of 4(ns)

qibolab.instruments.qblox.q1asm.loop_block(start: int, stop: int, step: int, register: Register, block: Block)[source]#

Generates blocks of code to implement loops.

Its behaviour is similar to range(): it includes the first value, but never the last.

Parameters:
  • start (int) – the initial value.

  • stop (int) – the final value (excluded).

  • step (int) – the step in which the register is incremented.

  • register (qibolab.instruments.qblox.qblox_q1asm.Register) – the register modified within the loop.

  • block (qibolab.instruments.qblox.qblox_q1asm.Register) – the block of code to be iterated.

qibolab.instruments.qblox.q1asm.convert_phase(phase_rad: float)[source]#

Converts phase values in radiants to the encoding used in qblox FPGAs.

The phase is divided into 1e9 steps between 0° and 360°, expressed as an integer between 0 and 1e9 (e.g 45°=125e6). https://qblox-qblox-instruments.readthedocs-hosted.com/en/master/api_reference/sequencer.html

qibolab.instruments.qblox.q1asm.convert_frequency(freq: float)[source]#

Converts frequency values to the encoding used in qblox FPGAs.

The frequency is divided into 4e9 steps between -500 and 500 MHz and expressed as an integer between -2e9 and 2e9. (e.g. 1 MHz=4e6). https://qblox-qblox-instruments.readthedocs-hosted.com/en/master/api_reference/sequencer.html

qibolab.instruments.qblox.q1asm.convert_gain(gain: float)[source]#

Converts gain values to the encoding used in qblox FPGAs.

Both gain values are divided in 2**sample path width steps. QCM DACs resolution 16bits, QRM DACs and ADCs 12 bit https://qblox-qblox-instruments.readthedocs-hosted.com/en/master/api_reference/sequencer.html

qibolab.instruments.qblox.q1asm.convert_offset(offset: float)[source]#

Converts offset values to the encoding used in qblox FPGAs.

Both offset values are divided in 2**sample path width steps. QCM DACs resolution 16bits, QRM DACs and ADCs 12 bit QCM 5Vpp, QRM 2Vpp https://qblox-qblox-instruments.readthedocs-hosted.com/en/master/api_reference/sequencer.html

qibolab.instruments.qblox.sequencer module#

qibolab.instruments.qblox.sequencer.SAMPLING_RATE = 1#

Sampling rate for qblox instruments in GSps.

class qibolab.instruments.qblox.sequencer.WaveformsBuffer[source]#

Bases: object

A class to represent a buffer that holds the unique waveforms used by a sequencer.

unique_waveforms#

A list of unique Waveform objects.

Type:

list

available_memory#

The amount of memory available expressed in numbers of samples.

Type:

int

SIZE: int = 16383#
exception NotEnoughMemory[source]#

Bases: Exception

An error raised when there is not enough memory left to add more waveforms.

exception NotEnoughMemoryForBaking[source]#

Bases: Exception

An error raised when there is not enough memory left to bake pulses.

add_waveforms(pulse: Pulse, hardware_mod_en: bool, sweepers: list[qibolab.sweeper.Sweeper])[source]#

Adds a pair of i and q waveforms to the list of unique waveforms.

Waveforms are added to the list if they were not there before. Each of the waveforms (i and q) is processed individually.

Parameters:
  • waveform_i (Waveform) – A Waveform object containing the samples of the real component of the pulse wave.

  • waveform_q (Waveform) – A Waveform object containing the samples of the imaginary component of the pulse wave.

Raises:

NotEnoughMemory – If the memory needed to store the waveforms in more than the memory avalible.

bake_pulse_waveforms(pulse: Pulse, values: [], hardware_mod_en: bool)[source]#

Generates and stores a set of i and q waveforms required for a pulse duration sweep.

These waveforms are generated and stored in a predefined order so that they can later be retrieved within the sweeper q1asm code. It bakes pulses from as short as 1ns, padding them at the end with 0s if required so that their length is a multiple of 4ns. It also supports the modulation of the pulse both in hardware (default) or software. With no other pulses stored in the sequencer memory, it supports values up to range(1, 126) for regular pulses and range(1, 180) for flux pulses.

Parameters:
  • pulse (qibolab.pulses.Pulse) – The pulse to be swept.

  • values (list(int)) – The list of values to sweep the pulse duration with.

  • hardware_mod_en (bool) – If set to True the pulses are assumed to be modulated in hardware and their envelope waveforms are uploaded; if False, software modulated waveforms are uploaded.

Returns:

An array with the indices of the set of pulses. For each pulse duration in

values the i component is saved in the next avalable index, followed by the q component. For flux pulses, since both i and q components are equal, they are only saved once.

Return type:

idx_range (numpy.ndarray)

Raises:

NotEnoughMemory – If the memory needed to store the waveforms in more than the memory avalible.

class qibolab.instruments.qblox.sequencer.Sequencer(number: int)[source]#

Bases: object

A class to extend the functionality of qblox_instruments Sequencer.

A sequencer is a hardware component synthesised in the instrument FPGA, responsible for fetching waveforms from memory, pre-processing them, sending them to the DACs, and processing the acquisitions from the ADCs (QRM modules). https://qblox-qblox-instruments.readthedocs-hosted.com/en/master/documentation/sequencer.html

This class extends the sequencer functionality by holding additional data required when processing a pulse sequence:

  • the sequencer number,

  • the sequence of pulses to be played,

  • a buffer of unique waveforms, and

  • the four components of the sequence file:

    • waveforms dictionary

    • acquisition dictionary

    • weights dictionary

    • program

device#

A reference to the underlying qblox_instruments.qcodes_drivers.sequencer.Sequencer object. It can be used to access other features not directly exposed by this wrapper. https://qblox-qblox-instruments.readthedocs-hosted.com/en/master/documentation/sequencer.html

Type:

QbloxSequencer

number#

An integer between 0 and 5 that identifies the number of the sequencer.

Type:

int

pulses#

The sequence of pulses to be played by the sequencer.

Type:

PulseSequence

waveforms_buffer#

A buffer of unique waveforms to be played by the sequencer.

Type:

WaveformsBuffer

waveforms#

A dictionary containing the waveforms to be played by the sequencer in qblox format.

Type:

dict

acquisitions#

A dictionary containing the list of acquisitions to be made by the sequencer in qblox format.

Type:

dict

weights#

A dictionary containing the list of weights to be used by the sequencer when demodulating and integrating the response, in qblox format.

Type:

dict

program#

The pseudo assembly (q1asm) program to be executed by the sequencer. https://qblox-qblox-instruments.readthedocs-hosted.com/en/master/documentation/sequencer.html#instructions

Type:

str

qubit#

The id of the qubit associated with the sequencer, if there is only one.

Type:

str

qibolab.instruments.qblox.sweeper module#

class qibolab.instruments.qblox.sweeper.QbloxSweeperType(value)[source]#

Bases: Enum

An enumeration for the different types of sweepers supported by qblox.

  • frequency: sweeps pulse frequency by adjusting the sequencer nco_freq with q1asm command set_freq.

  • gain: sweeps sequencer gain by adjusting the sequencer gain_awg_path0 and gain_awg_path1 with q1asm command set_awg_gain. Since the gain is a parameter between -1 and 1 that multiplies the samples of the waveforms before they are fed to the DACs, it can be used to sweep the pulse amplitude.

  • offset: sweeps sequencer offset by adjusting the sequencer offset_awg_path0 and offset_awg_path1 with q1asm command set_awg_offs

  • start: sweeps pulse start.

  • duration: sweeps pulse duration.

frequency = 1#
gain = 2#
offset = 3#
start = 4#
duration = 5#
number = 6#
relative_phase = 7#
time = 8#
class qibolab.instruments.qblox.sweeper.QbloxSweeper(program: Program, rel_values: list, type: QbloxSweeperType = QbloxSweeperType.number, add_to: float = 0, multiply_to: float = 1, name: str = '')[source]#

Bases: object

A custom sweeper object with the data and functionality required by qblox instruments.

It is responsible for generating the q1asm code required to execute sweeps in a sequencer. The object can be initialised with either:

  • a qibolab.sweepers.Sweeper using the qibolab.instruments.qblox.QbloxSweeper.from_sweeper(), or

  • a range of values and a sweeper type (qibolab.instruments.qblox.QbloxSweeperType)

Like most FPGAs, qblox FPGAs do not support floating point arithmetics. All parameters that can be manipulated in real time within the FPGA are represented as two’s complement integers.

type#

the type of sweeper

Type:

qibolab.instruments.qblox.QbloxSweeperType

name#

a name given for the sweep that is later used within the q1asm code to identify the loops.

Type:

str

register#

the main Register (q1asm variable) used in the loop.

Type:

qibolab.instruments.qblox_q1asm.Register

aux_register#

an auxialiry Register requried in duration sweeps.

Type:

qibolab.instruments.qblox_q1asm.Register

update_parameters#

a flag to instruct the sweeper to update the paramters or not depending on whether a parameter of the sequencer needs to be swept or not.

Type:

Bool

block(inner_block

qibolab.instruments.qblox_q1asm.Block): generates the block of q1asm code that implements the sweep.

FREQUENCY_LIMIT = 500000000.0#
classmethod from_sweeper(program: Program, sweeper: Sweeper, add_to: float = 0, multiply_to: float = 1, name: str = '')[source]#

Creates an instance form a qibolab.sweepers.Sweeper object.

Parameters:
  • program (qibolab.instruments.qblox_q1asm.Program) – a program object representing the q1asm program of a sequencer.

  • sweeper (qibolab.sweepers.Sweeper) – the original qibolab sweeper. associated with the sweep. If no name is provided it uses the sweeper type as name.

  • add_to (float) – a value to be added to each value of the range of values defined in sweeper.values, rel_values.

  • multiply_to (float) – a value to be multiplied by each value of the range of values defined in sweeper.values, rel_values.

  • name (str) – a name given for the sweep that is later used within the q1asm code to identify the loops.

block(inner_block: Block)[source]#

Generates the block of q1asm code that implements the sweep.

The q1asm code for a sweeper has the following structure:

# header_block
# initialise register with start value
move    0, R0           # 0 = start value, R0 = register name
nop                     # wait an instruction cycle (4ns) for the register to be updated with its value
loop_R0:                # loop label

    # update_parameter_block
    # update parameters, in this case pulse frequency
    set_freq    R0      # sets the frequency of the sequencer nco to the value stored in R0
    upd_param   100     # makes the change effective and wait 100ns

    # inner block
    play 0,1,4          # play waveforms with index 0 and 1 (i and q) and wait 4ns

# footer_block
# increment or decrement register with step value
add R0, 2500, R0        # R0 = R0 + 2500
nop                     # wait an instruction cycle (4ns) for the register to be updated with its value
# check condition and loop
jlt R0, 10001, @loop_R0 # while R0 is less than the stop value loop to loop_R0
                        # in this example it would loop 5 times
                        # with R0 values of 0, 2500, 5000, 7500 and 10000
Parameters:

inner_block (qibolab.instruments.qblox_q1asm.Block) – the block of q1asm code to be repeated within the loop.