mqt.ionshuttler.linear.actions

Actions supported by the Linear hardware model and compiler.

Malformed serialized action values raise ValueError because they represent invalid saved data rather than incorrect Python API argument types.

Module Contents

class Action[source]

Bases: abc.ABC

An operation that the Linear compiler can place in a schedule.

Hardware models can introduce new operations by subclassing Action and defining when they are available and how they change the state. Decisions involving several operations or circuit dependencies remain with the compiler.

individually_unconstrained: ClassVar[bool] = True
classmethod from_dict(data: Mapping[str, object]) → Action[source]

Restore an action from its serialized dataclass fields.

Actions containing nested values can override this method.

Returns:

The restored action.

Raises:

ValueError – If the saved fields cannot construct the action.

classmethod available_actions(state: State, architecture: Architecture, transport_timing: TransportTiming) → Iterable[Action][source]

Return instances this action type makes available in a given state.

Action types that are not generated directly by the compiler return no instances by default.

is_valid(state: State, architecture: Architecture) → bool[source]

Return whether this action can start in the current state.

Actions without their own restrictions are available by default. This check considers one action at a time; the compiler separately checks interactions between simultaneous actions.

abstractmethod apply(state: State, architecture: Architecture) → State[source]

Return the state produced when this action starts.

Physical actions leave circuit-progress tracking unchanged. Callers should check is_valid() before applying an action.

to_dict() → dict[str, object][source]

Return a description of this action using JSON-compatible values.

class SchedulableAction[source]

Bases: Action

An action that may appear in a compiled schedule.

__post_init__() → None[source]

Validate an action’s duration when it defines one.

Raises:
  • TypeError – If the duration is not an integer.

  • ValueError – If the duration is not a positive integer.

class PhysicalAction[source]

Bases: SchedulableAction

A control operation exposed by the hardware model.

Physical actions update ion placement or hardware availability while leaving the compiler’s circuit-progress tracking unchanged.

class TransportAction[source]

Bases: PhysicalAction

A hardware operation that changes where ions are located.

class Shuttle[source]

Bases: TransportAction

Move one ion between adjacent sites.

ion: int
src: int
dst: int
duration: int = 1
classmethod from_dict(data: Mapping[str, object]) → Action[source]

Restore a shuttle from serialized fields.

Returns:

The restored shuttle.

classmethod available_actions(state: State, architecture: Architecture, transport_timing: TransportTiming) → Iterable[Action][source]

Return shuttles to adjacent empty sites for every free ion.

is_valid(state: State, architecture: Architecture) → bool[source]

Return whether the ion can move into an adjacent empty site.

apply(state: State, architecture: Architecture) → State[source]

Move the ion and reserve it for the configured duration.

Returns:

The updated state with compiler progress preserved.

class PhysicalSwap[source]

Bases: TransportAction

Exchange two ions occupying adjacent sites.

ion_a: int
ion_b: int
pos_a: int
pos_b: int
duration: int = 1
classmethod from_dict(data: Mapping[str, object]) → Action[source]

Restore a physical swap from serialized fields.

Returns:

The restored swap.

classmethod available_actions(state: State, architecture: Architecture, transport_timing: TransportTiming) → Iterable[Action][source]

Return adjacent swaps between pairs of free ions.

is_valid(state: State, architecture: Architecture) → bool[source]

Return whether two free ions occupy the specified adjacent sites.

apply(state: State, architecture: Architecture) → State[source]

Exchange both positions and reserve both ions.

Returns:

The updated state with compiler progress preserved.

class GateAction[source]

Bases: PhysicalAction

A gate operation supported by the hardware model.

circuit_name: ClassVar[str | None] = None
parameter_names: ClassVar[tuple[str, ...]] = ()
classmethod from_instruction(ions: tuple[int, ...], parameters: tuple[float, ...], timing: GateTiming) → GateAction[source]

Create a gate from frontend-independent circuit operands.

Raises:

ValueError – If the gate type does not support circuit lowering.

class GateSpec[source]

Describe the rotation performed by a global pulse.

gate_name: str
theta: float | None = None
class SingleQubitGate[source]

Bases: GateAction

A rotation acting on one ion, implemented physically or virtually.

A virtual rotation changes the logical frame without occupying hardware time or a processing zone, but it remains part of the compiled circuit. A physical rotation uses the ion and its processing zone, even when a hardware abstraction assigns it zero duration.

ion: int
virtual: bool = False
parameter_names: ClassVar[tuple[str, ...]] = ('theta',)
classmethod from_instruction(ions: tuple[int, ...], parameters: tuple[float, ...], timing: GateTiming) → GateAction[source]

Create a single-ion rotation from normalized circuit operands.

