CUDA-Q backend for Qamomile.
This module provides transpiler, executor, and observable conversion for the CUDA-Q quantum computing platform.
All circuits are emitted through a unified CudaqKernelEmitter codegen
path, producing CudaqKernelArtifact instances. The artifact’s
ExecutionMode (STATIC or RUNNABLE) determines which CUDA-Q runtime
API is used for execution.
Public symbols are exported lazily so that a mere import qamomile.cudaq
does not fail in environments where the cudaq package is absent. Accessing
any public symbol (e.g. qamomile.cudaq.CudaqTranspiler) will raise an
:class:ImportError with actionable install guidance when cudaq is not
available.
Overview¶
| Function | Description |
|---|---|
hamiltonian_to_cudaq_spin_op | Convert qamomile.observable.Hamiltonian to cudaq.SpinOperator. |
| Class | Description |
|---|---|
BoundCudaqKernelArtifact | CUDA-Q kernel artifact with bound parameter values. |
CudaqEmitPass | CUDA-Q-specific emission pass. |
CudaqExecutor | CUDA-Q quantum executor. |
CudaqKernelArtifact | Compiled CUDA-Q decorator-kernel artifact. |
CudaqKernelEmitter | Unified GateEmitter that generates @cudaq.kernel Python source code. |
CudaqTranspiler | CUDA-Q transpiler for qamomile.circuit module. |
ExecutionMode | Execution mode for a CUDA-Q kernel artifact. |
Functions¶
hamiltonian_to_cudaq_spin_op [source]¶
def hamiltonian_to_cudaq_spin_op(hamiltonian: qm_o.Hamiltonian) -> AnyConvert qamomile.observable.Hamiltonian to cudaq.SpinOperator.
Parameters:
| Name | Type | Description |
|---|---|---|
hamiltonian | qm_o.Hamiltonian | The qamomile Hamiltonian to convert. |
Returns:
Any — A CUDA-Q SpinOperator built from cudaq.spin primitives.
Example:
import qamomile.observable as qm_o
from qamomile.cudaq.observable import hamiltonian_to_cudaq_spin_op
H = qm_o.Z(0) * qm_o.Z(1) + 0.5 * (qm_o.X(0) + qm_o.X(1))
spin_op = hamiltonian_to_cudaq_spin_op(H)Classes¶
BoundCudaqKernelArtifact [source]¶
class BoundCudaqKernelArtifactCUDA-Q kernel artifact with bound parameter values.
Used as the return type of CudaqExecutor.bind_parameters.
The executor dispatches to the appropriate CUDA-Q runtime API
based on execution_mode.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel_func | Any | The @cudaq.kernel decorated function. |
num_qubits | int | Number of qubits in the circuit. |
num_clbits | int | Number of classical bits in the circuit. |
param_values | list[float] | Bound parameter values in order. |
execution_mode | ExecutionMode | Execution mode inherited from the source artifact. |
Constructor¶
def __init__(
self,
kernel_func: Any,
num_qubits: int,
num_clbits: int,
param_values: list[float],
execution_mode: ExecutionMode = ExecutionMode.STATIC,
) -> NoneAttributes¶
execution_mode: ExecutionModekernel_func: Anynum_clbits: intnum_qubits: intparam_values: list[float]
CudaqEmitPass [source]¶
class CudaqEmitPass(StandardEmitPass[CudaqKernelArtifact])CUDA-Q-specific emission pass.
Uses a single CudaqKernelEmitter for all circuits. The emitter
generates @cudaq.kernel decorated Python source for both static
and runtime control flow circuits. The execution mode (STATIC or
RUNNABLE) is determined by a pre-scan of the operations.
Constructor¶
def __init__(
self,
bindings: dict[str, Any] | None = None,
parameters: list[str] | None = None,
)CudaqExecutor [source]¶
class CudaqExecutor(QuantumExecutor[CudaqKernelArtifact])CUDA-Q quantum executor.
Supports sampling via cudaq.sample and expectation value estimation
via cudaq.observe. Dispatches to the appropriate CUDA-Q runtime
API based on the artifact’s execution_mode.
Parameters:
| Name | Type | Description |
|---|---|---|
target | str | None | CUDA-Q target name (e.g., "qpp-cpu"). If None, uses the default CUDA-Q target. |
Constructor¶
def __init__(self, target: str | None = None)Methods¶
bind_parameters¶
def bind_parameters(
self,
circuit: Any,
bindings: dict[str, Any],
parameter_metadata: ParameterMetadata,
) -> BoundCudaqKernelArtifactBind parameters to a circuit for execution.
Returns a BoundCudaqKernelArtifact with the execution mode
inherited from the source artifact.
estimate¶
def estimate(
self,
circuit: Any,
hamiltonian: 'qm_o.Hamiltonian',
params: Sequence[float] | None = None,
) -> floatEstimate expectation value using cudaq.observe.
Only supported for STATIC-mode artifacts. RUNNABLE-mode artifacts
are not compatible with cudaq.observe() and raise TypeError.
execute¶
def execute(self, circuit: Any, shots: int) -> dict[str, int]Execute circuit and return canonical big-endian bitstring counts.
Dispatches based on execution_mode:
STATIC: usescudaq.sample()on the decorator kernel.RUNNABLE: usescudaq.run()on the runnable kernel.
Both paths return bitstrings in big-endian format (highest qubit index = leftmost bit).
CudaqKernelArtifact [source]¶
class CudaqKernelArtifactCompiled CUDA-Q decorator-kernel artifact.
Wraps a @cudaq.kernel decorated function produced by
CudaqKernelEmitter. The execution_mode field determines
which CUDA-Q runtime APIs are valid for this artifact.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel_func | Any | The @cudaq.kernel decorated function, or None before finalize() is called. |
num_qubits | int | Number of qubits in the circuit. |
num_clbits | int | Number of classical bits in the circuit. |
source | str | Generated Python source code (for debugging). |
execution_mode | ExecutionMode | Whether this is a STATIC or RUNNABLE kernel. |
param_count | int | Number of variational parameters. |
Constructor¶
def __init__(
self,
kernel_func: Any,
num_qubits: int,
num_clbits: int,
source: str = '',
execution_mode: ExecutionMode = ExecutionMode.STATIC,
param_count: int = 0,
) -> NoneAttributes¶
execution_mode: ExecutionModekernel_func: Anynum_clbits: intnum_qubits: intparam_count: intsource: str
CudaqKernelEmitter [source]¶
class CudaqKernelEmitterUnified GateEmitter that generates @cudaq.kernel Python source code.
Used for all CUDA-Q circuits. Gate calls are accumulated as Python
source lines forming a @cudaq.kernel decorated function. The
finalize() method compiles the source via exec() and populates
the artifact’s kernel_func.
The measurement_mode property controls measurement behaviour:
MeasurementMode.STATIC:emit_measureis a no-op;cudaq.sample()auto-measures all qubits.MeasurementMode.RUNNABLE:emit_measureemits explicitmz()calls for mid-circuit measurement variables.
Parameters:
| Name | Type | Description |
|---|---|---|
parametric | bool | Initial hint for parametricity. The emit pass overrides this after emission based on _param_count. |
Constructor¶
def __init__(self, parametric: bool = False) -> NoneAttributes¶
measurement_mode: MeasurementMode Return the current measurement mode.
Methods¶
append_gate¶
def append_gate(self, circuit: CudaqKernelArtifact, gate: Any, qubits: list[int]) -> NoneNo-op: not supported by CUDA-Q codegen path.
circuit_to_gate¶
def circuit_to_gate(self, circuit: CudaqKernelArtifact, name: str = 'U') -> AnyNo-op: not supported by CUDA-Q codegen path.
create_circuit¶
def create_circuit(self, num_qubits: int, num_clbits: int) -> CudaqKernelArtifactStart building a @cudaq.kernel function.
Resets internal state and emits the q = cudaq.qvector(N)
allocation line.
Parameters:
| Name | Type | Description |
|---|---|---|
num_qubits | int | Number of qubits to allocate. |
num_clbits | int | Number of classical bits. |
Returns:
CudaqKernelArtifact — A new CudaqKernelArtifact with kernel_func=None
CudaqKernelArtifact — (populated by finalize()).
create_parameter¶
def create_parameter(self, name: str) -> CudaqExprReturn a CudaqExpr referencing thetas[i].
Returns an arithmetic-capable expression object so that
StandardEmitPass._evaluate_binop() can compose gate-angle
expressions (e.g. gamma * Jij) without triggering a
TypeError on raw string operands.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | Symbolic parameter name. |
Returns:
CudaqExpr — CudaqExpr wrapping a source expression like
CudaqExpr — "thetas[0]".
emit_barrier¶
def emit_barrier(self, circuit: CudaqKernelArtifact, qubits: list[int]) -> NoneNo-op: CUDA-Q does not support barrier instructions.
emit_ch¶
def emit_ch(self, circuit: CudaqKernelArtifact, control: int, target: int) -> NoneEmit controlled-Hadamard via decomposition.
Mirrors the CH_DECOMPOSITION recipe from
qamomile.circuit.transpiler.decompositions. Inlined here (rather
than calling :func:emit_decomposition) so that the string-based
codegen produces the exact source contract expected by the tracing
test emitter, without double-recording primitive gate calls.
emit_cp¶
def emit_cp(
self,
circuit: CudaqKernelArtifact,
control: int,
target: int,
angle: float | Any,
) -> NoneEmit controlled-Phase via decomposition.
Follows the shared CP_DECOMPOSITION recipe from
qamomile.circuit.transpiler.decompositions.
Inlined here because CudaqExpr angles require string-based codegen.
emit_crx¶
def emit_crx(
self,
circuit: CudaqKernelArtifact,
control: int,
target: int,
angle: float | Any,
) -> NoneEmit controlled-RX gate.
emit_cry¶
def emit_cry(
self,
circuit: CudaqKernelArtifact,
control: int,
target: int,
angle: float | Any,
) -> NoneEmit controlled-RY gate.
emit_crz¶
def emit_crz(
self,
circuit: CudaqKernelArtifact,
control: int,
target: int,
angle: float | Any,
) -> NoneEmit controlled-RZ gate.
emit_cx¶
def emit_cx(self, circuit: CudaqKernelArtifact, control: int, target: int) -> NoneEmit CNOT (controlled-X) gate.
emit_cy¶
def emit_cy(self, circuit: CudaqKernelArtifact, control: int, target: int) -> NoneEmit controlled-Y via decomposition.
Mirrors the CY_DECOMPOSITION recipe from
qamomile.circuit.transpiler.decompositions. See
:meth:emit_ch for why this is inlined rather than delegating to
:func:emit_decomposition.
emit_cz¶
def emit_cz(self, circuit: CudaqKernelArtifact, control: int, target: int) -> NoneEmit controlled-Z gate.
emit_else_start¶
def emit_else_start(self, circuit: CudaqKernelArtifact, context: dict[str, Any]) -> NoneEmit else: block.
emit_for_loop_end¶
def emit_for_loop_end(self, circuit: CudaqKernelArtifact, context: Any) -> NoneNot supported: for-loops are unrolled by the transpiler.
emit_for_loop_start¶
def emit_for_loop_start(self, circuit: CudaqKernelArtifact, indexset: range) -> AnyNot supported: for-loops are unrolled by the transpiler.
emit_h¶
def emit_h(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit Hadamard gate.
emit_if_end¶
def emit_if_end(self, circuit: CudaqKernelArtifact, context: dict[str, Any]) -> NoneClose if block by decreasing indentation.
emit_if_start¶
def emit_if_start(
self,
circuit: CudaqKernelArtifact,
clbit: int,
value: int = 1,
) -> dict[str, Any]Emit if __b{clbit}: and increase indentation.
emit_measure¶
def emit_measure(self, circuit: CudaqKernelArtifact, qubit: int, clbit: int) -> NoneEmit measurement, respecting the current mode.
In STATIC mode (measurement_mode == STATIC), this is a
no-op: cudaq.sample() auto-measures all qubits.
In RUNNABLE mode (measurement_mode == RUNNABLE), emits
explicit mz() to capture mid-circuit measurement results as
local variables for if / while conditions.
emit_multi_controlled_x¶
def emit_multi_controlled_x(
self,
circuit: CudaqKernelArtifact,
control_indices: list[int],
target_idx: int,
) -> NoneEmit multi-controlled X using x.ctrl(c0, c1, ..., target).
emit_p¶
def emit_p(self, circuit: CudaqKernelArtifact, qubit: int, angle: float | Any) -> NoneEmit phase gate (R1).
emit_rx¶
def emit_rx(self, circuit: CudaqKernelArtifact, qubit: int, angle: float | Any) -> NoneEmit RX rotation gate.
emit_ry¶
def emit_ry(self, circuit: CudaqKernelArtifact, qubit: int, angle: float | Any) -> NoneEmit RY rotation gate.
emit_rz¶
def emit_rz(self, circuit: CudaqKernelArtifact, qubit: int, angle: float | Any) -> NoneEmit RZ rotation gate.
emit_rzz¶
def emit_rzz(
self,
circuit: CudaqKernelArtifact,
qubit1: int,
qubit2: int,
angle: float | Any,
) -> NoneEmit RZZ via CNOT + RZ decomposition.
RZZ(q1, q2, theta) = CNOT(q1, q2) RZ(q2, theta) CNOT(q1, q2)
emit_s¶
def emit_s(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit S (phase) gate.
emit_sdg¶
def emit_sdg(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit S-dagger gate.
emit_swap¶
def emit_swap(self, circuit: CudaqKernelArtifact, qubit1: int, qubit2: int) -> NoneEmit SWAP gate.
emit_t¶
def emit_t(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit T gate.
emit_tdg¶
def emit_tdg(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit T-dagger gate.
emit_toffoli¶
def emit_toffoli(
self,
circuit: CudaqKernelArtifact,
control1: int,
control2: int,
target: int,
) -> NoneEmit Toffoli (CCX) gate.
Delegates to :meth:emit_multi_controlled_x so that all
multi-controlled X emission flows through a single canonical helper.
emit_while_end¶
def emit_while_end(self, circuit: CudaqKernelArtifact, context: dict[str, Any]) -> NoneClose while block by decreasing indentation.
emit_while_start¶
def emit_while_start(
self,
circuit: CudaqKernelArtifact,
clbit: int,
value: int = 1,
) -> dict[str, Any]Emit while __b{clbit}: and increase indentation.
emit_x¶
def emit_x(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit Pauli-X gate.
emit_y¶
def emit_y(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit Pauli-Y gate.
emit_z¶
def emit_z(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit Pauli-Z gate.
finalize¶
def finalize(self, circuit: CudaqKernelArtifact, mode: ExecutionMode) -> CudaqKernelArtifactCompile accumulated source into a @cudaq.kernel function.
For RUNNABLE mode, appends return [__b0, __b1, ...] to
return per-shot logical clbit values. For STATIC mode,
generates a void function with no explicit terminal measurement.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | CudaqKernelArtifact | The artifact to finalize. |
mode | ExecutionMode | Execution mode determining the function signature. |
Returns:
CudaqKernelArtifact — The same artifact with kernel_func and source populated.
gate_controlled¶
def gate_controlled(self, gate: Any, num_controls: int) -> AnyNo-op: not supported by CUDA-Q codegen path.
gate_power¶
def gate_power(self, gate: Any, power: int) -> AnyNo-op: not supported by CUDA-Q codegen path.
supports_for_loop¶
def supports_for_loop(self) -> boolReturn False: for-loops are unrolled by the transpiler.
supports_if_else¶
def supports_if_else(self) -> boolReturn True only in RUNNABLE mode (measurement-dependent branching).
supports_while_loop¶
def supports_while_loop(self) -> boolReturn True only in RUNNABLE mode.
CudaqTranspiler [source]¶
class CudaqTranspiler(Transpiler[CudaqKernelArtifact])CUDA-Q transpiler for qamomile.circuit module.
Converts Qamomile QKernels into CUDA-Q decorator-kernel artifacts.
Example:
from qamomile.cudaq import CudaqTranspiler
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 = CudaqTranspiler()
executable = transpiler.transpile(bell_state)Methods¶
executor¶
def executor(self, target: str | None = None) -> CudaqExecutorCreate a CUDA-Q executor.
Parameters:
| Name | Type | Description |
|---|---|---|
target | str | None | CUDA-Q target name (e.g., "qpp-cpu"). If None, uses the default CUDA-Q target. |
ExecutionMode [source]¶
class ExecutionMode(enum.Enum)Execution mode for a CUDA-Q kernel artifact.
Determines which CUDA-Q runtime API is used for execution:
STATIC: Compatible withcudaq.sample(),cudaq.get_state(), andcudaq.observe(). The kernel has no explicit terminal measurements and no return value.RUNNABLE: Compatible withcudaq.run(). The kernel has explicit mid-circuit measurements and returnsmz(q)(list[bool]).
Attributes¶
RUNNABLESTATIC
qamomile.cudaq.emitter¶
CUDA-Q emitter implementation.
This module provides a unified emitter for the CUDA-Q backend:
CudaqKernelEmitter: Generates@cudaq.kerneldecorated Python source code for all circuits. The emitter supports two execution modes:STATIC: Measurement-free kernels compatible with
cudaq.sample(),cudaq.get_state(), andcudaq.observe().RUNNABLE: Kernels with explicit mid-circuit measurements and a final
return mz(q), compatible withcudaq.run().
The execution mode is determined by the emit pass based on whether the circuit contains runtime measurement-dependent control flow.
Overview¶
| Class | Description |
|---|---|
CudaqExpr | Arithmetic-capable wrapper for CUDA-Q source expressions. |
CudaqKernelArtifact | Compiled CUDA-Q decorator-kernel artifact. |
CudaqKernelEmitter | Unified GateEmitter that generates @cudaq.kernel Python source code. |
ExecutionMode | Execution mode for a CUDA-Q kernel artifact. |
MeasurementMode | How a backend handles measurement operations. |
Classes¶
CudaqExpr [source]¶
class CudaqExprArithmetic-capable wrapper for CUDA-Q source expressions.
Enables operator-overload-based expression building in
StandardEmitPass._evaluate_binop(). Each arithmetic operation
returns a new CudaqExpr with a properly parenthesized string
representation. str(expr) yields the raw source expression
suitable for embedding directly in generated @cudaq.kernel code.
Parameters:
| Name | Type | Description |
|---|---|---|
expr | str | Source expression string (e.g. "thetas[0]"). |
Constructor¶
def __init__(self, expr: str) -> NoneCudaqKernelArtifact [source]¶
class CudaqKernelArtifactCompiled CUDA-Q decorator-kernel artifact.
Wraps a @cudaq.kernel decorated function produced by
CudaqKernelEmitter. The execution_mode field determines
which CUDA-Q runtime APIs are valid for this artifact.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel_func | Any | The @cudaq.kernel decorated function, or None before finalize() is called. |
num_qubits | int | Number of qubits in the circuit. |
num_clbits | int | Number of classical bits in the circuit. |
source | str | Generated Python source code (for debugging). |
execution_mode | ExecutionMode | Whether this is a STATIC or RUNNABLE kernel. |
param_count | int | Number of variational parameters. |
Constructor¶
def __init__(
self,
kernel_func: Any,
num_qubits: int,
num_clbits: int,
source: str = '',
execution_mode: ExecutionMode = ExecutionMode.STATIC,
param_count: int = 0,
) -> NoneAttributes¶
execution_mode: ExecutionModekernel_func: Anynum_clbits: intnum_qubits: intparam_count: intsource: str
CudaqKernelEmitter [source]¶
class CudaqKernelEmitterUnified GateEmitter that generates @cudaq.kernel Python source code.
Used for all CUDA-Q circuits. Gate calls are accumulated as Python
source lines forming a @cudaq.kernel decorated function. The
finalize() method compiles the source via exec() and populates
the artifact’s kernel_func.
The measurement_mode property controls measurement behaviour:
MeasurementMode.STATIC:emit_measureis a no-op;cudaq.sample()auto-measures all qubits.MeasurementMode.RUNNABLE:emit_measureemits explicitmz()calls for mid-circuit measurement variables.
Parameters:
| Name | Type | Description |
|---|---|---|
parametric | bool | Initial hint for parametricity. The emit pass overrides this after emission based on _param_count. |
Constructor¶
def __init__(self, parametric: bool = False) -> NoneAttributes¶
measurement_mode: MeasurementMode Return the current measurement mode.
Methods¶
append_gate¶
def append_gate(self, circuit: CudaqKernelArtifact, gate: Any, qubits: list[int]) -> NoneNo-op: not supported by CUDA-Q codegen path.
circuit_to_gate¶
def circuit_to_gate(self, circuit: CudaqKernelArtifact, name: str = 'U') -> AnyNo-op: not supported by CUDA-Q codegen path.
create_circuit¶
def create_circuit(self, num_qubits: int, num_clbits: int) -> CudaqKernelArtifactStart building a @cudaq.kernel function.
Resets internal state and emits the q = cudaq.qvector(N)
allocation line.
Parameters:
| Name | Type | Description |
|---|---|---|
num_qubits | int | Number of qubits to allocate. |
num_clbits | int | Number of classical bits. |
Returns:
CudaqKernelArtifact — A new CudaqKernelArtifact with kernel_func=None
CudaqKernelArtifact — (populated by finalize()).
create_parameter¶
def create_parameter(self, name: str) -> CudaqExprReturn a CudaqExpr referencing thetas[i].
Returns an arithmetic-capable expression object so that
StandardEmitPass._evaluate_binop() can compose gate-angle
expressions (e.g. gamma * Jij) without triggering a
TypeError on raw string operands.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | Symbolic parameter name. |
Returns:
CudaqExpr — CudaqExpr wrapping a source expression like
CudaqExpr — "thetas[0]".
emit_barrier¶
def emit_barrier(self, circuit: CudaqKernelArtifact, qubits: list[int]) -> NoneNo-op: CUDA-Q does not support barrier instructions.
emit_ch¶
def emit_ch(self, circuit: CudaqKernelArtifact, control: int, target: int) -> NoneEmit controlled-Hadamard via decomposition.
Mirrors the CH_DECOMPOSITION recipe from
qamomile.circuit.transpiler.decompositions. Inlined here (rather
than calling :func:emit_decomposition) so that the string-based
codegen produces the exact source contract expected by the tracing
test emitter, without double-recording primitive gate calls.
emit_cp¶
def emit_cp(
self,
circuit: CudaqKernelArtifact,
control: int,
target: int,
angle: float | Any,
) -> NoneEmit controlled-Phase via decomposition.
Follows the shared CP_DECOMPOSITION recipe from
qamomile.circuit.transpiler.decompositions.
Inlined here because CudaqExpr angles require string-based codegen.
emit_crx¶
def emit_crx(
self,
circuit: CudaqKernelArtifact,
control: int,
target: int,
angle: float | Any,
) -> NoneEmit controlled-RX gate.
emit_cry¶
def emit_cry(
self,
circuit: CudaqKernelArtifact,
control: int,
target: int,
angle: float | Any,
) -> NoneEmit controlled-RY gate.
emit_crz¶
def emit_crz(
self,
circuit: CudaqKernelArtifact,
control: int,
target: int,
angle: float | Any,
) -> NoneEmit controlled-RZ gate.
emit_cx¶
def emit_cx(self, circuit: CudaqKernelArtifact, control: int, target: int) -> NoneEmit CNOT (controlled-X) gate.
emit_cy¶
def emit_cy(self, circuit: CudaqKernelArtifact, control: int, target: int) -> NoneEmit controlled-Y via decomposition.
Mirrors the CY_DECOMPOSITION recipe from
qamomile.circuit.transpiler.decompositions. See
:meth:emit_ch for why this is inlined rather than delegating to
:func:emit_decomposition.
emit_cz¶
def emit_cz(self, circuit: CudaqKernelArtifact, control: int, target: int) -> NoneEmit controlled-Z gate.
emit_else_start¶
def emit_else_start(self, circuit: CudaqKernelArtifact, context: dict[str, Any]) -> NoneEmit else: block.
emit_for_loop_end¶
def emit_for_loop_end(self, circuit: CudaqKernelArtifact, context: Any) -> NoneNot supported: for-loops are unrolled by the transpiler.
emit_for_loop_start¶
def emit_for_loop_start(self, circuit: CudaqKernelArtifact, indexset: range) -> AnyNot supported: for-loops are unrolled by the transpiler.
emit_h¶
def emit_h(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit Hadamard gate.
emit_if_end¶
def emit_if_end(self, circuit: CudaqKernelArtifact, context: dict[str, Any]) -> NoneClose if block by decreasing indentation.
emit_if_start¶
def emit_if_start(
self,
circuit: CudaqKernelArtifact,
clbit: int,
value: int = 1,
) -> dict[str, Any]Emit if __b{clbit}: and increase indentation.
emit_measure¶
def emit_measure(self, circuit: CudaqKernelArtifact, qubit: int, clbit: int) -> NoneEmit measurement, respecting the current mode.
In STATIC mode (measurement_mode == STATIC), this is a
no-op: cudaq.sample() auto-measures all qubits.
In RUNNABLE mode (measurement_mode == RUNNABLE), emits
explicit mz() to capture mid-circuit measurement results as
local variables for if / while conditions.
emit_multi_controlled_x¶
def emit_multi_controlled_x(
self,
circuit: CudaqKernelArtifact,
control_indices: list[int],
target_idx: int,
) -> NoneEmit multi-controlled X using x.ctrl(c0, c1, ..., target).
emit_p¶
def emit_p(self, circuit: CudaqKernelArtifact, qubit: int, angle: float | Any) -> NoneEmit phase gate (R1).
emit_rx¶
def emit_rx(self, circuit: CudaqKernelArtifact, qubit: int, angle: float | Any) -> NoneEmit RX rotation gate.
emit_ry¶
def emit_ry(self, circuit: CudaqKernelArtifact, qubit: int, angle: float | Any) -> NoneEmit RY rotation gate.
emit_rz¶
def emit_rz(self, circuit: CudaqKernelArtifact, qubit: int, angle: float | Any) -> NoneEmit RZ rotation gate.
emit_rzz¶
def emit_rzz(
self,
circuit: CudaqKernelArtifact,
qubit1: int,
qubit2: int,
angle: float | Any,
) -> NoneEmit RZZ via CNOT + RZ decomposition.
RZZ(q1, q2, theta) = CNOT(q1, q2) RZ(q2, theta) CNOT(q1, q2)
emit_s¶
def emit_s(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit S (phase) gate.
emit_sdg¶
def emit_sdg(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit S-dagger gate.
emit_swap¶
def emit_swap(self, circuit: CudaqKernelArtifact, qubit1: int, qubit2: int) -> NoneEmit SWAP gate.
emit_t¶
def emit_t(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit T gate.
emit_tdg¶
def emit_tdg(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit T-dagger gate.
emit_toffoli¶
def emit_toffoli(
self,
circuit: CudaqKernelArtifact,
control1: int,
control2: int,
target: int,
) -> NoneEmit Toffoli (CCX) gate.
Delegates to :meth:emit_multi_controlled_x so that all
multi-controlled X emission flows through a single canonical helper.
emit_while_end¶
def emit_while_end(self, circuit: CudaqKernelArtifact, context: dict[str, Any]) -> NoneClose while block by decreasing indentation.
emit_while_start¶
def emit_while_start(
self,
circuit: CudaqKernelArtifact,
clbit: int,
value: int = 1,
) -> dict[str, Any]Emit while __b{clbit}: and increase indentation.
emit_x¶
def emit_x(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit Pauli-X gate.
emit_y¶
def emit_y(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit Pauli-Y gate.
emit_z¶
def emit_z(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit Pauli-Z gate.
finalize¶
def finalize(self, circuit: CudaqKernelArtifact, mode: ExecutionMode) -> CudaqKernelArtifactCompile accumulated source into a @cudaq.kernel function.
For RUNNABLE mode, appends return [__b0, __b1, ...] to
return per-shot logical clbit values. For STATIC mode,
generates a void function with no explicit terminal measurement.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | CudaqKernelArtifact | The artifact to finalize. |
mode | ExecutionMode | Execution mode determining the function signature. |
Returns:
CudaqKernelArtifact — The same artifact with kernel_func and source populated.
gate_controlled¶
def gate_controlled(self, gate: Any, num_controls: int) -> AnyNo-op: not supported by CUDA-Q codegen path.
gate_power¶
def gate_power(self, gate: Any, power: int) -> AnyNo-op: not supported by CUDA-Q codegen path.
supports_for_loop¶
def supports_for_loop(self) -> boolReturn False: for-loops are unrolled by the transpiler.
supports_if_else¶
def supports_if_else(self) -> boolReturn True only in RUNNABLE mode (measurement-dependent branching).
supports_while_loop¶
def supports_while_loop(self) -> boolReturn True only in RUNNABLE mode.
ExecutionMode [source]¶
class ExecutionMode(enum.Enum)Execution mode for a CUDA-Q kernel artifact.
Determines which CUDA-Q runtime API is used for execution:
STATIC: Compatible withcudaq.sample(),cudaq.get_state(), andcudaq.observe(). The kernel has no explicit terminal measurements and no return value.RUNNABLE: Compatible withcudaq.run(). The kernel has explicit mid-circuit measurements and returnsmz(q)(list[bool]).
Attributes¶
RUNNABLESTATIC
MeasurementMode [source]¶
class MeasurementMode(Enum)How a backend handles measurement operations.
Attributes¶
NATIVERUNNABLESTATIC
qamomile.cudaq.observable¶
CUDA-Q observable support.
This module provides conversion from qamomile.observable.Hamiltonian
to CUDA-Q SpinOperator for use with cudaq.observe.
Overview¶
| Function | Description |
|---|---|
hamiltonian_to_cudaq_spin_op | Convert qamomile.observable.Hamiltonian to cudaq.SpinOperator. |
Functions¶
hamiltonian_to_cudaq_spin_op [source]¶
def hamiltonian_to_cudaq_spin_op(hamiltonian: qm_o.Hamiltonian) -> AnyConvert qamomile.observable.Hamiltonian to cudaq.SpinOperator.
Parameters:
| Name | Type | Description |
|---|---|---|
hamiltonian | qm_o.Hamiltonian | The qamomile Hamiltonian to convert. |
Returns:
Any — A CUDA-Q SpinOperator built from cudaq.spin primitives.
Example:
import qamomile.observable as qm_o
from qamomile.cudaq.observable import hamiltonian_to_cudaq_spin_op
H = qm_o.Z(0) * qm_o.Z(1) + 0.5 * (qm_o.X(0) + qm_o.X(1))
spin_op = hamiltonian_to_cudaq_spin_op(H)qamomile.cudaq.transpiler¶
CUDA-Q backend transpiler implementation.
This module provides CudaqTranspiler for converting Qamomile QKernels into CUDA-Q decorator-kernel artifacts, along with CudaqEmitPass and CudaqExecutor.
All circuits (static and runtime) are emitted through a single
CudaqKernelEmitter codegen path. The emitter produces
CudaqKernelArtifact instances whose execution_mode determines
whether cudaq.sample() / cudaq.observe() / cudaq.get_state()
(STATIC) or cudaq.run() (RUNNABLE) is used for execution.
Overview¶
| Class | Description |
|---|---|
BoundCudaqKernelArtifact | CUDA-Q kernel artifact with bound parameter values. |
CudaqEmitPass | CUDA-Q-specific emission pass. |
CudaqExecutor | CUDA-Q quantum executor. |
CudaqKernelArtifact | Compiled CUDA-Q decorator-kernel artifact. |
CudaqKernelEmitter | Unified GateEmitter that generates @cudaq.kernel Python source code. |
CudaqTranspiler | CUDA-Q transpiler for qamomile.circuit module. |
EmitError | Error during backend code emission. |
EmitPass | Base class for backend-specific emission passes. |
ExecutionMode | Execution mode for a CUDA-Q kernel artifact. |
ForItemsOperation | Represents iteration over dict/iterable items. |
ForOperation | Represents a for loop operation. |
GateOperation | Quantum gate operation. |
GateOperationType | |
IfOperation | Represents an if-else conditional operation. |
MeasurementMode | How a backend handles measurement operations. |
ReturnOperation | Explicit return operation marking the end of a block with return values. |
SegmentationPass | Segment a block into a strategy-specific executable program plan. |
StandardEmitPass | Standard emit pass implementation using GateEmitter protocol. |
Transpiler | Base class for backend-specific transpilers. |
WhileOperation | Represents a while loop operation. |
Classes¶
BoundCudaqKernelArtifact [source]¶
class BoundCudaqKernelArtifactCUDA-Q kernel artifact with bound parameter values.
Used as the return type of CudaqExecutor.bind_parameters.
The executor dispatches to the appropriate CUDA-Q runtime API
based on execution_mode.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel_func | Any | The @cudaq.kernel decorated function. |
num_qubits | int | Number of qubits in the circuit. |
num_clbits | int | Number of classical bits in the circuit. |
param_values | list[float] | Bound parameter values in order. |
execution_mode | ExecutionMode | Execution mode inherited from the source artifact. |
Constructor¶
def __init__(
self,
kernel_func: Any,
num_qubits: int,
num_clbits: int,
param_values: list[float],
execution_mode: ExecutionMode = ExecutionMode.STATIC,
) -> NoneAttributes¶
execution_mode: ExecutionModekernel_func: Anynum_clbits: intnum_qubits: intparam_values: list[float]
CudaqEmitPass [source]¶
class CudaqEmitPass(StandardEmitPass[CudaqKernelArtifact])CUDA-Q-specific emission pass.
Uses a single CudaqKernelEmitter for all circuits. The emitter
generates @cudaq.kernel decorated Python source for both static
and runtime control flow circuits. The execution mode (STATIC or
RUNNABLE) is determined by a pre-scan of the operations.
Constructor¶
def __init__(
self,
bindings: dict[str, Any] | None = None,
parameters: list[str] | None = None,
)CudaqExecutor [source]¶
class CudaqExecutor(QuantumExecutor[CudaqKernelArtifact])CUDA-Q quantum executor.
Supports sampling via cudaq.sample and expectation value estimation
via cudaq.observe. Dispatches to the appropriate CUDA-Q runtime
API based on the artifact’s execution_mode.
Parameters:
| Name | Type | Description |
|---|---|---|
target | str | None | CUDA-Q target name (e.g., "qpp-cpu"). If None, uses the default CUDA-Q target. |
Constructor¶
def __init__(self, target: str | None = None)Methods¶
bind_parameters¶
def bind_parameters(
self,
circuit: Any,
bindings: dict[str, Any],
parameter_metadata: ParameterMetadata,
) -> BoundCudaqKernelArtifactBind parameters to a circuit for execution.
Returns a BoundCudaqKernelArtifact with the execution mode
inherited from the source artifact.
estimate¶
def estimate(
self,
circuit: Any,
hamiltonian: 'qm_o.Hamiltonian',
params: Sequence[float] | None = None,
) -> floatEstimate expectation value using cudaq.observe.
Only supported for STATIC-mode artifacts. RUNNABLE-mode artifacts
are not compatible with cudaq.observe() and raise TypeError.
execute¶
def execute(self, circuit: Any, shots: int) -> dict[str, int]Execute circuit and return canonical big-endian bitstring counts.
Dispatches based on execution_mode:
STATIC: usescudaq.sample()on the decorator kernel.RUNNABLE: usescudaq.run()on the runnable kernel.
Both paths return bitstrings in big-endian format (highest qubit index = leftmost bit).
CudaqKernelArtifact [source]¶
class CudaqKernelArtifactCompiled CUDA-Q decorator-kernel artifact.
Wraps a @cudaq.kernel decorated function produced by
CudaqKernelEmitter. The execution_mode field determines
which CUDA-Q runtime APIs are valid for this artifact.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel_func | Any | The @cudaq.kernel decorated function, or None before finalize() is called. |
num_qubits | int | Number of qubits in the circuit. |
num_clbits | int | Number of classical bits in the circuit. |
source | str | Generated Python source code (for debugging). |
execution_mode | ExecutionMode | Whether this is a STATIC or RUNNABLE kernel. |
param_count | int | Number of variational parameters. |
Constructor¶
def __init__(
self,
kernel_func: Any,
num_qubits: int,
num_clbits: int,
source: str = '',
execution_mode: ExecutionMode = ExecutionMode.STATIC,
param_count: int = 0,
) -> NoneAttributes¶
execution_mode: ExecutionModekernel_func: Anynum_clbits: intnum_qubits: intparam_count: intsource: str
CudaqKernelEmitter [source]¶
class CudaqKernelEmitterUnified GateEmitter that generates @cudaq.kernel Python source code.
Used for all CUDA-Q circuits. Gate calls are accumulated as Python
source lines forming a @cudaq.kernel decorated function. The
finalize() method compiles the source via exec() and populates
the artifact’s kernel_func.
The measurement_mode property controls measurement behaviour:
MeasurementMode.STATIC:emit_measureis a no-op;cudaq.sample()auto-measures all qubits.MeasurementMode.RUNNABLE:emit_measureemits explicitmz()calls for mid-circuit measurement variables.
Parameters:
| Name | Type | Description |
|---|---|---|
parametric | bool | Initial hint for parametricity. The emit pass overrides this after emission based on _param_count. |
Constructor¶
def __init__(self, parametric: bool = False) -> NoneAttributes¶
measurement_mode: MeasurementMode Return the current measurement mode.
Methods¶
append_gate¶
def append_gate(self, circuit: CudaqKernelArtifact, gate: Any, qubits: list[int]) -> NoneNo-op: not supported by CUDA-Q codegen path.
circuit_to_gate¶
def circuit_to_gate(self, circuit: CudaqKernelArtifact, name: str = 'U') -> AnyNo-op: not supported by CUDA-Q codegen path.
create_circuit¶
def create_circuit(self, num_qubits: int, num_clbits: int) -> CudaqKernelArtifactStart building a @cudaq.kernel function.
Resets internal state and emits the q = cudaq.qvector(N)
allocation line.
Parameters:
| Name | Type | Description |
|---|---|---|
num_qubits | int | Number of qubits to allocate. |
num_clbits | int | Number of classical bits. |
Returns:
CudaqKernelArtifact — A new CudaqKernelArtifact with kernel_func=None
CudaqKernelArtifact — (populated by finalize()).
create_parameter¶
def create_parameter(self, name: str) -> CudaqExprReturn a CudaqExpr referencing thetas[i].
Returns an arithmetic-capable expression object so that
StandardEmitPass._evaluate_binop() can compose gate-angle
expressions (e.g. gamma * Jij) without triggering a
TypeError on raw string operands.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | Symbolic parameter name. |
Returns:
CudaqExpr — CudaqExpr wrapping a source expression like
CudaqExpr — "thetas[0]".
emit_barrier¶
def emit_barrier(self, circuit: CudaqKernelArtifact, qubits: list[int]) -> NoneNo-op: CUDA-Q does not support barrier instructions.
emit_ch¶
def emit_ch(self, circuit: CudaqKernelArtifact, control: int, target: int) -> NoneEmit controlled-Hadamard via decomposition.
Mirrors the CH_DECOMPOSITION recipe from
qamomile.circuit.transpiler.decompositions. Inlined here (rather
than calling :func:emit_decomposition) so that the string-based
codegen produces the exact source contract expected by the tracing
test emitter, without double-recording primitive gate calls.
emit_cp¶
def emit_cp(
self,
circuit: CudaqKernelArtifact,
control: int,
target: int,
angle: float | Any,
) -> NoneEmit controlled-Phase via decomposition.
Follows the shared CP_DECOMPOSITION recipe from
qamomile.circuit.transpiler.decompositions.
Inlined here because CudaqExpr angles require string-based codegen.
emit_crx¶
def emit_crx(
self,
circuit: CudaqKernelArtifact,
control: int,
target: int,
angle: float | Any,
) -> NoneEmit controlled-RX gate.
emit_cry¶
def emit_cry(
self,
circuit: CudaqKernelArtifact,
control: int,
target: int,
angle: float | Any,
) -> NoneEmit controlled-RY gate.
emit_crz¶
def emit_crz(
self,
circuit: CudaqKernelArtifact,
control: int,
target: int,
angle: float | Any,
) -> NoneEmit controlled-RZ gate.
emit_cx¶
def emit_cx(self, circuit: CudaqKernelArtifact, control: int, target: int) -> NoneEmit CNOT (controlled-X) gate.
emit_cy¶
def emit_cy(self, circuit: CudaqKernelArtifact, control: int, target: int) -> NoneEmit controlled-Y via decomposition.
Mirrors the CY_DECOMPOSITION recipe from
qamomile.circuit.transpiler.decompositions. See
:meth:emit_ch for why this is inlined rather than delegating to
:func:emit_decomposition.
emit_cz¶
def emit_cz(self, circuit: CudaqKernelArtifact, control: int, target: int) -> NoneEmit controlled-Z gate.
emit_else_start¶
def emit_else_start(self, circuit: CudaqKernelArtifact, context: dict[str, Any]) -> NoneEmit else: block.
emit_for_loop_end¶
def emit_for_loop_end(self, circuit: CudaqKernelArtifact, context: Any) -> NoneNot supported: for-loops are unrolled by the transpiler.
emit_for_loop_start¶
def emit_for_loop_start(self, circuit: CudaqKernelArtifact, indexset: range) -> AnyNot supported: for-loops are unrolled by the transpiler.
emit_h¶
def emit_h(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit Hadamard gate.
emit_if_end¶
def emit_if_end(self, circuit: CudaqKernelArtifact, context: dict[str, Any]) -> NoneClose if block by decreasing indentation.
emit_if_start¶
def emit_if_start(
self,
circuit: CudaqKernelArtifact,
clbit: int,
value: int = 1,
) -> dict[str, Any]Emit if __b{clbit}: and increase indentation.
emit_measure¶
def emit_measure(self, circuit: CudaqKernelArtifact, qubit: int, clbit: int) -> NoneEmit measurement, respecting the current mode.
In STATIC mode (measurement_mode == STATIC), this is a
no-op: cudaq.sample() auto-measures all qubits.
In RUNNABLE mode (measurement_mode == RUNNABLE), emits
explicit mz() to capture mid-circuit measurement results as
local variables for if / while conditions.
emit_multi_controlled_x¶
def emit_multi_controlled_x(
self,
circuit: CudaqKernelArtifact,
control_indices: list[int],
target_idx: int,
) -> NoneEmit multi-controlled X using x.ctrl(c0, c1, ..., target).
emit_p¶
def emit_p(self, circuit: CudaqKernelArtifact, qubit: int, angle: float | Any) -> NoneEmit phase gate (R1).
emit_rx¶
def emit_rx(self, circuit: CudaqKernelArtifact, qubit: int, angle: float | Any) -> NoneEmit RX rotation gate.
emit_ry¶
def emit_ry(self, circuit: CudaqKernelArtifact, qubit: int, angle: float | Any) -> NoneEmit RY rotation gate.
emit_rz¶
def emit_rz(self, circuit: CudaqKernelArtifact, qubit: int, angle: float | Any) -> NoneEmit RZ rotation gate.
emit_rzz¶
def emit_rzz(
self,
circuit: CudaqKernelArtifact,
qubit1: int,
qubit2: int,
angle: float | Any,
) -> NoneEmit RZZ via CNOT + RZ decomposition.
RZZ(q1, q2, theta) = CNOT(q1, q2) RZ(q2, theta) CNOT(q1, q2)
emit_s¶
def emit_s(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit S (phase) gate.
emit_sdg¶
def emit_sdg(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit S-dagger gate.
emit_swap¶
def emit_swap(self, circuit: CudaqKernelArtifact, qubit1: int, qubit2: int) -> NoneEmit SWAP gate.
emit_t¶
def emit_t(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit T gate.
emit_tdg¶
def emit_tdg(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit T-dagger gate.
emit_toffoli¶
def emit_toffoli(
self,
circuit: CudaqKernelArtifact,
control1: int,
control2: int,
target: int,
) -> NoneEmit Toffoli (CCX) gate.
Delegates to :meth:emit_multi_controlled_x so that all
multi-controlled X emission flows through a single canonical helper.
emit_while_end¶
def emit_while_end(self, circuit: CudaqKernelArtifact, context: dict[str, Any]) -> NoneClose while block by decreasing indentation.
emit_while_start¶
def emit_while_start(
self,
circuit: CudaqKernelArtifact,
clbit: int,
value: int = 1,
) -> dict[str, Any]Emit while __b{clbit}: and increase indentation.
emit_x¶
def emit_x(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit Pauli-X gate.
emit_y¶
def emit_y(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit Pauli-Y gate.
emit_z¶
def emit_z(self, circuit: CudaqKernelArtifact, qubit: int) -> NoneEmit Pauli-Z gate.
finalize¶
def finalize(self, circuit: CudaqKernelArtifact, mode: ExecutionMode) -> CudaqKernelArtifactCompile accumulated source into a @cudaq.kernel function.
For RUNNABLE mode, appends return [__b0, __b1, ...] to
return per-shot logical clbit values. For STATIC mode,
generates a void function with no explicit terminal measurement.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | CudaqKernelArtifact | The artifact to finalize. |
mode | ExecutionMode | Execution mode determining the function signature. |
Returns:
CudaqKernelArtifact — The same artifact with kernel_func and source populated.
gate_controlled¶
def gate_controlled(self, gate: Any, num_controls: int) -> AnyNo-op: not supported by CUDA-Q codegen path.
gate_power¶
def gate_power(self, gate: Any, power: int) -> AnyNo-op: not supported by CUDA-Q codegen path.
supports_for_loop¶
def supports_for_loop(self) -> boolReturn False: for-loops are unrolled by the transpiler.
supports_if_else¶
def supports_if_else(self) -> boolReturn True only in RUNNABLE mode (measurement-dependent branching).
supports_while_loop¶
def supports_while_loop(self) -> boolReturn True only in RUNNABLE mode.
CudaqTranspiler [source]¶
class CudaqTranspiler(Transpiler[CudaqKernelArtifact])CUDA-Q transpiler for qamomile.circuit module.
Converts Qamomile QKernels into CUDA-Q decorator-kernel artifacts.
Example:
from qamomile.cudaq import CudaqTranspiler
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 = CudaqTranspiler()
executable = transpiler.transpile(bell_state)Methods¶
executor¶
def executor(self, target: str | None = None) -> CudaqExecutorCreate a CUDA-Q executor.
Parameters:
| Name | Type | Description |
|---|---|---|
target | str | None | CUDA-Q target name (e.g., "qpp-cpu"). If None, uses the default CUDA-Q target. |
EmitError [source]¶
class EmitError(QamomileCompileError)Error during backend code emission.
Constructor¶
def __init__(self, message: str, operation: str | None = None)Attributes¶
operation
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:
| Name | Type | Description |
|---|---|---|
bindings | dict[str, Any] | None | Values to bind parameters to. If not provided, parameters must be bound at execution time. |
parameters | list[str] | None | List of parameter names to preserve as backend parameters. |
Attributes¶
bindingsname: strparameters
Methods¶
run¶
def run(self, input: ProgramPlan) -> ExecutableProgram[T]Emit backend code from a program plan.
ExecutionMode [source]¶
class ExecutionMode(enum.Enum)Execution mode for a CUDA-Q kernel artifact.
Determines which CUDA-Q runtime API is used for execution:
STATIC: Compatible withcudaq.sample(),cudaq.get_state(), andcudaq.observe(). The kernel has no explicit terminal measurements and no return value.RUNNABLE: Compatible withcudaq.run(). The kernel has explicit mid-circuit measurements and returnsmz(q)(list[bool]).
Attributes¶
RUNNABLESTATIC
ForItemsOperation [source]¶
class ForItemsOperation(HasNestedOps, Operation)Represents iteration over dict/iterable items.
Example:
for (i, j), Jij in qmc.items(ising):
bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
key_vars: list[str] = list(),
value_var: str = '',
key_is_vector: bool = False,
key_var_values: tuple[Value, ...] | None = None,
value_var_value: Value | None = None,
operations: list[Operation] = list(),
) -> NoneAttributes¶
key_is_vector: boolkey_var_values: tuple[Value, ...] | Nonekey_vars: list[str]operation_kind: OperationKindoperations: list[Operation]signature: Signaturevalue_var: strvalue_var_value: Value | None
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include the per-key/value Value fields for cloning/substitution.
Same rationale as ForOperation.all_input_values: keep the IR
identity fields in lockstep with body references so UUID-keyed
lookups stay valid after inline cloning.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operationreplace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationForOperation [source]¶
class ForOperation(HasNestedOps, Operation)Represents a for loop operation.
Example:
for i in range(start, stop, step):
bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
loop_var: str = '',
loop_var_value: Value | None = None,
operations: list[Operation] = list(),
) -> NoneAttributes¶
loop_var: strloop_var_value: Value | Noneoperation_kind: OperationKindoperations: list[Operation]signature: Signature
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]]) -> Operationreplace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationGateOperation [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,
) -> NoneAttributes¶
gate_type: GateOperationType | Noneoperation_kind: OperationKindqubit_operands: list[Value] Qubit operands (excluding the theta parameter if present).signature: Signaturetheta: Value | None Angle parameter for rotation gates, orNonefor fixed gates.
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¶
CPCXCZHPRXRYRZRZZSSDGSWAPTTDGTOFFOLIXYZ
IfOperation [source]¶
class IfOperation(HasNestedOps, Operation)Represents an if-else conditional operation.
Example:
if condition:
true_body
else:
false_bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
true_operations: list[Operation] = list(),
false_operations: list[Operation] = list(),
phi_ops: list[PhiOp] = list(),
) -> NoneAttributes¶
condition: Valuefalse_operations: list[Operation]operation_kind: OperationKindphi_ops: list[PhiOp]signature: Signaturetrue_operations: list[Operation]
Methods¶
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> OperationMeasurementMode [source]¶
class MeasurementMode(Enum)How a backend handles measurement operations.
Attributes¶
NATIVERUNNABLESTATIC
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()) -> NoneAttributes¶
operation_kind: OperationKind Return CLASSICAL as this is a control flow operation without quantum effects.signature: Signature Return the signature with operands for each return value and no results.
SegmentationPass [source]¶
class SegmentationPass(Pass[Block, ProgramPlan])Segment a block into a strategy-specific executable program plan.
This pass:
Materializes return operations (syncs output_values from ReturnOperation)
Splits the operation list into quantum and classical segments
Builds a ProgramPlan via the configured segmentation strategy
Input: Block (typically ANALYZED or AFFINE) Output: ProgramPlan
Constructor¶
def __init__(self, strategy: SegmentationStrategy | None = None) -> NoneAttributes¶
name: str
Methods¶
run¶
def run(self, input: Block) -> ProgramPlanSegment 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:
| Name | Type | Description |
|---|---|---|
gate_emitter | GateEmitter[T] | Backend-specific gate emitter |
bindings | dict[str, Any] | None | Parameter bindings for the circuit |
parameters | list[str] | None | List of parameter names to preserve as backend parameters |
composite_emitters | list[CompositeGateEmitter[T]] | None | Optional 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¶
MAX_UNROLL_DEPTH: intconfig: TranspilerConfig Get the transpiler configuration.
Methods¶
affine_validate¶
def affine_validate(self, block: Block) -> BlockPass 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) -> BlockPass 2: Validate and analyze dependencies.
classical_lowering¶
def classical_lowering(self, block: Block) -> BlockPass 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) -> BlockPass 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:
| Name | Type | Description |
|---|---|---|
separated | ProgramPlan | The separated program to emit |
bindings | dict[str, Any] | None | Parameter values to bind at compile time |
parameters | list[str] | None | Parameter 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) -> BlockPass 1: Inline all CallBlockOperations.
lower_compile_time_ifs¶
def lower_compile_time_ifs(self, block: Block, bindings: dict[str, Any] | None = None) -> BlockPass 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) -> BlockPass 1.75: Fold constants and lower compile-time control flow.
plan¶
def plan(self, block: Block) -> ProgramPlanPass 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) -> BlockPass 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) -> NoneSet the transpiler configuration.
Parameters:
| Name | Type | Description |
|---|---|---|
config | TranspilerConfig | Transpiler configuration to use |
substitute¶
def substitute(self, block: Block) -> BlockPass 0.5: Apply substitutions (optional).
This pass replaces CallBlockOperation targets and sets strategy names on CompositeGateOperations based on config.
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | Block 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,
) -> BlockConvert a QKernel to a Block.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernel | The QKernel to convert |
bindings | dict[str, Any] | None | Concrete values to bind at trace time (resolves array shapes) |
parameters | list[str] | None | Names 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) -> TCompile and extract just the quantum circuit.
This is a convenience method for when you just want the backend circuit without the full executable.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernel | The QKernel to compile |
bindings | dict[str, Any] | None | Parameter 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:
| Name | Type | Description |
|---|---|---|
kernel | QKernel | The QKernel to compile |
bindings | dict[str, Any] | None | Parameter 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. |
parameters | list[str] | None | Parameter names to preserve as backend parameters |
Returns:
ExecutableProgram[T] — ExecutableProgram ready for execution
Raises:
ValueError— If a name appears in bothbindingsandparameters. A name being in both is ambiguous (placeholder value vs runtime symbol) and used to silently miscompile control-flow predicates that depended on parameter-array elements; rejecting the overlap up front keeps the contract unambiguous.QamomileCompileError— If compilation fails (validation, dependency errors)
Pipeline:
to_block: Convert QKernel to Block
substitute: Apply substitutions (if configured)
resolve_parameter_shapes: Constant-fold symbolic Vector param dims
inline: Inline CallBlockOperations
affine_validate: Validate affine type semantics
partial_eval: Fold constants and lower compile-time control flow
analyze: Validate and analyze dependencies
validate_symbolic_shapes: Reject unresolved parameter shape dims
plan: Build ProgramPlan (segment into C->Q->C steps)
emit: Generate backend-specific code
unroll_recursion¶
def unroll_recursion(self, block: Block, bindings: dict[str, Any] | None = None) -> BlockFixed-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 the call count
stops decreasing (symbolic driver — self-calls are left in the
IR and handled by downstream passes), or when MAX_UNROLL_DEPTH
is reached (non-terminating recursion — raises).
validate_symbolic_shapes¶
def validate_symbolic_shapes(self, block: Block) -> BlockPass 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.
WhileOperation [source]¶
class WhileOperation(HasNestedOps, Operation)Represents a while loop operation.
Only measurement-backed conditions are supported: the condition must
be a Bit value produced by qmc.measure(). Non-measurement
conditions (classical variables, constants, comparisons) are rejected
by ValidateWhileContractPass before reaching backend emit.
Example::
bit = qmc.measure(q)
while bit:
q = qmc.h(q)
bit = qmc.measure(q)Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
operations: list[Operation] = list(),
max_iterations: int | None = None,
) -> NoneAttributes¶
max_iterations: int | Noneoperation_kind: OperationKindoperations: list[Operation]signature: Signature
Methods¶
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation