quantum.adjoint (::catalyst::quantum::AdjointOp)

Calculate the adjoint of the enclosed operations

Syntax:

operation ::= `quantum.adjoint` `(` $args `)` attr-dict `:` type($results) $region

Traits: SingleBlockImplicitTerminator<YieldOp>, SingleBlock

Interfaces: NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand

Description

args

variadic of An array of value-semantic qubits (i.e. quantum register). or A value-semantic qubit (state).

Results:

Result

Description

results

variadic of An array of value-semantic qubits (i.e. quantum register). or A value-semantic qubit (state).

quantum.alloc (::catalyst::quantum::AllocOp)

Allocate n qubits into a quantum register.

Syntax:

operation ::= `quantum.alloc` `(` ($nqubits^):($nqubits_attr)? `)` attr-dict `:` type(results)

Attributes:

AttributeMLIR TypeDescription
nqubits_attr::mlir::IntegerAttr64-bit signless integer attribute whose value is non-negative

Operands:

Operand

Description

nqubits

64-bit signless integer

Results:

Result

Description

qreg

An array of value-semantic qubits (i.e. quantum register).

quantum.alloc_qb (::catalyst::quantum::AllocQubitOp)

Allocate a single qubit.

Syntax:

operation ::= `quantum.alloc_qb` attr-dict `:` type(results)

Results:

Result

Description

qubit

A value-semantic qubit (state).

quantum.compbasis (::catalyst::quantum::ComputationalBasisOp)

Define a pseudo-observable of the computational basis for use in measurements

Syntax:

operation ::= `quantum.compbasis` (`qubits` $qubits^)? (`qreg` $qreg^)? attr-dict `:` type(results)

The quantum.compbasis operation defines a quantum observable to be used by other operations such as measurement processes. The specific observable defined here is a “pseudo” observable to represent measurements in the computational basis. The only arguments are either the list of qubits to measure, or the quantum register to measure. When the argument is a register, the measurement occurs on all qubits in the register.

Example:

func.func @foo(%q0: !quantum.bit, %q1: !quantum.bit, %r: !quantum.reg)
{
    %obs_q = quantum.compbasis qubits %q0, %q1 : !quantum.obs
    %obs_r = quantum.compbasis qreg %r : !quantum.obs
    func.return
}

Traits: AlwaysSpeculatableImplTrait, AttrSizedOperandSegments

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand

Description

qubits

variadic of A value-semantic qubit (state).

qreg

An array of value-semantic qubits (i.e. quantum register).

Results:

Result

Description

obs

A quantum observable for use in measurements.

quantum.counts (::catalyst::quantum::CountsOp)

Compute sample counts for the given observable for the current state

Syntax:

operation ::= `quantum.counts` $obs ( `shape` $dynamic_shape^ )?
              ( `in` `(` $in_eigvals^ `:` type($in_eigvals) `,` $in_counts `:` type($in_counts) `)` )?
              attr-dict ( `:` type($eigvals)^ `,` type($counts) )?

The quantum.counts operation represents the measurement process of sampling eigenvalues from an observable on the current quantum state and counting the frequency of each eigenvalue. The only SSA argument is an observable that must be defined by an operation in the local scope. from an observable on the current quantum state. The number of samples to draw is determined by the device shots argument in the device initialization operation in the local scope.

Note that the “counts dictionary” is returned as two separate arrays of the same length, one array for the eigenvalues, and one for count of each eigenvalue. When operating in the computational basis, the “eigenvalues” are the possible bitstrings one could measure on the given qubits, encoded as (floating-point) integers.

Example:

func.func @foo(%q0: !quantum.bit, %q1: !quantum.bit, %shots: i64)
{
    quantum.device shots(%shots) ["rtd_lightning.so", "lightning.qubit", "{my_attr: my_attr_value}"]
    %obs = quantum.compbasis %q0, %q1 : !quantum.obs
    %counts = quantum.counts %obs : tensor<4xf64>, tensor<4xi64>

    %obs2 = quantum.pauli %q0[3], %q1[1] : !quantum.obs
    %counts2 = quantum.counts %obs2 : tensor<2xf64>, tensor<2xi64>

    func.return
}

Traits: AttrSizedOperandSegments, SameVariadicResultSize

Interfaces: MeasurementProcess

Operands:

Operand

Description

obs

A quantum observable for use in measurements.

dynamic_shape

64-bit signless integer

in_eigvals

1D memref of 64-bit float values

in_counts

1D memref of 64-bit signless integer values

Results:

Result

Description

eigvals

1D tensor of 64-bit float values

counts

1D tensor of 64-bit signless integer values

quantum.custom (::catalyst::quantum::CustomOp)

A generic quantum gate on n qubits with m floating point parameters.

Syntax:

operation ::= `quantum.custom` $gate_name `(` $params `)` $in_qubits (`adj` $adjoint^)? attr-dict ( `ctrls` `(` $in_ctrl_qubits^ `)` )?  ( `ctrlvals` `(` $in_ctrl_values^ `)` )? `:` type($out_qubits) (`ctrls` type($out_ctrl_qubits)^ )?

Traits: AttrSizedOperandSegments, AttrSizedResultSegments, Unitary

Interfaces: DifferentiableGate, NoMemoryEffect (MemoryEffectOpInterface), ParametrizedGate, QuantumGate, QuantumOperation

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
gate_name::mlir::StringAttrstring attribute
adjoint::mlir::UnitAttrunit attribute

Operands:

Operand

Description

params

variadic of 64-bit float

in_qubits

variadic of A value-semantic qubit (state).

in_ctrl_qubits

variadic of A value-semantic qubit (state).

in_ctrl_values

variadic of 1-bit signless integer

Results:

Result

Description

out_qubits

variadic of A value-semantic qubit (state).

out_ctrl_qubits

variadic of A value-semantic qubit (state).

quantum.dealloc (::catalyst::quantum::DeallocOp)

Deallocate a quantum register.

Syntax:

operation ::= `quantum.dealloc` $qreg attr-dict `:` type(operands)

Operands:

Operand

Description

qreg

An array of value-semantic qubits (i.e. quantum register).

quantum.dealloc_qb (::catalyst::quantum::DeallocQubitOp)

Deallocate a single qubit.

Syntax:

operation ::= `quantum.dealloc_qb` $qubit attr-dict `:` type(operands)

Operands:

Operand

Description

qubit

A value-semantic qubit (state).

quantum.device (::catalyst::quantum::DeviceInitOp)

Initialize a quantum device.

Syntax:

operation ::= `quantum.device` (`shots` `(` $shots^ `)`)? `[` $lib `,` $device_name `,` $kwargs `]` attr-dict

Attributes:

AttributeMLIR TypeDescription
auto_qubit_management::mlir::UnitAttrunit attribute
lib::mlir::StringAttrstring attribute
device_name::mlir::StringAttrstring attribute
kwargs::mlir::StringAttrstring attribute

Operands:

Operand

Description

shots

64-bit signless integer

quantum.device_release (::catalyst::quantum::DeviceReleaseOp)

Release the active quantum device.

Syntax:

operation ::= `quantum.device_release` attr-dict

quantum.expval (::catalyst::quantum::ExpvalOp)

Compute the expectation value of the given observable for the current state

Syntax:

operation ::= `quantum.expval` $obs attr-dict `:` type(results)

The quantum.expval operation represents the measurement process of computing the expectation value of an observable on the current quantum state. While this quantity can be computed analytically on simulators, for hardware execution or shot noise simulation, the shots attached to the device in the local scope is used. The only SSA argument is an observable that must be defined by an operation in the local scope.

Example:

func.func @foo(%q: !quantum.bit)
{
    %obs = quantum.namedobs %q[4] : !quantum.obs
    %expval = quantum.expval %obs : f64

    func.return
}

Interfaces: MeasurementProcess

Operands:

Operand

Description

obs

A quantum observable for use in measurements.

Results:

Result

Description

expval

64-bit float

quantum.extract (::catalyst::quantum::ExtractOp)

Extract a qubit value from a register.

Syntax:

operation ::= `quantum.extract` $qreg `[` ($idx^):($idx_attr)? `]` attr-dict `:` type($qreg) `->` type(results)

Interfaces: NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
idx_attr::mlir::IntegerAttr64-bit signless integer attribute whose value is non-negative

Operands:

Operand

Description

qreg

An array of value-semantic qubits (i.e. quantum register).

idx

64-bit signless integer

Results:

Result

Description

qubit

A value-semantic qubit (state).

quantum.finalize (::catalyst::quantum::FinalizeOp)

Teardown the quantum runtime.

Syntax:

operation ::= `quantum.finalize` attr-dict

Executing this instruction concretely corresponds to executing the __catalyst\ **rt**\ finalize function in the runtime which is expected to be the very last thing executed by the library.

quantum.gphase (::catalyst::quantum::GlobalPhaseOp)

Global Phase.

Syntax:

operation ::= `quantum.gphase` `(` $angle `)` (`adj` $adjoint^)? attr-dict ( `ctrls` `(` $in_ctrl_qubits^ `)` )?  ( `ctrlvals` `(` $in_ctrl_values^ `)` )? ( `:` `ctrls` type($out_ctrl_qubits)^ )?

Applies global phase to the current system.

Traits: AttrSizedOperandSegments, Unitary

Interfaces: DifferentiableGate, ParametrizedGate, QuantumGate, QuantumOperation

Attributes:

AttributeMLIR TypeDescription
adjoint::mlir::UnitAttrunit attribute

Operands:

Operand

Description

angle

64-bit float

in_ctrl_qubits

variadic of A value-semantic qubit (state).

in_ctrl_values

variadic of 1-bit signless integer

Results:

Result

Description

out_ctrl_qubits

variadic of A value-semantic qubit (state).

quantum.hamiltonian (::catalyst::quantum::HamiltonianOp)

Define a Hamiltonian observable for use in measurements

Syntax:

operation ::= `quantum.hamiltonian` `(` $coeffs `:` type($coeffs) `)` $terms attr-dict `:` type(results)

The quantum.hamiltonian operation defines a quantum observable to be used by other operations such as measurement processes. The specific observable defined here represents the hamiltonian of observables. The arguments are a set of coefficients and a set of quantum.Observable generated by quantum.namedobs, quantum.hermitian, or quantum.tensorobs.

Example:

func.func @foo(%q0: !quantum.bit, %q1: !quantum.bit, %c: tensor<2xf64>) {
    %obs1 = quantum.namedobs %q0[4] : !quantum.obs
    %obs2 = quantum.namedobs %q1[2] : !quantum.obs
    %res = quantum.hamiltonian(%c: tensor<2xf64>) %obs1, %obs2 : !quantum.obs
    func.return
}

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand

Description

coeffs

1D tensor of 64-bit float values or 1D memref of 64-bit float values

terms

variadic of A quantum observable for use in measurements.

Results:

Result

Description

obs

A quantum observable for use in measurements.

quantum.hermitian (::catalyst::quantum::HermitianOp)

Define a Hermitian observable for use in measurements

Syntax:

operation ::= `quantum.hermitian` `(` $matrix `:` type($matrix) `)` $qubits attr-dict `:` type(results)

The quantum.hermitian operation defines a quantum observable to be used by measurement processes. The specific observable defined here represents the Hermitian observable on a set of qubits. The arguments are a set of qubits to measure as well as a row-major flatten matrix of complex numbers that represents a Hermitian matrix that must be of size 2^(number of qubits) * 2^(number of qubits).

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand

Description

matrix

2D tensor of complex type with 64-bit float elements values or 2D memref of complex type with 64-bit float elements values

qubits

variadic of A value-semantic qubit (state).

Results:

Result

Description

obs

A quantum observable for use in measurements.

quantum.init (::catalyst::quantum::InitializeOp)

Initialize the quantum runtime.

Syntax:

operation ::= `quantum.init` attr-dict

The execution of this operation corresponds to the execution of Catalyst’s runtime function __catalyst\ **rt**\ initialize which is the first function that will be called for the duration of the whole compiled object.

quantum.insert (::catalyst::quantum::InsertOp)

Update the qubit value of a register.

Syntax:

operation ::= `quantum.insert` $in_qreg `[` ($idx^):($idx_attr)? `]` `,` $qubit attr-dict `:` type($in_qreg) `,` type($qubit)

Interfaces: NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
idx_attr::mlir::IntegerAttr64-bit signless integer attribute whose value is non-negative

Operands:

Operand

Description

in_qreg

An array of value-semantic qubits (i.e. quantum register).

idx

64-bit signless integer

qubit

A value-semantic qubit (state).

Results:

Result

Description

out_qreg

An array of value-semantic qubits (i.e. quantum register).

quantum.mcmobs (::catalyst::quantum::MCMObsOp)

Define a pseudo-observable of mid-circuit measurements for use in measurement processes

Syntax:

