qibolab package#

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.

class qibolab.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.Readout 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.Readout) – 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.

class qibolab.Channel(*, device: str = '', path: str = '')[source]#

Bases: Model

Channel to communicate with the qubit.

device: str#

Name of the device.

path: str#

Physical port addresss within the device.

property port: int#
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class qibolab.DcChannel(*, device: str = '', path: str = '')[source]#

Bases: Channel

Channel that can be used to send DC pulses.

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class qibolab.IqChannel(*, device: str = '', path: str = '', mixer: str | None, lo: str | None)[source]#

Bases: Channel

Channel that can be used to send IQ pulses.

mixer: str | None#

Name of the IQ mixer component corresponding to this channel.

None, if the channel does not have a mixer, or it does not need configuration.

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

lo: str | None#

Name of the local oscillator component corresponding to this channel.

None, if the channel does not have an LO, or it is not configurable.

class qibolab.AcquisitionChannel(*, device: str = '', path: str = '', twpa_pump: str | None, probe: str | None = None)[source]#

Bases: Channel

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

twpa_pump: str | None#

Name of the TWPA pump component.

None, if there is no TWPA, or it is not configurable.

probe: str | None#

Name of the corresponding measure/probe channel.

FIXME: This is temporary solution to be able to relate acquisition channel to corresponding probe channel wherever needed in drivers, until we make acquire channels completely independent, and users start putting explicit acquisition commands in pulse sequence.

qibolab.create_dummy() Platform[source]#

Create a dummy platform using the dummy instrument.

class qibolab.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.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

property average: bool#

Whether an average is performed or not.

class qibolab.ConfigKinds[source]#

Bases: object

Registered configuration kinds.

This class is handling the known configuration kinds for deserialization.

Attention

Beware that is managing a global state. This should not be a major issue, as the known configurations should be fixed per run. But prefer avoiding changing them during a single session, unless you are clearly controlling the sequence of all loading operations.

classmethod extend(kinds: Iterable[Any | type[qibolab._core.components.configs.Config]])[source]#

Extend the known configuration kinds.

Nested unions are supported (i.e. Union as elements of kinds).

classmethod reset()[source]#

Reset known configuration kinds to built-ins.

classmethod registered() list[Union[Any, type[qibolab._core.components.configs.Config]]][source]#

Retrieve registered configuration kinds.

classmethod adapted() TypeAdapter[source]#

Construct tailored pydantic type adapter.

The adapter will be able to directly load all the registered configuration kinds as the appropriate Python objects.

qibolab.create_platform(name: str) 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.

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

Returns:

The plaform class.

qibolab.locate_platform(name: str, paths: list[pathlib.Path] | None = None) Path[source]#

Locate platform’s path.

The name corresponds to the name of the folder in which the platform is defined, i.e. the one containing the platform.py file.

If paths are specified, the environment is ignored, and the folder search happens only in the specified paths.

class qibolab.Platform(name: str, parameters: ~qibolab._core.parameters.Parameters, instruments: dict[str, qibolab._core.instruments.abstract.Instrument], qubits: dict[typing.Union[int, str], qibolab._core.qubits.Qubit], couplers: dict[typing.Union[int, str], qibolab._core.qubits.Qubit] = <factory>, resonator_type: ~typing.Literal['2D', '3D'] = '2D', is_connected: bool = False)[source]#

Bases: object

Platform for controlling quantum devices.

name: str#

Name of the platform.

parameters: Parameters#

instruments: dict[str, qibolab._core.instruments.abstract.Instrument]#

Mapping instrument names to qibolab.instruments.abstract.Instrument objects.

qubits: dict[Union[int, str], qibolab._core.qubits.Qubit]#

Qubit controllers.

The mapped objects hold the qubit.components.channels.Channel instances required to send pulses addressing the desired qubits.

couplers: dict[Union[int, str], qibolab._core.qubits.Qubit]#

Coupler controllers.

Fully analogue to qubits. Only the flux channel is expected to be populated in the mapped objects.

resonator_type: Literal['2D', '3D'] = '2D'#

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

is_connected: bool = False#

Flag for whether we are connected to the physical instruments.

property nqubits: int#

Total number of usable qubits in the QPU.

property pairs: list[tuple[Union[int, str], Union[int, str]]]#

Available pairs in thee platform.

property ordered_pairs#

List of qubit pairs that are connected in the QPU.

property settings: Settings#

Container with default execution settings.

property natives: NativeGates#

Native gates containers.

property sampling_rate#

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

property components: set[str]#

Names of all components available in the platform.

property channels: dict[str, qibolab._core.components.channels.Channel]#

Channels in the platform.

property qubit_channels: dict[str, Union[int, str]]#

Channel to qubit map.

property coupler_channels#

Channel to coupler map.

config(name: str) Config[source]#

Returns configuration of given component.

update(update: dict[str, Any])[source]#

Update platform’s parameters.

connect()[source]#

Connect to all instruments.

disconnect()[source]#

Disconnects from instruments.

execute(sequences: list[qibolab._core.sequence.PulseSequence], sweepers: list[list[qibolab._core.sweeper.Sweeper]] | None = None, **options) dict[int, numpy.ndarray[Any, numpy.dtype[numpy.float64]]][source]#

Execute pulse sequences.

If any sweeper is passed, the execution is performed for the different values of sweeped parameters.

Returns readout results acquired by after execution.

Example

import numpy as np
from qibolab import Parameter, PulseSequence, Sweeper, create_dummy


platform = create_dummy()
qubit = platform.qubits[0]
natives = platform.natives.single_qubit[0]
sequence = natives.MZ.create_sequence()
parameter_range = np.random.randint(10, size=10)
sweeper = [
    Sweeper(
        parameter=Parameter.frequency,
        values=parameter_range,
        channels=[qubit.probe],
    )
]
platform.execute([sequence], [sweeper])
classmethod load(path: Path, instruments: dict[str, qibolab._core.instruments.abstract.Instrument], qubits: dict[Union[int, str], qibolab._core.qubits.Qubit], couplers: dict[Union[int, str], qibolab._core.qubits.Qubit] | None = None, name: str | None = None) Platform[source]#

Dump platform.

dump(path: Path)[source]#

Dump platform.

qubit(qubit: int | str) tuple[Union[int, str], qibolab._core.qubits.Qubit][source]#

Retrieve physical qubit name and object.

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

coupler(coupler: int | str) tuple[Union[int, str], qibolab._core.qubits.Qubit][source]#

Retrieve physical coupler name and object.

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

qibolab.Waveform#

alias of ndarray[Any, dtype[float64]]

qibolab.IqWaveform#

alias of ndarray[Any, dtype[float64]]

class qibolab.BaseEnvelope[source]#

Bases: ABC, Model

Pulse envelopes.

Generates both i (in-phase) and q (quadrature) components.

i(samples: int) ndarray[Any, dtype[float64]][source]#

In-phase envelope.

q(samples: int) ndarray[Any, dtype[float64]][source]#

Quadrature envelope.

envelopes(samples: int) ndarray[Any, dtype[float64]][source]#

Stacked i and q envelope waveforms of the pulse.

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class qibolab.Rectangular(*, kind: Literal['rectangular'] = 'rectangular')[source]#

Bases: BaseEnvelope

Rectangular envelope.

kind: Literal['rectangular']#
i(samples: int) ndarray[Any, dtype[float64]][source]#

Generate a rectangular envelope.

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class qibolab.Exponential(*, kind: Literal['exponential'] = 'exponential', tau: float, upsilon: float, g: float = 0.1)[source]#

Bases: BaseEnvelope

Exponential shape, i.e. square pulse with an exponential decay.

\[\frac{\exp\left(-\frac{x}{\text{upsilon}}\right) + g \exp\left(-\frac{x}{\text{tau}}\right)}{1 + g}\]
kind: Literal['exponential']#
tau: float#

The decay rate of the first exponential function.

In units of the interval duration.

upsilon: float#

The decay rate of the second exponential function.

In units of the interval duration.

g: float#

Weight of the second exponential function.

i(samples: int) ndarray[Any, dtype[float64]][source]#

Generate a combination of two exponential decays.

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class qibolab.Gaussian(*, kind: Literal['gaussian'] = 'gaussian', rel_sigma: float)[source]#

Bases: BaseEnvelope

Gaussian pulse shape.

Parameters:

rel_sigma (float) –

\[A\exp^{-\frac{1}{2}\frac{(t-\mu)^2}{\sigma^2}}\]
kind: Literal['gaussian']#
rel_sigma: float#

Relative Gaussian standard deviation.

In units of the interval duration.

i(samples: int) ndarray[Any, dtype[float64]][source]#

Generate a Gaussian window.

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class qibolab.GaussianSquare(*, kind: Literal['gaussian_square'] = 'gaussian_square', rel_sigma: float, width: float)[source]#

Bases: BaseEnvelope

Rectangular envelope with Gaussian rise and fall.

\[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]\]
kind: Literal['gaussian_square']#
rel_sigma: float#

Relative Gaussian standard deviation.

In units of the interval duration.

width: float#

Length of the flat portion.

i(samples: int) ndarray[Any, dtype[float64]][source]#

Generate a Gaussian envelope, with a flat central window.

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class qibolab.Drag(*, kind: Literal['drag'] = 'drag', rel_sigma: float, beta: float)[source]#

Bases: BaseEnvelope

Derivative Removal by Adiabatic Gate (DRAG) pulse envelope.

kind: Literal['drag']#
rel_sigma: float#

Relative Gaussian standard deviation.

In units of the interval duration.

beta: float#

Beta.

i(samples: int) ndarray[Any, dtype[float64]][source]#

Generate a Gaussian envelope.

q(samples: int) ndarray[Any, dtype[float64]][source]#

Generate …

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class qibolab.Iir(*, kind: Literal['iir'] = 'iir', a: ndarray[Any, dtype[_ScalarType_co]], b: ndarray[Any, dtype[_ScalarType_co]], target: BaseEnvelope)[source]#

Bases: BaseEnvelope

IIR Filter using scipy.signal lfilter.

https://arxiv.org/pdf/1907.04818.pdf (page 11 - filter formula S22):

p = [A, tau_iir]
p = [b0 = 1−k +k ·α, b1 = −(1−k)·(1−α),a0 = 1 and a1 = −(1−α)]
p = [b0, b1, a0, a1]
kind: Literal['iir']#
a: ndarray[Any, dtype[_ScalarType_co]]#
b: ndarray[Any, dtype[_ScalarType_co]]#
target: BaseEnvelope#
i(samples: int) ndarray[Any, dtype[float64]][source]#
q(samples: int) ndarray[Any, dtype[float64]][source]#

Q. .. todo:

Add docstring
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class qibolab.Snz(*, kind: Literal['snz'] = 'snz', t_idling: float, b_amplitude: float = 0.5)[source]#

Bases: BaseEnvelope

Sudden variant Net Zero.

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

kind: Literal['snz']#
t_idling: float#

Fraction of interval where idling.

b_amplitude: float#

Relative B amplitude (wrt A).

i(samples: int) ndarray[Any, dtype[float64]][source]#
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class qibolab.ECap(*, kind: Literal['ecap'] = 'ecap', alpha: float)[source]#

Bases: BaseEnvelope

ECap pulse envelope.

\[\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}\]
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

kind: Literal['ecap']#
alpha: float#

In units of the inverse interval duration.

i(samples: int) ndarray[Any, dtype[float64]][source]#
class qibolab.Custom(*, kind: Literal['custom'] = 'custom', i_: ndarray[Any, dtype[_ScalarType_co]], q_: ndarray[Any, dtype[_ScalarType_co]])[source]#

Bases: BaseEnvelope

Arbitrary envelope.

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

kind: Literal['custom']#
i_: ndarray[Any, dtype[_ScalarType_co]]#
q_: ndarray[Any, dtype[_ScalarType_co]]#
i(samples: int) ndarray[Any, dtype[float64]][source]#
q(samples: int) ndarray[Any, dtype[float64]][source]#
class qibolab.Acquisition(*, kind: Literal['acquisition'] = 'acquisition', duration: float)[source]#

Bases: _PulseLike

Acquisition instruction.

This event instructs the device to acquire samples for the event span.

Only valid on an acquisition channel.

kind: Literal['acquisition']#
duration: float#

Duration in ns.

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class qibolab.Align(*, kind: Literal['align'] = 'align')[source]#

Bases: _PulseLike

Brings different channels at the same point in time.

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

kind: Literal['align']#
class qibolab.Delay(*, kind: Literal['delay'] = 'delay', duration: float)[source]#

Bases: _PulseLike

Wait instruction.

During its length no pulse is sent on the same channel.

Valid on any channel.

kind: Literal['delay']#
duration: float#

Duration in ns.

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class qibolab.Pulse(*, kind: Literal['pulse'] = 'pulse', duration: float, amplitude: float, envelope: Rectangular | Exponential | Gaussian | GaussianSquare | Drag | Iir | Snz | ECap | Custom, relative_phase: float = 0.0)[source]#

Bases: _PulseLike

A pulse to be sent to the QPU.

Valid on any channel, except acquisition ones.

kind: Literal['pulse']#
duration: float#

Pulse duration.

amplitude: float#

Pulse digital amplitude (unitless).

