qibolab package#

qibolab.get_platforms_path()[source]#

Get path to repository containing the platforms.

Path is specified using the environment variable QIBOLAB_PLATFORMS.

qibolab.create_platform(name) Platform[source]#

A platform for executing quantum algorithms.

It consists of a quantum processor QPU and a set of controlling instruments.

Parameters:
  • name (str) – name of the platform. Options are ‘tiiq’, ‘qili’ and ‘icarusq’.

  • path (pathlib.Path) – path with platform serialization

Returns:

The plaform class.

qibolab.execute_qasm(circuit: str, platform, initial_state=None, nshots=1000)[source]#

Executes a QASM circuit.

Parameters:
  • circuit (str) – the QASM circuit.

  • platform (str) – the platform where to execute the circuit.

  • initial_state (qibo.models.circuit.Circuit) – Circuit to prepare the initial state. If None the default |00...0> state is used.

  • nshots (int) – Number of shots to sample from the experiment.

Returns:

MeasurementOutcomes object containing the results acquired from the execution.

qibolab.get_available_platforms() list[str][source]#

Returns the platforms found in the $QIBOLAB_PLATFORMS directory.

class qibolab.MetaBackend[source]#

Bases: object

Meta-backend class which takes care of loading the qibolab backend.

static load(platform: str)[source]#

Loads the backend.

Parameters:

platform (str) – Name of the platform to load.

Returns:

The loaded backend.

Return type:

qibo.backends.abstract.Backend

list_available() dict[source]#

Lists all the available qibolab platforms.

Subpackages#

Submodules#

qibolab.backends module#

class qibolab.backends.QibolabBackend(platform)[source]#

Bases: NumpyBackend

apply_gate(gate, state, nqubits)[source]#

Apply a gate to state vector.

apply_gate_density_matrix(gate, state, nqubits)[source]#

Apply a gate to density matrix.

assign_measurements(measurement_map, readout)[source]#

Assigning measurement outcomes to qibo.states.MeasurementResult for each gate.

This allows properly obtaining the measured shots from the qibolab.pulses.ReadoutPulse object obtaned after pulse sequence execution.

Parameters:
  • measurement_map (dict) – Map from each measurement gate to the sequence of readout pulses implementing it.

  • readout (qibolab.pulses.ReadoutPulse) – Readout result object containing the readout measurement shots. This is created in execute_circuit.

execute_circuit(circuit, initial_state=None, nshots=1000)[source]#

Executes a quantum circuit.

Parameters:
  • circuit (qibo.models.circuit.Circuit) – Circuit to execute.

  • initial_state (qibo.models.circuit.Circuit) – Circuit to prepare the initial state. If None the default |00...0> state is used.

  • nshots (int) – Number of shots to sample from the experiment.

Returns:

MeasurementOutcomes object containing the results acquired from the execution.

execute_circuits(circuits, initial_states=None, nshots=1000)[source]#

Executes multiple quantum circuits with a single communication with the control electronics.

Circuits are unrolled to a single pulse sequence.

Parameters:
  • circuits (list) – List of circuits to execute.

  • initial_states (qibo.models.circuit.Circuit) – Circuit to prepare the initial state. If None the default |00...0> state is used.

  • nshots (int) – Number of shots to sample from the experiment.

Returns:

List of MeasurementOutcomes objects containing the results acquired from the execution of each circuit.

qibolab.channels module#

qibolab.channels.check_max_offset(offset, max_offset)[source]#

Checks if a given offset value exceeds the maximum supported offset.

This is to avoid sending high currents that could damage lab equipment such as amplifiers.

class qibolab.channels.Channel(name: str, port: Port | None = None, local_oscillator: LocalOscillator | None = None, max_offset: float | None = None)[source]#

Bases: object

Representation of physical wire connection (channel).

name: str#

Name of the channel from the lab schematics.

port: Port | None = None#

Instrument port that is connected to this channel.

local_oscillator: LocalOscillator | None = None#

Instrument object controlling the local oscillator connected to this channel.

Not applicable for setups that do not use external local oscillators because the controller can send sufficiently high frequencies or contains internal local oscillators.

max_offset: float | None = None#

Maximum DC voltage that we can safely send through this channel.

Sending high voltages for prolonged times may damage amplifiers or other lab equipment. If the user attempts to send a higher value an error will be raised to prevent execution in real instruments.

property offset#

DC offset that is applied to this port.

property lo_frequency#
property lo_power#
property gain#
property attenuation#
property power_range#
property filter#
class qibolab.channels.ChannelMap(_channels: ~typing.Dict[str, ~qibolab.channels.Channel] = <factory>)[source]#

Bases: object

Collection of qibolab.designs.channel.Channel objects identified by name.

Essentially, it allows creating a mapping of names to channels just specifying the names.

add(*items)[source]#

Add multiple items to the channel map.

If :class: qibolab.channels.Channel objects are given they are dded to the channel map. If a different type is given, a :class: qibolab.channels.Channel with the corresponding name is created and added to the channel map.

qibolab.couplers module#

qibolab.couplers.QubitId#

Type for Coupler names.

alias of Union[str, int]

class qibolab.couplers.Coupler(name: str | int, sweetspot: float = 0, native_pulse: ~qibolab.native.CouplerNatives = <factory>, _flux: ~qibolab.channels.Channel | None = None, qubits: ~typing.Dict = <factory>)[source]#

Bases: object

Representation of a physical coupler.

Coupler objects are instantiated by :class: qibolab.platforms.platform.Platform and are passed to instruments to play pulses on them.

name: str | int#

Coupler number or name.

sweetspot: float = 0#

Coupler sweetspot to center it’s flux dependence if needed.

native_pulse: CouplerNatives#

For now this only contains the calibrated pulse to activate the coupler.

qubits: Dict#

Qubits the coupler acts on

property flux#
property channels#

qibolab.execution_parameters module#

class qibolab.execution_parameters.AcquisitionType(value)[source]#

Bases: Enum

Data acquisition from hardware.

DISCRIMINATION = 1#