Returns:

The lowered gate.

classmethod from_dict(data: Mapping[str, object]) → Action[source]

Restore a single-ion gate from serialized fields.

Returns:

The restored gate.

__post_init__() → None[source]

Validate virtuality and duration consistency.

Raises:
  • TypeError – If virtual is not Boolean.

  • ValueError – If the duration is invalid or a virtual gate has nonzero duration.

Warns:

UserWarning – If a physical gate has zero duration.

is_valid(state: State, architecture: Architecture) → bool[source]

Return whether the target ion and physical resources are eligible.

apply(state: State, architecture: Architecture) → State[source]

Reserve physical resources, or leave machine state unchanged if virtual.

Returns:

The updated state with compiler progress preserved.

class TwoQubitGate[source]

Bases: GateAction

A gate acting on two ions in the same processing zone.

ion_a: int
ion_b: int
classmethod from_instruction(ions: tuple[int, ...], parameters: tuple[float, ...], timing: GateTiming) → GateAction[source]

Create a two-ion gate from normalized circuit operands.

Returns:

The lowered gate.

classmethod from_dict(data: Mapping[str, object]) → Action[source]

Restore a two-ion gate from serialized fields.

Returns:

The restored gate.

is_valid(state: State, architecture: Architecture) → bool[source]

Return whether both free ions occupy one free processing zone.

apply(state: State, architecture: Architecture) → State[source]

Reserve both ions and their shared processing zone.

Returns:

The updated state with compiler progress preserved.

class Rx[source]

Bases: SingleQubitGate

Rotate one ion around the x axis.

theta: float
duration: int = 1
circuit_name: ClassVar[str] = 'rx'
class Ry[source]

Bases: SingleQubitGate

Rotate one ion around the y axis.

theta: float
duration: int = 1
circuit_name: ClassVar[str] = 'ry'
class Rz[source]

Bases: SingleQubitGate

Rotate one ion around the z axis.

The rotation is virtual by default to align with typical trapped-ion hardware implementations. Set virtual=False to model a physical implementation subject to ordinary scheduling-resource checks.

theta: float
duration: int = 0
virtual: bool = True
circuit_name: ClassVar[str] = 'rz'
class Rxx[source]

Bases: TwoQubitGate

Rotate two ions around the xx axis.

theta: float
duration: int = 2
circuit_name: ClassVar[str] = 'rxx'
parameter_names: ClassVar[tuple[str, ...]] = ('theta',)
class Ryy[source]

Bases: TwoQubitGate

Rotate two ions around the yy axis.

theta: float
duration: int = 2
circuit_name: ClassVar[str] = 'ryy'
parameter_names: ClassVar[tuple[str, ...]] = ('theta',)
class Rzz[source]

Bases: TwoQubitGate

Rotate two ions around the zz axis.

theta: float
duration: int = 2
circuit_name: ClassVar[str] = 'rzz'
parameter_names: ClassVar[tuple[str, ...]] = ('theta',)
class GlobalPulse[source]

Bases: GateAction

Apply one gate to ions simultaneously, as in coil-based microwave control.

The default Linear model treats this pulse as non-blocking w.r.t to other gates. A hardware model with shared-drive conflicts can subclass it and provide stricter validity and state-update behavior.

gate: GateSpec
duration: int = 1
classmethod from_dict(data: Mapping[str, object]) → Action[source]

Restore a global pulse and its nested gate description.

Returns:

The restored pulse.

apply(state: State, architecture: Architecture) → State[source]

Return the state with hardware availability unchanged.

to_dict() → dict[str, object][source]

Return a JSON-compatible description of the pulse and rotation.

DEFAULT_ACTION_TYPES: tuple[type[Action], ...]
BUILTIN_ACTION_TYPES: tuple[type[Action], ...]
class AdvanceTime[source]

Bases: SchedulableAction

Move the schedule forward by one timestep.

This is a compiler operation advancing the clock state and has no real hardware equivalent. It allows running operations to finish before further actions are scheduled.

timestep_increment: ClassVar[int] = 1
classmethod from_dict(data: Mapping[str, object]) → Action[source]

Restore the scheduler’s AdvanceTime marker.

Returns:

The restored marker.

apply(state: State, architecture: Architecture) → State[source]

Advance time and finish operations due by the next timestep.

Returns:

The state at the next compiler timestep.

build_action_type_registry(action_types: Iterable[type[Action]] | None = None, *, include_advance_time: bool = True) → dict[str, type[Action]][source]

Return built-in and caller-provided action classes by serialized name.

Returns:

A mapping from serialized action name to its action class.

Raises:
  • TypeError – If a supplied entry is not an action class.

  • ValueError – If two different action classes have the same serialized name.