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.circuit.frontend


qamomile.circuit.frontend.ast_transform

Overview

FunctionDescription
collect_quantum_rebind_violationsAnalyze func for forbidden quantum rebind patterns.
emit_ifBuilder function for if-else conditional with Phi function merging.
for_itemsBuilder function to create a for-items loop in Qamomile frontend.
for_loopBuilder function to create a for loop in Qamomile frontend.
transform_control_flow
while_loopCreate a while loop whose condition is a measurement result.
ClassDescription
ControlFlowTransformer
QuantumRebindAnalyzerDetects forbidden quantum variable reassignment at the AST level.
RebindViolationA detected forbidden quantum variable rebinding.
VariableCollectorCollect variables used and mutated within a block.

Functions

collect_quantum_rebind_violations [source]

def collect_quantum_rebind_violations(func: Callable, quantum_param_names: set[str]) -> list[RebindViolation]

Analyze func for forbidden quantum rebind patterns.

Returns a (possibly empty) list of violations. Never raises on analysis failure – returns [] instead.


emit_if [source]

def emit_if(
    cond_func: Callable,
    true_func: Callable,
    false_func: Callable,
    variables: list,
) -> Any

Builder function for if-else conditional with Phi function merging.

This function is called from AST-transformed code. The AST transformer converts: if condition: true_body else: false_body

Into:

def _cond_N(vars): return condition def _body_N(vars): true_body; return vars def _body_N+1(vars): false_body; return vars result = emit_if(_cond_N, _body_N, _body_N+1, [var_list])

Parameters:

NameTypeDescription
cond_functyping.CallableFunction returning the condition (Bit or bool-like Handle)
true_functyping.CallableFunction executing true branch, returns updated variables
false_functyping.CallableFunction executing false branch, returns updated variables
variableslistList of variables used in the branches

Returns:

typing.Any — Merged variable values after conditional execution (using Phi functions)

Example:

@qkernel
def my_kernel(q: Qubit) -> Qubit:
    result = measure(q)
    if result:
        q = z(q)
    return q

for_items [source]

def for_items(
    d: Dict,
    key_var_names: list[str],
    value_var_name: str,
) -> Generator[tuple[Any, Any], None, None]

Builder function to create a for-items loop in Qamomile frontend.

This context manager creates a ForItemsOperation that iterates over dictionary (key, value) pairs. The operation is always unrolled at transpile time since quantum backends cannot natively iterate over classical data structures.

Parameters:

NameTypeDescription
dDictDict handle to iterate over
key_var_nameslist[str]Names of key unpacking variables (e.g., [“i”, “j”] for tuple keys)
value_var_namestrName of value variable (e.g., “Jij”)

Yields:

tuple[typing.Any, typing.Any] — Tuple of (key_handles, value_handle) for use in loop body

Example:

@qkernel
def ising_cost(
    q: Vector[Qubit],
    ising: Dict[Tuple[UInt, UInt], Float],
    gamma: Float,
) -> Vector[Qubit]:
    for (i, j), Jij in qmc.items(ising):
        q[i], q[j] = qmc.rzz(q[i], q[j], gamma * Jij)
    return q

for_loop [source]

def for_loop(
    start,
    stop,
    step = 1,
    var_name: str = '_loop_idx',
) -> Generator[UInt, None, None]

Builder function to create a for loop in Qamomile frontend.

Parameters:

NameTypeDescription
start``Loop start value (can be Handle or int)
stop``Loop stop value (can be Handle or int)
step``Loop step value (default=1)
var_namestrName of the loop variable (default=“_loop_idx”)

Yields:

UInt — The loop iteration variable (can be used as array index)

Example:

@QKernel
def my_kernel(qubits: Array[Qubit, Literal[3]]) -> Array[Qubit, Literal[3]]:
    for i in qm.range(3):
        qubits[i] = h(qubits[i])
    return qubits

@QKernel
def my_kernel2(qubits: Array[Qubit, Literal[5]]) -> Array[Qubit, Literal[5]]:
    for i in qm.range(1, 4):  # i = 1, 2, 3
        qubits[i] = h(qubits[i])
    return qubits

transform_control_flow [source]

def transform_control_flow(func: Callable)

while_loop [source]

def while_loop(cond: Callable) -> Generator[WhileLoop, None, None]

Create a while loop whose condition is a measurement result.

The condition must be a Bit produced by qmc.measure(). Non-measurement conditions (classical variables, constants, comparisons) are accepted at build time but will be rejected by ValidateWhileContractPass during transpilation.

Parameters:

NameTypeDescription
condtyping.CallableA callable (lambda) that returns the loop condition. Must return a Bit handle originating from qmc.measure().

Yields:

WhileLoop — A marker object for the while loop context.

Example::

@qm.qkernel
def repeat_until_zero() -> qm.Bit:
    q = qm.qubit("q")
    q = qm.h(q)
    bit = qm.measure(q)
    while bit:
        q = qm.qubit("q2")
        q = qm.h(q)
        bit = qm.measure(q)
    return bit

Classes

ControlFlowTransformer [source]

class ControlFlowTransformer(ast.NodeTransformer)
Constructor
def __init__(
    self,
    global_names: set[str] | None = None,
    param_names: set[str] | None = None,
    namespace: dict[str, Any] | None = None,
) -> None
Attributes
Methods
visit_AnnAssign
def visit_AnnAssign(self, node: ast.AnnAssign) -> Any

Detect annotated assignments such as a: int = 0 and register the type information.

visit_For
def visit_For(self, node: ast.For) -> Any
visit_FunctionDef
def visit_FunctionDef(self, node: ast.FunctionDef) -> ast.FunctionDef

Process the function body with definition tracking.

Collects parameter names as the initial set of defined variables and delegates to _visit_body_with_tracking for sequential statement processing.

visit_If
def visit_If(self, node: ast.If) -> Any
visit_While
def visit_While(self, node: ast.While) -> Any

QuantumRebindAnalyzer [source]

class QuantumRebindAnalyzer(ast.NodeVisitor)

Detects forbidden quantum variable reassignment at the AST level.

Forbidden patterns (target is an existing quantum variable):

Allowed patterns:

Constructor
def __init__(self, quantum_param_names: set[str]) -> None
Attributes
Methods
visit_Assign
def visit_Assign(self, node: ast.Assign) -> None

RebindViolation [source]

class RebindViolation

A detected forbidden quantum variable rebinding.

Constructor
def __init__(
    self,
    target_name: str,
    source_name: str,
    func_name: str | None,
    lineno: int,
) -> None
Attributes

VariableCollector [source]

class VariableCollector(ast.NodeVisitor)

Collect variables used and mutated within a block.

Excludes:

Constructor
def __init__(self, global_names: set[str] | None = None)
Attributes
Methods
visit_Assign
def visit_Assign(self, node: ast.Assign)

Visit the RHS first to match Python’s evaluation order.

q1 = qm.h(q1) → RHS q1 (Load) is first → first_context is “Load” cond2 = qm.measure(q2) → RHS q2 (Load) first, LHS cond2 (Store) after

visit_Attribute
def visit_Attribute(self, node: ast.Attribute)

Record the base name of an attribute access.

Global names such as module names (qm.h) are excluded as before, while user variables (qs.shape) are treated as Load.

visit_AugAssign
def visit_AugAssign(self, node: ast.AugAssign)

AugAssign (e.g. x += 1) is an implicit Read-before-Write.

Visit the RHS first and record Name targets as both Load and Store. first_context is “Load” (the existing value is read first).

visit_Call
def visit_Call(self, node: ast.Call)

Exclude the function name of a call.

visit_FunctionDef
def visit_FunctionDef(self, node: ast.FunctionDef)

Skip traversal of inner function definitions.

visit_Name
def visit_Name(self, node: ast.Name)

Collect variable names (only those not in the exclude list).


qamomile.circuit.frontend.composite_gate

Frontend interface for composite gates.

Overview

FunctionDescription
composite_gateDecorator to create a CompositeGate from a qkernel function or as a stub.
get_current_tracer
traceContext manager to set the current tracer.
ClassDescription
BlockUnified block representation for all pipeline stages.
BlockKindClassification of block structure for pipeline stages.
CompositeGateBase class for user-facing composite gate definitions.
CompositeGateOperationRepresents a composite gate (QPE, QFT, etc.) as a single operation.
CompositeGateTypeRegistry of known composite gate types.
DecompositionStrategyProtocol for defining decomposition strategies.
Qubit
ResourceMetadataResource estimation metadata for composite gates.
Tracer
ValueA typed SSA value in the IR.
Vector1-dimensional array type.

Functions

composite_gate [source]

def composite_gate(
    func: Callable | None = None,
    *,
    stub: bool = False,
    name: str = '',
    num_qubits: int | None = None,
    num_controls: int = 0,
    resource_metadata: ResourceMetadata | None = None,
    gate_type: CompositeGateType = CompositeGateType.CUSTOM,
) -> _WrappedCompositeGate | _StubCompositeGate | Callable[[Callable], _WrappedCompositeGate | _StubCompositeGate]

Decorator to create a CompositeGate from a qkernel function or as a stub.

Usage with qkernel (implementation provided): composite_gate [source](name=“my_qft”) qkernel [source] def my_qft(q0: Qubit, q1: Qubit) -> tuple[Qubit, Qubit]: q0 = h(q0) q0, q1 = cp(q0, q1, pi/2) q1 = h(q1) return q0, q1

# Usage:
q0, q1 = my_qft(q0, q1)

Usage as stub (no implementation, for resource estimation): composite_gate [source]( stub=True, name=“oracle”, num_qubits=5, resource_metadata=ResourceMetadata(query_complexity=100, t_gates=10), ) def oracle(): pass

# Usage:
results = oracle(*qubits)
metadata = oracle.get_resource_metadata()

Parameters:

NameTypeDescription
funcCallable | NoneThe qkernel function (when used without arguments)
stubboolIf True, create a stub gate with no implementation
namestrName for the composite gate
num_qubitsint | NoneNumber of target qubits (required for stub)
num_controlsintNumber of control qubits (default: 0)
resource_metadataResourceMetadata | NoneResourceMetadata for resource estimation (stub mode)
gate_typeCompositeGateTypeThe type of composite gate (default: CUSTOM)

Returns:

_WrappedCompositeGate | _StubCompositeGate | Callable[[Callable], _WrappedCompositeGate | _StubCompositeGate] — A CompositeGate instance that can be called like a gate function.


get_current_tracer [source]

def get_current_tracer() -> Tracer

trace [source]

def trace(tracer: Tracer | None = None) -> Generator[Tracer, None, None]

Context manager to set the current tracer.

Classes

Block [source]

class Block

Unified block representation for all pipeline stages.

Replaces the older traced and callable IR wrappers with a single structure. The kind field indicates which pipeline stage this block is at.

Constructor
def __init__(
    self,
    name: str = '',
    label_args: list[str] = list(),
    input_values: list[Value] = list(),
    output_values: list[Value] = list(),
    output_names: list[str] = list(),
    operations: list['Operation'] = list(),
    kind: BlockKind = BlockKind.HIERARCHICAL,
    parameters: dict[str, Value] = dict(),
) -> None
Attributes
Methods
call
def call(self, **kwargs: Value = {}) -> 'CallBlockOperation'

Create a CallBlockOperation against this block.

is_affine
def is_affine(self) -> bool

Check if block contains no CallBlockOperations.

unbound_parameters
def unbound_parameters(self) -> list[str]

Return list of unbound parameter names.


BlockKind [source]

class BlockKind(Enum)

Classification of block structure for pipeline stages.

Attributes

CompositeGate [source]

class CompositeGate(abc.ABC)

Base class for user-facing composite gate definitions.

Subclasses can define composite gates in two ways:

  1. Using _decompose() (recommended for users): Define the gate decomposition using frontend syntax (same as qkernel [source]).

    class QFT(CompositeGate):
        def __init__(self, num_qubits: int):
            self._num_qubits = num_qubits
    
        @property
        def num_target_qubits(self) -> int:
            return self._num_qubits
    
        def _decompose(self, qubits: Vector[Qubit]) -> Vector[Qubit]:
            # Use frontend syntax: qm.h(), qm.cp(), qm.range(), etc.
            n = self._num_qubits
            for j in qmc.range(n - 1, -1, -1):
                qubits[j] = qmc.h(qubits[j])
                for k in qmc.range(j - 1, -1, -1):
                    angle = math.pi / (2 ** (j - k))
                    qubits[j], qubits[k] = qmc.cp(qubits[j], qubits[k], angle)
            return qubits
    
        def _resources(self) -> ResourceMetadata:
            return ResourceMetadata(t_gates=0)
  2. Using get_implementation() (advanced): Return a pre-built Block directly.

Example usage:

# Factory function pattern
def qft(qubits: Vector[Qubit]) -> Vector[Qubit]:
    n = _get_size(qubits)
    return QFT(n)(qubits)

# Direct class usage
result = QFT(3)(*qubit_list)
Attributes
Methods
build_decomposition
def build_decomposition(self, *qubits: Qubit = (), **params: Any = {}) -> Block | None

Build the decomposition circuit dynamically.

Override this method to provide a decomposition that depends on runtime arguments (e.g., QPE needs the unitary Block).

This method is called by InlinePass when inlining composite gates that have dynamic implementations.

Parameters:

NameTypeDescription
*qubitsQubitThe qubits passed to the gate
**paramsAnyAdditional parameters (e.g., unitary for QPE)

Returns:

Block | None — Block containing the decomposition, or None if not available.

Example:

class QPE(CompositeGate):
    def build_decomposition(self, *qubits, **params):
        unitary = params.get("unitary")
        # Build QPE circuit using the unitary
        return self._build_qpe_impl(qubits, unitary)
get_implementation
def get_implementation(self) -> Block | None

Get the implementation Block, if any.

Return None for stub gates (used in resource estimation). Override in subclasses to provide implementation.

Note: If _decompose() is defined, it takes precedence over this method.

get_resource_metadata
def get_resource_metadata(self) -> ResourceMetadata | None

Get resource estimation metadata.

Returns _resources() if defined, otherwise None. Override _resources() to provide resource hints.

get_resources_for_strategy
def get_resources_for_strategy(self, strategy_name: str | None = None) -> ResourceMetadata | None

Get resource metadata for a specific strategy.

Parameters:

NameTypeDescription
strategy_namestr | NoneStrategy to query, or None for default

Returns:

ResourceMetadata | None — ResourceMetadata for the strategy, or None if not available

get_strategy
@classmethod
def get_strategy(cls, name: str | None = None) -> 'DecompositionStrategy | None'

Get a registered decomposition strategy.

Parameters:

NameTypeDescription
namestr | NoneStrategy name, or None for default strategy

Returns:

'DecompositionStrategy | None' — DecompositionStrategy instance, or None if not found

list_strategies
@classmethod
def list_strategies(cls) -> list[str]

List all registered strategy names.

Returns:

list[str] — List of strategy names

register_strategy
@classmethod
def register_strategy(cls, name: str, strategy: 'DecompositionStrategy') -> None

Register a decomposition strategy for this gate type.

Parameters:

NameTypeDescription
namestrStrategy identifier (e.g., “standard”, “approximate”)
strategy'DecompositionStrategy'DecompositionStrategy instance

Example:

QFT.register_strategy("approximate", ApproximateQFTStrategy(k=3))
set_default_strategy
@classmethod
def set_default_strategy(cls, name: str) -> None

Set the default decomposition strategy.

Parameters:

NameTypeDescription
namestrStrategy name to use as default

Raises:


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

CompositeGateType [source]

class CompositeGateType(enum.Enum)

Registry of known composite gate types.

Attributes

DecompositionStrategy [source]