Demodulate, integrate the waveform and discriminate among states based on the voltages.

INTEGRATION = 2#

Demodulate and integrate the waveform.

RAW = 3#

Acquire the waveform as it is.

SPECTROSCOPY = 4#

Zurich Integration mode for RO frequency sweeps.

class qibolab.execution_parameters.AveragingMode(value)[source]#

Bases: Enum

Data averaging modes from hardware.

CYCLIC = 1#

Better averaging for short timescale noise.

SINGLESHOT = 2#

No averaging.

Type:

SINGLESHOT

SEQUENTIAL = 3#

Worse averaging for noise[Avoid]

Type:

SEQUENTIAL

class qibolab.execution_parameters.ExecutionParameters(nshots: int | None = None, relaxation_time: int | None = None, fast_reset: bool = False, acquisition_type: AcquisitionType = AcquisitionType.DISCRIMINATION, averaging_mode: AveragingMode = AveragingMode.SINGLESHOT)[source]#

Bases: object

Data structure to deal with execution parameters.

nshots: int | None = None#

Number of shots to sample from the experiment.

Default is the runcard value.

relaxation_time: int | None = None#

Time to wait for the qubit to relax to its ground Sample between shots in ns.

Default is the runcard value.

fast_reset: bool = False#

Enable or disable fast reset.

acquisition_type: AcquisitionType = 1#

Data acquisition type.

averaging_mode: AveragingMode = 2#

Data averaging mode.

property results_type#

Returns corresponding results class.

qibolab.kernels module#

class qibolab.kernels.Kernels[source]#

Bases: dict[Union[str, int], ndarray]

A dictionary subclass for handling Qubit Kernels.

This class extends the built-in dict class and maps QubitId to numpy arrays. It provides methods to load and dump the kernels from and to a file.

classmethod load(path: Path)[source]#

Class method to load kernels from a file.

The file should contain a serialized dictionary where keys are serialized QubitId and values are numpy arrays.

dump(path: Path)[source]#

Instance method to dump the kernels to a file.

The keys (QubitId) are serialized to strings and the values (numpy arrays) are kept as is.

qibolab.native module#

class qibolab.native.NativePulse(name: str, duration: int, amplitude: float, shape: str, pulse_type: PulseType, qubit: qubits.Qubit, frequency: int = 0, relative_start: int = 0, if_frequency: int | None = None, start: int = 0, phase: float = 0.0)[source]#

Bases: object

Container with parameters required to generate a pulse implementing a native gate.

name: str#

Name of the gate that the pulse implements.

duration: int#
amplitude: float#
shape: str#
pulse_type: PulseType#
qubit: qubits.Qubit#
frequency: int = 0#
relative_start: int = 0#

Relative start is relevant for two-qubit gate operations which correspond to a pulse sequence.

if_frequency: int | None = None#
start: int = 0#
phase: float = 0.0#
classmethod from_dict(name, pulse, qubit)[source]#

Parse the dictionary provided by the runcard.

Parameters:
  • name (str) – Name of the native gate (dictionary key).

  • pulse (dict) – Dictionary containing the parameters of the pulse implementing the gate, as loaded from the runcard.

  • qubits (qibolab.platforms.abstract.Qubit) – Qubit that the pulse is acting on

property raw#
pulse(start, relative_phase=0.0)[source]#

Construct the qibolab.pulses.Pulse object implementing the gate.

Parameters:
  • start (int) – Start time of the pulse in the sequence.

  • relative_phase (float) – Relative phase of the pulse.

Returns:

A qibolab.pulses.DrivePulse or qibolab.pulses.DrivePulse or qibolab.pulses.FluxPulse with the pulse parameters of the gate.

class qibolab.native.VirtualZPulse(phase: float, qubit: qubits.Qubit)[source]#

Bases: object

Container with parameters required to add a virtual Z phase in a pulse sequence.

phase: float#
qubit: qubits.Qubit#
property raw#
class qibolab.native.CouplerPulse(duration: int, amplitude: float, shape: str, coupler: couplers.Coupler, relative_start: int = 0)[source]#

Bases: object

Container with parameters required to add a coupler pulse in a pulse sequence.

duration: int#
amplitude: float#
shape: str#
coupler: couplers.Coupler#
relative_start: int = 0#
classmethod from_dict(pulse, coupler)[source]#

Parse the dictionary provided by the runcard.

Parameters:
  • name (str) – Name of the native gate (dictionary key).

  • pulse (dict) – Dictionary containing the parameters of the pulse implementing the gate, as loaded from the runcard.

  • coupler (qibolab.platforms.abstract.Coupler) – Coupler that the pulse is acting on

property raw#
pulse(start)[source]#

Construct the qibolab.pulses.Pulse object implementing the gate.

Parameters:

start (int) – Start time of the pulse in the sequence.

Returns:

A qibolab.pulses.FluxPulse with the pulse parameters of the gate.

class qibolab.native.NativeSequence(name: str, pulses: ~typing.List[~qibolab.native.NativePulse | ~qibolab.native.VirtualZPulse] = <factory>, coupler_pulses: ~typing.List[~qibolab.native.CouplerPulse] = <factory>)[source]#

Bases: object

List of qibolab.platforms.native.NativePulse objects implementing a gate.

Relevant for two-qubit gates, which usually require a sequence of pulses to be implemented. These pulses may act on qubits different than the qubits the gate is targeting.

name: str#
pulses: List[NativePulse | VirtualZPulse]#
coupler_pulses: List[CouplerPulse]#
classmethod from_dict(name, sequence, qubits, couplers)[source]#

Constructs the native sequence from the dictionaries provided in the runcard.

Parameters:
  • name (str) – Name of the gate the sequence is applying.

  • sequence (dict) – Dictionary describing the sequence as provided in the runcard.

  • qubits (list) – List of qibolab.qubits.Qubit object for all qubits in the platform. All qubits are required because the sequence may be acting on qubits that the implemented gate is not targeting.

  • couplers (list) – List of qibolab.couplers.Coupler object for all couplers in the platform. All couplers are required because the sequence may be acting on couplers that the implemented gate is not targeting.

property raw#
sequence(start=0)[source]#

Creates a qibolab.pulses.PulseSequence object implementing the sequence.

class qibolab.native.SingleQubitNatives(RX: NativePulse | None = None, RX12: NativePulse | None = None, MZ: NativePulse | None = None)[source]#

Bases: object

Container with the native single-qubit gates acting on a specific qubit.

RX: NativePulse | None = None#

Pulse to drive the qubit from state 0 to state 1.

RX12: NativePulse | None = None#

Pulse to drive to qubit from state 1 to state 2.

MZ: NativePulse | None = None#

Measurement pulse.

property RX90: NativePulse#

RX90 native pulse is inferred from RX by halving its amplitude.

classmethod from_dict(qubit, native_gates)[source]#

Parse native gates of the qubit from the runcard.

Parameters:
  • qubit (qibolab.qubits.Qubit) – Qubit object that the native gates are acting on.

  • native_gates (dict) – Dictionary with native gate pulse parameters as loaded from the runcard.

property raw#

Serialize native gate pulses.

None gates are not included.

class qibolab.native.CouplerNatives(CP: NativePulse | None = None)[source]#

Bases: object

Container with the native single-qubit gates acting on a specific qubit.

CP: NativePulse | None = None#

Pulse to activate the coupler.

classmethod from_dict(coupler, native_gates)[source]#

Parse coupler native gates from the runcard.

Parameters:
  • coupler (qibolab.couplers.Coupler) – Coupler object that the native pulses are acting on.

  • native_gates (dict) – Dictionary with native gate pulse parameters as loaded from the runcard [Reusing the dict from qubits].

property raw#

Serialize native gate pulses.

None gates are not included.

class qibolab.native.TwoQubitNatives(CZ: NativeSequence | None = None, CNOT: NativeSequence | None = None, iSWAP: NativeSequence | None = None)[source]#

Bases: object

Container with the native two-qubit gates acting on a specific pair of qubits.

CZ: NativeSequence | None = None#
CNOT: NativeSequence | None = None#
iSWAP: NativeSequence | None = None#
property symmetric#

Check if the defined two-qubit gates are symmetric between target and control qubits.

classmethod from_dict(qubits, couplers, native_gates)[source]#
property raw#

qibolab.platform module#

A platform for executing quantum algorithms.

qibolab.platform.unroll_sequences(sequences: List[PulseSequence], relaxation_time: int) Tuple[PulseSequence, Dict[str, str]][source]#

Unrolls a list of pulse sequences to a single pulse sequence with multiple measurements.

Parameters:
  • sequences (list) – List of pulse sequences to unroll.

  • relaxation_time (int) – Time in ns to wait for the qubit to relax between playing different sequences.

Returns:

Unrolled pulse sequence containing

multiple measurements.

readout_map (dict): Map from original readout pulse serials to the unrolled readout pulse

serials. Required to construct the results dictionary that is returned after execution.

Return type:

total_sequence (qibolab.pulses.PulseSequence)

class qibolab.platform.Settings(nshots: int = 1024, relaxation_time: int = 100000)[source]#

Bases: object

Default execution settings read from the runcard.

nshots: int = 1024#

Default number of repetitions when executing a pulse sequence.

relaxation_time: int = 100000#

Time in ns to wait for the qubit to relax to its ground state between shots.

fill(options: ExecutionParameters)[source]#

Use default values for missing execution options.

class qibolab.platform.Platform(name: str, qubits: ~typing.Dict[str | int, ~qibolab.qubits.Qubit], pairs: ~typing.Dict[~typing.Tuple[str | int, str | int], ~qibolab.qubits.QubitPair], instruments: ~typing.Dict[str, ~qibolab.instruments.abstract.Instrument], settings: ~qibolab.platform.Settings = <factory>, resonator_type: str | None = None, couplers: ~typing.Dict[str | int, ~qibolab.couplers.Coupler] = <factory>, is_connected: bool = False, topology: ~networkx.classes.graph.Graph = <factory>)[source]#

Bases: object

Platform for controlling quantum devices.

name: str#

Name of the platform.

qubits: Dict[str | int, Qubit]#

Dictionary mapping qubit names to qibolab.qubits.Qubit objects.

pairs: Dict[Tuple[str | int, str | int], QubitPair]#

Dictionary mapping tuples of qubit names to qibolab.qubits.QubitPair objects.

instruments: Dict[str, Instrument]#

Dictionary mapping instrument names to qibolab.instruments.abstract.Instrument objects.

settings: Settings#

Container with default execution settings.

resonator_type: str | None = None#

Type of resonator (2D or 3D) in the used QPU.

Default is 3D for single-qubit chips and 2D for multi-qubit.

couplers: Dict[str | int, Coupler]#

Dictionary mapping coupler names to qibolab.couplers.Coupler objects.

is_connected: bool = False#

Flag for whether we are connected to the physical instruments.

topology: Graph#

Graph representing the qubit connectivity in the quantum chip.

property nqubits: int#

Total number of usable qubits in the QPU.

property ordered_pairs#

List of qubit pairs that are connected in the QPU.

property sampling_rate#

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

connect()[source]#

Connect to all instruments.

disconnect()[source]#

Disconnects from instruments.

execute_pulse_sequence(sequence: PulseSequence, options: ExecutionParameters, **kwargs)[source]#
Parameters:
  • sequence (qibolab.pulses.PulseSequence) – Pulse sequences to execute.

  • options (qibolab.platforms.platform.ExecutionParameters) – Object holding the execution options.

  • **kwargs – May need them for something

Returns:

Readout results acquired by after execution.

execute_pulse_sequences(sequences: List[PulseSequence], options: ExecutionParameters, **kwargs)[source]#
Parameters:
  • sequence (List[qibolab.pulses.PulseSequence]) – Pulse sequences to execute.

  • options (qibolab.platforms.platform.ExecutionParameters) – Object holding the execution options.

  • **kwargs – May need them for something

Returns:

Readout results acquired by after execution.