operation ::= `quantum.mcmobs` $mcms attr-dict `:` type(results)

The quantum.mcmobs operation defines a quantum observable from mid-circuit measurements, to be used by other operations such as measurement processes.

The only argument is a sequence of boolean result values of mid-circuit measurements.

Example:

func.func @foo(%mcm: i1)
{
    %obs = quantum.mcmobs %mcm : !quantum.obs
    func.return
}

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand

Description

mcms

variadic of 1-bit signless integer

Results:

Result

Description

obs

A quantum observable for use in measurements.

quantum.measure (::catalyst::quantum::MeasureOp)

A single-qubit projective measurement in the computational basis.

Syntax:

operation ::= `quantum.measure` $in_qubit (`postselect` $postselect^)? attr-dict `:` type(results)

Attributes:

AttributeMLIR TypeDescription
postselect::mlir::IntegerAttr32-bit signless integer attribute whose minimum value is 0 whose maximum value is 1

Operands:

Operand

Description

in_qubit

A value-semantic qubit (state).

Results:

Result

Description

mres

1-bit signless integer

out_qubit

A value-semantic qubit (state).

quantum.multirz (::catalyst::quantum::MultiRZOp)

Apply an arbitrary multi Z rotation

Syntax:

operation ::= `quantum.multirz` `(` $theta `)` $in_qubits (`adj` $adjoint^)? attr-dict ( `ctrls` `(` $in_ctrl_qubits^ `)` )?  ( `ctrlvals` `(` $in_ctrl_values^ `)` )? `:` type($out_qubits) (`ctrls` type($out_ctrl_qubits)^ )?

The quantum.multirz operation applies an arbitrary multi Z rotation to the state-vector. The arguments are the rotation angle theta and a set of qubits the operation acts on.

Note

This operation is one of the few quantum operations that is not applied via quantum.custom. The reason for this is that it needs to be handled in a special way during the lowering due to its C function being variadic on the number of qubits.

Traits: AttrSizedOperandSegments, AttrSizedResultSegments, Unitary

Interfaces: DifferentiableGate, NoMemoryEffect (MemoryEffectOpInterface), ParametrizedGate, QuantumGate, QuantumOperation

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
adjoint::mlir::UnitAttrunit attribute

Operands:

Operand

Description

theta

64-bit float

in_qubits

variadic of A value-semantic qubit (state).

in_ctrl_qubits

variadic of A value-semantic qubit (state).

in_ctrl_values

variadic of 1-bit signless integer

Results:

Result

Description

out_qubits

variadic of A value-semantic qubit (state).

out_ctrl_qubits

variadic of A value-semantic qubit (state).

quantum.namedobs (::catalyst::quantum::NamedObsOp)

Define a Named observable for use in measurements

Syntax:

operation ::= `quantum.namedobs` $qubit `[` $type `]` attr-dict  `:` type(results)

The quantum.namedobs operation defines a quantum observable to be used by measurement processes. The specific observable defined here represents one of 5 named observables {Identity, PauliX, PauliY, PauliZ, Hadamard} on a qubit. The arguments are a qubit to measure as well as an encoding operator for the qubit as an integer between 0-4.

Example:

func.func @foo(%q: !quantum.bit)
{
    %res = quantum.namedobs %q[4] : !quantum.obs
    func.return
}

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
type::catalyst::quantum::NamedObservableAttrKnown named observables

Operands:

Operand

Description

qubit

A value-semantic qubit (state).

Results:

Result

Description

obs

A quantum observable for use in measurements.

quantum.num_qubits (::catalyst::quantum::NumQubitsOp)

Get the number of currently allocated qubits.

Syntax:

operation ::= `quantum.num_qubits` attr-dict `:` type(results)

