Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

qamomile.quri_parts.transpiler

QURI Parts backend transpiler implementation.

This module provides QuriPartsTranspiler for converting Qamomile QKernels into QURI Parts quantum circuits.

Overview

FunctionDescription
emit_controlled_gateEmit a controlled version of a gate.
emit_controlled_pauli_evolveEmit exp(-i * gamma * H) under accumulated controls.
emit_multi_controlled_gateEmit one gate under an arbitrary number of accumulated controls.
evaluate_binopEvaluate a BinOp and store the result in bindings.
map_nested_controlled_u_resultsMap a nested controlled-U’s result values to physical qubits.
resolve_controlled_u_callResolve a (possibly nested) controlled-U call site to physical qubits.
resolve_powerResolve ControlledUOperation.power to a concrete int.
ClassDescription
BinOpBinary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN).
CompositeGateOperationRepresents a composite gate (QPE, QFT, etc.) as a single operation.
ControlledUOperationBase class for controlled-U operations.
EmitErrorError during backend code emission.
EmitPassBase class for backend-specific emission passes.
ForOperationRepresents a for loop operation.
GateOperationQuantum gate operation.
GateOperationType
InverseBlockOperationRepresent an inverse qkernel/block as a first-class IR operation.
PauliEvolveOpPauli evolution operation: exp(-i * gamma * H).
QamomileQuriPartsTranspileErrorException raised for errors in the Qamomile to QURI Parts conversion process.
QuriPartsEmitPassQURI Parts-specific emission pass.
QuriPartsExecutorQURI Parts quantum executor.
QuriPartsGateEmitterGateEmitter implementation for QURI Parts.
QuriPartsTranspilerQURI Parts transpiler for qamomile.circuit module.
ReturnOperationExplicit return operation marking the end of a block with return values.
SegmentationPassSegment a block into a strategy-specific executable program plan.
StandardEmitPassStandard emit pass implementation using GateEmitter protocol.
TranspilerBase class for backend-specific transpilers.

Functions

emit_controlled_gate [source]

def emit_controlled_gate(
    emit_pass: 'StandardEmitPass',
    circuit: Any,
    op: GateOperation,
    control_idx: int,
    target_indices: list[int],
    bindings: dict[str, Any],
) -> None

Emit a controlled version of a gate.


emit_controlled_pauli_evolve [source]

def emit_controlled_pauli_evolve(
    emit_pass: 'StandardEmitPass',
    circuit: Any,
    op: PauliEvolveOp,
    control_indices: list[int],
    qubit_map: QubitMap,
    bindings: dict[str, Any],
) -> None

Emit exp(-i * gamma * H) under accumulated controls.

Lowers a controlled Pauli evolution by exploiting that each Pauli term’s evolution exp(-i * theta * P) factors as U_dagger * RZ(2 * theta) * U where U (the basis change onto the Z axis followed by the parity CX ladder) is Clifford and thus control-independent. Controlling a conjugated gate is U_dagger * C[RZ] * U with U / U_dagger applied unconditionally: when every control is 0 the central RZ becomes the identity and U_dagger * I * U = I. Only the central RZ therefore carries the controls, which keeps the dense multi-controlled cost to a single rotation per Hamiltonian term instead of controlling every basis-change and ladder gate.

The basis-change (H / SDG / S) and CX-ladder gates are emitted uncontrolled through emit_pass._emitter; the central RZ is routed through :func:_emit_mc_rotation, which dispatches to emit_crz for a single control and to the backend’s _emit_irreducible_multi_controlled_gate hook for two or more.

A constant (identity) Hamiltonian term c * I is a global phase exp(-i * gamma * c) for the uncontrolled evolution (correctly dropped by :func:emit_pauli_evolve), but under controls it becomes an observable relative phase on the all-controls-on subspace, so it MUST be emitted here. It is realized as a P(-gamma * c) on one control conditioned on the remaining controls (emit_p for a single control, a controlled / dense P for more), matching Qiskit’s native PauliEvolutionGate whose SparsePauliOp carries the constant.

Parameters:

NameTypeDescription
emit_passStandardEmitPassActive emit pass; provides the value resolver, gate emitter, and the multi-controlled rotation hook.
circuitAnyBackend circuit being emitted into.
opPauliEvolveOpThe Pauli evolution operation inside the controlled block.
control_indiceslist[int]Accumulated physical control qubits. Must be non-empty.
qubit_mapQubitMapBlock-local qubit map the operation’s quantum operands resolve against; updated in place with the evolved-register result addresses.
bindingsdict[str, Any]Bindings visible inside the block, used to resolve the Hamiltonian, gamma, and register shape.

Raises:


emit_multi_controlled_gate [source]

def emit_multi_controlled_gate(
    emit_pass: 'StandardEmitPass',
    circuit: Any,
    op: GateOperation,
    control_indices: list[int],
    target_indices: list[int],
    bindings: dict[str, Any],
) -> None

Emit one gate under an arbitrary number of accumulated controls.