sweep(sequence: PulseSequence, options: ExecutionParameters, *sweepers: Sweeper)[source]#

Executes a pulse sequence for different values of sweeped parameters.

Useful for performing chip characterization.

Example

import numpy as np
from qibolab.dummy import create_dummy
from qibolab.sweeper import Sweeper, Parameter
from qibolab.pulses import PulseSequence
from qibolab.execution_parameters import ExecutionParameters


platform = create_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, ExecutionParameters(), sweeper)
Returns:

Readout results acquired by after execution.

get_qubit(qubit)[source]#

Return the name of the physical qubit corresponding to a logical qubit.

Temporary fix for the compiler to work for platforms where the qubits are not named as 0, 1, 2, …

get_coupler(coupler)[source]#

Return the name of the physical coupler corresponding to a logical coupler.

Temporary fix for the compiler to work for platforms where the couplers are not named as 0, 1, 2, …

create_RX90_pulse(qubit, start=0, relative_phase=0)[source]#
create_RX_pulse(qubit, start=0, relative_phase=0)[source]#
create_RX12_pulse(qubit, start=0, relative_phase=0)[source]#
create_CZ_pulse_sequence(qubits, start=0)[source]#
create_iSWAP_pulse_sequence(qubits, start=0)[source]#
create_CNOT_pulse_sequence(qubits, start=0)[source]#
create_MZ_pulse(qubit, start)[source]#
create_qubit_drive_pulse(qubit, start, duration, relative_phase=0)[source]#
create_qubit_readout_pulse(qubit, start)[source]#
create_qubit_flux_pulse(qubit, start, duration, amplitude=1)[source]#
create_coupler_pulse(coupler, start, duration=None, amplitude=None)[source]#
create_RX90_drag_pulse(qubit, start, beta, relative_phase=0)[source]#

Create native RX90 pulse with Drag shape.

create_RX_drag_pulse(qubit, start, beta, relative_phase=0)[source]#

Create native RX pulse with Drag shape.

qibolab.pulses module#

Pulse and PulseSequence classes.

qibolab.pulses.SAMPLING_RATE = 1#

Default sampling rate in gigasamples per second (GSps).

Used for generating waveform envelopes if the instruments do not provide a different value.

class qibolab.pulses.PulseType(value)[source]#

Bases: Enum

An enumeration to distinguish different types of pulses.

READOUT pulses triger acquisitions. DRIVE pulses are used to control qubit states. FLUX pulses are used to shift the frequency of flux tunable qubits and with it implement two-qubit gates.

READOUT = 'ro'#
DRIVE = 'qd'#
FLUX = 'qf'#
COUPLERFLUX = 'cf'#
class qibolab.pulses.Waveform(data)[source]#

Bases: object

A class to save pulse waveforms.

A waveform is a list of samples, or discrete data points, used by the digital to analogue converters (DACs) to synthesise pulses.

data#

a numpy array containing the samples.

Type:

np.ndarray

serial#

a string that can be used as a lable to identify the waveform. It is not automatically generated, it must be set by the user.

Type:

str

DECIMALS = 5#
plot(savefig_filename=None)[source]#

Plots the waveform.

Parameters:

savefig_filename (str) – a file path. If provided the plot is save to a file.

exception qibolab.pulses.ShapeInitError(msg=None, *args)[source]#

Bases: RuntimeError

Error raised when a pulse has not been fully defined.

default_msg = 'PulseShape attribute pulse must be initialised in order to be able to generate pulse waveforms'#
class qibolab.pulses.PulseShape[source]#

Bases: ABC

Abstract class for pulse shapes.

This object is responsible for generating envelope and modulated waveforms from a set of pulse parameters and its type. Generates both i (in-phase) and q (quadrature) components.

pulse = None#

the pulse associated with it.

Its parameters are used to generate pulse waveforms.

Type:

Pulse (Pulse)

abstract envelope_waveform_i(sampling_rate=1) Waveform[source]#
abstract envelope_waveform_q(sampling_rate=1) Waveform[source]#
envelope_waveforms(sampling_rate=1)[source]#

A tuple with the i and q envelope waveforms of the pulse.

modulated_waveform_i(sampling_rate=1) Waveform[source]#

The waveform of the i component of the pulse, modulated with its frequency.

modulated_waveform_q(sampling_rate=1) Waveform[source]#

The waveform of the q component of the pulse, modulated with its frequency.

modulated_waveforms(sampling_rate=1)[source]#

A tuple with the i and q waveforms of the pulse, modulated with its frequency.

static eval(value: str) PulseShape[source]#

Deserialize string representation.

class qibolab.pulses.Rectangular[source]#

Bases: PulseShape

Rectangular pulse shape.

envelope_waveform_i(sampling_rate=1) Waveform[source]#

The envelope waveform of the i component of the pulse.

envelope_waveform_q(sampling_rate=1) Waveform[source]#

The envelope waveform of the q component of the pulse.

class qibolab.pulses.Exponential(tau: float, upsilon: float, g: float = 0.1)[source]#

Bases: PulseShape

Exponential pulse shape (Square pulse with an exponential decay).

Parameters:
  • tau (float) – Parameter that controls the decay of the first exponential function

  • upsilon (float) – Parameter that controls the decay of the second exponential function

  • g (float) – Parameter that weights the second exponential function

\[A\frac{\exp\left(-\frac{x}{\text{upsilon}}\right) + g \exp\left(-\frac{x}{\text{tau}}\right)}{1 + g}\]
envelope_waveform_i(sampling_rate=1) Waveform[source]#

The envelope waveform of the i component of the pulse.

envelope_waveform_q(sampling_rate=1) Waveform[source]#

The envelope waveform of the q component of the pulse.

class qibolab.pulses.Gaussian(rel_sigma: float)[source]#

Bases: PulseShape

Gaussian pulse shape.

Parameters:

rel_sigma (float) – relative sigma so that the pulse standard deviation (sigma) = duration / rel_sigma

\[A\exp^{-\frac{1}{2}\frac{(t-\mu)^2}{\sigma^2}}\]
envelope_waveform_i(sampling_rate=1) Waveform[source]#