Interfaces: MemoryEffectOpInterface (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{MemoryEffects::Read on ::mlir::SideEffects::DefaultResource}

Results:

Result

Description

num_qubits

64-bit signless integer

quantum.operator (::catalyst::quantum::OperatorOp)

A generalized quantum operation with arbitrary input signature.

The quantum.operator is a generic representation for arbitrary quantum operations that cannot be expressed by the simpler quantum.custom op and don’t have a dedicated operation. It’s purpose is to represent high-level operations from frontend languages such as PennyLane — in particular templates and operators parametrized by Python (or frontend-language) data. The signature allows for an arbitrary number of dynamic data arguments (of arbitrary MLIR type), as well as limited static data (e.g. Pauli-word strings). Frontend-level data arguments are compressed into a unique identifier, since in general they may not be lowerable to MLIR.

The operation has two mutually exclusive representations:

  • Qubit mode (in_qubits / out_qubits): Use this when the operator acts on a statically known set of wires. Qubits are threaded through the op explicitly and can carry per-control values through in_ctrl_qubits / in_ctrl_values (with matching out_ctrl_qubits).

  • Register mode (in_qreg / out_qreg + index arrays): Use this when the operator acts on a dynamic number of wires. The operation receives one register and one or more index arrays selecting which qubits in that register are targeted. Controls are expressed with matching control index/value arrays.

Besides one of the above, the operator can hold the following information:

  • op_name — canonical operator name

  • Operator inputs in one of several forms:

    • params — dynamic operator inputs

    • static_data — static inputs available to compiler passes

    • UID — non-lowerable static inputs compressed into a unique ID; It can be used for

      equivalence checking but not much else. The decomposition rule functions
      (if provided) will reference the UID they were generated with.
      
    • forward_args — dynamic inputs of operators that were themselves input to this

      operator; Can only be present if `UID` is also present. Usually
      just forwarded to decomposition functions after the params list.
      
  • decompositions — optional symbol list of decomposition rule functions; This argument

    is added for decomposition rules generated by the frontend together
    with the program. Otherwise, decomposition rules will be obtained
    from a pre-compiled library or generated by the compiler on demand.
    
  • Optional frontend-level metadata:

    • param_map — maps frontend argument names to the lowered params operand positions

    • qubit_map — maps frontend argument names to lowered qubit/index-array positions

Examples:

A complex operator with one compilable static argument and an adjoint modifier acting on a single qubit:

%out = quantum.operator "MyOp"(%theta: f64) adj qubits(%q)
    static_data = {pauli_word = "XYZ", greedy = true}

An operator with two qubit-mode controls:

%oq, %ocq:2 = quantum.operator "MyOp"() qubits(%q)
    ctrls(%cq0, %cq1) ctrl_vals(%cv0, %cv1)

An operator acting on a dynamic number of qubits, expressed in register mode, with explicit name-to-position maps for its parameters and wire arguments:

%out_qreg = quantum.operator "MyOp"(%state: tensor<?xcomplex<f64>>)
    quregs(%qreg) indices(%w0: tensor<?xi64>, %w1: tensor<1xi64>)
    param_map = {state_vector = [0]}
    qubit_map = {wires = [0], precision_wire = [1]}

An operator carrying frontend-level data (summarized by UID), together with pre-traced decomposition rules referenced through decompositions and extra dynamic data forwarded into those rules via forward(...):

%out:3 = quantum.operator "MyOp"(%state: tensor<8xcomplex<f64>>) qubits(%q0, %q1, %q2)
    UID(324958) forward(%phi: f64, %delta: f64)
    decompositions = [@MyOp324958_0, @MyOp324958_1]

Traits: AttrSizedOperandSegments, AttrSizedResultSegments, Unitary

Interfaces: NoMemoryEffect (MemoryEffectOpInterface), ParametrizedGate, QuantumGate, QuantumOperation

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
decompositions::mlir::ArrayAttrFlatSymbolRefArrayAttr with const builder
static_data::mlir::DictionaryAttrdictionary of named attribute values
param_map::mlir::DictionaryAttrdictionary of named attribute values dictionary with DenseI64ArrayAttr values
qubit_map::mlir::DictionaryAttrdictionary of named attribute values dictionary with DenseI64ArrayAttr values

Operands:

Operand

Description

params

variadic of any type

forward_args

variadic of any type

in_qubits

variadic of A value-semantic qubit (state).

in_ctrl_qubits

variadic of A value-semantic qubit (state).

in_ctrl_values

variadic of 1-bit signless integer

in_qreg

An array of value-semantic qubits (i.e. quantum register).

arr_qubit_indices

variadic of 1D tensor of 64-bit signless integer values

arr_ctrl_indices

1D tensor of 64-bit signless integer values

arr_ctrl_values

1D tensor of 1-bit signless integer values

Results:

Result

Description

out_qubits

variadic of A value-semantic qubit (state).

out_ctrl_qubits

variadic of A value-semantic qubit (state).

out_qreg

An array of value-semantic qubits (i.e. quantum register).

quantum.pcphase (::catalyst::quantum::PCPhaseOp)

Apply a projector-controlled phase gate

Syntax:

operation ::= `quantum.pcphase` `(` $theta `,` $dim `)` $in_qubits (`adj` $adjoint^)? attr-dict ( `ctrls` `(` $in_ctrl_qubits^ `)` )?  ( `ctrlvals` `(` $in_ctrl_values^ `)` )? `:` type($out_qubits) (`ctrls` type($out_ctrl_qubits)^ )?

This gate is built from simpler gates like PhaseShift and PauliX and acts on a group of wires and takes a rotation angle. It also takes another number, an integer called dim, which defines a specific part of the quantum state. The gate then applies a positive phase shift to a portion of the state defined by dim. At the same time, it applies a negative phase shift to the rest of the state.

Note

This operation is one of the few quantum operations that is not applied via quantum.custom. The reason for this is that it needs to be handled in a special way during the lowering due to its C function being variadic on the number of qubits.

Note

dim is currently captured as a float number for compatibility with runtime and device integration.

Traits: AttrSizedOperandSegments, AttrSizedResultSegments, Unitary

Interfaces: DifferentiableGate, NoMemoryEffect (MemoryEffectOpInterface), ParametrizedGate, QuantumGate, QuantumOperation

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
adjoint::mlir::UnitAttrunit attribute

Operands:

Operand

Description

theta

64-bit float

dim

64-bit float

in_qubits

variadic of A value-semantic qubit (state).

in_ctrl_qubits

variadic of A value-semantic qubit (state).

in_ctrl_values

variadic of 1-bit signless integer

Results:

Result

Description

out_qubits

variadic of A value-semantic qubit (state).

out_ctrl_qubits

variadic of A value-semantic qubit (state).

quantum.paulirot (::catalyst::quantum::PauliRotOp)

Apply a Pauli Product Rotation

Syntax:

operation ::= `quantum.paulirot` $pauli_product `(` $angle `)` $in_qubits (`adj` $adjoint^)? attr-dict ( `ctrls` `(` $in_ctrl_qubits^ `)` )?  ( `ctrlvals` `(` $in_ctrl_values^ `)` )? `:` type($out_qubits) (`ctrls` type($out_ctrl_qubits)^ )?

The quantum.paulirot operation applies a rotation around a Pauli product operator to the state-vector. The arguments are the rotation angle angle, a string representing the Pauli product operator, and a set of qubits the operation acts on.

Traits: AttrSizedOperandSegments, AttrSizedResultSegments, Unitary

Interfaces: DifferentiableGate, NoMemoryEffect (MemoryEffectOpInterface), ParametrizedGate, QuantumGate, QuantumOperation

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
pauli_product::mlir::ArrayAttrA product of Pauli operators, aka a Pauli word.
adjoint::mlir::UnitAttrunit attribute

Operands:

Operand

Description

angle

64-bit float

in_qubits

variadic of A value-semantic qubit (state).

in_ctrl_qubits

variadic of A value-semantic qubit (state).

in_ctrl_values

variadic of 1-bit signless integer

Results:

Result

Description

out_qubits

variadic of A value-semantic qubit (state).

out_ctrl_qubits

variadic of A value-semantic qubit (state).

quantum.probs (::catalyst::quantum::ProbsOp)

Compute computational basis probabilities for the current state

Syntax:

operation ::= `quantum.probs` $obs ( `shape` $dynamic_shape^ )?
              ( `in` `(` $state_in^ `:` type($state_in) `)` )?
              attr-dict ( `:` type($probabilities)^ )?

The quantum.probs operation represents the measurement process of computing probabilities for measurement outcomes in the computational basis for a set of qubits. Marginal probabilities are supported, that is the provided qubits do not need to make up the entire statevector. The result array contains one element for each possible bitstring, i.e. 2^n where n is the number of qubits.

Example:

func.func @foo(%q0: !quantum.bit, %q1: !quantum.bit)
{
    %probs = quantum.probs %q0, %q1 : tensor<4xf64>
    func.return
}

Note

The optional operand state_in is only used after bufferization.

Traits: AttrSizedOperandSegments

Interfaces: MeasurementProcess

Operands:

Operand

Description

obs

A quantum observable for use in measurements.

dynamic_shape

64-bit signless integer

state_in

1D memref of 64-bit float values

Results:

Result

Description

probabilities

1D tensor of 64-bit float values

quantum.unitary (::catalyst::quantum::QubitUnitaryOp)

Apply an arbitrary fixed unitary matrix

Syntax:

operation ::= `quantum.unitary` `(` $matrix `:` type($matrix) `)` $in_qubits (`adj` $adjoint^)? attr-dict ( `ctrls` `(` $in_ctrl_qubits^ `)` )?  ( `ctrlvals` `(` $in_ctrl_values^ `)` )? `:` type($out_qubits) (`ctrls` type($out_ctrl_qubits)^ )?

The quantum.unitary operation applies an arbitrary fixed unitary matrix to the state-vector. The arguments are a set of qubits and a 2-dim matrix of complex numbers that represents a Unitary matrix of size 2^(number of qubits) * 2^(number of qubits).

Traits: AttrSizedOperandSegments, AttrSizedResultSegments, Unitary

Interfaces: NoMemoryEffect (MemoryEffectOpInterface), ParametrizedGate, QuantumGate, QuantumOperation

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
adjoint::mlir::UnitAttrunit attribute

Operands:

Operand

Description

matrix

2D tensor of complex type with 64-bit float elements values or 2D memref of complex type with 64-bit float elements values

in_qubits

variadic of A value-semantic qubit (state).

in_ctrl_qubits

variadic of A value-semantic qubit (state).

in_ctrl_values

variadic of 1-bit signless integer

Results:

Result

Description

out_qubits

variadic of A value-semantic qubit (state).

out_ctrl_qubits

variadic of A value-semantic qubit (state).

quantum.sample (::catalyst::quantum::SampleOp)

Sample eigenvalues from the given observable for the current state

Syntax:

operation ::= `quantum.sample` $obs ( `shape` $dynamic_shape^ )?
              ( `in` `(` $in_data^ `:` type($in_data) `)` )?
              attr-dict ( `:` type($samples)^ )?

The quantum.sample operation represents the measurement process of sampling eigenvalues from an observable on the current quantum state. The only SSA argument is an observable that must be defined by an operation in the local scope. from an observable on the current quantum state. The number of samples to draw is determined by the device shots argument in the device initialization operation in the local scope.

Note that the return value type depends on the type of observable provided. Computational basis samples are returned as a 2D array of shape (shot number, number of qubits), with all other observables the output is a 1D array of length equal to the shot number.

Example:

func.func @foo(%q0: !quantum.bit, %q1: !quantum.bit, %shots: i64)
{
    quantum.device shots(%shots) ["rtd_lightning.so", "lightning.qubit", "{my_attr: my_attr_value}"]
    %obs1 = quantum.compbasis %q0, %q1 : !quantum.obs
    %samples = quantum.sample %obs1 : tensor<?xf64>

    %obs2 = quantum.pauli %q0[3], %q1[1] : !quantum.obs
    %samples2 = quantum.sample %obs2 : tensor<?x2xf64>

    func.return
}

Note

The return value type depends on the type of observable provided. Computational basis samples are returned as a 2D array of shape (shot number, number of qubits), with all other observables the output is a 1D array of length equal to the shot number.

Note

The in_data field is needed only after bufferization. It is an implementation detail that transform writers are unlikely to be worried about.

Traits: AttrSizedOperandSegments

Interfaces: MeasurementProcess

Operands:

Operand

Description

obs

A quantum observable for use in measurements.

dynamic_shape

variadic of 64-bit signless integer

in_data

1D memref of 64-bit float values or 2D memref of 64-bit float values

Results:

Result

Description

samples

1D tensor of 64-bit float values or 2D tensor of 64-bit float values

quantum.set_basis_state (::catalyst::quantum::SetBasisStateOp)

Set basis state.

Syntax:

operation ::= `quantum.set_basis_state` `(` $basis_state`)` $in_qubits attr-dict `:` functional-type(operands, results)

This operation is useful for simulators implementing set basis state. Instead of decomposing basis state into multiple operations, this operation shortcuts all of that into a single operation. This signature matches the one in pennylane-lightning which expects only a single integer as opposed to a binary digit.

Interfaces: QuantumOperation

Operands:

Operand

Description

basis_state

1D tensor of 1-bit signless integer values or 1D memref of 1-bit signless integer values

in_qubits

variadic of A value-semantic qubit (state).

Results:

Result

Description

out_qubits

variadic of A value-semantic qubit (state).

quantum.set_state (::catalyst::quantum::SetStateOp)

Set state to a complex vector.

Syntax:

operation ::= `quantum.set_state` `(` $in_state `)` $in_qubits attr-dict `:` functional-type(operands, results)

This operation is useful for simulators implementing state preparation. Instead of decomposing state preparation into multiple operations, this operation shortcuts all of that into a single operation.

Interfaces: QuantumOperation

Operands:

Operand

Description

in_state

1D tensor of complex type with 64-bit float elements values or 1D memref of complex type with 64-bit float elements values

in_qubits

variadic of A value-semantic qubit (state).

Results:

Result

Description

out_qubits

variadic of A value-semantic qubit (state).

quantum.state (::catalyst::quantum::StateOp)

Return the current statevector

Syntax:

operation ::= `quantum.state` $obs ( `shape` $dynamic_shape^ )?
              ( `in` `(` $state_in^ `:` type($state_in) `)` )?
              attr-dict ( `:` type($state)^ )?

The quantum.state operation represents the measurement process of returning the current statevector in the computational basis. Typically reserved for simulator devices, although in principle also achievable on hardware via tomography techniques. While marginal states are supported, the operation is only well-defined if the provided qubits are not entangled with the rest of the quantum state. The result array contains one (complex) element for each possible bitstring, i.e. 2^n where n is the number of qubits.

Example:

func.func @foo(%q0: !quantum.bit, %q1: !quantum.bit)
{
    %obs = quantum.compbasis qubits %q0, %q1 : !quantum.obs
    %state = quantum.state %obs : tensor<4xcomplex<f64>>
    func.return
}

Traits: AttrSizedOperandSegments

Interfaces: MeasurementProcess

Operands:

Operand

Description

obs

A quantum observable for use in measurements.

dynamic_shape

64-bit signless integer

state_in

1D memref of complex type with 64-bit float elements values

Results:

Result

Description

state

1D tensor of complex type with 64-bit float elements values

quantum.tensor (::catalyst::quantum::TensorOp)

Define a tensor product of observables for use in measurements

Syntax:

operation ::= `quantum.tensor` $terms attr-dict `:` type(results)

The quantum.tensor operation defines a quantum observable to be used by other operations such as measurement processes. The specific observable defined here represents the tensor product of observables on a set of qubits. The arguments are a set of quantum.Observable generated by quantum.namedobs and quantum.hermitian.

Example:

func.func @foo(%q0: !quantum.bit, %q1: !quantum.bit, %m: tensor<2x2xcomplex<f64>>)
{
    %obs1 = quantum.namedobs %q0[4] : !quantum.obs
    %obs2 = quantum.hermitian(%m: tensor<2x2xcomplex<f64>>) %q1 : !quantum.obs
    %res = quantum.tensorprod %obs1, %obs2 : !quantum.obs
    func.return
}

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand

Description

terms

variadic of A quantum observable for use in measurements.

Results:

Result

Description

obs

A quantum observable for use in measurements.

quantum.var (::catalyst::quantum::VarianceOp)

Compute the variance of the given observable for the current state

Syntax:

operation ::= `quantum.var` $obs attr-dict `:` type(results)

The quantum.var operation represents the measurement process of computing the variance of an observable on the current quantum state. While this quantity can be computed analytically on simulators, for hardware execution or shot noise simulation, the shots attached to the device in the local scope is used. The only SSA argument is an observable that must be defined by an operation in the local scope.

Example:

func.func @foo(%q: !quantum.bit)
{
    %obs = quantum.namedobs %q[4] : !quantum.obs
    %var = quantum.var %obs : f64

    func.return
}

Interfaces: MeasurementProcess

Operands:

Operand

Description

obs

A quantum observable for use in measurements.

Results:

Result

Description

variance

64-bit float

quantum.yield (::catalyst::quantum::YieldOp)

Return results from quantum program regions

Syntax:

operation ::= `quantum.yield` attr-dict ($retvals ^ `:` type($retvals))?

Traits: AlwaysSpeculatableImplTrait, HasParent<AdjointOp>, ReturnLike, Terminator

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface), RegionBranchTerminatorOpInterface

Effects: MemoryEffects::Effect{}

Operands:

Operand

Description

retvals

variadic of An array of value-semantic qubits (i.e. quantum register). or A value-semantic qubit (state).