Structurally reduces multi-qubit gate types to single-target forms by absorbing their own control qubits into the control set (CX -> X, CZ -> Z, CP -> P, TOFFOLI -> X; SWAP and RZZ via their standard CX conjugations), then emits:

Parameters:

NameTypeDescription
emit_passStandardEmitPassActive emit pass. Subclass overrides of _emit_irreducible_multi_controlled_gate are respected for the irreducible tail.
circuitAnyBackend circuit being emitted into.
opGateOperationGate operation whose operands are already resolved to target_indices.
control_indiceslist[int]Physical control qubits. Must be non-empty.
target_indiceslist[int]Physical qubits for the gate’s own operands, in operand order.
bindingsdict[str, Any]Bindings used to resolve rotation angles.

Raises:


evaluate_binop [source]

def evaluate_binop(emit_pass: 'StandardEmitPass', op: BinOp, bindings: dict[str, Any]) -> None

Evaluate a BinOp and store the result in bindings.

Tries the shared fold_classical_op first for a clean concrete fold (which already encapsulates the runtime-parameter guard). Falls back to creating backend Parameter symbols and doing symbolic arithmetic when one or both operands are runtime parameters — that’s the path that lets rx(q, gamma * 2) produce a circuit with a single Parameter("gamma") * 2 expression rather than baking in a placeholder.


map_nested_controlled_u_results [source]

def map_nested_controlled_u_results(
    op: ControlledUOperation,
    resolved: ResolvedControlledU,
    qubit_map: QubitMap,
) -> None

Map a nested controlled-U’s result values to physical qubits.

The result layout mirrors the operand layout for every controlled-U shape: one result per control operand slot followed by one result per sub-kernel quantum operand. Controlled gates only add a relative phase — no qubit moves — so each result keeps the physical slots of its operand. For the control_indices pool form the whole pool passes through, selected controls included.

Parameters:

NameTypeDescription
opControlledUOperationThe operation whose results need mapping.
resolvedResolvedControlledUPhysical resolution returned by :func:resolve_controlled_u_call for this operation.
qubit_mapQubitMapMutable qubit map updated in place.

resolve_controlled_u_call [source]

def resolve_controlled_u_call(
    emit_pass: 'StandardEmitPass',
    op: ControlledUOperation,
    qubit_map: QubitMap,
    bindings: dict[str, Any],
) -> ResolvedControlledU

Resolve a (possibly nested) controlled-U call site to physical qubits.

Handles all three operand layouts:

Parameters:

NameTypeDescription
emit_passStandardEmitPassActive emit pass; provides the value resolver.
opControlledUOperationThe controlled-U operation to resolve.
qubit_mapQubitMapQubit map the operands resolve against (block-local when called from a controlled walker).
bindingsdict[str, Any]Bindings visible at the call site, including loop-iteration values during unrolling.

Returns:

ResolvedControlledU — Physical controls / targets and the inner-block bindings.

Raises:


resolve_power [source]

def resolve_power(
    emit_pass: 'StandardEmitPass',
    op: ControlledUOperation,
    bindings: dict[str, Any],
) -> int

Resolve ControlledUOperation.power to a concrete int.

Classes

BinOp [source]

class BinOp(BinaryOperationBase)

Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN).

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    kind: BinOpKind | None = None,
) -> None
Attributes

CompositeGateOperation [source]

class CompositeGateOperation(Operation)

Represents a composite gate (QPE, QFT, etc.) as a single operation.

CompositeGate allows representing complex multi-gate operations as a single atomic operation in the IR. This enables:

The operands structure is:

The results structure:

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    gate_type: CompositeGateType = CompositeGateType.CUSTOM,
    num_control_qubits: int = 0,
    num_target_qubits: int = 0,
    custom_name: str = '',
    resource_metadata: ResourceMetadata | None = None,
    has_implementation: bool = True,
    implementation_block: Block | None = None,
    composite_gate_instance: Any = None,
    strategy_name: str | None = None,
) -> None
Attributes

ControlledUOperation [source]

class ControlledUOperation(Operation)

Base class for controlled-U operations.

Two concrete subclasses handle distinct operand layouts:

All isinstance(op, ControlledUOperation) checks match every subclass.

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    power: int | Value = 1,
    block: Block | None = None,
    num_controls: int | Value = 1,
) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]
replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

EmitError [source]

class EmitError(QamomileCompileError)

Error during backend code emission.

Constructor
def __init__(self, message: str, operation: str | None = None)
Attributes

EmitPass [source]

class EmitPass(Pass[ProgramPlan, ExecutableProgram[T]], Generic[T])

Base class for backend-specific emission passes.

Subclasses implement _emit_quantum_segment() to generate backend-specific quantum circuits.

Input: ProgramPlan Output: ExecutableProgram with compiled segments

Constructor
def __init__(
    self,
    bindings: dict[str, Any] | None = None,
    parameters: list[str] | None = None,
)

Initialize with optional parameter bindings.

Parameters:

NameTypeDescription
bindingsdict[str, Any] | NoneValues to bind parameters to. If not provided, parameters must be bound at execution time.
parameterslist[str] | NoneList of parameter names to preserve as backend parameters.
Attributes
Methods
run
def run(self, input: ProgramPlan) -> ExecutableProgram[T]

Emit backend code from a program plan.


ForOperation [source]

class ForOperation(HasNestedOps, Operation)

Represents a for loop operation.

Example:

for i in range(start, stop, step):
    body
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    loop_var: str = '',
    loop_var_value: Value | None = None,
    operations: list[Operation] = list(),
) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Include loop_var_value so cloning/substitution stays consistent.

Without this override, UUIDRemapper would clone every body reference to the loop variable to a fresh UUID, but leave loop_var_value pointing at the un-cloned original — emit-time UUID-keyed lookups for the loop variable would then miss.

nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]
rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation
replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

GateOperation [source]

class GateOperation(Operation)

Quantum gate operation.

For rotation gates (RX, RY, RZ, P, CP, RZZ), the angle parameter is stored as the last element of operands. Use the theta property for typed read access and the rotation / fixed factory class-methods for type-safe construction.

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    gate_type: GateOperationType | None = None,
) -> None
Attributes
Methods
fixed
@classmethod
def fixed(
    cls,
    gate_type: GateOperationType,
    qubits: list[Value],
    results: list[Value],
) -> 'GateOperation'

Create a fixed gate (H, X, CX, SWAP, …) with no angle parameter.

rotation
@classmethod
def rotation(
    cls,
    gate_type: GateOperationType,
    qubits: list[Value],
    theta: Value,
    results: list[Value],
) -> 'GateOperation'

Create a rotation gate (RX, RY, RZ, P, CP, RZZ) with an angle.


GateOperationType [source]

class GateOperationType(enum.Enum)
Attributes

InverseBlockOperation [source]

class InverseBlockOperation(Operation)

Represent an inverse qkernel/block as a first-class IR operation.

The operation stores both the original forward block and a Qamomile-built inverse implementation block. Emitters may use source_block with a backend-native inverse/adjoint primitive, then fall back to implementation_block when native inversion is unavailable.

Operands are ordered as control qubits, target quantum operands, then classical/object parameters. Results mirror the quantum operand layout: control results first, then one target result per target operand. Vector target operands therefore count as one operand/result while contributing their scalar width to num_target_qubits.

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    num_control_qubits: int = 0,
    num_target_qubits: int = 0,
    custom_name: str = '',
    source_block: Block | None = None,
    implementation_block: Block | None = None,
) -> None
Attributes

PauliEvolveOp [source]

class PauliEvolveOp(Operation)

Pauli evolution operation: exp(-i * gamma * H).

This operation applies the time evolution of a Pauli Hamiltonian to a quantum register.

Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

QamomileQuriPartsTranspileError [source]

class QamomileQuriPartsTranspileError(QamomileCompileError)

Exception raised for errors in the Qamomile to QURI Parts conversion process.


QuriPartsEmitPass [source]

class QuriPartsEmitPass(StandardEmitPass['qp_c.LinearMappedUnboundParametricQuantumCircuit'])

QURI Parts-specific emission pass.

Uses StandardEmitPass with QuriPartsGateEmitter for gate emission. QURI Parts does not support native control flow, so all loops are unrolled.

Constructor
def __init__(
    self,
    bindings: dict[str, Any] | None = None,
    parameters: list[str] | None = None,
)

Initialize the QURI Parts emit pass.

Parameters:

NameTypeDescription
bindingsdict[str, Any] | NoneParameter bindings for the circuit
parameterslist[str] | NoneList of parameter names to preserve as backend parameters

QuriPartsExecutor [source]

class QuriPartsExecutor(QuantumExecutor['qp_c.LinearMappedUnboundParametricQuantumCircuit'])

QURI Parts quantum executor.

Supports both sampling and expectation value estimation. Uses Qulacs backend by default for efficient simulation.

Example:

executor = QuriPartsExecutor()  # Uses Qulacs by default
counts = executor.execute(circuit, shots=1000)
# counts: {"00": 512, "11": 512}
Constructor
def __init__(self, sampler: Any = None, estimator: Any = None, seed: int | None = None)

Initialize executor with optional sampler, estimator, and seed.

Parameters:

NameTypeDescription
samplerAnyQURI Parts sampler. Defaults to None, meaning a qulacs vector sampler is created lazily on first use.
estimatorAnyQURI Parts parametric estimator. Defaults to None, meaning a qulacs parametric estimator is created lazily on first use.
seedint | NoneOptional random seed forwarded to the qulacs vector sampler so that sampling is reproducible. When set, two execute calls with the same seed and circuit return identical shot counts, which unblocks reproducible tutorials and benchmarks. Defaults to None, meaning sampling is non-deterministic. The seed is only applied to the default qulacs sampler; it is ignored when a custom sampler is supplied, since an arbitrary sampler has no standard seed interface.
Attributes
Methods
bind_parameters
def bind_parameters(
    self,
    circuit: 'qp_c.LinearMappedUnboundParametricQuantumCircuit',
    bindings: dict[str, Any],
    parameter_metadata: ParameterMetadata,
) -> 'ImmutableBoundParametricQuantumCircuit'

