Platforms#
Qibolab provides support to different quantum laboratories.
Each lab is implemented using a custom Platform
class
which inherits the qibolab.platforms.abstract.AbstractPlatform
which implements basic features including how to connect to the platform,
how to start the instruments and how to run your model on the platform.
Therefore, the Platform
enables the user to interface with all
the required lab instruments at the same time with minimum effort.
Abstract platform#
- class qibolab.platforms.abstract.AbstractPlatform(name, runcard)#
Abstract platform for controlling quantum devices.
- Parameters:
name (str) – name of the platform.
runcard (str) – path to the yaml file containing the platform setup.
- abstract connect()#
Connects to instruments.
- abstract setup()#
Prepares instruments to execute experiments.
- abstract start()#
Starts all the instruments.
- abstract stop()#
Starts all the instruments.
- abstract disconnect()#
Disconnects to instruments.
- transpile(circuit: Circuit)#
Transforms a circuit to pulse sequence.
- Parameters:
circuit (qibo.models.Circuit) – Qibo circuit that respects the platform’s connectivity and native gates.
- Returns:
- Pulse sequence that implements the
circuit on the qubit.
- Return type:
sequence (qibolab.pulses.PulseSequence)
- abstract execute_pulse_sequence(sequence, nshots=1024, relaxation_time=None)#
Executes a pulse sequence.
- Parameters:
sequence (
qibolab.pulses.PulseSequence
) – Pulse sequence to execute.nshots (int) – Number of shots to sample from the experiment. Default is 1024.
relaxation_time (int) – Time to wait for the qubit to relax to its ground state between shots in ns. If
None
the default value provided asrepetition_duration
in the runcard will be used.
- Returns:
Readout results acquired by after execution.
- sweep(sequence, *sweepers, nshots=1024, average=True, relaxation_time=None)#
Executes a pulse sequence for different values of sweeped parameters. Useful for performing chip characterization.
Example
import numpy as np from qibolab.platform import Platform from qibolab.sweeper import Sweeper, Parameter from qibolab.pulses import PulseSequence platform = Platform("dummy") sequence = PulseSequence() parameter = Parameter.frequency pulse = platform.create_qubit_readout_pulse(qubit=0, start=0) sequence.add(pulse) parameter_range = np.random.randint(10, size=10) sweeper = Sweeper(parameter, parameter_range, [pulse]) platform.sweep(sequence, sweeper)
- Parameters:
sequence (
qibolab.pulses.PulseSequence
) – Pulse sequence to execute.sweepers (
qibolab.sweeper.Sweeper
) – Sweeper objects that specify which parameters are being sweeped.nshots (int) – Number of shots to sample from the experiment. Default is 1024.
relaxation_time (int) – Time to wait for the qubit to relax to its ground state between shots in ns. If
None
the default value provided asrepetition_duration
in the runcard will be used.average (bool) – If
True
the IQ results of individual shots are averaged on hardware.
- Returns:
Readout results acquired by after execution.
- set_attenuation(qubit, att)#
Set attenuation value. Usefeul for calibration routines such as punchout.
- Parameters:
qubit (int) – qubit whose attenuation will be modified.
att (int) – new value of the attenuation (dB).
- Returns:
None
- set_gain(qubit, gain)#
Set gain value. Usefeul for calibration routines such as Rabis.
- Parameters:
qubit (int) – qubit whose attenuation will be modified.
gain (int) – new value of the gain (dimensionless).
- Returns:
None
- set_bias(qubit, bias)#
Set bias value. Usefeul for calibration routines involving flux.
- Parameters:
qubit (int) – qubit whose attenuation will be modified.
bias (int) – new value of the bias (V).
- Returns:
None
QBloxPlatform#
ICPlatform#
- class qibolab.platforms.icplatform.ICPlatform(name, runcard)#
Platform for controlling quantum devices with IC.
Example
from qibolab import Platform platform = Platform("icarusq")
- execute_pulse_sequence(sequence, nshots=None)#
- Executes a pulse sequence. Pulses are being cached so that are not reuploaded
if they are the same as the ones sent previously. This greatly accelerates some characterization routines that recurrently use the same set of pulses, i.e. qubit and resonator spectroscopy, spin echo, and future circuits based on fixed gates.
- Parameters:
sequence (
qibolab.pulses.PulseSequence
) – Pulse sequence to execute.nshots (int) – Number of shots to sample from the experiment. If
None
the default value provided as hardware_avg in the calibration json will be used.
- Returns:
Readout results acquired by the assigned readout instrument after execution.
- fetch_instrument(name)#
Returns a reference to an instrument.
- fetch_qubit(qubit_id=0) Qubit #
Fetches the qubit based on the id.
- start_experiment()#
Starts the instrument to start the experiment sequence.
- fetch_qubit_pi_pulse(qubit_id=0) dict #
Fetches the qubit pi-pulse.
- fetch_qubit_readout_pulse(qubit_id=0) dict #
Fetches the qubit readout pulse.
Pulses#
In Qibolab we have a dedicated API to pulses and pulses sequence, which at the moment works for both qblox and FPGAs setups.
The main component of the API is the qibolab.pulses.Pulse
object,
which enables the user to code a pulse with specific parameters. We provide
also a special object for the ReadoutPulse
given its importance when dealing
with a quantum hardware. Moreover, we supports different kinds of Pulse shape.
The qibolab.circuit.PulseSequence
class enables to combine different pulses
into a sequence through the add
method.
Basic Pulse#
- class qibolab.pulses.Pulse(start, duration, amplitude, frequency, relative_phase, shape, channel, type=PulseType.DRIVE, qubit=0)#
A class to represent a pulse to be sent to the QPU.
- Parameters:
start (int | intSymbolicExpression) – Start time of pulse in ns.
duration (int | intSymbolicExpression) – Pulse duration in ns.
amplitude (float) – Pulse digital amplitude (unitless) [-1 to 1].
frequency (int) – Pulse Intermediate Frequency in Hz [10e6 to 300e6].
relative_phase (float) – To be added.
shape – (PulseShape | str): {‘Rectangular()’, ‘Gaussian(rel_sigma)’, ‘DRAG(rel_sigma, beta)’} Pulse shape. See
qibolab.pulses
for list of available shapes.channel (int | str) – the channel on which the pulse should be synthesised.
type (PulseType | str) – {‘ro’, ‘qd’, ‘qf’} type of pulse {ReadOut, Qubit Drive, Qubit Flux}
qubit (int) – qubit associated with the pulse
Example
from qibolab.pulses import Pulse, Gaussian # define Gaussian drive pulse drive_pulse = Pulse(start=0, duration=60, amplitude=0.3, frequency=-200_000_000, relative_phase=0.0, shape=Gaussian(5), channel=1, type=PulseType.DRIVE, qubit=0) # define Rectangular readout pulse readout_pulse = Pulse(start=intSymbolicExpression(60), duration=2000, amplitude=0.3, frequency=20_000_000, relative_phase=0.0, shape=Rectangular(), channel=2, type=PulseType.READOUT, qubit=0)
- property start: int#
Returns the time when the pulse is scheduled to be played, in ns.
- property duration: int#
Returns the duration of the pulse, in ns.
- property finish: int#
Returns the time when the pulse is scheduled to finish.
Calculated as pulse.start - pulse finish.
- property se_start: intSymbolicExpression#
Returns a symbolic expression for the pulse start.
- property se_duration: intSymbolicExpression#
Returns a symbolic expression for the pulse duration.
- property se_finish: intSymbolicExpression#
Returns a symbolic expression for the pulse finish.
- property amplitude: float#
Returns the amplitude of the pulse.
Pulse amplitudes are normalised between -1 and 1.
- property frequency: int#
Returns the frequency of the pulse, in Hz.
- property global_phase#
Returns the global phase of the pulse, in radians.
This phase is calculated from the pulse start time and frequency as 2 * pi * frequency * start.
- property relative_phase: float#
Returns the relative phase of the pulse, in radians.
- property phase: float#
Returns the total phase of the pulse, in radians.
The total phase is computed as the sum of the global and relative phases.
- property shape: PulseShape#
Returns the shape of the pulse, as a PulseShape object.
- property channel#
Returns the channel on which the pulse should be played.
When a sequence of pulses is sent to the platform for execution, each pulse is sent to the instrument responsible for playing pulses the pulse channel. The connection of instruments with channels is defined in the platform runcard.
- property type: PulseType#
Returns the pulse type, as an element of PulseType enumeration.
- property qubit#
Returns the qubit addressed by the pulse.
- property serial: str#
Returns a string representation of the pulse.
- property envelope_waveform_i: Waveform#
The envelope waveform of the i component of the pulse.
- property envelope_waveform_q: Waveform#
The envelope waveform of the q component of the pulse.
- property envelope_waveforms#
A tuple with the i and q envelope waveforms of the pulse.
- property modulated_waveform_i: Waveform#
The waveform of the i component of the pulse, modulated with its frequency.
- property modulated_waveform_q: Waveform#
The waveform of the q component of the pulse, modulated with its frequency.
- property modulated_waveforms#
A tuple with the i and q waveforms of the pulse, modulated with its frequency.
- copy()#
Returns a new Pulse object with the same attributes.
- plot(savefig_filename=None)#
Plots the pulse envelope and modulated waveforms.
- Parameters:
savefig_filename (str) – a file path. If provided the plot is save to a file.
Readout Pulse#
- class qibolab.pulses.ReadoutPulse(start, duration, amplitude, frequency, relative_phase, shape, channel, qubit=0)#
Bases:
Pulse
Describes a readout pulse.
See
qibolab.pulses.Pulse
for argument desciption.- property serial#
Returns a string representation of the pulse.
- property global_phase#
Returns the global phase of the pulse, in radians.
This phase is calculated from the pulse start time and frequency as 2 * pi * frequency * start.
Pulse Sequence#
Pulse shape#
Rectangular#
Gaussian#
Drag#
SWIPHT#
Data structures and sweeping#
- class qibolab.platforms.abstract.Qubit(name: str, readout_frequency: int = 0, drive_frequency: int = 0, sweetspot: float = 0, peak_voltage: float = 0, pi_pulse_amplitude: float = 0, T1: int = 0, T2: int = 0, state0_voltage: int = 0, state1_voltage: int = 0, mean_gnd_states: complex = 0j, mean_exc_states: complex = 0j, resonator_polycoef_flux: ~typing.List[float] = <factory>, filter: dict = <factory>, threshold: float | None = None, iq_angle: float = 0.0, rotation_angle: float = 0.0, mixer_drive_g: float = 0.0, mixer_drive_phi: float = 0.0, mixer_readout_g: float = 0.0, mixer_readout_phi: float = 0.0, readout: ~qibolab.designs.channels.Channel | None = None, feedback: ~qibolab.designs.channels.Channel | None = None, twpa: ~qibolab.designs.channels.Channel | None = None, drive: ~qibolab.designs.channels.Channel | None = None, flux: ~qibolab.designs.channels.Channel | None = None)#
Representation of a physical qubit.
Qubit objects are instantiated by
qibolab.platforms.platform.Platform
but they are passed to instrument designs in order to play pulses.- Parameters:
name (int, str) – Qubit number or name.
readout (
qibolab.platforms.utils.Channel
) – Channel used to readout pulses to the qubit.feedback (
qibolab.platforms.utils.Channel
) – Channel used to get readout feedback from the qubit.drive (
qibolab.platforms.utils.Channel
) – Channel used to send drive pulses to the qubit.flux (
qibolab.platforms.utils.Channel
) – Channel used to send flux pulses to the qubit.qubit (Other characterization parameters for the) –
runcard. (loaded from the) –
- class qibolab.result.ExecutionResults(array: dtype[dtype([('i', '<f8'), ('q', '<f8')])]], shots: ndarray[Any, dtype[uint32]] | None = None)#
Data structure to deal with the output of
qibolab.platforms.abstract.AbstractPlatform.execute_pulse_sequence()
- property measurement#
Resonator signal voltage mesurement (MSR) in volts.
- property phase#
Computes phase value.
- property ground_state_probability#
Computes ground state probability
- to_dict_probability(state=1)#
Serialize probabilities in dict. :param state: if 0 stores the probabilities of finding
the ground state. If 1 stores the probabilities of finding the excited state.
- compute_average()#
Perform average over i and q
- to_dict(average=True)#
Serialize output in dict. :param average: If True returns a dictionary of the form
{‘MSR[V]’ : v, ‘i[V]’ : i, ‘q[V]’ : q, ‘phase[rad]’ : phase}. Where each value is averaged over the number shots. If False all the values for each shot are saved.
- class qibolab.result.AveragedResults(i: ndarray[Any, dtype[float64]], q: ndarray[Any, dtype[float64]])#
Data structure containing averages of
ExecutionResults
.- to_dict()#
Serialize output in dict
- class qibolab.sweeper.Sweeper(parameter: Parameter, values: ndarray[Any, dtype[ScalarType]], pulses: list | None = None, qubits: list | None = None)#
Data structure for Sweeper object.
This object is passed as an argument to the method
qibolab.platforms.abstract.AbstractPlatform.sweep()
which enables the user to sweep a specific parameter for one or more pulses. For information on how to perform sweeps seeqibolab.platforms.abstract.AbstractPlatform.sweep()
.Example
import numpy as np from qibolab.platform import Platform from qibolab.sweeper import Sweeper, Parameter from qibolab.pulses import PulseSequence platform = Platform("dummy") sequence = PulseSequence() parameter = Parameter.frequency pulse = platform.create_qubit_readout_pulse(qubit=0, start=0) sequence.add(pulse) parameter_range = np.random.randint(10, size=10) sweeper = Sweeper(parameter, parameter_range, [pulse]) platform.sweep(sequence, sweeper)
- Parameters:
parameter (qibolab.sweeper.Parameter) – parameter to be swept, possible choices are frequency, attenuation, amplitude, current and gain.
values (np.ndarray) – sweep range. If the parameter is frequency the sweep will be a shift around the readout frequency in case of a ReadoutPulse or around the drive frequency for a generic Pulse. If the parameter is amplitude the range is normalized with the current amplitude of the pulse. For other parameters the sweep will be performed directly over the range specified.
pulses (list) – list of qibolab.pulses.Pulse to be swept (optional).
qubits (list) – list of qibolab.platforms.abstract.Qubit to be swept (optional).
Instruments supported#
Qibolab currently supports different instruments including local oscillators, qblox and FPGAs.
Qblox#
GenericPulsar#
PulsarQCM#
PulsarQRM#
QuicSyn#
RohdeSchwarz SGS100A#
Tektronix AWG5204#
- class qibolab.instruments.icarusq.TektronixAWG5204(name, address)#
- generate_waveforms_from_pulse(pulse: Pulse, time_array: ndarray)#
Generates a numpy array based on the pulse parameters
- Parameters:
pulse (qibolab.pulses.Pulse | qibolab.pulses.ReadoutPulse) – Pulse to be compiled
time_array (numpy.ndarray) – Array corresponding to the global time
- translate(sequence: List[Pulse], nshots=None)#
Translates the pulse sequence into a numpy array.
- Parameters:
sequence (qibolab.pulses.Pulse[]) – Array containing pulses to be fired on this instrument.
nshots (int) – Number of repetitions.
- upload(waveform: ndarray)#
Uploads a nchannels X nsamples array to the AWG, load it into memory and assign it to the channels for playback.
MiniCircuit RCDAT-8000-30#
FPGA#
ATS9371#
- class qibolab.instruments.icarusq.AlazarADC(name, address)#
Driver for the AlazarTech ATS9371 ADC.
- setup(trigger_volts, **kwargs)#
Sets the frequency in Hz
- play_sequence_and_acquire()#
this method performs an acquisition, which is the get_cmd for the acquisiion parameter of this instrument :return:
- process_result(readout_frequency=100000000.0, readout_channels=[0, 1])#
Returns the processed signal result from the ADC.
- Parameters:
readout_frequency (float) – Frequency to be used for signal processing.
readout_channels (int[]) – Channels to be used for signal processing.
- Returns:
Amplitude of the processed signal. phase (float): Phase shift of the processed signal in degrees. it (float): I component of the processed signal. qt (float): Q component of the processed signal.
- Return type:
ampl (float)
- start()#
Starts the instrument.
- stop()#
Stops the instrument.