QuantumOp#
Module: iqm.pulse.quantum_ops
- class iqm.pulse.quantum_ops.QuantumOp(name, arity=1, params=<factory>, optional_params=<factory>, implementations=<factory>, symmetric=False, factorizable=False, default_implementation='', defaults_for_locus=<factory>, unitary=None)#
Bases:
objectDescribes a native quantum operation type.
Quantum operations (or “ops” in short), are simple, abstract, self-contained actions one can execute on a station as parts of a quantum circuit. They include quantum gates, measurements, and resets. They must have an unambiguous definition in terms of their intended effect on the computational subspace of the quantum subsystems (qubits, qudits, qumodes…) they act on. They are implemented on the hardware using
instruction schedules.A QuantumOp can also be a metaoperation, which (in an idealized picture) has no effect on the quantum state, but affects the scheduling of the other ops.
Execution barriersare an example of a metaoperation.The ops can have any number of named parameters. For example,
PRXis a two-parameter quantum gate family, whereasCZis a single gate with no parameters.A locus (plural: loci) is a
tuple[str, ...](an ordered sequence) of CHAD component names an instance of a quantum operation acts on. The locus consists of those QPU components that store the quantum information the operation acts on. For example, aCZgate implemented using a flux pulse on the coupler connecting the qubits does not include the coupler in its locus, since the coupler is simply an implementation detail.In a quantum circuit each operation type normally has several different loci. For example, you could have a
PRXgate being used on qubits{('QB1',), ('QB2',), ('QB5',)}, or aCZgate used on qubit pairs{('QB1', 'QB3'), ('QB3', 'QB5',), ('QB1', 'QB5',)}.Each quantum operation can have any number of named implementations, each represented by a
GateImplementationsubclass. For example, we may have two implementations of the CZ gate, one with just a single flux pulse applied to the coupler, and another one with additional flux pulses applied to the qubits as well.operation defines the abstract intention (what)
implementation defines the concrete method (how)
locus defines the target of the operation (where)
The quantum operations are typically calibrated using specific calibration experiments that output the required calibration data. Each implementation of each operation can require its own, independent set of calibration data for each locus.
Attributes
Number of locus components the operation acts on.
Use this implementation of the op by default.
True iff the operation is always factorizable to independent single-subsystem operations, which is also how it is implemented, for example parallel single-qubit measurements.
True iff the effect of operation is symmetric in the quantum subsystems it acts on.
Unitary matrix that represents the effect of this quantum operation in the computational basis, or
Noneif the quantum operation is not unitary or the exact unitary is not known.Unique name of the operation.
Maps names of required operation parameters to their allowed types.
Maps names of optional operation parameters to their allowed types.
Maps implementation names to
GateImplementationclasses that provide them.Overrides
default_implementationfor some loci.Methods
Make a copy of
selfwith the given changes applied to the contents.Get the default implementation for the given locus.
Sets the given implementation as the default.
Set the locus-specific default implementation.
- Parameters:
- arity: int = 1#
Number of locus components the operation acts on. Each locus component corresponds to a quantum subsystem in the definition of the operation. The computational subspace always consists of the lowest two levels of the subsystem. Zero means the operation can be applied on any number of locus components.
- params: dict[str, tuple[type, ...]]#
Maps names of required operation parameters to their allowed types.
- optional_params: dict[str, tuple[type, ...]]#
Maps names of optional operation parameters to their allowed types.
- implementations: dict[str, type[GateImplementation]]#
Maps implementation names to
GateImplementationclasses that provide them. Each such class should describe the implementation in detail in its docstring.
- symmetric: bool = False#
True iff the effect of operation is symmetric in the quantum subsystems it acts on. Only meaningful if
self.arity != 1.
- factorizable: bool = False#
True iff the operation is always factorizable to independent single-subsystem operations, which is also how it is implemented, for example parallel single-qubit measurements. In this case the operation calibration data is for individual subsystems as well.
- default_implementation: str = ''#
Use this implementation of the op by default. Must exist in
implementations.
- defaults_for_locus: dict[Locus, str]#
Overrides
default_implementationfor some loci. Maps the locus to the gate implementation name that should be the default for that locus. If a locus is not found in this dict (by default, the dict is empty),default_implementationapplies. The listed implementations must all exist inimplementations.
- unitary: Callable[..., np.ndarray] | None = None#
Unitary matrix that represents the effect of this quantum operation in the computational basis, or
Noneif the quantum operation is not unitary or the exact unitary is not known. The Callable needs to take exactly the arguments given inparams, for example ifparams={'angle': (float,), 'phase': (float,)}, the function must have signaturef(angle: float, phase: float) -> np.ndarray. For operations acting on more than 1 qubit, unitary should be given in the big-endian order, i.e. in the basisnp.kron(first_qubit_basis_ket, second_qubit_basis_ket).
- copy(**changes)#
Make a copy of
selfwith the given changes applied to the contents.- Return type:
- set_default_implementation(default)#
Sets the given implementation as the default.
- Parameters:
default (str) – name of the new default implementation
- Raises:
ValueError –
defaultis unknown or is a special implementation.- Return type:
None
- get_default_implementation_for_locus(locus)#
Get the default implementation for the given locus.
If no locus-specific default is defined, returns the global default.
- Parameters:
locus (Iterable[str]) – Operation locus to check. For symmetric operations, checks for every locus permutation in
defaults_for_locus(starting with the original) before returning the global default.- Returns:
Default implementation name for
locus.- Return type:
- set_default_implementation_for_locus(default, locus)#
Set the locus-specific default implementation.
- Parameters:
- Raises:
ValueError – if there is no implementation defined with the name
defaultordefaultis a special implementation.- Return type:
None
Inheritance