Bind parameter values to the QURI Parts circuit.

QURI Parts requires parameter values as a sequence in the order parameters were added to the circuit.

Parameters:

NameTypeDescription
circuit'qp_c.LinearMappedUnboundParametricQuantumCircuit'The unbound parametric circuit
bindingsdict[str, Any]Dictionary of parameter name to value
parameter_metadataParameterMetadataMetadata about the parameters

Returns:

'ImmutableBoundParametricQuantumCircuit' — Bound parametric circuit

Raises:

estimate
def estimate(
    self,
    circuit: 'qp_c.LinearMappedUnboundParametricQuantumCircuit',
    hamiltonian: 'qm_o.Hamiltonian',
    params: Sequence[float] | None = None,
) -> float

Estimate expectation value <psi|H|psi>.

Also accepts a native quri_parts.core.operator.Operator at runtime for convenience (auto-conversion is skipped in that case).

Parameters:

NameTypeDescription
circuit'qp_c.LinearMappedUnboundParametricQuantumCircuit'The unbound parametric circuit (state preparation ansatz)
hamiltonian'qm_o.Hamiltonian'Hamiltonian to measure (qamomile Hamiltonian or native QURI Parts Operator at runtime)
paramsSequence[float] | NoneParameter values for the parametric circuit

Returns:

float — Real part of the expectation value

estimate_expectation
def estimate_expectation(
    self,
    circuit: 'qp_c.LinearMappedUnboundParametricQuantumCircuit',
    hamiltonian: 'qp_o.Operator',
    param_values: Sequence[float],
) -> float

Estimate expectation value of hamiltonian for a circuit.

Handles both unbound parametric circuits (used during optimization) and already-bound or non-parametric circuits. When the circuit has already been bound (e.g., by _run_expval in ExecutableProgram), apply_circuit produces a GeneralCircuitQuantumState instead of a ParametricCircuitQuantumState, so we dispatch to the non-parametric estimator automatically.

Parameters:

NameTypeDescription
circuit'qp_c.LinearMappedUnboundParametricQuantumCircuit'The quantum circuit (unbound parametric or bound/concrete)
hamiltonian'qp_o.Operator'QURI Parts Operator representing the Hamiltonian
param_valuesSequence[float]Sequence of parameter values in order (ignored for bound/non-parametric circuits)

Returns:

float — Real part of the expectation value

execute
def execute(self, circuit: Any, shots: int) -> dict[str, int]

Execute circuit and return bitstring counts.

Parameters:

NameTypeDescription
circuitAnyThe quantum circuit to execute (bound or unbound)
shotsintNumber of measurement shots

Returns:

dict[str, int] — Dictionary mapping bitstrings to counts (e.g., {“00”: 512, “11”: 512})


QuriPartsGateEmitter [source]

class QuriPartsGateEmitter

GateEmitter implementation for QURI Parts.

Emits individual quantum gates to QURI Parts circuits.

QURI Parts parametric circuits accept angles in dictionary form: {parameter: coefficient, CONST: constant_offset}

Constructor
def __init__(self) -> None

Initialize the emitter.

Attributes
Methods
append_gate
def append_gate(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    gate: Any,
    qubits: list[int],
) -> None

Append a gate to the circuit.

Since circuit_to_gate returns None, this is only called with QURI Parts native gates which can be extended into the circuit.

circuit_to_gate
def circuit_to_gate(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    name: str = 'U',
) -> Any

QURI Parts doesn’t support converting circuits to gates.

Returns None to signal that manual decomposition should be used.

combine_symbolic
def combine_symbolic(self, kind: BinOpKind, lhs: Any, rhs: Any) -> 'dict[Parameter, float]'

Combine two angle operands as a QURI Parts linear-combination dict.

QURI Parts’ Parameter is Rust-backed and exposes no Python arithmetic operators (param * float raises TypeError). The only supported representation for parametric angles is the linear-combination dict consumed by LinearMappedUnboundParametricQuantumCircuit.add_Parametric*, which fundamentally cannot express non-linear combinations (parameter × parameter, parameter ** n, etc.). This override produces such a dict for every linear case and raises a clear QamomileQuriPartsTranspileError for non-linear cases instead of letting the underlying TypeError bubble up.

Parameters:

NameTypeDescription
kindBinOpKindThe BinOpKind from the IR.
lhsAnyLeft operand (numeric, QURI Parts Parameter, or an existing linear-combination dict).
rhsAnyRight operand (same shapes).

Returns:

'dict[Parameter, float]' — A fresh dict[Parameter, float] representing the linear 'dict[Parameter, float]' — combination of the operands.

Raises:

create_circuit
def create_circuit(
    self,
    num_qubits: int,
    num_clbits: int,
) -> 'LinearMappedUnboundParametricQuantumCircuit'

Create a new QURI Parts parametric circuit.

Note: QURI Parts does not support classical bits in circuits. The num_clbits parameter is accepted for interface compatibility but is not used.