class DecompositionStrategy(Protocol)

Protocol for defining decomposition strategies.

A decomposition strategy provides:

  1. A unique name for identification

  2. A decompose method that performs the actual decomposition

  3. Resource estimation for the decomposition

Strategies allow the same composite gate to have multiple implementations with different trade-offs (e.g., precision vs. gate count).

Attributes
Methods
decompose
def decompose(self, qubits: tuple['Qubit', ...]) -> tuple['Qubit', ...]

Perform the decomposition.

Parameters:

NameTypeDescription
qubitstuple['Qubit', ...]Input qubits to decompose

Returns:

tuple['Qubit', ...] — Output qubits after decomposition

resources
def resources(self, num_qubits: int) -> 'ResourceMetadata'

Return resource estimates for this decomposition.

Parameters:

NameTypeDescription
num_qubitsintNumber of qubits the gate operates on

Returns:

'ResourceMetadata' — ResourceMetadata with gate counts, depth estimates, etc.


Qubit [source]

class Qubit(Handle)
Constructor
def __init__(
    self,
    value: Value[QubitType],
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None
Attributes

ResourceMetadata [source]

class ResourceMetadata

Resource estimation metadata for composite gates.

Gate count fields mirror GateCount categories.

None semantics:

Fields left as None mean “unknown/unspecified”. During extraction, gate_counter treats None as 0, which may undercount resources if the true value is nonzero. To ensure accurate resource estimates, set all relevant fields explicitly.

When total_gates is set but some of single_qubit_gates, two_qubit_gates, or multi_qubit_gates are None, the extractor emits a UserWarning if the known sub-total is less than total_gates, indicating potentially missing gate category data.

Constructor
def __init__(
    self,
    query_complexity: int | None = None,
    t_gates: int | None = None,
    ancilla_qubits: int = 0,
    total_gates: int | None = None,
    single_qubit_gates: int | None = None,
    two_qubit_gates: int | None = None,
    multi_qubit_gates: int | None = None,
    clifford_gates: int | None = None,
    rotation_gates: int | None = None,
    custom_metadata: dict[str, Any] = dict(),
) -> None
Attributes

Tracer [source]

class Tracer
Constructor
def __init__(self, _operations: list[Operation] = list()) -> None
Attributes
Methods
add_operation
def add_operation(self, op) -> None

Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


Vector [source]

class Vector(ArrayBase[T])

1-dimensional array type.

Example:

import qamomile.circuit as qmc

# Create a vector of 3 qubits
qubits: qmc.Vector[qmc.Qubit] = qmc.qubit_array(3, name="qubits")

# Access elements
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0

# Apply H gate to all qubits (CORRECT)
n = qubits.shape[0]
for i in qmc.range(n):
    qubits[i] = qmc.h(qubits[i])
Constructor
def __init__(
    self,
    value: ArrayValue = None,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _shape: tuple[int | UInt] = (0,),
    _borrowed_indices: dict[tuple[str, ...], tuple[UInt, ...]] = dict(),
) -> None
Attributes

qamomile.circuit.frontend.constructors

Overview

FunctionDescription
bitCreate a Bit handle from a boolean/int literal or declare a named Bit parameter.
float_Create a Float handle from a float literal or declare a named Float parameter.
get_current_tracer
qubitCreate a new qubit and emit a QInitOperation.
qubit_arrayCreate a new qubit array (vector/matrix/tensor) and emit QInitOperations.
uintCreate a UInt handle from an integer literal or declare a named UInt parameter.
ClassDescription
ArrayValueAn array of typed IR values.
QInitOperationInitialize the qubit
ValueA typed SSA value in the IR.

Functions

bit [source]

def bit(arg: bool | str | int) -> Bit

Create a Bit handle from a boolean/int literal or declare a named Bit parameter.


float_ [source]

def float_(arg: float | str) -> Float

Create a Float handle from a float literal or declare a named Float parameter.


get_current_tracer [source]

def get_current_tracer() -> Tracer

qubit [source]

def qubit(name: str) -> Qubit

Create a new qubit and emit a QInitOperation.


qubit_array [source]

def qubit_array(
    shape: UInt | int | tuple[UInt | int, ...],
    name: str,
) -> Vector[Qubit] | Matrix[Qubit] | Tensor[Qubit]

Create a new qubit array (vector/matrix/tensor) and emit QInitOperations.


uint [source]

def uint(arg: int | str) -> UInt

Create a UInt handle from an integer literal or declare a named UInt parameter.

Classes

ArrayValue [source]

class ArrayValue(Value[T])

An array of typed IR values.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
    shape: tuple[Value, ...] = tuple(),
) -> None
Attributes
Methods
next_version
def next_version(self) -> ArrayValue[T]

QInitOperation [source]

class QInitOperation(Operation)

Initialize the qubit

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

Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


qamomile.circuit.frontend.decomposition

Decomposition strategy framework for composite gates.

This module provides the infrastructure for defining multiple decomposition patterns for composite gates, enabling flexible gate synthesis strategies.

Example:

class StandardQFTStrategy:
    @property
    def name(self) -> str:
        return "standard"

    def decompose(self, qubits: tuple[Qubit, ...]) -> tuple[Qubit, ...]:
        # Full precision QFT implementation
        ...

    def resources(self, num_qubits: int) -> ResourceMetadata:
        return ResourceMetadata(...)

class ApproximateQFTStrategy:
    def __init__(self, truncation_depth: int = 3):
        self._k = truncation_depth

    @property
    def name(self) -> str:
        return f"approximate_k{self._k}"

    def decompose(self, qubits: tuple[Qubit, ...]) -> tuple[Qubit, ...]:
        # Truncated rotations QFT
        ...

# Register strategies
QFT.register_strategy("standard", StandardQFTStrategy())
QFT.register_strategy("approximate", ApproximateQFTStrategy(truncation_depth=3))

Overview

FunctionDescription
get_global_registryGet the global strategy registry.
get_strategyGet a strategy from the global registry.
register_strategyRegister a strategy in the global registry.
ClassDescription
DecompositionConfigConfiguration for decomposition strategy selection.
DecompositionStrategyProtocol for defining decomposition strategies.
Qubit
ResourceMetadataResource estimation metadata for composite gates.
StrategyRegistryRegistry for managing decomposition strategies.

Functions

get_global_registry [source]

def get_global_registry() -> StrategyRegistry

Get the global strategy registry.

Returns:

StrategyRegistry — The global StrategyRegistry instance


get_strategy [source]

def get_strategy(
    gate_name: str,
    strategy_name: str | None = None,
) -> DecompositionStrategy | None

Get a strategy from the global registry.

Parameters:

NameTypeDescription
gate_namestrThe gate name
strategy_namestr | NoneThe strategy name (uses “standard” if None)

Returns:

DecompositionStrategy | None — The strategy instance, or None if not found


register_strategy [source]

def register_strategy(gate_name: str, strategy_name: str, strategy: DecompositionStrategy) -> None

Register a strategy in the global registry.

Parameters:

NameTypeDescription
gate_namestrThe gate name (e.g., “qft”, “iqft”)
strategy_namestrThe strategy name (e.g., “standard”, “approximate”)
strategyDecompositionStrategyThe strategy instance

Classes

DecompositionConfig [source]

class DecompositionConfig

Configuration for decomposition strategy selection.

This configuration is passed to the transpiler to control which decomposition strategies are used for composite gates.

Constructor
def __init__(
    self,
    strategy_overrides: dict[str, str] = dict(),
    strategy_params: dict[str, dict[str, Any]] = dict(),
    default_strategy: str = 'standard',
) -> None
Attributes
Methods
get_strategy_for_gate
def get_strategy_for_gate(self, gate_name: str) -> str

Get the strategy name for a specific gate.

Parameters:

NameTypeDescription
gate_namestrThe gate name (e.g., “qft”, “iqft”)

Returns:

str — Strategy name to use

get_strategy_params
def get_strategy_params(self, strategy_name: str) -> dict[str, Any]

Get parameters for a specific strategy.

Parameters:

NameTypeDescription
strategy_namestrThe strategy name

Returns:

dict[str, Any] — Dictionary of parameters


DecompositionStrategy [source]

class DecompositionStrategy(Protocol)

Protocol for defining decomposition strategies.

A decomposition strategy provides:

  1. A unique name for identification

  2. A decompose method that performs the actual decomposition

  3. Resource estimation for the decomposition

Strategies allow the same composite gate to have multiple implementations with different trade-offs (e.g., precision vs. gate count).

Attributes
Methods
decompose
def decompose(self, qubits: tuple['Qubit', ...]) -> tuple['Qubit', ...]

Perform the decomposition.

Parameters:

NameTypeDescription
qubitstuple['Qubit', ...]Input qubits to decompose

Returns:

tuple['Qubit', ...] — Output qubits after decomposition

resources
def resources(self, num_qubits: int) -> 'ResourceMetadata'

Return resource estimates for this decomposition.

Parameters:

NameTypeDescription
num_qubitsintNumber of qubits the gate operates on

Returns:

'ResourceMetadata' — ResourceMetadata with gate counts, depth estimates, etc.


Qubit [source]

class Qubit(Handle)
Constructor
def __init__(
    self,
    value: Value[QubitType],
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None
Attributes

ResourceMetadata [source]

class ResourceMetadata

Resource estimation metadata for composite gates.

Gate count fields mirror GateCount categories.

None semantics:

Fields left as None mean “unknown/unspecified”. During extraction, gate_counter treats None as 0, which may undercount resources if the true value is nonzero. To ensure accurate resource estimates, set all relevant fields explicitly.

When total_gates is set but some of single_qubit_gates, two_qubit_gates, or multi_qubit_gates are None, the extractor emits a UserWarning if the known sub-total is less than total_gates, indicating potentially missing gate category data.

Constructor
def __init__(
    self,
    query_complexity: int | None = None,
    t_gates: int | None = None,
    ancilla_qubits: int = 0,
    total_gates: int | None = None,
    single_qubit_gates: int | None = None,
    two_qubit_gates: int | None = None,
    multi_qubit_gates: int | None = None,
    clifford_gates: int | None = None,
    rotation_gates: int | None = None,
    custom_metadata: dict[str, Any] = dict(),
) -> None
Attributes

StrategyRegistry [source]

class StrategyRegistry

Registry for managing decomposition strategies.

This class provides a centralized registry for strategies, allowing them to be looked up by name across the transpiler pipeline.

Example:

registry = StrategyRegistry()
registry.register("qft", "standard", StandardQFTStrategy())
registry.register("qft", "approximate", ApproximateQFTStrategy())

strategy = registry.get("qft", "standard")
Constructor
def __init__(self) -> None

Initialize empty registry.

Methods
get
def get(
    self,
    gate_name: str,
    strategy_name: str | None = None,
) -> DecompositionStrategy | None

Get a strategy for a gate.

Parameters:

NameTypeDescription
gate_namestrThe gate name
strategy_namestr | NoneThe strategy name (uses “standard” if None)

Returns:

DecompositionStrategy | None — The strategy instance, or None if not found

list_gates
def list_gates(self) -> list[str]

List all gates with registered strategies.

Returns:

list[str] — List of gate names

list_strategies
def list_strategies(self, gate_name: str) -> list[str]

List available strategies for a gate.

Parameters:

NameTypeDescription
gate_namestrThe gate name

Returns:

list[str] — List of strategy names

register
def register(
    self,
    gate_name: str,
    strategy_name: str,
    strategy: DecompositionStrategy,
) -> None

Register a strategy for a gate.

Parameters:

NameTypeDescription
gate_namestrThe gate name (e.g., “qft”, “iqft”)
strategy_namestrThe strategy name (e.g., “standard”, “approximate”)
strategyDecompositionStrategyThe strategy instance

qamomile.circuit.frontend.func_to_block

Overview

FunctionDescription
create_dummy_handleCreate a dummy Handle instance based on ValueType.
create_dummy_inputCreate a dummy input based on parameter type annotation.
func_to_blockConvert a function to a hierarchical Block.
get_current_tracer
handle_type_mapMap Handle type to ValueType.
is_array_typeCheck if type is a Vector, Matrix, or Tensor subclass.
is_dict_typeCheck if type is a Dict handle type.
is_tuple_typeCheck if type is a Tuple handle type.
traceContext manager to set the current tracer.
ClassDescription
ArrayValueAn array of typed IR values.
Bit
BitTypeType representing a classical bit.
BlockUnified block representation for all pipeline stages.
BlockKindClassification of block structure for pipeline stages.
DictDict handle for qkernel functions.
DictTypeType representing a dictionary mapping keys to values.
DictValueA dictionary value stored as stable ordered entries.
FloatFloating-point handle with arithmetic operations.
FloatTypeType representing a floating-point number.
ObservableHandle representing a Hamiltonian observable parameter.
ObservableTypeType representing a Hamiltonian observable parameter.
QInitOperationInitialize the qubit
Qubit
ReturnOperationExplicit return operation marking the end of a block with return values.
Tracer
TupleTuple handle for qkernel functions.
TupleTypeType representing a tuple of values.
TupleValueA tuple of IR values for structured data.
UIntUnsigned integer handle with arithmetic operations.
UIntTypeType representing an unsigned integer.
ValueA typed SSA value in the IR.
ValueTypeBase class for all value types in the IR.

Constants

Functions

create_dummy_handle [source]

def create_dummy_handle(value_type: ValueType, name: str = 'dummy', emit_init: bool = True) -> Handle

Create a dummy Handle instance based on ValueType.

Parameters:

NameTypeDescription
value_typeValueTypeThe IR type for the value.
namestrName for the value.
emit_initboolIf True, emit QInitOperation for qubit types (requires active tracer).

Used for creating input parameters during tracing.


create_dummy_input [source]

def create_dummy_input(param_type: Any, name: str = 'param', emit_init: bool = True) -> Handle

Create a dummy input based on parameter type annotation.

Parameters:

NameTypeDescription
param_typetyping.AnyThe type annotation for the parameter.
namestrName for the value.
emit_initboolIf True, emit QInitOperation for qubit arrays (default: True). Set to False when creating a nested Block’s internal dummy inputs.

This creates input Handles for function parameters.


func_to_block [source]

def func_to_block(func: Callable) -> Block

Convert a function to a hierarchical Block.

Example:

def my_func(a: UInt, b: UInt) -> tuple[UInt]:
    c = a + b
    return (c, )

block = func_to_block(my_func)

get_current_tracer [source]

def get_current_tracer() -> Tracer

handle_type_map [source]

def handle_type_map(handle_type: type[Handle] | type) -> ValueType

Map Handle type to ValueType.


is_array_type [source]

def is_array_type(t: Any) -> bool

Check if type is a Vector, Matrix, or Tensor subclass.


is_dict_type [source]

def is_dict_type(t: Any) -> bool

Check if type is a Dict handle type.


is_tuple_type [source]

def is_tuple_type(t: Any) -> bool

Check if type is a Tuple handle type.


trace [source]

def trace(tracer: Tracer | None = None) -> Generator[Tracer, None, None]

Context manager to set the current tracer.

Classes

ArrayValue [source]

class ArrayValue(Value[T])

An array of typed IR values.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
    shape: tuple[Value, ...] = tuple(),
) -> None
Attributes
Methods
next_version
def next_version(self) -> ArrayValue[T]

Bit [source]

class Bit(Handle)
Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: bool = False,
) -> None
Attributes

BitType [source]

class BitType(ClassicalTypeMixin, ValueType)

Type representing a classical bit.


Block [source]

class Block

Unified block representation for all pipeline stages.

Replaces the older traced and callable IR wrappers with a single structure. The kind field indicates which pipeline stage this block is at.