The envelope waveform of the i component of the pulse.

envelope_waveform_q(sampling_rate=1) Waveform[source]#

The envelope waveform of the q component of the pulse.

class qibolab.pulses.GaussianSquare(rel_sigma: float, width: float)[source]#

Bases: PulseShape

GaussianSquare pulse shape.

Parameters:
  • rel_sigma (float) – relative sigma so that the pulse standard deviation (sigma) = duration / rel_sigma

  • width (float) – Percentage of the pulse that is flat

\[A\exp^{-\frac{1}{2}\frac{(t-\mu)^2}{\sigma^2}}[Rise] + Flat + A\exp^{-\frac{1}{2}\frac{(t-\mu)^2}{\sigma^2}}[Decay]\]
envelope_waveform_i(sampling_rate=1) Waveform[source]#

The envelope waveform of the i component of the pulse.

envelope_waveform_q(sampling_rate=1) Waveform[source]#

The envelope waveform of the q component of the pulse.

class qibolab.pulses.Drag(rel_sigma, beta)[source]#

Bases: PulseShape

Derivative Removal by Adiabatic Gate (DRAG) pulse shape.

Parameters:
  • rel_sigma (float) – relative sigma so that the pulse standard deviation (sigma) = duration / rel_sigma

  • beta (float) – relative sigma so that the pulse standard deviation (sigma) = duration / rel_sigma

\[\]
envelope_waveform_i(sampling_rate=1) Waveform[source]#

The envelope waveform of the i component of the pulse.

envelope_waveform_q(sampling_rate=1) Waveform[source]#

The envelope waveform of the q component of the pulse.

class qibolab.pulses.IIR(b, a, target: PulseShape)[source]#

Bases: PulseShape

IIR Filter using scipy.signal lfilter.

property pulse#
envelope_waveform_i(sampling_rate=1) Waveform[source]#

The envelope waveform of the i component of the pulse.

envelope_waveform_q(sampling_rate=1) Waveform[source]#

The envelope waveform of the q component of the pulse.

class qibolab.pulses.SNZ(t_idling, b_amplitude=None)[source]#

Bases: PulseShape

Sudden variant Net Zero.

https://arxiv.org/abs/2008.07411 (Supplementary materials: FIG. S1.)

envelope_waveform_i(sampling_rate=1) Waveform[source]#

The envelope waveform of the i component of the pulse.

envelope_waveform_q(sampling_rate=1) Waveform[source]#

The envelope waveform of the q component of the pulse.

class qibolab.pulses.eCap(alpha: float)[source]#

Bases: PulseShape

ECap pulse shape.

Parameters:

alpha (float) –

\[\begin{split}e_{\cap(t,\alpha)} &=& A[1 + \tanh(\alpha t/t_\theta)][1 + \tanh(\alpha (1 - t/t_\theta))]\\ &\times& [1 + \tanh(\alpha/2)]^{-2}\end{split}\]
envelope_waveform_i(sampling_rate=1) Waveform[source]#
envelope_waveform_q(sampling_rate=1) Waveform[source]#
class qibolab.pulses.Custom(envelope_i, envelope_q=None)[source]#

Bases: PulseShape

Arbitrary shape.

envelope_waveform_i(sampling_rate=1) Waveform[source]#

The envelope waveform of the i component of the pulse.

envelope_waveform_q(sampling_rate=1) Waveform[source]#

The envelope waveform of the q component of the pulse.

class qibolab.pulses.Pulse(start: int, duration: int, amplitude: float, frequency: int, relative_phase: float, shape: PulseShape, channel: str | None = None, type: PulseType = PulseType.DRIVE, qubit: int = 0, _if: int = 0)[source]#

Bases: object

A class to represent a pulse to be sent to the QPU.

start: int#

Start time of pulse in ns.

duration: int#

Pulse duration in ns.

amplitude: float#

Pulse digital amplitude (unitless).

Pulse amplitudes are normalised between -1 and 1.

frequency: int#

Pulse Intermediate Frequency in Hz.

The value has to be in the range [10e6 to 300e6].

relative_phase: float#

Relative phase of the pulse, in radians.

shape: PulseShape#

Pulse shape, as a PulseShape object.

See :py: mod:qibolab.pulses for list of available shapes.

channel: str | None = None#

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.

type: PulseType = 'qd'#

Pulse type, as an element of PulseType enumeration.

qubit: int = 0#

Qubit or coupler addressed by the pulse.

property finish: int | None#

Time when the pulse is scheduled to finish.

property global_phase#

Global phase of the pulse, in radians.

This phase is calculated from the pulse start time and frequency as 2 * pi * frequency * start.

property phase: float#

Total phase of the pulse, in radians.

The total phase is computed as the sum of the global and relative phases.

property serial: str#

Returns a string representation of the pulse.

property id: int#
envelope_waveform_i(sampling_rate=1) Waveform[source]#

The envelope waveform of the i component of the pulse.

envelope_waveform_q(sampling_rate=1) Waveform[source]#

The envelope waveform of the q component of the pulse.

envelope_waveforms(sampling_rate=1)[source]#

A tuple with the i and q envelope waveforms of the pulse.

modulated_waveform_i(sampling_rate=1) Waveform[source]#

The waveform of the i component of the pulse, modulated with its frequency.

modulated_waveform_q(sampling_rate=1) Waveform[source]#

The waveform of the q component of the pulse, modulated with its frequency.

modulated_waveforms(sampling_rate)[source]#

A tuple with the i and q waveforms of the pulse, modulated with its frequency.

copy()[source]#

Returns a new Pulse object with the same attributes.

shallow_copy()[source]#
is_equal_ignoring_start(item) bool[source]#

Check if two pulses are equal ignoring start time.

plot(savefig_filename=None, sampling_rate=1)[source]#

Plots the pulse envelope and modulated waveforms.

Parameters:

savefig_filename (str) – a file path. If provided the plot is save to a file.

class qibolab.pulses.ReadoutPulse(start, duration, amplitude, frequency, relative_phase, shape, channel=0, qubit=0)[source]#

