qibolab package¶
- class qibolab.MetaBackend[source]¶
Bases:
objectMeta-backend class which takes care of loading the qibolab backend.
- class qibolab.QibolabBackend(platform)[source]¶
Bases:
NumpyBackend- property qubits: list[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])]]¶
Returns the qubits in the platform.
- property connectivity: list[Annotated[tuple[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])]], BeforeValidator(func=_split, json_schema_input_type=PydanticUndefined), PlainSerializer(func=_join, return_type=PydanticUndefined, when_used=always)]]¶
Returns the list of connected qubits.
- assign_measurements(measurement_map, readout)[source]¶
Assigning measurement outcomes to
qibo.states.MeasurementResultfor each gate.This allows properly obtaining the measured shots from the
qibolab.Readoutobject 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 inexecute_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. IfNonethe default|00...0>state is used.nshots (int) – Number of shots to sample from the experiment.
- Returns:
MeasurementOutcomesobject 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:
- Returns:
List of
MeasurementOutcomesobjects containing the results acquired from the execution of each circuit.
- class qibolab.Channel(*, device: str = '', path: str = '')[source]¶
Bases:
ModelChannel to communicate with the qubit.
- iqout(id_: str) str | None[source]¶
Extract associated IQ output channel.
This is the identity for each IQ output channel identifier, while it retrieves the associated probe channel for acquisition ones, and
Nonefor any other one (essentially, non-RF channels).The argument is the identifier of the present channel, since it is not stored within the objec itself, as it is only relevant to address it in a collection (and so, out of the scope of the object itself).
- 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:
ChannelChannel 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 = None, lo: str | None = None)[source]¶
Bases:
ChannelChannel 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].
- class qibolab.AcquisitionChannel(*, device: str = '', path: str = '', twpa_pump: str | None = 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.
- class qibolab.DcConfig(*, kind: Literal['dc'] = 'dc', offset: float)[source]¶
Bases:
ConfigConfiguration for a channel that can be used to send DC pulses (i.e. just envelopes without modulation).
- 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.IqConfig(*, kind: Literal['iq'] = 'iq', frequency: float)[source]¶
Bases:
ConfigConfiguration for an IQ 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].
- class qibolab.AcquisitionConfig(*, kind: Literal['acquisition'] = 'acquisition', delay: float, smearing: float, threshold: float | None = None, iq_angle: float | None = None, kernel: Annotated[ndarray[tuple[Any, ...], dtype[_ScalarT]], PlainValidator(func=ndarray_deserialize, json_schema_input_type=Any), PlainSerializer(func=ndarray_serialize, return_type=str, when_used=always)] | None = None)[source]¶
Bases:
ConfigConfiguration for acquisition channel.
Currently, in qibolab, acquisition channels are FIXME:
- 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].
- kernel: Annotated[Annotated[ndarray[tuple[Any, ...], dtype[_ScalarT]], PlainValidator(func=ndarray_deserialize, json_schema_input_type=Any), PlainSerializer(func=ndarray_serialize, return_type=str, when_used=always)] | None, FieldInfo(annotation=NoneType, required=True, repr=False)]¶
Integration weights to be used when post-processing the acquired signal.
- class qibolab.IqMixerConfig(*, kind: Literal['iq-mixer'] = 'iq-mixer', offset_i: float = 0.0, offset_q: float = 0.0, scale_q: float = 1.0, phase_q: float = 0.0)[source]¶
Bases:
ConfigConfiguration for IQ mixer.
Mixers usually have various imperfections, and one needs to compensate for them. This class holds the compensation configuration.
- scale_q: float¶
The relative amplitude scale/factor of the q channel, to account for I-Q amplitude imbalance.
- 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.OscillatorConfig(*, kind: Literal['oscillator'] = 'oscillator', frequency: float, power: float)[source]¶
Bases:
ConfigConfiguration for an oscillator.
- 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.Config[source]¶
Bases:
ModelConfiguration values depot.
- 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.LogConfig(*, kind: Literal['log'] = 'log', path: Path)[source]¶
Bases:
ConfigConfiguration for logging.
- 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.AcquisitionType(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]¶
Bases:
EnumData 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.
- class qibolab.AveragingMode(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]¶
Bases:
EnumData 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.ConfigKinds[source]¶
Bases:
objectRegistered 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.
- class qibolab.Hardware(*, instruments: ~collections.abc.Mapping[str, ~qibolab._core.instruments.abstract.Instrument], qubits: ~collections.abc.Mapping[~typing.Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], ~qibolab._core.qubits.Qubit], couplers: ~collections.abc.Mapping[~typing.Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], ~qibolab._core.qubits.Qubit] = <factory>)[source]¶
Bases:
ModelPart of the platform that specifies the hardware configuration.
- qubits: Mapping[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], Qubit]¶
- couplers: Mapping[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], Qubit]¶
- 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.Parameters(*, settings: ~qibolab._core.parameters.Settings = <factory>, configs: ~typing.Annotated[dict[str, ~qibolab._core.components.configs.Config], ~pydantic.functional_validators.BeforeValidator(func=~qibolab._core.parameters._load_configs, json_schema_input_type=PydanticUndefined), ~pydantic.functional_serializers.PlainSerializer(func=~qibolab._core.parameters._dump_configs, return_type=PydanticUndefined, when_used=always)] = <factory>, native_gates: ~qibolab._core.parameters.NativeGates = <factory>)[source]¶
Bases:
ModelSerializable parameters.
- settings: Settings¶
- configs: Annotated[dict[str, Config], BeforeValidator(func=_load_configs, json_schema_input_type=PydanticUndefined), PlainSerializer(func=_dump_configs, return_type=PydanticUndefined, when_used=always)]¶
- native_gates: NativeGates¶
- 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.initialize_parameters(hardware: Hardware, natives: set[str] | None = None, pairs: list[str] | None = None) Parameters[source]¶
Generates default
Parametersfor a given hardware configuration.
- 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.
- Returns:
The plaform class.
- qibolab.locate_platform(name: str, paths: list[Path] | None = None) Path[source]¶
Locate platform’s path.
The
namecorresponds to the name of the folder in which the platform is defined, i.e. the one containing theplatform.pyfile.If
pathsare 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: ~collections.abc.Mapping[str, ~qibolab._core.instruments.abstract.Instrument], qubits: ~collections.abc.Mapping[~typing.Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], ~qibolab._core.qubits.Qubit], couplers: ~collections.abc.Mapping[~typing.Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], ~qibolab._core.qubits.Qubit] = <factory>, resonator_type: ~typing.Literal['2D', '3D'] = '2D', is_connected: bool = False)[source]¶
Bases:
objectPlatform for controlling quantum devices.
- parameters: Parameters¶
…
- instruments: Mapping[str, Instrument]¶
Mapping instrument names to
qibolab.instruments.abstract.Instrumentobjects.
- qubits: Mapping[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], Qubit]¶
Qubit controllers.
The mapped objects hold the
qubit.components.channels.Channelinstances required to send pulses addressing the desired qubits.
- couplers: Mapping[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], Qubit]¶
Coupler controllers.
Fully analogue to
qubits. Only the flux channel is expected to be populated in the mapped objects.
- property pairs: list[Annotated[tuple[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])]], BeforeValidator(func=_split, json_schema_input_type=PydanticUndefined), PlainSerializer(func=_join, return_type=PydanticUndefined, when_used=always)]]¶
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 qubit_channels: dict[str, Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])]]¶
Channel to qubit map.
- property coupler_channels¶
Channel to coupler map.
- execute(sequences: list[PulseSequence], sweepers: list[list[Sweeper]] | None = None, **options) dict[Annotated[UUID, UuidVersion(uuid_version=4)], ndarray[tuple[Any, ...], dtype[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: Mapping[str, Instrument], qubits: Mapping[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], Qubit], couplers: Mapping[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], Qubit] | None = None, name: str | None = None) Platform[source]¶
Dump platform.
- qubit(qubit: Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])]) tuple[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], 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: Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])]) tuple[Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], 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, …
- class qibolab.BaseEnvelope[source]¶
Bases:
ABC,ModelPulse envelopes.
Generates both i (in-phase) and q (quadrature) components.
- envelopes(samples: int) ndarray[tuple[Any, ...], dtype[float64]][source]¶
Stacked i and q envelope waveforms of the pulse.
- static normalize_trim_pulse(pulse: ndarray[tuple[Any, ...], dtype[float64]]) ndarray[tuple[Any, ...], dtype[float64]][source]¶
Normalize the pulse relative to its first sample, then remove the first and last samples.
- 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:
BaseEnvelopeRectangular 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:
BaseEnvelopeExponential 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}\]- upsilon: float¶
The decay rate of the second exponential function.
In units of the interval duration.
- i(samples: int) ndarray[tuple[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:
BaseEnvelopeGaussian pulse shape.
- Parameters:
rel_sigma (float)
\[A\exp^{-\frac{1}{2}\frac{(t-\mu)^2}{\sigma^2}}\]- 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', risefall: int = 0, sigma: float = 0)[source]¶
Bases:
BaseEnvelopeRectangular envelope with Gaussian rise and fall.
Note
The risefall and sigma are absolute values.
\[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]\]- i(samples: int) ndarray[tuple[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:
BaseEnvelopeDerivative Removal by Adiabatic Gate (DRAG) pulse 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.Iir(*, kind: Literal['iir'] = 'iir', a: Annotated[ndarray[tuple[Any, ...], dtype[_ScalarT]], PlainValidator(func=ndarray_deserialize, json_schema_input_type=Any), PlainSerializer(func=ndarray_serialize, return_type=str, when_used=always)], b: Annotated[ndarray[tuple[Any, ...], dtype[_ScalarT]], PlainValidator(func=ndarray_deserialize, json_schema_input_type=Any), PlainSerializer(func=ndarray_serialize, return_type=str, when_used=always)], target: BaseEnvelope)[source]¶
Bases:
BaseEnvelopeIIR 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]
- a: Annotated[ndarray[tuple[Any, ...], dtype[_ScalarT]], PlainValidator(func=ndarray_deserialize, json_schema_input_type=Any), PlainSerializer(func=ndarray_serialize, return_type=str, when_used=always)]¶
- b: Annotated[ndarray[tuple[Any, ...], dtype[_ScalarT]], PlainValidator(func=ndarray_deserialize, json_schema_input_type=Any), PlainSerializer(func=ndarray_serialize, return_type=str, when_used=always)]¶
- target: BaseEnvelope¶
- 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: int, b_amplitude: float = 0.5)[source]¶
Bases:
BaseEnvelopeSudden variant Net Zero.
https://arxiv.org/abs/2008.07411 (Supplementary materials: FIG. S1.)
- i(samples: int) ndarray[tuple[Any, ...], dtype[float64]][source]¶
- \[\begin{split}\\Phi(t) = \begin{cases} 1 & \text{for } 0 \\leq t < \tau \\ b & \text{for } t = \tau \\ 0 & \text{for } \tau < t < \tau + \tau_{idle}\\ b & \text{for } t = \tau + \tau_{idle}\\ -1 & \text{for } \tau + \tau_{idle} < t \\leq 2\tau + \tau_{idle} \\ \\end{cases}.\end{split}\]
Where $tau$ is the duration of the square 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.ECap(*, kind: Literal['ecap'] = 'ecap', alpha: float)[source]¶
Bases:
BaseEnvelopeECap 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].
- class qibolab.Custom(*, kind: Literal['custom'] = 'custom', i_: Annotated[ndarray[tuple[Any, ...], dtype[_ScalarT]], PlainValidator(func=ndarray_deserialize, json_schema_input_type=Any), PlainSerializer(func=ndarray_serialize, return_type=str, when_used=always)], q_: Annotated[ndarray[tuple[Any, ...], dtype[_ScalarT]], PlainValidator(func=ndarray_deserialize, json_schema_input_type=Any), PlainSerializer(func=ndarray_serialize, return_type=str, when_used=always)])[source]¶
Bases:
BaseEnvelopeArbitrary 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].
- i_: Annotated[ndarray[tuple[Any, ...], dtype[_ScalarT]], PlainValidator(func=ndarray_deserialize, json_schema_input_type=Any), PlainSerializer(func=ndarray_serialize, return_type=str, when_used=always)]¶
- class qibolab.Acquisition(*, id_: ~uuid.Annotated[~uuid.UUID, ~pydantic.types.UuidVersion(uuid_version=4)] = <factory>, kind: ~typing.Literal['acquisition'] = 'acquisition', duration: float)[source]¶
Bases:
_PulseLikeAcquisition instruction.
This event instructs the device to acquire samples for the event span.
Only valid on an acquisition 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].
- class qibolab.Align(*, id_: ~uuid.Annotated[~uuid.UUID, ~pydantic.types.UuidVersion(uuid_version=4)] = <factory>, kind: ~typing.Literal['align'] = 'align')[source]¶
Bases:
_PulseLikeBrings 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].
- class qibolab.Delay(*, id_: ~uuid.Annotated[~uuid.UUID, ~pydantic.types.UuidVersion(uuid_version=4)] = <factory>, kind: ~typing.Literal['delay'] = 'delay', duration: float)[source]¶
Bases:
_PulseLikeWait instruction.
During its length no pulse is sent on the same channel.
Valid on any 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].
- class qibolab.Pulse(*, id_: ~uuid.Annotated[~uuid.UUID, ~pydantic.types.UuidVersion(uuid_version=4)] = <factory>, kind: ~typing.Literal['pulse'] = 'pulse', duration: float, amplitude: float, envelope: ~qibolab._core.pulses.envelope.Rectangular | ~qibolab._core.pulses.envelope.Exponential | ~qibolab._core.pulses.envelope.Gaussian | ~qibolab._core.pulses.envelope.GaussianSquare | ~qibolab._core.pulses.envelope.Drag | ~qibolab._core.pulses.envelope.Iir | ~qibolab._core.pulses.envelope.Snz | ~qibolab._core.pulses.envelope.ECap | ~qibolab._core.pulses.envelope.Custom, relative_phase: float = 0.0)[source]¶
Bases:
_PulseLikeA pulse to be sent to the QPU.
Valid on any channel, except acquisition ones.
- amplitude: float¶
Pulse digital amplitude (unitless).
Pulse amplitudes are normalised between -1 and 1.
- envelope: Annotated[Rectangular | Exponential | Gaussian | GaussianSquare | Drag | Iir | Snz | ECap | Custom, FieldInfo(annotation=NoneType, required=True, discriminator='kind')]¶
The pulse envelope shape.
See
qibolab.Envelopefor list of available shapes.
- i(sampling_rate: float) ndarray[tuple[Any, ...], dtype[float64]][source]¶
Compute the envelope of the waveform i component.
- q(sampling_rate: float) ndarray[tuple[Any, ...], dtype[float64]][source]¶
Compute the envelope of the waveform q component.
- envelopes(sampling_rate: float) ndarray[tuple[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].
- class qibolab.Readout(*, id_: ~uuid.Annotated[~uuid.UUID, ~pydantic.types.UuidVersion(uuid_version=4)] = <factory>, kind: ~typing.Literal['readout'] = 'readout', acquisition: ~qibolab._core.pulses.pulse.Acquisition, probe: ~qibolab._core.pulses.pulse.Pulse)[source]¶
Bases:
_PulseLikeReadout instruction.
This event instructs the device to acquire samples for the event span.
Only valid on an acquisition channel.
- acquisition: Acquisition¶
- 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.VirtualZ(*, id_: ~uuid.Annotated[~uuid.UUID, ~pydantic.types.UuidVersion(uuid_version=4)] = <factory>, kind: ~typing.Literal['virtualz'] = 'virtualz', phase: float)[source]¶
Bases:
_PulseLikeImplementation of Z-rotations using virtual phase.
Only valid on a drive channel.
- 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: ~typing.Annotated[str | None, True] = None, drive_extra: ~typing.Annotated[dict[~typing.Annotated[tuple[int, int], ~pydantic.functional_validators.BeforeValidator(func=~qibolab._core.identifier._split, json_schema_input_type=PydanticUndefined), ~pydantic.functional_serializers.PlainSerializer(func=~qibolab._core.identifier._join, return_type=PydanticUndefined, when_used=always)] | ~typing.Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], str], False] = <factory>, flux: ~typing.Annotated[str | None, True] = None, probe: ~typing.Annotated[str | None, True] = None, acquisition: ~typing.Annotated[str | None, True] = None)[source]¶
Bases:
ModelRepresentation 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_extra: Annotated[dict[Annotated[tuple[int, int], BeforeValidator(func=_split, json_schema_input_type=PydanticUndefined), PlainSerializer(func=_join, return_type=PydanticUndefined, when_used=always)] | Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], str], False]¶
Output channels collection, to drive non-qubit transitions.
- classmethod default(name: Annotated[int | str, FieldInfo(annotation=NoneType, required=True, metadata=[_PydanticGeneralMetadata(union_mode='left_to_right')])], 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
Nonethe following channels will be added: probe, acquisition, drive and flux.
- class qibolab.PulseSequence(initlist=None)[source]¶
Bases:
UserList[tuple[str,Annotated[Align|Pulse|Delay|VirtualZ|Acquisition|Readout, FieldInfo(annotation=NoneType, required=True, discriminator=’kind’)]]]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, Annotated[Align | Pulse | Delay | VirtualZ | Acquisition | Readout, FieldInfo(annotation=NoneType, required=True, discriminator='kind')]]])[source]¶
- channel(channel: str) Iterable[Annotated[Align | Pulse | Delay | VirtualZ | Acquisition | Readout, FieldInfo(annotation=NoneType, required=True, discriminator='kind')]][source]¶
Isolate pulses on a given channel.
- pulse_channels(pulse_id: Annotated[UUID, UuidVersion(uuid_version=4)]) list[str][source]¶
Find channels on which a pulse with a given id plays.
- concatenate(other: Iterable[tuple[str, Annotated[Align | Pulse | Delay | VirtualZ | Acquisition | Readout, FieldInfo(annotation=NoneType, required=True, discriminator='kind')]]]) None[source]¶
Concatenate two sequences.
Appends
otherin-place such that the result is:selfnecessary delays to synchronize channels
other
Guarantees that the all the channels in the concatenated sequence will start simultaneously
- juxtapose(other: Iterable[tuple[str, Annotated[Align | Pulse | Delay | VirtualZ | Acquisition | Readout, FieldInfo(annotation=NoneType, required=True, discriminator='kind')]]]) None[source]¶
Juxtapose two sequences.
Appends
otherin-place such that the result is:selfnecessary delays to synchronize channels
other
Guarantee simultaneous start and no overlap.
- 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, Readout | Acquisition]]¶
Return list of the readout pulses in this sequence.
Note
This selects only the
Acquisitionevents, and not all the instructions directed to an acquistion channel
- property split_readouts: PulseSequence¶
Split readout operations in its constituents.
This will also double the rest of the channels (mainly delays) on which the readouts are placed, assuming the probe channels to be absent.
Note
Since
Readoutis only placed on an acquisition channel, the name of the associated probe channel is actually unknown. This function assumes the convention that the relevant channels are named.../acquisitionand.../probe.
- class qibolab.Parameter(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]¶
Bases:
EnumSweeping parameters.
- frequency = (1, 'channel')¶
- amplitude = (2, 'pulse')¶
- duration = (3, 'pulse')¶
- duration_interpolated = (4, 'pulse')¶
- relative_phase = (5, 'pulse')¶
- phase = (6, 'pulse')¶
- offset = (7, 'channel')¶
- class qibolab.Sweeper(*, parameter: Parameter, values: ndarray[tuple[Any, ...], dtype[_ScalarT]] | None = None, range: tuple[float, float, float] | None = None, pulses: list[Annotated[Align | Pulse | Delay | VirtualZ | Acquisition | Readout, FieldInfo(annotation=NoneType, required=True, discriminator='kind')]] | None = None, channels: list[str] | None = None)[source]¶
Bases:
ModelData 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 seeqibolab.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]])
- range: tuple[float, float, float] | None¶
Tuple of
(start, stop, step).To sweep over the array
np.arange(start, stop, step). Can be provided instead ofvaluesfor more efficient sweeps on some instruments.
- pulses: list[Annotated[Align | Pulse | Delay | VirtualZ | Acquisition | Readout, FieldInfo(annotation=NoneType, required=True, discriminator='kind')]] | None¶
List of qibolab.Pulse to be swept.
- property irange: tuple[float, float, float]¶
Inferred range.
Always ensure a range, inferring it from
valuesifrangeis not set.
- 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¶
- qibolab.instruments package
DummyLocalOscillatorDummyInstrument- Submodules
- qibolab.instruments.bluefors module
TemperatureControllerTemperatureController.addressTemperatureController.portTemperatureController.client_socketTemperatureController.connect()TemperatureController.disconnect()TemperatureController.get_data()TemperatureController.model_configTemperatureController.model_post_init()TemperatureController.read_data()
- qibolab.instruments.dummy module
- qibolab.instruments.emulator module
EmulatorControllerDriveEmulatorConfigFluxEmulatorConfigHamiltonianConfigHamiltonianConfig.model_configHamiltonianConfig.kindHamiltonianConfig.transmon_levelsHamiltonianConfig.qubitsHamiltonianConfig.pairsHamiltonianConfig.nqubitsHamiltonianConfig.replace()HamiltonianConfig.initial_state()HamiltonianConfig.hilbert_space_index()HamiltonianConfig.dimsHamiltonianConfig.hamiltonian()HamiltonianConfig.dissipation()
- qibolab.instruments.era module
- qibolab.instruments.keysight_qcs module
- qibolab.instruments.qblox module
- qibolab.instruments.qm module
- qibolab.instruments.qrng module
- qibolab.instruments.rohde_schwarz module