Constructor
def __init__(
    self,
    name: str = '',
    label_args: list[str] = list(),
    input_values: list[Value] = list(),
    output_values: list[Value] = list(),
    output_names: list[str] = list(),
    operations: list['Operation'] = list(),
    kind: BlockKind = BlockKind.HIERARCHICAL,
    parameters: dict[str, Value] = dict(),
) -> None
Attributes
Methods
call
def call(self, **kwargs: Value = {}) -> 'CallBlockOperation'

Create a CallBlockOperation against this block.

is_affine
def is_affine(self) -> bool

Check if block contains no CallBlockOperations.

unbound_parameters
def unbound_parameters(self) -> list[str]

Return list of unbound parameter names.


BlockKind [source]

class BlockKind(Enum)

Classification of block structure for pipeline stages.

Attributes

Dict [source]

class Dict(Handle, Generic[K, V])

Dict handle for qkernel functions.

Represents a dictionary mapping keys to values, commonly used for Ising coefficients like {(i, j): Jij}.

Example:

@qmc.qkernel
def ising_cost(
    q: qmc.Vector[qmc.Qubit],
    ising: qmc.Dict[qmc.Tuple[qmc.UInt, qmc.UInt], qmc.Float],
    gamma: qmc.Float,
) -> qmc.Vector[qmc.Qubit]:
    for (i, j), Jij in qmc.items(ising):
        q[i], q[j] = qmc.rzz(q[i], q[j], gamma * Jij)
    return q
Constructor
def __init__(
    self,
    value: DictValue,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _entries: list[tuple[Handle, Handle]] = list(),
    _size: UInt | None = None,
    _key_type: type | None = None,
) -> None
Attributes
Methods
items
def items(self) -> DictItemsIterator[K, V]

Return an iterator over (key, value) pairs.


DictType [source]

class DictType(ValueType)

Type representing a dictionary mapping keys to values.

Unlike simple types, DictType stores the key and value types, so equality and hashing depend on those types. When key_type and value_type are None, represents a generic Dict type.

Quantum/classical classification is derived from key/value types.

Constructor
def __init__(
    self,
    key_type: ValueType | None = None,
    value_type: ValueType | None = None,
) -> None
Attributes
Methods
is_classical
def is_classical(self) -> bool
is_quantum
def is_quantum(self) -> bool
label
def label(self) -> str

DictValue [source]

class DictValue(_MetadataValueMixin)

A dictionary value stored as stable ordered entries.

Constructor
def __init__(
    self,
    name: str,
    entries: tuple[tuple[TupleValue | Value, Value], ...] = tuple(),
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> None
Attributes
Methods
is_constant
def is_constant(self) -> bool
next_version
def next_version(self) -> DictValue

Float [source]

class Float(ArithmeticMixin, Handle)

Floating-point handle with arithmetic operations.

Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: float = 0.0,
) -> None
Attributes

FloatType [source]

class FloatType(ClassicalTypeMixin, ValueType)

Type representing a floating-point number.


Observable [source]

class Observable(Handle)

Handle representing a Hamiltonian observable parameter.

This is a reference type - the actual qamomile.observable.Hamiltonian is provided via bindings during transpilation. It cannot be constructed or manipulated within qkernels.

Example:

import qamomile.circuit as qm
import qamomile.observable as qm_o

# Build Hamiltonian in Python
H = qm_o.Z(0) * qm_o.Z(1) + 0.5 * qm_o.X(0)

@qm.qkernel
def vqe(q: qm.Vector[qm.Qubit], H: qm.Observable) -> qm.Float:
    # Use Hamiltonian from bindings
    return qm.expval(q, H)

# Pass via bindings
executable = transpiler.transpile(vqe, bindings={"H": H})
Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None

ObservableType [source]

class ObservableType(ObjectTypeMixin, ValueType)

Type representing a Hamiltonian observable parameter.

This is a reference type - the actual qamomile.observable.Hamiltonian is provided via bindings during transpilation. It cannot be constructed or manipulated within qkernels.

Example usage:

import qamomile.circuit as qm
import qamomile.observable as qm_o

# Build Hamiltonian in Python
H = qm_o.Z(0) * qm_o.Z(1)

@qm.qkernel
def vqe(q: qm.Vector[qm.Qubit], H: qm.Observable) -> qm.Float:
    return qm.expval(q, H)

# H is passed as binding
executable = transpiler.transpile(vqe, bindings={"H": H})
Constructor
def __init__(self) -> None

QInitOperation [source]

class QInitOperation(Operation)

Initialize the qubit

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

Qubit [source]

class Qubit(Handle)
Constructor
def __init__(
    self,
    value: Value[QubitType],
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None
Attributes

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

Tracer [source]

class Tracer
Constructor
def __init__(self, _operations: list[Operation] = list()) -> None
Attributes
Methods
add_operation
def add_operation(self, op) -> None

Tuple [source]

class Tuple(Handle, Generic[K, V])

Tuple handle for qkernel functions.

Represents a tuple of values, commonly used for multi-index keys like (i, j) in Ising models.

Example:

@qmc.qkernel
def my_kernel(idx: qmc.Tuple[qmc.UInt, qmc.UInt]) -> qmc.UInt:
    i, j = idx
    return i + j
Constructor
def __init__(
    self,
    value: TupleValue,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _elements: tuple[Handle, ...] = tuple(),
) -> None
Attributes

TupleType [source]

class TupleType(ValueType)

Type representing a tuple of values.

Unlike simple types, TupleType stores the types of its elements, so equality and hashing depend on the element types.

Quantum/classical classification is derived from element types: quantum if any element is quantum, classical if all are classical.

Constructor
def __init__(self, element_types: tuple[ValueType, ...]) -> None
Attributes
Methods
is_classical
def is_classical(self) -> bool
is_quantum
def is_quantum(self) -> bool
label
def label(self) -> str

TupleValue [source]

class TupleValue(_MetadataValueMixin)

A tuple of IR values for structured data.

Constructor
def __init__(
    self,
    name: str,
    elements: tuple[Value, ...] = tuple(),
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> None
Attributes
Methods
is_constant
def is_constant(self) -> bool
next_version
def next_version(self) -> TupleValue

UInt [source]

class UInt(ArithmeticMixin, Handle)

Unsigned integer handle with arithmetic operations.

Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: int = 0,
) -> None
Attributes

UIntType [source]

class UIntType(ClassicalTypeMixin, ValueType)

Type representing an unsigned integer.


Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


ValueType [source]

class ValueType(abc.ABC)

Base class for all value types in the IR.

Type instances are compared by class - all instances of the same type class are considered equal. This allows using type instances as dictionary keys where all QubitType() instances match.

Methods
is_classical
def is_classical(self) -> bool
is_object
def is_object(self) -> bool
is_quantum
def is_quantum(self) -> bool
label
def label(self) -> str

qamomile.circuit.frontend.handle

Overview

FunctionDescription
get_sizeReturn the size of a Vector handle as a Python integer.
ClassDescription
Bit
DictDict handle for qkernel functions.
FloatFloating-point handle with arithmetic operations.
Handle
Matrix2-dimensional array type.
ObservableHandle representing a Hamiltonian observable parameter.
QFixed
Qubit
TensorN-dimensional array type (3 or more dimensions).
TupleTuple handle for qkernel functions.
UIntUnsigned integer handle with arithmetic operations.
Vector1-dimensional array type.

Functions

get_size [source]

def get_size(arr: Vector[_H]) -> int

Return the size of a Vector handle as a Python integer.

Resolves the leading axis of arr.shape through two forms a Vector shape entry can take:

  1. A plain Python int (built-in bound shape; this is what you get from qmc.qubit_array(N, ...) for literal N).

  2. A UInt handle whose underlying Value carries a compile-time constant (set by uint(literal), _create_bound_input, or partial evaluation).

A UInt handle whose underlying Value is not a constant is treated as an unresolved symbolic dimension and raises ValueError even when the handle has the dataclass-default init_value=0. Falling back to init_value for that case would silently turn a runtime-symbolic Vector[Float] parameter into a “size 0” array, hiding programming errors. Callers that need to handle symbolic shapes (e.g., to gracefully no-op when the size is unknown) must catch the ValueError themselves.

Parameters:

NameTypeDescription
arrVector[Handle]Vector handle whose first axis size is requested.

Returns:

int — The first-axis size as a plain Python int.

Raises:

Classes

Bit [source]

class Bit(Handle)
Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: bool = False,
) -> None
Attributes

Dict [source]

class Dict(Handle, Generic[K, V])

Dict handle for qkernel functions.

Represents a dictionary mapping keys to values, commonly used for Ising coefficients like {(i, j): Jij}.

Example:

@qmc.qkernel
def ising_cost(
    q: qmc.Vector[qmc.Qubit],
    ising: qmc.Dict[qmc.Tuple[qmc.UInt, qmc.UInt], qmc.Float],
    gamma: qmc.Float,
) -> qmc.Vector[qmc.Qubit]:
    for (i, j), Jij in qmc.items(ising):
        q[i], q[j] = qmc.rzz(q[i], q[j], gamma * Jij)
    return q
Constructor
def __init__(
    self,
    value: DictValue,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _entries: list[tuple[Handle, Handle]] = list(),
    _size: UInt | None = None,
    _key_type: type | None = None,
) -> None
Attributes
Methods
items
def items(self) -> DictItemsIterator[K, V]

Return an iterator over (key, value) pairs.


Float [source]

class Float(ArithmeticMixin, Handle)

Floating-point handle with arithmetic operations.

Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: float = 0.0,
) -> None
Attributes

Handle [source]

class Handle(abc.ABC)
Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None
Attributes
Methods
consume
def consume(self, operation_name: str = 'unknown') -> Self

Mark this handle as consumed and return a fresh handle.

Parameters:

NameTypeDescription
operation_namestrName of the operation consuming this handle, used for error messages.

Returns:

typing.Self — A new handle pointing to the same underlying value.

Raises:


Matrix [source]

class Matrix(ArrayBase[T])

2-dimensional array type.

Example:

import qamomile as qm

# Create a 3x4 matrix of qubits
matrix: qm.Matrix[qm.Qubit] = qm.Matrix(shape=(3, 4))

# Access elements (always requires 2 indices)
q = matrix[0, 1]
q = qm.h(q)
matrix[0, 1] = q
Constructor
def __init__(
    self,
    value: ArrayValue = None,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _shape: tuple[int | UInt, int | UInt] = (0, 0),
    _borrowed_indices: dict[tuple[str, ...], tuple[UInt, ...]] = dict(),
) -> None
Attributes

Observable [source]

class Observable(Handle)

Handle representing a Hamiltonian observable parameter.

This is a reference type - the actual qamomile.observable.Hamiltonian is provided via bindings during transpilation. It cannot be constructed or manipulated within qkernels.

Example:

import qamomile.circuit as qm
import qamomile.observable as qm_o

# Build Hamiltonian in Python
H = qm_o.Z(0) * qm_o.Z(1) + 0.5 * qm_o.X(0)

@qm.qkernel
def vqe(q: qm.Vector[qm.Qubit], H: qm.Observable) -> qm.Float:
    # Use Hamiltonian from bindings
    return qm.expval(q, H)

# Pass via bindings
executable = transpiler.transpile(vqe, bindings={"H": H})
Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None

QFixed [source]

class QFixed(Handle)
Constructor
def __init__(
    self,
    value: Value[QFixedType],
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None
Attributes

Qubit [source]

class Qubit(Handle)
Constructor
def __init__(
    self,
    value: Value[QubitType],
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None
Attributes

Tensor [source]

class Tensor(ArrayBase[T])

N-dimensional array type (3 or more dimensions).

Example:

import qamomile as qm

# Create a 2x3x4 tensor of qubits
tensor: qm.Tensor[qm.Qubit] = qm.Tensor(shape=(2, 3, 4))

# Access elements (requires all indices)
q = tensor[0, 1, 2]
q = qm.h(q)
tensor[0, 1, 2] = q
Constructor
def __init__(
    self,
    value: ArrayValue = None,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _shape: tuple[int | UInt, ...] = tuple(),
    _borrowed_indices: dict[tuple[str, ...], tuple[UInt, ...]] = dict(),
) -> None
Attributes

Tuple [source]

class Tuple(Handle, Generic[K, V])

Tuple handle for qkernel functions.

Represents a tuple of values, commonly used for multi-index keys like (i, j) in Ising models.

Example:

@qmc.qkernel
def my_kernel(idx: qmc.Tuple[qmc.UInt, qmc.UInt]) -> qmc.UInt:
    i, j = idx
    return i + j
Constructor
def __init__(
    self,
    value: TupleValue,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _elements: tuple[Handle, ...] = tuple(),
) -> None
Attributes

UInt [source]

class UInt(ArithmeticMixin, Handle)

Unsigned integer handle with arithmetic operations.

Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: int = 0,
) -> None
Attributes

Vector [source]

class Vector(ArrayBase[T])

1-dimensional array type.

Example:

import qamomile.circuit as qmc

# Create a vector of 3 qubits
qubits: qmc.Vector[qmc.Qubit] = qmc.qubit_array(3, name="qubits")

# Access elements
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0

# Apply H gate to all qubits (CORRECT)
n = qubits.shape[0]
for i in qmc.range(n):
    qubits[i] = qmc.h(qubits[i])
Constructor
def __init__(
    self,
    value: ArrayValue = None,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _shape: tuple[int | UInt] = (0,),
    _borrowed_indices: dict[tuple[str, ...], tuple[UInt, ...]] = dict(),
) -> None
Attributes

qamomile.circuit.frontend.handle.array

Overview

FunctionDescription
get_current_tracer
ClassDescription
AffineTypeErrorBase class for affine type violations.
ArrayBaseBase class for array types (Vector, Matrix, Tensor).
ArrayValueAn array of typed IR values.
Bit
BitTypeType representing a classical bit.
CInitOperationInitialize the classical values (const, arguments etc)
FloatFloating-point handle with arithmetic operations.
FloatTypeType representing a floating-point number.
Handle
Matrix2-dimensional array type.
QInitOperationInitialize the qubit
Qubit
QubitConsumedErrorQubit handle used after being consumed by a previous operation.
QubitTypeType representing a quantum bit (qubit).
TensorN-dimensional array type (3 or more dimensions).
UIntUnsigned integer handle with arithmetic operations.
UIntTypeType representing an unsigned integer.
UnreturnedBorrowErrorBorrowed array element not returned before array use.
ValueA typed SSA value in the IR.
Vector1-dimensional array type.

Functions

get_current_tracer [source]

def get_current_tracer() -> Tracer

Classes

AffineTypeError [source]

class AffineTypeError(QamomileCompileError)

Base class for affine type violations.

Affine types enforce that quantum resources (qubits) are used at most once. This prevents common errors such as reusing a consumed qubit or aliasing.

Constructor
def __init__(
    self,
    message: str,
    handle_name: str | None = None,
    operation_name: str | None = None,
    first_use_location: str | None = None,
)
Attributes

ArrayBase [source]

class ArrayBase(Handle, Generic[T])

Base class for array types (Vector, Matrix, Tensor).

Provides common functionality for array indexing and element access.

Constructor
def __init__(
    self,
    value: ArrayValue,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _shape: tuple[int | UInt, ...] = tuple(),
    _borrowed_indices: dict[tuple[str, ...], tuple[UInt, ...]] = dict(),
) -> None
Attributes
Methods
consume
def consume(self, operation_name: str = 'unknown') -> Self

Consume the array, enforcing borrow-return contract for quantum arrays.

For quantum arrays, all borrowed elements must be returned before the array can be consumed. This ensures that no unreturned borrows are silently discarded by operations like qkernel calls or controlled gates.

create
@classmethod
def create(
    cls,
    shape: tuple[int | UInt, ...],
    name: str,
    el_type: Type[T],
) -> 'ArrayBase[T]'

Create an ArrayValue for the given shape and name.

validate_all_returned
def validate_all_returned(self) -> None

Validate all borrowed elements have been returned.

This method is useful for ensuring that all borrowed elements have been properly written back before using the array in operations that require the entire array.

Raises:


ArrayValue [source]

class ArrayValue(Value[T])

An array of typed IR values.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
    shape: tuple[Value, ...] = tuple(),
) -> None
Attributes
Methods
next_version
def next_version(self) -> ArrayValue[T]