create_parameter
def create_parameter(self, name: str) -> 'Parameter'

Create a QURI Parts parameter and register it with the circuit.

emit_barrier
def emit_barrier(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    qubits: list[int],
) -> None

No-op: QURI Parts doesn’t support barrier instructions.

emit_ch
def emit_ch(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    control: int,
    target: int,
) -> None

Emit controlled-Hadamard gate using decomposition.

Follows the shared CH_DECOMPOSITION recipe from qamomile.circuit.transpiler.decompositions.

emit_cp
def emit_cp(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    control: int,
    target: int,
    angle: float | Any,
) -> None

Emit controlled-Phase gate using decomposition.

Follows the shared CP_DECOMPOSITION recipe from qamomile.circuit.transpiler.decompositions. Inlined here because QURI Parts parametric angles use dict representation.

emit_crx
def emit_crx(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    control: int,
    target: int,
    angle: float | Any,
) -> None

Emit controlled-RX gate using decomposition.

CRX(ctrl, tgt, θ) = RZ(tgt, π/2) CNOT(ctrl, tgt) RY(tgt, -θ/2) CNOT(ctrl, tgt) RY(tgt, θ/2) RZ(tgt, -π/2)

emit_cry
def emit_cry(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    control: int,
    target: int,
    angle: float | Any,
) -> None

Emit controlled-RY gate using decomposition.

Follows the shared CRY_DECOMPOSITION recipe from qamomile.circuit.transpiler.decompositions. Inlined here because QURI Parts parametric angles use dict representation.

emit_crz
def emit_crz(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    control: int,
    target: int,
    angle: float | Any,
) -> None

Emit controlled-RZ gate using decomposition.

Follows the shared CRZ_DECOMPOSITION recipe from qamomile.circuit.transpiler.decompositions. Inlined here because QURI Parts parametric angles use dict representation.

emit_cx
def emit_cx(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    control: int,
    target: int,
) -> None

Emit CNOT (controlled-X) gate.

emit_cy
def emit_cy(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    control: int,
    target: int,
) -> None

Emit controlled-Y gate using decomposition.

Follows the shared CY_DECOMPOSITION recipe from qamomile.circuit.transpiler.decompositions.

emit_cz
def emit_cz(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    control: int,
    target: int,
) -> None

Emit controlled-Z gate.

emit_h
def emit_h(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    qubit: int,
) -> None

Emit Hadamard gate.

emit_measure
def emit_measure(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    qubit: int,
    clbit: int,
) -> None

No-op: QURI Parts circuits don’t support measurement gates.

Measurement is handled separately by samplers/estimators.

emit_p
def emit_p(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    qubit: int,
    angle: float | Any,
) -> None

Emit Phase gate using U1.

P(θ) = U1(θ) = diag(1, e^{iθ}). For non-parametric angles we use the native U1 gate which is mathematically identical to the Phase gate. For parametric angles we fall back to ParametricRZ because QURI Parts does not provide a ParametricU1 gate. RZ differs only by a global phase: P(θ) = e^{iθ/2} · RZ(θ), which is physically irrelevant for single-qubit usage. Controlled-phase (CP) has its own decomposition and does not go through this path.

emit_rx
def emit_rx(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    qubit: int,
    angle: float | Any,
) -> None

Emit RX rotation gate.

emit_ry
def emit_ry(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    qubit: int,
    angle: float | Any,
) -> None

Emit RY rotation gate.

emit_rz
def emit_rz(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    qubit: int,
    angle: float | Any,
) -> None

Emit RZ rotation gate.

emit_rzz
def emit_rzz(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    qubit1: int,
    qubit2: int,
    angle: float | Any,
) -> None

Emit RZZ gate using ParametricPauliRotation.

emit_s
def emit_s(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    qubit: int,
) -> None

Emit S (phase) gate.

emit_sdg
def emit_sdg(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    qubit: int,
) -> None

Emit S-dagger (inverse S) gate.

emit_swap
def emit_swap(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    qubit1: int,
    qubit2: int,
) -> None

Emit SWAP gate.

emit_t
def emit_t(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    qubit: int,
) -> None

Emit T gate.

emit_tdg
def emit_tdg(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    qubit: int,
) -> None

Emit T-dagger (inverse T) gate.

emit_toffoli
def emit_toffoli(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    control1: int,
    control2: int,
    target: int,
) -> None

Emit Toffoli (CCX) gate.

emit_x
def emit_x(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    qubit: int,
) -> None

Emit Pauli-X gate.

emit_y
def emit_y(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    qubit: int,
) -> None

Emit Pauli-Y gate.

emit_z
def emit_z(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    qubit: int,
) -> None

Emit Pauli-Z gate.

gate_controlled
def gate_controlled(self, gate: Any, num_controls: int) -> Any

Create controlled version of a gate.

Returns None since QURI Parts doesn’t support this natively.

gate_inverse
def gate_inverse(self, gate: Any) -> Any

Return the inverse of a concrete QURI Parts circuit.