Pulse amplitudes are normalised between -1 and 1.

envelope: Rectangular | Exponential | Gaussian | GaussianSquare | Drag | Iir | Snz | ECap | Custom#

The pulse envelope shape.

See qibolab.Envelope for list of available shapes.

relative_phase: float#

Relative phase of the pulse, in radians.

i(sampling_rate: float) ndarray[Any, dtype[float64]][source]#

Compute the envelope of the waveform i component.

q(sampling_rate: float) ndarray[Any, dtype[float64]][source]#

Compute the envelope of the waveform q component.

envelopes(sampling_rate: float) ndarray[Any, dtype[float64]][source]#

Compute a tuple with the i and q envelopes.

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

qibolab.PulseId#

alias of int

class qibolab.Readout(*, kind: Literal['readout'] = 'readout', acquisition: Acquisition, probe: Pulse)[source]#

Bases: _PulseLike

Readout instruction.

This event instructs the device to acquire samples for the event span.

Only valid on an acquisition channel.

kind: Literal['readout']#
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

acquisition: Acquisition#
probe: Pulse#
classmethod from_probe(probe: Pulse)[source]#

Create a whole readout operation from its probe pulse.

The acquisition is made to match the same probe duration.

property duration: float#

Duration in ns.

property id: int#

Instruction identifier.

class qibolab.VirtualZ(*, kind: Literal['virtualz'] = 'virtualz', phase: float)[source]#

Bases: _PulseLike

Implementation of Z-rotations using virtual phase.

Only valid on a drive channel.

kind: Literal['virtualz']#
phase: float#

Phase that implements the rotation.

property duration#

Duration of the virtual gate should always be zero.

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class qibolab.Qubit(*, drive: str | None = None, drive_qudits: dict[typing.Annotated[tuple[int, int], BeforeValidator(func=<function _split at 0x7fb3873248b0>, json_schema_input_type=PydanticUndefined), PlainSerializer(func=<function _join at 0x7fb387324a60>, return_type=PydanticUndefined, when_used='always')], str] = <factory>, flux: str | None = None, probe: str | None = None, acquisition: str | None = None)[source]#

Bases: Model

Representation of a physical qubit.

Contains the channel ids used to control the qubit and is instantiated in the function that creates the corresponding qibolab.Platform

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': False}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

drive: str | None#

Ouput channel, to drive the qubit state.

drive_qudits: dict[typing.Annotated[tuple[int, int], BeforeValidator(func=<function _split at 0x7fb3873248b0>, json_schema_input_type=PydanticUndefined), PlainSerializer(func=<function _join at 0x7fb387324a60>, return_type=PydanticUndefined, when_used='always')], str]#

Output channels collection, to drive non-qubit transitions.

flux: str | None#

Output channel, to control the qubit flux.

probe: str | None#

Output channel, to probe the resonator.

acquisition: str | None#

Input channel, to acquire the readout results.

property channels: list[str]#
classmethod default(name: int | str, channels: list[str] | None = None, **kwargs)[source]#

Create a qubit with default channel names.

Default channel names follow the convention: ‘{qubit_name}/{channel_type}’

Parameters:
  • name – Name for the qubit to be used for channel ids.

  • channels – List of channels to add to the qubit. If None the following channels will be added: probe, acquisition, drive and flux.

class qibolab.PulseSequence(initlist=None)[source]#

Bases: UserList[tuple[str, Union[Align, Pulse, Delay, VirtualZ, Acquisition, Readout][Union[Align, Pulse, Delay, VirtualZ, Acquisition, Readout]]]]

Synchronized sequence of control instructions across multiple channels.

The sequence is a linear stream of instructions, which may be executed in parallel over multiple channels.

Each instruction is composed by the pulse-like object representing the action, and the channel on which it should be performed.

classmethod load(value: list[tuple[str, Union[qibolab._core.pulses.pulse.Align, qibolab._core.pulses.pulse.Pulse, qibolab._core.pulses.pulse.Delay, qibolab._core.pulses.pulse.VirtualZ, qibolab._core.pulses.pulse.Acquisition, qibolab._core.pulses.pulse.Readout]]])[source]#
property duration: float#

Duration of the entire sequence.

property channels: set[str]#

Channels involved in the sequence.

channel(channel: str) Iterable[Align | Pulse | Delay | VirtualZ | Acquisition | Readout][source]#

Isolate pulses on a given channel.

channel_duration(channel: str) float[source]#

Duration of the given channel.

pulse_channels(pulse_id: int) list[str][source]#

Find channels on which a pulse with a given id plays.