Bit [source]

class Bit(Handle)
Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: bool = False,
) -> None
Attributes

BitType [source]

class BitType(ClassicalTypeMixin, ValueType)

Type representing a classical bit.


CInitOperation [source]

class CInitOperation(Operation)

Initialize the classical values (const, arguments etc)

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

Float [source]

class Float(ArithmeticMixin, Handle)

Floating-point handle with arithmetic operations.

Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: float = 0.0,
) -> None
Attributes

FloatType [source]

class FloatType(ClassicalTypeMixin, ValueType)

Type representing a floating-point number.


Handle [source]

class Handle(abc.ABC)
Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None
Attributes
Methods
consume
def consume(self, operation_name: str = 'unknown') -> Self

Mark this handle as consumed and return a fresh handle.

Parameters:

NameTypeDescription
operation_namestrName of the operation consuming this handle, used for error messages.

Returns:

typing.Self — A new handle pointing to the same underlying value.

Raises:


Matrix [source]

class Matrix(ArrayBase[T])

2-dimensional array type.

Example:

import qamomile as qm

# Create a 3x4 matrix of qubits
matrix: qm.Matrix[qm.Qubit] = qm.Matrix(shape=(3, 4))

# Access elements (always requires 2 indices)
q = matrix[0, 1]
q = qm.h(q)
matrix[0, 1] = q
Constructor
def __init__(
    self,
    value: ArrayValue = None,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _shape: tuple[int | UInt, int | UInt] = (0, 0),
    _borrowed_indices: dict[tuple[str, ...], tuple[UInt, ...]] = dict(),
) -> None
Attributes

QInitOperation [source]

class QInitOperation(Operation)

Initialize the qubit

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

Qubit [source]

class Qubit(Handle)
Constructor
def __init__(
    self,
    value: Value[QubitType],
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None
Attributes

QubitConsumedError [source]

class QubitConsumedError(AffineTypeError)

Qubit handle used after being consumed by a previous operation.

Each qubit handle can only be used once. After a gate operation, you must reassign the result to use the new handle.

Example of incorrect code:

q1 = qm.h(q) q2 = qm.x(q) # ERROR: q was already consumed by h()

Correct code:

q = qm.h(q) # Reassign to capture new handle q = qm.x(q) # Use the reassigned handle


QubitType [source]

class QubitType(QuantumTypeMixin, ValueType)

Type representing a quantum bit (qubit).


Tensor [source]

class Tensor(ArrayBase[T])

N-dimensional array type (3 or more dimensions).

Example:

import qamomile as qm

# Create a 2x3x4 tensor of qubits
tensor: qm.Tensor[qm.Qubit] = qm.Tensor(shape=(2, 3, 4))

# Access elements (requires all indices)
q = tensor[0, 1, 2]
q = qm.h(q)
tensor[0, 1, 2] = q
Constructor
def __init__(
    self,
    value: ArrayValue = None,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _shape: tuple[int | UInt, ...] = tuple(),
    _borrowed_indices: dict[tuple[str, ...], tuple[UInt, ...]] = dict(),
) -> None
Attributes

UInt [source]

class UInt(ArithmeticMixin, Handle)

Unsigned integer handle with arithmetic operations.

Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: int = 0,
) -> None
Attributes

UIntType [source]

class UIntType(ClassicalTypeMixin, ValueType)

Type representing an unsigned integer.


UnreturnedBorrowError [source]

class UnreturnedBorrowError(AffineTypeError)

Borrowed array element not returned before array use.

When you borrow an element from a qubit array, you must return it (write it back) before using other elements or the array itself.

Example of incorrect code:

q0 = qubits[0] q0 = qm.h(q0) q1 = qubits[1] # ERROR: q0 not returned yet

Correct code:

q0 = qubits[0] q0 = qm.h(q0) qubits[0] = q0 # Return the borrowed element q1 = qubits[1] # Now safe to borrow another


Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


Vector [source]

class Vector(ArrayBase[T])

1-dimensional array type.

Example:

import qamomile.circuit as qmc

# Create a vector of 3 qubits
qubits: qmc.Vector[qmc.Qubit] = qmc.qubit_array(3, name="qubits")

# Access elements
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0

# Apply H gate to all qubits (CORRECT)
n = qubits.shape[0]
for i in qmc.range(n):
    qubits[i] = qmc.h(qubits[i])
Constructor
def __init__(
    self,
    value: ArrayValue = None,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _shape: tuple[int | UInt] = (0,),
    _borrowed_indices: dict[tuple[str, ...], tuple[UInt, ...]] = dict(),
) -> None
Attributes

qamomile.circuit.frontend.handle.containers

Container types for qkernel: Tuple and Dict handles.

Overview

ClassDescription
DictDict handle for qkernel functions.
DictItemsIteratorIterator for Dict.items() that yields (key, value) pairs.
DictValueA dictionary value stored as stable ordered entries.
Handle
TupleTuple handle for qkernel functions.
TupleValueA tuple of IR values for structured data.
UIntUnsigned integer handle with arithmetic operations.
UIntTypeType representing an unsigned integer.
ValueA typed SSA value in the IR.

Classes

Dict [source]

class Dict(Handle, Generic[K, V])

Dict handle for qkernel functions.

Represents a dictionary mapping keys to values, commonly used for Ising coefficients like {(i, j): Jij}.

Example:

@qmc.qkernel
def ising_cost(
    q: qmc.Vector[qmc.Qubit],
    ising: qmc.Dict[qmc.Tuple[qmc.UInt, qmc.UInt], qmc.Float],
    gamma: qmc.Float,
) -> qmc.Vector[qmc.Qubit]:
    for (i, j), Jij in qmc.items(ising):
        q[i], q[j] = qmc.rzz(q[i], q[j], gamma * Jij)
    return q
Constructor
def __init__(
    self,
    value: DictValue,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _entries: list[tuple[Handle, Handle]] = list(),
    _size: UInt | None = None,
    _key_type: type | None = None,
) -> None
Attributes
Methods
items
def items(self) -> DictItemsIterator[K, V]

Return an iterator over (key, value) pairs.


DictItemsIterator [source]

class DictItemsIterator(Generic[K, V])

Iterator for Dict.items() that yields (key, value) pairs.

This is used internally for iterating over Dict entries in qkernel.

Constructor
def __init__(self, dict_handle: 'Dict[K, V]', _index: int = 0) -> None
Attributes

DictValue [source]

class DictValue(_MetadataValueMixin)

A dictionary value stored as stable ordered entries.

Constructor
def __init__(
    self,
    name: str,
    entries: tuple[tuple[TupleValue | Value, Value], ...] = tuple(),
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> None
Attributes
Methods
is_constant
def is_constant(self) -> bool
next_version
def next_version(self) -> DictValue

Handle [source]

class Handle(abc.ABC)
Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None
Attributes
Methods
consume
def consume(self, operation_name: str = 'unknown') -> Self

Mark this handle as consumed and return a fresh handle.

Parameters:

NameTypeDescription
operation_namestrName of the operation consuming this handle, used for error messages.

Returns:

typing.Self — A new handle pointing to the same underlying value.

Raises:


Tuple [source]

class Tuple(Handle, Generic[K, V])

Tuple handle for qkernel functions.

Represents a tuple of values, commonly used for multi-index keys like (i, j) in Ising models.

Example:

@qmc.qkernel
def my_kernel(idx: qmc.Tuple[qmc.UInt, qmc.UInt]) -> qmc.UInt:
    i, j = idx
    return i + j
Constructor
def __init__(
    self,
    value: TupleValue,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _elements: tuple[Handle, ...] = tuple(),
) -> None
Attributes

TupleValue [source]

class TupleValue(_MetadataValueMixin)

A tuple of IR values for structured data.

Constructor
def __init__(
    self,
    name: str,
    elements: tuple[Value, ...] = tuple(),
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> None
Attributes
Methods
is_constant
def is_constant(self) -> bool
next_version
def next_version(self) -> TupleValue

UInt [source]

class UInt(ArithmeticMixin, Handle)

Unsigned integer handle with arithmetic operations.

Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: int = 0,
) -> None
Attributes

UIntType [source]

class UIntType(ClassicalTypeMixin, ValueType)

Type representing an unsigned integer.


Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


qamomile.circuit.frontend.handle.hamiltonian

Observable handle for Hamiltonian parameters.

This module provides the Observable handle class that represents a reference to a Hamiltonian observable provided via bindings during transpilation. Unlike HamiltonianExpr in previous versions, this is a pure parameter handle with no arithmetic operations.

Overview

ClassDescription
Handle
ObservableHandle representing a Hamiltonian observable parameter.

Classes

Handle [source]

class Handle(abc.ABC)
Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None
Attributes
Methods
consume
def consume(self, operation_name: str = 'unknown') -> Self

Mark this handle as consumed and return a fresh handle.

Parameters:

NameTypeDescription
operation_namestrName of the operation consuming this handle, used for error messages.

Returns:

typing.Self — A new handle pointing to the same underlying value.

Raises:


Observable [source]

class Observable(Handle)

Handle representing a Hamiltonian observable parameter.

This is a reference type - the actual qamomile.observable.Hamiltonian is provided via bindings during transpilation. It cannot be constructed or manipulated within qkernels.

Example:

import qamomile.circuit as qm
import qamomile.observable as qm_o

# Build Hamiltonian in Python
H = qm_o.Z(0) * qm_o.Z(1) + 0.5 * qm_o.X(0)

@qm.qkernel
def vqe(q: qm.Vector[qm.Qubit], H: qm.Observable) -> qm.Float:
    # Use Hamiltonian from bindings
    return qm.expval(q, H)

# Pass via bindings
executable = transpiler.transpile(vqe, bindings={"H": H})
Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None

qamomile.circuit.frontend.handle.handle

Overview

FunctionDescription
get_current_tracer
ClassDescription
ArithmeticMixinMixin providing arithmetic operations for numeric Handle types.
ArrayBaseBase class for array types (Vector, Matrix, Tensor).
BinOpBinary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, POW).
BinOpKind
CompOpComparison operation (EQ, NEQ, LT, LE, GT, GE).
CompOpKind
CondOpConditional logical operation (AND, OR).
CondOpKind
Handle
NotOp
QubitConsumedErrorQubit handle used after being consumed by a previous operation.
UIntUnsigned integer handle with arithmetic operations.
ValueA typed SSA value in the IR.

Functions

get_current_tracer [source]

def get_current_tracer() -> Tracer

Classes

ArithmeticMixin [source]

class ArithmeticMixin

Mixin providing arithmetic operations for numeric Handle types.

Requires:

Attributes

ArrayBase [source]

class ArrayBase(Handle, Generic[T])

Base class for array types (Vector, Matrix, Tensor).

Provides common functionality for array indexing and element access.

Constructor
def __init__(
    self,
    value: ArrayValue,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _shape: tuple[int | UInt, ...] = tuple(),
    _borrowed_indices: dict[tuple[str, ...], tuple[UInt, ...]] = dict(),
) -> None
Attributes
Methods
consume
def consume(self, operation_name: str = 'unknown') -> Self

Consume the array, enforcing borrow-return contract for quantum arrays.

For quantum arrays, all borrowed elements must be returned before the array can be consumed. This ensures that no unreturned borrows are silently discarded by operations like qkernel calls or controlled gates.

create
@classmethod
def create(
    cls,
    shape: tuple[int | UInt, ...],
    name: str,
    el_type: Type[T],
) -> 'ArrayBase[T]'

Create an ArrayValue for the given shape and name.

validate_all_returned
def validate_all_returned(self) -> None

Validate all borrowed elements have been returned.

This method is useful for ensuring that all borrowed elements have been properly written back before using the array in operations that require the entire array.

Raises:


BinOp [source]

class BinOp(BinaryOperationBase)

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

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

BinOpKind [source]

class BinOpKind(enum.Enum)
Attributes

CompOp [source]

class CompOp(BinaryOperationBase)

Comparison operation (EQ, NEQ, LT, LE, GT, GE).

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

CompOpKind [source]

class CompOpKind(enum.Enum)
Attributes

CondOp [source]

class CondOp(BinaryOperationBase)

Conditional logical operation (AND, OR).

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

CondOpKind [source]

class CondOpKind(enum.Enum)
Attributes

Handle [source]

class Handle(abc.ABC)
Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None
Attributes
Methods
consume
def consume(self, operation_name: str = 'unknown') -> Self

Mark this handle as consumed and return a fresh handle.

Parameters:

NameTypeDescription
operation_namestrName of the operation consuming this handle, used for error messages.

Returns:

typing.Self — A new handle pointing to the same underlying value.

Raises:


NotOp [source]

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

QubitConsumedError [source]

class QubitConsumedError(AffineTypeError)

Qubit handle used after being consumed by a previous operation.

Each qubit handle can only be used once. After a gate operation, you must reassign the result to use the new handle.

Example of incorrect code:

q1 = qm.h(q) q2 = qm.x(q) # ERROR: q was already consumed by h()

Correct code:

q = qm.h(q) # Reassign to capture new handle q = qm.x(q) # Use the reassigned handle


UInt [source]

class UInt(ArithmeticMixin, Handle)

Unsigned integer handle with arithmetic operations.

Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: int = 0,
) -> None
Attributes

Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


qamomile.circuit.frontend.handle.primitives

Overview

ClassDescription
ArithmeticMixinMixin providing arithmetic operations for numeric Handle types.
BinOpKind
Bit
BitTypeType representing a classical bit.
CompOpKind
CondOpKind
FloatFloating-point handle with arithmetic operations.
FloatTypeType representing a floating-point number.
Handle
QFixed
Qubit
QubitTypeType representing a quantum bit (qubit).
UIntUnsigned integer handle with arithmetic operations.
UIntTypeType representing an unsigned integer.
ValueA typed SSA value in the IR.

Classes

ArithmeticMixin [source]

class ArithmeticMixin

Mixin providing arithmetic operations for numeric Handle types.

Requires:

Attributes

BinOpKind [source]

class BinOpKind(enum.Enum)
Attributes

Bit [source]

class Bit(Handle)
Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: bool = False,
) -> None
Attributes

BitType [source]

class BitType(ClassicalTypeMixin, ValueType)

Type representing a classical bit.


CompOpKind [source]

class CompOpKind(enum.Enum)
Attributes

CondOpKind [source]

class CondOpKind(enum.Enum)
Attributes

Float [source]

class Float(ArithmeticMixin, Handle)

Floating-point handle with arithmetic operations.

Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: float = 0.0,
) -> None
Attributes

FloatType [source]

class FloatType(ClassicalTypeMixin, ValueType)

Type representing a floating-point number.


Handle [source]

class Handle(abc.ABC)
Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None
Attributes
Methods
consume
def consume(self, operation_name: str = 'unknown') -> Self

Mark this handle as consumed and return a fresh handle.

Parameters:

NameTypeDescription
operation_namestrName of the operation consuming this handle, used for error messages.

Returns:

typing.Self — A new handle pointing to the same underlying value.

Raises:


QFixed [source]