Parameters:

NameTypeDescription
gateAnyCandidate QURI Parts circuit to invert. Runtime parametric circuits are expected to fall back to Qamomile’s gate-by-gate inverse implementation.

Returns:

Any — Inverted QURI Parts circuit when inverse_circuit can handle gate; otherwise None so callers can fall back to Qamomile-level decomposition.

gate_power
def gate_power(self, gate: Any, power: int) -> Any

Create gate raised to a power.

Returns None since QURI Parts doesn’t support this natively.

supports_for_loop
def supports_for_loop(self) -> bool

QURI Parts does not support native for loops.

supports_gate_inverse
def supports_gate_inverse(self) -> bool

Report QURI Parts circuit inverse support.

Returns:

bool — True because gate_inverse can invert concrete bool — QURI Parts circuits. The backend still reports no reusable bool — gate support, so inverse blocks normally use the bool — transpiler-level native path rather than the shared boolblockvalue_to_gate path.

supports_if_else
def supports_if_else(self) -> bool

QURI Parts does not support native if/else.

supports_while_loop
def supports_while_loop(self) -> bool

QURI Parts does not support native while loops.


QuriPartsTranspiler [source]

class QuriPartsTranspiler(Transpiler['qp_c.LinearMappedUnboundParametricQuantumCircuit'])

QURI Parts transpiler for qamomile.circuit module.

Converts Qamomile QKernels into QURI Parts quantum circuits.

Example:

from qamomile.quri_parts import QuriPartsTranspiler
import qamomile.circuit as qm

@qm.qkernel
def bell_state(q0: qm.Qubit, q1: qm.Qubit) -> tuple[qm.Bit, qm.Bit]:
    q0 = qm.h(q0)
    q0, q1 = qm.cx(q0, q1)
    return qm.measure(q0), qm.measure(q1)

transpiler = QuriPartsTranspiler()
circuit = transpiler.to_circuit(bell_state)
Methods
executor
def executor(
    self,
    sampler: Any = None,
    estimator: Any = None,
    seed: int | None = None,
) -> QuriPartsExecutor

Create a QURI Parts executor.

Parameters:

NameTypeDescription
samplerAnyOptional custom sampler. Defaults to None, meaning the qulacs vector sampler is used.
estimatorAnyOptional custom estimator. Defaults to None, meaning the qulacs parametric estimator is used.
seedint | NoneOptional random seed forwarded to the qulacs vector sampler for reproducible sampling. Defaults to None, meaning sampling is non-deterministic. The seed is ignored when a custom sampler is supplied, since an arbitrary sampler has no standard seed interface.

Returns:

QuriPartsExecutor — Executor configured for this backend, bound to the given seed.


ReturnOperation [source]

class ReturnOperation(Operation)

Explicit return operation marking the end of a block with return values.

This operation represents an explicit return statement in the IR. It takes the values to be returned as operands and produces no results (it is a terminal operation that transfers control flow back to the caller).

operands: [Value, ...] - The values to return (may be empty for void returns) results: [] - Always empty (terminal operation)

Example:

A function that returns two values (a UInt and a Float):

ReturnOperation(
    operands=[uint_value, float_value],
    results=[],
)

The signature would be:
    operands=[ParamHint("return_0", UIntType()), ParamHint("return_1", FloatType())]
    results=[]
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

SegmentationPass [source]

class SegmentationPass(Pass[Block, ProgramPlan])

Segment a block into a strategy-specific executable program plan.

This pass:

  1. Materializes return operations (syncs output_values from ReturnOperation)

  2. Splits the operation list into quantum and classical segments

  3. Builds a ProgramPlan via the configured segmentation strategy

Input: Block (typically ANALYZED or AFFINE) Output: ProgramPlan

Constructor
def __init__(self, strategy: SegmentationStrategy | None = None) -> None
Attributes
Methods
run
def run(self, input: Block) -> ProgramPlan

Segment the block into a ProgramPlan.


StandardEmitPass [source]

class StandardEmitPass(EmitPass[T], Generic[T])

Standard emit pass implementation using GateEmitter protocol.

This class provides the orchestration logic for circuit emission while delegating backend-specific operations to a GateEmitter.

Subclasses (QiskitEmitPass, CudaqEmitPass) override specific methods to provide native backend support. The thin wrappers here delegate to module functions in emit_support/ by default.

Parameters:

NameTypeDescription
gate_emitterGateEmitter[T]Backend-specific gate emitter
bindingsdict[str, Any] | NoneParameter bindings for the circuit
parameterslist[str] | NoneList of parameter names to preserve as backend parameters
composite_emitterslist[CompositeGateEmitter[T]] | NoneOptional list of CompositeGateEmitter for native implementations
Constructor
def __init__(
    self,
    gate_emitter: GateEmitter[T],
    bindings: dict[str, Any] | None = None,
    parameters: list[str] | None = None,
    composite_emitters: list[CompositeGateEmitter[T]] | None = None,
)

Transpiler [source]

class Transpiler(ABC, Generic[T])

Base class for backend-specific transpilers.