concatenate(other: Iterable[tuple[str, Union[qibolab._core.pulses.pulse.Align, qibolab._core.pulses.pulse.Pulse, qibolab._core.pulses.pulse.Delay, qibolab._core.pulses.pulse.VirtualZ, qibolab._core.pulses.pulse.Acquisition, qibolab._core.pulses.pulse.Readout]]]) None[source]#

Concatenate two sequences.

Appends other in-place such that the result is:
  • self

  • necessary delays to synchronize channels

  • other

Guarantees that the all the channels in the concatenated sequence will start simultaneously

juxtapose(other: Iterable[tuple[str, Union[qibolab._core.pulses.pulse.Align, qibolab._core.pulses.pulse.Pulse, qibolab._core.pulses.pulse.Delay, qibolab._core.pulses.pulse.VirtualZ, qibolab._core.pulses.pulse.Acquisition, qibolab._core.pulses.pulse.Readout]]]) None[source]#

Juxtapose two sequences.

Appends other in-place such that the result is:
  • self

  • necessary delays to synchronize channels

  • other

Guarantee simultaneous start and no overlap.

align(channels: list[str]) Align[source]#

Introduce align commands to the sequence.

align_to_delays() PulseSequence[source]#

Compile align commands to delays.

trim() PulseSequence[source]#

Drop final delays.

The operation is not in place, and does not modify the original sequence.

property acquisitions: list[tuple[str, Union[qibolab._core.pulses.pulse.Readout, qibolab._core.pulses.pulse.Acquisition]]]#

Return list of the readout pulses in this sequence.

Note

This selects only the Acquisition events, and not all the instructions directed to an acquistion channel

class qibolab.Parameter(value)[source]#

Bases: Enum

Sweeping parameters.

frequency = (<enum.auto object>, 'channel')#
amplitude = (<enum.auto object>, 'pulse')#
duration = (<enum.auto object>, 'pulse')#
duration_interpolated = (<enum.auto object>, 'pulse')#
relative_phase = (<enum.auto object>, 'pulse')#
offset = (<enum.auto object>, 'channel')#
classmethod channels() set['Parameter'][source]#

Set of parameters to be swept on the channel.

qibolab.ParallelSweepers#

alias of list[Sweeper]

class qibolab.Sweeper(*, parameter: Parameter, values: ndarray[Any, dtype[_ScalarType_co]] | None = None, range: tuple[float, float, float] | None = None, pulses: list[typing.Annotated[typing.Union[qibolab._core.pulses.pulse.Align, qibolab._core.pulses.pulse.Pulse, qibolab._core.pulses.pulse.Delay, qibolab._core.pulses.pulse.VirtualZ, qibolab._core.pulses.pulse.Acquisition, qibolab._core.pulses.pulse.Readout], FieldInfo(annotation=NoneType, required=True, discriminator='kind')]] | None = None, channels: list[str] | None = None)[source]#

Bases: Model

Data structure for Sweeper object.

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

Example

import numpy as np
from qibolab import Parameter, PulseSequence, Sweeper, create_dummy


platform = create_dummy()
qubit = platform.qubits[0]
natives = platform.natives.single_qubit[0]
sequence = natives.MZ.create_sequence()
parameter_range = np.random.randint(10, size=10)
sweeper = Sweeper(
    parameter=Parameter.frequency, values=parameter_range, channels=[qubit.probe]
)
platform.execute([sequence], [[sweeper]])
Parameters:
  • parameter – parameter to be swept, possible choices are frequency, attenuation, amplitude, current and gain.

  • values – array of parameter values to sweep over.

  • range – tuple of (start, stop, step) to sweep over the array np.arange(start, stop, step). Can be provided instead of values for more efficient sweeps on some instruments.

  • pulses – list of qibolab.Pulse to be swept.

  • channels – list of channel names for which the parameter should be swept.

parameter: Parameter#
values: ndarray[Any, dtype[_ScalarType_co]] | None#
range: tuple[float, float, float] | None#
pulses: list[typing.Annotated[typing.Union[qibolab._core.pulses.pulse.Align, qibolab._core.pulses.pulse.Pulse, qibolab._core.pulses.pulse.Delay, qibolab._core.pulses.pulse.VirtualZ, qibolab._core.pulses.pulse.Acquisition, qibolab._core.pulses.pulse.Readout], FieldInfo(annotation=NoneType, required=True, discriminator='kind')]] | None#
channels: list[str] | None#
check_values()[source]#
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': True}#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

Subpackages#