class QFixed(Handle)
Constructor
def __init__(
    self,
    value: Value[QFixedType],
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None
Attributes

Qubit [source]

class Qubit(Handle)
Constructor
def __init__(
    self,
    value: Value[QubitType],
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None
Attributes

QubitType [source]

class QubitType(QuantumTypeMixin, ValueType)

Type representing a quantum bit (qubit).


UInt [source]

class UInt(ArithmeticMixin, Handle)

Unsigned integer handle with arithmetic operations.

Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: int = 0,
) -> None
Attributes

UIntType [source]

class UIntType(ClassicalTypeMixin, ValueType)

Type representing an unsigned integer.


Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


qamomile.circuit.frontend.handle.utils

Utility helpers for handle types.

Overview

FunctionDescription
get_sizeReturn the size of a Vector handle as a Python integer.
ClassDescription
Handle
Vector1-dimensional array type.

Functions

get_size [source]

def get_size(arr: Vector[_H]) -> int

Return the size of a Vector handle as a Python integer.

Resolves the leading axis of arr.shape through two forms a Vector shape entry can take:

  1. A plain Python int (built-in bound shape; this is what you get from qmc.qubit_array(N, ...) for literal N).

  2. A UInt handle whose underlying Value carries a compile-time constant (set by uint(literal), _create_bound_input, or partial evaluation).

A UInt handle whose underlying Value is not a constant is treated as an unresolved symbolic dimension and raises ValueError even when the handle has the dataclass-default init_value=0. Falling back to init_value for that case would silently turn a runtime-symbolic Vector[Float] parameter into a “size 0” array, hiding programming errors. Callers that need to handle symbolic shapes (e.g., to gracefully no-op when the size is unknown) must catch the ValueError themselves.

Parameters:

NameTypeDescription
arrVector[Handle]Vector handle whose first axis size is requested.

Returns:

int — The first-axis size as a plain Python int.

Raises:

Classes

Handle [source]

class Handle(abc.ABC)
Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None
Attributes
Methods
consume
def consume(self, operation_name: str = 'unknown') -> Self

Mark this handle as consumed and return a fresh handle.

Parameters:

NameTypeDescription
operation_namestrName of the operation consuming this handle, used for error messages.

Returns:

typing.Self — A new handle pointing to the same underlying value.

Raises:


Vector [source]

class Vector(ArrayBase[T])

1-dimensional array type.

Example:

import qamomile.circuit as qmc

# Create a vector of 3 qubits
qubits: qmc.Vector[qmc.Qubit] = qmc.qubit_array(3, name="qubits")

# Access elements
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0

# Apply H gate to all qubits (CORRECT)
n = qubits.shape[0]
for i in qmc.range(n):
    qubits[i] = qmc.h(qubits[i])
Constructor
def __init__(
    self,
    value: ArrayValue = None,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _shape: tuple[int | UInt] = (0,),
    _borrowed_indices: dict[tuple[str, ...], tuple[UInt, ...]] = dict(),
) -> None
Attributes

qamomile.circuit.frontend.operation


qamomile.circuit.frontend.operation.cast

Cast operation for type conversions over the same quantum resources.

Overview

FunctionDescription
castCast a quantum value to a different type without allocating new qubits.
get_current_tracer
ClassDescription
CastOperationType cast operation for creating aliases over the same quantum resources.
QFixed
QFixedTypeQuantum fixed-point type.
Qubit
ValueA typed SSA value in the IR.
Vector1-dimensional array type.

Functions

cast [source]

def cast(source: Vector[Qubit], target_type: type, *, int_bits: int = 0) -> QFixed

Cast a quantum value to a different type without allocating new qubits.

The cast performs a move: the source handle is consumed and cannot be reused after the cast. The returned handle references the same physical qubits.

Parameters:

NameTypeDescription
sourceVector[Qubit]The value to cast (currently supports Vector[Qubit])
target_typetypeThe target type class (currently supports QFixed)
int_bitsintFor QFixed, number of integer bits (default: 0 = all fractional)

Returns:

QFixed — A new handle of the target type referencing the same qubits.

Example:

@qmc.qkernel
def my_circuit():
    phase_register = qmc.qubit_array(5, name="phase")
    # ... apply some operations ...

    # Cast the qubit array to QFixed for measurement
    phase_qfixed = qmc.cast(phase_register, qmc.QFixed, int_bits=0)
    phase_value = qmc.measure(phase_qfixed)
    return phase_value

Raises:


get_current_tracer [source]

def get_current_tracer() -> Tracer

Classes

CastOperation [source]

class CastOperation(Operation)

Type cast operation for creating aliases over the same quantum resources.

This operation does NOT allocate new qubits. It creates a new Value that references the same underlying quantum resources with a different type.

Use cases:

operands: [source_value] - The value being cast results: [cast_result] - The new value with target type (same physical qubits)

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    source_type: ValueType | None = None,
    target_type: ValueType | None = None,
    qubit_mapping: list[str] = list(),
) -> None
Attributes

QFixed [source]

class QFixed(Handle)
Constructor
def __init__(
    self,
    value: Value[QFixedType],
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None
Attributes

QFixedType [source]

class QFixedType(QuantumTypeMixin, ValueType)

Quantum fixed-point type.

Represents a quantum register encoding a fixed-point number with specified integer and fractional bits.

Constructor
def __init__(
    self,
    integer_bits: int | Value[UIntType] = 0,
    fractional_bits: int | Value[UIntType] = 0,
) -> None
Attributes
Methods
label
def label(self) -> str

Qubit [source]

class Qubit(Handle)
Constructor
def __init__(
    self,
    value: Value[QubitType],
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None
Attributes

Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


Vector [source]

class Vector(ArrayBase[T])

1-dimensional array type.

Example:

import qamomile.circuit as qmc

# Create a vector of 3 qubits
qubits: qmc.Vector[qmc.Qubit] = qmc.qubit_array(3, name="qubits")

# Access elements
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0

# Apply H gate to all qubits (CORRECT)
n = qubits.shape[0]
for i in qmc.range(n):
    qubits[i] = qmc.h(qubits[i])
Constructor
def __init__(
    self,
    value: ArrayValue = None,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _shape: tuple[int | UInt] = (0,),
    _borrowed_indices: dict[tuple[str, ...], tuple[UInt, ...]] = dict(),
) -> None
Attributes

qamomile.circuit.frontend.operation.control_flow

Overview

FunctionDescription
emit_ifBuilder function for if-else conditional with Phi function merging.
for_itemsBuilder function to create a for-items loop in Qamomile frontend.
for_loopBuilder function to create a for loop in Qamomile frontend.
get_current_tracer
is_array_typeCheck if type is a Vector, Matrix, or Tensor subclass.
itemsIterate over dictionary key-value pairs.
rangeSymbolic range for use in qkernel for-loops.
traceContext manager to set the current tracer.
while_loopCreate a while loop whose condition is a measurement result.
ClassDescription
ArrayBaseBase class for array types (Vector, Matrix, Tensor).
ArrayValueAn array of typed IR values.
Bit
BitTypeType representing a classical bit.
DictDict handle for qkernel functions.
DictItemsIteratorIterator for Dict.items() that yields (key, value) pairs.
FloatFloating-point handle with arithmetic operations.
FloatTypeType representing a floating-point number.
ForItemsOperationRepresents iteration over dict/iterable items.
ForOperationRepresents a for loop operation.
IfOperationRepresents an if-else conditional operation.
PhiOpSSA Phi function: merge point after conditional branch.
Qubit
Tracer
UIntUnsigned integer handle with arithmetic operations.
UIntTypeType representing an unsigned integer.
ValueA typed SSA value in the IR.
Vector1-dimensional array type.
WhileLoop
WhileOperationRepresents a while loop operation.

Functions

emit_if [source]

def emit_if(
    cond_func: Callable,
    true_func: Callable,
    false_func: Callable,
    variables: list,
) -> Any

Builder function for if-else conditional with Phi function merging.

This function is called from AST-transformed code. The AST transformer converts: if condition: true_body else: false_body

Into:

def _cond_N(vars): return condition def _body_N(vars): true_body; return vars def _body_N+1(vars): false_body; return vars result = emit_if(_cond_N, _body_N, _body_N+1, [var_list])

Parameters:

NameTypeDescription
cond_functyping.CallableFunction returning the condition (Bit or bool-like Handle)
true_functyping.CallableFunction executing true branch, returns updated variables
false_functyping.CallableFunction executing false branch, returns updated variables
variableslistList of variables used in the branches

Returns:

typing.Any — Merged variable values after conditional execution (using Phi functions)

Example:

@qkernel
def my_kernel(q: Qubit) -> Qubit:
    result = measure(q)
    if result:
        q = z(q)
    return q

for_items [source]

def for_items(
    d: Dict,
    key_var_names: list[str],
    value_var_name: str,
) -> Generator[tuple[Any, Any], None, None]

Builder function to create a for-items loop in Qamomile frontend.

This context manager creates a ForItemsOperation that iterates over dictionary (key, value) pairs. The operation is always unrolled at transpile time since quantum backends cannot natively iterate over classical data structures.

Parameters:

NameTypeDescription
dDictDict handle to iterate over
key_var_nameslist[str]Names of key unpacking variables (e.g., [“i”, “j”] for tuple keys)
value_var_namestrName of value variable (e.g., “Jij”)

Yields:

tuple[typing.Any, typing.Any] — Tuple of (key_handles, value_handle) for use in loop body

Example:

@qkernel
def ising_cost(
    q: Vector[Qubit],
    ising: Dict[Tuple[UInt, UInt], Float],
    gamma: Float,
) -> Vector[Qubit]:
    for (i, j), Jij in qmc.items(ising):
        q[i], q[j] = qmc.rzz(q[i], q[j], gamma * Jij)
    return q

for_loop [source]

def for_loop(
    start,
    stop,
    step = 1,
    var_name: str = '_loop_idx',
) -> Generator[UInt, None, None]

Builder function to create a for loop in Qamomile frontend.

Parameters:

NameTypeDescription
start``Loop start value (can be Handle or int)
stop``Loop stop value (can be Handle or int)
step``Loop step value (default=1)
var_namestrName of the loop variable (default=“_loop_idx”)

Yields:

UInt — The loop iteration variable (can be used as array index)

Example:

@QKernel
def my_kernel(qubits: Array[Qubit, Literal[3]]) -> Array[Qubit, Literal[3]]:
    for i in qm.range(3):
        qubits[i] = h(qubits[i])
    return qubits

@QKernel
def my_kernel2(qubits: Array[Qubit, Literal[5]]) -> Array[Qubit, Literal[5]]:
    for i in qm.range(1, 4):  # i = 1, 2, 3
        qubits[i] = h(qubits[i])
    return qubits

get_current_tracer [source]

def get_current_tracer() -> Tracer

is_array_type [source]

def is_array_type(t: Any) -> bool

Check if type is a Vector, Matrix, or Tensor subclass.


items [source]

def items(d: Dict) -> DictItemsIterator

Iterate over dictionary key-value pairs.

This function returns an iterator over (key, value) pairs from a Dict. Used for iterating over Ising coefficients and similar data structures.

Example:

for (i, j), Jij in qmc.items(ising):
    q[i], q[j] = qmc.rzz(q[i], q[j], gamma * Jij)

Parameters:

NameTypeDescription
dDictA Dict handle to iterate over

Returns:

DictItemsIterator — DictItemsIterator yielding (key, value) pairs


range [source]

def range(
    stop_or_start: int | UInt,
    stop: int | UInt | None = None,
    step: int | UInt = 1,
) -> Iterator[UInt]

Symbolic range for use in qkernel for-loops.

This function accepts UInt (symbolic) values and is transformed by the AST transformer into for_loop() calls.

Example:

for i in qmc.range(n):          # 0 to n-1
for i in qmc.range(start, stop):  # start to stop-1
for i in qmc.range(start, stop, step):

trace [source]

def trace(tracer: Tracer | None = None) -> Generator[Tracer, None, None]

Context manager to set the current tracer.


while_loop [source]

def while_loop(cond: Callable) -> Generator[WhileLoop, None, None]

Create a while loop whose condition is a measurement result.

The condition must be a Bit produced by qmc.measure(). Non-measurement conditions (classical variables, constants, comparisons) are accepted at build time but will be rejected by ValidateWhileContractPass during transpilation.

Parameters:

NameTypeDescription
condtyping.CallableA callable (lambda) that returns the loop condition. Must return a Bit handle originating from qmc.measure().

Yields:

WhileLoop — A marker object for the while loop context.

Example::

@qm.qkernel
def repeat_until_zero() -> qm.Bit:
    q = qm.qubit("q")
    q = qm.h(q)
    bit = qm.measure(q)
    while bit:
        q = qm.qubit("q2")
        q = qm.h(q)
        bit = qm.measure(q)
    return bit

Classes

ArrayBase [source]

class ArrayBase(Handle, Generic[T])

Base class for array types (Vector, Matrix, Tensor).

Provides common functionality for array indexing and element access.

Constructor
def __init__(
    self,
    value: ArrayValue,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _shape: tuple[int | UInt, ...] = tuple(),
    _borrowed_indices: dict[tuple[str, ...], tuple[UInt, ...]] = dict(),
) -> None
Attributes
Methods
consume
def consume(self, operation_name: str = 'unknown') -> Self

Consume the array, enforcing borrow-return contract for quantum arrays.

For quantum arrays, all borrowed elements must be returned before the array can be consumed. This ensures that no unreturned borrows are silently discarded by operations like qkernel calls or controlled gates.

create
@classmethod
def create(
    cls,
    shape: tuple[int | UInt, ...],
    name: str,
    el_type: Type[T],
) -> 'ArrayBase[T]'

Create an ArrayValue for the given shape and name.

validate_all_returned
def validate_all_returned(self) -> None

Validate all borrowed elements have been returned.

This method is useful for ensuring that all borrowed elements have been properly written back before using the array in operations that require the entire array.

Raises:


ArrayValue [source]

class ArrayValue(Value[T])

An array of typed IR values.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
    shape: tuple[Value, ...] = tuple(),
) -> None
Attributes
Methods
next_version
def next_version(self) -> ArrayValue[T]

Bit [source]

class Bit(Handle)
Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: bool = False,
) -> None
Attributes

BitType [source]

class BitType(ClassicalTypeMixin, ValueType)

Type representing a classical bit.


Dict [source]

class Dict(Handle, Generic[K, V])

Dict handle for qkernel functions.

Represents a dictionary mapping keys to values, commonly used for Ising coefficients like {(i, j): Jij}.

Example:

@qmc.qkernel
def ising_cost(
    q: qmc.Vector[qmc.Qubit],
    ising: qmc.Dict[qmc.Tuple[qmc.UInt, qmc.UInt], qmc.Float],
    gamma: qmc.Float,
) -> qmc.Vector[qmc.Qubit]:
    for (i, j), Jij in qmc.items(ising):
        q[i], q[j] = qmc.rzz(q[i], q[j], gamma * Jij)
    return q
Constructor
def __init__(
    self,
    value: DictValue,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _entries: list[tuple[Handle, Handle]] = list(),
    _size: UInt | None = None,
    _key_type: type | None = None,
) -> None
Attributes
Methods
items
def items(self) -> DictItemsIterator[K, V]

Return an iterator over (key, value) pairs.


DictItemsIterator [source]

class DictItemsIterator(Generic[K, V])

Iterator for Dict.items() that yields (key, value) pairs.

This is used internally for iterating over Dict entries in qkernel.

Constructor
def __init__(self, dict_handle: 'Dict[K, V]', _index: int = 0) -> None
Attributes

Float [source]

class Float(ArithmeticMixin, Handle)

Floating-point handle with arithmetic operations.

Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: float = 0.0,
) -> None
Attributes

FloatType [source]

class FloatType(ClassicalTypeMixin, ValueType)

Type representing a floating-point number.