Bases: Pulse

Describes a readout pulse.

See :class: qibolab.pulses.Pulse for argument desciption.

property serial#

Returns a string representation of the pulse.

property global_phase#

Global phase of the pulse, in radians.

This phase is calculated from the pulse start time and frequency as 2 * pi * frequency * start.

copy()[source]#

Returns a new Pulse object with the same attributes.

class qibolab.pulses.DrivePulse(start, duration, amplitude, frequency, relative_phase, shape, channel=0, qubit=0)[source]#

Bases: Pulse

Describes a qubit drive pulse.

See :class: qibolab.pulses.Pulse for argument desciption.

property serial#

Returns a string representation of the pulse.

class qibolab.pulses.FluxPulse(start, duration, amplitude, shape, channel=0, qubit=0)[source]#

Bases: Pulse

Describes a qubit flux pulse.

Flux pulses have frequency and relative_phase equal to 0. Their i and q components are equal. See :class: qibolab.pulses.Pulse for argument desciption.

PULSE_TYPE = 'qf'#
envelope_waveform_q(sampling_rate=1) Waveform[source]#

Flux pulses only have i component.

modulated_waveform_i(sampling_rate=1) Waveform[source]#

The waveform of the i component of the pulse, modulated with its frequency.

modulated_waveform_q(sampling_rate=1) Waveform[source]#

The waveform of the q component of the pulse, modulated with its frequency.

property serial#

Returns a string representation of the pulse.

class qibolab.pulses.CouplerFluxPulse(start, duration, amplitude, shape, channel=0, qubit=0)[source]#

Bases: FluxPulse

Describes a coupler flux pulse.

See :class: qibolab.pulses.FluxPulse for argument desciption.

PULSE_TYPE = 'cf'#
class qibolab.pulses.PulseConstructor(value)[source]#

Bases: Enum

An enumeration to map each PulseType to the proper pulse constructor.

READOUT = <class 'qibolab.pulses.ReadoutPulse'>#
DRIVE = <class 'qibolab.pulses.DrivePulse'>#
FLUX = <class 'qibolab.pulses.FluxPulse'>#
class qibolab.pulses.PulseSequence(*pulses)[source]#

Bases: object

A collection of scheduled pulses.

A quantum circuit can be translated into a set of scheduled pulses that implement the circuit gates. This class contains many supporting fuctions to facilitate the creation and manipulation of these collections of pulses. None of the methods of PulseSequence modify any of the properties of its pulses.

pulses#

a list containing the pulses, ordered by their channel and start times.

Type:

Pulses (list)

property serial#

Returns a string representation of the pulse sequence.

property count#

Returns the number of pulses in the sequence.

add(*items)[source]#

Adds pulses to the sequence and sorts them by channel and start time.

index(pulse)[source]#

Returns the index of a pulse in the sequence.

pop(index=-1)[source]#

Returns the pulse with the index provided and removes it from the sequence.

remove(pulse)[source]#

Removes a pulse from the sequence.

clear()[source]#

Removes all pulses from the sequence.

shallow_copy()[source]#

Returns a shallow copy of the sequence.

It returns a new PulseSequence object with references to the same Pulse objects.

copy()[source]#

Returns a deep copy of the sequence.

It returns a new PulseSequence with replicates of each of the pulses contained in the original sequence.

property ro_pulses#

Returns a new PulseSequence containing only its readout pulses.

property qd_pulses#

Returns a new PulseSequence containing only its qubit drive pulses.

property qf_pulses#

Returns a new PulseSequence containing only its qubit flux pulses.

property cf_pulses#

Returns a new PulseSequence containing only its coupler flux pulses.

get_channel_pulses(*channels)[source]#

Returns a new PulseSequence containing only the pulses on a specific set of channels.

get_qubit_pulses(*qubits)[source]#

Returns a new PulseSequence containing only the pulses on a specific set of qubits.

coupler_pulses(*couplers)[source]#

Returns a new PulseSequence containing only the pulses on a specific set of couplers.

property is_empty#

Returns True if the sequence does not contain any pulses.

property finish: int#

Returns the time when the last pulse of the sequence finishes.

property start: int#

Returns the start time of the first pulse of the sequence.

property duration: int#

Returns duration of the sequence calculated as its finish - start times.

property channels: list#

Returns list containing the channels used by the pulses in the sequence.

property qubits: list#

Returns list containing the qubits associated with the pulses in the sequence.

get_pulse_overlaps()[source]#

Returns a dictionary of slices of time (tuples with start and finish times) where pulses overlap.

separate_overlapping_pulses()[source]#

Separates a sequence of overlapping pulses into a list of non- overlapping sequences.

property pulses_overlap: bool#

Returns True if any of the pulses in the sequence overlap.

plot(savefig_filename=None, sampling_rate=1)[source]#

Plots the sequence of pulses.

Parameters:

savefig_filename (str) – a file path. If provided the plot is save to a file.

qibolab.qubits module#

qibolab.qubits.QubitId#

Type for qubit names.

alias of Union[str, int]

qibolab.qubits.CHANNEL_NAMES = ('readout', 'feedback', 'drive', 'flux', 'twpa')#

Names of channels that belong to a qubit.

Not all channels are required to operate a qubit.

qibolab.qubits.EXCLUDED_FIELDS = ('readout', 'feedback', 'drive', 'flux', 'twpa', 'name', 'native_gates', 'kernel', '_flux')#

Qubit dataclass fields that are excluded by the characterization property.

class qibolab.qubits.Qubit(name: str | int, bare_resonator_frequency: int = 0, readout_frequency: int = 0, drive_frequency: int = 0, anharmonicity: int = 0, sweetspot: float = 0.0, asymmetry: float = 0.0, crosstalk_matrix: dict[typing.Union[str, int], float] = <factory>, Ec: float = 0.0, Ej: float = 0.0, g: float = 0.0, assignment_fidelity: float = 0.0, readout_fidelity: float = 0.0, effective_temperature: float = 0.0, peak_voltage: float = 0, pi_pulse_amplitude: float = 0, resonator_depletion_time: int = 0, T1: int = 0, T2: int = 0, T2_spin_echo: int = 0, state0_voltage: int = 0, state1_voltage: int = 0, mean_gnd_states: ~typing.List[float] = <factory>, mean_exc_states: ~typing.List[float] = <factory>, threshold: float | None = None, iq_angle: float = 0.0, kernel: ~numpy.ndarray | None = None, 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.channels.Channel | None = None, feedback: ~qibolab.channels.Channel | None = None, twpa: ~qibolab.channels.Channel | None = None, drive: ~qibolab.channels.Channel | None = None, _flux: ~qibolab.channels.Channel | None = None, native_gates: ~qibolab.native.SingleQubitNatives = <factory>)[source]#

Bases: object

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) –

name: str | int#
bare_resonator_frequency: int = 0#
readout_frequency: int = 0#

Readout dressed frequency.

drive_frequency: int = 0#
anharmonicity: int = 0#
sweetspot: float = 0.0#
asymmetry: float = 0.0#
crosstalk_matrix: dict[Union[str, int], float]#

Crosstalk matrix for voltages.

Ec: float = 0.0#

Readout Charge Energy.

Ej: float = 0.0#

Readout Josephson Energy.

g: float = 0.0#

Readout coupling.

assignment_fidelity: float = 0.0#

Assignment fidelity.

readout_fidelity: float = 0.0#

Readout fidelity.

effective_temperature: float = 0.0#

Effective temperature.

peak_voltage: float = 0#
pi_pulse_amplitude: float = 0#
resonator_depletion_time: int = 0#
T1: int = 0#
T2: int = 0#
T2_spin_echo: int = 0#
state0_voltage: int = 0#
state1_voltage: int = 0#
mean_gnd_states: List[float]#
mean_exc_states: List[float]#
threshold: float | None = None#
iq_angle: float = 0.0#
kernel: ndarray | None = None#
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: Channel | None = None#
feedback: Channel | None = None#
twpa: Channel | None = None#
drive: Channel | None = None#
native_gates: SingleQubitNatives#
property flux#
property channels#
property characterization#

Dictionary containing characterization parameters.

property mixer_frequencies#

Get local oscillator and intermediate frequencies of native gates.

Assumes RF = LO + IF.

qibolab.qubits.QubitPairId#

Type for holding QubitPair``s in the ``platform.pairs dictionary.

alias of Tuple[Union[str, int], Union[str, int]]

class qibolab.qubits.QubitPair(qubit1: ~qibolab.qubits.Qubit, qubit2: ~qibolab.qubits.Qubit, coupler: ~qibolab.couplers.Coupler | None = None, native_gates: ~qibolab.native.TwoQubitNatives = <factory>)[source]#

Bases: object

Data structure for holding the native two-qubit gates acting on a pair of qubits.

This is needed for symmetry to the single-qubit gates which are storred in the qibolab.platforms.abstract.Qubit.

qubit1: Qubit#

First qubit of the pair.

Acts as control on two-qubit gates.

qubit2: Qubit#

Second qubit of the pair.

Acts as target on two-qubit gates.

coupler: Coupler | None = None#
native_gates: TwoQubitNatives#

qibolab.result module#

class qibolab.result.IntegratedResults(data: ndarray)[source]#

Bases: object

Data structure to deal with the output of qibolab.platforms.abstr act.AbstractPlatform.execute_pulse_sequence() qibolab.platforms.abstract.AbstractPlatform.sweep()

Associated with AcquisitionType.INTEGRATION and AveragingMode.SINGLESHOT

property voltage_i#

Signal component i in volts.

property voltage_q#

Signal component q in volts.

property magnitude#

Signal magnitude in volts.

property phase#

Signal phase in radians.

property phase_std#

Signal phase in radians.

property serialize#

Serialize as a dictionary.

property average#

Perform average over i and q.

class qibolab.result.AveragedIntegratedResults(data: ndarray, std: ndarray | None = None)[source]#

Bases: IntegratedResults

Data structure to deal with the output of qibolab.platforms.abstr act.AbstractPlatform.execute_pulse_sequence() qibolab.platforms.abstract.AbstractPlatform.sweep()

Associated with AcquisitionType.INTEGRATION and AveragingMode.CYCLIC or the averages of IntegratedResults

property average#

Average on AveragedIntegratedResults is itself.

property phase_std#

Standard deviation is None for AveragedIntegratedResults.

property phase#

Phase not unwrapped because it is a single value.

class qibolab.result.RawWaveformResults(data: ndarray)[source]#

Bases: IntegratedResults

Data structure to deal with the output of qibolab.platforms.abstr act.AbstractPlatform.execute_pulse_sequence() qibolab.platforms.abstract.AbstractPlatform.sweep()

Associated with AcquisitionType.RAW and AveragingMode.SINGLESHOT may also be used to store the integration weights ?

class qibolab.result.AveragedRawWaveformResults(data: ndarray, std: ndarray | None = None)[source]#

Bases: AveragedIntegratedResults

Data structure to deal with the output of qibolab.platforms.abstr act.AbstractPlatform.execute_pulse_sequence() qibolab.platforms.abstract.AbstractPlatform.sweep()

Associated with AcquisitionType.RAW and AveragingMode.CYCLIC or the averages of RawWaveformResults

class qibolab.result.SampleResults(data: ndarray)[source]#

Bases: object

Data structure to deal with the output of qibolab.platforms.abstr act.AbstractPlatform.execute_pulse_sequence() qibolab.platforms.abstract.AbstractPlatform.sweep()

Associated with AcquisitionType.DISCRIMINATION and AveragingMode.SINGLESHOT

probability(state=0)[source]#

Returns the statistical frequency of the specified state (0 or 1).

property serialize#

Serialize as a dictionary.

property average#

Perform samples average.

class qibolab.result.AveragedSampleResults(statistical_frequency: ndarray, samples: ndarray = array([], dtype=float64), std: ndarray = array([], dtype=float64))[source]#

Bases: SampleResults

