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

QURI Parts backend for Qamomile.

Design intent: this package concretizes circuit’s abstract IR for QURI Parts through QuriPartsMaterializer. QuriPartsTranspiler plugs the materializer into the shared compiler pipeline, while observable.py converts Hamiltonians to QURI Parts Operators.

Backend-specific quirks stay confined here: parametric circuits use LinearMappedUnboundParametricQuantumCircuit, so symbolic angles are normalized to linear-combination form ({param: coeff, CONST: offset}) at emit time, and controlled gates without a native equivalent fall back to circuit’s shared decomposition recipes. Failures surface as QamomileQuriPartsTranspileError (exceptions.py) rather than raw SDK errors.

Constraints: depend only on qamomile.circuit public APIs plus the quri-parts SDK — never on qamomile.optimization or other backends. Lowering decisions belong at emit time, not in the IR.

Overview

FunctionDescription
hamiltonian_to_quri_operatorConvert qamomile.observable.Hamiltonian to QURI Parts Operator.
to_quri_operatorConvert Hamiltonian to QURI Parts Operator.
ClassDescription
QamomileQuriPartsTranspileErrorException raised for errors in the Qamomile to QURI Parts conversion process.
QuriPartsExecutorExecute QURI Parts circuits with sampling and expectation estimation.
QuriPartsGateEmitterGateEmitter implementation for QURI Parts.
QuriPartsTranspilerTranspile Qamomile programs to QURI Parts circuits.

Functions

hamiltonian_to_quri_operator [source]

def hamiltonian_to_quri_operator(hamiltonian: qm_o.Hamiltonian) -> 'Operator'

Convert qamomile.observable.Hamiltonian to QURI Parts Operator.

Parameters:

NameTypeDescription
hamiltonianqm_o.HamiltonianThe qamomile Hamiltonian to convert.

Returns:

'Operator' — QURI Parts Operator representation.

Example:

import qamomile.observable as qm_o
from qamomile.quri_parts.observable import hamiltonian_to_quri_operator

H = qm_o.Z(0) * qm_o.Z(1) + 0.5 * (qm_o.X(0) + qm_o.X(1))
operator = hamiltonian_to_quri_operator(H)

to_quri_operator [source]

def to_quri_operator(hamiltonian: qm_o.Hamiltonian) -> 'Operator'

Convert Hamiltonian to QURI Parts Operator.

Convenience alias for :func:hamiltonian_to_quri_operator.

Parameters:

NameTypeDescription
hamiltonianqm_o.HamiltonianThe qamomile Hamiltonian to convert.

Returns:

'Operator' — QURI Parts Operator representation.

Classes

QamomileQuriPartsTranspileError [source]

class QamomileQuriPartsTranspileError(QamomileCompileError)

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


QuriPartsExecutor [source]

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

Execute QURI Parts circuits with sampling and expectation estimation.

Constructor

def __init__(
    self,
    sampler: Any = None,
    estimator: Any = None,
    seed: int | None = None,
    *,
    bound_estimator: Any = None,
)

Initialize the executor.

Parameters:

NameTypeDescription
samplerAnyOptional QURI Parts sampler.
estimatorAnyOptional QURI Parts parametric estimator, used only with unbound parametric circuit states.
seedint | NoneOptional seed for the default Qulacs sampler.
bound_estimatorAnyOptional non-parametric estimator for circuits that have already been bound by ExecutableProgram.

Attributes

Methods

bind_parameters
def bind_parameters(
    self,
    circuit: 'qp_c.LinearMappedUnboundParametricQuantumCircuit',
    bindings: dict[str, Any],
    parameter_metadata: ParameterMetadata,
) -> 'ImmutableBoundParametricQuantumCircuit'

Bind named parameters in backend order.

Parameters:

NameTypeDescription
circuit'qp_c.LinearMappedUnboundParametricQuantumCircuit'Unbound parametric circuit.
bindingsdict[str, Any]Parameter values by Qamomile name.
parameter_metadataParameterMetadataOrdered backend parameter metadata.

Returns:

'ImmutableBoundParametricQuantumCircuit' — Bound QURI Parts circuit.

Raises:

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

Estimate a Hamiltonian expectation value.

Parameters:

NameTypeDescription
circuit'qp_c.LinearMappedUnboundParametricQuantumCircuit'State-preparation circuit.
hamiltonian'qm_o.Hamiltonian'Qamomile Hamiltonian or native QURI Parts operator.
paramsSequence[float] | NoneOptional circuit parameter values.

Returns:

float — Real expectation value.

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

Estimate a native QURI Parts operator expectation value.

Parameters:

NameTypeDescription
circuit'qp_c.LinearMappedUnboundParametricQuantumCircuit'Parametric or concrete QURI Parts circuit.
hamiltonian'qp_o.Operator'Native QURI Parts operator.
param_valuesSequence[float]Values for an unbound parametric circuit.

Returns:

float — Real expectation value.

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

Sample a circuit and return bitstring counts.

Parameters:

NameTypeDescription
circuitAnyBound or unbound QURI Parts circuit.
shotsintNumber of measurement shots.

Returns:

dict[str, int] — Counts keyed by zero-padded bitstrings. A zero-qubit circuit dict[str, int] — returns {"": shots} without invoking the sampler.


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, phase_carrier: int | None = None) -> None

Initialize the emitter.

Parameters:

NameTypeDescription
phase_carrierint | NoneDedicated clean |0> qubit used only where exact scalar-phase synthesis cannot reuse an existing qubit. None still permits a concrete phase when the caller supplies an existing carrier, but rejects symbolic or zero-qubit phase emission.

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. The concrete case replaces its final exp(iθ/4) RZ(θ/2) pair with the exact native U1(θ/2). The parametric case has no native ParametricU1, so it emits RZ plus the missing scalar factor on the dedicated phase carrier.

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_global_phase
def emit_global_phase(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    angle: float | Any,
    carrier: int | None = None,
) -> None

Synthesize exp(i * angle) I exactly.

A concrete phase reuses an arbitrary existing qubit through U1(2a) RZ(-2a) = exp(ia) I. Symbolic and zero-qubit phases use the configured clean carrier because QURI Parts has no ParametricU1 or circuit-level phase operation.

Parameters:

NameTypeDescription
circuitLinearMappedUnboundParametricQuantumCircuitDestination QURI circuit.
anglefloat | AnyConcrete or linear phase in radians.
carrierint | NoneExisting arbitrary-state qubit available for concrete two-gate synthesis. Defaults to None.

Raises:

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 use ParametricRZ plus a scalar phase on the dedicated clean carrier that restores P(θ) = exp(iθ/2) RZ(θ) exactly.

emit_pauli_rotation
def emit_pauli_rotation(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    qubits: list[int],
    pauli_ids: list[int],
    angle: float | Any,
) -> None

Emit one native QURI Parts Pauli-string rotation.

Parameters:

NameTypeDescription
circuitLinearMappedUnboundParametricQuantumCircuitDestination QURI Parts circuit.
qubitslist[int]Target qubit indices in Pauli-word order.
pauli_idslist[int]QURI Pauli identifiers aligned with qubits.
anglefloat | AnyRotation angle for exp(-i * angle / 2 * P).
emit_reset
def emit_reset(
    self,
    circuit: 'LinearMappedUnboundParametricQuantumCircuit',
    qubit: int,
) -> None

Raise because QURI Parts circuits do not support reset.

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'])

Transpile Qamomile programs to QURI Parts circuits.

Methods

executor
def executor(
    self,
    sampler: Any = None,
    estimator: Any = None,
    seed: int | None = None,
    *,
    bound_estimator: Any = None,
) -> QuriPartsExecutor

Create a QURI Parts executor.

Parameters:

NameTypeDescription
samplerAnyOptional custom sampler.
estimatorAnyOptional custom parametric estimator for unbound states.
seedint | NoneOptional seed for the default sampler.
bound_estimatorAnyOptional custom non-parametric estimator for circuits already bound by ExecutableProgram.

Returns:

QuriPartsExecutor — Configured QURI Parts executor.

Submodules