ForItemsOperation [source]

class ForItemsOperation(HasNestedOps, Operation)

Represents iteration over dict/iterable items.

Example:

for (i, j), Jij in qmc.items(ising):
    body
Constructor
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(),
) -> None
Attributes
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]]) -> Operation
replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

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

IfOperation [source]

class IfOperation(HasNestedOps, Operation)

Represents an if-else conditional operation.

Example:

if condition:
    true_body
else:
    false_body
Constructor
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(),
) -> None
Attributes
Methods
nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]
rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation

PhiOp [source]

class PhiOp(Operation)

SSA Phi function: merge point after conditional branch.

This operation selects one of two values based on a condition. Used to merge values from different branches of an if-else statement.

Example:

if condition:
    x = x + 1  # true_value
else:
    x = x + 2  # false_value
# x is now PhiOp(condition, true_value, false_value)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes

Qubit [source]

class Qubit(Handle)
Constructor
def __init__(
    self,
    value: Value[QubitType],
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None
Attributes

Tracer [source]

class Tracer
Constructor
def __init__(self, _operations: list[Operation] = list()) -> None
Attributes
Methods
add_operation
def add_operation(self, op) -> None

UInt [source]

class UInt(ArithmeticMixin, Handle)

Unsigned integer handle with arithmetic operations.

Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: int = 0,
) -> None
Attributes

UIntType [source]

class UIntType(ClassicalTypeMixin, ValueType)

Type representing an unsigned integer.


Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


Vector [source]

class Vector(ArrayBase[T])

1-dimensional array type.

Example:

import qamomile.circuit as qmc

# Create a vector of 3 qubits
qubits: qmc.Vector[qmc.Qubit] = qmc.qubit_array(3, name="qubits")

# Access elements
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0

# Apply H gate to all qubits (CORRECT)
n = qubits.shape[0]
for i in qmc.range(n):
    qubits[i] = qmc.h(qubits[i])
Constructor
def __init__(
    self,
    value: ArrayValue = None,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _shape: tuple[int | UInt] = (0,),
    _borrowed_indices: dict[tuple[str, ...], tuple[UInt, ...]] = dict(),
) -> None
Attributes

WhileLoop [source]

class WhileLoop

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,
) -> None
Attributes
Methods
nested_op_lists
def nested_op_lists(self) -> list[list[Operation]]
rebuild_nested
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operation

qamomile.circuit.frontend.operation.controlled

Controlled gate operations.

Overview

FunctionDescription
controlledCreate a controlled version of a quantum gate.
get_current_tracer
ClassDescription
ArrayValueAn array of typed IR values.
ConcreteControlledUControlled-U with concrete (int) number of controls.
ControlledGateWrapper for controlled version of a QKernel.
ControlledUOperationBase class for controlled-U operations.
FloatFloating-point handle with arithmetic operations.
FloatTypeType representing a floating-point number.
IndexSpecControlledUControlled-U with explicit target/control index specification.
QKernelDecorator class for Qamomile quantum kernels.
Qubit
QubitAliasErrorSame qubit used multiple times in one operation.
SymbolicControlledUControlled-U with symbolic (Value) number of controls.
UIntUnsigned integer handle with arithmetic operations.
UIntTypeType representing an unsigned integer.
ValueA typed SSA value in the IR.

Functions

controlled [source]

def controlled(
    qkernel: QKernel | Callable[..., Any],
    num_controls: int | UInt = 1,
) -> ControlledGate

Create a controlled version of a quantum gate.

Accepts either a @qmc.qkernel-decorated function or a plain built-in gate callable (qmc.rx, qmc.h, qmc.cp, ...). When given a plain callable, a thin @qkernel wrapper is synthesized automatically by inspecting the callable’s signature, so users no longer need to write a one-line wrapper just to control a primitive gate.

Parameters:

NameTypeDescription
qkernelQKernel | Callable[..., Any]A QKernel defining the gate to control, or a built-in gate callable whose parameters are annotated with Qubit, Float/float, or UInt/int (possibly inside a Union such as Union[Qubit, Vector[Qubit]]).
num_controlsint | UIntNumber of control qubits (default: 1). Can be int (concrete) or UInt (symbolic).

Returns:

ControlledGate — A ControlledGate that can be called with ControlledGate(*controls, *targets, **params).

Raises:

Example:

Built-in gates can be controlled directly, with no wrapper::

    crx = qmc.controlled(qmc.rx)
    ctrl_out, tgt_out = crx(ctrl, target, angle=0.5)

    cch = qmc.controlled(qmc.h, num_controls=2)
    c0, c1, tgt = cch(ctrl0, ctrl1, target)

``@qmc.qkernel`` arguments are still supported for cases that need
custom logic::

    @qmc.qkernel
    def rx_then_h(q: Qubit, theta: float) -> Qubit:
        q = qmc.rx(q, theta)
        q = qmc.h(q)
        return q

    ctrl_out, tgt_out = qmc.controlled(rx_then_h)(ctrl, target, theta=0.5)

get_current_tracer [source]

def get_current_tracer() -> Tracer

Classes

ArrayValue [source]

class ArrayValue(Value[T])

An array of typed IR values.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
    shape: tuple[Value, ...] = tuple(),
) -> None
Attributes
Methods
next_version
def next_version(self) -> ArrayValue[T]

ConcreteControlledU [source]

class ConcreteControlledU(ControlledUOperation)

Controlled-U with concrete (int) number of controls.

Operand layout: [ctrl_0, ..., ctrl_n, tgt_0, ..., tgt_m, params...] Result layout: [ctrl_0', ..., ctrl_n', tgt_0', ..., tgt_m']

Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    power: int | Value = 1,
    block: Block | None = None,
    num_controls: int = 1,
) -> None
Attributes

ControlledGate [source]

class ControlledGate

Wrapper for controlled version of a QKernel.

Created by calling controlled(qkernel). The resulting object can be called like a gate function.

Example:

@qmc.qkernel
def phase_gate(q: Qubit, theta: float) -> Qubit:
    return qmc.p(q, theta)

controlled_phase = qmc.controlled(phase_gate)
ctrl_out, tgt_out = controlled_phase(ctrl, target, theta=0.5)

# Double-controlled
cc_phase = qmc.controlled(phase_gate, num_controls=2)
c0, c1, tgt = cc_phase(ctrl0, ctrl1, target, theta=0.5)
Constructor
def __init__(self, qkernel: 'QKernel', num_controls: int | UInt = 1) -> None

ControlledUOperation [source]

class ControlledUOperation(Operation)

Base class for controlled-U operations.

Three 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,
) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]
replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

Float [source]

class Float(ArithmeticMixin, Handle)

Floating-point handle with arithmetic operations.

Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: float = 0.0,
) -> None
Attributes

FloatType [source]

class FloatType(ClassicalTypeMixin, ValueType)

Type representing a floating-point number.


IndexSpecControlledU [source]

class IndexSpecControlledU(ControlledUOperation)

Controlled-U with explicit target/control index specification.

A single vector covers both controls and targets; the partition is determined by target_indices or controlled_indices.

Operand layout: [vector, params...] Result layout: [vector']

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,
    target_indices: list[Value] | None = None,
    controlled_indices: list[Value] | None = None,
) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]
replace_values
def replace_values(self, mapping: dict[str, ValueBase]) -> Operation

QKernel [source]

class QKernel(Generic[P, R])

Decorator class for Qamomile quantum kernels.

Constructor
def __init__(self, func: Callable[P, R]) -> None
Attributes
Methods
build
def build(self, parameters: list[str] | None = None, **kwargs: Any = {}) -> Block

Build a traced Block by tracing this kernel.

Parameters:

NameTypeDescription
parameterslist[str] | NoneList of argument names to keep as unbound parameters. - None (default): Auto-detect parameters (non-Qubit args without value/default) - []: No parameters (all non-Qubit args must have value/default) - [“name”]: Explicit parameter list Only float, int, UInt, and their arrays are allowed as parameters.
**kwargsAnyConcrete values for non-parameter arguments.

Returns:

Block — The traced block ready for transpilation, estimation, or visualization.

Raises:

Example:

@qm.qkernel
def circuit(q: Qubit, theta: float) -> Qubit:
    q = qm.rx(q, theta)
    return q

# Auto-detect theta as parameter
block = circuit.build()

# Explicit parameter list
block = circuit.build(parameters=["theta"])

# theta bound to concrete value
block = circuit.build(theta=0.5)

# Transpile with binding
transpiler = QiskitTranspiler()
result = transpiler.emit(graph, binding={"theta": 0.5})
draw
def draw(
    self,
    inline: bool = False,
    fold_loops: bool = True,
    expand_composite: bool = False,
    inline_depth: int | None = None,
    **kwargs: Any = {},
) -> Any

Visualize the circuit using Matplotlib.

This method builds the computation graph and creates a static visualization. Parameters are auto-detected: non-Qubit arguments without concrete values are shown as symbolic parameters.

Parameters:

NameTypeDescription
inlineboolIf True, expand CallBlockOperation contents (inlining). If False (default), show CallBlockOperation as boxes.
fold_loopsboolIf True (default), display ForOperation as blocks instead of unrolling. If False, expand loops and show all iterations.
expand_compositeboolIf True, expand CompositeGateOperation (QFT, IQFT, etc.). If False (default), show as boxes. Independent of inline.
inline_depthint | NoneMaximum nesting depth for inline expansion. None means unlimited (default). 0 means no inlining, 1 means top-level only, etc. Only affects CallBlock/ControlledU, not CompositeGate.
**kwargsAnyConcrete values for arguments. Arguments not provided here (and without defaults) will be shown as symbolic parameters.

Returns:

Any — matplotlib.figure.Figure object.

Raises:

Example:

import qamomile.circuit as qm

@qm.qkernel
def inner(q: qm.Qubit) -> qm.Qubit:
    return qm.x(q)

@qm.qkernel
def circuit(q: qm.Qubit, theta: float) -> qm.Qubit:
    q = inner(q)
    q = qm.h(q)
    q = qm.rx(q, theta)
    return q

# Draw with auto-detected symbolic parameter (theta)
fig = circuit.draw()

# Draw with bound parameter
fig = circuit.draw(theta=0.5)

# Draw with blocks as boxes (default)
fig = circuit.draw()

# Draw with blocks expanded (inlined)
fig = circuit.draw(inline=True)

# Draw with loops folded (shown as blocks)
fig = circuit.draw(fold_loops=True)

# Draw with composite gates expanded
fig = circuit.draw(expand_composite=True)
estimate_resources
def estimate_resources(self, *, bindings: dict[str, Any] | None = None) -> ResourceEstimate

Estimate all resources for this kernel’s circuit.

Convenience method that delegates to the module-level estimate_resources function, eliminating the need to access .block directly.

Parameters:

NameTypeDescription
bindingsdict[str, Any] | NoneOptional concrete parameter bindings (scalars and dicts). Dict values trigger |key| cardinality substitution.

Returns:

ResourceEstimate — ResourceEstimate with qubits, gates, and parameters.

Example:

>>> @qm.qkernel
... def bell() -> qm.Vector[qm.Qubit]:
...     q = qm.qubit_array(2)
...     q[0] = qm.h(q[0])
...     q[0], q[1] = qm.cx(q[0], q[1])
...     return q
>>> est = bell.estimate_resources()
>>> print(est.qubits)  # 2

Qubit [source]

class Qubit(Handle)
Constructor
def __init__(
    self,
    value: Value[QubitType],
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
) -> None
Attributes

QubitAliasError [source]

class QubitAliasError(AffineTypeError)

Same qubit used multiple times in one operation.

Operations like cx() require distinct qubits for control and target. Using the same qubit in both positions is physically impossible and indicates a programming error.

Example of incorrect code:

q1, q2 = qm.cx(q, q) # ERROR: same qubit as control and target

Correct code:

q1, q2 = qm.cx(control, target) # Use distinct qubits


SymbolicControlledU [source]

class SymbolicControlledU(ControlledUOperation)

Controlled-U with symbolic (Value) number of controls.

Operand layout: [ctrl_vector, tgt_0, ..., tgt_m, params...] Result layout: [ctrl_vector', tgt_0', ..., tgt_m']

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

UInt [source]

class UInt(ArithmeticMixin, Handle)

Unsigned integer handle with arithmetic operations.

Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: int = 0,
) -> None
Attributes

UIntType [source]

class UIntType(ClassicalTypeMixin, ValueType)

Type representing an unsigned integer.


Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


qamomile.circuit.frontend.operation.expval

Expectation value operation for computing <psi|H|psi>.

This module provides the expval() function for computing the expectation value of a Hamiltonian observable with respect to a quantum state.

Overview

FunctionDescription
expvalCompute the expectation value of an observable on a quantum state.
get_current_tracer
ClassDescription
ArrayValueAn array of typed IR values.
ExpvalOpExpectation value operation.
FloatTypeType representing a floating-point number.
ValueA typed SSA value in the IR.

Functions

expval [source]

def expval(qubits: Vector[Qubit] | tuple[Qubit, ...], hamiltonian: Observable) -> Float

Compute the expectation value of an observable on a quantum state.

This function computes <psi|H|psi> where psi is the quantum state represented by the qubits and H is the Hamiltonian observable.

The quantum state (qubits) is NOT consumed by this operation - the qubits can still be used for further operations after expval.

Parameters:

NameTypeDescription
qubitsVector[Qubit] | tuple[Qubit, ...]The quantum register holding the prepared state. Can be a Vector[Qubit] or a tuple of individual Qubits.
hamiltonianObservableThe Observable parameter representing the Hamiltonian. The actual qamomile.observable.Hamiltonian is provided via bindings.

Returns:

Float — Float containing the expectation value.

Example:

import qamomile.circuit as qm
import qamomile.observable as qm_o

# Build Hamiltonian in Python
H = qm_o.Z(0) * qm_o.Z(1) + 0.5 * (qm_o.X(0) + qm_o.X(1))

@qm.qkernel
def vqe_step(q: qm.Vector[qm.Qubit], H: qm.Observable) -> qm.Float:
    # Ansatz
    q[0] = qm.ry(q[0], theta)
    q[0], q[1] = qm.cx(q[0], q[1])

    # Expectation value -> Float
    return qm.expval(q, H)

# Pass Hamiltonian via bindings
executable = transpiler.transpile(vqe_step, bindings={"H": H})

get_current_tracer [source]

def get_current_tracer() -> Tracer

Classes

ArrayValue [source]

class ArrayValue(Value[T])

An array of typed IR values.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
    shape: tuple[Value, ...] = tuple(),
) -> None
Attributes
Methods
next_version
def next_version(self) -> ArrayValue[T]

ExpvalOp [source]

class ExpvalOp(Operation)

Expectation value operation.

This operation computes the expectation value <psi|H|psi> where psi is the quantum state and H is the Hamiltonian observable.

The operation bridges quantum and classical computation:

Example IR:

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

FloatType [source]

class FloatType(ClassicalTypeMixin, ValueType)

Type representing a floating-point number.


Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


qamomile.circuit.frontend.operation.measurement

Measurement operations for quantum circuits.

Overview

FunctionDescription
get_current_tracer
measureMeasure a qubit or QFixed in the computational basis.
ClassDescription
ArrayValueAn array of typed IR values.
IRMeasureOperation
MeasureQFixedOperationMeasure a quantum fixed-point number.
MeasureVectorOperationMeasure a vector of qubits.
UIntTypeType representing an unsigned integer.
ValueA typed SSA value in the IR.
VectorClass1-dimensional array type.

Functions

get_current_tracer [source]

def get_current_tracer() -> Tracer

measure [source]

def measure(target: Union[Qubit, QFixed, Vector[Qubit]]) -> Union[Bit, Float, Vector[Bit]]