Data structure to deal with the output of qibolab.platforms.abstr act.AbstractPlatform.execute_pulse_sequence() qibolab.platforms.abstract.AbstractPlatform.sweep()

Associated with AcquisitionType.DISCRIMINATION and AveragingMode.CYCLIC or the averages of SampleResults

probability(state=0)[source]#

Returns the statistical frequency of the specified state (0 or 1).

qibolab.serialize module#

Helper methods for loading and saving to runcards.

The format of runcards in the qiboteam/qibolab_platforms_qrc repository is assumed here. See Using runcards example for more details.

qibolab.serialize.load_runcard(path: Path) dict[source]#

Load runcard JSON to a dictionary.

qibolab.serialize.load_settings(runcard: dict) Settings[source]#

Load platform settings section from the runcard.

qibolab.serialize.load_qubits(runcard: dict, kernels: Kernels | None = None) Tuple[Dict[str | int, Qubit], Dict[str | int, Coupler], Dict[Tuple[str | int, str | int], QubitPair]][source]#

Load qubits and pairs from the runcard.

Uses the native gate and characterization sections of the runcard to parse the :class: qibolab.qubits.Qubit and :class: qibolab.qubits.QubitPair objects.

qibolab.serialize.register_gates(runcard: dict, qubits: Dict[str | int, Qubit], pairs: Dict[Tuple[str | int, str | int], QubitPair], couplers: Dict[str | int, Coupler] | None = None) Tuple[Dict[str | int, Qubit], Dict[Tuple[str | int, str | int], QubitPair]][source]#

Register single qubit native gates to Qubit objects from the runcard.

Uses the native gate and characterization sections of the runcard to parse the qibolab.qubits.Qubit and qibolab.qubits.QubitPair objects.

qibolab.serialize.load_instrument_settings(runcard: dict, instruments: Dict[str, Instrument]) Dict[str, Instrument][source]#

Setup instruments according to the settings given in the runcard.

qibolab.serialize.dump_native_gates(qubits: Dict[str | int, Qubit], pairs: Dict[Tuple[str | int, str | int], QubitPair], couplers: Dict[str | int, Coupler] | None = None) dict[source]#

Dump native gates section to dictionary following the runcard format, using qubit and pair objects.

qibolab.serialize.dump_characterization(qubits: Dict[str | int, Qubit], couplers: Dict[str | int, Coupler] | None = None) dict[source]#

Dump qubit characterization section to dictionary following the runcard format, using qubit and pair objects.

qibolab.serialize.dump_instruments(instruments: Dict[str, Instrument]) dict[source]#

Dump instrument settings to a dictionary following the runcard format.

qibolab.serialize.dump_runcard(platform: Platform, path: Path)[source]#

Serializes the platform and saves it as a json runcard file.

The file saved follows the format explained in Using runcards.

Parameters:
qibolab.serialize.dump_kernels(platform: Platform, path: Path)[source]#

Creates Kernels instance from platform and dumps as npz.

Parameters:
qibolab.serialize.dump_platform(platform: Platform, path: Path)[source]#

Platform serialization as runcard (json) and kernels (npz).

Parameters:

qibolab.sweeper module#

class qibolab.sweeper.Parameter(value)[source]#

Bases: Enum

Sweeping parameters.

frequency = 1#
amplitude = 2#
duration = 3#
relative_phase = 4#
start = 5#
attenuation = 6#
gain = 7#
bias = 8#
lo_frequency = 9#
class qibolab.sweeper.SweeperType(value)[source]#

Bases: Enum

Type of the Sweeper.

ABSOLUTE = functools.partial(<function SweeperType.<lambda>>)#
FACTOR = <built-in function mul>#
OFFSET = <built-in function add>#
class qibolab.sweeper.Sweeper(parameter: Parameter, values: ndarray[Any, dtype[_ScalarType_co]], pulses: list | None = None, qubits: list | None = None, couplers: list | None = None, type: SweeperType | None = SweeperType.ABSOLUTE)[source]#

Bases: object

Data structure for Sweeper object.

This object is passed as an argument to the method qibolab.platforms.abstract.Platform.sweep() which enables the user to sweep a specific parameter for one or more pulses. For information on how to perform sweeps see qibolab.platforms.abstract.Platform.sweep().

Example

import numpy as np
from qibolab.dummy import create_dummy
from qibolab.sweeper import Sweeper, Parameter
from qibolab.pulses import PulseSequence
from qibolab import ExecutionParameters


platform = create_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, ExecutionParameters(), 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 of the sweep is a pulse parameter, if the sweeper type is not ABSOLUTE, the base value will be taken from the runcard pulse parameters. If the sweep parameter is Bias, the base value will be the sweetspot of the qubits.

  • pulses (list) – list of qibolab.pulses.Pulse to be swept (optional).

  • qubits (list) – list of qibolab.platforms.abstract.Qubit to be swept (optional).

  • type (SweeperType) – can be ABSOLUTE (the sweeper range is swept directly), FACTOR (sweeper values are multiplied by base value), OFFSET (sweeper values are added to base value)

parameter: Parameter#
values: ndarray[Any, dtype[_ScalarType_co]]#
pulses: list | None = None#
qubits: list | None = None#
couplers: list | None = None#
type: SweeperType | None = functools.partial(<function SweeperType.<lambda>>)#
get_values(base_value)[source]#

Convert sweeper values depending on the sweeper type.

qibolab.unrolling module#

Utilities for sequence unrolling.

May be reused by different instruments.

class qibolab.unrolling.Bounds(waveforms: int, readout: int, instructions: int)[source]#

Bases: object

Instument memory limitations proxies.

waveforms: int#

Waveforms estimated size.

readout: int#

Number of readouts.

instructions: int#

Instructions estimated size.

classmethod update(sequence: PulseSequence)[source]#
qibolab.unrolling.batch(sequences: list[qibolab.pulses.PulseSequence], bounds: Bounds)[source]#

Split a list of sequences to batches.

Takes into account the various limitations throught the mechanics defined in :cls:`Bounds`, and the numerical limitations specified by the bounds argument.