Provides the full compilation pipeline from QKernel to executable program.

Usage:

transpiler = QiskitTranspiler()

Option 1: Full pipeline

executable = transpiler.compile(kernel, bindings={“theta”: 0.5}) results = executable.run(transpiler.executor())

Option 2: Step-by-step

block = transpiler.to_block(kernel) substituted = transpiler.substitute(block) affine = transpiler.inline(substituted) validated = transpiler.affine_validate(affine) folded = transpiler.constant_fold(validated, bindings={“theta”: 0.5}) analyzed = transpiler.analyze(folded) plan = transpiler.plan(analyzed) executable = transpiler.emit(plan, bindings={“theta”: 0.5})

Option 3: Just get the circuit (no execution)

circuit = transpiler.to_circuit(kernel, bindings={“theta”: 0.5})

With configuration (strategy overrides)

config = TranspilerConfig.with_strategies({“qft”: “approximate”}) transpiler = QiskitTranspiler(config=config)

Attributes
Methods
affine_validate
def affine_validate(self, block: Block) -> Block

Pass 1.5: Validate affine type semantics.

This is a safety net to catch affine type violations that may have bypassed frontend checks. Validates that quantum values are used at most once.

analyze
def analyze(self, block: Block) -> Block

Pass 2: Validate and analyze dependencies.

classical_lowering
def classical_lowering(self, block: Block) -> Block

Pass 2.25: Lower measurement-derived classical ops.

Identifies CompOp / CondOp / NotOp / BinOp instances whose operand dataflow traces back to a measurement and rewrites them to RuntimeClassicalExpr. Compile-time-foldable and emit-time-foldable (loop-bound, parameter-bound) classical ops are left unchanged.

Runs after analyze so the measurement-taint analysis has the full dependency graph available, and before validate_symbolic_shapes / plan / emit so downstream passes can rely on the cleaner IR (in particular: future segmentation work can dispatch on RuntimeClassicalExpr type instead of the BitType-only heuristic).

constant_fold
def constant_fold(self, block: Block, bindings: dict[str, Any] | None = None) -> Block

Pass 1.5: Fold constant expressions.

Evaluates BinOp operations when all operands are constants or bound parameters. This prevents quantum segment splitting from parametric expressions like phase * 2.

emit
def emit(
    self,
    separated: ProgramPlan,
    bindings: dict[str, Any] | None = None,
    parameters: list[str] | None = None,
) -> ExecutableProgram[T]

Pass 4: Generate backend-specific code.

Parameters:

NameTypeDescription
separatedProgramPlanThe separated program to emit
bindingsdict[str, Any] | NoneParameter values to bind at compile time
parameterslist[str] | NoneParameter names to preserve as backend parameters
executor
def executor(self, **kwargs: Any = {}) -> QuantumExecutor[T]

Create a quantum executor for this backend.

inline
def inline(self, block: Block) -> Block

Pass 1: Inline all CallBlockOperations.

lower_compile_time_ifs
def lower_compile_time_ifs(self, block: Block, bindings: dict[str, Any] | None = None) -> Block

Pass 1.75: Lower compile-time resolvable IfOperations.

Evaluates IfOperation conditions (including expression-derived conditions via CompOp/CondOp/NotOp) and replaces resolved ones with selected-branch operations. Phi outputs are substituted with selected-branch values throughout the block.

This prevents SegmentationPass from seeing classical-only compile-time IfOperations that would otherwise split quantum segments.

partial_eval
def partial_eval(self, block: Block, bindings: dict[str, Any] | None = None) -> Block

Pass 1.75: Fold constants and lower compile-time control flow.

plan
def plan(self, block: Block) -> ProgramPlan

Pass 3: Lower and split into a program plan.

Validates C→Q→C pattern with single quantum segment.

resolve_parameter_shapes
def resolve_parameter_shapes(self, block: Block, bindings: dict[str, Any] | None = None) -> Block

Pass 0.75: Resolve symbolic Vector parameter shape dims.

Qamomile circuits are compile-time fixed-structure. Parameter Vector[Float] / Vector[UInt] inputs carry symbolic {name}_dim{i} shape Values so frontend code like arr.shape[0] returns a usable handle. This pass looks at bindings and, for every parameter array that has a concrete binding, substitutes those symbolic dims with constants so that downstream loop-bound resolution sees fixed lengths.

Parameters without a concrete binding are left as-is; their symbolic dims are harmless as long as no compile-time structure decision depends on them (the library QAOA pattern).

set_config
def set_config(self, config: TranspilerConfig) -> None

Set the transpiler configuration.

Parameters:

NameTypeDescription
configTranspilerConfigTranspiler configuration to use
slice_borrow_check
def slice_borrow_check(self, block: Block) -> Block

Pass 1.9: Post-fold slice-view linearity checker.