Measure a qubit or QFixed in the computational basis.

Performs a projective measurement in the Z-basis. The quantum resource is consumed by this operation and cannot be used afterwards.

Parameters:

NameTypeDescription
targetUnion[Qubit, QFixed, Vector[Qubit]]The quantum resource to measure. - Qubit: Returns a classical Bit - QFixed: Returns a Float (decoded from measured bits)

Returns:

Union[Bit, Float, Vector[Bit]] — Bit for Qubit input, Float for QFixed input.

Example:

@qkernel
def measure_qubit(q: Qubit) -> Bit:
    q = h(q)
    return measure(q)

@qkernel
def measure_qfixed(qf: QFixed) -> Float:
    # After QPE, qf holds phase bits
    return measure(qf)

Classes

ArrayValue [source]

class ArrayValue(Value[T])

An array of typed IR values.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
    shape: tuple[Value, ...] = tuple(),
) -> None
Attributes
Methods
next_version
def next_version(self) -> ArrayValue[T]

MeasureOperation [source]

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

MeasureQFixedOperation [source]

class MeasureQFixedOperation(Operation)

Measure a quantum fixed-point number.

This operation measures all qubits in a QFixed register and produces a Float result. During transpilation, this is lowered to individual MeasureOperations plus a DecodeQFixedOperation.

operands: [QFixed value (contains qubit_values in params)] results: [Float value]

Encoding:

For QPE phase (int_bits=0): float_value = 0.b0b1b2... = b00.5 + b10.25 + b2*0.125 + ...

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

MeasureVectorOperation [source]

class MeasureVectorOperation(Operation)

Measure a vector of qubits.

Takes a Vector[Qubit] (ArrayValue) and produces a Vector[Bit] (ArrayValue). This operation measures all qubits in the vector as a single operation.

operands: [ArrayValue of qubits] results: [ArrayValue of bits]

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

UIntType [source]

class UIntType(ClassicalTypeMixin, ValueType)

Type representing an unsigned integer.


Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


Vector [source]

class Vector(ArrayBase[T])

1-dimensional array type.

Example:

import qamomile.circuit as qmc

# Create a vector of 3 qubits
qubits: qmc.Vector[qmc.Qubit] = qmc.qubit_array(3, name="qubits")

# Access elements
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0

# Apply H gate to all qubits (CORRECT)
n = qubits.shape[0]
for i in qmc.range(n):
    qubits[i] = qmc.h(qubits[i])
Constructor
def __init__(
    self,
    value: ArrayValue = None,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _shape: tuple[int | UInt] = (0,),
    _borrowed_indices: dict[tuple[str, ...], tuple[UInt, ...]] = dict(),
) -> None
Attributes

qamomile.circuit.frontend.operation.pauli_evolve

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

This module provides the pauli_evolve() function for applying the time evolution operator of a Pauli Hamiltonian to a quantum state.

Overview

FunctionDescription
get_current_tracer
pauli_evolveApply exp(-i * gamma * H) to a qubit register.
ClassDescription
PauliEvolveOpPauli evolution operation: exp(-i * gamma * H).

Functions

get_current_tracer [source]

def get_current_tracer() -> Tracer

pauli_evolve [source]

def pauli_evolve(q: Vector[Qubit], hamiltonian: Observable, gamma: Float) -> Vector[Qubit]

Apply exp(-i * gamma * H) to a qubit register.

Implements Hamiltonian time evolution using the Pauli gadget technique. The actual Hamiltonian is provided via bindings at transpile time.

Each backend can use native implementations:

Parameters:

NameTypeDescription
qVector[Qubit]The quantum register to evolve.
hamiltonianObservableObservable parameter referencing the Hamiltonian. The actual qamomile.observable.Hamiltonian is provided via bindings.
gammaFloatEvolution time / variational parameter.

Returns:

Vector[Qubit] — Vector[Qubit]: The evolved qubit register.

Example:

import qamomile.circuit as qmc
import qamomile.observable as qm_o

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

@qmc.qkernel
def cost_layer(
    q: qmc.Vector[qmc.Qubit],
    H: qmc.Observable,
    gamma: qmc.Float,
) -> qmc.Vector[qmc.Qubit]:
    q = qmc.pauli_evolve(q, H, gamma)
    return q

transpiler = QiskitTranspiler()
exe = transpiler.transpile(cost_layer, bindings={"H": H, "gamma": 0.5})

Classes

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

qamomile.circuit.frontend.operation.qubit_gates

Overview

FunctionDescription
ccxToffoli (CCX) gate: flips target when both controls are |1>.
cpControlled-Phase gate.
cxCNOT (Controlled-X) gate.
czCZ (Controlled-Z) gate.
get_current_tracer
hHadamard gate.
pPhase gate: P(theta)|1> = e^{i*theta}|1>.
rxRotation around X-axis: RX(angle) = exp(-i * angle/2 * X).
ryRotation around Y-axis: RY(angle) = exp(-i * angle/2 * Y).
rzRotation around Z-axis: RZ(angle) = exp(-i * angle/2 * Z).
rzzRZZ gate: exp(-i * angle/2 * Z ⊗ Z).
sS gate (square root of Z).
sdgS-dagger gate (inverse of S gate).
swapSWAP gate: exchanges two qubits.
tT gate (fourth root of Z).
tdgT-dagger gate (inverse of T gate).
xPauli-X gate (NOT gate).
yPauli-Y gate.
zPauli-Z gate.
ClassDescription
FloatTypeType representing a floating-point number.
GateOperationType
IRGateOperationQuantum gate operation.
QubitAliasErrorSame qubit used multiple times in one operation.
ValueA typed SSA value in the IR.
VectorClass1-dimensional array type.

Functions

ccx [source]

def ccx(control1: Qubit, control2: Qubit, target: Qubit) -> tuple[Qubit, Qubit, Qubit]

Toffoli (CCX) gate: flips target when both controls are |1>.

Parameters:

NameTypeDescription
control1QubitFirst control qubit.
control2QubitSecond control qubit.
targetQubitTarget qubit.

Returns:

tuple[Qubit, Qubit, Qubit] — Tuple of (control1_out, control2_out, target_out) after CCX.


cp [source]

def cp(control: Qubit, target: Qubit, theta: float | Float) -> tuple[Qubit, Qubit]

Controlled-Phase gate.


cx [source]

def cx(control: Qubit, target: Qubit) -> tuple[Qubit, Qubit]

CNOT (Controlled-X) gate.


cz [source]

def cz(control: Qubit, target: Qubit) -> tuple[Qubit, Qubit]

CZ (Controlled-Z) gate.


get_current_tracer [source]

def get_current_tracer() -> Tracer

h [source]

def h(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]

Hadamard gate.

Applied to a single Qubit it returns the transformed qubit. Applied to a Vector[Qubit] it broadcasts the gate over every element via a transpile-time loop, equivalent to for i in qmc.range(n): qs[i] = h(qs[i]).

Parameters:

NameTypeDescription
targetUnion[Qubit, Vector[Qubit]]A single Qubit or a Vector[Qubit] to apply H to.

Returns:

Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.

Raises:


p [source]

def p(
    target: Union[Qubit, Vector[Qubit]],
    theta: float | Float,
) -> Union[Qubit, Vector[Qubit]]

Phase gate: P(theta)|1> = e^{i*theta}|1>.

Broadcasts the same theta over every qubit when called with a Vector[Qubit].

Parameters:

NameTypeDescription
targetUnion[Qubit, Vector[Qubit]]A single Qubit or a Vector[Qubit] to apply the phase to.
thetafloat | FloatPhase angle in radians.

Returns:

Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.

Raises:


rx [source]

def rx(
    target: Union[Qubit, Vector[Qubit]],
    angle: float | Float,
) -> Union[Qubit, Vector[Qubit]]

Rotation around X-axis: RX(angle) = exp(-i * angle/2 * X).

Broadcasts the same angle over every qubit when called with a Vector[Qubit].

Parameters:

NameTypeDescription
targetUnion[Qubit, Vector[Qubit]]A single Qubit or a Vector[Qubit].
anglefloat | FloatRotation angle in radians.

Returns:

Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.

Raises:


ry [source]

def ry(
    target: Union[Qubit, Vector[Qubit]],
    angle: float | Float,
) -> Union[Qubit, Vector[Qubit]]

Rotation around Y-axis: RY(angle) = exp(-i * angle/2 * Y).

Broadcasts the same angle over every qubit when called with a Vector[Qubit].

Parameters:

NameTypeDescription
targetUnion[Qubit, Vector[Qubit]]A single Qubit or a Vector[Qubit].
anglefloat | FloatRotation angle in radians.

Returns:

Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.

Raises:


rz [source]

def rz(
    target: Union[Qubit, Vector[Qubit]],
    angle: float | Float,
) -> Union[Qubit, Vector[Qubit]]

Rotation around Z-axis: RZ(angle) = exp(-i * angle/2 * Z).

Broadcasts the same angle over every qubit when called with a Vector[Qubit].

Parameters:

NameTypeDescription
targetUnion[Qubit, Vector[Qubit]]A single Qubit or a Vector[Qubit].
anglefloat | FloatRotation angle in radians.

Returns:

Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.

Raises:


rzz [source]

def rzz(qubit_0: Qubit, qubit_1: Qubit, angle: float | Float) -> tuple[Qubit, Qubit]

RZZ gate: exp(-i * angle/2 * Z ⊗ Z).

The RZZ gate applies a rotation around the ZZ axis on two qubits.

Parameters:

NameTypeDescription
qubit_0QubitFirst qubit.
qubit_1QubitSecond qubit.
anglefloat | FloatRotation angle in radians.

Returns:

tuple[Qubit, Qubit] — Tuple of (qubit_0_out, qubit_1_out) after RZZ.


s [source]

def s(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]

S gate (square root of Z).

Broadcasts over a Vector[Qubit] when applied to one.

Parameters:

NameTypeDescription
targetUnion[Qubit, Vector[Qubit]]A single Qubit or a Vector[Qubit].

Returns:

Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.

Raises:


sdg [source]

def sdg(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]

S-dagger gate (inverse of S gate).

Broadcasts over a Vector[Qubit] when applied to one.

Parameters:

NameTypeDescription
targetUnion[Qubit, Vector[Qubit]]A single Qubit or a Vector[Qubit].

Returns:

Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.

Raises:


swap [source]

def swap(qubit_0: Qubit, qubit_1: Qubit) -> tuple[Qubit, Qubit]

SWAP gate: exchanges two qubits.

The SWAP gate swaps the states of two qubits.

Parameters:

NameTypeDescription
qubit_0QubitFirst qubit.
qubit_1QubitSecond qubit.

Returns:

tuple[Qubit, Qubit] — Tuple of (qubit_0_out, qubit_1_out) after SWAP.


t [source]

def t(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]

T gate (fourth root of Z).

Broadcasts over a Vector[Qubit] when applied to one.

Parameters:

NameTypeDescription
targetUnion[Qubit, Vector[Qubit]]A single Qubit or a Vector[Qubit].

Returns:

Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.

Raises:


tdg [source]

def tdg(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]

T-dagger gate (inverse of T gate).

Broadcasts over a Vector[Qubit] when applied to one.

Parameters:

NameTypeDescription
targetUnion[Qubit, Vector[Qubit]]A single Qubit or a Vector[Qubit].

Returns:

Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.

Raises:


x [source]

def x(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]

Pauli-X gate (NOT gate).

Broadcasts over a Vector[Qubit] when applied to one.

Parameters:

NameTypeDescription
targetUnion[Qubit, Vector[Qubit]]A single Qubit or a Vector[Qubit].

Returns:

Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.

Raises:


y [source]

def y(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]

Pauli-Y gate.

Broadcasts over a Vector[Qubit] when applied to one.

Parameters:

NameTypeDescription
targetUnion[Qubit, Vector[Qubit]]A single Qubit or a Vector[Qubit].

Returns:

Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.

Raises:


z [source]

def z(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]

Pauli-Z gate.

Broadcasts over a Vector[Qubit] when applied to one.

Parameters:

NameTypeDescription
targetUnion[Qubit, Vector[Qubit]]A single Qubit or a Vector[Qubit].

Returns:

Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.

Raises:

Classes

FloatType [source]

class FloatType(ClassicalTypeMixin, ValueType)

Type representing a floating-point number.


GateOperationType [source]

class GateOperationType(enum.Enum)
Attributes

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.


QubitAliasError [source]

class QubitAliasError(AffineTypeError)

Same qubit used multiple times in one operation.

Operations like cx() require distinct qubits for control and target. Using the same qubit in both positions is physically impossible and indicates a programming error.

Example of incorrect code:

q1, q2 = qm.cx(q, q) # ERROR: same qubit as control and target

Correct code:

q1, q2 = qm.cx(control, target) # Use distinct qubits


Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


Vector [source]

class Vector(ArrayBase[T])

1-dimensional array type.

Example:

import qamomile.circuit as qmc

# Create a vector of 3 qubits
qubits: qmc.Vector[qmc.Qubit] = qmc.qubit_array(3, name="qubits")

# Access elements
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0

# Apply H gate to all qubits (CORRECT)
n = qubits.shape[0]
for i in qmc.range(n):
    qubits[i] = qmc.h(qubits[i])
Constructor
def __init__(
    self,
    value: ArrayValue = None,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _shape: tuple[int | UInt] = (0,),
    _borrowed_indices: dict[tuple[str, ...], tuple[UInt, ...]] = dict(),
) -> None
Attributes

qamomile.circuit.frontend.qkernel

Overview

FunctionDescription
bitCreate a Bit handle from a boolean/int literal or declare a named Bit parameter.
collect_quantum_rebind_violationsAnalyze func for forbidden quantum rebind patterns.
create_dummy_inputCreate a dummy input based on parameter type annotation.
float_Create a Float handle from a float literal or declare a named Float parameter.
func_to_blockConvert a function to a hierarchical Block.
get_current_tracer
handle_type_mapMap Handle type to ValueType.
is_array_typeCheck if type is a Vector, Matrix, or Tensor subclass.
is_dict_typeCheck if type is a Dict handle type.
is_tuple_typeCheck if type is a Tuple handle type.
qkernelDecorator to define a Qamomile quantum kernel.
qubit_arrayCreate a new qubit array (vector/matrix/tensor) and emit QInitOperations.
traceContext manager to set the current tracer.
transform_control_flow
uintCreate a UInt handle from an integer literal or declare a named UInt parameter.
ClassDescription
ArrayBaseBase class for array types (Vector, Matrix, Tensor).
ArrayValueAn array of typed IR values.
Bit
BlockUnified block representation for all pipeline stages.
BlockKindClassification of block structure for pipeline stages.
CallBlockOperation
DictDict handle for qkernel functions.
DictValueA dictionary value stored as stable ordered entries.
FloatFloating-point handle with arithmetic operations.
FrontendTransformErrorError during frontend AST-to-builder lowering.
QKernelDecorator class for Qamomile quantum kernels.
ResourceEstimateComprehensive resource estimate for a quantum circuit.
Tracer
UIntUnsigned integer handle with arithmetic operations.
ValueA typed SSA value in the IR.
Vector1-dimensional array type.

Functions

bit [source]

def bit(arg: bool | str | int) -> Bit

Create a Bit handle from a boolean/int literal or declare a named Bit parameter.


collect_quantum_rebind_violations [source]

def collect_quantum_rebind_violations(func: Callable, quantum_param_names: set[str]) -> list[RebindViolation]

Analyze func for forbidden quantum rebind patterns.

Returns a (possibly empty) list of violations. Never raises on analysis failure – returns [] instead.


create_dummy_input [source]

def create_dummy_input(param_type: Any, name: str = 'param', emit_init: bool = True) -> Handle

Create a dummy input based on parameter type annotation.

Parameters:

NameTypeDescription
param_typetyping.AnyThe type annotation for the parameter.
namestrName for the value.
emit_initboolIf True, emit QInitOperation for qubit arrays (default: True). Set to False when creating a nested Block’s internal dummy inputs.

This creates input Handles for function parameters.


float_ [source]

def float_(arg: float | str) -> Float

Create a Float handle from a float literal or declare a named Float parameter.


func_to_block [source]

def func_to_block(func: Callable) -> Block

Convert a function to a hierarchical Block.

Example:

def my_func(a: UInt, b: UInt) -> tuple[UInt]:
    c = a + b
    return (c, )

block = func_to_block(my_func)

get_current_tracer [source]

def get_current_tracer() -> Tracer

handle_type_map [source]

def handle_type_map(handle_type: type[Handle] | type) -> ValueType

Map Handle type to ValueType.


is_array_type [source]

def is_array_type(t: Any) -> bool

Check if type is a Vector, Matrix, or Tensor subclass.


is_dict_type [source]

def is_dict_type(t: Any) -> bool

Check if type is a Dict handle type.


is_tuple_type [source]

def is_tuple_type(t: Any) -> bool

Check if type is a Tuple handle type.


qkernel [source]

def qkernel(func: Callable[P, R]) -> QKernel[P, R]

Decorator to define a Qamomile quantum kernel.

Parameters:

NameTypeDescription
funcCallable[P, R]The function to decorate.

Returns:

QKernel[P, R] — An instance of QKernel wrapping the function.


qubit_array [source]

def qubit_array(
    shape: UInt | int | tuple[UInt | int, ...],
    name: str,
) -> Vector[Qubit] | Matrix[Qubit] | Tensor[Qubit]

Create a new qubit array (vector/matrix/tensor) and emit QInitOperations.


trace [source]

def trace(tracer: Tracer | None = None) -> Generator[Tracer, None, None]

Context manager to set the current tracer.


transform_control_flow [source]

def transform_control_flow(func: Callable)

uint [source]

def uint(arg: int | str) -> UInt

Create a UInt handle from an integer literal or declare a named UInt parameter.

Classes

ArrayBase [source]

class ArrayBase(Handle, Generic[T])

Base class for array types (Vector, Matrix, Tensor).

Provides common functionality for array indexing and element access.

Constructor
def __init__(
    self,
    value: ArrayValue,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _shape: tuple[int | UInt, ...] = tuple(),
    _borrowed_indices: dict[tuple[str, ...], tuple[UInt, ...]] = dict(),
) -> None
Attributes
Methods
consume
def consume(self, operation_name: str = 'unknown') -> Self

Consume the array, enforcing borrow-return contract for quantum arrays.

For quantum arrays, all borrowed elements must be returned before the array can be consumed. This ensures that no unreturned borrows are silently discarded by operations like qkernel calls or controlled gates.

create
@classmethod
def create(
    cls,
    shape: tuple[int | UInt, ...],
    name: str,
    el_type: Type[T],
) -> 'ArrayBase[T]'

Create an ArrayValue for the given shape and name.

validate_all_returned
def validate_all_returned(self) -> None

Validate all borrowed elements have been returned.

This method is useful for ensuring that all borrowed elements have been properly written back before using the array in operations that require the entire array.

Raises:


ArrayValue [source]

class ArrayValue(Value[T])

An array of typed IR values.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
    shape: tuple[Value, ...] = tuple(),
) -> None
Attributes
Methods
next_version
def next_version(self) -> ArrayValue[T]

Bit [source]

class Bit(Handle)
Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: bool = False,
) -> None
Attributes

Block [source]

class Block

Unified block representation for all pipeline stages.

Replaces the older traced and callable IR wrappers with a single structure. The kind field indicates which pipeline stage this block is at.

Constructor
def __init__(
    self,
    name: str = '',
    label_args: list[str] = list(),
    input_values: list[Value] = list(),
    output_values: list[Value] = list(),
    output_names: list[str] = list(),
    operations: list['Operation'] = list(),
    kind: BlockKind = BlockKind.HIERARCHICAL,
    parameters: dict[str, Value] = dict(),
) -> None
Attributes
Methods
call
def call(self, **kwargs: Value = {}) -> 'CallBlockOperation'

Create a CallBlockOperation against this block.

is_affine
def is_affine(self) -> bool

Check if block contains no CallBlockOperations.

unbound_parameters
def unbound_parameters(self) -> list[str]

Return list of unbound parameter names.


BlockKind [source]

class BlockKind(Enum)

Classification of block structure for pipeline stages.

Attributes

CallBlockOperation [source]

class CallBlockOperation(Operation)
Constructor
def __init__(
    self,
    operands: list[Value] = list(),
    results: list[Value] = list(),
    block: Block | None = None,
) -> None
Attributes
Methods
is_self_reference_to
def is_self_reference_to(self, block: Block) -> bool

Return True if this call points to the given block (self-ref).


Dict [source]

class Dict(Handle, Generic[K, V])

Dict handle for qkernel functions.

Represents a dictionary mapping keys to values, commonly used for Ising coefficients like {(i, j): Jij}.

Example:

@qmc.qkernel
def ising_cost(
    q: qmc.Vector[qmc.Qubit],
    ising: qmc.Dict[qmc.Tuple[qmc.UInt, qmc.UInt], qmc.Float],
    gamma: qmc.Float,
) -> qmc.Vector[qmc.Qubit]:
    for (i, j), Jij in qmc.items(ising):
        q[i], q[j] = qmc.rzz(q[i], q[j], gamma * Jij)
    return q
Constructor
def __init__(
    self,
    value: DictValue,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _entries: list[tuple[Handle, Handle]] = list(),
    _size: UInt | None = None,
    _key_type: type | None = None,
) -> None
Attributes
Methods
items
def items(self) -> DictItemsIterator[K, V]

Return an iterator over (key, value) pairs.


DictValue [source]

class DictValue(_MetadataValueMixin)

A dictionary value stored as stable ordered entries.

Constructor
def __init__(
    self,
    name: str,
    entries: tuple[tuple[TupleValue | Value, Value], ...] = tuple(),
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> None
Attributes
Methods
is_constant
def is_constant(self) -> bool
next_version
def next_version(self) -> DictValue

Float [source]

class Float(ArithmeticMixin, Handle)

Floating-point handle with arithmetic operations.

Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: float = 0.0,
) -> None
Attributes

FrontendTransformError [source]

class FrontendTransformError(QamomileCompileError)

Error during frontend AST-to-builder lowering.


QKernel [source]

class QKernel(Generic[P, R])

Decorator class for Qamomile quantum kernels.

Constructor
def __init__(self, func: Callable[P, R]) -> None
Attributes
Methods
build
def build(self, parameters: list[str] | None = None, **kwargs: Any = {}) -> Block

Build a traced Block by tracing this kernel.

Parameters:

NameTypeDescription
parameterslist[str] | NoneList of argument names to keep as unbound parameters. - None (default): Auto-detect parameters (non-Qubit args without value/default) - []: No parameters (all non-Qubit args must have value/default) - [“name”]: Explicit parameter list Only float, int, UInt, and their arrays are allowed as parameters.
**kwargsAnyConcrete values for non-parameter arguments.

Returns:

Block — The traced block ready for transpilation, estimation, or visualization.

Raises:

Example:

@qm.qkernel
def circuit(q: Qubit, theta: float) -> Qubit:
    q = qm.rx(q, theta)
    return q

# Auto-detect theta as parameter
block = circuit.build()

# Explicit parameter list
block = circuit.build(parameters=["theta"])

# theta bound to concrete value
block = circuit.build(theta=0.5)

# Transpile with binding
transpiler = QiskitTranspiler()
result = transpiler.emit(graph, binding={"theta": 0.5})
draw
def draw(
    self,
    inline: bool = False,
    fold_loops: bool = True,
    expand_composite: bool = False,
    inline_depth: int | None = None,
    **kwargs: Any = {},
) -> Any

Visualize the circuit using Matplotlib.

This method builds the computation graph and creates a static visualization. Parameters are auto-detected: non-Qubit arguments without concrete values are shown as symbolic parameters.

Parameters:

NameTypeDescription
inlineboolIf True, expand CallBlockOperation contents (inlining). If False (default), show CallBlockOperation as boxes.
fold_loopsboolIf True (default), display ForOperation as blocks instead of unrolling. If False, expand loops and show all iterations.
expand_compositeboolIf True, expand CompositeGateOperation (QFT, IQFT, etc.). If False (default), show as boxes. Independent of inline.
inline_depthint | NoneMaximum nesting depth for inline expansion. None means unlimited (default). 0 means no inlining, 1 means top-level only, etc. Only affects CallBlock/ControlledU, not CompositeGate.
**kwargsAnyConcrete values for arguments. Arguments not provided here (and without defaults) will be shown as symbolic parameters.

Returns:

Any — matplotlib.figure.Figure object.

Raises:

Example:

import qamomile.circuit as qm

@qm.qkernel
def inner(q: qm.Qubit) -> qm.Qubit:
    return qm.x(q)

@qm.qkernel
def circuit(q: qm.Qubit, theta: float) -> qm.Qubit:
    q = inner(q)
    q = qm.h(q)
    q = qm.rx(q, theta)
    return q

# Draw with auto-detected symbolic parameter (theta)
fig = circuit.draw()

# Draw with bound parameter
fig = circuit.draw(theta=0.5)

# Draw with blocks as boxes (default)
fig = circuit.draw()

# Draw with blocks expanded (inlined)
fig = circuit.draw(inline=True)

# Draw with loops folded (shown as blocks)
fig = circuit.draw(fold_loops=True)

# Draw with composite gates expanded
fig = circuit.draw(expand_composite=True)
estimate_resources
def estimate_resources(self, *, bindings: dict[str, Any] | None = None) -> ResourceEstimate

Estimate all resources for this kernel’s circuit.

Convenience method that delegates to the module-level estimate_resources function, eliminating the need to access .block directly.

Parameters:

NameTypeDescription
bindingsdict[str, Any] | NoneOptional concrete parameter bindings (scalars and dicts). Dict values trigger |key| cardinality substitution.

Returns:

ResourceEstimate — ResourceEstimate with qubits, gates, and parameters.

Example:

>>> @qm.qkernel
... def bell() -> qm.Vector[qm.Qubit]:
...     q = qm.qubit_array(2)
...     q[0] = qm.h(q[0])
...     q[0], q[1] = qm.cx(q[0], q[1])
...     return q
>>> est = bell.estimate_resources()
>>> print(est.qubits)  # 2

ResourceEstimate [source]

class ResourceEstimate

Comprehensive resource estimate for a quantum circuit.

All metrics are SymPy expressions that may contain symbols for parametric problem sizes.

Constructor
def __init__(
    self,
    qubits: sp.Expr,
    gates: GateCount,
    parameters: dict[str, sp.Symbol] = dict(),
) -> None
Attributes
Methods
simplify
def simplify(self) -> ResourceEstimate

Simplify all SymPy expressions.

Returns:

ResourceEstimate — New ResourceEstimate with simplified expressions

substitute
def substitute(self, **values: int | float = {}) -> ResourceEstimate

Substitute concrete values for parameters.

Parameters:

NameTypeDescription
**valuesint | floatParameter name -> concrete value mappings

Returns:

ResourceEstimate — New ResourceEstimate with substituted values

Example:

>>> est = estimate_resources(circuit)
>>> concrete = est.substitute(n=100, p=3)
>>> print(concrete.qubits)  # 100 (instead of 'n')
to_dict
def to_dict(self) -> dict[str, Any]

Convert to a dictionary for serialization.

Returns:

dict[str, Any] — Dictionary with all metrics as strings (for JSON/YAML export)

Example:

>>> est = estimate_resources(circuit)
>>> data = est.to_dict()
>>> import json
>>> print(json.dumps(data, indent=2))

Tracer [source]

class Tracer
Constructor
def __init__(self, _operations: list[Operation] = list()) -> None
Attributes
Methods
add_operation
def add_operation(self, op) -> None

UInt [source]

class UInt(ArithmeticMixin, Handle)

Unsigned integer handle with arithmetic operations.

Constructor
def __init__(
    self,
    value: Value,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    init_value: int = 0,
) -> None
Attributes

Value [source]

class Value(_MetadataValueMixin, Generic[T])

A typed SSA value in the IR.

The name field is display-only: it labels the value for visualization and error messages and has no role in identity. Identity is carried by uuid (per-version) and logical_id (across versions).

An empty string (name="") is the anonymous marker used by auto-generated tmp values (arithmetic results, comparison results, coerced constants). Name-based readers must guard with truthiness (if value.name and value.name in bindings: ...) so anonymous values never collide on a shared empty key. User-supplied parameter names and array names continue to be non-empty.

Constructor
def __init__(
    self,
    type: T,
    name: str,
    version: int = 0,
    metadata: ValueMetadata = ValueMetadata(),
    uuid: str = (lambda: str(uuid.uuid4()))(),
    logical_id: str = (lambda: str(uuid.uuid4()))(),
    parent_array: ArrayValue | None = None,
    element_indices: tuple[Value, ...] = (),
) -> None
Attributes
Methods
is_array_element
def is_array_element(self) -> bool
next_version
def next_version(self) -> Value[T]

Create a new Value with incremented version and fresh UUID.

Metadata is intentionally preserved across versions so that parameter bindings and constant annotations remain accessible after the value is updated (e.g. by a gate application or a classical operation). The logical_id also stays the same: it identifies the same logical variable across SSA versions, independently of backend resource allocation. This applies to every Value regardless of its type (Qubit, Float, Bit, ...) -- it is not specific to qubits.


Vector [source]

class Vector(ArrayBase[T])

1-dimensional array type.

Example:

import qamomile.circuit as qmc

# Create a vector of 3 qubits
qubits: qmc.Vector[qmc.Qubit] = qmc.qubit_array(3, name="qubits")

# Access elements
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0

# Apply H gate to all qubits (CORRECT)
n = qubits.shape[0]
for i in qmc.range(n):
    qubits[i] = qmc.h(qubits[i])
Constructor
def __init__(
    self,
    value: ArrayValue = None,
    parent: 'ArrayBase | None' = None,
    indices: tuple['UInt', ...] = (),
    name: str | None = None,
    id: str = (lambda: str(uuid.uuid4()))(),
    _consumed: bool = False,
    _consumed_by: str | None = None,
    _shape: tuple[int | UInt] = (0,),
    _borrowed_indices: dict[tuple[str, ...], tuple[UInt, ...]] = dict(),
) -> None
Attributes

qamomile.circuit.frontend.tracer

Overview

FunctionDescription
get_current_tracer
traceContext manager to set the current tracer.
ClassDescription
Operation
Tracer

Functions

get_current_tracer [source]

def get_current_tracer() -> Tracer

trace [source]

def trace(tracer: Tracer | None = None) -> Generator[Tracer, None, None]

Context manager to set the current tracer.

Classes

Operation [source]

class Operation(abc.ABC)
Constructor
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> None
Attributes
Methods
all_input_values
def all_input_values(self) -> list[ValueBase]

Return all input Values including subclass-specific fields.

Generic passes should use this instead of accessing operands directly to ensure no Value is missed. Subclasses override this to include extra Value fields (e.g. ControlledUOperation.power).

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

Return a copy with all Values substituted via mapping.

Handles operands, results, and subclass-specific Value fields. Subclasses override to handle their extra fields.


Tracer [source]

class Tracer
Constructor
def __init__(self, _operations: list[Operation] = list()) -> None
Attributes
Methods
add_operation
def add_operation(self, op) -> None