Runs after :meth:partial_eval has resolved slice bounds to concrete values. Catches the slice-view linearity violations that the trace-time frontend check cannot detect on its own — specifically, slices whose bounds were symbolic at trace time (so the frontend bulk-borrow tracker had to skip them) and aliasing scenarios that only become visible once those bounds are folded to constants:

  1. A view whose newly-concrete coverage overlaps another live view of the same root parent.

  2. A view whose newly-concrete coverage hits a slot that was consumed by a destructive view operation earlier in the block.

  3. A view that reaches the end of the block while still recorded as the owner of the parent’s slots (i.e. it was never used or never released).

Direct element borrows (q[i]) emit no IR operation, so the IR-level pass cannot observe them; the trace-time validation in :func:func_to_block._validate_returned_arrays covers that path.

The pass is a pass-through for the IR — it only raises on violations and leaves the block unchanged on success.

strip_slice_ops
def strip_slice_ops(self, block: Block) -> Block

Pass 1.95: Remove SliceArrayOperation nodes from the block.

PartialEvaluationPass keeps these declarative ops through constant folding so :meth:slice_borrow_check can use them as view-declaration markers. Once the linearity check has run, segmentation and downstream passes expect a classical-op-free quantum stream — this pass performs that cleanup.

substitute
def substitute(self, block: Block) -> Block

Pass 0.5: Apply substitutions (optional).

This pass replaces CallBlockOperation targets and sets strategy names on CompositeGateOperations based on config.

Parameters:

NameTypeDescription
blockBlockBlock to transform

Returns:

Block — Block with substitutions applied

to_block
def to_block(
    self,
    kernel: QKernel,
    bindings: dict[str, Any] | None = None,
    parameters: list[str] | None = None,
) -> Block

Convert a QKernel to a Block.

Parameters:

NameTypeDescription
kernelQKernelThe QKernel to convert
bindingsdict[str, Any] | NoneConcrete values to bind at trace time (resolves array shapes)
parameterslist[str] | NoneNames to keep as unbound parameters

When bindings or parameters are provided, uses kernel.build() to properly resolve array shapes from the bound data. Otherwise uses the cached hierarchical block for efficiency.

to_circuit
def to_circuit(self, kernel: QKernel, bindings: dict[str, Any] | None = None) -> T

Compile and extract just the quantum circuit.

This is a convenience method for when you just want the backend circuit without the full executable.

Parameters:

NameTypeDescription
kernelQKernelThe QKernel to compile
bindingsdict[str, Any] | NoneParameter values to bind

Returns:

T — Backend-specific quantum circuit

transpile
def transpile(
    self,
    kernel: QKernel,
    bindings: dict[str, Any] | None = None,
    parameters: list[str] | None = None,
) -> ExecutableProgram[T]

Full compilation pipeline from QKernel to executable.

Parameters:

NameTypeDescription
kernelQKernelThe QKernel to compile
bindingsdict[str, Any] | NoneParameter values to bind (also resolves array shapes). Names in bindings and parameters must be disjoint — a name is either compile-time bound or runtime symbolic, never both.
parameterslist[str] | NoneParameter names to preserve as backend parameters

Returns:

ExecutableProgram[T] — ExecutableProgram ready for execution

Raises:

Pipeline:

  1. to_block: Convert QKernel to Block

  2. substitute: Apply substitutions (if configured)

  3. resolve_parameter_shapes: Constant-fold symbolic Vector param dims

  4. inline: Inline CallBlockOperations

  5. affine_validate: Validate affine type semantics

  6. partial_eval: Fold constants and lower compile-time control flow

  7. analyze: Validate and analyze dependencies

  8. validate_symbolic_shapes: Reject unresolved parameter shape dims

  9. plan: Build ProgramPlan (segment into C->Q->C steps)

  10. emit: Generate backend-specific code

unroll_recursion
def unroll_recursion(self, block: Block, bindings: dict[str, Any] | None = None) -> Block

Fixed-point loop of inline ↔ partial_eval for self-recursive kernels.

Each iteration unrolls one layer of self-referential CallBlockOperation and then folds the base-case IfOperation via partial_eval. Terminates when no CallBlockOperation remains (success), when every residual call is trapped inside an operation-owned block where partial_eval cannot fold it (control / inverse of a recursive kernel — raises a targeted error, see below), or when MAX_UNROLL_DEPTH is reached (genuinely non-terminating top-level recursion — raises).

Parameters:

NameTypeDescription
blockBlockThe block to unroll. May be HIERARCHICAL (still containing self-referential CallBlockOperations) or already AFFINE (returned unchanged).
bindingsdict[str, Any] | NoneCompile-time bindings used by partial_eval to fold the base-case condition. Defaults to None, meaning no bindings are applied.

Returns:

Block — The fully unrolled, AFFINE block once no CallBlockOperation remains. Returned unchanged when the input already has no calls.

Raises:

validate_symbolic_shapes
def validate_symbolic_shapes(self, block: Block) -> Block

Pass 2.5: Reject unresolved parameter shape dims in loop bounds.

Runs after analyze so dependency info is complete. Raises QamomileCompileError with an actionable message when a gamma_dim0-style symbolic Value reaches a ForOperation bound without being folded to a constant by ParameterShapeResolutionPass.