Public surface for the Qamomile IR package.
Re-exports the contributor-facing debugging and canonical-form
helpers so callers can use the short form
from qamomile.circuit.ir import pretty_print_block or
from qamomile.circuit.ir import canonicalize.
Overview¶
| Function | Description |
|---|---|
canonicalize | Return a canonical-form clone of block. |
canonicalize_and_remap | Return canonical-form Block plus the UUID and logical_id remap tables. |
content_hash | Compute a content-addressable hash of block. |
format_value | Format an IR value reference as %name@vN. |
pretty_print_block | Return a MLIR-style textual dump of block. |
to_canonical_bytes | Serialize block to a deterministic byte representation. |
| Class | Description |
|---|---|
KernelEffect | Describe non-unitary behavior reachable from a kernel body. |
Functions¶
canonicalize [source]¶
def canonicalize(block: Block) -> BlockReturn a canonical-form clone of block.
The returned Block has the same structure as block but with
every Value UUID and logical_id re-issued from a deterministic
counter. All UUID references inside operations and value metadata
are rewritten consistently. Block.kind is preserved.
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | The block to canonicalize. Must be at BlockKind.AFFINE or BlockKind.ANALYZED. |
Returns:
Block — A new Block with canonical UUIDs. Block.kind matches
the input. Existing input/output ordering, operation
ordering, metadata structure, and the param_slots
manifest (carried over verbatim) are preserved.
Raises:
ValueError— Ifblock.kindis not in{AFFINE, ANALYZED}, or if a loop operation’s region arguments violate the SSA identity invariants (see :func:validate_region_args).NotImplementedError— If an unsupported operation is encountered.
Example:
>>> from qamomile.qiskit import QiskitTranspiler
>>> transpiler = QiskitTranspiler()
>>> affine = transpiler.inline(transpiler.to_block(my_kernel))
>>> canon = canonicalize(affine)
>>> canon.kind is affine.kind
Truecanonicalize_and_remap [source]¶
def canonicalize_and_remap(block: Block) -> tuple[Block, dict[str, str], dict[str, str]]Return canonical-form Block plus the UUID and logical_id remap tables.
Useful when the caller holds external references keyed on the original Value UUIDs or logical_ids (e.g., a host-side port map) and needs to update those references to match the canonical form.
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | The block to canonicalize. Must be at BlockKind.AFFINE or BlockKind.ANALYZED. |
Returns:
tuple[Block, dict[str, str], dict[str, str]] — tuple[Block, dict[str, str], dict[str, str]]: A triple
(canonical_block, uuid_remap, logical_id_remap) where
each remap maps every original identifier encountered
during the walk to its canonical counterpart. uuid and
logical_id share the same monotonic counter but are
tracked in separate maps.
Raises:
ValueError— Ifblock.kindis not in{AFFINE, ANALYZED}, or if a loop operation’s region arguments violate the SSA identity invariants (see :func:validate_region_args).NotImplementedError— If an unsupported operation is encountered.
content_hash [source]¶
def content_hash(block: Block) -> strCompute a content-addressable hash of block.
Two Blocks that canonicalize to the same form (structurally equal after UUID remapping) produce the same hash. Any IR-level change (gate added, parameter renamed, operand reordered) produces a different hash.
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | The block to hash. Must be at BlockKind.AFFINE or BlockKind.ANALYZED. |
Returns:
str — The SHA-256 hex digest of to_canonical_bytes(block).
Raises:
ValueError— Ifblock.kindis not in{AFFINE, ANALYZED}.
Example:
>>> h1 = content_hash(canonicalize(affine_a))
>>> h2 = content_hash(canonicalize(affine_b))
>>> # If the two kernels are structurally identical, h1 == h2.format_value [source]¶
def format_value(value: Any) -> strFormat an IR value reference as %name@vN.
Handles Value, ArrayValue, TupleValue, DictValue, and
array-element Values (rendered as %parent[i]@vN). Constants
and parameters are shown with their tagged metadata when available.
Falls back to repr() for unrecognised inputs so callers can use
this helper for any operand-like field without a type switch.
pretty_print_block [source]¶
def pretty_print_block(block: Block, *, depth: int = 0) -> strReturn a MLIR-style textual dump of block.
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | The Block to format. Works on any BlockKind. |
depth | int | How many levels of callable bodies to expand inline. 0 (default) shows only the callable name and I/O. Positive values expand InvokeOperation bodies recursively, decrementing the allowance at each step. Useful for seeing what inline will produce without actually running the pass. |
Returns:
str — A newline-separated string. The format is for human debugging and
str — is not guaranteed to be stable across releases.
to_canonical_bytes [source]¶
def to_canonical_bytes(block: Block) -> bytesSerialize block to a deterministic byte representation.
The byte format is the internal representation backing
content_hash and is not stable across qamomile versions. It is
suitable for hashing and equality checks within a single
deployment but should not be relied upon as a serialization
format. (A stable, versioned serialization format is tracked
separately.)
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | The block to serialize. Must be at BlockKind.AFFINE or BlockKind.ANALYZED. The block is canonicalized first; passing an already-canonical block is harmless. |
Returns:
bytes — A UTF-8-encoded byte string. Two structurally-equal
Blocks produce the same bytes; changing the IR yields
different bytes.
Raises:
ValueError— Ifblock.kindis not in{AFFINE, ANALYZED}.
Classes¶
KernelEffect [source]¶
class KernelEffect(enum.Flag)Describe non-unitary behavior reachable from a kernel body.
KernelEffect.NONE is the empty effect set and denotes unitary behavior.
Flags compose with bitwise union so one kernel can expose measurement,
reset, and measurement-backed feed-forward together.
Attributes¶
FEED_FORWARDMEASUREMENTNONERESETis_unitary: bool Return whether this is the empty effect set.
Methods¶
labels¶
def labels(self) -> tuple[str, ...]Return stable effect names for diagnostics and serialization.
Returns:
tuple[str, ...] — tuple[str, ...]: Active flag names in declaration order.
qamomile.circuit.ir.block¶
Unified block representation for all pipeline stages.
Overview¶
| Function | Description |
|---|---|
collect_value_like_uuids | Collect UUIDs contained in a value-like IR object. |
| Class | Description |
|---|---|
Block | Unified block representation for all pipeline stages. |
BlockKind | Classification of block structure for pipeline stages. |
InvokeOperation | Represent a composite, stdlib, or oracle call. |
KernelEffect | Describe non-unitary behavior reachable from a kernel body. |
ParamSlot | Metadata for a single classical kernel argument. |
StaticBindingSlot | Declare one typed compile-time object required by a qkernel. |
Value | A typed SSA value in the IR. |
Constants¶
ValueLike:TypeAlias='Value | ArrayValue | TupleValue | DictValue'
Functions¶
collect_value_like_uuids [source]¶
def collect_value_like_uuids(value: 'ValueLike') -> set[str]Collect UUIDs contained in a value-like IR object.
Parameters:
| Name | Type | Description |
|---|---|---|
value | ValueLike | Value-like object to inspect. |
Returns:
set[str] — set[str]: UUIDs for value itself, recursively contained tuple/dict
elements, and array view/element dependencies.
Classes¶
Block [source]¶
class BlockUnified 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[ValueLike] = list(),
output_values: list[ValueLike] = list(),
output_names: list[str] = list(),
operations: list['Operation'] = list(),
kind: BlockKind = BlockKind.HIERARCHICAL,
parameters: dict[str, Value] = dict(),
param_slots: tuple[ParamSlot, ...] = tuple(),
static_bindings: tuple[StaticBindingSlot, ...] = tuple(),
) -> NoneAttributes¶
effects: ‘KernelEffect’ Return lazily cached semantic effects for this block.input_values: list[ValueLike]kind: BlockKindlabel_args: list[str]measurement_result_indices: frozenset[int] Return public output positions derived from measurement.name: stroperations: list[‘Operation’]output_names: list[str]output_values: list[ValueLike]param_slots: tuple[ParamSlot, ...]parameters: dict[str, Value]static_bindings: tuple[StaticBindingSlot, ...]
Methods¶
call¶
def call(self, **kwargs: ValueLike = {}) -> 'InvokeOperation'Create an inline callable invocation against this block.
Parameters:
| Name | Type | Description |
|---|---|---|
**kwargs | ValueLike | Actual argument values keyed by self.label_args. |
Returns:
'InvokeOperation' — Inline-policy invocation whose callable
definition points at this block.
Raises:
KeyError— If a required label inself.label_argsis missing fromkwargs.
is_affine¶
def is_affine(self) -> boolReturn whether this block has passed affine validation.
Returns:
bool — True for AFFINE and ANALYZED blocks.
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¶
AFFINEANALYZEDHIERARCHICALTRACED
InvokeOperation [source]¶
class InvokeOperation(Operation)Represent a composite, stdlib, or oracle call.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | list[ValueLike] | Input values consumed by the call. |
results | list[ValueLike] | Output values produced by the call. |
target | CallableRef | Callable identity. |
transform | CallTransform | Direct, inverse, or controlled invocation. |
attrs | dict[str, Any] | Compile-time attributes for strategy, arity, and resource/lowering decisions. control_value is reserved for a controlled invocation’s LSB-first activation value. Values must be serializer-friendly. |
definition | CallableDef | None | Optional callable definition. |
Constructor¶
def __init__(
self,
operands: Sequence[ValueLike] | None = None,
results: Sequence[ValueLike] | None = None,
*,
target: CallableRef | None = None,
transform: CallTransform = CallTransform.DIRECT,
attrs: dict[str, Any] | None = None,
definition: CallableDef | None = None,
) -> NoneInitialize an invocation operation.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | Sequence[ValueLike] | None | Input values consumed by the call. Defaults to None, meaning no operands. |
results | Sequence[ValueLike] | None | Output values produced by the call. Defaults to None, meaning no results. |
target | CallableRef | None | Callable identity. Defaults to an anonymous user callable when omitted. |
transform | CallTransform | Requested call transform. Defaults to CallTransform.DIRECT. |
attrs | dict[str, Any] | None | Serializer-friendly call attributes. Defaults to an empty dict. |
definition | CallableDef | None | Callable definition. Defaults to None, in which case one is created from target. |
Raises:
TypeError— If a controlled invocation’scontrol_valueor an Oracle control-partition field has an invalid Python type.ValueError— Ifcontrol_valueis used on a non-controlled call or does not fit the controlled invocation’s width, or if Oracle invocation and definition control metadata disagree.
Attributes¶
attrs: dict[str, Any]body: Block | None Return the callable’s default body from its definition.body_ref: CallableBodyRef | None Return the callable’s deferred body reference.control_qubits: list[‘Value’] Return the control-qubit operands.control_value: int | None Return the controlled invocation’s activation value.custom_name: str Return the display name for custom callable boxes.default_policy: CallPolicy Return the callable’s default lowering policy.definition: CallableDef | Noneeffects: ‘KernelEffect’ Return cached effects of relevant callable implementations.gate_type: CompositeGateType Return the standard composite classification for this invocation.measurement_result_indices: frozenset[int] Return a conservative union of measurement-derived results.name: str Return the display name for this invocation.num_added_control_qubits: int Return controls introduced by a frontend control transform.num_body_external_control_qubits: int Return control operands generic lowering adds outside a base body.num_control_qubits: int Return the number of leading control-qubit operands.num_declared_control_qubits: int Return controls included in an opaque Oracle’s base definition.num_target_qubits: int Return the number of target-qubit operands.operandsoperation_kind: OperationKind Return the operation kind.parameters: list[‘Value’] Return non-qubit parameter operands.resultssignature: Signature Return the operation signature.strategy_name: str | None Return the selected lowering/resource strategy name.target: CallableReftarget_qubits: list[‘Value’] Return the target-qubit operands.transform: CallTransform
Methods¶
body_for_transform¶
def body_for_transform(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> tuple[Block | None, CallTransform]Select a body and report the transform it already realizes.
A controlled-inverse invocation may reuse an explicitly registered inverse body when no implementation realizes both transforms. Keeping that fallback in the IR operation gives emitters and static analyses one selection rule while still letting each consumer apply the remaining coherent controls in its own representation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None. |
strategy | str | None | Strategy name to match. Defaults to the invocation’s strategy_name attribute. |
Returns:
Block | None — tuple[Block | None, CallTransform]: Selected body and the transform
CallTransform — already implemented by that body. The callable’s direct body is
tuple[Block | None, CallTransform] — returned with DIRECT when no transform-specific body matches.
Raises:
ValueError— If the selected body disagrees with the invocation’s input or output contract.
effective_body¶
def effective_body(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> Block | NoneReturn the implementation body selected for this invocation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None. |
strategy | str | None | Strategy name to match. Defaults to the invocation’s strategy_name attribute. |
Returns:
Block | None — Block | None: Selected implementation body, or the callable’s
Block | None — default body when no transform-specific implementation exists.
Block | None — A compiler may synthesize inverse or controlled behavior from this
Block | None — fallback body.
implementation_for¶
def implementation_for(
self,
*,
backend: str | None = None,
strategy: str | None = None,
require_body: bool = False,
) -> CallableImplementation | NoneReturn the selected implementation for this invocation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None, which only selects backend-generic implementations. |
strategy | str | None | Strategy name to match. Defaults to None, meaning the invocation’s strategy_name attribute is used. |
require_body | bool | Whether candidates without an IR body should be excluded before ranking. Defaults to False. |
Returns:
CallableImplementation | None — CallableImplementation | None: Matching implementation candidate,
CallableImplementation | None — or None when the callable definition has no match.
measurement_result_indices_for¶
def measurement_result_indices_for(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> frozenset[int]Return measurement-derived results for one selected implementation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name used for implementation selection. Defaults to None. |
strategy | str | None | Strategy name used for implementation selection. Defaults to the invocation’s strategy_name. |
Returns:
frozenset[int] — frozenset[int]: Caller-local result positions derived from
measurement in the selected body.
Raises:
ValueError— If the selected body disagrees with the invocation’s input or output contract.
select_body¶
def select_body(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> CallableBodySelectionSelect and validate the composable body for this invocation.
The result carries the transform already realized by the body and the exact call-site values that bind to it. Consumers therefore cannot independently disagree about whether an invocation’s control prefix belongs to the selected implementation ABI.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None. |
strategy | str | None | Strategy name to match. Defaults to the invocation’s strategy_name attribute. |
Returns:
CallableBodySelection — Validated body, realized transform, and
CallableBodySelection — aligned call-site operands and results.
Raises:
ValueError— If the selected body disagrees with the invocation’s input or output contract.
KernelEffect [source]¶
class KernelEffect(enum.Flag)Describe non-unitary behavior reachable from a kernel body.
KernelEffect.NONE is the empty effect set and denotes unitary behavior.
Flags compose with bitwise union so one kernel can expose measurement,
reset, and measurement-backed feed-forward together.
Attributes¶
FEED_FORWARDMEASUREMENTNONERESETis_unitary: bool Return whether this is the empty effect set.
Methods¶
labels¶
def labels(self) -> tuple[str, ...]Return stable effect names for diagnostics and serialization.
Returns:
tuple[str, ...] — tuple[str, ...]: Active flag names in declaration order.
ParamSlot [source]¶
class ParamSlotMetadata for a single classical kernel argument.
A ParamSlot describes one position in the kernel’s classical
parameter contract — its declared type, whether it is a runtime
parameter or a compile-time-bound value, the Python default (if
any), the actually-bound value (when kind is
COMPILE_TIME_BOUND), and any outer-DSL hints. Slots are
immutable; pipeline passes that need to update a slot must clone
via dataclasses.replace.
The slot is identified by name, which matches the kernel’s
Python parameter name and the corresponding entry in
Block.label_args. A slot’s name MUST never overlap between
RUNTIME_PARAMETER and COMPILE_TIME_BOUND instances within
one Block (this mirrors the project-level bindings /
parameters disjointness rule).
Constructor¶
def __init__(
self,
name: str,
type: 'ValueType',
kind: ParamKind,
ndim: int = 0,
default: Any = None,
bound_value: Any = None,
differentiable: bool = False,
) -> NoneAttributes¶
bound_value: Anydefault: Anydifferentiable: boolkind: ParamKindname: strndim: inttype: ‘ValueType’
StaticBindingSlot [source]¶
class StaticBindingSlotDeclare one typed compile-time object required by a qkernel.
The object itself is not an SSA value and never reaches a backend. Only registered scalar projections and deferred callable-member references may appear in the hierarchical body. A build must resolve the slot before the block advances to a compiler stage.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | QKernel argument name used by bindings. |
type_key | str | Stable key of the registered static-binding adapter. |
fields | tuple[StaticBindingField, ...] | Scalar projections referenced while tracing the unbound qkernel. |
Constructor¶
def __init__(
self,
name: str,
type_key: str,
fields: tuple[StaticBindingField, ...] = (),
) -> NoneAttributes¶
fields: tuple[StaticBindingField, ...]name: strtype_key: str
Value [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.ir.canonical¶
Canonical form for IR blocks: deterministic UUIDs and content hashing.
This module provides a normalization pass that re-numbers every Value
UUID (and logical_id) in a Block from a deterministic counter,
rewriting every UUID reference embedded in operations and value
metadata so the resulting Block is structurally invariant across
independent builds of the same kernel.
The canonical form is intended for IR-level equality checks, debugging
diffs, and a content-addressable identity (content_hash) suitable
for caching and (later) for serialization keyed on IR contents rather
than build-local Python state.
Supported scope:
Only BlockKind.AFFINE and BlockKind.ANALYZED are accepted.
HIERARCHICAL Blocks may still contain inline-policy
InvokeOperations that reference nested Blocks before inlining;
canonical treatment for those pre-inline references is deferred (see
backlog [IR design] Add named/versioned module references for cross-process kernel composition).
Output guarantees:
canonicalizedoes not changeBlock.kind; it is a normalization, not a pipeline stage advance.For two builds of the same kernel that produce structurally identical IR,
canonicalizereturns Blocks that are equal underto_canonical_bytes(and therefore undercontent_hash).canonicalizeis idempotent: running it twice on the same Block yields the same canonical bytes as running it once.
Canonical-bytes scope:
Display-only fields (Block.name, Block.output_names,
Value.name) are excluded from to_canonical_bytes;
functional fields are included. Block.label_args (input port
names by position) and Block.param_slots (the kernel’s
classical parameter contract) are both functional: two Blocks
whose operations match but whose parameter manifests differ (e.g.,
a slot rebound from RUNTIME_PARAMETER to
COMPILE_TIME_BOUND) hash differently. param_slots holds no
Value/UUID references, so canonicalize carries the tuple over
verbatim with nothing to remap.
Limitations:
Value.parent_arraycycles (a Value whoseparent_arrayis itself reachable from the Value’s siblings) are not constructed by the frontend today; the canonicalizer assumes the Value-reference graph throughparent_arrayandelement_indicesis acyclic.ValueMetadata.dict_runtime.bound_data,ArrayRuntimeMetadata.const_array, andParamSlot.default/ParamSlot.bound_valuemay carry arbitrary frozen Python data. Every payload type the wire format supports is hashed structurally:numpy.ndarray(except object-dtype arrays) from its raw buffer (dtype + shape + bytes),numpyscalars via their Python value,bytesvia a digest,complexvia its components, andHamiltonianvia its term structure (order-independent, matchingHamiltonian.__eq__plus the declared register width). Only object types outside that set fall back toreprand therefore require a stablereprfor the hash to be reliable.
Overview¶
| Function | Description |
|---|---|
canonicalize | Return a canonical-form clone of block. |
canonicalize_and_remap | Return canonical-form Block plus the UUID and logical_id remap tables. |
collect_reachable_values | Collect values reachable from an IR block in canonical walk order. |
content_fingerprint | Compute a deterministic fingerprint for supported lowered IR content. |
content_hash | Compute a content-addressable hash of block. |
hamiltonian_to_dict | Encode a Hamiltonian into the wrapper dict. |
remap_indexed_identifier | Remap an identifier while preserving a legacy index suffix. |
remap_value_metadata_references | Rewrite UUID and logical-id references inside value metadata. |
to_canonical_bytes | Serialize block to a deterministic byte representation. |
validate_region_args | Validate the SSA identities owned by a loop’s region arguments. |
| Class | Description |
|---|---|
ArrayValue | An array of typed IR values. |
Block | Unified block representation for all pipeline stages. |
BlockKind | Classification of block structure for pipeline stages. |
BranchRebind | Trace-time record of a quantum variable rebound inside an if branch. |
CastOperation | Type cast operation for creating aliases over the same quantum resources. |
ControlledUOperation | Base class for controlled-U operations. |
DictValue | A dictionary value stored as stable ordered entries. |
ForItemsOperation | Represents iteration over dict/iterable items. |
ForOperation | Represents a for loop operation. |
Hamiltonian | Represents a quantum Hamiltonian as a sum of Pauli operator products. |
HasNestedOps | Mixin for operations that contain nested operation lists. |
InverseBlockOperation | Represent an inverse qkernel/block as a first-class IR operation. |
InvokeOperation | Represent a composite, stdlib, or oracle call. |
LoopCarriedRebind | Trace-time record of a variable rebound inside a loop body. |
RegionArg | Explicit loop-carried value on a loop operation (MLIR-style iter_arg). |
SelectOperation | Quantum multiplexer: apply case_blocks[i] when the index reads i. |
StaticBindingField | Reference one scalar field projected from a static binding. |
StaticBindingSlot | Declare one typed compile-time object required by a qkernel. |
TupleValue | A tuple of IR values for structured data. |
Value | A typed SSA value in the IR. |
ValueBase | Nominal base for every typed IR value. |
ValueMetadata | Typed metadata owned by the compiler/runtime. |
ValueType | Base class for all value types in the IR. |
WhileOperation | Represents a while loop operation. |
Constants¶
ValueLike:TypeAlias='Value | ArrayValue | TupleValue | DictValue'
Functions¶
canonicalize [source]¶
def canonicalize(block: Block) -> BlockReturn a canonical-form clone of block.
The returned Block has the same structure as block but with
every Value UUID and logical_id re-issued from a deterministic
counter. All UUID references inside operations and value metadata
are rewritten consistently. Block.kind is preserved.
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | The block to canonicalize. Must be at BlockKind.AFFINE or BlockKind.ANALYZED. |
Returns:
Block — A new Block with canonical UUIDs. Block.kind matches
the input. Existing input/output ordering, operation
ordering, metadata structure, and the param_slots
manifest (carried over verbatim) are preserved.
Raises:
ValueError— Ifblock.kindis not in{AFFINE, ANALYZED}, or if a loop operation’s region arguments violate the SSA identity invariants (see :func:validate_region_args).NotImplementedError— If an unsupported operation is encountered.
Example:
>>> from qamomile.qiskit import QiskitTranspiler
>>> transpiler = QiskitTranspiler()
>>> affine = transpiler.inline(transpiler.to_block(my_kernel))
>>> canon = canonicalize(affine)
>>> canon.kind is affine.kind
Truecanonicalize_and_remap [source]¶
def canonicalize_and_remap(block: Block) -> tuple[Block, dict[str, str], dict[str, str]]Return canonical-form Block plus the UUID and logical_id remap tables.
Useful when the caller holds external references keyed on the original Value UUIDs or logical_ids (e.g., a host-side port map) and needs to update those references to match the canonical form.
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | The block to canonicalize. Must be at BlockKind.AFFINE or BlockKind.ANALYZED. |
Returns:
tuple[Block, dict[str, str], dict[str, str]] — tuple[Block, dict[str, str], dict[str, str]]: A triple
(canonical_block, uuid_remap, logical_id_remap) where
each remap maps every original identifier encountered
during the walk to its canonical counterpart. uuid and
logical_id share the same monotonic counter but are
tracked in separate maps.
Raises:
ValueError— Ifblock.kindis not in{AFFINE, ANALYZED}, or if a loop operation’s region arguments violate the SSA identity invariants (see :func:validate_region_args).NotImplementedError— If an unsupported operation is encountered.
collect_reachable_values [source]¶
def collect_reachable_values(block: Block) -> tuple[ValueBase, ...]Collect values reachable from an IR block in canonical walk order.
The traversal includes values referenced by operation-owned nested blocks and returns each value UUID at most once. Its ordering is the same stable ordering used by canonical byte emission.
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | Root block whose reachable values to collect. |
Returns:
tuple[ValueBase, ...] — tuple[ValueBase, ...]: Reachable values in deterministic canonical
declaration order.
content_fingerprint [source]¶
def content_fingerprint(obj: Any) -> strCompute a deterministic fingerprint for supported lowered IR content.
Unlike the legacy canonical content_hash encoder, this function rejects
values that would require a repr fallback. Its accepted values are the
stable scalar, collection, enum, array, Hamiltonian, type, and dataclass
forms used by lowered circuit programs.
Parameters:
| Name | Type | Description |
|---|---|---|
obj | Any | Lowered IR content composed exclusively of supported stable values. |
Returns:
str — SHA-256 hexadecimal digest of the structural content token.
Raises:
TypeError— Ifobjcontains a value without a stable structural encoding.
content_hash [source]¶
def content_hash(block: Block) -> strCompute a content-addressable hash of block.
Two Blocks that canonicalize to the same form (structurally equal after UUID remapping) produce the same hash. Any IR-level change (gate added, parameter renamed, operand reordered) produces a different hash.
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | The block to hash. Must be at BlockKind.AFFINE or BlockKind.ANALYZED. |
Returns:
str — The SHA-256 hex digest of to_canonical_bytes(block).
Raises:
ValueError— Ifblock.kindis not in{AFFINE, ANALYZED}.
Example:
>>> h1 = content_hash(canonicalize(affine_a))
>>> h2 = content_hash(canonicalize(affine_b))
>>> # If the two kernels are structurally identical, h1 == h2.hamiltonian_to_dict [source]¶
def hamiltonian_to_dict(h: Hamiltonian) -> dict[str, Any]Encode a Hamiltonian into the wrapper dict.
Terms are emitted in the Hamiltonian’s own term-dict iteration
order; each term is a [operators, coefficient] pair where
operators is a list of [pauli_name, qubit_index] entries.
Parameters:
| Name | Type | Description |
|---|---|---|
h | Hamiltonian | The Hamiltonian to encode. Term coefficients and the constant must be int, float, or complex, or a numpy scalar of one of those kinds (coerced via .item()). |
Returns:
dict[str, Any] — dict[str, Any]: A wrapper dict with $hamiltonian,
terms, constant, and num_qubits (the declared
register width passed to the constructor, or None).
Raises:
TypeError— Ifhis not aHamiltonian, if a coefficient / the constant is not int, float, or complex, or if the declarednum_qubitsis not an int — all after coercing anynumpyscalar to its Python equivalent.ValueError— If the declarednum_qubitsis negative.
remap_indexed_identifier [source]¶
def remap_indexed_identifier(identifier: str, remap_identifier: Callable[[str], str]) -> strRemap an identifier while preserving a legacy index suffix.
Parameters:
| Name | Type | Description |
|---|---|---|
identifier | str | Scalar identifier or legacy "<base>_<index>" carrier key. |
remap_identifier | typing.Callable[[str], str] | Function that remaps scalar identifiers and carrier-key bases. |
Returns:
str — Remapped identifier. Numeric index suffixes are preserved after
remapping the base identifier.
remap_value_metadata_references [source]¶
def remap_value_metadata_references(
metadata: ValueMetadata,
remap_uuid: Callable[[str], str],
remap_logical_id: Callable[[str], str],
) -> ValueMetadataRewrite UUID and logical-id references inside value metadata.
Parameters:
| Name | Type | Description |
|---|---|---|
metadata | ValueMetadata | Metadata bundle whose embedded references should be rewritten. |
remap_uuid | typing.Callable[[str], str] | Function that maps scalar UUID references (and carrier-key bases) to replacement UUIDs. |
remap_logical_id | typing.Callable[[str], str] | Function that maps scalar logical-id references (and carrier-key bases) to replacement logical IDs. |
Returns:
ValueMetadata — Metadata with every embedded UUID / logical-id reference
rewritten. Legacy "<uuid>_<index>" carrier keys keep their
index suffix while remapping the base UUID. The original bundle is
returned unchanged when no reference is rewritten.
to_canonical_bytes [source]¶
def to_canonical_bytes(block: Block) -> bytesSerialize block to a deterministic byte representation.
The byte format is the internal representation backing
content_hash and is not stable across qamomile versions. It is
suitable for hashing and equality checks within a single
deployment but should not be relied upon as a serialization
format. (A stable, versioned serialization format is tracked
separately.)
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | The block to serialize. Must be at BlockKind.AFFINE or BlockKind.ANALYZED. The block is canonicalized first; passing an already-canonical block is harmless. |
Returns:
bytes — A UTF-8-encoded byte string. Two structurally-equal
Blocks produce the same bytes; changing the IR yields
different bytes.
Raises:
ValueError— Ifblock.kindis not in{AFFINE, ANALYZED}.
validate_region_args [source]¶
def validate_region_args(op: ForOperation | ForItemsOperation | WhileOperation) -> tuple[RegionArg, ...]Validate the SSA identities owned by a loop’s region arguments.
A loop owns several definition namespaces: its iteration variables,
every RegionArg.block_arg, and every RegionArg.result. Those
identities must be pairwise disjoint. Otherwise different stages can
assign incompatible meanings to one UUID: a UUID-keyed environment has
only one slot, so binding either the iteration variable or the carried
value overwrites the other and makes both reads observe the same value.
Parameters:
| Name | Type | Description |
|---|---|---|
op | ForOperation | ForItemsOperation | WhileOperation | Loop operation whose region arguments should be validated. |
Returns:
tuple[RegionArg, ...] — tuple[RegionArg, ...]: The validated op.region_args tuple.
Raises:
ValueError— If result counts or positions disagree, slot types differ, or any loop-owned definition identity collides with another definition or with a region initializer/body yield.
Classes¶
ArrayValue [source]¶
class ArrayValue(Value[T])An array of typed IR values.
When slice_of is set, this array is a strided view over another
array. Element accesses on a sliced ArrayValue resolve to
physical slots on the root parent via the affine map
parent_index = slice_start + slice_step * view_local_index,
applied recursively along slice_of chains. The emit-time
resolver walks this chain to produce the final qubit index; passes
that substitute or clone values must treat slice_of /
slice_start / slice_step as Value references that need to
track through the same mapping as parent_array.
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(),
slice_of: 'ArrayValue | None' = None,
slice_start: 'Value | None' = None,
slice_step: 'Value | None' = None,
) -> NoneAttributes¶
logical_id: strmetadata: ValueMetadataname: strshape: tuple[Value, ...]slice_of: ‘ArrayValue | None’slice_start: ‘Value | None’slice_step: ‘Value | None’type: Tuuid: str
Methods¶
is_slice¶
def is_slice(self) -> boolReturn True if this array is a strided view of another array.
Returns:
bool — True iff slice_of is non-None.
next_version¶
def next_version(self) -> ArrayValue[T]Block [source]¶
class BlockUnified 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[ValueLike] = list(),
output_values: list[ValueLike] = list(),
output_names: list[str] = list(),
operations: list['Operation'] = list(),
kind: BlockKind = BlockKind.HIERARCHICAL,
parameters: dict[str, Value] = dict(),
param_slots: tuple[ParamSlot, ...] = tuple(),
static_bindings: tuple[StaticBindingSlot, ...] = tuple(),
) -> NoneAttributes¶
effects: ‘KernelEffect’ Return lazily cached semantic effects for this block.input_values: list[ValueLike]kind: BlockKindlabel_args: list[str]measurement_result_indices: frozenset[int] Return public output positions derived from measurement.name: stroperations: list[‘Operation’]output_names: list[str]output_values: list[ValueLike]param_slots: tuple[ParamSlot, ...]parameters: dict[str, Value]static_bindings: tuple[StaticBindingSlot, ...]
Methods¶
call¶
def call(self, **kwargs: ValueLike = {}) -> 'InvokeOperation'Create an inline callable invocation against this block.
Parameters:
| Name | Type | Description |
|---|---|---|
**kwargs | ValueLike | Actual argument values keyed by self.label_args. |
Returns:
'InvokeOperation' — Inline-policy invocation whose callable
definition points at this block.
Raises:
KeyError— If a required label inself.label_argsis missing fromkwargs.
is_affine¶
def is_affine(self) -> boolReturn whether this block has passed affine validation.
Returns:
bool — True for AFFINE and ANALYZED blocks.
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¶
AFFINEANALYZEDHIERARCHICALTRACED
BranchRebind [source]¶
class BranchRebindTrace-time record of a quantum variable rebound inside an if branch.
The frontend’s branch tracing merges only the new branch values
through merge operations; when both branches rebind a variable, the
value the variable held before the branch no longer appears anywhere
in the IfOperation. These records preserve that pre-branch
binding so the transpiler’s control-flow discard check
(reject_control_flow_quantum_discard in
qamomile.circuit.transpiler.passes.analyze) can verify that the
pre-branch quantum state is consumed or carried on every runtime
execution path instead of being silently dropped.
Constructor¶
def __init__(
self,
var_name: str,
before: Value,
rebound_in_true: bool,
rebound_in_false: bool,
) -> NoneAttributes¶
before: Valuerebound_in_false: boolrebound_in_true: boolvar_name: str
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:
Vector[Qubit] -> QFixed (after QPE, for phase measurement)
Vector[Qubit] -> QUInt (for quantum arithmetic)
QUInt -> QFixed (reinterpret bits with different encoding)
QFixed -> QUInt (reinterpret bits with different encoding)
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(),
) -> NoneAttributes¶
num_qubits: int Number of qubits involved in the cast.operation_kind: OperationKind Cast stays in the same segment as its source (QUANTUM for quantum types).qubit_mapping: list[str]signature: Signature Return the type signature of this cast operation.source_type: ValueType | Nonetarget_type: ValueType | None
ControlledUOperation [source]¶
class ControlledUOperation(Operation)Base class for controlled-U operations.
Two concrete subclasses handle distinct operand layouts:
ConcreteControlledU: Fixednum_controls: int, individual qubit operands.SymbolicControlledU: Symbolicnum_controls: Value, vector-based control operands; optionalcontrol_indicesselects a subset of the control vector to act as controls (the rest pass through).
All isinstance(op, ControlledUOperation) checks match every subclass.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
power: int | Value = 1,
block: Block | None = None,
num_controls: int | Value = 1,
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] = dict(),
) -> NoneAttributes¶
block: Block | Nonebody_operands: list[Value] Get the wrapped callable’s complete argument list.callable_attrs: dict[str, Any]callable_ref: CallableRef | Nonecontrol_operands: list[Value] Get the control qubit values.is_symbolic_num_controls: bool Whether num_controls is symbolic (Value) rather than concrete.num_controls: int | Valueoperation_kind: OperationKindparam_operands: list[Value] Get the controlled operation’s classical/object arguments.power: int | Valuesignature: Signaturetarget_operands: list[Value] Get the target qubit values (arguments to U).
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationDictValue [source]¶
class DictValue(_MetadataValueMixin, ValueBase)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()))(),
) -> NoneAttributes¶
entries: tuple[tuple[TupleValue | Value, Value], ...]logical_id: strmetadata: ValueMetadataname: strtype: DictTypeuuid: str
Methods¶
is_constant¶
def is_constant(self) -> boolnext_version¶
def next_version(self) -> DictValueForItemsOperation [source]¶
class ForItemsOperation(HasNestedOps, Operation)Represents iteration over dict/iterable items.
Example:
for (i, j), Jij in qmc.items(ising):
bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
key_vars: list[str] = list(),
value_var: str = '',
key_is_vector: bool = False,
key_var_values: tuple[Value, ...] | None = None,
value_var_value: Value | None = None,
operations: list[Operation] = list(),
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_args: tuple[RegionArg, ...] = (),
captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
captures: tuple[ValueBase, ...]key_is_vector: boolkey_var_values: tuple[Value, ...] | Nonekey_vars: list[str]loop_carried_rebinds: tuple[LoopCarriedRebind, ...]operation_kind: OperationKindoperations: list[Operation]region_args: tuple[RegionArg, ...]signature: Signaturevalue_var: strvalue_var_value: Value | None
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include the per-key/value Value fields for cloning/substitution.
Same rationale as ForOperation.all_input_values: keep the IR
identity fields in lockstep with body references so UUID-keyed
lookups stay valid after inline cloning. Loop-carried rebind
records and region arguments are included for the same reason.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the items-loop body with its explicit interface.
Returns:
tuple[Region, ...] — tuple[Region, ...]: One body region containing key/value formals,
carried-value formals, captures, and carried yields.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operationrebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild the items-loop body and complete boundary interface.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Exactly one replacement body region. |
Returns:
Operation — Rebuilt items-loop operation.
Raises:
ValueError— If arity or boundary value kinds are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationForOperation [source]¶
class ForOperation(HasNestedOps, Operation)Represents a for loop operation.
Example:
for i in range(start, stop, step):
bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
loop_var: str = '',
loop_var_value: Value | None = None,
operations: list[Operation] = list(),
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_args: tuple[RegionArg, ...] = (),
captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
captures: tuple[ValueBase, ...]loop_carried_rebinds: tuple[LoopCarriedRebind, ...]loop_var: strloop_var_value: Value | Noneoperation_kind: OperationKindoperations: list[Operation]region_args: tuple[RegionArg, ...]signature: Signature
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include loop_var_value so cloning/substitution stays consistent.
Without this override, UUIDRemapper would clone every body
reference to the loop variable to a fresh UUID, but leave
loop_var_value pointing at the un-cloned original — emit-time
UUID-keyed lookups for the loop variable would then miss.
Loop-carried rebind records and region arguments are included
for the same reason.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the range-loop body with its explicit interface.
Returns:
tuple[Region, ...] — tuple[Region, ...]: One body region containing the induction
value, carried-value formals, captures, and carried yields.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operationrebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild the range-loop body and complete boundary interface.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Exactly one replacement body region. |
Returns:
Operation — Rebuilt range-loop operation.
Raises:
ValueError— If arity or boundary value kinds are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationHamiltonian [source]¶
class HamiltonianRepresents a quantum Hamiltonian as a sum of Pauli operator products.
The Hamiltonian is stored as a dictionary where keys are tuples of PauliOperators and values are their corresponding coefficients.
Example:
>>> H = Hamiltonian()
>>> H.add_term((PauliOperator(Pauli.X, 0), PauliOperator(Pauli.Y, 1)), 0.5)
>>> H.add_term((PauliOperator(Pauli.Z, 2),), 1.0)
>>> print(H.terms)
{(X0, Y1): 0.5, (Z2,): 1.0}Constructor¶
def __init__(self, num_qubits: int | None = None) -> NoneAttributes¶
constant: float | complexnum_qubits: int Calculates the number of qubits in the Hamiltonian.terms: dict[tuple[PauliOperator, ...], complex] Getter for the terms of the Hamiltonian.
Methods¶
add_term¶
def add_term(self, operators: tuple[PauliOperator, ...], coeff: float | complex)Adds a term to the Hamiltonian.
This method adds a product of Pauli operators with a given coefficient to the Hamiltonian. If the term already exists, the coefficients are summed.
Parameters:
| Name | Type | Description |
|---|---|---|
operators | Tuple[PauliOperator, ...] | A tuple of PauliOperators representing the term. |
coeff | Union[float, complex] | The coefficient of the term. |
Example:
>>> H = Hamiltonian()
>>> H.add_term((PauliOperator(Pauli.X, 0), PauliOperator(Pauli.Y, 1)), 0.5)
>>> H.add_term((PauliOperator(Pauli.X, 0), PauliOperator(Pauli.Y, 1)), 0.5j)
>>> print(H.terms)
{(X0, Y1): (0.5+0.5j)}copy¶
def copy(self) -> HamiltonianReturn an independent copy sharing no mutable state with self.
Produces a new Hamiltonian with the same terms, constant,
and declared _num_qubits. The underlying _terms dict
is fresh, so subsequent add_term / constant mutations
on either instance do not affect the other. PauliOperator
instances inside the term tuples are reused — they are
dataclass(frozen=True) values and safely shared.
Returns:
Hamiltonian — A shallow-cloned Hamiltonian instance.
Example:
>>> H = Hamiltonian()
>>> H.add_term((PauliOperator(Pauli.Z, 0),), 1.0)
>>> H2 = H.copy()
>>> H2.add_term((PauliOperator(Pauli.X, 1),), 0.5)
>>> H.num_qubits # unchanged by H2's mutation
1identity¶
@classmethod
def identity(
cls,
coeff: float | complex = 1.0,
num_qubits: int | None = None,
) -> HamiltonianCreate a scalar times identity Hamiltonian.
remap_qubits¶
def remap_qubits(self, qubit_map: dict[int, int]) -> HamiltonianRemap qubit indices according to the given mapping.
This is used to translate Pauli indices (logical indices within an expval call) to physical qubit indices in the actual quantum circuit.
Parameters:
| Name | Type | Description |
|---|---|---|
qubit_map | dict[int, int] | Mapping from logical index to physical index. e.g., {0: 5, 1: 3} maps logical index 0 → physical qubit 5 |
Returns:
Hamiltonian — New Hamiltonian with remapped qubit indices.
single_pauli¶
@classmethod
def single_pauli(cls, pauli: Pauli, index: int, coeff: float | complex = 1.0) -> HamiltonianCreate a single Pauli term Hamiltonian.
to_latex¶
def to_latex(self) -> strConverts the Hamiltonian to a LaTeX representation.
This function does not add constant term when we show the Hamiltonian. This function does not add $ symbols.
Returns:
str —
A LaTeX representation of the Hamiltonian.
import qamomile.observable as qm_o
import IPython.display as ipd
h = qm_o.Hamiltonian()
h += -qm_o.X(0) * qm_o.Y(1) - 2.0 * qm_o.Z(0) * qm_o.Z(1)
# Show the Hamiltonian in LaTeX at Jupyter Notebook
ipd.display(ipd.Latex("$" + h.to_latex() + "$"))to_numpy¶
def to_numpy(self) -> np.ndarrayConvert the Hamiltonian to a dense NumPy matrix.
Qubit 0 is mapped to the least-significant bit of computational-basis
indices, matching :meth:qamomile.linalg.HermitianMatrix.to_hamiltonian.
The returned array has shape (2**n, 2**n) where n is
:attr:num_qubits.
zero¶
@classmethod
def zero(cls, num_qubits: int | None = None) -> HamiltonianCreate a zero Hamiltonian.
HasNestedOps [source]¶
class HasNestedOpsMixin for operations that contain nested operation lists.
nested_regions() is the canonical traversal API because it exposes
operations together with block arguments, captures, and yields.
nested_op_lists() / rebuild_nested() remain compatibility helpers
for specialized consumers while they migrate to the region interface.
Methods¶
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]Return all nested operation lists in this control flow op.
nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return uniform views of every nested operation region.
Subclasses with explicit block arguments, captures, or yields override
this method. The fallback keeps legacy operation-owned blocks visible
while consumers migrate from nested_op_lists.
Returns:
tuple[Region, ...] — tuple[Region, ...]: Region views in nested_op_lists order.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> OperationReturn a copy with nested operation lists replaced.
new_lists must have the same length/order as nested_op_lists().
rebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationReturn a copy with replacement region operation sequences.
Concrete control-flow operations override this method to rebuild both their body operations and boundary values. The fallback supports legacy region owners whose boundary remains operation-specific.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Replacement regions in nested_regions order. |
Returns:
Operation — Rebuilt control-flow operation.
Raises:
ValueError— If the replacement region count differs from the operation’s current region count.
InverseBlockOperation [source]¶
class InverseBlockOperation(Operation)Represent an inverse qkernel/block as a first-class IR operation.
The operation stores both the original forward block and a Qamomile-built
inverse implementation block. Emitters may use source_block with a
backend-native inverse/adjoint primitive, then fall back to
implementation_block when native inversion is unavailable.
Operands are ordered as scalar control qubits, target quantum operands,
then classical/object parameters. Results mirror the quantum operand
layout: control results first, then one target result per target operand.
Vector target operands therefore count as one operand/result while
contributing their scalar width to num_target_qubits.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_control_qubits: int = 0,
num_target_qubits: int = 0,
custom_name: str = '',
source_block: Block | None = None,
implementation_block: Block | None = None,
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] = dict(),
control_value: int | None = None,
) -> NoneAttributes¶
callable_attrs: dict[str, Any]callable_ref: CallableRef | Nonecontrol_qubits: list[‘Value’] Return control quantum operands.control_value: int | Nonecustom_name: strimplementation_block: Block | Nonename: str Return a human-readable inverse operation name.num_control_qubits: intnum_target_qubits: intoperation_kind: OperationKind Return the operation kind.parameters: list[‘Value’] Return classical/object parameter operands.signature: Signature Return the operation signature.source_block: Block | Nonetarget_qubits: list[‘Value’] Return target quantum operands.
InvokeOperation [source]¶
class InvokeOperation(Operation)Represent a composite, stdlib, or oracle call.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | list[ValueLike] | Input values consumed by the call. |
results | list[ValueLike] | Output values produced by the call. |
target | CallableRef | Callable identity. |
transform | CallTransform | Direct, inverse, or controlled invocation. |
attrs | dict[str, Any] | Compile-time attributes for strategy, arity, and resource/lowering decisions. control_value is reserved for a controlled invocation’s LSB-first activation value. Values must be serializer-friendly. |
definition | CallableDef | None | Optional callable definition. |
Constructor¶
def __init__(
self,
operands: Sequence[ValueLike] | None = None,
results: Sequence[ValueLike] | None = None,
*,
target: CallableRef | None = None,
transform: CallTransform = CallTransform.DIRECT,
attrs: dict[str, Any] | None = None,
definition: CallableDef | None = None,
) -> NoneInitialize an invocation operation.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | Sequence[ValueLike] | None | Input values consumed by the call. Defaults to None, meaning no operands. |
results | Sequence[ValueLike] | None | Output values produced by the call. Defaults to None, meaning no results. |
target | CallableRef | None | Callable identity. Defaults to an anonymous user callable when omitted. |
transform | CallTransform | Requested call transform. Defaults to CallTransform.DIRECT. |
attrs | dict[str, Any] | None | Serializer-friendly call attributes. Defaults to an empty dict. |
definition | CallableDef | None | Callable definition. Defaults to None, in which case one is created from target. |
Raises:
TypeError— If a controlled invocation’scontrol_valueor an Oracle control-partition field has an invalid Python type.ValueError— Ifcontrol_valueis used on a non-controlled call or does not fit the controlled invocation’s width, or if Oracle invocation and definition control metadata disagree.
Attributes¶
attrs: dict[str, Any]body: Block | None Return the callable’s default body from its definition.body_ref: CallableBodyRef | None Return the callable’s deferred body reference.control_qubits: list[‘Value’] Return the control-qubit operands.control_value: int | None Return the controlled invocation’s activation value.custom_name: str Return the display name for custom callable boxes.default_policy: CallPolicy Return the callable’s default lowering policy.definition: CallableDef | Noneeffects: ‘KernelEffect’ Return cached effects of relevant callable implementations.gate_type: CompositeGateType Return the standard composite classification for this invocation.measurement_result_indices: frozenset[int] Return a conservative union of measurement-derived results.name: str Return the display name for this invocation.num_added_control_qubits: int Return controls introduced by a frontend control transform.num_body_external_control_qubits: int Return control operands generic lowering adds outside a base body.num_control_qubits: int Return the number of leading control-qubit operands.num_declared_control_qubits: int Return controls included in an opaque Oracle’s base definition.num_target_qubits: int Return the number of target-qubit operands.operandsoperation_kind: OperationKind Return the operation kind.parameters: list[‘Value’] Return non-qubit parameter operands.resultssignature: Signature Return the operation signature.strategy_name: str | None Return the selected lowering/resource strategy name.target: CallableReftarget_qubits: list[‘Value’] Return the target-qubit operands.transform: CallTransform
Methods¶
body_for_transform¶
def body_for_transform(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> tuple[Block | None, CallTransform]Select a body and report the transform it already realizes.
A controlled-inverse invocation may reuse an explicitly registered inverse body when no implementation realizes both transforms. Keeping that fallback in the IR operation gives emitters and static analyses one selection rule while still letting each consumer apply the remaining coherent controls in its own representation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None. |
strategy | str | None | Strategy name to match. Defaults to the invocation’s strategy_name attribute. |
Returns:
Block | None — tuple[Block | None, CallTransform]: Selected body and the transform
CallTransform — already implemented by that body. The callable’s direct body is
tuple[Block | None, CallTransform] — returned with DIRECT when no transform-specific body matches.
Raises:
ValueError— If the selected body disagrees with the invocation’s input or output contract.
effective_body¶
def effective_body(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> Block | NoneReturn the implementation body selected for this invocation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None. |
strategy | str | None | Strategy name to match. Defaults to the invocation’s strategy_name attribute. |
Returns:
Block | None — Block | None: Selected implementation body, or the callable’s
Block | None — default body when no transform-specific implementation exists.
Block | None — A compiler may synthesize inverse or controlled behavior from this
Block | None — fallback body.
implementation_for¶
def implementation_for(
self,
*,
backend: str | None = None,
strategy: str | None = None,
require_body: bool = False,
) -> CallableImplementation | NoneReturn the selected implementation for this invocation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None, which only selects backend-generic implementations. |
strategy | str | None | Strategy name to match. Defaults to None, meaning the invocation’s strategy_name attribute is used. |
require_body | bool | Whether candidates without an IR body should be excluded before ranking. Defaults to False. |
Returns:
CallableImplementation | None — CallableImplementation | None: Matching implementation candidate,
CallableImplementation | None — or None when the callable definition has no match.
measurement_result_indices_for¶
def measurement_result_indices_for(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> frozenset[int]Return measurement-derived results for one selected implementation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name used for implementation selection. Defaults to None. |
strategy | str | None | Strategy name used for implementation selection. Defaults to the invocation’s strategy_name. |
Returns:
frozenset[int] — frozenset[int]: Caller-local result positions derived from
measurement in the selected body.
Raises:
ValueError— If the selected body disagrees with the invocation’s input or output contract.
select_body¶
def select_body(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> CallableBodySelectionSelect and validate the composable body for this invocation.
The result carries the transform already realized by the body and the exact call-site values that bind to it. Consumers therefore cannot independently disagree about whether an invocation’s control prefix belongs to the selected implementation ABI.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None. |
strategy | str | None | Strategy name to match. Defaults to the invocation’s strategy_name attribute. |
Returns:
CallableBodySelection — Validated body, realized transform, and
CallableBodySelection — aligned call-site operands and results.
Raises:
ValueError— If the selected body disagrees with the invocation’s input or output contract.
LoopCarriedRebind [source]¶
class LoopCarriedRebindTrace-time record of a variable rebound inside a loop body.
Two rebind families share this record type, distinguished by the
type of before:
Classical scalar (
beforeclassical): the frontend traces a loop body exactly once, so a Python-level reassignment liketotal = total + iproduces IR whose right-hand side reads the fixed pre-loop value instead of the previous iteration’s value. Most such carries are now represented as explicitRegionArgs (see above) and are fully supported; a classical record is only created for the shapes region binding declines —while-body carries (a runtime while loop cannot be unrolled) and measurement-backedBitcarries — and the transpiler’s classical loop-carried check rejects those with a targeted error instead of silently miscompiling.Quantum (
beforequantum): the loop body left the variable bound to a different quantum resource (logical_idchange — a fresh allocation or another register, not a gate self-update). The transpiler’s control-flow discard check (reject_control_flow_quantum_discard) rejects the ones whose incoming state the body never consumes.
Constructor¶
def __init__(
self,
var_name: str,
before: ValueBase,
after: ValueBase,
before_synthesized: bool = False,
) -> NoneAttributes¶
after: ValueBasebefore: ValueBasebefore_synthesized: boolvar_name: str
RegionArg [source]¶
class RegionArgExplicit loop-carried value on a loop operation (MLIR-style iter_arg).
A RegionArg makes a loop-carried dependency explicit in the IR,
the way MLIR’s scf.for models iter_args / scf.yield:
On iteration 0 the body reads
block_argbound toinit.After each iteration,
block_argis rebound to that iteration’syieldedvalue.After the loop,
resultholds the final carried value (initwhen the loop ran zero iterations).
The loop body’s operations reference block_arg (the frontend
substitutes the traced pre-loop reads), and post-loop operations
reference result (the frontend rebinds the Python handle when it
closes the loop). result is also appended to the loop operation’s
results list so dependency analysis sees the loop as its
producer.
This subsumes the trace-once staleness that LoopCarriedRebind
records exist to reject: a rebind represented as a RegionArg is
a supported loop-carried value, not a miscompilation hazard.
Constructor¶
def __init__(
self,
var_name: str,
init: Value,
block_arg: Value,
yielded: Value,
result: Value,
) -> NoneAttributes¶
block_arg: Valueinit: Valueresult: Valuevar_name: stryielded: Value
SelectOperation [source]¶
class SelectOperation(Operation)Quantum multiplexer: apply case_blocks[i] when the index reads i.
Concrete operand layout:
[idx_0, ..., idx_{k-1}, tgt_0, ..., tgt_m, params...].
Symbolic-width operand layout:
[idx_arg_0, ..., idx_arg_{a-1}, tgt_0, ..., tgt_m, params...].
Results mirror the quantum operand grouping.
A concrete index register is normalized to one scalar Qubit operand
per physical index qubit. A symbolic-width register instead retains each
leading caller argument as one scalar or array operand until its bound
shape is known. Whole-Vector[Qubit] / scalar targets follow and keep
their shapes, and classical parameters shared across every case come last.
Index bit order is LSB-first: idx_0 is the least-significant
bit, matching Qamomile’s qubit-zero convention. Case i is selected
when index qubit j reads bit j of i. len(case_blocks)
need not be a power of two; index values >= len(case_blocks) apply
no operation (identity).
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_index_qubits: int | Value = 0,
case_blocks: list[Block] = list(),
num_index_args: int = 0,
case_callable_attrs: list[dict[str, Any]] = list(),
) -> NoneAttributes¶
case_blocks: list[Block]case_callable_attrs: list[dict[str, Any]]index_operands: list[Value] Return the grouped index-prefix operands.is_symbolic_num_index_qubits: bool Return whether the index width is a symbolic IR value.num_cases: int Return the number of selectable cases.num_index_args: intnum_index_qubits: int | Valueoperation_kind: OperationKind Return the operation kind.param_operands: list[Value] Return the shared classical parameter operands.signature: Signature Return the operation signature.target_operands: list[Value] Return the quantum target operands applied by every case.
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Return every value consumed by the SELECT operation.
Returns:
list[ValueBase] — list[ValueBase]: Ordinary operands plus the symbolic index-width
value when present.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationReplace operand and symbolic-width values by UUID.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | dict[str, ValueBase] | UUID-keyed replacement values. |
Returns:
Operation — Rebuilt SELECT operation with matching values replaced.
StaticBindingField [source]¶
class StaticBindingFieldReference one scalar field projected from a static binding.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | Registered field name on the bound object. |
value | Value | Symbolic scalar used by the hierarchical IR until the binding is materialized. |
Constructor¶
def __init__(self, name: str, value: Value) -> NoneAttributes¶
name: strvalue: Value
StaticBindingSlot [source]¶
class StaticBindingSlotDeclare one typed compile-time object required by a qkernel.
The object itself is not an SSA value and never reaches a backend. Only registered scalar projections and deferred callable-member references may appear in the hierarchical body. A build must resolve the slot before the block advances to a compiler stage.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | QKernel argument name used by bindings. |
type_key | str | Stable key of the registered static-binding adapter. |
fields | tuple[StaticBindingField, ...] | Scalar projections referenced while tracing the unbound qkernel. |
Constructor¶
def __init__(
self,
name: str,
type_key: str,
fields: tuple[StaticBindingField, ...] = (),
) -> NoneAttributes¶
fields: tuple[StaticBindingField, ...]name: strtype_key: str
TupleValue [source]¶
class TupleValue(_MetadataValueMixin, ValueBase)A tuple of IR values for structured data.
Constructor¶
def __init__(
self,
name: str,
elements: tuple[ValueLike, ...] = tuple(),
metadata: ValueMetadata = ValueMetadata(),
uuid: str = (lambda: str(uuid.uuid4()))(),
logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> NoneAttributes¶
elements: tuple[ValueLike, ...]logical_id: strmetadata: ValueMetadataname: strtype: ‘TupleType’uuid: str
Methods¶
is_constant¶
def is_constant(self) -> boolnext_version¶
def next_version(self) -> TupleValueValue [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.
ValueBase [source]¶
class ValueBaseNominal base for every typed IR value.
Runtime compiler passes inspect values in their innermost loops. A nominal base keeps those checks constant-time; a runtime-checkable protocol would repeatedly scan the protocol members on Python versions that do not cache structural checks.
Attributes¶
logical_id: strmetadata: ValueMetadataname: strtype: ValueType Return the static IR type carried by this value.uuid: str
Methods¶
get_const¶
def get_const(self) -> int | float | bool | NoneReturn the scalar constant carried by this value.
Returns:
int | float | bool | None — int | float | bool | None: Constant value, or None when the
value is not constant.
is_constant¶
def is_constant(self) -> boolReturn whether this value carries a scalar constant.
Returns:
bool — Whether scalar constant metadata is present.
is_parameter¶
def is_parameter(self) -> boolReturn whether this value represents a runtime parameter.
Returns:
bool — Whether parameter metadata is present.
next_version¶
def next_version(self) -> ValueBaseCreate the next SSA version of this value.
Returns:
ValueBase — A value with a fresh version UUID and preserved logical
identity.
parameter_name¶
def parameter_name(self) -> str | NoneReturn the public parameter name carried by this value.
Returns:
str | None — str | None: Parameter name, or None for a non-parameter value.
ValueMetadata [source]¶
class ValueMetadataTyped metadata owned by the compiler/runtime.
Constructor¶
def __init__(
self,
scalar: ScalarMetadata | None = None,
cast: CastMetadata | None = None,
qfixed: QFixedMetadata | None = None,
array_runtime: ArrayRuntimeMetadata | None = None,
dict_runtime: DictRuntimeMetadata | None = None,
) -> NoneAttributes¶
array_runtime: ArrayRuntimeMetadata | Nonecast: CastMetadata | Nonedict_runtime: DictRuntimeMetadata | Noneqfixed: QFixedMetadata | Nonescalar: ScalarMetadata | None
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) -> boolis_object¶
def is_object(self) -> boolis_quantum¶
def is_quantum(self) -> boollabel¶
def label(self) -> strWhileOperation [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,
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_args: tuple[RegionArg, ...] = (),
captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
captures: tuple[ValueBase, ...]loop_carried_rebinds: tuple[LoopCarriedRebind, ...]max_iterations: int | Noneoperation_kind: OperationKindoperations: list[Operation]region_args: tuple[RegionArg, ...]signature: Signature
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include rebind records and region args for cloning/substitution.
Same rationale as ForOperation.all_input_values: rebind
records and region arguments reference body/pre-loop values by
identity, so inline cloning must remap them in lockstep with
body operands.
Returns:
list[ValueBase] — list[ValueBase]: Base input values plus rebind-record and
region-argument values.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the while body with explicit boundary values.
Returns:
tuple[Region, ...] — tuple[Region, ...]: One body region whose block arguments and
yields are aligned with region_args. The updated
condition, when present, is appended as the final yield.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operationrebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild the while body and its complete boundary interface.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Exactly one replacement body region. |
Returns:
Operation — Rebuilt while operation.
Raises:
ValueError— If arity or boundary value kinds are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationSubstitute operand, rebind-record, and region-arg values.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | dict[str, ValueBase] | UUID-keyed substitution map. |
Returns:
Operation — The rewritten operation.
qamomile.circuit.ir.dataflow¶
Backend-independent dataflow utilities for semantic Qamomile IR.
Overview¶
| Function | Description |
|---|---|
build_dependency_graph | Build result-to-input dependency edges for semantic operations. |
find_loop_carried_condition_reads | Find legacy loop rebinds whose entry value controls a nested branch. |
find_loop_carried_condition_uuids | Find branch conditions that read legacy loop-carried scalar Bits. |
find_loop_carried_value_reads | Find unsupported scalar Bit carries read by selected body values. |
find_measurement_derived_values | Propagate measurement provenance forward through a dependency graph. |
find_measurement_results | Return UUIDs directly produced from quantum measurement. |
has_legacy_scalar_bit_rebinds | Return whether an operation tree contains legacy scalar Bit state. |
walk_operations | Yield operations in preorder across every nested control-flow region. |
| Class | Description |
|---|---|
ArrayValue | An array of typed IR values. |
BitType | Type representing a classical bit. |
ForItemsOperation | Represents iteration over dict/iterable items. |
ForOperation | Represents a for loop operation. |
HasNestedOps | Mixin for operations that contain nested operation lists. |
IfOperation | Represents an if-else conditional operation. |
MeasureOperation | |
MeasureQFixedOperation | Measure a quantum fixed-point number. |
MeasureVectorOperation | Measure a vector of qubits. |
ProjectOperation | Project a qubit in one Pauli basis and keep the projected state. |
Value | A typed SSA value in the IR. |
ValueBase | Nominal base for every typed IR value. |
WhileOperation | Represents a while loop operation. |
Functions¶
build_dependency_graph [source]¶
def build_dependency_graph(operations: Sequence[Operation]) -> dict[str, set[str]]Build result-to-input dependency edges for semantic operations.
The graph includes nested control flow, branch merges, loop-carried region arguments, array-element ancestry, and slice ancestry. These are the shared semantics used by measurement provenance, kernel effects, and the compiler’s classical lowering passes.
Parameters:
| Name | Type | Description |
|---|---|---|
operations | Sequence[Operation] | Top-level semantic operations. |
Returns:
dict[str, set[str]] — dict[str, set[str]]: Result UUIDs mapped to the UUIDs they depend on.
find_loop_carried_condition_reads [source]¶
def find_loop_carried_condition_reads(
loop_operation: ForOperation | ForItemsOperation | WhileOperation,
*,
condition_values: Sequence[ValueBase] | None = None,
selected_aliases: Mapping[str, str] | None = None,
) -> set[tuple[str, str]]Find legacy loop rebinds whose entry value controls a nested branch.
A legacy LoopCarriedRebind does not provide runtime storage between
iterations. If its entry value transitively feeds an IfOperation
condition, pruning that first-iteration branch must therefore not erase
the evidence that a later iteration would read the updated value.
Parameters:
| Name | Type | Description |
|---|---|---|
loop_operation | ForOperation | ForItemsOperation | WhileOperation | Loop whose legacy rebind records are inspected. |
condition_values | Sequence[ValueBase] | None | Optional branch conditions from a reachability-aware caller. When omitted, every nested IfOperation condition in the loop body is considered. |
selected_aliases | Mapping[str, str] | None | Optional merge-result to selected-source aliases established by branch specialization. |
Returns:
set[tuple[str, str]] — set[tuple[str, str]]: (before_uuid, after_uuid) pairs for rebinds
whose entry value transitively influences a considered condition.
find_loop_carried_condition_uuids [source]¶
def find_loop_carried_condition_uuids(operations: Sequence[Operation]) -> set[str]Find branch conditions that read legacy loop-carried scalar Bits.
Compile-time specialization normally removes a branch whose first traced condition is a constant. That is unsafe while recursively unrolling a body when the same condition reads a legacy loop-carried Bit: later iterations observe the refreshed value, so the final loop-state validator still needs the branch as dependency evidence.
Parameters:
| Name | Type | Description |
|---|---|---|
operations | Sequence[Operation] | Semantic operation tree to inspect. |
Returns:
set[str] — set[str]: UUIDs of conditions that transitively depend on a legacy
scalar Bit entry value.
find_loop_carried_value_reads [source]¶
def find_loop_carried_value_reads(
loop_operation: ForOperation | ForItemsOperation | WhileOperation,
values: Sequence[ValueBase],
*,
selected_aliases: Mapping[str, str] | None = None,
) -> set[tuple[str, str]]Find unsupported scalar Bit carries read by selected body values.
Parameters:
| Name | Type | Description |
|---|---|---|
loop_operation | ForOperation | ForItemsOperation | WhileOperation | Loop whose legacy rebind records are inspected. |
values | Sequence[ValueBase] | Reached operation inputs whose transitive dependencies are checked. |
selected_aliases | Mapping[str, str] | None | Optional merge-result to selected-source aliases. An alias replaces the merge’s ordinary dependency edges because the other branch is unreachable. |
Returns:
set[tuple[str, str]] — set[tuple[str, str]]: (before_uuid, after_uuid) pairs for legacy
scalar Bit rebinds read by at least one selected value.
find_measurement_derived_values [source]¶
def find_measurement_derived_values(dependency_graph: dict[str, set[str]], measurement_uuids: set[str]) -> set[str]Propagate measurement provenance forward through a dependency graph.
Parameters:
| Name | Type | Description |
|---|---|---|
dependency_graph | dict[str, set[str]] | Result UUIDs mapped to their dependency UUIDs. |
measurement_uuids | set[str] | Direct measurement-result UUIDs. |
Returns:
set[str] — set[str]: Direct and transitively measurement-derived UUIDs.
find_measurement_results [source]¶
def find_measurement_results(operations: Sequence[Operation]) -> set[str]Return UUIDs directly produced from quantum measurement.
Parameters:
| Name | Type | Description |
|---|---|---|
operations | Sequence[Operation] | Top-level semantic operations. |
Returns:
set[str] — set[str]: Direct scalar, vector, fixed-point, and projection results.
has_legacy_scalar_bit_rebinds [source]¶
def has_legacy_scalar_bit_rebinds(operations: Sequence[Operation]) -> boolReturn whether an operation tree contains legacy scalar Bit state.
Parameters:
| Name | Type | Description |
|---|---|---|
operations | Sequence[Operation] | Top-level semantic operations. |
Returns:
bool — Whether a loop carries a scalar Bit through legacy rebind
metadata rather than an explicit region argument.
walk_operations [source]¶
def walk_operations(operations: Sequence[Operation]) -> Iterable[Operation]Yield operations in preorder across every nested control-flow region.
Parameters:
| Name | Type | Description |
|---|---|---|
operations | Sequence[Operation] | Top-level semantic operations. |
Returns:
Iterable[Operation] — Iterable[Operation]: Preorder traversal including nested operations.
Classes¶
ArrayValue [source]¶
class ArrayValue(Value[T])An array of typed IR values.
When slice_of is set, this array is a strided view over another
array. Element accesses on a sliced ArrayValue resolve to
physical slots on the root parent via the affine map
parent_index = slice_start + slice_step * view_local_index,
applied recursively along slice_of chains. The emit-time
resolver walks this chain to produce the final qubit index; passes
that substitute or clone values must treat slice_of /
slice_start / slice_step as Value references that need to
track through the same mapping as parent_array.
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(),
slice_of: 'ArrayValue | None' = None,
slice_start: 'Value | None' = None,
slice_step: 'Value | None' = None,
) -> NoneAttributes¶
logical_id: strmetadata: ValueMetadataname: strshape: tuple[Value, ...]slice_of: ‘ArrayValue | None’slice_start: ‘Value | None’slice_step: ‘Value | None’type: Tuuid: str
Methods¶
is_slice¶
def is_slice(self) -> boolReturn True if this array is a strided view of another array.
Returns:
bool — True iff slice_of is non-None.
next_version¶
def next_version(self) -> ArrayValue[T]BitType [source]¶
class BitType(ClassicalTypeMixin, ValueType)Type representing a classical bit.
ForItemsOperation [source]¶
class ForItemsOperation(HasNestedOps, Operation)Represents iteration over dict/iterable items.
Example:
for (i, j), Jij in qmc.items(ising):
bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
key_vars: list[str] = list(),
value_var: str = '',
key_is_vector: bool = False,
key_var_values: tuple[Value, ...] | None = None,
value_var_value: Value | None = None,
operations: list[Operation] = list(),
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_args: tuple[RegionArg, ...] = (),
captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
captures: tuple[ValueBase, ...]key_is_vector: boolkey_var_values: tuple[Value, ...] | Nonekey_vars: list[str]loop_carried_rebinds: tuple[LoopCarriedRebind, ...]operation_kind: OperationKindoperations: list[Operation]region_args: tuple[RegionArg, ...]signature: Signaturevalue_var: strvalue_var_value: Value | None
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include the per-key/value Value fields for cloning/substitution.
Same rationale as ForOperation.all_input_values: keep the IR
identity fields in lockstep with body references so UUID-keyed
lookups stay valid after inline cloning. Loop-carried rebind
records and region arguments are included for the same reason.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the items-loop body with its explicit interface.
Returns:
tuple[Region, ...] — tuple[Region, ...]: One body region containing key/value formals,
carried-value formals, captures, and carried yields.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operationrebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild the items-loop body and complete boundary interface.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Exactly one replacement body region. |
Returns:
Operation — Rebuilt items-loop operation.
Raises:
ValueError— If arity or boundary value kinds are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationForOperation [source]¶
class ForOperation(HasNestedOps, Operation)Represents a for loop operation.
Example:
for i in range(start, stop, step):
bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
loop_var: str = '',
loop_var_value: Value | None = None,
operations: list[Operation] = list(),
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_args: tuple[RegionArg, ...] = (),
captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
captures: tuple[ValueBase, ...]loop_carried_rebinds: tuple[LoopCarriedRebind, ...]loop_var: strloop_var_value: Value | Noneoperation_kind: OperationKindoperations: list[Operation]region_args: tuple[RegionArg, ...]signature: Signature
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include loop_var_value so cloning/substitution stays consistent.
Without this override, UUIDRemapper would clone every body
reference to the loop variable to a fresh UUID, but leave
loop_var_value pointing at the un-cloned original — emit-time
UUID-keyed lookups for the loop variable would then miss.
Loop-carried rebind records and region arguments are included
for the same reason.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the range-loop body with its explicit interface.
Returns:
tuple[Region, ...] — tuple[Region, ...]: One body region containing the induction
value, carried-value formals, captures, and carried yields.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operationrebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild the range-loop body and complete boundary interface.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Exactly one replacement body region. |
Returns:
Operation — Rebuilt range-loop operation.
Raises:
ValueError— If arity or boundary value kinds are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationHasNestedOps [source]¶
class HasNestedOpsMixin for operations that contain nested operation lists.
nested_regions() is the canonical traversal API because it exposes
operations together with block arguments, captures, and yields.
nested_op_lists() / rebuild_nested() remain compatibility helpers
for specialized consumers while they migrate to the region interface.
Methods¶
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]Return all nested operation lists in this control flow op.
nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return uniform views of every nested operation region.
Subclasses with explicit block arguments, captures, or yields override
this method. The fallback keeps legacy operation-owned blocks visible
while consumers migrate from nested_op_lists.
Returns:
tuple[Region, ...] — tuple[Region, ...]: Region views in nested_op_lists order.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> OperationReturn a copy with nested operation lists replaced.
new_lists must have the same length/order as nested_op_lists().
rebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationReturn a copy with replacement region operation sequences.
Concrete control-flow operations override this method to rebuild both their body operations and boundary values. The fallback supports legacy region owners whose boundary remains operation-specific.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Replacement regions in nested_regions order. |
Returns:
Operation — Rebuilt control-flow operation.
Raises:
ValueError— If the replacement region count differs from the operation’s current region count.
IfOperation [source]¶
class IfOperation(HasNestedOps, Operation)Represents an if-else conditional operation.
Example:
if condition:
true_body
else:
false_bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
true_operations: list[Operation] = list(),
false_operations: list[Operation] = list(),
true_yields: list[Value] = list(),
false_yields: list[Value] = list(),
branch_rebinds: tuple[BranchRebind, ...] = (),
true_captures: tuple[ValueBase, ...] = (),
false_captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
branch_rebinds: tuple[BranchRebind, ...]condition: Valuefalse_captures: tuple[ValueBase, ...]false_operations: list[Operation]false_yields: list[Value]operation_kind: OperationKindsignature: Signaturetrue_captures: tuple[ValueBase, ...]true_operations: list[Operation]true_yields: list[Value]
Methods¶
add_merge¶
def add_merge(self, true_value: Value, false_value: Value, result: Value) -> NoneAppend a branch-merge slot to this if-else.
The only sanctioned construction path for merges: it keeps the
yield lists and results index-aligned so iter_merges can
rely on the invariants it checks.
Parameters:
| Name | Type | Description |
|---|---|---|
true_value | Value | Value selected when the condition is true. |
false_value | Value | Value selected when the condition is false. Must have the same type as true_value. |
result | Value | Fresh SSA value representing the merged output. Must have the same type as the branch values. |
Raises:
RuntimeError— If the condition operand has not been attached to this operation yet (operands[0]must exist before merges are added), or the branch / result types do not match.
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include branch-yield values and rebind records for cloning/substitution.
The yields are subclass-specific Value fields (not operands —
see the class docstring), so generic passes reach them through
this override, mirroring ForItemsOperation.key_var_values.
Branch rebind records follow the loop operations’ rationale: the
recorded pre-branch values reference program values by identity,
so inline cloning must remap them in lockstep with operands.
Read-based checks must not treat the records as reads (see
_op_read_uuids in the analyze pass module).
Returns:
list[ValueBase] — list[ValueBase]: Base input values plus the true/false
yields and rebind-record values.
iter_merges¶
def iter_merges(self) -> Iterator[IfMerge]Iterate the branch-merge slots of this if-else.
This is the single read API for merge semantics: passes must consume merges through it (never through the yield lists directly) so the underlying storage can change without touching consumers.
Yields:
IfMerge — One entry per merged output, in result order.
Raises:
RuntimeError— If the stored merge data is internally inconsistent (the yield-list lengths differ from the result count, or the condition operand is missing while merges are attached). This indicates IR corruption, not a user error. The per-merge corruption modes of the old embedded-operation storage (a foreign entry, a malformed or mismatched condition, a result copy diverging fromresults[i]) cannot be represented in the yield-list storage and need no checks.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]Return the two branch bodies (merge yields are not operations).
Returns:
list[list[Operation]] — list[list[Operation]]: [true_operations, false_operations].
The branch-merge yields are values, not operations, so
they are intentionally absent here.
nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the true and false branch interfaces.
Returns:
tuple[Region, ...] — tuple[Region, ...]: True and false regions in that order, with
branch-local captures and merge yields.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> OperationReturn a copy with the true and false branch bodies replaced.
Parameters:
| Name | Type | Description |
|---|---|---|
new_lists | list[list[Operation]] | The replacement branch bodies in nested_op_lists order ([true_operations, false_operations]). |
Returns:
Operation — A copy of this if-else with the branch bodies
swapped and all other fields (yields, rebinds) preserved.
rebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild both branches and their complete boundary interfaces.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | True and false replacement regions. |
Returns:
Operation — Rebuilt conditional operation.
Raises:
ValueError— If region count, block arguments, or yield signatures are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationSubstitute operand, result, branch-yield, and rebind-record values.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | dict[str, ValueBase] | UUID-keyed substitution map. |
Returns:
Operation — The rewritten operation.
MeasureOperation [source]¶
class MeasureOperation(Operation)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
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):
Qubits are stored least-significant first. For n qubits,
bit i has weight 2**(-n + i).
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_bits: int = 0,
int_bits: int = 0,
) -> NoneAttributes¶
int_bits: intnum_bits: intoperation_kind: OperationKindsignature: Signature
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()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
ProjectOperation [source]¶
class ProjectOperation(Operation)Project a qubit in one Pauli basis and keep the projected state.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
axis: str = 'z',
) -> NoneAttributes¶
axis: stroperation_kind: OperationKindsignature: Signature
Value [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.
ValueBase [source]¶
class ValueBaseNominal base for every typed IR value.
Runtime compiler passes inspect values in their innermost loops. A nominal base keeps those checks constant-time; a runtime-checkable protocol would repeatedly scan the protocol members on Python versions that do not cache structural checks.
Attributes¶
logical_id: strmetadata: ValueMetadataname: strtype: ValueType Return the static IR type carried by this value.uuid: str
Methods¶
get_const¶
def get_const(self) -> int | float | bool | NoneReturn the scalar constant carried by this value.
Returns:
int | float | bool | None — int | float | bool | None: Constant value, or None when the
value is not constant.
is_constant¶
def is_constant(self) -> boolReturn whether this value carries a scalar constant.
Returns:
bool — Whether scalar constant metadata is present.
is_parameter¶
def is_parameter(self) -> boolReturn whether this value represents a runtime parameter.
Returns:
bool — Whether parameter metadata is present.
next_version¶
def next_version(self) -> ValueBaseCreate the next SSA version of this value.
Returns:
ValueBase — A value with a fresh version UUID and preserved logical
identity.
parameter_name¶
def parameter_name(self) -> str | NoneReturn the public parameter name carried by this value.
Returns:
str | None — str | None: Parameter name, or None for a non-parameter value.
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,
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_args: tuple[RegionArg, ...] = (),
captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
captures: tuple[ValueBase, ...]loop_carried_rebinds: tuple[LoopCarriedRebind, ...]max_iterations: int | Noneoperation_kind: OperationKindoperations: list[Operation]region_args: tuple[RegionArg, ...]signature: Signature
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include rebind records and region args for cloning/substitution.
Same rationale as ForOperation.all_input_values: rebind
records and region arguments reference body/pre-loop values by
identity, so inline cloning must remap them in lockstep with
body operands.
Returns:
list[ValueBase] — list[ValueBase]: Base input values plus rebind-record and
region-argument values.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the while body with explicit boundary values.
Returns:
tuple[Region, ...] — tuple[Region, ...]: One body region whose block arguments and
yields are aligned with region_args. The updated
condition, when present, is appended as the final yield.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operationrebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild the while body and its complete boundary interface.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Exactly one replacement body region. |
Returns:
Operation — Rebuilt while operation.
Raises:
ValueError— If arity or boundary value kinds are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationSubstitute operand, rebind-record, and region-arg values.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | dict[str, ValueBase] | UUID-keyed substitution map. |
Returns:
Operation — The rewritten operation.
qamomile.circuit.ir.effect¶
First-class semantic effects for qkernel bodies and invocations.
Overview¶
| Function | Description |
|---|---|
build_dependency_graph | Build result-to-input dependency edges for semantic operations. |
callable_bodies | Return cached semantic bodies relevant to one call transform. |
callable_effects | Return cached effects for a callable invocation. |
callable_measurement_result_indices | Return callable result positions carrying measurement provenance. |
find_measurement_derived_values | Propagate measurement provenance forward through a dependency graph. |
find_measurement_results | Return UUIDs directly produced from quantum measurement. |
format_kernel_effects | Format an effect set for deterministic user-facing diagnostics. |
refresh_block_effects | Refresh reachable effect metadata as a least fixed point. |
require_unitary_effects | Reject non-unitary effects with a uniform early diagnostic. |
summarize_block_effects | Summarize kernel effects and measurement-derived public outputs. |
walk_operations | Yield operations in preorder across every nested control-flow region. |
| Class | Description |
|---|---|
Block | Unified block representation for all pipeline stages. |
CallTransform | Describe the requested transform of a callable implementation. |
CallableDef | Describe a compiler-facing callable definition. |
ControlledUOperation | Base class for controlled-U operations. |
IfOperation | Represents an if-else conditional operation. |
InverseBlockOperation | Represent an inverse qkernel/block as a first-class IR operation. |
InvokeOperation | Represent a composite, stdlib, or oracle call. |
KernelEffect | Describe non-unitary behavior reachable from a kernel body. |
ResetOperation | Reset a qubit to the |0> state and return the fresh handle. |
SelectOperation | Quantum multiplexer: apply case_blocks[i] when the index reads i. |
WhileOperation | Represents a while loop operation. |
Functions¶
build_dependency_graph [source]¶
def build_dependency_graph(operations: Sequence[Operation]) -> dict[str, set[str]]Build result-to-input dependency edges for semantic operations.
The graph includes nested control flow, branch merges, loop-carried region arguments, array-element ancestry, and slice ancestry. These are the shared semantics used by measurement provenance, kernel effects, and the compiler’s classical lowering passes.
Parameters:
| Name | Type | Description |
|---|---|---|
operations | Sequence[Operation] | Top-level semantic operations. |
Returns:
dict[str, set[str]] — dict[str, set[str]]: Result UUIDs mapped to the UUIDs they depend on.
callable_bodies [source]¶
def callable_bodies(definition: 'CallableDef', transform: CallTransform) -> tuple['Block', ...]Return cached semantic bodies relevant to one call transform.
An explicit implementation of the complete transform takes precedence. A controlled-inverse call then reuses explicit inverse-body metadata when generic lowering only needs to add controls; all other structural fallbacks conservatively inherit the direct body’s effects.
Parameters:
| Name | Type | Description |
|---|---|---|
definition | CallableDef | Callable definition referenced by a call. |
transform | CallTransform | Requested direct, inverse, or controlled transform. |
Returns:
tuple['Block', ...] — tuple[Block, ...]: Candidate bodies whose cached metadata applies.
callable_effects [source]¶
def callable_effects(
definition: 'CallableDef | None',
transform: CallTransform = CallTransform.DIRECT,
) -> KernelEffectReturn cached effects for a callable invocation.
Parameters:
| Name | Type | Description |
|---|---|---|
definition | CallableDef | None | Referenced callable definition. |
transform | CallTransform | Requested call transform. Defaults to CallTransform.DIRECT. |
Returns:
KernelEffect — Union of the relevant cached body effects.
callable_measurement_result_indices [source]¶
def callable_measurement_result_indices(
definition: 'CallableDef | None',
transform: CallTransform = CallTransform.DIRECT,
) -> frozenset[int]Return callable result positions carrying measurement provenance.
Parameters:
| Name | Type | Description |
|---|---|---|
definition | CallableDef | None | Referenced callable definition. |
transform | CallTransform | Requested call transform. Defaults to CallTransform.DIRECT. |
Returns:
frozenset[int] — frozenset[int]: Result positions derived from measurement in any
applicable body.
find_measurement_derived_values [source]¶
def find_measurement_derived_values(dependency_graph: dict[str, set[str]], measurement_uuids: set[str]) -> set[str]Propagate measurement provenance forward through a dependency graph.
Parameters:
| Name | Type | Description |
|---|---|---|
dependency_graph | dict[str, set[str]] | Result UUIDs mapped to their dependency UUIDs. |
measurement_uuids | set[str] | Direct measurement-result UUIDs. |
Returns:
set[str] — set[str]: Direct and transitively measurement-derived UUIDs.
find_measurement_results [source]¶
def find_measurement_results(operations: Sequence[Operation]) -> set[str]Return UUIDs directly produced from quantum measurement.
Parameters:
| Name | Type | Description |
|---|---|---|
operations | Sequence[Operation] | Top-level semantic operations. |
Returns:
set[str] — set[str]: Direct scalar, vector, fixed-point, and projection results.
format_kernel_effects [source]¶
def format_kernel_effects(effects: KernelEffect) -> strFormat an effect set for deterministic user-facing diagnostics.
Parameters:
| Name | Type | Description |
|---|---|---|
effects | KernelEffect | Effect set to format. |
Returns:
str — Comma-separated flag names, or NONE for a unitary kernel.
refresh_block_effects [source]¶
def refresh_block_effects(block: 'Block') -> NoneRefresh reachable effect metadata as a least fixed point.
Recursive and mutually recursive callables are valid serialized IR. Their
semantic effects therefore cannot be populated with an ordinary recursive
cache: a cycle would expose and then persist a partial NONE result.
The effect and measured-output lattices are finite, so this routine starts
every reachable body at the empty summary and repeatedly applies the
ordinary local equations until no flag or result index grows.
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | Mutable semantic block whose operations are finalized. |
require_unitary_effects [source]¶
def require_unitary_effects(
effects: KernelEffect,
*,
operation: str,
target: str,
alternative: str,
) -> NoneReject non-unitary effects with a uniform early diagnostic.
Parameters:
| Name | Type | Description |
|---|---|---|
effects | KernelEffect | Cached target effects to validate. |
operation | str | User-facing meta-operation name. |
target | str | Target kernel or callable name. |
alternative | str | Actionable compatible API guidance. |
Raises:
ValueError— Ifeffectsis not the empty unitary set.
summarize_block_effects [source]¶
def summarize_block_effects(
operations: Sequence[Operation],
output_values: Sequence[object],
) -> tuple[KernelEffect, frozenset[int]]Summarize kernel effects and measurement-derived public outputs.
Parameters:
| Name | Type | Description |
|---|---|---|
operations | Sequence[Operation] | Block operation tree. |
output_values | Sequence[object] | Ordered block output values. |
Returns:
tuple[KernelEffect, frozenset[int]] — tuple[KernelEffect, frozenset[int]]: Aggregated effects and output
positions carrying measurement provenance.
walk_operations [source]¶
def walk_operations(operations: Sequence[Operation]) -> Iterable[Operation]Yield operations in preorder across every nested control-flow region.
Parameters:
| Name | Type | Description |
|---|---|---|
operations | Sequence[Operation] | Top-level semantic operations. |
Returns:
Iterable[Operation] — Iterable[Operation]: Preorder traversal including nested operations.
Classes¶
Block [source]¶
class BlockUnified 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[ValueLike] = list(),
output_values: list[ValueLike] = list(),
output_names: list[str] = list(),
operations: list['Operation'] = list(),
kind: BlockKind = BlockKind.HIERARCHICAL,
parameters: dict[str, Value] = dict(),
param_slots: tuple[ParamSlot, ...] = tuple(),
static_bindings: tuple[StaticBindingSlot, ...] = tuple(),
) -> NoneAttributes¶
effects: ‘KernelEffect’ Return lazily cached semantic effects for this block.input_values: list[ValueLike]kind: BlockKindlabel_args: list[str]measurement_result_indices: frozenset[int] Return public output positions derived from measurement.name: stroperations: list[‘Operation’]output_names: list[str]output_values: list[ValueLike]param_slots: tuple[ParamSlot, ...]parameters: dict[str, Value]static_bindings: tuple[StaticBindingSlot, ...]
Methods¶
call¶
def call(self, **kwargs: ValueLike = {}) -> 'InvokeOperation'Create an inline callable invocation against this block.
Parameters:
| Name | Type | Description |
|---|---|---|
**kwargs | ValueLike | Actual argument values keyed by self.label_args. |
Returns:
'InvokeOperation' — Inline-policy invocation whose callable
definition points at this block.
Raises:
KeyError— If a required label inself.label_argsis missing fromkwargs.
is_affine¶
def is_affine(self) -> boolReturn whether this block has passed affine validation.
Returns:
bool — True for AFFINE and ANALYZED blocks.
unbound_parameters¶
def unbound_parameters(self) -> list[str]Return list of unbound parameter names.
CallTransform [source]¶
class CallTransform(enum.Enum)Describe the requested transform of a callable implementation.
Attributes¶
CONTROLLEDCONTROLLED_INVERSEDIRECTINVERSEis_controlled: bool Return whether the transform adds coherent controls.is_inverse: bool Return whether the transform requests inverse application.
Methods¶
inverted¶
def inverted(self) -> CallTransformToggle inverse application while preserving coherent control.
Returns:
CallTransform — Transform with the inverse component toggled.
CallableDef [source]¶
class CallableDefDescribe a compiler-facing callable definition.
Parameters:
| Name | Type | Description |
|---|---|---|
ref | CallableRef | Stable callable identity. |
signature | Signature | None | Optional callable signature. |
body | Block | None | Standard IR body, or None for opaque calls. |
body_ref | CallableBodyRef | None | Reference to a standard body that is intentionally deferred. Defaults to None. |
implementations | list[CallableImplementation] | Alternative native or strategy-specific implementations. |
opaque_cost | Any | None | Explicit cost contract for a bodyless callable. Body-backed callables must leave this as None. |
default_policy | CallPolicy | Default call lowering policy. |
attrs | dict[str, Any] | Serializer-friendly definition metadata. |
Constructor¶
def __init__(
self,
ref: CallableRef,
signature: Signature | None = None,
body: Block | None = None,
body_ref: CallableBodyRef | None = None,
implementations: list[CallableImplementation] = list(),
opaque_cost: Any | None = None,
default_policy: CallPolicy = CallPolicy.INLINE,
attrs: dict[str, Any] = dict(),
) -> NoneAttributes¶
attrs: dict[str, Any]body: Block | Nonebody_ref: CallableBodyRef | Nonedefault_policy: CallPolicyimplementations: list[CallableImplementation]opaque_cost: Any | Noneref: CallableRefsignature: Signature | None
Methods¶
effects_for¶
def effects_for(self, transform: CallTransform = CallTransform.DIRECT) -> 'KernelEffect'Return cached semantic effects for one call transform.
Parameters:
| Name | Type | Description |
|---|---|---|
transform | CallTransform | Requested call transform. Defaults to CallTransform.DIRECT. |
Returns:
'KernelEffect' — Union of relevant implementation-body effects.
implementation_for¶
def implementation_for(
self,
*,
transform: CallTransform = CallTransform.DIRECT,
backend: str | None = None,
strategy: str | None = None,
require_body: bool = False,
) -> CallableImplementation | NoneReturn the best matching implementation candidate.
Parameters:
| Name | Type | Description |
|---|---|---|
transform | CallTransform | Requested call transform. |
backend | str | None | Requested backend name. |
strategy | str | None | Requested strategy name. |
require_body | bool | Whether candidates without an IR body should be excluded before ranking. Defaults to False. |
Returns:
CallableImplementation | None — CallableImplementation | None: Matching implementation, if any.
measurement_result_indices_for¶
def measurement_result_indices_for(self, transform: CallTransform = CallTransform.DIRECT) -> frozenset[int]Return measured result positions for one call transform.
Parameters:
| Name | Type | Description |
|---|---|---|
transform | CallTransform | Requested call transform. Defaults to CallTransform.DIRECT. |
Returns:
frozenset[int] — frozenset[int]: Result indices carrying measurement provenance.
ControlledUOperation [source]¶
class ControlledUOperation(Operation)Base class for controlled-U operations.
Two concrete subclasses handle distinct operand layouts:
ConcreteControlledU: Fixednum_controls: int, individual qubit operands.SymbolicControlledU: Symbolicnum_controls: Value, vector-based control operands; optionalcontrol_indicesselects a subset of the control vector to act as controls (the rest pass through).
All isinstance(op, ControlledUOperation) checks match every subclass.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
power: int | Value = 1,
block: Block | None = None,
num_controls: int | Value = 1,
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] = dict(),
) -> NoneAttributes¶
block: Block | Nonebody_operands: list[Value] Get the wrapped callable’s complete argument list.callable_attrs: dict[str, Any]callable_ref: CallableRef | Nonecontrol_operands: list[Value] Get the control qubit values.is_symbolic_num_controls: bool Whether num_controls is symbolic (Value) rather than concrete.num_controls: int | Valueoperation_kind: OperationKindparam_operands: list[Value] Get the controlled operation’s classical/object arguments.power: int | Valuesignature: Signaturetarget_operands: list[Value] Get the target qubit values (arguments to U).
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationIfOperation [source]¶
class IfOperation(HasNestedOps, Operation)Represents an if-else conditional operation.
Example:
if condition:
true_body
else:
false_bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
true_operations: list[Operation] = list(),
false_operations: list[Operation] = list(),
true_yields: list[Value] = list(),
false_yields: list[Value] = list(),
branch_rebinds: tuple[BranchRebind, ...] = (),
true_captures: tuple[ValueBase, ...] = (),
false_captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
branch_rebinds: tuple[BranchRebind, ...]condition: Valuefalse_captures: tuple[ValueBase, ...]false_operations: list[Operation]false_yields: list[Value]operation_kind: OperationKindsignature: Signaturetrue_captures: tuple[ValueBase, ...]true_operations: list[Operation]true_yields: list[Value]
Methods¶
add_merge¶
def add_merge(self, true_value: Value, false_value: Value, result: Value) -> NoneAppend a branch-merge slot to this if-else.
The only sanctioned construction path for merges: it keeps the
yield lists and results index-aligned so iter_merges can
rely on the invariants it checks.
Parameters:
| Name | Type | Description |
|---|---|---|
true_value | Value | Value selected when the condition is true. |
false_value | Value | Value selected when the condition is false. Must have the same type as true_value. |
result | Value | Fresh SSA value representing the merged output. Must have the same type as the branch values. |
Raises:
RuntimeError— If the condition operand has not been attached to this operation yet (operands[0]must exist before merges are added), or the branch / result types do not match.
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include branch-yield values and rebind records for cloning/substitution.
The yields are subclass-specific Value fields (not operands —
see the class docstring), so generic passes reach them through
this override, mirroring ForItemsOperation.key_var_values.
Branch rebind records follow the loop operations’ rationale: the
recorded pre-branch values reference program values by identity,
so inline cloning must remap them in lockstep with operands.
Read-based checks must not treat the records as reads (see
_op_read_uuids in the analyze pass module).
Returns:
list[ValueBase] — list[ValueBase]: Base input values plus the true/false
yields and rebind-record values.
iter_merges¶
def iter_merges(self) -> Iterator[IfMerge]Iterate the branch-merge slots of this if-else.
This is the single read API for merge semantics: passes must consume merges through it (never through the yield lists directly) so the underlying storage can change without touching consumers.
Yields:
IfMerge — One entry per merged output, in result order.
Raises:
RuntimeError— If the stored merge data is internally inconsistent (the yield-list lengths differ from the result count, or the condition operand is missing while merges are attached). This indicates IR corruption, not a user error. The per-merge corruption modes of the old embedded-operation storage (a foreign entry, a malformed or mismatched condition, a result copy diverging fromresults[i]) cannot be represented in the yield-list storage and need no checks.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]Return the two branch bodies (merge yields are not operations).
Returns:
list[list[Operation]] — list[list[Operation]]: [true_operations, false_operations].
The branch-merge yields are values, not operations, so
they are intentionally absent here.
nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the true and false branch interfaces.
Returns:
tuple[Region, ...] — tuple[Region, ...]: True and false regions in that order, with
branch-local captures and merge yields.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> OperationReturn a copy with the true and false branch bodies replaced.
Parameters:
| Name | Type | Description |
|---|---|---|
new_lists | list[list[Operation]] | The replacement branch bodies in nested_op_lists order ([true_operations, false_operations]). |
Returns:
Operation — A copy of this if-else with the branch bodies
swapped and all other fields (yields, rebinds) preserved.
rebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild both branches and their complete boundary interfaces.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | True and false replacement regions. |
Returns:
Operation — Rebuilt conditional operation.
Raises:
ValueError— If region count, block arguments, or yield signatures are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationSubstitute operand, result, branch-yield, and rebind-record values.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | dict[str, ValueBase] | UUID-keyed substitution map. |
Returns:
Operation — The rewritten operation.
InverseBlockOperation [source]¶
class InverseBlockOperation(Operation)Represent an inverse qkernel/block as a first-class IR operation.
The operation stores both the original forward block and a Qamomile-built
inverse implementation block. Emitters may use source_block with a
backend-native inverse/adjoint primitive, then fall back to
implementation_block when native inversion is unavailable.
Operands are ordered as scalar control qubits, target quantum operands,
then classical/object parameters. Results mirror the quantum operand
layout: control results first, then one target result per target operand.
Vector target operands therefore count as one operand/result while
contributing their scalar width to num_target_qubits.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_control_qubits: int = 0,
num_target_qubits: int = 0,
custom_name: str = '',
source_block: Block | None = None,
implementation_block: Block | None = None,
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] = dict(),
control_value: int | None = None,
) -> NoneAttributes¶
callable_attrs: dict[str, Any]callable_ref: CallableRef | Nonecontrol_qubits: list[‘Value’] Return control quantum operands.control_value: int | Nonecustom_name: strimplementation_block: Block | Nonename: str Return a human-readable inverse operation name.num_control_qubits: intnum_target_qubits: intoperation_kind: OperationKind Return the operation kind.parameters: list[‘Value’] Return classical/object parameter operands.signature: Signature Return the operation signature.source_block: Block | Nonetarget_qubits: list[‘Value’] Return target quantum operands.
InvokeOperation [source]¶
class InvokeOperation(Operation)Represent a composite, stdlib, or oracle call.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | list[ValueLike] | Input values consumed by the call. |
results | list[ValueLike] | Output values produced by the call. |
target | CallableRef | Callable identity. |
transform | CallTransform | Direct, inverse, or controlled invocation. |
attrs | dict[str, Any] | Compile-time attributes for strategy, arity, and resource/lowering decisions. control_value is reserved for a controlled invocation’s LSB-first activation value. Values must be serializer-friendly. |
definition | CallableDef | None | Optional callable definition. |
Constructor¶
def __init__(
self,
operands: Sequence[ValueLike] | None = None,
results: Sequence[ValueLike] | None = None,
*,
target: CallableRef | None = None,
transform: CallTransform = CallTransform.DIRECT,
attrs: dict[str, Any] | None = None,
definition: CallableDef | None = None,
) -> NoneInitialize an invocation operation.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | Sequence[ValueLike] | None | Input values consumed by the call. Defaults to None, meaning no operands. |
results | Sequence[ValueLike] | None | Output values produced by the call. Defaults to None, meaning no results. |
target | CallableRef | None | Callable identity. Defaults to an anonymous user callable when omitted. |
transform | CallTransform | Requested call transform. Defaults to CallTransform.DIRECT. |
attrs | dict[str, Any] | None | Serializer-friendly call attributes. Defaults to an empty dict. |
definition | CallableDef | None | Callable definition. Defaults to None, in which case one is created from target. |
Raises:
TypeError— If a controlled invocation’scontrol_valueor an Oracle control-partition field has an invalid Python type.ValueError— Ifcontrol_valueis used on a non-controlled call or does not fit the controlled invocation’s width, or if Oracle invocation and definition control metadata disagree.
Attributes¶
attrs: dict[str, Any]body: Block | None Return the callable’s default body from its definition.body_ref: CallableBodyRef | None Return the callable’s deferred body reference.control_qubits: list[‘Value’] Return the control-qubit operands.control_value: int | None Return the controlled invocation’s activation value.custom_name: str Return the display name for custom callable boxes.default_policy: CallPolicy Return the callable’s default lowering policy.definition: CallableDef | Noneeffects: ‘KernelEffect’ Return cached effects of relevant callable implementations.gate_type: CompositeGateType Return the standard composite classification for this invocation.measurement_result_indices: frozenset[int] Return a conservative union of measurement-derived results.name: str Return the display name for this invocation.num_added_control_qubits: int Return controls introduced by a frontend control transform.num_body_external_control_qubits: int Return control operands generic lowering adds outside a base body.num_control_qubits: int Return the number of leading control-qubit operands.num_declared_control_qubits: int Return controls included in an opaque Oracle’s base definition.num_target_qubits: int Return the number of target-qubit operands.operandsoperation_kind: OperationKind Return the operation kind.parameters: list[‘Value’] Return non-qubit parameter operands.resultssignature: Signature Return the operation signature.strategy_name: str | None Return the selected lowering/resource strategy name.target: CallableReftarget_qubits: list[‘Value’] Return the target-qubit operands.transform: CallTransform
Methods¶
body_for_transform¶
def body_for_transform(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> tuple[Block | None, CallTransform]Select a body and report the transform it already realizes.
A controlled-inverse invocation may reuse an explicitly registered inverse body when no implementation realizes both transforms. Keeping that fallback in the IR operation gives emitters and static analyses one selection rule while still letting each consumer apply the remaining coherent controls in its own representation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None. |
strategy | str | None | Strategy name to match. Defaults to the invocation’s strategy_name attribute. |
Returns:
Block | None — tuple[Block | None, CallTransform]: Selected body and the transform
CallTransform — already implemented by that body. The callable’s direct body is
tuple[Block | None, CallTransform] — returned with DIRECT when no transform-specific body matches.
Raises:
ValueError— If the selected body disagrees with the invocation’s input or output contract.
effective_body¶
def effective_body(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> Block | NoneReturn the implementation body selected for this invocation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None. |
strategy | str | None | Strategy name to match. Defaults to the invocation’s strategy_name attribute. |
Returns:
Block | None — Block | None: Selected implementation body, or the callable’s
Block | None — default body when no transform-specific implementation exists.
Block | None — A compiler may synthesize inverse or controlled behavior from this
Block | None — fallback body.
implementation_for¶
def implementation_for(
self,
*,
backend: str | None = None,
strategy: str | None = None,
require_body: bool = False,
) -> CallableImplementation | NoneReturn the selected implementation for this invocation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None, which only selects backend-generic implementations. |
strategy | str | None | Strategy name to match. Defaults to None, meaning the invocation’s strategy_name attribute is used. |
require_body | bool | Whether candidates without an IR body should be excluded before ranking. Defaults to False. |
Returns:
CallableImplementation | None — CallableImplementation | None: Matching implementation candidate,
CallableImplementation | None — or None when the callable definition has no match.
measurement_result_indices_for¶
def measurement_result_indices_for(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> frozenset[int]Return measurement-derived results for one selected implementation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name used for implementation selection. Defaults to None. |
strategy | str | None | Strategy name used for implementation selection. Defaults to the invocation’s strategy_name. |
Returns:
frozenset[int] — frozenset[int]: Caller-local result positions derived from
measurement in the selected body.
Raises:
ValueError— If the selected body disagrees with the invocation’s input or output contract.
select_body¶
def select_body(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> CallableBodySelectionSelect and validate the composable body for this invocation.
The result carries the transform already realized by the body and the exact call-site values that bind to it. Consumers therefore cannot independently disagree about whether an invocation’s control prefix belongs to the selected implementation ABI.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None. |
strategy | str | None | Strategy name to match. Defaults to the invocation’s strategy_name attribute. |
Returns:
CallableBodySelection — Validated body, realized transform, and
CallableBodySelection — aligned call-site operands and results.
Raises:
ValueError— If the selected body disagrees with the invocation’s input or output contract.
KernelEffect [source]¶
class KernelEffect(enum.Flag)Describe non-unitary behavior reachable from a kernel body.
KernelEffect.NONE is the empty effect set and denotes unitary behavior.
Flags compose with bitwise union so one kernel can expose measurement,
reset, and measurement-backed feed-forward together.
Attributes¶
FEED_FORWARDMEASUREMENTNONERESETis_unitary: bool Return whether this is the empty effect set.
Methods¶
labels¶
def labels(self) -> tuple[str, ...]Return stable effect names for diagnostics and serialization.
Returns:
tuple[str, ...] — tuple[str, ...]: Active flag names in declaration order.
ResetOperation [source]¶
class ResetOperation(Operation)Reset a qubit to the |0> state and return the fresh handle.
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
SelectOperation [source]¶
class SelectOperation(Operation)Quantum multiplexer: apply case_blocks[i] when the index reads i.
Concrete operand layout:
[idx_0, ..., idx_{k-1}, tgt_0, ..., tgt_m, params...].
Symbolic-width operand layout:
[idx_arg_0, ..., idx_arg_{a-1}, tgt_0, ..., tgt_m, params...].
Results mirror the quantum operand grouping.
A concrete index register is normalized to one scalar Qubit operand
per physical index qubit. A symbolic-width register instead retains each
leading caller argument as one scalar or array operand until its bound
shape is known. Whole-Vector[Qubit] / scalar targets follow and keep
their shapes, and classical parameters shared across every case come last.
Index bit order is LSB-first: idx_0 is the least-significant
bit, matching Qamomile’s qubit-zero convention. Case i is selected
when index qubit j reads bit j of i. len(case_blocks)
need not be a power of two; index values >= len(case_blocks) apply
no operation (identity).
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_index_qubits: int | Value = 0,
case_blocks: list[Block] = list(),
num_index_args: int = 0,
case_callable_attrs: list[dict[str, Any]] = list(),
) -> NoneAttributes¶
case_blocks: list[Block]case_callable_attrs: list[dict[str, Any]]index_operands: list[Value] Return the grouped index-prefix operands.is_symbolic_num_index_qubits: bool Return whether the index width is a symbolic IR value.num_cases: int Return the number of selectable cases.num_index_args: intnum_index_qubits: int | Valueoperation_kind: OperationKind Return the operation kind.param_operands: list[Value] Return the shared classical parameter operands.signature: Signature Return the operation signature.target_operands: list[Value] Return the quantum target operands applied by every case.
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Return every value consumed by the SELECT operation.
Returns:
list[ValueBase] — list[ValueBase]: Ordinary operands plus the symbolic index-width
value when present.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationReplace operand and symbolic-width values by UUID.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | dict[str, ValueBase] | UUID-keyed replacement values. |
Returns:
Operation — Rebuilt SELECT operation with matching values replaced.
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,
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_args: tuple[RegionArg, ...] = (),
captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
captures: tuple[ValueBase, ...]loop_carried_rebinds: tuple[LoopCarriedRebind, ...]max_iterations: int | Noneoperation_kind: OperationKindoperations: list[Operation]region_args: tuple[RegionArg, ...]signature: Signature
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include rebind records and region args for cloning/substitution.
Same rationale as ForOperation.all_input_values: rebind
records and region arguments reference body/pre-loop values by
identity, so inline cloning must remap them in lockstep with
body operands.
Returns:
list[ValueBase] — list[ValueBase]: Base input values plus rebind-record and
region-argument values.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the while body with explicit boundary values.
Returns:
tuple[Region, ...] — tuple[Region, ...]: One body region whose block arguments and
yields are aligned with region_args. The updated
condition, when present, is appended as the final yield.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operationrebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild the while body and its complete boundary interface.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Exactly one replacement body region. |
Returns:
Operation — Rebuilt while operation.
Raises:
ValueError— If arity or boundary value kinds are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationSubstitute operand, rebind-record, and region-arg values.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | dict[str, ValueBase] | UUID-keyed substitution map. |
Returns:
Operation — The rewritten operation.
qamomile.circuit.ir.operation¶
Operation hierarchy of the qamomile IR.
Design center¶
Every IR node is an Operation (operation.py): a dataclass with
operands / results lists of SSA-like Values, a declared
Signature, and an OperationKind (QUANTUM / CLASSICAL / HYBRID /
CONTROL) that drives classical/quantum segmentation. Operations are
data, not behavior — passes rewrite them; backends interpret them at
emit time.
Design principles¶
Stay as abstract as the program semantics allow. An operation expresses what the program means, never how a backend realizes it.
MeasureVectorOperationis one op for a whole Vector — never N per-qubitMeasureOperations at IR level; per-qubit expansion is an emit-time backend concern.MeasureQFixedOperationsits even higher (HYBRID measure + classical decode) and is split only whenplan’s segmentation forces it. Pre-expanding an abstract concept into per-element / per-qubit ops here is a design regression.Generic value-access protocol. Passes reach Values only through
Operation.all_input_values()/replace_values(). Subclasses that carry extra Value fields outsideoperands(e.g.ControlledUOperation.power, loop bounds) override both, so generic passes need no per-subclass special cases. A new operation with extra Value fields MUST override these or passes will silently miss them.Explicit
Regionprotocol for control flow. For / ForItems / If / While (control_flow.py) expose operations, block arguments, captures, and yields throughnested_regions()/rebuild_regions(); passes recurse through this protocol instead of isinstance chains, so new control-flow ops cannot be missed.Loop-carried classical scalars are explicit
RegionArgs (init/block_arg/yielded/result, in the style of MLIRscf.foriter_args/yield) on For / ForItems / While, making the carried dependency visible to dependency analysis.Composite gates and callables stay boxed. QFT / QPE / user kernels are
InvokeOperations referencing aCallableDef(callable.py) with an optionalbody, alternativeimplementations, and an optional bodylessopaque_cost; whether a backend emits a native gate, the embedded body, or a shared decomposition is decided at emit time, not here.Typed construction over raw operand lists.
GateOperationoffersrotation()/fixed()factories that keep theta as the last operand, plustheta/qubit_operandsaccessors for typed read access.
Overview¶
| Function | Description |
|---|---|
validate_region_args | Validate the SSA identities owned by a loop’s region arguments. |
| Class | Description |
|---|---|
BranchRebind | Trace-time record of a quantum variable rebound inside an if branch. |
CallPolicy | Describe the default lowering policy for a callable call. |
CallTransform | Describe the requested transform of a callable implementation. |
CallableBodyRef | Reference a callable body that can be materialized later. |
CallableDef | Describe a compiler-facing callable definition. |
CallableImplementation | Describe one implementation candidate for a callable. |
CallableRef | Identify a callable independently of its Python object. |
CastOperation | Type cast operation for creating aliases over the same quantum resources. |
CompositeGateType | Classify standard boxed quantum callables. |
ConcreteControlledU | Controlled-U with concrete (int) number of controls. |
ControlledUOperation | Base class for controlled-U operations. |
DecodeQFixedOperation | Decode measured bits to float (classical operation). |
DictGetItemOperation | Look up one entry of a Dict by a (possibly symbolic) key. |
ExpvalOp | Expectation value operation. |
ForItemsOperation | Represents iteration over dict/iterable items. |
GateOperation | Quantum gate operation. |
GateOperationType | |
GlobalPhaseOperation | Multiply the complete quantum state by exp(i * phase). |
HasNestedOps | Mixin for operations that contain nested operation lists. |
InverseBlockOperation | Represent an inverse qkernel/block as a first-class IR operation. |
InvokeOperation | Represent a composite, stdlib, or oracle call. |
LoopCarriedRebind | Trace-time record of a variable rebound inside a loop body. |
MeasureOperation | |
MeasureQFixedOperation | Measure a quantum fixed-point number. |
MeasureVectorOperation | Measure a vector of qubits. |
Operation | |
ProjectOperation | Project a qubit in one Pauli basis and keep the projected state. |
Region | Expose one structured-control region through a uniform interface. |
RegionArg | Explicit loop-carried value on a loop operation (MLIR-style iter_arg). |
ReleaseSliceViewOperation | Mark a slice view’s borrow as explicitly returned to its parent. |
ResetOperation | Reset a qubit to the |0> state and return the fresh handle. |
ReturnOperation | Explicit return operation marking the end of a block with return values. |
ReturnQuantumArrayElementOperation | Validate a branch-selected quantum element’s array return at emit time. |
SelectOperation | Quantum multiplexer: apply case_blocks[i] when the index reads i. |
SliceArrayOperation | Construct a strided view of an ArrayValue. |
StoreArrayElementOperation | Store a classical scalar into one element of a classical array. |
SymbolicControlledU | Controlled-U with symbolic (Value) number of controls. |
Functions¶
validate_region_args [source]¶
def validate_region_args(op: ForOperation | ForItemsOperation | WhileOperation) -> tuple[RegionArg, ...]Validate the SSA identities owned by a loop’s region arguments.
A loop owns several definition namespaces: its iteration variables,
every RegionArg.block_arg, and every RegionArg.result. Those
identities must be pairwise disjoint. Otherwise different stages can
assign incompatible meanings to one UUID: a UUID-keyed environment has
only one slot, so binding either the iteration variable or the carried
value overwrites the other and makes both reads observe the same value.
Parameters:
| Name | Type | Description |
|---|---|---|
op | ForOperation | ForItemsOperation | WhileOperation | Loop operation whose region arguments should be validated. |
Returns:
tuple[RegionArg, ...] — tuple[RegionArg, ...]: The validated op.region_args tuple.
Raises:
ValueError— If result counts or positions disagree, slot types differ, or any loop-owned definition identity collides with another definition or with a region initializer/body yield.
Classes¶
BranchRebind [source]¶
class BranchRebindTrace-time record of a quantum variable rebound inside an if branch.
The frontend’s branch tracing merges only the new branch values
through merge operations; when both branches rebind a variable, the
value the variable held before the branch no longer appears anywhere
in the IfOperation. These records preserve that pre-branch
binding so the transpiler’s control-flow discard check
(reject_control_flow_quantum_discard in
qamomile.circuit.transpiler.passes.analyze) can verify that the
pre-branch quantum state is consumed or carried on every runtime
execution path instead of being silently dropped.
Constructor¶
def __init__(
self,
var_name: str,
before: Value,
rebound_in_true: bool,
rebound_in_false: bool,
) -> NoneAttributes¶
before: Valuerebound_in_false: boolrebound_in_true: boolvar_name: str
CallPolicy [source]¶
class CallPolicy(enum.Enum)Describe the default lowering policy for a callable call.
Attributes¶
INLINENATIVE_FIRSTPRESERVE_BOX
CallTransform [source]¶
class CallTransform(enum.Enum)Describe the requested transform of a callable implementation.
Attributes¶
CONTROLLEDCONTROLLED_INVERSEDIRECTINVERSEis_controlled: bool Return whether the transform adds coherent controls.is_inverse: bool Return whether the transform requests inverse application.
Methods¶
inverted¶
def inverted(self) -> CallTransformToggle inverse application while preserving coherent control.
Returns:
CallTransform — Transform with the inverse component toggled.
CallableBodyRef [source]¶
class CallableBodyRefReference a callable body that can be materialized later.
Parameters:
| Name | Type | Description |
|---|---|---|
ref | CallableRef | Callable whose standard body is referenced. |
kind | str | Body-reference kind, such as "standard" or "symbolic_vector". Defaults to "standard". |
attrs | dict[str, Any] | Serializer-friendly body-materialization attributes. Defaults to an empty dict. |
Constructor¶
def __init__(
self,
ref: CallableRef,
kind: str = 'standard',
attrs: dict[str, Any] = dict(),
) -> NoneAttributes¶
attrs: dict[str, Any]kind: strref: CallableRef
CallableDef [source]¶
class CallableDefDescribe a compiler-facing callable definition.
Parameters:
| Name | Type | Description |
|---|---|---|
ref | CallableRef | Stable callable identity. |
signature | Signature | None | Optional callable signature. |
body | Block | None | Standard IR body, or None for opaque calls. |
body_ref | CallableBodyRef | None | Reference to a standard body that is intentionally deferred. Defaults to None. |
implementations | list[CallableImplementation] | Alternative native or strategy-specific implementations. |
opaque_cost | Any | None | Explicit cost contract for a bodyless callable. Body-backed callables must leave this as None. |
default_policy | CallPolicy | Default call lowering policy. |
attrs | dict[str, Any] | Serializer-friendly definition metadata. |
Constructor¶
def __init__(
self,
ref: CallableRef,
signature: Signature | None = None,
body: Block | None = None,
body_ref: CallableBodyRef | None = None,
implementations: list[CallableImplementation] = list(),
opaque_cost: Any | None = None,
default_policy: CallPolicy = CallPolicy.INLINE,
attrs: dict[str, Any] = dict(),
) -> NoneAttributes¶
attrs: dict[str, Any]body: Block | Nonebody_ref: CallableBodyRef | Nonedefault_policy: CallPolicyimplementations: list[CallableImplementation]opaque_cost: Any | Noneref: CallableRefsignature: Signature | None
Methods¶
effects_for¶
def effects_for(self, transform: CallTransform = CallTransform.DIRECT) -> 'KernelEffect'Return cached semantic effects for one call transform.
Parameters:
| Name | Type | Description |
|---|---|---|
transform | CallTransform | Requested call transform. Defaults to CallTransform.DIRECT. |
Returns:
'KernelEffect' — Union of relevant implementation-body effects.
implementation_for¶
def implementation_for(
self,
*,
transform: CallTransform = CallTransform.DIRECT,
backend: str | None = None,
strategy: str | None = None,
require_body: bool = False,
) -> CallableImplementation | NoneReturn the best matching implementation candidate.
Parameters:
| Name | Type | Description |
|---|---|---|
transform | CallTransform | Requested call transform. |
backend | str | None | Requested backend name. |
strategy | str | None | Requested strategy name. |
require_body | bool | Whether candidates without an IR body should be excluded before ranking. Defaults to False. |
Returns:
CallableImplementation | None — CallableImplementation | None: Matching implementation, if any.
measurement_result_indices_for¶
def measurement_result_indices_for(self, transform: CallTransform = CallTransform.DIRECT) -> frozenset[int]Return measured result positions for one call transform.
Parameters:
| Name | Type | Description |
|---|---|---|
transform | CallTransform | Requested call transform. Defaults to CallTransform.DIRECT. |
Returns:
frozenset[int] — frozenset[int]: Result indices carrying measurement provenance.
CallableImplementation [source]¶
class CallableImplementationDescribe one implementation candidate for a callable.
Parameters:
| Name | Type | Description |
|---|---|---|
transform | CallTransform | Transform this implementation realizes. |
backend | str | None | Backend name for native implementations. |
strategy | str | None | Strategy name such as "standard". |
body | Block | None | IR implementation body. A transform-specific body realizes that transform completely; a controlled body therefore includes control operands in its signature. |
body_ref | CallableBodyRef | None | Reference to a body that should be materialized by a later resolver. Defaults to None. |
emitter | Any | Backend-native emitter object. |
attrs | dict[str, Any] | Serializer-friendly implementation metadata. |
Constructor¶
def __init__(
self,
transform: CallTransform = CallTransform.DIRECT,
backend: str | None = None,
strategy: str | None = None,
body: Block | None = None,
body_ref: CallableBodyRef | None = None,
emitter: Any = None,
attrs: dict[str, Any] = dict(),
) -> NoneAttributes¶
attrs: dict[str, Any]backend: str | Nonebody: Block | Nonebody_ref: CallableBodyRef | Noneemitter: Anystrategy: str | Nonetransform: CallTransform
CallableRef [source]¶
class CallableRefIdentify a callable independently of its Python object.
Parameters:
| Name | Type | Description |
|---|---|---|
namespace | str | Stable namespace such as "qamomile.stdlib" or "user". |
name | str | Stable callable name within the namespace. |
version | str | Schema or behavior version for the callable. |
Constructor¶
def __init__(self, namespace: str, name: str, version: str = '1') -> NoneAttributes¶
name: strnamespace: strversion: str
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:
Vector[Qubit] -> QFixed (after QPE, for phase measurement)
Vector[Qubit] -> QUInt (for quantum arithmetic)
QUInt -> QFixed (reinterpret bits with different encoding)
QFixed -> QUInt (reinterpret bits with different encoding)
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(),
) -> NoneAttributes¶
num_qubits: int Number of qubits involved in the cast.operation_kind: OperationKind Cast stays in the same segment as its source (QUANTUM for quantum types).qubit_mapping: list[str]signature: Signature Return the type signature of this cast operation.source_type: ValueType | Nonetarget_type: ValueType | None
CompositeGateType [source]¶
class CompositeGateType(enum.Enum)Classify standard boxed quantum callables.
Attributes¶
CUSTOMIQFTQFTQPE
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,
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] = dict(),
control_value: int | None = None,
) -> NoneAttributes¶
control_operands: list[Value]control_value: int | Nonenum_controls: intparam_operands: list[Value] Get classical/object operands after the concrete control prefix.signature: Signature Build the concrete controlled call signature.target_operands: list[Value] Return the wrapped callable’s target and parameter operands.
ControlledUOperation [source]¶
class ControlledUOperation(Operation)Base class for controlled-U operations.
Two concrete subclasses handle distinct operand layouts:
ConcreteControlledU: Fixednum_controls: int, individual qubit operands.SymbolicControlledU: Symbolicnum_controls: Value, vector-based control operands; optionalcontrol_indicesselects a subset of the control vector to act as controls (the rest pass through).
All isinstance(op, ControlledUOperation) checks match every subclass.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
power: int | Value = 1,
block: Block | None = None,
num_controls: int | Value = 1,
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] = dict(),
) -> NoneAttributes¶
block: Block | Nonebody_operands: list[Value] Get the wrapped callable’s complete argument list.callable_attrs: dict[str, Any]callable_ref: CallableRef | Nonecontrol_operands: list[Value] Get the control qubit values.is_symbolic_num_controls: bool Whether num_controls is symbolic (Value) rather than concrete.num_controls: int | Valueoperation_kind: OperationKindparam_operands: list[Value] Get the controlled operation’s classical/object arguments.power: int | Valuesignature: Signaturetarget_operands: list[Value] Get the target qubit values (arguments to U).
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationDecodeQFixedOperation [source]¶
class DecodeQFixedOperation(Operation)Decode measured bits to float (classical operation).
This operation converts a sequence of classical bits from qubit measurements into a floating-point number using fixed-point encoding.
The decoding formula for least-significant-first storage:
float_value = Σ bit[i] * 2^(int_bits - num_bits + i)
For QPE phase (int_bits=0):
bit[0] has weight 2**(-num_bits) and bit[-1] has weight 0.5.
Example:
bits = [1, 0, 1] with int_bits=0
→ 0.101 (MSB-first display) = 0.5 + 0.125 = 0.625operands: [ArrayValue of bits (vec[bit])] results: [Float value]
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_bits: int = 0,
int_bits: int = 0,
) -> NoneAttributes¶
int_bits: intnum_bits: intoperation_kind: OperationKindsignature: Signature
DictGetItemOperation [source]¶
class DictGetItemOperation(Operation)Look up one entry of a Dict by a (possibly symbolic) key.
This is the IR form of d[key] on a Dict handle. The key
components may be symbolic (e.g. loop variables of a for-items
loop); the lookup is resolved at emit time when the key values and
the dict’s bound data are both concrete.
operands: [DictValue, *key_component_values] results: [looked-up scalar value]
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
key_arity: int = 1,
) -> NoneAttributes¶
dict_value: Value Value: The DictValue being indexed (operands[0]).key_arity: intkey_values: tuple[Value, ...] tuple[Value, ...]: The key component values.operation_kind: OperationKindsignature: Signature
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:
Input: quantum state (qubits) + Observable reference
Output: classical Float (expectation value)
Example IR:
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
hamiltonian: Value Alias for observable (deprecated, use observable instead).observable: Value The Observable parameter operand.operation_kind: OperationKind ExpvalOp is HYBRID - bridges quantum state to classical value.output: Value The expectation value result.qubits: Value The quantum register operand.signature: Signature
ForItemsOperation [source]¶
class ForItemsOperation(HasNestedOps, Operation)Represents iteration over dict/iterable items.
Example:
for (i, j), Jij in qmc.items(ising):
bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
key_vars: list[str] = list(),
value_var: str = '',
key_is_vector: bool = False,
key_var_values: tuple[Value, ...] | None = None,
value_var_value: Value | None = None,
operations: list[Operation] = list(),
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_args: tuple[RegionArg, ...] = (),
captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
captures: tuple[ValueBase, ...]key_is_vector: boolkey_var_values: tuple[Value, ...] | Nonekey_vars: list[str]loop_carried_rebinds: tuple[LoopCarriedRebind, ...]operation_kind: OperationKindoperations: list[Operation]region_args: tuple[RegionArg, ...]signature: Signaturevalue_var: strvalue_var_value: Value | None
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include the per-key/value Value fields for cloning/substitution.
Same rationale as ForOperation.all_input_values: keep the IR
identity fields in lockstep with body references so UUID-keyed
lookups stay valid after inline cloning. Loop-carried rebind
records and region arguments are included for the same reason.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the items-loop body with its explicit interface.
Returns:
tuple[Region, ...] — tuple[Region, ...]: One body region containing key/value formals,
carried-value formals, captures, and carried yields.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operationrebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild the items-loop body and complete boundary interface.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Exactly one replacement body region. |
Returns:
Operation — Rebuilt items-loop operation.
Raises:
ValueError— If arity or boundary value kinds are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationGateOperation [source]¶
class GateOperation(Operation)Quantum gate operation.
For rotation gates (RX, RY, RZ, P, CP, RZZ), the angle parameter is
stored as the last element of operands. Use the theta
property for typed read access and the rotation / fixed factory
class-methods for type-safe construction.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
gate_type: GateOperationType | None = None,
) -> NoneAttributes¶
gate_type: GateOperationType | Noneoperation_kind: OperationKindqubit_operands: list[Value] Qubit operands (excluding the theta parameter if present).signature: Signaturetheta: Value | None Angle parameter for rotation gates, orNonefor fixed gates.
Methods¶
fixed¶
@classmethod
def fixed(
cls,
gate_type: GateOperationType,
qubits: list[Value],
results: list[Value],
) -> 'GateOperation'Create a fixed gate (H, X, CX, SWAP, …) with no angle parameter.
rotation¶
@classmethod
def rotation(
cls,
gate_type: GateOperationType,
qubits: list[Value],
theta: Value,
results: list[Value],
) -> 'GateOperation'Create a rotation gate (RX, RY, RZ, P, CP, RZZ) with an angle.
GateOperationType [source]¶
class GateOperationType(enum.Enum)Attributes¶
CPCXCZHPRXRYRZRZZSSDGSWAPTTDGTOFFOLIXYZ
GlobalPhaseOperation [source]¶
class GlobalPhaseOperation(Operation)Multiply the complete quantum state by exp(i * phase).
Global phase has no target qubit and does not create a new quantum value. Keeping the phase as the operation’s sole ordinary operand lets generic IR passes substitute, serialize, and analyze it without a special value-field protocol. A surrounding controlled-unitary lowering turns the operation into an observable phase gate on the accumulated controls.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | list[Value] | Exactly one scalar FloatType phase angle in radians. |
results | list[Value] | Must be empty because global phase changes no qubit identity. |
Raises:
ValueError— If the operand/result layout is invalid or the phase is not a scalarFloatTypevalue.
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKind Classify global phase as a quantum operation.phase: Value Return the scalar phase-angle operand.signature: Signature Return the zero-qubit operation signature.
HasNestedOps [source]¶
class HasNestedOpsMixin for operations that contain nested operation lists.
nested_regions() is the canonical traversal API because it exposes
operations together with block arguments, captures, and yields.
nested_op_lists() / rebuild_nested() remain compatibility helpers
for specialized consumers while they migrate to the region interface.
Methods¶
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]Return all nested operation lists in this control flow op.
nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return uniform views of every nested operation region.
Subclasses with explicit block arguments, captures, or yields override
this method. The fallback keeps legacy operation-owned blocks visible
while consumers migrate from nested_op_lists.
Returns:
tuple[Region, ...] — tuple[Region, ...]: Region views in nested_op_lists order.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> OperationReturn a copy with nested operation lists replaced.
new_lists must have the same length/order as nested_op_lists().
rebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationReturn a copy with replacement region operation sequences.
Concrete control-flow operations override this method to rebuild both their body operations and boundary values. The fallback supports legacy region owners whose boundary remains operation-specific.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Replacement regions in nested_regions order. |
Returns:
Operation — Rebuilt control-flow operation.
Raises:
ValueError— If the replacement region count differs from the operation’s current region count.
InverseBlockOperation [source]¶
class InverseBlockOperation(Operation)Represent an inverse qkernel/block as a first-class IR operation.
The operation stores both the original forward block and a Qamomile-built
inverse implementation block. Emitters may use source_block with a
backend-native inverse/adjoint primitive, then fall back to
implementation_block when native inversion is unavailable.
Operands are ordered as scalar control qubits, target quantum operands,
then classical/object parameters. Results mirror the quantum operand
layout: control results first, then one target result per target operand.
Vector target operands therefore count as one operand/result while
contributing their scalar width to num_target_qubits.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_control_qubits: int = 0,
num_target_qubits: int = 0,
custom_name: str = '',
source_block: Block | None = None,
implementation_block: Block | None = None,
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] = dict(),
control_value: int | None = None,
) -> NoneAttributes¶
callable_attrs: dict[str, Any]callable_ref: CallableRef | Nonecontrol_qubits: list[‘Value’] Return control quantum operands.control_value: int | Nonecustom_name: strimplementation_block: Block | Nonename: str Return a human-readable inverse operation name.num_control_qubits: intnum_target_qubits: intoperation_kind: OperationKind Return the operation kind.parameters: list[‘Value’] Return classical/object parameter operands.signature: Signature Return the operation signature.source_block: Block | Nonetarget_qubits: list[‘Value’] Return target quantum operands.
InvokeOperation [source]¶
class InvokeOperation(Operation)Represent a composite, stdlib, or oracle call.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | list[ValueLike] | Input values consumed by the call. |
results | list[ValueLike] | Output values produced by the call. |
target | CallableRef | Callable identity. |
transform | CallTransform | Direct, inverse, or controlled invocation. |
attrs | dict[str, Any] | Compile-time attributes for strategy, arity, and resource/lowering decisions. control_value is reserved for a controlled invocation’s LSB-first activation value. Values must be serializer-friendly. |
definition | CallableDef | None | Optional callable definition. |
Constructor¶
def __init__(
self,
operands: Sequence[ValueLike] | None = None,
results: Sequence[ValueLike] | None = None,
*,
target: CallableRef | None = None,
transform: CallTransform = CallTransform.DIRECT,
attrs: dict[str, Any] | None = None,
definition: CallableDef | None = None,
) -> NoneInitialize an invocation operation.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | Sequence[ValueLike] | None | Input values consumed by the call. Defaults to None, meaning no operands. |
results | Sequence[ValueLike] | None | Output values produced by the call. Defaults to None, meaning no results. |
target | CallableRef | None | Callable identity. Defaults to an anonymous user callable when omitted. |
transform | CallTransform | Requested call transform. Defaults to CallTransform.DIRECT. |
attrs | dict[str, Any] | None | Serializer-friendly call attributes. Defaults to an empty dict. |
definition | CallableDef | None | Callable definition. Defaults to None, in which case one is created from target. |
Raises:
TypeError— If a controlled invocation’scontrol_valueor an Oracle control-partition field has an invalid Python type.ValueError— Ifcontrol_valueis used on a non-controlled call or does not fit the controlled invocation’s width, or if Oracle invocation and definition control metadata disagree.
Attributes¶
attrs: dict[str, Any]body: Block | None Return the callable’s default body from its definition.body_ref: CallableBodyRef | None Return the callable’s deferred body reference.control_qubits: list[‘Value’] Return the control-qubit operands.control_value: int | None Return the controlled invocation’s activation value.custom_name: str Return the display name for custom callable boxes.default_policy: CallPolicy Return the callable’s default lowering policy.definition: CallableDef | Noneeffects: ‘KernelEffect’ Return cached effects of relevant callable implementations.gate_type: CompositeGateType Return the standard composite classification for this invocation.measurement_result_indices: frozenset[int] Return a conservative union of measurement-derived results.name: str Return the display name for this invocation.num_added_control_qubits: int Return controls introduced by a frontend control transform.num_body_external_control_qubits: int Return control operands generic lowering adds outside a base body.num_control_qubits: int Return the number of leading control-qubit operands.num_declared_control_qubits: int Return controls included in an opaque Oracle’s base definition.num_target_qubits: int Return the number of target-qubit operands.operandsoperation_kind: OperationKind Return the operation kind.parameters: list[‘Value’] Return non-qubit parameter operands.resultssignature: Signature Return the operation signature.strategy_name: str | None Return the selected lowering/resource strategy name.target: CallableReftarget_qubits: list[‘Value’] Return the target-qubit operands.transform: CallTransform
Methods¶
body_for_transform¶
def body_for_transform(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> tuple[Block | None, CallTransform]Select a body and report the transform it already realizes.
A controlled-inverse invocation may reuse an explicitly registered inverse body when no implementation realizes both transforms. Keeping that fallback in the IR operation gives emitters and static analyses one selection rule while still letting each consumer apply the remaining coherent controls in its own representation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None. |
strategy | str | None | Strategy name to match. Defaults to the invocation’s strategy_name attribute. |
Returns:
Block | None — tuple[Block | None, CallTransform]: Selected body and the transform
CallTransform — already implemented by that body. The callable’s direct body is
tuple[Block | None, CallTransform] — returned with DIRECT when no transform-specific body matches.
Raises:
ValueError— If the selected body disagrees with the invocation’s input or output contract.
effective_body¶
def effective_body(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> Block | NoneReturn the implementation body selected for this invocation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None. |
strategy | str | None | Strategy name to match. Defaults to the invocation’s strategy_name attribute. |
Returns:
Block | None — Block | None: Selected implementation body, or the callable’s
Block | None — default body when no transform-specific implementation exists.
Block | None — A compiler may synthesize inverse or controlled behavior from this
Block | None — fallback body.
implementation_for¶
def implementation_for(
self,
*,
backend: str | None = None,
strategy: str | None = None,
require_body: bool = False,
) -> CallableImplementation | NoneReturn the selected implementation for this invocation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None, which only selects backend-generic implementations. |
strategy | str | None | Strategy name to match. Defaults to None, meaning the invocation’s strategy_name attribute is used. |
require_body | bool | Whether candidates without an IR body should be excluded before ranking. Defaults to False. |
Returns:
CallableImplementation | None — CallableImplementation | None: Matching implementation candidate,
CallableImplementation | None — or None when the callable definition has no match.
measurement_result_indices_for¶
def measurement_result_indices_for(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> frozenset[int]Return measurement-derived results for one selected implementation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name used for implementation selection. Defaults to None. |
strategy | str | None | Strategy name used for implementation selection. Defaults to the invocation’s strategy_name. |
Returns:
frozenset[int] — frozenset[int]: Caller-local result positions derived from
measurement in the selected body.
Raises:
ValueError— If the selected body disagrees with the invocation’s input or output contract.
select_body¶
def select_body(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> CallableBodySelectionSelect and validate the composable body for this invocation.
The result carries the transform already realized by the body and the exact call-site values that bind to it. Consumers therefore cannot independently disagree about whether an invocation’s control prefix belongs to the selected implementation ABI.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None. |
strategy | str | None | Strategy name to match. Defaults to the invocation’s strategy_name attribute. |
Returns:
CallableBodySelection — Validated body, realized transform, and
CallableBodySelection — aligned call-site operands and results.
Raises:
ValueError— If the selected body disagrees with the invocation’s input or output contract.
LoopCarriedRebind [source]¶
class LoopCarriedRebindTrace-time record of a variable rebound inside a loop body.
Two rebind families share this record type, distinguished by the
type of before:
Classical scalar (
beforeclassical): the frontend traces a loop body exactly once, so a Python-level reassignment liketotal = total + iproduces IR whose right-hand side reads the fixed pre-loop value instead of the previous iteration’s value. Most such carries are now represented as explicitRegionArgs (see above) and are fully supported; a classical record is only created for the shapes region binding declines —while-body carries (a runtime while loop cannot be unrolled) and measurement-backedBitcarries — and the transpiler’s classical loop-carried check rejects those with a targeted error instead of silently miscompiling.Quantum (
beforequantum): the loop body left the variable bound to a different quantum resource (logical_idchange — a fresh allocation or another register, not a gate self-update). The transpiler’s control-flow discard check (reject_control_flow_quantum_discard) rejects the ones whose incoming state the body never consumes.
Constructor¶
def __init__(
self,
var_name: str,
before: ValueBase,
after: ValueBase,
before_synthesized: bool = False,
) -> NoneAttributes¶
after: ValueBasebefore: ValueBasebefore_synthesized: boolvar_name: str
MeasureOperation [source]¶
class MeasureOperation(Operation)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
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):
Qubits are stored least-significant first. For n qubits,
bit i has weight 2**(-n + i).
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_bits: int = 0,
int_bits: int = 0,
) -> NoneAttributes¶
int_bits: intnum_bits: intoperation_kind: OperationKindsignature: Signature
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()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
Operation [source]¶
class Operation(abc.ABC)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operands: list[Value]operation_kind: OperationKind Return the kind of this operation for classical/quantum classification.results: list[Value]signature: Signature
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]) -> OperationReturn a copy with all Values substituted via mapping.
Handles operands, results, and subclass-specific Value
fields. Subclasses override to handle their extra fields.
ProjectOperation [source]¶
class ProjectOperation(Operation)Project a qubit in one Pauli basis and keep the projected state.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
axis: str = 'z',
) -> NoneAttributes¶
axis: stroperation_kind: OperationKindsignature: Signature
Region [source]¶
class RegionExpose one structured-control region through a uniform interface.
This is a view over the existing semantic IR rather than a parallel value
system: every entry is an ordinary Qamomile ValueBase carrying the
current UUID identity. Control-flow operations remain the owners of the
stored fields and construct Region views through nested_regions.
Parameters:
| Name | Type | Description |
|---|---|---|
operations | tuple[Operation, ...] | Operations evaluated inside the region in program order. |
block_args | tuple[ValueBase, ...] | Values defined at region entry, such as a loop induction variable or carried-value formal. |
captures | tuple[ValueBase, ...] | Explicit outer-scope values read by the region, ordered by first use. |
yields | tuple[ValueBase, ...] | Values yielded at the region boundary in result-slot order. |
Constructor¶
def __init__(
self,
operations: tuple[Operation, ...],
block_args: tuple[ValueBase, ...] = (),
captures: tuple[ValueBase, ...] = (),
yields: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
block_args: tuple[ValueBase, ...]captures: tuple[ValueBase, ...]operations: tuple[Operation, ...]yields: tuple[ValueBase, ...]
RegionArg [source]¶
class RegionArgExplicit loop-carried value on a loop operation (MLIR-style iter_arg).
A RegionArg makes a loop-carried dependency explicit in the IR,
the way MLIR’s scf.for models iter_args / scf.yield:
On iteration 0 the body reads
block_argbound toinit.After each iteration,
block_argis rebound to that iteration’syieldedvalue.After the loop,
resultholds the final carried value (initwhen the loop ran zero iterations).
The loop body’s operations reference block_arg (the frontend
substitutes the traced pre-loop reads), and post-loop operations
reference result (the frontend rebinds the Python handle when it
closes the loop). result is also appended to the loop operation’s
results list so dependency analysis sees the loop as its
producer.
This subsumes the trace-once staleness that LoopCarriedRebind
records exist to reject: a rebind represented as a RegionArg is
a supported loop-carried value, not a miscompilation hazard.
Constructor¶
def __init__(
self,
var_name: str,
init: Value,
block_arg: Value,
yielded: Value,
result: Value,
) -> NoneAttributes¶
block_arg: Valueinit: Valueresult: Valuevar_name: stryielded: Value
ReleaseSliceViewOperation [source]¶
class ReleaseSliceViewOperation(Operation)Mark a slice view’s borrow as explicitly returned to its parent.
Emitted by :meth:Vector.__setitem__ when used with a slice index
(qs[a:b] = qmc.h(qs[a:b])). This op tells the post-fold
linearity checker
(:class:~qamomile.circuit.transpiler.passes.slice_borrow_check.SliceBorrowCheckPass)
that the view referenced in operands[0] no longer owns its
covered parent slots, mirroring the frontend’s
VectorView.consume(operation_name="slice assignment") borrow
release.
Like :class:SliceArrayOperation, this op is a declarative
classical-side marker that does not survive into the emit stream:
:class:~qamomile.circuit.transpiler.passes.strip_slice_ops.StripSliceArrayOpsPass
removes both :class:SliceArrayOperation and
:class:ReleaseSliceViewOperation after
:class:SliceBorrowCheckPass has observed them. Reaching emit
is a compiler-internal invariant violation and is rejected with a
RuntimeError from :mod:standard_emit.
Within a control-flow body (ForOperation / WhileOperation
/ IfOperation), this op only releases view borrows that were
created within the same body. Releasing a borrow that the
enclosing block has registered (an “outer-snapshot” borrow) is
rejected by SliceBorrowCheckPass with ValidationError — the
loop-merge semantics of the
pass cannot propagate entry deletions out of the body, so the only
way to keep the static check consistent is to forbid that pattern.
Example:
``qs[1:3] = qmc.h(qs[1:3])`` emits, after the broadcast loop::
ReleaseSliceViewOperation(
operands=[qmc_h_result_view], # slice_of=qs_value
results=[],
)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKind Release is classical — it updates borrow tracking metadata only.signature: Signature Return the type signature of this release operation.
ResetOperation [source]¶
class ResetOperation(Operation)Reset a qubit to the |0> state and return the fresh handle.
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
ReturnOperation [source]¶
class ReturnOperation(Operation)Explicit return operation marking the end of a block with return values.
This operation represents an explicit return statement in the IR. It takes the values to be returned as operands and produces no results (it is a terminal operation that transfers control flow back to the caller).
operands: [Value, ...] - The values to return (may be empty for void returns) results: [] - Always empty (terminal operation)
Example:
A function that returns two values (a UInt and a Float):
ReturnOperation(
operands=[uint_value, float_value],
results=[],
)
The signature would be:
operands=[ParamHint("return_0", UIntType()), ParamHint("return_1", FloatType())]
results=[]Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKind Return CLASSICAL as this is a control flow operation without quantum effects.signature: Signature Return the signature with operands for each return value and no results.
ReturnQuantumArrayElementOperation [source]¶
class ReturnQuantumArrayElementOperation(Operation)Validate a branch-selected quantum element’s array return at emit time.
Most quantum element assignments are verified structurally by the frontend and emit no IR. A compile-time conditional can instead select different element indices on its branches; only the unrolled emit context knows which source index survived. This operation carries both the requested target indices and the conditional source indices so emission can prove they resolve to the same physical slot before treating the assignment as a borrow return.
Operand convention:
[array, returned_qubit, *target_indices, *source_indices]. The
target and source halves have equal nonzero arity, inferred from the
operand count. The operation has no results and emits no backend gate.
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
array: ArrayValue Return the quantum array receiving the borrowed element.index_arity: int Return the number of target (and source) index operands.operation_kind: OperationKind Classify the return validator as a quantum operation.returned_value: Value Return the quantum value being returned.signature: Signature Return the deferred validator’s operand-only signature.source_indices: tuple[Value, ...] Return the branch-merged borrow-source indices.target_indices: tuple[Value, ...] Return the user-written assignment indices.
SelectOperation [source]¶
class SelectOperation(Operation)Quantum multiplexer: apply case_blocks[i] when the index reads i.
Concrete operand layout:
[idx_0, ..., idx_{k-1}, tgt_0, ..., tgt_m, params...].
Symbolic-width operand layout:
[idx_arg_0, ..., idx_arg_{a-1}, tgt_0, ..., tgt_m, params...].
Results mirror the quantum operand grouping.
A concrete index register is normalized to one scalar Qubit operand
per physical index qubit. A symbolic-width register instead retains each
leading caller argument as one scalar or array operand until its bound
shape is known. Whole-Vector[Qubit] / scalar targets follow and keep
their shapes, and classical parameters shared across every case come last.
Index bit order is LSB-first: idx_0 is the least-significant
bit, matching Qamomile’s qubit-zero convention. Case i is selected
when index qubit j reads bit j of i. len(case_blocks)
need not be a power of two; index values >= len(case_blocks) apply
no operation (identity).
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_index_qubits: int | Value = 0,
case_blocks: list[Block] = list(),
num_index_args: int = 0,
case_callable_attrs: list[dict[str, Any]] = list(),
) -> NoneAttributes¶
case_blocks: list[Block]case_callable_attrs: list[dict[str, Any]]index_operands: list[Value] Return the grouped index-prefix operands.is_symbolic_num_index_qubits: bool Return whether the index width is a symbolic IR value.num_cases: int Return the number of selectable cases.num_index_args: intnum_index_qubits: int | Valueoperation_kind: OperationKind Return the operation kind.param_operands: list[Value] Return the shared classical parameter operands.signature: Signature Return the operation signature.target_operands: list[Value] Return the quantum target operands applied by every case.
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Return every value consumed by the SELECT operation.
Returns:
list[ValueBase] — list[ValueBase]: Ordinary operands plus the symbolic index-width
value when present.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationReplace operand and symbolic-width values by UUID.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | dict[str, ValueBase] | UUID-keyed replacement values. |
Returns:
Operation — Rebuilt SELECT operation with matching values replaced.
SliceArrayOperation [source]¶
class SliceArrayOperation(Operation)Construct a strided view of an ArrayValue.
The op itself performs no quantum action — it records that the
result ArrayValue is a strided view of the operand parent
with the given start / step. The result’s
slice_of / slice_start / slice_step fields carry the
affine map used by the emit-time resolver.
SliceArrayOperation is classified as :attr:OperationKind.CLASSICAL
because slicing is pure index selection — no new quantum operation
is introduced. The pipeline keeps this op through
PartialEvaluationPass (which invokes
ConstantFoldingPass(..., strip_slice_ops=False)) so the
post-fold :class:~qamomile.circuit.transpiler.passes.slice_borrow_check.SliceBorrowCheckPass
can use it as a view-declaration marker; once that check has run,
StripSliceArrayOpsPass removes every SliceArrayOperation
/ ReleaseSliceViewOperation so segmentation
(:mod:~qamomile.circuit.transpiler.passes.separate) and the
downstream emit stage only see a pure quantum-op stream. By the
time :mod:~qamomile.circuit.transpiler.passes.separate runs the
op has therefore been stripped — reaching emit is a compiler-
internal invariant violation.
Example:
``q[1::2]`` on a ``Vector[Qubit]`` emits::
SliceArrayOperation(
operands=[q_value, uint_1, uint_2],
results=[sliced_value], # slice_of=q_value, slice_start=uint_1, slice_step=uint_2
)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKind Slice is classical — it selects indices without quantum action.signature: Signature Return the type signature of this slice operation.
StoreArrayElementOperation [source]¶
class StoreArrayElementOperation(Operation)Store a classical scalar into one element of a classical array.
This is the IR form of array[index] = value for classical element
types (Bit / UInt / Float). Classical values are freely
copyable, so the store is an ordinary SSA rewrite: the operation
consumes the current array version and produces a new ArrayValue
version (same logical_id, fresh uuid) whose contents equal the
input array with the addressed element replaced. Quantum arrays never
use this operation — qubit element assignment is the return half of
the borrow-return idiom and emits no IR.
The operation is evaluated in one of two places:
Compile time:
ConstantFoldingPassfolds the store when the source array contents, the index, and the stored value are all compile-time resolvable, attaching the updatedconst_arraymetadata to the result value.Runtime: otherwise the store executes host-side in a classical segment via
ClassicalExecutor(e.g. for measurement-derivedVector[Bit]contents). It must never reach a quantum segment; backend emit rejects it explicitly.
Operand convention:
operands: [array (ArrayValue), stored_value (Value), *index_values]
results: [new_array (ArrayValue)]
Example:
@qmc.qkernel
def k() -> qmc.Vector[qmc.Bit]:
qs = qmc.qubit_array(2, "qs")
qs[0] = qmc.x(qs[0])
bits = qmc.measure(qs)
bits[1] = bits[0] # emits StoreArrayElementOperation
return bitsConstructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
array: ArrayValue ArrayValue: The array version the store reads from.index_values: tuple[Value, ...] tuple[Value, ...]: The element indices being written.operation_kind: OperationKindsignature: Signature Return the operation’s dynamic array/qubit/index signature.stored_value: Value Value: The scalar being written into the array.
SymbolicControlledU [source]¶
class SymbolicControlledU(ControlledUOperation)Controlled-U with symbolic (Value) number of controls.
Operand layout: [ctrl_arg_0, ..., ctrl_arg_{k-1}, tgt_0, ..., tgt_m, params...]
Result layout: [ctrl_arg_0', ..., ctrl_arg_{k-1}', tgt_0', ..., tgt_m']
The number of control arguments k is recorded in
num_control_args; the default k = 1 corresponds to the
historical single-pool form (operands[0] is a
Vector[Qubit] / VectorView whose length equals
num_controls, or whose control_indices-selected subset
does). When k > 1 the control prefix is a heterogeneous
sequence of scalar Qubit values and ArrayValues whose
total qubit count is num_controls; the emit pass walks them
in order to recover the per-physical-qubit control set.
When control_indices is None the entire control prefix
is used as active controls (one-arg form: len(ctrl_vector) == num_controls; multi-arg form: the qubit-count sum of the
prefix args equals num_controls). When non-None, the
listed indices select exactly num_controls slots from a
single-arg pool to act as controls; combining
control_indices with the multi-arg control prefix is
rejected at frontend time.
Each control_indices entry is stored as a Value of
UIntType regardless of whether the frontend passed an
int literal or a UInt handle, so all downstream
value-substitution passes see a uniform shape.
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=(UIntType()), name=''))(),
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] = dict(),
control_indices: tuple[Value, ...] | None = None,
num_control_args: int = 1,
) -> NoneAttributes¶
control_indices: tuple[Value, ...] | Nonecontrol_operands: list[Value]is_symbolic_num_controls: boolnum_control_args: intnum_controls: Valueparam_operands: list[Value] Get classical/object operands after the symbolic control prefix.signature: Signaturetarget_operands: list[Value] Return the wrapped callable’s target and parameter operands.
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> Operationqamomile.circuit.ir.operation.arithmetic_operations¶
Overview¶
| Function | Description |
|---|---|
runtime_kind_from_binop | Map a BinOpKind to its RuntimeOpKind counterpart. |
runtime_kind_from_compop | Map a CompOpKind to its RuntimeOpKind counterpart. |
runtime_kind_from_condop | Map a CondOpKind to its RuntimeOpKind counterpart. |
| Class | Description |
|---|---|
BinOp | Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN). |
BinOpKind | |
BinaryOperationBase | Base for binary operations with lhs, rhs, and output. |
CompOp | Comparison operation (EQ, NEQ, LT, LE, GT, GE). |
CompOpKind | |
CondOp | Conditional logical operation (AND, OR). |
CondOpKind | |
NotOp | |
Operation | |
OperationKind | Classification of operations for classical/quantum separation. |
ParamHint | |
RuntimeClassicalExpr | A classical expression known to require runtime evaluation. |
RuntimeOpKind | Unified kind for RuntimeClassicalExpr covering all classical |
Signature | |
UnaryMathOp | Represent one pure unary mathematical expression. |
UnaryMathOpKind | Identify one abstract unary mathematical operation. |
Value | A typed SSA value in the IR. |
Functions¶
runtime_kind_from_binop [source]¶
def runtime_kind_from_binop(kind: BinOpKind) -> RuntimeOpKindMap a BinOpKind to its RuntimeOpKind counterpart.
runtime_kind_from_compop [source]¶
def runtime_kind_from_compop(kind: CompOpKind) -> RuntimeOpKindMap a CompOpKind to its RuntimeOpKind counterpart.
runtime_kind_from_condop [source]¶
def runtime_kind_from_condop(kind: CondOpKind) -> RuntimeOpKindMap a CondOpKind to its RuntimeOpKind counterpart.
Classes¶
BinOp [source]¶
class BinOp(BinaryOperationBase)Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN).
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
kind: BinOpKind | None = None,
) -> NoneAttributes¶
kind: BinOpKind | Noneoperation_kind: OperationKindsignature: Signature
BinOpKind [source]¶
class BinOpKind(enum.Enum)Attributes¶
ADDDIVFLOORDIVMINMODMULPOWSUB
BinaryOperationBase [source]¶
class BinaryOperationBase(Operation)Base for binary operations with lhs, rhs, and output.
Provides common properties and validation for operations that take two operands and produce one result.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
kind: enum.Enum | None = None,
) -> NoneAttributes¶
kind: enum.Enum | Nonelhs: Value Left-hand side operand.output: Value Output result.rhs: Value Right-hand side operand.
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,
) -> NoneAttributes¶
kind: CompOpKind | Noneoperation_kind: OperationKindsignature: Signature
CompOpKind [source]¶
class CompOpKind(enum.Enum)Attributes¶
EQGEGTLELTNEQ
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,
) -> NoneAttributes¶
kind: CondOpKind | Noneoperation_kind: OperationKindsignature: Signature
CondOpKind [source]¶
class CondOpKind(enum.Enum)Attributes¶
ANDOR
NotOp [source]¶
class NotOp(Operation)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
input: Valueoperation_kind: OperationKindoutput: Valuesignature: Signature
Operation [source]¶
class Operation(abc.ABC)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operands: list[Value]operation_kind: OperationKind Return the kind of this operation for classical/quantum classification.results: list[Value]signature: Signature
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]) -> OperationReturn a copy with all Values substituted via mapping.
Handles operands, results, and subclass-specific Value
fields. Subclasses override to handle their extra fields.
OperationKind [source]¶
class OperationKind(enum.Enum)Classification of operations for classical/quantum separation.
This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.
Values:
QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)
Attributes¶
CLASSICALCONTROLHYBRIDQUANTUM
ParamHint [source]¶
class ParamHintConstructor¶
def __init__(self, name: str, type: ValueType) -> NoneAttributes¶
name: strtype: ValueType
RuntimeClassicalExpr [source]¶
class RuntimeClassicalExpr(Operation)A classical expression known to require runtime evaluation.
Lowered from CompOp / CondOp / NotOp / BinOp by
ClassicalLoweringPass when the op’s operand dataflow traces back
to a MeasureOperation (i.e. cannot be folded at compile-time, by
emit-time loop unrolling, or by compile_time_if_lowering). Backend
emit translates this 1:1 to a backend-native runtime expression
(e.g. qiskit.circuit.classical.expr.Expr).
Operand convention:
Binary kinds (EQ/NEQ/LT/LE/GT/GE/AND/OR/ADD/SUB/MUL/DIV/FLOORDIV/MOD/POW):
operands = [lhs, rhs].Unary kind (NOT):
operands = [val].Ternary kind (SELECT):
operands = [condition, true_value, false_value]— the runtime form of a branch merge (result = true_value if condition else false_value).Result:
results = [output_value].
The single-node + unified-kind shape (vs four parallel subclasses)
keeps the backend dispatch a single match op.kind instead of four
parallel hooks, and makes the IR self-documenting: a single
RuntimeClassicalExpr instance signals “runtime evaluation
required” regardless of which classical family it came from.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
kind: RuntimeOpKind | None = None,
) -> NoneAttributes¶
kind: RuntimeOpKind | Noneoperation_kind: OperationKindsignature: Signature
RuntimeOpKind [source]¶
class RuntimeOpKind(enum.Enum)Unified kind for RuntimeClassicalExpr covering all classical
op families that can appear at runtime.
The split between this enum and the per-family BinOpKind /
CompOpKind / CondOpKind is intentional: compile-time-foldable
classical ops keep their original IR types so the existing fold
pipeline (constant_fold → compile_time_if_lowering → emit-time
evaluate_classical_predicate) is undisturbed. Only ops identified
as runtime-evaluation-only by ClassicalLoweringPass get rewritten
to RuntimeClassicalExpr with a member of this enum.
Attributes¶
ADDANDDIVEQFLOORDIVGEGTLELTMODMULNEQNOTORPOWSELECTSUB
Signature [source]¶
class SignatureConstructor¶
def __init__(
self,
operands: list[ParamHint | None] = list(),
results: list[ParamHint] = list(),
) -> NoneAttributes¶
operands: list[ParamHint | None]results: list[ParamHint]
UnaryMathOp [source]¶
class UnaryMathOp(Operation)Represent one pure unary mathematical expression.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | list[Value] | Single numeric input value. |
results | list[Value] | Single numeric result value. |
kind | UnaryMathOpKind | None | Mathematical operation to apply. |
Raises:
ValueError— Ifkindis missing or the operation does not have exactly one operand and one result.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
kind: UnaryMathOpKind | None = None,
) -> NoneAttributes¶
input: Value Return the input value.kind: UnaryMathOpKind | Noneoperation_kind: OperationKind Classify the operation as classical.output: Value Return the output value.signature: Signature Return the typed unary signature.
UnaryMathOpKind [source]¶
class UnaryMathOpKind(enum.Enum)Identify one abstract unary mathematical operation.
Attributes¶
CEILLOG2
Value [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.ir.operation.callable¶
Callable operation model for composite and oracle calls.
Overview¶
| Function | Description |
|---|---|
block_call_operands_and_results | Materialize one block invocation’s operands and results. |
collect_value_like_uuids | Collect UUIDs contained in a value-like IR object. |
normalize_control_value | Normalize an integer activation state for a control register. |
remap_value_metadata_references | Rewrite UUID and logical-id references inside value metadata. |
signature_from_block | Build a callable signature from a traced implementation block. |
signature_from_values | Build a callable signature from concrete operand and result values. |
| Class | Description |
|---|---|
ArrayValue | An array of typed IR values. |
Block | Unified block representation for all pipeline stages. |
CallPolicy | Describe the default lowering policy for a callable call. |
CallTransform | Describe the requested transform of a callable implementation. |
CallableBodyRef | Reference a callable body that can be materialized later. |
CallableBodySelection | Describe one validated IR body selected for an invocation. |
CallableDef | Describe a compiler-facing callable definition. |
CallableImplementation | Describe one implementation candidate for a callable. |
CallableRef | Identify a callable independently of its Python object. |
CompositeGateType | Classify standard boxed quantum callables. |
DictValue | A dictionary value stored as stable ordered entries. |
InvokeOperation | Represent a composite, stdlib, or oracle call. |
KernelEffect | Describe non-unitary behavior reachable from a kernel body. |
Operation | |
OperationKind | Classification of operations for classical/quantum separation. |
ParamHint | |
ReturnOperation | Explicit return operation marking the end of a block with return values. |
Signature | |
TupleValue | A tuple of IR values for structured data. |
Value | A typed SSA value in the IR. |
ValueBase | Nominal base for every typed IR value. |
Constants¶
ValueLike:TypeAlias='Value | ArrayValue | TupleValue | DictValue'
Functions¶
block_call_operands_and_results [source]¶
def block_call_operands_and_results(
block: Block,
inputs_map: Mapping[str, ValueLike],
) -> tuple[list[ValueLike], list[ValueLike]]Materialize one block invocation’s operands and results.
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | Callee block. |
inputs_map | Mapping[str, ValueLike] | Caller values keyed by formal label. |
Returns:
list[ValueLike] — tuple[list[ValueLike], list[ValueLike]]: Ordered caller operands and
list[ValueLike] — caller-local result values.
Raises:
KeyError— If a formal label is missing frominputs_map.ValueError— If the resulting argument count does not match the block.
collect_value_like_uuids [source]¶
def collect_value_like_uuids(value: 'ValueLike') -> set[str]Collect UUIDs contained in a value-like IR object.
Parameters:
| Name | Type | Description |
|---|---|---|
value | ValueLike | Value-like object to inspect. |
Returns:
set[str] — set[str]: UUIDs for value itself, recursively contained tuple/dict
elements, and array view/element dependencies.
normalize_control_value [source]¶
def normalize_control_value(control_value: int | None, num_controls: int) -> int | NoneNormalize an integer activation state for a control register.
Control qubits follow Qamomile’s LSB-first integer convention: bit j
of control_value describes the j-th flattened control operand.
None and the all-ones value are the canonical ordinary-control state.
Parameters:
| Name | Type | Description |
|---|---|---|
control_value | int | None | Required computational-basis value, or None for the ordinary all-ones control state. |
num_controls | int | Concrete positive control-register width. |
Returns:
int | None — int | None: A non-default activation value, or None for all-ones.
Raises:
TypeError— Ifcontrol_valueis not a PythonintorNone.ValueError— Ifnum_controlsis not positive, or ifcontrol_valuedoes not fit in the control-register width.
remap_value_metadata_references [source]¶
def remap_value_metadata_references(
metadata: ValueMetadata,
remap_uuid: Callable[[str], str],
remap_logical_id: Callable[[str], str],
) -> ValueMetadataRewrite UUID and logical-id references inside value metadata.
Parameters:
| Name | Type | Description |
|---|---|---|
metadata | ValueMetadata | Metadata bundle whose embedded references should be rewritten. |
remap_uuid | typing.Callable[[str], str] | Function that maps scalar UUID references (and carrier-key bases) to replacement UUIDs. |
remap_logical_id | typing.Callable[[str], str] | Function that maps scalar logical-id references (and carrier-key bases) to replacement logical IDs. |
Returns:
ValueMetadata — Metadata with every embedded UUID / logical-id reference
rewritten. Legacy "<uuid>_<index>" carrier keys keep their
index suffix while remapping the base UUID. The original bundle is
returned unchanged when no reference is rewritten.
signature_from_block [source]¶
def signature_from_block(block: Block) -> SignatureBuild a callable signature from a traced implementation block.
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | Callable implementation block whose inputs and outputs define the signature. |
Returns:
Signature — IR signature using Block.label_args and
Signature — Block.output_names when available.
signature_from_values [source]¶
def signature_from_values(
operands: Sequence[ValueLike],
results: Sequence[ValueLike],
*,
operand_names: Sequence[str] | None = None,
result_names: Sequence[str] | None = None,
) -> SignatureBuild a callable signature from concrete operand and result values.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | Sequence[ValueLike] | Values consumed by the callable. |
results | Sequence[ValueLike] | Values produced by the callable. |
operand_names | Sequence[str] | None | Optional names for operands. Missing entries fall back to arg_<index>. Defaults to None. |
result_names | Sequence[str] | None | Optional names for results. Missing entries fall back to result_<index>. Defaults to None. |
Returns:
Signature — IR signature with typed parameter hints.
Classes¶
ArrayValue [source]¶
class ArrayValue(Value[T])An array of typed IR values.
When slice_of is set, this array is a strided view over another
array. Element accesses on a sliced ArrayValue resolve to
physical slots on the root parent via the affine map
parent_index = slice_start + slice_step * view_local_index,
applied recursively along slice_of chains. The emit-time
resolver walks this chain to produce the final qubit index; passes
that substitute or clone values must treat slice_of /
slice_start / slice_step as Value references that need to
track through the same mapping as parent_array.
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(),
slice_of: 'ArrayValue | None' = None,
slice_start: 'Value | None' = None,
slice_step: 'Value | None' = None,
) -> NoneAttributes¶
logical_id: strmetadata: ValueMetadataname: strshape: tuple[Value, ...]slice_of: ‘ArrayValue | None’slice_start: ‘Value | None’slice_step: ‘Value | None’type: Tuuid: str
Methods¶
is_slice¶
def is_slice(self) -> boolReturn True if this array is a strided view of another array.
Returns:
bool — True iff slice_of is non-None.
next_version¶
def next_version(self) -> ArrayValue[T]Block [source]¶
class BlockUnified 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[ValueLike] = list(),
output_values: list[ValueLike] = list(),
output_names: list[str] = list(),
operations: list['Operation'] = list(),
kind: BlockKind = BlockKind.HIERARCHICAL,
parameters: dict[str, Value] = dict(),
param_slots: tuple[ParamSlot, ...] = tuple(),
static_bindings: tuple[StaticBindingSlot, ...] = tuple(),
) -> NoneAttributes¶
effects: ‘KernelEffect’ Return lazily cached semantic effects for this block.input_values: list[ValueLike]kind: BlockKindlabel_args: list[str]measurement_result_indices: frozenset[int] Return public output positions derived from measurement.name: stroperations: list[‘Operation’]output_names: list[str]output_values: list[ValueLike]param_slots: tuple[ParamSlot, ...]parameters: dict[str, Value]static_bindings: tuple[StaticBindingSlot, ...]
Methods¶
call¶
def call(self, **kwargs: ValueLike = {}) -> 'InvokeOperation'Create an inline callable invocation against this block.
Parameters:
| Name | Type | Description |
|---|---|---|
**kwargs | ValueLike | Actual argument values keyed by self.label_args. |
Returns:
'InvokeOperation' — Inline-policy invocation whose callable
definition points at this block.
Raises:
KeyError— If a required label inself.label_argsis missing fromkwargs.
is_affine¶
def is_affine(self) -> boolReturn whether this block has passed affine validation.
Returns:
bool — True for AFFINE and ANALYZED blocks.
unbound_parameters¶
def unbound_parameters(self) -> list[str]Return list of unbound parameter names.
CallPolicy [source]¶
class CallPolicy(enum.Enum)Describe the default lowering policy for a callable call.
Attributes¶
INLINENATIVE_FIRSTPRESERVE_BOX
CallTransform [source]¶
class CallTransform(enum.Enum)Describe the requested transform of a callable implementation.
Attributes¶
CONTROLLEDCONTROLLED_INVERSEDIRECTINVERSEis_controlled: bool Return whether the transform adds coherent controls.is_inverse: bool Return whether the transform requests inverse application.
Methods¶
inverted¶
def inverted(self) -> CallTransformToggle inverse application while preserving coherent control.
Returns:
CallTransform — Transform with the inverse component toggled.
CallableBodyRef [source]¶
class CallableBodyRefReference a callable body that can be materialized later.
Parameters:
| Name | Type | Description |
|---|---|---|
ref | CallableRef | Callable whose standard body is referenced. |
kind | str | Body-reference kind, such as "standard" or "symbolic_vector". Defaults to "standard". |
attrs | dict[str, Any] | Serializer-friendly body-materialization attributes. Defaults to an empty dict. |
Constructor¶
def __init__(
self,
ref: CallableRef,
kind: str = 'standard',
attrs: dict[str, Any] = dict(),
) -> NoneAttributes¶
attrs: dict[str, Any]kind: strref: CallableRef
CallableBodySelection [source]¶
class CallableBodySelectionDescribe one validated IR body selected for an invocation.
Parameters:
| Name | Type | Description |
|---|---|---|
body | Block | None | Selected IR body, or None when no composable body is available. |
realized_transform | CallTransform | Transform already implemented by body. |
operands | tuple[ValueBase, ...] | Call-site operands corresponding to the selected body’s formal inputs. |
results | tuple[ValueBase, ...] | Call-site results corresponding to the selected body’s formal outputs. |
Constructor¶
def __init__(
self,
body: Block | None,
realized_transform: CallTransform,
operands: tuple[ValueBase, ...],
results: tuple[ValueBase, ...],
) -> NoneAttributes¶
body: Block | Noneimplements_controls: bool Return whether the selected body includes invocation controls.operands: tuple[ValueBase, ...]realized_transform: CallTransformresults: tuple[ValueBase, ...]
Methods¶
map_result_indices¶
def map_result_indices(
self,
body_indices: Iterable[int],
invocation_results: Sequence[ValueBase],
) -> frozenset[int]Map selected-body output positions to invocation result positions.
Generic controlled lowering removes the external control prefix before aligning a direct body. Transform-specific implementations instead use the complete invocation ABI. Mapping through the selected call-site result values handles both layouts, including any quantum/non-quantum reordering performed while aligning a fallback body.
Parameters:
| Name | Type | Description |
|---|---|---|
body_indices | Iterable[int] | Selected-body output positions to map. |
invocation_results | Sequence[ValueBase] | Complete caller-side invocation results. |
Returns:
frozenset[int] — frozenset[int]: Corresponding positions in invocation_results.
CallableDef [source]¶
class CallableDefDescribe a compiler-facing callable definition.
Parameters:
| Name | Type | Description |
|---|---|---|
ref | CallableRef | Stable callable identity. |
signature | Signature | None | Optional callable signature. |
body | Block | None | Standard IR body, or None for opaque calls. |
body_ref | CallableBodyRef | None | Reference to a standard body that is intentionally deferred. Defaults to None. |
implementations | list[CallableImplementation] | Alternative native or strategy-specific implementations. |
opaque_cost | Any | None | Explicit cost contract for a bodyless callable. Body-backed callables must leave this as None. |
default_policy | CallPolicy | Default call lowering policy. |
attrs | dict[str, Any] | Serializer-friendly definition metadata. |
Constructor¶
def __init__(
self,
ref: CallableRef,
signature: Signature | None = None,
body: Block | None = None,
body_ref: CallableBodyRef | None = None,
implementations: list[CallableImplementation] = list(),
opaque_cost: Any | None = None,
default_policy: CallPolicy = CallPolicy.INLINE,
attrs: dict[str, Any] = dict(),
) -> NoneAttributes¶
attrs: dict[str, Any]body: Block | Nonebody_ref: CallableBodyRef | Nonedefault_policy: CallPolicyimplementations: list[CallableImplementation]opaque_cost: Any | Noneref: CallableRefsignature: Signature | None
Methods¶
effects_for¶
def effects_for(self, transform: CallTransform = CallTransform.DIRECT) -> 'KernelEffect'Return cached semantic effects for one call transform.
Parameters:
| Name | Type | Description |
|---|---|---|
transform | CallTransform | Requested call transform. Defaults to CallTransform.DIRECT. |
Returns:
'KernelEffect' — Union of relevant implementation-body effects.
implementation_for¶
def implementation_for(
self,
*,
transform: CallTransform = CallTransform.DIRECT,
backend: str | None = None,
strategy: str | None = None,
require_body: bool = False,
) -> CallableImplementation | NoneReturn the best matching implementation candidate.
Parameters:
| Name | Type | Description |
|---|---|---|
transform | CallTransform | Requested call transform. |
backend | str | None | Requested backend name. |
strategy | str | None | Requested strategy name. |
require_body | bool | Whether candidates without an IR body should be excluded before ranking. Defaults to False. |
Returns:
CallableImplementation | None — CallableImplementation | None: Matching implementation, if any.
measurement_result_indices_for¶
def measurement_result_indices_for(self, transform: CallTransform = CallTransform.DIRECT) -> frozenset[int]Return measured result positions for one call transform.
Parameters:
| Name | Type | Description |
|---|---|---|
transform | CallTransform | Requested call transform. Defaults to CallTransform.DIRECT. |
Returns:
frozenset[int] — frozenset[int]: Result indices carrying measurement provenance.
CallableImplementation [source]¶
class CallableImplementationDescribe one implementation candidate for a callable.
Parameters:
| Name | Type | Description |
|---|---|---|
transform | CallTransform | Transform this implementation realizes. |
backend | str | None | Backend name for native implementations. |
strategy | str | None | Strategy name such as "standard". |
body | Block | None | IR implementation body. A transform-specific body realizes that transform completely; a controlled body therefore includes control operands in its signature. |
body_ref | CallableBodyRef | None | Reference to a body that should be materialized by a later resolver. Defaults to None. |
emitter | Any | Backend-native emitter object. |
attrs | dict[str, Any] | Serializer-friendly implementation metadata. |
Constructor¶
def __init__(
self,
transform: CallTransform = CallTransform.DIRECT,
backend: str | None = None,
strategy: str | None = None,
body: Block | None = None,
body_ref: CallableBodyRef | None = None,
emitter: Any = None,
attrs: dict[str, Any] = dict(),
) -> NoneAttributes¶
attrs: dict[str, Any]backend: str | Nonebody: Block | Nonebody_ref: CallableBodyRef | Noneemitter: Anystrategy: str | Nonetransform: CallTransform
CallableRef [source]¶
class CallableRefIdentify a callable independently of its Python object.
Parameters:
| Name | Type | Description |
|---|---|---|
namespace | str | Stable namespace such as "qamomile.stdlib" or "user". |
name | str | Stable callable name within the namespace. |
version | str | Schema or behavior version for the callable. |
Constructor¶
def __init__(self, namespace: str, name: str, version: str = '1') -> NoneAttributes¶
name: strnamespace: strversion: str
CompositeGateType [source]¶
class CompositeGateType(enum.Enum)Classify standard boxed quantum callables.
Attributes¶
CUSTOMIQFTQFTQPE
DictValue [source]¶
class DictValue(_MetadataValueMixin, ValueBase)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()))(),
) -> NoneAttributes¶
entries: tuple[tuple[TupleValue | Value, Value], ...]logical_id: strmetadata: ValueMetadataname: strtype: DictTypeuuid: str
Methods¶
is_constant¶
def is_constant(self) -> boolnext_version¶
def next_version(self) -> DictValueInvokeOperation [source]¶
class InvokeOperation(Operation)Represent a composite, stdlib, or oracle call.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | list[ValueLike] | Input values consumed by the call. |
results | list[ValueLike] | Output values produced by the call. |
target | CallableRef | Callable identity. |
transform | CallTransform | Direct, inverse, or controlled invocation. |
attrs | dict[str, Any] | Compile-time attributes for strategy, arity, and resource/lowering decisions. control_value is reserved for a controlled invocation’s LSB-first activation value. Values must be serializer-friendly. |
definition | CallableDef | None | Optional callable definition. |
Constructor¶
def __init__(
self,
operands: Sequence[ValueLike] | None = None,
results: Sequence[ValueLike] | None = None,
*,
target: CallableRef | None = None,
transform: CallTransform = CallTransform.DIRECT,
attrs: dict[str, Any] | None = None,
definition: CallableDef | None = None,
) -> NoneInitialize an invocation operation.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | Sequence[ValueLike] | None | Input values consumed by the call. Defaults to None, meaning no operands. |
results | Sequence[ValueLike] | None | Output values produced by the call. Defaults to None, meaning no results. |
target | CallableRef | None | Callable identity. Defaults to an anonymous user callable when omitted. |
transform | CallTransform | Requested call transform. Defaults to CallTransform.DIRECT. |
attrs | dict[str, Any] | None | Serializer-friendly call attributes. Defaults to an empty dict. |
definition | CallableDef | None | Callable definition. Defaults to None, in which case one is created from target. |
Raises:
TypeError— If a controlled invocation’scontrol_valueor an Oracle control-partition field has an invalid Python type.ValueError— Ifcontrol_valueis used on a non-controlled call or does not fit the controlled invocation’s width, or if Oracle invocation and definition control metadata disagree.
Attributes¶
attrs: dict[str, Any]body: Block | None Return the callable’s default body from its definition.body_ref: CallableBodyRef | None Return the callable’s deferred body reference.control_qubits: list[‘Value’] Return the control-qubit operands.control_value: int | None Return the controlled invocation’s activation value.custom_name: str Return the display name for custom callable boxes.default_policy: CallPolicy Return the callable’s default lowering policy.definition: CallableDef | Noneeffects: ‘KernelEffect’ Return cached effects of relevant callable implementations.gate_type: CompositeGateType Return the standard composite classification for this invocation.measurement_result_indices: frozenset[int] Return a conservative union of measurement-derived results.name: str Return the display name for this invocation.num_added_control_qubits: int Return controls introduced by a frontend control transform.num_body_external_control_qubits: int Return control operands generic lowering adds outside a base body.num_control_qubits: int Return the number of leading control-qubit operands.num_declared_control_qubits: int Return controls included in an opaque Oracle’s base definition.num_target_qubits: int Return the number of target-qubit operands.operandsoperation_kind: OperationKind Return the operation kind.parameters: list[‘Value’] Return non-qubit parameter operands.resultssignature: Signature Return the operation signature.strategy_name: str | None Return the selected lowering/resource strategy name.target: CallableReftarget_qubits: list[‘Value’] Return the target-qubit operands.transform: CallTransform
Methods¶
body_for_transform¶
def body_for_transform(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> tuple[Block | None, CallTransform]Select a body and report the transform it already realizes.
A controlled-inverse invocation may reuse an explicitly registered inverse body when no implementation realizes both transforms. Keeping that fallback in the IR operation gives emitters and static analyses one selection rule while still letting each consumer apply the remaining coherent controls in its own representation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None. |
strategy | str | None | Strategy name to match. Defaults to the invocation’s strategy_name attribute. |
Returns:
Block | None — tuple[Block | None, CallTransform]: Selected body and the transform
CallTransform — already implemented by that body. The callable’s direct body is
tuple[Block | None, CallTransform] — returned with DIRECT when no transform-specific body matches.
Raises:
ValueError— If the selected body disagrees with the invocation’s input or output contract.
effective_body¶
def effective_body(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> Block | NoneReturn the implementation body selected for this invocation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None. |
strategy | str | None | Strategy name to match. Defaults to the invocation’s strategy_name attribute. |
Returns:
Block | None — Block | None: Selected implementation body, or the callable’s
Block | None — default body when no transform-specific implementation exists.
Block | None — A compiler may synthesize inverse or controlled behavior from this
Block | None — fallback body.
implementation_for¶
def implementation_for(
self,
*,
backend: str | None = None,
strategy: str | None = None,
require_body: bool = False,
) -> CallableImplementation | NoneReturn the selected implementation for this invocation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None, which only selects backend-generic implementations. |
strategy | str | None | Strategy name to match. Defaults to None, meaning the invocation’s strategy_name attribute is used. |
require_body | bool | Whether candidates without an IR body should be excluded before ranking. Defaults to False. |
Returns:
CallableImplementation | None — CallableImplementation | None: Matching implementation candidate,
CallableImplementation | None — or None when the callable definition has no match.
measurement_result_indices_for¶
def measurement_result_indices_for(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> frozenset[int]Return measurement-derived results for one selected implementation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name used for implementation selection. Defaults to None. |
strategy | str | None | Strategy name used for implementation selection. Defaults to the invocation’s strategy_name. |
Returns:
frozenset[int] — frozenset[int]: Caller-local result positions derived from
measurement in the selected body.
Raises:
ValueError— If the selected body disagrees with the invocation’s input or output contract.
select_body¶
def select_body(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> CallableBodySelectionSelect and validate the composable body for this invocation.
The result carries the transform already realized by the body and the exact call-site values that bind to it. Consumers therefore cannot independently disagree about whether an invocation’s control prefix belongs to the selected implementation ABI.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None. |
strategy | str | None | Strategy name to match. Defaults to the invocation’s strategy_name attribute. |
Returns:
CallableBodySelection — Validated body, realized transform, and
CallableBodySelection — aligned call-site operands and results.
Raises:
ValueError— If the selected body disagrees with the invocation’s input or output contract.
KernelEffect [source]¶
class KernelEffect(enum.Flag)Describe non-unitary behavior reachable from a kernel body.
KernelEffect.NONE is the empty effect set and denotes unitary behavior.
Flags compose with bitwise union so one kernel can expose measurement,
reset, and measurement-backed feed-forward together.
Attributes¶
FEED_FORWARDMEASUREMENTNONERESETis_unitary: bool Return whether this is the empty effect set.
Methods¶
labels¶
def labels(self) -> tuple[str, ...]Return stable effect names for diagnostics and serialization.
Returns:
tuple[str, ...] — tuple[str, ...]: Active flag names in declaration order.
Operation [source]¶
class Operation(abc.ABC)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operands: list[Value]operation_kind: OperationKind Return the kind of this operation for classical/quantum classification.results: list[Value]signature: Signature
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]) -> OperationReturn a copy with all Values substituted via mapping.
Handles operands, results, and subclass-specific Value
fields. Subclasses override to handle their extra fields.
OperationKind [source]¶
class OperationKind(enum.Enum)Classification of operations for classical/quantum separation.
This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.
Values:
QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)
Attributes¶
CLASSICALCONTROLHYBRIDQUANTUM
ParamHint [source]¶
class ParamHintConstructor¶
def __init__(self, name: str, type: ValueType) -> NoneAttributes¶
name: strtype: ValueType
ReturnOperation [source]¶
class ReturnOperation(Operation)Explicit return operation marking the end of a block with return values.
This operation represents an explicit return statement in the IR. It takes the values to be returned as operands and produces no results (it is a terminal operation that transfers control flow back to the caller).
operands: [Value, ...] - The values to return (may be empty for void returns) results: [] - Always empty (terminal operation)
Example:
A function that returns two values (a UInt and a Float):
ReturnOperation(
operands=[uint_value, float_value],
results=[],
)
The signature would be:
operands=[ParamHint("return_0", UIntType()), ParamHint("return_1", FloatType())]
results=[]Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKind Return CLASSICAL as this is a control flow operation without quantum effects.signature: Signature Return the signature with operands for each return value and no results.
Signature [source]¶
class SignatureConstructor¶
def __init__(
self,
operands: list[ParamHint | None] = list(),
results: list[ParamHint] = list(),
) -> NoneAttributes¶
operands: list[ParamHint | None]results: list[ParamHint]
TupleValue [source]¶
class TupleValue(_MetadataValueMixin, ValueBase)A tuple of IR values for structured data.
Constructor¶
def __init__(
self,
name: str,
elements: tuple[ValueLike, ...] = tuple(),
metadata: ValueMetadata = ValueMetadata(),
uuid: str = (lambda: str(uuid.uuid4()))(),
logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> NoneAttributes¶
elements: tuple[ValueLike, ...]logical_id: strmetadata: ValueMetadataname: strtype: ‘TupleType’uuid: str
Methods¶
is_constant¶
def is_constant(self) -> boolnext_version¶
def next_version(self) -> TupleValueValue [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.
ValueBase [source]¶
class ValueBaseNominal base for every typed IR value.
Runtime compiler passes inspect values in their innermost loops. A nominal base keeps those checks constant-time; a runtime-checkable protocol would repeatedly scan the protocol members on Python versions that do not cache structural checks.
Attributes¶
logical_id: strmetadata: ValueMetadataname: strtype: ValueType Return the static IR type carried by this value.uuid: str
Methods¶
get_const¶
def get_const(self) -> int | float | bool | NoneReturn the scalar constant carried by this value.
Returns:
int | float | bool | None — int | float | bool | None: Constant value, or None when the
value is not constant.
is_constant¶
def is_constant(self) -> boolReturn whether this value carries a scalar constant.
Returns:
bool — Whether scalar constant metadata is present.
is_parameter¶
def is_parameter(self) -> boolReturn whether this value represents a runtime parameter.
Returns:
bool — Whether parameter metadata is present.
next_version¶
def next_version(self) -> ValueBaseCreate the next SSA version of this value.
Returns:
ValueBase — A value with a fresh version UUID and preserved logical
identity.
parameter_name¶
def parameter_name(self) -> str | NoneReturn the public parameter name carried by this value.
Returns:
str | None — str | None: Parameter name, or None for a non-parameter value.
qamomile.circuit.ir.operation.cast¶
Cast operation for type conversions over the same quantum resources.
Overview¶
| Class | Description |
|---|---|
CastOperation | Type cast operation for creating aliases over the same quantum resources. |
Operation | |
OperationKind | Classification of operations for classical/quantum separation. |
ParamHint | |
Signature |
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:
Vector[Qubit] -> QFixed (after QPE, for phase measurement)
Vector[Qubit] -> QUInt (for quantum arithmetic)
QUInt -> QFixed (reinterpret bits with different encoding)
QFixed -> QUInt (reinterpret bits with different encoding)
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(),
) -> NoneAttributes¶
num_qubits: int Number of qubits involved in the cast.operation_kind: OperationKind Cast stays in the same segment as its source (QUANTUM for quantum types).qubit_mapping: list[str]signature: Signature Return the type signature of this cast operation.source_type: ValueType | Nonetarget_type: ValueType | None
Operation [source]¶
class Operation(abc.ABC)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operands: list[Value]operation_kind: OperationKind Return the kind of this operation for classical/quantum classification.results: list[Value]signature: Signature
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]) -> OperationReturn a copy with all Values substituted via mapping.
Handles operands, results, and subclass-specific Value
fields. Subclasses override to handle their extra fields.
OperationKind [source]¶
class OperationKind(enum.Enum)Classification of operations for classical/quantum separation.
This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.
Values:
QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)
Attributes¶
CLASSICALCONTROLHYBRIDQUANTUM
ParamHint [source]¶
class ParamHintConstructor¶
def __init__(self, name: str, type: ValueType) -> NoneAttributes¶
name: strtype: ValueType
Signature [source]¶
class SignatureConstructor¶
def __init__(
self,
operands: list[ParamHint | None] = list(),
results: list[ParamHint] = list(),
) -> NoneAttributes¶
operands: list[ParamHint | None]results: list[ParamHint]
qamomile.circuit.ir.operation.classical_ops¶
Classical operations for quantum-classical hybrid programs.
Overview¶
| Class | Description |
|---|---|
ArrayValue | An array of typed IR values. |
BitType | Type representing a classical bit. |
DecodeQFixedOperation | Decode measured bits to float (classical operation). |
DictGetItemOperation | Look up one entry of a Dict by a (possibly symbolic) key. |
FloatType | Type representing a floating-point number. |
Operation | |
OperationKind | Classification of operations for classical/quantum separation. |
ParamHint | |
ReturnQuantumArrayElementOperation | Validate a branch-selected quantum element’s array return at emit time. |
Signature | |
StoreArrayElementOperation | Store a classical scalar into one element of a classical array. |
Value | A typed SSA value in the IR. |
Classes¶
ArrayValue [source]¶
class ArrayValue(Value[T])An array of typed IR values.
When slice_of is set, this array is a strided view over another
array. Element accesses on a sliced ArrayValue resolve to
physical slots on the root parent via the affine map
parent_index = slice_start + slice_step * view_local_index,
applied recursively along slice_of chains. The emit-time
resolver walks this chain to produce the final qubit index; passes
that substitute or clone values must treat slice_of /
slice_start / slice_step as Value references that need to
track through the same mapping as parent_array.
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(),
slice_of: 'ArrayValue | None' = None,
slice_start: 'Value | None' = None,
slice_step: 'Value | None' = None,
) -> NoneAttributes¶
logical_id: strmetadata: ValueMetadataname: strshape: tuple[Value, ...]slice_of: ‘ArrayValue | None’slice_start: ‘Value | None’slice_step: ‘Value | None’type: Tuuid: str
Methods¶
is_slice¶
def is_slice(self) -> boolReturn True if this array is a strided view of another array.
Returns:
bool — True iff slice_of is non-None.
next_version¶
def next_version(self) -> ArrayValue[T]BitType [source]¶
class BitType(ClassicalTypeMixin, ValueType)Type representing a classical bit.
DecodeQFixedOperation [source]¶
class DecodeQFixedOperation(Operation)Decode measured bits to float (classical operation).
This operation converts a sequence of classical bits from qubit measurements into a floating-point number using fixed-point encoding.
The decoding formula for least-significant-first storage:
float_value = Σ bit[i] * 2^(int_bits - num_bits + i)
For QPE phase (int_bits=0):
bit[0] has weight 2**(-num_bits) and bit[-1] has weight 0.5.
Example:
bits = [1, 0, 1] with int_bits=0
→ 0.101 (MSB-first display) = 0.5 + 0.125 = 0.625operands: [ArrayValue of bits (vec[bit])] results: [Float value]
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_bits: int = 0,
int_bits: int = 0,
) -> NoneAttributes¶
int_bits: intnum_bits: intoperation_kind: OperationKindsignature: Signature
DictGetItemOperation [source]¶
class DictGetItemOperation(Operation)Look up one entry of a Dict by a (possibly symbolic) key.
This is the IR form of d[key] on a Dict handle. The key
components may be symbolic (e.g. loop variables of a for-items
loop); the lookup is resolved at emit time when the key values and
the dict’s bound data are both concrete.
operands: [DictValue, *key_component_values] results: [looked-up scalar value]
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
key_arity: int = 1,
) -> NoneAttributes¶
dict_value: Value Value: The DictValue being indexed (operands[0]).key_arity: intkey_values: tuple[Value, ...] tuple[Value, ...]: The key component values.operation_kind: OperationKindsignature: Signature
FloatType [source]¶
class FloatType(ClassicalTypeMixin, ValueType)Type representing a floating-point number.
Operation [source]¶
class Operation(abc.ABC)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operands: list[Value]operation_kind: OperationKind Return the kind of this operation for classical/quantum classification.results: list[Value]signature: Signature
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]) -> OperationReturn a copy with all Values substituted via mapping.
Handles operands, results, and subclass-specific Value
fields. Subclasses override to handle their extra fields.
OperationKind [source]¶
class OperationKind(enum.Enum)Classification of operations for classical/quantum separation.
This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.
Values:
QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)
Attributes¶
CLASSICALCONTROLHYBRIDQUANTUM
ParamHint [source]¶
class ParamHintConstructor¶
def __init__(self, name: str, type: ValueType) -> NoneAttributes¶
name: strtype: ValueType
ReturnQuantumArrayElementOperation [source]¶
class ReturnQuantumArrayElementOperation(Operation)Validate a branch-selected quantum element’s array return at emit time.
Most quantum element assignments are verified structurally by the frontend and emit no IR. A compile-time conditional can instead select different element indices on its branches; only the unrolled emit context knows which source index survived. This operation carries both the requested target indices and the conditional source indices so emission can prove they resolve to the same physical slot before treating the assignment as a borrow return.
Operand convention:
[array, returned_qubit, *target_indices, *source_indices]. The
target and source halves have equal nonzero arity, inferred from the
operand count. The operation has no results and emits no backend gate.
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
array: ArrayValue Return the quantum array receiving the borrowed element.index_arity: int Return the number of target (and source) index operands.operation_kind: OperationKind Classify the return validator as a quantum operation.returned_value: Value Return the quantum value being returned.signature: Signature Return the deferred validator’s operand-only signature.source_indices: tuple[Value, ...] Return the branch-merged borrow-source indices.target_indices: tuple[Value, ...] Return the user-written assignment indices.
Signature [source]¶
class SignatureConstructor¶
def __init__(
self,
operands: list[ParamHint | None] = list(),
results: list[ParamHint] = list(),
) -> NoneAttributes¶
operands: list[ParamHint | None]results: list[ParamHint]
StoreArrayElementOperation [source]¶
class StoreArrayElementOperation(Operation)Store a classical scalar into one element of a classical array.
This is the IR form of array[index] = value for classical element
types (Bit / UInt / Float). Classical values are freely
copyable, so the store is an ordinary SSA rewrite: the operation
consumes the current array version and produces a new ArrayValue
version (same logical_id, fresh uuid) whose contents equal the
input array with the addressed element replaced. Quantum arrays never
use this operation — qubit element assignment is the return half of
the borrow-return idiom and emits no IR.
The operation is evaluated in one of two places:
Compile time:
ConstantFoldingPassfolds the store when the source array contents, the index, and the stored value are all compile-time resolvable, attaching the updatedconst_arraymetadata to the result value.Runtime: otherwise the store executes host-side in a classical segment via
ClassicalExecutor(e.g. for measurement-derivedVector[Bit]contents). It must never reach a quantum segment; backend emit rejects it explicitly.
Operand convention:
operands: [array (ArrayValue), stored_value (Value), *index_values]
results: [new_array (ArrayValue)]
Example:
@qmc.qkernel
def k() -> qmc.Vector[qmc.Bit]:
qs = qmc.qubit_array(2, "qs")
qs[0] = qmc.x(qs[0])
bits = qmc.measure(qs)
bits[1] = bits[0] # emits StoreArrayElementOperation
return bitsConstructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
array: ArrayValue ArrayValue: The array version the store reads from.index_values: tuple[Value, ...] tuple[Value, ...]: The element indices being written.operation_kind: OperationKindsignature: Signature Return the operation’s dynamic array/qubit/index signature.stored_value: Value Value: The scalar being written into the array.
Value [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.ir.operation.control_flow¶
Overview¶
| Function | Description |
|---|---|
genuine_input_values | Return an operation’s input values that count as genuine reads. |
validate_region_args | Validate the SSA identities owned by a loop’s region arguments. |
| Class | Description |
|---|---|
BitType | Type representing a classical bit. |
BlockType | Type representing a block/function reference. |
BranchRebind | Trace-time record of a quantum variable rebound inside an if branch. |
ForItemsOperation | Represents iteration over dict/iterable items. |
ForOperation | Represents a for loop operation. |
HasNestedOps | Mixin for operations that contain nested operation lists. |
IfMerge | One branch-merge slot of an :class:IfOperation. |
IfOperation | Represents an if-else conditional operation. |
LoopCarriedRebind | Trace-time record of a variable rebound inside a loop body. |
Operation | |
OperationKind | Classification of operations for classical/quantum separation. |
ParamHint | |
Region | Expose one structured-control region through a uniform interface. |
RegionArg | Explicit loop-carried value on a loop operation (MLIR-style iter_arg). |
Signature | |
UIntType | Type representing an unsigned integer. |
Value | A typed SSA value in the IR. |
ValueBase | Nominal base for every typed IR value. |
WhileOperation | Represents a while loop operation. |
Functions¶
genuine_input_values [source]¶
def genuine_input_values(op: Operation) -> list[ValueBase]Return an operation’s input values that count as genuine reads.
Structured operations derive reads from their explicit region interface:
enclosing operands, captures, loop initializers, and region yields.
Block arguments and operation results are definitions, while legacy
rebind records are diagnostics rather than dataflow. Leaf operations keep
their ordinary all_input_values contract.
Parameters:
| Name | Type | Description |
|---|---|---|
op | Operation | Operation to inspect. |
Returns:
list[ValueBase] — list[ValueBase]: Semantic reads in interface order.
validate_region_args [source]¶
def validate_region_args(op: ForOperation | ForItemsOperation | WhileOperation) -> tuple[RegionArg, ...]Validate the SSA identities owned by a loop’s region arguments.
A loop owns several definition namespaces: its iteration variables,
every RegionArg.block_arg, and every RegionArg.result. Those
identities must be pairwise disjoint. Otherwise different stages can
assign incompatible meanings to one UUID: a UUID-keyed environment has
only one slot, so binding either the iteration variable or the carried
value overwrites the other and makes both reads observe the same value.
Parameters:
| Name | Type | Description |
|---|---|---|
op | ForOperation | ForItemsOperation | WhileOperation | Loop operation whose region arguments should be validated. |
Returns:
tuple[RegionArg, ...] — tuple[RegionArg, ...]: The validated op.region_args tuple.
Raises:
ValueError— If result counts or positions disagree, slot types differ, or any loop-owned definition identity collides with another definition or with a region initializer/body yield.
Classes¶
BitType [source]¶
class BitType(ClassicalTypeMixin, ValueType)Type representing a classical bit.
BlockType [source]¶
class BlockType(ObjectTypeMixin, ValueType)Type representing a block/function reference.
BranchRebind [source]¶
class BranchRebindTrace-time record of a quantum variable rebound inside an if branch.
The frontend’s branch tracing merges only the new branch values
through merge operations; when both branches rebind a variable, the
value the variable held before the branch no longer appears anywhere
in the IfOperation. These records preserve that pre-branch
binding so the transpiler’s control-flow discard check
(reject_control_flow_quantum_discard in
qamomile.circuit.transpiler.passes.analyze) can verify that the
pre-branch quantum state is consumed or carried on every runtime
execution path instead of being silently dropped.
Constructor¶
def __init__(
self,
var_name: str,
before: Value,
rebound_in_true: bool,
rebound_in_false: bool,
) -> NoneAttributes¶
before: Valuerebound_in_false: boolrebound_in_true: boolvar_name: str
ForItemsOperation [source]¶
class ForItemsOperation(HasNestedOps, Operation)Represents iteration over dict/iterable items.
Example:
for (i, j), Jij in qmc.items(ising):
bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
key_vars: list[str] = list(),
value_var: str = '',
key_is_vector: bool = False,
key_var_values: tuple[Value, ...] | None = None,
value_var_value: Value | None = None,
operations: list[Operation] = list(),
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_args: tuple[RegionArg, ...] = (),
captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
captures: tuple[ValueBase, ...]key_is_vector: boolkey_var_values: tuple[Value, ...] | Nonekey_vars: list[str]loop_carried_rebinds: tuple[LoopCarriedRebind, ...]operation_kind: OperationKindoperations: list[Operation]region_args: tuple[RegionArg, ...]signature: Signaturevalue_var: strvalue_var_value: Value | None
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include the per-key/value Value fields for cloning/substitution.
Same rationale as ForOperation.all_input_values: keep the IR
identity fields in lockstep with body references so UUID-keyed
lookups stay valid after inline cloning. Loop-carried rebind
records and region arguments are included for the same reason.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the items-loop body with its explicit interface.
Returns:
tuple[Region, ...] — tuple[Region, ...]: One body region containing key/value formals,
carried-value formals, captures, and carried yields.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operationrebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild the items-loop body and complete boundary interface.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Exactly one replacement body region. |
Returns:
Operation — Rebuilt items-loop operation.
Raises:
ValueError— If arity or boundary value kinds are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationForOperation [source]¶
class ForOperation(HasNestedOps, Operation)Represents a for loop operation.
Example:
for i in range(start, stop, step):
bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
loop_var: str = '',
loop_var_value: Value | None = None,
operations: list[Operation] = list(),
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_args: tuple[RegionArg, ...] = (),
captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
captures: tuple[ValueBase, ...]loop_carried_rebinds: tuple[LoopCarriedRebind, ...]loop_var: strloop_var_value: Value | Noneoperation_kind: OperationKindoperations: list[Operation]region_args: tuple[RegionArg, ...]signature: Signature
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include loop_var_value so cloning/substitution stays consistent.
Without this override, UUIDRemapper would clone every body
reference to the loop variable to a fresh UUID, but leave
loop_var_value pointing at the un-cloned original — emit-time
UUID-keyed lookups for the loop variable would then miss.
Loop-carried rebind records and region arguments are included
for the same reason.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the range-loop body with its explicit interface.
Returns:
tuple[Region, ...] — tuple[Region, ...]: One body region containing the induction
value, carried-value formals, captures, and carried yields.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operationrebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild the range-loop body and complete boundary interface.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Exactly one replacement body region. |
Returns:
Operation — Rebuilt range-loop operation.
Raises:
ValueError— If arity or boundary value kinds are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationHasNestedOps [source]¶
class HasNestedOpsMixin for operations that contain nested operation lists.
nested_regions() is the canonical traversal API because it exposes
operations together with block arguments, captures, and yields.
nested_op_lists() / rebuild_nested() remain compatibility helpers
for specialized consumers while they migrate to the region interface.
Methods¶
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]Return all nested operation lists in this control flow op.
nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return uniform views of every nested operation region.
Subclasses with explicit block arguments, captures, or yields override
this method. The fallback keeps legacy operation-owned blocks visible
while consumers migrate from nested_op_lists.
Returns:
tuple[Region, ...] — tuple[Region, ...]: Region views in nested_op_lists order.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> OperationReturn a copy with nested operation lists replaced.
new_lists must have the same length/order as nested_op_lists().
rebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationReturn a copy with replacement region operation sequences.
Concrete control-flow operations override this method to rebuild both their body operations and boundary values. The fallback supports legacy region owners whose boundary remains operation-specific.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Replacement regions in nested_regions order. |
Returns:
Operation — Rebuilt control-flow operation.
Raises:
ValueError— If the replacement region count differs from the operation’s current region count.
IfMerge [source]¶
class IfMerge(NamedTuple)One branch-merge slot of an :class:IfOperation.
An IfOperation merges each variable touched by its branches back
into a single SSA value. IfMerge is the read-side view of one such
merge slot, decoupling every consumer from how the merge is stored in
the IR (today the parallel IfOperation.true_yields /
false_yields lists; the storage may change without touching
consumers).
Attributes¶
false_value: Valueindex: intis_identity: bool Whether both branches merge the same underlying value.result: Valuetrue_value: Value
Methods¶
select¶
def select(self, taken: bool) -> ValueReturn the branch source selected by a resolved condition.
Parameters:
| Name | Type | Description |
|---|---|---|
taken | bool | The condition’s truth value (True selects the true branch). |
Returns:
Value — true_value when taken is true, else
false_value.
IfOperation [source]¶
class IfOperation(HasNestedOps, Operation)Represents an if-else conditional operation.
Example:
if condition:
true_body
else:
false_bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
true_operations: list[Operation] = list(),
false_operations: list[Operation] = list(),
true_yields: list[Value] = list(),
false_yields: list[Value] = list(),
branch_rebinds: tuple[BranchRebind, ...] = (),
true_captures: tuple[ValueBase, ...] = (),
false_captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
branch_rebinds: tuple[BranchRebind, ...]condition: Valuefalse_captures: tuple[ValueBase, ...]false_operations: list[Operation]false_yields: list[Value]operation_kind: OperationKindsignature: Signaturetrue_captures: tuple[ValueBase, ...]true_operations: list[Operation]true_yields: list[Value]
Methods¶
add_merge¶
def add_merge(self, true_value: Value, false_value: Value, result: Value) -> NoneAppend a branch-merge slot to this if-else.
The only sanctioned construction path for merges: it keeps the
yield lists and results index-aligned so iter_merges can
rely on the invariants it checks.
Parameters:
| Name | Type | Description |
|---|---|---|
true_value | Value | Value selected when the condition is true. |
false_value | Value | Value selected when the condition is false. Must have the same type as true_value. |
result | Value | Fresh SSA value representing the merged output. Must have the same type as the branch values. |
Raises:
RuntimeError— If the condition operand has not been attached to this operation yet (operands[0]must exist before merges are added), or the branch / result types do not match.
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include branch-yield values and rebind records for cloning/substitution.
The yields are subclass-specific Value fields (not operands —
see the class docstring), so generic passes reach them through
this override, mirroring ForItemsOperation.key_var_values.
Branch rebind records follow the loop operations’ rationale: the
recorded pre-branch values reference program values by identity,
so inline cloning must remap them in lockstep with operands.
Read-based checks must not treat the records as reads (see
_op_read_uuids in the analyze pass module).
Returns:
list[ValueBase] — list[ValueBase]: Base input values plus the true/false
yields and rebind-record values.
iter_merges¶
def iter_merges(self) -> Iterator[IfMerge]Iterate the branch-merge slots of this if-else.
This is the single read API for merge semantics: passes must consume merges through it (never through the yield lists directly) so the underlying storage can change without touching consumers.
Yields:
IfMerge — One entry per merged output, in result order.
Raises:
RuntimeError— If the stored merge data is internally inconsistent (the yield-list lengths differ from the result count, or the condition operand is missing while merges are attached). This indicates IR corruption, not a user error. The per-merge corruption modes of the old embedded-operation storage (a foreign entry, a malformed or mismatched condition, a result copy diverging fromresults[i]) cannot be represented in the yield-list storage and need no checks.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]Return the two branch bodies (merge yields are not operations).
Returns:
list[list[Operation]] — list[list[Operation]]: [true_operations, false_operations].
The branch-merge yields are values, not operations, so
they are intentionally absent here.
nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the true and false branch interfaces.
Returns:
tuple[Region, ...] — tuple[Region, ...]: True and false regions in that order, with
branch-local captures and merge yields.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> OperationReturn a copy with the true and false branch bodies replaced.
Parameters:
| Name | Type | Description |
|---|---|---|
new_lists | list[list[Operation]] | The replacement branch bodies in nested_op_lists order ([true_operations, false_operations]). |
Returns:
Operation — A copy of this if-else with the branch bodies
swapped and all other fields (yields, rebinds) preserved.
rebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild both branches and their complete boundary interfaces.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | True and false replacement regions. |
Returns:
Operation — Rebuilt conditional operation.
Raises:
ValueError— If region count, block arguments, or yield signatures are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationSubstitute operand, result, branch-yield, and rebind-record values.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | dict[str, ValueBase] | UUID-keyed substitution map. |
Returns:
Operation — The rewritten operation.
LoopCarriedRebind [source]¶
class LoopCarriedRebindTrace-time record of a variable rebound inside a loop body.
Two rebind families share this record type, distinguished by the
type of before:
Classical scalar (
beforeclassical): the frontend traces a loop body exactly once, so a Python-level reassignment liketotal = total + iproduces IR whose right-hand side reads the fixed pre-loop value instead of the previous iteration’s value. Most such carries are now represented as explicitRegionArgs (see above) and are fully supported; a classical record is only created for the shapes region binding declines —while-body carries (a runtime while loop cannot be unrolled) and measurement-backedBitcarries — and the transpiler’s classical loop-carried check rejects those with a targeted error instead of silently miscompiling.Quantum (
beforequantum): the loop body left the variable bound to a different quantum resource (logical_idchange — a fresh allocation or another register, not a gate self-update). The transpiler’s control-flow discard check (reject_control_flow_quantum_discard) rejects the ones whose incoming state the body never consumes.
Constructor¶
def __init__(
self,
var_name: str,
before: ValueBase,
after: ValueBase,
before_synthesized: bool = False,
) -> NoneAttributes¶
after: ValueBasebefore: ValueBasebefore_synthesized: boolvar_name: str
Operation [source]¶
class Operation(abc.ABC)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operands: list[Value]operation_kind: OperationKind Return the kind of this operation for classical/quantum classification.results: list[Value]signature: Signature
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]) -> OperationReturn a copy with all Values substituted via mapping.
Handles operands, results, and subclass-specific Value
fields. Subclasses override to handle their extra fields.
OperationKind [source]¶
class OperationKind(enum.Enum)Classification of operations for classical/quantum separation.
This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.
Values:
QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)
Attributes¶
CLASSICALCONTROLHYBRIDQUANTUM
ParamHint [source]¶
class ParamHintConstructor¶
def __init__(self, name: str, type: ValueType) -> NoneAttributes¶
name: strtype: ValueType
Region [source]¶
class RegionExpose one structured-control region through a uniform interface.
This is a view over the existing semantic IR rather than a parallel value
system: every entry is an ordinary Qamomile ValueBase carrying the
current UUID identity. Control-flow operations remain the owners of the
stored fields and construct Region views through nested_regions.
Parameters:
| Name | Type | Description |
|---|---|---|
operations | tuple[Operation, ...] | Operations evaluated inside the region in program order. |
block_args | tuple[ValueBase, ...] | Values defined at region entry, such as a loop induction variable or carried-value formal. |
captures | tuple[ValueBase, ...] | Explicit outer-scope values read by the region, ordered by first use. |
yields | tuple[ValueBase, ...] | Values yielded at the region boundary in result-slot order. |
Constructor¶
def __init__(
self,
operations: tuple[Operation, ...],
block_args: tuple[ValueBase, ...] = (),
captures: tuple[ValueBase, ...] = (),
yields: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
block_args: tuple[ValueBase, ...]captures: tuple[ValueBase, ...]operations: tuple[Operation, ...]yields: tuple[ValueBase, ...]
RegionArg [source]¶
class RegionArgExplicit loop-carried value on a loop operation (MLIR-style iter_arg).
A RegionArg makes a loop-carried dependency explicit in the IR,
the way MLIR’s scf.for models iter_args / scf.yield:
On iteration 0 the body reads
block_argbound toinit.After each iteration,
block_argis rebound to that iteration’syieldedvalue.After the loop,
resultholds the final carried value (initwhen the loop ran zero iterations).
The loop body’s operations reference block_arg (the frontend
substitutes the traced pre-loop reads), and post-loop operations
reference result (the frontend rebinds the Python handle when it
closes the loop). result is also appended to the loop operation’s
results list so dependency analysis sees the loop as its
producer.
This subsumes the trace-once staleness that LoopCarriedRebind
records exist to reject: a rebind represented as a RegionArg is
a supported loop-carried value, not a miscompilation hazard.
Constructor¶
def __init__(
self,
var_name: str,
init: Value,
block_arg: Value,
yielded: Value,
result: Value,
) -> NoneAttributes¶
block_arg: Valueinit: Valueresult: Valuevar_name: stryielded: Value
Signature [source]¶
class SignatureConstructor¶
def __init__(
self,
operands: list[ParamHint | None] = list(),
results: list[ParamHint] = list(),
) -> NoneAttributes¶
operands: list[ParamHint | None]results: list[ParamHint]
UIntType [source]¶
class UIntType(ClassicalTypeMixin, ValueType)Type representing an unsigned integer.
Value [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.
ValueBase [source]¶
class ValueBaseNominal base for every typed IR value.
Runtime compiler passes inspect values in their innermost loops. A nominal base keeps those checks constant-time; a runtime-checkable protocol would repeatedly scan the protocol members on Python versions that do not cache structural checks.
Attributes¶
logical_id: strmetadata: ValueMetadataname: strtype: ValueType Return the static IR type carried by this value.uuid: str
Methods¶
get_const¶
def get_const(self) -> int | float | bool | NoneReturn the scalar constant carried by this value.
Returns:
int | float | bool | None — int | float | bool | None: Constant value, or None when the
value is not constant.
is_constant¶
def is_constant(self) -> boolReturn whether this value carries a scalar constant.
Returns:
bool — Whether scalar constant metadata is present.
is_parameter¶
def is_parameter(self) -> boolReturn whether this value represents a runtime parameter.
Returns:
bool — Whether parameter metadata is present.
next_version¶
def next_version(self) -> ValueBaseCreate the next SSA version of this value.
Returns:
ValueBase — A value with a fresh version UUID and preserved logical
identity.
parameter_name¶
def parameter_name(self) -> str | NoneReturn the public parameter name carried by this value.
Returns:
str | None — str | None: Parameter name, or None for a non-parameter value.
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,
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_args: tuple[RegionArg, ...] = (),
captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
captures: tuple[ValueBase, ...]loop_carried_rebinds: tuple[LoopCarriedRebind, ...]max_iterations: int | Noneoperation_kind: OperationKindoperations: list[Operation]region_args: tuple[RegionArg, ...]signature: Signature
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include rebind records and region args for cloning/substitution.
Same rationale as ForOperation.all_input_values: rebind
records and region arguments reference body/pre-loop values by
identity, so inline cloning must remap them in lockstep with
body operands.
Returns:
list[ValueBase] — list[ValueBase]: Base input values plus rebind-record and
region-argument values.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the while body with explicit boundary values.
Returns:
tuple[Region, ...] — tuple[Region, ...]: One body region whose block arguments and
yields are aligned with region_args. The updated
condition, when present, is appended as the final yield.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operationrebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild the while body and its complete boundary interface.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Exactly one replacement body region. |
Returns:
Operation — Rebuilt while operation.
Raises:
ValueError— If arity or boundary value kinds are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationSubstitute operand, rebind-record, and region-arg values.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | dict[str, ValueBase] | UUID-keyed substitution map. |
Returns:
Operation — The rewritten operation.
qamomile.circuit.ir.operation.control_value¶
Shared activation-value semantics for coherent quantum controls.
Overview¶
| Function | Description |
|---|---|
control_pattern_for_value | Return the LSB-first activation pattern for a control value. |
is_plain_int | Return True if value is a Python int but not a bool. |
normalize_control_value | Normalize an integer activation state for a control register. |
Functions¶
control_pattern_for_value [source]¶
def control_pattern_for_value(control_value: int | None, num_controls: int) -> tuple[int, ...]Return the LSB-first activation pattern for a control value.
Parameters:
| Name | Type | Description |
|---|---|---|
control_value | int | None | Required computational-basis value. None means the ordinary all-ones control state. |
num_controls | int | Concrete positive control-register width. |
Returns:
tuple[int, ...] — tuple[int, ...]: One 0/1 activation bit per flattened control,
with the first control represented by bit zero.
Raises:
TypeError— Ifcontrol_valueis not a PythonintorNone.ValueError— If the width or activation value is invalid.
Example:
>>> control_pattern_for_value(2, 2)
(0, 1)
>>> control_pattern_for_value(None, 2)
(1, 1)is_plain_int [source]¶
def is_plain_int(value: object) -> boolReturn True if value is a Python int but not a bool.
bool is a subclass of int in Python, so isinstance(True, int)
is True. This helper distinguishes a genuine integer from a boolean,
which matters wherever a boolean must be rejected in an integer slot — for
example, validating decoded wire data or a register width.
Parameters:
| Name | Type | Description |
|---|---|---|
value | object | The value to test. |
Returns:
bool — True when value is an int and not a bool.
normalize_control_value [source]¶
def normalize_control_value(control_value: int | None, num_controls: int) -> int | NoneNormalize an integer activation state for a control register.
Control qubits follow Qamomile’s LSB-first integer convention: bit j
of control_value describes the j-th flattened control operand.
None and the all-ones value are the canonical ordinary-control state.
Parameters:
| Name | Type | Description |
|---|---|---|
control_value | int | None | Required computational-basis value, or None for the ordinary all-ones control state. |
num_controls | int | Concrete positive control-register width. |
Returns:
int | None — int | None: A non-default activation value, or None for all-ones.
Raises:
TypeError— Ifcontrol_valueis not a PythonintorNone.ValueError— Ifnum_controlsis not positive, or ifcontrol_valuedoes not fit in the control-register width.
qamomile.circuit.ir.operation.control_work¶
Classify IR operations for coherent-control work analysis.
This module owns only semantic categories shared by resource estimation and emission. It deliberately does not assign decomposition weights: the estimator and emitter translate the same category into their own model or engine-specific cost after classification.
Overview¶
| Function | Description |
|---|---|
classify_control_work | Return the shared coherent-control category for one IR operation. |
| Class | Description |
|---|---|
BinOp | Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN). |
CInitOperation | Initialize the classical values (const, arguments etc) |
CastOperation | Type cast operation for creating aliases over the same quantum resources. |
CompOp | Comparison operation (EQ, NEQ, LT, LE, GT, GE). |
CondOp | Conditional logical operation (AND, OR). |
ControlWorkKind | Describe how an operation participates in coherent-control analysis. |
ControlledUOperation | Base class for controlled-U operations. |
DictGetItemOperation | Look up one entry of a Dict by a (possibly symbolic) key. |
GateOperation | Quantum gate operation. |
GlobalPhaseOperation | Multiply the complete quantum state by exp(i * phase). |
HasNestedOps | Mixin for operations that contain nested operation lists. |
InverseBlockOperation | Represent an inverse qkernel/block as a first-class IR operation. |
InvokeOperation | Represent a composite, stdlib, or oracle call. |
NotOp | |
Operation | |
PauliEvolveOp | Pauli evolution operation: exp(-i * gamma * H). |
QInitOperation | Initialize the qubit |
ReturnOperation | Explicit return operation marking the end of a block with return values. |
ReturnQuantumArrayElementOperation | Validate a branch-selected quantum element’s array return at emit time. |
SelectOperation | Quantum multiplexer: apply case_blocks[i] when the index reads i. |
UnaryMathOp | Represent one pure unary mathematical expression. |
Functions¶
classify_control_work [source]¶
def classify_control_work(operation: Operation) -> ControlWorkKindReturn the shared coherent-control category for one IR operation.
BOOKKEEPING means zero controlled quantum work, not that the operation
may be discarded. Emitters must still run bookkeeping semantics such as
classical evaluation, cast alias propagation, and deferred borrow-return
validation.
Parameters:
| Name | Type | Description |
|---|---|---|
operation | Operation | IR operation inside a coherently controlled body. |
Returns:
ControlWorkKind — Semantic category consumed by both estimation and
emission policy.
Classes¶
BinOp [source]¶
class BinOp(BinaryOperationBase)Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN).
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
kind: BinOpKind | None = None,
) -> NoneAttributes¶
kind: BinOpKind | Noneoperation_kind: OperationKindsignature: Signature
CInitOperation [source]¶
class CInitOperation(Operation)Initialize the classical values (const, arguments etc)
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
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:
Vector[Qubit] -> QFixed (after QPE, for phase measurement)
Vector[Qubit] -> QUInt (for quantum arithmetic)
QUInt -> QFixed (reinterpret bits with different encoding)
QFixed -> QUInt (reinterpret bits with different encoding)
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(),
) -> NoneAttributes¶
num_qubits: int Number of qubits involved in the cast.operation_kind: OperationKind Cast stays in the same segment as its source (QUANTUM for quantum types).qubit_mapping: list[str]signature: Signature Return the type signature of this cast operation.source_type: ValueType | Nonetarget_type: ValueType | None
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,
) -> NoneAttributes¶
kind: CompOpKind | Noneoperation_kind: OperationKindsignature: Signature
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,
) -> NoneAttributes¶
kind: CondOpKind | Noneoperation_kind: OperationKindsignature: Signature
ControlWorkKind [source]¶
class ControlWorkKind(enum.Enum)Describe how an operation participates in coherent-control analysis.
Values:
BOOKKEEPING: The operation contributes no controlled quantum gate, but its validation or value/alias update may still have to execute. QUANTUM_LEAF: One primitive quantum gate whose decomposition policy is selected by the consumer. CONTEXT_DEPENDENT: A structured operation whose work must be resolved from its values, selected body, or nested regions. UNSUPPORTED: An operation outside the supported controlled-unitary language. Consumers keep it visible so their normal error path rejects it rather than silently dropping it.
Attributes¶
BOOKKEEPINGCONTEXT_DEPENDENTQUANTUM_LEAFUNSUPPORTED
ControlledUOperation [source]¶
class ControlledUOperation(Operation)Base class for controlled-U operations.
Two concrete subclasses handle distinct operand layouts:
ConcreteControlledU: Fixednum_controls: int, individual qubit operands.SymbolicControlledU: Symbolicnum_controls: Value, vector-based control operands; optionalcontrol_indicesselects a subset of the control vector to act as controls (the rest pass through).
All isinstance(op, ControlledUOperation) checks match every subclass.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
power: int | Value = 1,
block: Block | None = None,
num_controls: int | Value = 1,
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] = dict(),
) -> NoneAttributes¶
block: Block | Nonebody_operands: list[Value] Get the wrapped callable’s complete argument list.callable_attrs: dict[str, Any]callable_ref: CallableRef | Nonecontrol_operands: list[Value] Get the control qubit values.is_symbolic_num_controls: bool Whether num_controls is symbolic (Value) rather than concrete.num_controls: int | Valueoperation_kind: OperationKindparam_operands: list[Value] Get the controlled operation’s classical/object arguments.power: int | Valuesignature: Signaturetarget_operands: list[Value] Get the target qubit values (arguments to U).
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationDictGetItemOperation [source]¶
class DictGetItemOperation(Operation)Look up one entry of a Dict by a (possibly symbolic) key.
This is the IR form of d[key] on a Dict handle. The key
components may be symbolic (e.g. loop variables of a for-items
loop); the lookup is resolved at emit time when the key values and
the dict’s bound data are both concrete.
operands: [DictValue, *key_component_values] results: [looked-up scalar value]
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
key_arity: int = 1,
) -> NoneAttributes¶
dict_value: Value Value: The DictValue being indexed (operands[0]).key_arity: intkey_values: tuple[Value, ...] tuple[Value, ...]: The key component values.operation_kind: OperationKindsignature: Signature
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,
) -> NoneAttributes¶
gate_type: GateOperationType | Noneoperation_kind: OperationKindqubit_operands: list[Value] Qubit operands (excluding the theta parameter if present).signature: Signaturetheta: Value | None Angle parameter for rotation gates, orNonefor fixed gates.
Methods¶
fixed¶
@classmethod
def fixed(
cls,
gate_type: GateOperationType,
qubits: list[Value],
results: list[Value],
) -> 'GateOperation'Create a fixed gate (H, X, CX, SWAP, …) with no angle parameter.
rotation¶
@classmethod
def rotation(
cls,
gate_type: GateOperationType,
qubits: list[Value],
theta: Value,
results: list[Value],
) -> 'GateOperation'Create a rotation gate (RX, RY, RZ, P, CP, RZZ) with an angle.
GlobalPhaseOperation [source]¶
class GlobalPhaseOperation(Operation)Multiply the complete quantum state by exp(i * phase).
Global phase has no target qubit and does not create a new quantum value. Keeping the phase as the operation’s sole ordinary operand lets generic IR passes substitute, serialize, and analyze it without a special value-field protocol. A surrounding controlled-unitary lowering turns the operation into an observable phase gate on the accumulated controls.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | list[Value] | Exactly one scalar FloatType phase angle in radians. |
results | list[Value] | Must be empty because global phase changes no qubit identity. |
Raises:
ValueError— If the operand/result layout is invalid or the phase is not a scalarFloatTypevalue.
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKind Classify global phase as a quantum operation.phase: Value Return the scalar phase-angle operand.signature: Signature Return the zero-qubit operation signature.
HasNestedOps [source]¶
class HasNestedOpsMixin for operations that contain nested operation lists.
nested_regions() is the canonical traversal API because it exposes
operations together with block arguments, captures, and yields.
nested_op_lists() / rebuild_nested() remain compatibility helpers
for specialized consumers while they migrate to the region interface.
Methods¶
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]Return all nested operation lists in this control flow op.
nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return uniform views of every nested operation region.
Subclasses with explicit block arguments, captures, or yields override
this method. The fallback keeps legacy operation-owned blocks visible
while consumers migrate from nested_op_lists.
Returns:
tuple[Region, ...] — tuple[Region, ...]: Region views in nested_op_lists order.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> OperationReturn a copy with nested operation lists replaced.
new_lists must have the same length/order as nested_op_lists().
rebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationReturn a copy with replacement region operation sequences.
Concrete control-flow operations override this method to rebuild both their body operations and boundary values. The fallback supports legacy region owners whose boundary remains operation-specific.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Replacement regions in nested_regions order. |
Returns:
Operation — Rebuilt control-flow operation.
Raises:
ValueError— If the replacement region count differs from the operation’s current region count.
InverseBlockOperation [source]¶
class InverseBlockOperation(Operation)Represent an inverse qkernel/block as a first-class IR operation.
The operation stores both the original forward block and a Qamomile-built
inverse implementation block. Emitters may use source_block with a
backend-native inverse/adjoint primitive, then fall back to
implementation_block when native inversion is unavailable.
Operands are ordered as scalar control qubits, target quantum operands,
then classical/object parameters. Results mirror the quantum operand
layout: control results first, then one target result per target operand.
Vector target operands therefore count as one operand/result while
contributing their scalar width to num_target_qubits.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_control_qubits: int = 0,
num_target_qubits: int = 0,
custom_name: str = '',
source_block: Block | None = None,
implementation_block: Block | None = None,
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] = dict(),
control_value: int | None = None,
) -> NoneAttributes¶
callable_attrs: dict[str, Any]callable_ref: CallableRef | Nonecontrol_qubits: list[‘Value’] Return control quantum operands.control_value: int | Nonecustom_name: strimplementation_block: Block | Nonename: str Return a human-readable inverse operation name.num_control_qubits: intnum_target_qubits: intoperation_kind: OperationKind Return the operation kind.parameters: list[‘Value’] Return classical/object parameter operands.signature: Signature Return the operation signature.source_block: Block | Nonetarget_qubits: list[‘Value’] Return target quantum operands.
InvokeOperation [source]¶
class InvokeOperation(Operation)Represent a composite, stdlib, or oracle call.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | list[ValueLike] | Input values consumed by the call. |
results | list[ValueLike] | Output values produced by the call. |
target | CallableRef | Callable identity. |
transform | CallTransform | Direct, inverse, or controlled invocation. |
attrs | dict[str, Any] | Compile-time attributes for strategy, arity, and resource/lowering decisions. control_value is reserved for a controlled invocation’s LSB-first activation value. Values must be serializer-friendly. |
definition | CallableDef | None | Optional callable definition. |
Constructor¶
def __init__(
self,
operands: Sequence[ValueLike] | None = None,
results: Sequence[ValueLike] | None = None,
*,
target: CallableRef | None = None,
transform: CallTransform = CallTransform.DIRECT,
attrs: dict[str, Any] | None = None,
definition: CallableDef | None = None,
) -> NoneInitialize an invocation operation.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | Sequence[ValueLike] | None | Input values consumed by the call. Defaults to None, meaning no operands. |
results | Sequence[ValueLike] | None | Output values produced by the call. Defaults to None, meaning no results. |
target | CallableRef | None | Callable identity. Defaults to an anonymous user callable when omitted. |
transform | CallTransform | Requested call transform. Defaults to CallTransform.DIRECT. |
attrs | dict[str, Any] | None | Serializer-friendly call attributes. Defaults to an empty dict. |
definition | CallableDef | None | Callable definition. Defaults to None, in which case one is created from target. |
Raises:
TypeError— If a controlled invocation’scontrol_valueor an Oracle control-partition field has an invalid Python type.ValueError— Ifcontrol_valueis used on a non-controlled call or does not fit the controlled invocation’s width, or if Oracle invocation and definition control metadata disagree.
Attributes¶
attrs: dict[str, Any]body: Block | None Return the callable’s default body from its definition.body_ref: CallableBodyRef | None Return the callable’s deferred body reference.control_qubits: list[‘Value’] Return the control-qubit operands.control_value: int | None Return the controlled invocation’s activation value.custom_name: str Return the display name for custom callable boxes.default_policy: CallPolicy Return the callable’s default lowering policy.definition: CallableDef | Noneeffects: ‘KernelEffect’ Return cached effects of relevant callable implementations.gate_type: CompositeGateType Return the standard composite classification for this invocation.measurement_result_indices: frozenset[int] Return a conservative union of measurement-derived results.name: str Return the display name for this invocation.num_added_control_qubits: int Return controls introduced by a frontend control transform.num_body_external_control_qubits: int Return control operands generic lowering adds outside a base body.num_control_qubits: int Return the number of leading control-qubit operands.num_declared_control_qubits: int Return controls included in an opaque Oracle’s base definition.num_target_qubits: int Return the number of target-qubit operands.operandsoperation_kind: OperationKind Return the operation kind.parameters: list[‘Value’] Return non-qubit parameter operands.resultssignature: Signature Return the operation signature.strategy_name: str | None Return the selected lowering/resource strategy name.target: CallableReftarget_qubits: list[‘Value’] Return the target-qubit operands.transform: CallTransform
Methods¶
body_for_transform¶
def body_for_transform(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> tuple[Block | None, CallTransform]Select a body and report the transform it already realizes.
A controlled-inverse invocation may reuse an explicitly registered inverse body when no implementation realizes both transforms. Keeping that fallback in the IR operation gives emitters and static analyses one selection rule while still letting each consumer apply the remaining coherent controls in its own representation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None. |
strategy | str | None | Strategy name to match. Defaults to the invocation’s strategy_name attribute. |
Returns:
Block | None — tuple[Block | None, CallTransform]: Selected body and the transform
CallTransform — already implemented by that body. The callable’s direct body is
tuple[Block | None, CallTransform] — returned with DIRECT when no transform-specific body matches.
Raises:
ValueError— If the selected body disagrees with the invocation’s input or output contract.
effective_body¶
def effective_body(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> Block | NoneReturn the implementation body selected for this invocation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None. |
strategy | str | None | Strategy name to match. Defaults to the invocation’s strategy_name attribute. |
Returns:
Block | None — Block | None: Selected implementation body, or the callable’s
Block | None — default body when no transform-specific implementation exists.
Block | None — A compiler may synthesize inverse or controlled behavior from this
Block | None — fallback body.
implementation_for¶
def implementation_for(
self,
*,
backend: str | None = None,
strategy: str | None = None,
require_body: bool = False,
) -> CallableImplementation | NoneReturn the selected implementation for this invocation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None, which only selects backend-generic implementations. |
strategy | str | None | Strategy name to match. Defaults to None, meaning the invocation’s strategy_name attribute is used. |
require_body | bool | Whether candidates without an IR body should be excluded before ranking. Defaults to False. |
Returns:
CallableImplementation | None — CallableImplementation | None: Matching implementation candidate,
CallableImplementation | None — or None when the callable definition has no match.
measurement_result_indices_for¶
def measurement_result_indices_for(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> frozenset[int]Return measurement-derived results for one selected implementation.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name used for implementation selection. Defaults to None. |
strategy | str | None | Strategy name used for implementation selection. Defaults to the invocation’s strategy_name. |
Returns:
frozenset[int] — frozenset[int]: Caller-local result positions derived from
measurement in the selected body.
Raises:
ValueError— If the selected body disagrees with the invocation’s input or output contract.
select_body¶
def select_body(
self,
*,
backend: str | None = None,
strategy: str | None = None,
) -> CallableBodySelectionSelect and validate the composable body for this invocation.
The result carries the transform already realized by the body and the exact call-site values that bind to it. Consumers therefore cannot independently disagree about whether an invocation’s control prefix belongs to the selected implementation ABI.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | str | None | Backend name to match. Defaults to None. |
strategy | str | None | Strategy name to match. Defaults to the invocation’s strategy_name attribute. |
Returns:
CallableBodySelection — Validated body, realized transform, and
CallableBodySelection — aligned call-site operands and results.
Raises:
ValueError— If the selected body disagrees with the invocation’s input or output contract.
NotOp [source]¶
class NotOp(Operation)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
input: Valueoperation_kind: OperationKindoutput: Valuesignature: Signature
Operation [source]¶
class Operation(abc.ABC)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operands: list[Value]operation_kind: OperationKind Return the kind of this operation for classical/quantum classification.results: list[Value]signature: Signature
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]) -> OperationReturn a copy with all Values substituted via mapping.
Handles operands, results, and subclass-specific Value
fields. Subclasses override to handle their extra fields.
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()) -> NoneAttributes¶
evolved_qubits: Value The evolved quantum register result.gamma: Value The evolution time parameter.observable: Value The Observable parameter operand.operation_kind: OperationKind PauliEvolveOp is QUANTUM - transforms quantum state.qubits: Value The quantum register operand.signature: Signature
QInitOperation [source]¶
class QInitOperation(Operation)Initialize the qubit
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
ReturnOperation [source]¶
class ReturnOperation(Operation)Explicit return operation marking the end of a block with return values.
This operation represents an explicit return statement in the IR. It takes the values to be returned as operands and produces no results (it is a terminal operation that transfers control flow back to the caller).
operands: [Value, ...] - The values to return (may be empty for void returns) results: [] - Always empty (terminal operation)
Example:
A function that returns two values (a UInt and a Float):
ReturnOperation(
operands=[uint_value, float_value],
results=[],
)
The signature would be:
operands=[ParamHint("return_0", UIntType()), ParamHint("return_1", FloatType())]
results=[]Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKind Return CLASSICAL as this is a control flow operation without quantum effects.signature: Signature Return the signature with operands for each return value and no results.
ReturnQuantumArrayElementOperation [source]¶
class ReturnQuantumArrayElementOperation(Operation)Validate a branch-selected quantum element’s array return at emit time.
Most quantum element assignments are verified structurally by the frontend and emit no IR. A compile-time conditional can instead select different element indices on its branches; only the unrolled emit context knows which source index survived. This operation carries both the requested target indices and the conditional source indices so emission can prove they resolve to the same physical slot before treating the assignment as a borrow return.
Operand convention:
[array, returned_qubit, *target_indices, *source_indices]. The
target and source halves have equal nonzero arity, inferred from the
operand count. The operation has no results and emits no backend gate.
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
array: ArrayValue Return the quantum array receiving the borrowed element.index_arity: int Return the number of target (and source) index operands.operation_kind: OperationKind Classify the return validator as a quantum operation.returned_value: Value Return the quantum value being returned.signature: Signature Return the deferred validator’s operand-only signature.source_indices: tuple[Value, ...] Return the branch-merged borrow-source indices.target_indices: tuple[Value, ...] Return the user-written assignment indices.
SelectOperation [source]¶
class SelectOperation(Operation)Quantum multiplexer: apply case_blocks[i] when the index reads i.
Concrete operand layout:
[idx_0, ..., idx_{k-1}, tgt_0, ..., tgt_m, params...].
Symbolic-width operand layout:
[idx_arg_0, ..., idx_arg_{a-1}, tgt_0, ..., tgt_m, params...].
Results mirror the quantum operand grouping.
A concrete index register is normalized to one scalar Qubit operand
per physical index qubit. A symbolic-width register instead retains each
leading caller argument as one scalar or array operand until its bound
shape is known. Whole-Vector[Qubit] / scalar targets follow and keep
their shapes, and classical parameters shared across every case come last.
Index bit order is LSB-first: idx_0 is the least-significant
bit, matching Qamomile’s qubit-zero convention. Case i is selected
when index qubit j reads bit j of i. len(case_blocks)
need not be a power of two; index values >= len(case_blocks) apply
no operation (identity).
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_index_qubits: int | Value = 0,
case_blocks: list[Block] = list(),
num_index_args: int = 0,
case_callable_attrs: list[dict[str, Any]] = list(),
) -> NoneAttributes¶
case_blocks: list[Block]case_callable_attrs: list[dict[str, Any]]index_operands: list[Value] Return the grouped index-prefix operands.is_symbolic_num_index_qubits: bool Return whether the index width is a symbolic IR value.num_cases: int Return the number of selectable cases.num_index_args: intnum_index_qubits: int | Valueoperation_kind: OperationKind Return the operation kind.param_operands: list[Value] Return the shared classical parameter operands.signature: Signature Return the operation signature.target_operands: list[Value] Return the quantum target operands applied by every case.
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Return every value consumed by the SELECT operation.
Returns:
list[ValueBase] — list[ValueBase]: Ordinary operands plus the symbolic index-width
value when present.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationReplace operand and symbolic-width values by UUID.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | dict[str, ValueBase] | UUID-keyed replacement values. |
Returns:
Operation — Rebuilt SELECT operation with matching values replaced.
UnaryMathOp [source]¶
class UnaryMathOp(Operation)Represent one pure unary mathematical expression.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | list[Value] | Single numeric input value. |
results | list[Value] | Single numeric result value. |
kind | UnaryMathOpKind | None | Mathematical operation to apply. |
Raises:
ValueError— Ifkindis missing or the operation does not have exactly one operand and one result.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
kind: UnaryMathOpKind | None = None,
) -> NoneAttributes¶
input: Value Return the input value.kind: UnaryMathOpKind | Noneoperation_kind: OperationKind Classify the operation as classical.output: Value Return the output value.signature: Signature Return the typed unary signature.
qamomile.circuit.ir.operation.expval¶
Expectation value operation for computing <psi|H|psi>.
This module defines the ExpvalOp IR operation that represents computing the expectation value of a Hamiltonian observable with respect to a quantum state.
Overview¶
| Class | Description |
|---|---|
ExpvalOp | Expectation value operation. |
FloatType | Type representing a floating-point number. |
ObservableType | Type representing a Hamiltonian observable parameter. |
Operation | |
OperationKind | Classification of operations for classical/quantum separation. |
ParamHint | |
Signature | |
Value | A typed SSA value in the IR. |
Classes¶
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:
Input: quantum state (qubits) + Observable reference
Output: classical Float (expectation value)
Example IR:
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
hamiltonian: Value Alias for observable (deprecated, use observable instead).observable: Value The Observable parameter operand.operation_kind: OperationKind ExpvalOp is HYBRID - bridges quantum state to classical value.output: Value The expectation value result.qubits: Value The quantum register operand.signature: Signature
FloatType [source]¶
class FloatType(ClassicalTypeMixin, ValueType)Type representing a floating-point number.
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) -> NoneOperation [source]¶
class Operation(abc.ABC)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operands: list[Value]operation_kind: OperationKind Return the kind of this operation for classical/quantum classification.results: list[Value]signature: Signature
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]) -> OperationReturn a copy with all Values substituted via mapping.
Handles operands, results, and subclass-specific Value
fields. Subclasses override to handle their extra fields.
OperationKind [source]¶
class OperationKind(enum.Enum)Classification of operations for classical/quantum separation.
This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.
Values:
QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)
Attributes¶
CLASSICALCONTROLHYBRIDQUANTUM
ParamHint [source]¶
class ParamHintConstructor¶
def __init__(self, name: str, type: ValueType) -> NoneAttributes¶
name: strtype: ValueType
Signature [source]¶
class SignatureConstructor¶
def __init__(
self,
operands: list[ParamHint | None] = list(),
results: list[ParamHint] = list(),
) -> NoneAttributes¶
operands: list[ParamHint | None]results: list[ParamHint]
Value [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.ir.operation.gate¶
Overview¶
| Function | Description |
|---|---|
normalize_control_value | Normalize an integer activation state for a control register. |
| Class | Description |
|---|---|
BitType | Type representing a classical bit. |
Block | Unified block representation for all pipeline stages. |
CallableRef | Identify a callable independently of its Python object. |
ConcreteControlledU | Controlled-U with concrete (int) number of controls. |
ControlledUOperation | Base class for controlled-U operations. |
FloatType | Type representing a floating-point number. |
GateOperation | Quantum gate operation. |
GateOperationType | |
MeasureOperation | |
MeasureQFixedOperation | Measure a quantum fixed-point number. |
MeasureVectorOperation | Measure a vector of qubits. |
Operation | |
OperationKind | Classification of operations for classical/quantum separation. |
ParamHint | |
ProjectOperation | Project a qubit in one Pauli basis and keep the projected state. |
QubitType | Type representing a quantum bit (qubit). |
ResetOperation | Reset a qubit to the |0> state and return the fresh handle. |
Signature | |
SymbolicControlledU | Controlled-U with symbolic (Value) number of controls. |
UIntType | Type representing an unsigned integer. |
Value | A typed SSA value in the IR. |
ValueBase | Nominal base for every typed IR value. |
Functions¶
normalize_control_value [source]¶
def normalize_control_value(control_value: int | None, num_controls: int) -> int | NoneNormalize an integer activation state for a control register.
Control qubits follow Qamomile’s LSB-first integer convention: bit j
of control_value describes the j-th flattened control operand.
None and the all-ones value are the canonical ordinary-control state.
Parameters:
| Name | Type | Description |
|---|---|---|
control_value | int | None | Required computational-basis value, or None for the ordinary all-ones control state. |
num_controls | int | Concrete positive control-register width. |
Returns:
int | None — int | None: A non-default activation value, or None for all-ones.
Raises:
TypeError— Ifcontrol_valueis not a PythonintorNone.ValueError— Ifnum_controlsis not positive, or ifcontrol_valuedoes not fit in the control-register width.
Classes¶
BitType [source]¶
class BitType(ClassicalTypeMixin, ValueType)Type representing a classical bit.
Block [source]¶
class BlockUnified 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[ValueLike] = list(),
output_values: list[ValueLike] = list(),
output_names: list[str] = list(),
operations: list['Operation'] = list(),
kind: BlockKind = BlockKind.HIERARCHICAL,
parameters: dict[str, Value] = dict(),
param_slots: tuple[ParamSlot, ...] = tuple(),
static_bindings: tuple[StaticBindingSlot, ...] = tuple(),
) -> NoneAttributes¶
effects: ‘KernelEffect’ Return lazily cached semantic effects for this block.input_values: list[ValueLike]kind: BlockKindlabel_args: list[str]measurement_result_indices: frozenset[int] Return public output positions derived from measurement.name: stroperations: list[‘Operation’]output_names: list[str]output_values: list[ValueLike]param_slots: tuple[ParamSlot, ...]parameters: dict[str, Value]static_bindings: tuple[StaticBindingSlot, ...]
Methods¶
call¶
def call(self, **kwargs: ValueLike = {}) -> 'InvokeOperation'Create an inline callable invocation against this block.
Parameters:
| Name | Type | Description |
|---|---|---|
**kwargs | ValueLike | Actual argument values keyed by self.label_args. |
Returns:
'InvokeOperation' — Inline-policy invocation whose callable
definition points at this block.
Raises:
KeyError— If a required label inself.label_argsis missing fromkwargs.
is_affine¶
def is_affine(self) -> boolReturn whether this block has passed affine validation.
Returns:
bool — True for AFFINE and ANALYZED blocks.
unbound_parameters¶
def unbound_parameters(self) -> list[str]Return list of unbound parameter names.
CallableRef [source]¶
class CallableRefIdentify a callable independently of its Python object.
Parameters:
| Name | Type | Description |
|---|---|---|
namespace | str | Stable namespace such as "qamomile.stdlib" or "user". |
name | str | Stable callable name within the namespace. |
version | str | Schema or behavior version for the callable. |
Constructor¶
def __init__(self, namespace: str, name: str, version: str = '1') -> NoneAttributes¶
name: strnamespace: strversion: str
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,
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] = dict(),
control_value: int | None = None,
) -> NoneAttributes¶
control_operands: list[Value]control_value: int | Nonenum_controls: intparam_operands: list[Value] Get classical/object operands after the concrete control prefix.signature: Signature Build the concrete controlled call signature.target_operands: list[Value] Return the wrapped callable’s target and parameter operands.
ControlledUOperation [source]¶
class ControlledUOperation(Operation)Base class for controlled-U operations.
Two concrete subclasses handle distinct operand layouts:
ConcreteControlledU: Fixednum_controls: int, individual qubit operands.SymbolicControlledU: Symbolicnum_controls: Value, vector-based control operands; optionalcontrol_indicesselects a subset of the control vector to act as controls (the rest pass through).
All isinstance(op, ControlledUOperation) checks match every subclass.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
power: int | Value = 1,
block: Block | None = None,
num_controls: int | Value = 1,
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] = dict(),
) -> NoneAttributes¶
block: Block | Nonebody_operands: list[Value] Get the wrapped callable’s complete argument list.callable_attrs: dict[str, Any]callable_ref: CallableRef | Nonecontrol_operands: list[Value] Get the control qubit values.is_symbolic_num_controls: bool Whether num_controls is symbolic (Value) rather than concrete.num_controls: int | Valueoperation_kind: OperationKindparam_operands: list[Value] Get the controlled operation’s classical/object arguments.power: int | Valuesignature: Signaturetarget_operands: list[Value] Get the target qubit values (arguments to U).
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationFloatType [source]¶
class FloatType(ClassicalTypeMixin, ValueType)Type representing a floating-point number.
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,
) -> NoneAttributes¶
gate_type: GateOperationType | Noneoperation_kind: OperationKindqubit_operands: list[Value] Qubit operands (excluding the theta parameter if present).signature: Signaturetheta: Value | None Angle parameter for rotation gates, orNonefor fixed gates.
Methods¶
fixed¶
@classmethod
def fixed(
cls,
gate_type: GateOperationType,
qubits: list[Value],
results: list[Value],
) -> 'GateOperation'Create a fixed gate (H, X, CX, SWAP, …) with no angle parameter.
rotation¶
@classmethod
def rotation(
cls,
gate_type: GateOperationType,
qubits: list[Value],
theta: Value,
results: list[Value],
) -> 'GateOperation'Create a rotation gate (RX, RY, RZ, P, CP, RZZ) with an angle.
GateOperationType [source]¶
class GateOperationType(enum.Enum)Attributes¶
CPCXCZHPRXRYRZRZZSSDGSWAPTTDGTOFFOLIXYZ
MeasureOperation [source]¶
class MeasureOperation(Operation)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
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):
Qubits are stored least-significant first. For n qubits,
bit i has weight 2**(-n + i).
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_bits: int = 0,
int_bits: int = 0,
) -> NoneAttributes¶
int_bits: intnum_bits: intoperation_kind: OperationKindsignature: Signature
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()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
Operation [source]¶
class Operation(abc.ABC)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operands: list[Value]operation_kind: OperationKind Return the kind of this operation for classical/quantum classification.results: list[Value]signature: Signature
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]) -> OperationReturn a copy with all Values substituted via mapping.
Handles operands, results, and subclass-specific Value
fields. Subclasses override to handle their extra fields.
OperationKind [source]¶
class OperationKind(enum.Enum)Classification of operations for classical/quantum separation.
This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.
Values:
QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)
Attributes¶
CLASSICALCONTROLHYBRIDQUANTUM
ParamHint [source]¶
class ParamHintConstructor¶
def __init__(self, name: str, type: ValueType) -> NoneAttributes¶
name: strtype: ValueType
ProjectOperation [source]¶
class ProjectOperation(Operation)Project a qubit in one Pauli basis and keep the projected state.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
axis: str = 'z',
) -> NoneAttributes¶
axis: stroperation_kind: OperationKindsignature: Signature
QubitType [source]¶
class QubitType(QuantumTypeMixin, ValueType)Type representing a quantum bit (qubit).
ResetOperation [source]¶
class ResetOperation(Operation)Reset a qubit to the |0> state and return the fresh handle.
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
Signature [source]¶
class SignatureConstructor¶
def __init__(
self,
operands: list[ParamHint | None] = list(),
results: list[ParamHint] = list(),
) -> NoneAttributes¶
operands: list[ParamHint | None]results: list[ParamHint]
SymbolicControlledU [source]¶
class SymbolicControlledU(ControlledUOperation)Controlled-U with symbolic (Value) number of controls.
Operand layout: [ctrl_arg_0, ..., ctrl_arg_{k-1}, tgt_0, ..., tgt_m, params...]
Result layout: [ctrl_arg_0', ..., ctrl_arg_{k-1}', tgt_0', ..., tgt_m']
The number of control arguments k is recorded in
num_control_args; the default k = 1 corresponds to the
historical single-pool form (operands[0] is a
Vector[Qubit] / VectorView whose length equals
num_controls, or whose control_indices-selected subset
does). When k > 1 the control prefix is a heterogeneous
sequence of scalar Qubit values and ArrayValues whose
total qubit count is num_controls; the emit pass walks them
in order to recover the per-physical-qubit control set.
When control_indices is None the entire control prefix
is used as active controls (one-arg form: len(ctrl_vector) == num_controls; multi-arg form: the qubit-count sum of the
prefix args equals num_controls). When non-None, the
listed indices select exactly num_controls slots from a
single-arg pool to act as controls; combining
control_indices with the multi-arg control prefix is
rejected at frontend time.
Each control_indices entry is stored as a Value of
UIntType regardless of whether the frontend passed an
int literal or a UInt handle, so all downstream
value-substitution passes see a uniform shape.
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=(UIntType()), name=''))(),
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] = dict(),
control_indices: tuple[Value, ...] | None = None,
num_control_args: int = 1,
) -> NoneAttributes¶
control_indices: tuple[Value, ...] | Nonecontrol_operands: list[Value]is_symbolic_num_controls: boolnum_control_args: intnum_controls: Valueparam_operands: list[Value] Get classical/object operands after the symbolic control prefix.signature: Signaturetarget_operands: list[Value] Return the wrapped callable’s target and parameter operands.
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationUIntType [source]¶
class UIntType(ClassicalTypeMixin, ValueType)Type representing an unsigned integer.
Value [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.
ValueBase [source]¶
class ValueBaseNominal base for every typed IR value.
Runtime compiler passes inspect values in their innermost loops. A nominal base keeps those checks constant-time; a runtime-checkable protocol would repeatedly scan the protocol members on Python versions that do not cache structural checks.
Attributes¶
logical_id: strmetadata: ValueMetadataname: strtype: ValueType Return the static IR type carried by this value.uuid: str
Methods¶
get_const¶
def get_const(self) -> int | float | bool | NoneReturn the scalar constant carried by this value.
Returns:
int | float | bool | None — int | float | bool | None: Constant value, or None when the
value is not constant.
is_constant¶
def is_constant(self) -> boolReturn whether this value carries a scalar constant.
Returns:
bool — Whether scalar constant metadata is present.
is_parameter¶
def is_parameter(self) -> boolReturn whether this value represents a runtime parameter.
Returns:
bool — Whether parameter metadata is present.
next_version¶
def next_version(self) -> ValueBaseCreate the next SSA version of this value.
Returns:
ValueBase — A value with a fresh version UUID and preserved logical
identity.
parameter_name¶
def parameter_name(self) -> str | NoneReturn the public parameter name carried by this value.
Returns:
str | None — str | None: Parameter name, or None for a non-parameter value.
qamomile.circuit.ir.operation.global_phase¶
Define the zero-qubit global-phase IR operation.
Overview¶
| Class | Description |
|---|---|
ArrayValue | An array of typed IR values. |
FloatType | Type representing a floating-point number. |
GlobalPhaseOperation | Multiply the complete quantum state by exp(i * phase). |
Operation | |
OperationKind | Classification of operations for classical/quantum separation. |
ParamHint | |
Signature | |
Value | A typed SSA value in the IR. |
Classes¶
ArrayValue [source]¶
class ArrayValue(Value[T])An array of typed IR values.
When slice_of is set, this array is a strided view over another
array. Element accesses on a sliced ArrayValue resolve to
physical slots on the root parent via the affine map
parent_index = slice_start + slice_step * view_local_index,
applied recursively along slice_of chains. The emit-time
resolver walks this chain to produce the final qubit index; passes
that substitute or clone values must treat slice_of /
slice_start / slice_step as Value references that need to
track through the same mapping as parent_array.
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(),
slice_of: 'ArrayValue | None' = None,
slice_start: 'Value | None' = None,
slice_step: 'Value | None' = None,
) -> NoneAttributes¶
logical_id: strmetadata: ValueMetadataname: strshape: tuple[Value, ...]slice_of: ‘ArrayValue | None’slice_start: ‘Value | None’slice_step: ‘Value | None’type: Tuuid: str
Methods¶
is_slice¶
def is_slice(self) -> boolReturn True if this array is a strided view of another array.
Returns:
bool — True iff slice_of is non-None.
next_version¶
def next_version(self) -> ArrayValue[T]FloatType [source]¶
class FloatType(ClassicalTypeMixin, ValueType)Type representing a floating-point number.
GlobalPhaseOperation [source]¶
class GlobalPhaseOperation(Operation)Multiply the complete quantum state by exp(i * phase).
Global phase has no target qubit and does not create a new quantum value. Keeping the phase as the operation’s sole ordinary operand lets generic IR passes substitute, serialize, and analyze it without a special value-field protocol. A surrounding controlled-unitary lowering turns the operation into an observable phase gate on the accumulated controls.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | list[Value] | Exactly one scalar FloatType phase angle in radians. |
results | list[Value] | Must be empty because global phase changes no qubit identity. |
Raises:
ValueError— If the operand/result layout is invalid or the phase is not a scalarFloatTypevalue.
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKind Classify global phase as a quantum operation.phase: Value Return the scalar phase-angle operand.signature: Signature Return the zero-qubit operation signature.
Operation [source]¶
class Operation(abc.ABC)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operands: list[Value]operation_kind: OperationKind Return the kind of this operation for classical/quantum classification.results: list[Value]signature: Signature
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]) -> OperationReturn a copy with all Values substituted via mapping.
Handles operands, results, and subclass-specific Value
fields. Subclasses override to handle their extra fields.
OperationKind [source]¶
class OperationKind(enum.Enum)Classification of operations for classical/quantum separation.
This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.
Values:
QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)
Attributes¶
CLASSICALCONTROLHYBRIDQUANTUM
ParamHint [source]¶
class ParamHintConstructor¶
def __init__(self, name: str, type: ValueType) -> NoneAttributes¶
name: strtype: ValueType
Signature [source]¶
class SignatureConstructor¶
def __init__(
self,
operands: list[ParamHint | None] = list(),
results: list[ParamHint] = list(),
) -> NoneAttributes¶
operands: list[ParamHint | None]results: list[ParamHint]
Value [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.ir.operation.inverse_block¶
First-class inverse block operation.
InverseBlockOperation represents “apply the inverse of this block”
as a single IR operation. It shares the operand layout convention of
:class:~qamomile.circuit.ir.operation.callable.InvokeOperation
(control qubits, then quantum targets, then classical/object
parameters) but is an independent :class:Operation subclass, not a
composite-gate variant.
Overview¶
| Function | Description |
|---|---|
normalize_control_value | Normalize an integer activation state for a control register. |
quantum_operand_widths | Decode exact quantum-operand widths from callable resource metadata. |
static_quantum_width | Return a quantum value’s compile-time scalar-qubit width. |
| Class | Description |
|---|---|
ArrayValue | An array of typed IR values. |
Block | Unified block representation for all pipeline stages. |
BlockType | Type representing a block/function reference. |
CallableRef | Identify a callable independently of its Python object. |
InverseBlockOperation | Represent an inverse qkernel/block as a first-class IR operation. |
Operation | |
OperationKind | Classification of operations for classical/quantum separation. |
ParamHint | |
QubitType | Type representing a quantum bit (qubit). |
Signature | |
Value | A typed SSA value in the IR. |
Functions¶
normalize_control_value [source]¶
def normalize_control_value(control_value: int | None, num_controls: int) -> int | NoneNormalize an integer activation state for a control register.
Control qubits follow Qamomile’s LSB-first integer convention: bit j
of control_value describes the j-th flattened control operand.
None and the all-ones value are the canonical ordinary-control state.
Parameters:
| Name | Type | Description |
|---|---|---|
control_value | int | None | Required computational-basis value, or None for the ordinary all-ones control state. |
num_controls | int | Concrete positive control-register width. |
Returns:
int | None — int | None: A non-default activation value, or None for all-ones.
Raises:
TypeError— Ifcontrol_valueis not a PythonintorNone.ValueError— Ifnum_controlsis not positive, or ifcontrol_valuedoes not fit in the control-register width.
quantum_operand_widths [source]¶
def quantum_operand_widths(attrs: Mapping[str, Any], *, source: str) -> tuple[QuantumOperandWidth, ...]Decode exact quantum-operand widths from callable resource metadata.
Parameters:
| Name | Type | Description |
|---|---|---|
attrs | Mapping[str, Any] | Callable definition or operation attrs. |
source | str | Callable name used in malformed-contract diagnostics. |
Returns:
tuple[QuantumOperandWidth, ...] — tuple[QuantumOperandWidth, ...]: Validated exact-width entries, or an
empty tuple when the callable declares no such contract.
Raises:
ValueError— If present resource metadata is malformed or repeats an operand index.
static_quantum_width [source]¶
def static_quantum_width(value: ValueBase) -> int | NoneReturn a quantum value’s compile-time scalar-qubit width.
The helper understands both ordinary qubit arrays and packed quantum register carriers. Runtime carrier metadata is preferred when present because it records the physical scalar values represented by a packed value even when its type-level width is symbolic.
Parameters:
| Name | Type | Description |
|---|---|---|
value | ValueBase | Quantum scalar, array, or packed register value. |
Returns:
int | None — int | None: Non-negative scalar-qubit width, or None when the
value is non-quantum or any required dimension remains symbolic.
Classes¶
ArrayValue [source]¶
class ArrayValue(Value[T])An array of typed IR values.
When slice_of is set, this array is a strided view over another
array. Element accesses on a sliced ArrayValue resolve to
physical slots on the root parent via the affine map
parent_index = slice_start + slice_step * view_local_index,
applied recursively along slice_of chains. The emit-time
resolver walks this chain to produce the final qubit index; passes
that substitute or clone values must treat slice_of /
slice_start / slice_step as Value references that need to
track through the same mapping as parent_array.
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(),
slice_of: 'ArrayValue | None' = None,
slice_start: 'Value | None' = None,
slice_step: 'Value | None' = None,
) -> NoneAttributes¶
logical_id: strmetadata: ValueMetadataname: strshape: tuple[Value, ...]slice_of: ‘ArrayValue | None’slice_start: ‘Value | None’slice_step: ‘Value | None’type: Tuuid: str
Methods¶
is_slice¶
def is_slice(self) -> boolReturn True if this array is a strided view of another array.
Returns:
bool — True iff slice_of is non-None.
next_version¶
def next_version(self) -> ArrayValue[T]Block [source]¶
class BlockUnified 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[ValueLike] = list(),
output_values: list[ValueLike] = list(),
output_names: list[str] = list(),
operations: list['Operation'] = list(),
kind: BlockKind = BlockKind.HIERARCHICAL,
parameters: dict[str, Value] = dict(),
param_slots: tuple[ParamSlot, ...] = tuple(),
static_bindings: tuple[StaticBindingSlot, ...] = tuple(),
) -> NoneAttributes¶
effects: ‘KernelEffect’ Return lazily cached semantic effects for this block.input_values: list[ValueLike]kind: BlockKindlabel_args: list[str]measurement_result_indices: frozenset[int] Return public output positions derived from measurement.name: stroperations: list[‘Operation’]output_names: list[str]output_values: list[ValueLike]param_slots: tuple[ParamSlot, ...]parameters: dict[str, Value]static_bindings: tuple[StaticBindingSlot, ...]
Methods¶
call¶
def call(self, **kwargs: ValueLike = {}) -> 'InvokeOperation'Create an inline callable invocation against this block.
Parameters:
| Name | Type | Description |
|---|---|---|
**kwargs | ValueLike | Actual argument values keyed by self.label_args. |
Returns:
'InvokeOperation' — Inline-policy invocation whose callable
definition points at this block.
Raises:
KeyError— If a required label inself.label_argsis missing fromkwargs.
is_affine¶
def is_affine(self) -> boolReturn whether this block has passed affine validation.
Returns:
bool — True for AFFINE and ANALYZED blocks.
unbound_parameters¶
def unbound_parameters(self) -> list[str]Return list of unbound parameter names.
BlockType [source]¶
class BlockType(ObjectTypeMixin, ValueType)Type representing a block/function reference.
CallableRef [source]¶
class CallableRefIdentify a callable independently of its Python object.
Parameters:
| Name | Type | Description |
|---|---|---|
namespace | str | Stable namespace such as "qamomile.stdlib" or "user". |
name | str | Stable callable name within the namespace. |
version | str | Schema or behavior version for the callable. |
Constructor¶
def __init__(self, namespace: str, name: str, version: str = '1') -> NoneAttributes¶
name: strnamespace: strversion: str
InverseBlockOperation [source]¶
class InverseBlockOperation(Operation)Represent an inverse qkernel/block as a first-class IR operation.
The operation stores both the original forward block and a Qamomile-built
inverse implementation block. Emitters may use source_block with a
backend-native inverse/adjoint primitive, then fall back to
implementation_block when native inversion is unavailable.
Operands are ordered as scalar control qubits, target quantum operands,
then classical/object parameters. Results mirror the quantum operand
layout: control results first, then one target result per target operand.
Vector target operands therefore count as one operand/result while
contributing their scalar width to num_target_qubits.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_control_qubits: int = 0,
num_target_qubits: int = 0,
custom_name: str = '',
source_block: Block | None = None,
implementation_block: Block | None = None,
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] = dict(),
control_value: int | None = None,
) -> NoneAttributes¶
callable_attrs: dict[str, Any]callable_ref: CallableRef | Nonecontrol_qubits: list[‘Value’] Return control quantum operands.control_value: int | Nonecustom_name: strimplementation_block: Block | Nonename: str Return a human-readable inverse operation name.num_control_qubits: intnum_target_qubits: intoperation_kind: OperationKind Return the operation kind.parameters: list[‘Value’] Return classical/object parameter operands.signature: Signature Return the operation signature.source_block: Block | Nonetarget_qubits: list[‘Value’] Return target quantum operands.
Operation [source]¶
class Operation(abc.ABC)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operands: list[Value]operation_kind: OperationKind Return the kind of this operation for classical/quantum classification.results: list[Value]signature: Signature
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]) -> OperationReturn a copy with all Values substituted via mapping.
Handles operands, results, and subclass-specific Value
fields. Subclasses override to handle their extra fields.
OperationKind [source]¶
class OperationKind(enum.Enum)Classification of operations for classical/quantum separation.
This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.
Values:
QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)
Attributes¶
CLASSICALCONTROLHYBRIDQUANTUM
ParamHint [source]¶
class ParamHintConstructor¶
def __init__(self, name: str, type: ValueType) -> NoneAttributes¶
name: strtype: ValueType
QubitType [source]¶
class QubitType(QuantumTypeMixin, ValueType)Type representing a quantum bit (qubit).
Signature [source]¶
class SignatureConstructor¶
def __init__(
self,
operands: list[ParamHint | None] = list(),
results: list[ParamHint] = list(),
) -> NoneAttributes¶
operands: list[ParamHint | None]results: list[ParamHint]
Value [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.ir.operation.operation¶
Overview¶
| Class | Description |
|---|---|
CInitOperation | Initialize the classical values (const, arguments etc) |
Operation | |
OperationKind | Classification of operations for classical/quantum separation. |
ParamHint | |
QInitOperation | Initialize the qubit |
Signature | |
Value | A typed SSA value in the IR. |
ValueBase | Nominal base for every typed IR value. |
Classes¶
CInitOperation [source]¶
class CInitOperation(Operation)Initialize the classical values (const, arguments etc)
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
Operation [source]¶
class Operation(abc.ABC)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operands: list[Value]operation_kind: OperationKind Return the kind of this operation for classical/quantum classification.results: list[Value]signature: Signature
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]) -> OperationReturn a copy with all Values substituted via mapping.
Handles operands, results, and subclass-specific Value
fields. Subclasses override to handle their extra fields.
OperationKind [source]¶
class OperationKind(enum.Enum)Classification of operations for classical/quantum separation.
This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.
Values:
QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)
Attributes¶
CLASSICALCONTROLHYBRIDQUANTUM
ParamHint [source]¶
class ParamHintConstructor¶
def __init__(self, name: str, type: ValueType) -> NoneAttributes¶
name: strtype: ValueType
QInitOperation [source]¶
class QInitOperation(Operation)Initialize the qubit
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
Signature [source]¶
class SignatureConstructor¶
def __init__(
self,
operands: list[ParamHint | None] = list(),
results: list[ParamHint] = list(),
) -> NoneAttributes¶
operands: list[ParamHint | None]results: list[ParamHint]
Value [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.
ValueBase [source]¶
class ValueBaseNominal base for every typed IR value.
Runtime compiler passes inspect values in their innermost loops. A nominal base keeps those checks constant-time; a runtime-checkable protocol would repeatedly scan the protocol members on Python versions that do not cache structural checks.
Attributes¶
logical_id: strmetadata: ValueMetadataname: strtype: ValueType Return the static IR type carried by this value.uuid: str
Methods¶
get_const¶
def get_const(self) -> int | float | bool | NoneReturn the scalar constant carried by this value.
Returns:
int | float | bool | None — int | float | bool | None: Constant value, or None when the
value is not constant.
is_constant¶
def is_constant(self) -> boolReturn whether this value carries a scalar constant.
Returns:
bool — Whether scalar constant metadata is present.
is_parameter¶
def is_parameter(self) -> boolReturn whether this value represents a runtime parameter.
Returns:
bool — Whether parameter metadata is present.
next_version¶
def next_version(self) -> ValueBaseCreate the next SSA version of this value.
Returns:
ValueBase — A value with a fresh version UUID and preserved logical
identity.
parameter_name¶
def parameter_name(self) -> str | NoneReturn the public parameter name carried by this value.
Returns:
str | None — str | None: Parameter name, or None for a non-parameter value.
qamomile.circuit.ir.operation.pauli_evolve¶
Pauli evolution operation for applying exp(-i * gamma * H).
This module defines the PauliEvolveOp IR operation that represents applying Hamiltonian time evolution to a quantum state.
Overview¶
| Class | Description |
|---|---|
FloatType | Type representing a floating-point number. |
ObservableType | Type representing a Hamiltonian observable parameter. |
Operation | |
OperationKind | Classification of operations for classical/quantum separation. |
ParamHint | |
PauliEvolveOp | Pauli evolution operation: exp(-i * gamma * H). |
Signature | |
Value | A typed SSA value in the IR. |
Classes¶
FloatType [source]¶
class FloatType(ClassicalTypeMixin, ValueType)Type representing a floating-point number.
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) -> NoneOperation [source]¶
class Operation(abc.ABC)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operands: list[Value]operation_kind: OperationKind Return the kind of this operation for classical/quantum classification.results: list[Value]signature: Signature
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]) -> OperationReturn a copy with all Values substituted via mapping.
Handles operands, results, and subclass-specific Value
fields. Subclasses override to handle their extra fields.
OperationKind [source]¶
class OperationKind(enum.Enum)Classification of operations for classical/quantum separation.
This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.
Values:
QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)
Attributes¶
CLASSICALCONTROLHYBRIDQUANTUM
ParamHint [source]¶
class ParamHintConstructor¶
def __init__(self, name: str, type: ValueType) -> NoneAttributes¶
name: strtype: ValueType
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()) -> NoneAttributes¶
evolved_qubits: Value The evolved quantum register result.gamma: Value The evolution time parameter.observable: Value The Observable parameter operand.operation_kind: OperationKind PauliEvolveOp is QUANTUM - transforms quantum state.qubits: Value The quantum register operand.signature: Signature
Signature [source]¶
class SignatureConstructor¶
def __init__(
self,
operands: list[ParamHint | None] = list(),
results: list[ParamHint] = list(),
) -> NoneAttributes¶
operands: list[ParamHint | None]results: list[ParamHint]
Value [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.ir.operation.return_operation¶
Return operation for explicit block termination.
Overview¶
| Class | Description |
|---|---|
Operation | |
OperationKind | Classification of operations for classical/quantum separation. |
ParamHint | |
ReturnOperation | Explicit return operation marking the end of a block with return values. |
Signature |
Classes¶
Operation [source]¶
class Operation(abc.ABC)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operands: list[Value]operation_kind: OperationKind Return the kind of this operation for classical/quantum classification.results: list[Value]signature: Signature
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]) -> OperationReturn a copy with all Values substituted via mapping.
Handles operands, results, and subclass-specific Value
fields. Subclasses override to handle their extra fields.
OperationKind [source]¶
class OperationKind(enum.Enum)Classification of operations for classical/quantum separation.
This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.
Values:
QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)
Attributes¶
CLASSICALCONTROLHYBRIDQUANTUM
ParamHint [source]¶
class ParamHintConstructor¶
def __init__(self, name: str, type: ValueType) -> NoneAttributes¶
name: strtype: ValueType
ReturnOperation [source]¶
class ReturnOperation(Operation)Explicit return operation marking the end of a block with return values.
This operation represents an explicit return statement in the IR. It takes the values to be returned as operands and produces no results (it is a terminal operation that transfers control flow back to the caller).
operands: [Value, ...] - The values to return (may be empty for void returns) results: [] - Always empty (terminal operation)
Example:
A function that returns two values (a UInt and a Float):
ReturnOperation(
operands=[uint_value, float_value],
results=[],
)
The signature would be:
operands=[ParamHint("return_0", UIntType()), ParamHint("return_1", FloatType())]
results=[]Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKind Return CLASSICAL as this is a control flow operation without quantum effects.signature: Signature Return the signature with operands for each return value and no results.
Signature [source]¶
class SignatureConstructor¶
def __init__(
self,
operands: list[ParamHint | None] = list(),
results: list[ParamHint] = list(),
) -> NoneAttributes¶
operands: list[ParamHint | None]results: list[ParamHint]
qamomile .circuit .ir .operation .select¶
SELECT (quantum multiplexer) operation.
SelectOperation is the IR node behind qmc.select: a quantum
multiplexer that applies a different unitary U_i to a shared target
register depending on the computational-basis value i read off an
index (control) register::
SELECT = sum_i |i><i| (x) U_iFollowing the project’s IR-abstraction principle, the op stays as a single high-level box. Circuit-family lowering preserves that identity as one reusable call whose fallback contains controlled case calls. A target can therefore select a native realization without changing the frontend or semantic IR.
Overview¶
| Function | Description |
|---|---|
is_plain_int | Return True if value is a Python int but not a bool. |
| Class | Description |
|---|---|
Block | Unified block representation for all pipeline stages. |
Operation | |
OperationKind | Classification of operations for classical/quantum separation. |
ParamHint | |
QubitType | Type representing a quantum bit (qubit). |
SelectOperation | Quantum multiplexer: apply case_blocks[i] when the index reads i. |
Signature | |
UIntType | Type representing an unsigned integer. |
Value | A typed SSA value in the IR. |
ValueBase | Nominal base for every typed IR value. |
Functions¶
is_plain_int [source]¶
def is_plain_int(value: object) -> boolReturn True if value is a Python int but not a bool.
bool is a subclass of int in Python, so isinstance(True, int)
is True. This helper distinguishes a genuine integer from a boolean,
which matters wherever a boolean must be rejected in an integer slot — for
example, validating decoded wire data or a register width.
Parameters:
| Name | Type | Description |
|---|---|---|
value | object | The value to test. |
Returns:
bool — True when value is an int and not a bool.
Classes¶
Block [source]¶
class BlockUnified 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[ValueLike] = list(),
output_values: list[ValueLike] = list(),
output_names: list[str] = list(),
operations: list['Operation'] = list(),
kind: BlockKind = BlockKind.HIERARCHICAL,
parameters: dict[str, Value] = dict(),
param_slots: tuple[ParamSlot, ...] = tuple(),
static_bindings: tuple[StaticBindingSlot, ...] = tuple(),
) -> NoneAttributes¶
effects: ‘KernelEffect’ Return lazily cached semantic effects for this block.input_values: list[ValueLike]kind: BlockKindlabel_args: list[str]measurement_result_indices: frozenset[int] Return public output positions derived from measurement.name: stroperations: list[‘Operation’]output_names: list[str]output_values: list[ValueLike]param_slots: tuple[ParamSlot, ...]parameters: dict[str, Value]static_bindings: tuple[StaticBindingSlot, ...]
Methods¶
call¶
def call(self, **kwargs: ValueLike = {}) -> 'InvokeOperation'Create an inline callable invocation against this block.
Parameters:
| Name | Type | Description |
|---|---|---|
**kwargs | ValueLike | Actual argument values keyed by self.label_args. |
Returns:
'InvokeOperation' — Inline-policy invocation whose callable
definition points at this block.
Raises:
KeyError— If a required label inself.label_argsis missing fromkwargs.
is_affine¶
def is_affine(self) -> boolReturn whether this block has passed affine validation.
Returns:
bool — True for AFFINE and ANALYZED blocks.
unbound_parameters¶
def unbound_parameters(self) -> list[str]Return list of unbound parameter names.
Operation [source]¶
class Operation(abc.ABC)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operands: list[Value]operation_kind: OperationKind Return the kind of this operation for classical/quantum classification.results: list[Value]signature: Signature
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]) -> OperationReturn a copy with all Values substituted via mapping.
Handles operands, results, and subclass-specific Value
fields. Subclasses override to handle their extra fields.
OperationKind [source]¶
class OperationKind(enum.Enum)Classification of operations for classical/quantum separation.
This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.
Values:
QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)
Attributes¶
CLASSICALCONTROLHYBRIDQUANTUM
ParamHint [source]¶
class ParamHintConstructor¶
def __init__(self, name: str, type: ValueType) -> NoneAttributes¶
name: strtype: ValueType
QubitType [source]¶
class QubitType(QuantumTypeMixin, ValueType)Type representing a quantum bit (qubit).
SelectOperation [source]¶
class SelectOperation(Operation)Quantum multiplexer: apply case_blocks[i] when the index reads i.
Concrete operand layout:
[idx_0, ..., idx_{k-1}, tgt_0, ..., tgt_m, params...].
Symbolic-width operand layout:
[idx_arg_0, ..., idx_arg_{a-1}, tgt_0, ..., tgt_m, params...].
Results mirror the quantum operand grouping.
A concrete index register is normalized to one scalar Qubit operand
per physical index qubit. A symbolic-width register instead retains each
leading caller argument as one scalar or array operand until its bound
shape is known. Whole-Vector[Qubit] / scalar targets follow and keep
their shapes, and classical parameters shared across every case come last.
Index bit order is LSB-first: idx_0 is the least-significant
bit, matching Qamomile’s qubit-zero convention. Case i is selected
when index qubit j reads bit j of i. len(case_blocks)
need not be a power of two; index values >= len(case_blocks) apply
no operation (identity).
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_index_qubits: int | Value = 0,
case_blocks: list[Block] = list(),
num_index_args: int = 0,
case_callable_attrs: list[dict[str, Any]] = list(),
) -> NoneAttributes¶
case_blocks: list[Block]case_callable_attrs: list[dict[str, Any]]index_operands: list[Value] Return the grouped index-prefix operands.is_symbolic_num_index_qubits: bool Return whether the index width is a symbolic IR value.num_cases: int Return the number of selectable cases.num_index_args: intnum_index_qubits: int | Valueoperation_kind: OperationKind Return the operation kind.param_operands: list[Value] Return the shared classical parameter operands.signature: Signature Return the operation signature.target_operands: list[Value] Return the quantum target operands applied by every case.
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Return every value consumed by the SELECT operation.
Returns:
list[ValueBase] — list[ValueBase]: Ordinary operands plus the symbolic index-width
value when present.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationReplace operand and symbolic-width values by UUID.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | dict[str, ValueBase] | UUID-keyed replacement values. |
Returns:
Operation — Rebuilt SELECT operation with matching values replaced.
Signature [source]¶
class SignatureConstructor¶
def __init__(
self,
operands: list[ParamHint | None] = list(),
results: list[ParamHint] = list(),
) -> NoneAttributes¶
operands: list[ParamHint | None]results: list[ParamHint]
UIntType [source]¶
class UIntType(ClassicalTypeMixin, ValueType)Type representing an unsigned integer.
Value [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.
ValueBase [source]¶
class ValueBaseNominal base for every typed IR value.
Runtime compiler passes inspect values in their innermost loops. A nominal base keeps those checks constant-time; a runtime-checkable protocol would repeatedly scan the protocol members on Python versions that do not cache structural checks.
Attributes¶
logical_id: strmetadata: ValueMetadataname: strtype: ValueType Return the static IR type carried by this value.uuid: str
Methods¶
get_const¶
def get_const(self) -> int | float | bool | NoneReturn the scalar constant carried by this value.
Returns:
int | float | bool | None — int | float | bool | None: Constant value, or None when the
value is not constant.
is_constant¶
def is_constant(self) -> boolReturn whether this value carries a scalar constant.
Returns:
bool — Whether scalar constant metadata is present.
is_parameter¶
def is_parameter(self) -> boolReturn whether this value represents a runtime parameter.
Returns:
bool — Whether parameter metadata is present.
next_version¶
def next_version(self) -> ValueBaseCreate the next SSA version of this value.
Returns:
ValueBase — A value with a fresh version UUID and preserved logical
identity.
parameter_name¶
def parameter_name(self) -> str | NoneReturn the public parameter name carried by this value.
Returns:
str | None — str | None: Parameter name, or None for a non-parameter value.
qamomile.circuit.ir.operation.slice_array¶
Slice operation that produces a strided view of an array.
Overview¶
| Class | Description |
|---|---|
Operation | |
OperationKind | Classification of operations for classical/quantum separation. |
ParamHint | |
ReleaseSliceViewOperation | Mark a slice view’s borrow as explicitly returned to its parent. |
Signature | |
SliceArrayOperation | Construct a strided view of an ArrayValue. |
Classes¶
Operation [source]¶
class Operation(abc.ABC)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operands: list[Value]operation_kind: OperationKind Return the kind of this operation for classical/quantum classification.results: list[Value]signature: Signature
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]) -> OperationReturn a copy with all Values substituted via mapping.
Handles operands, results, and subclass-specific Value
fields. Subclasses override to handle their extra fields.
OperationKind [source]¶
class OperationKind(enum.Enum)Classification of operations for classical/quantum separation.
This enum is used to categorize operations during compilation to determine which parts run on classical hardware vs quantum hardware.
Values:
QUANTUM: Pure quantum operations (gates, qubit allocation) CLASSICAL: Pure classical operations (arithmetic, comparisons) HYBRID: Operations that bridge classical and quantum (measurement, encode/decode) CONTROL: Control flow structures (for, while, if)
Attributes¶
CLASSICALCONTROLHYBRIDQUANTUM
ParamHint [source]¶
class ParamHintConstructor¶
def __init__(self, name: str, type: ValueType) -> NoneAttributes¶
name: strtype: ValueType
ReleaseSliceViewOperation [source]¶
class ReleaseSliceViewOperation(Operation)Mark a slice view’s borrow as explicitly returned to its parent.
Emitted by :meth:Vector.__setitem__ when used with a slice index
(qs[a:b] = qmc.h(qs[a:b])). This op tells the post-fold
linearity checker
(:class:~qamomile.circuit.transpiler.passes.slice_borrow_check.SliceBorrowCheckPass)
that the view referenced in operands[0] no longer owns its
covered parent slots, mirroring the frontend’s
VectorView.consume(operation_name="slice assignment") borrow
release.
Like :class:SliceArrayOperation, this op is a declarative
classical-side marker that does not survive into the emit stream:
:class:~qamomile.circuit.transpiler.passes.strip_slice_ops.StripSliceArrayOpsPass
removes both :class:SliceArrayOperation and
:class:ReleaseSliceViewOperation after
:class:SliceBorrowCheckPass has observed them. Reaching emit
is a compiler-internal invariant violation and is rejected with a
RuntimeError from :mod:standard_emit.
Within a control-flow body (ForOperation / WhileOperation
/ IfOperation), this op only releases view borrows that were
created within the same body. Releasing a borrow that the
enclosing block has registered (an “outer-snapshot” borrow) is
rejected by SliceBorrowCheckPass with ValidationError — the
loop-merge semantics of the
pass cannot propagate entry deletions out of the body, so the only
way to keep the static check consistent is to forbid that pattern.
Example:
``qs[1:3] = qmc.h(qs[1:3])`` emits, after the broadcast loop::
ReleaseSliceViewOperation(
operands=[qmc_h_result_view], # slice_of=qs_value
results=[],
)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKind Release is classical — it updates borrow tracking metadata only.signature: Signature Return the type signature of this release operation.
Signature [source]¶
class SignatureConstructor¶
def __init__(
self,
operands: list[ParamHint | None] = list(),
results: list[ParamHint] = list(),
) -> NoneAttributes¶
operands: list[ParamHint | None]results: list[ParamHint]
SliceArrayOperation [source]¶
class SliceArrayOperation(Operation)Construct a strided view of an ArrayValue.
The op itself performs no quantum action — it records that the
result ArrayValue is a strided view of the operand parent
with the given start / step. The result’s
slice_of / slice_start / slice_step fields carry the
affine map used by the emit-time resolver.
SliceArrayOperation is classified as :attr:OperationKind.CLASSICAL
because slicing is pure index selection — no new quantum operation
is introduced. The pipeline keeps this op through
PartialEvaluationPass (which invokes
ConstantFoldingPass(..., strip_slice_ops=False)) so the
post-fold :class:~qamomile.circuit.transpiler.passes.slice_borrow_check.SliceBorrowCheckPass
can use it as a view-declaration marker; once that check has run,
StripSliceArrayOpsPass removes every SliceArrayOperation
/ ReleaseSliceViewOperation so segmentation
(:mod:~qamomile.circuit.transpiler.passes.separate) and the
downstream emit stage only see a pure quantum-op stream. By the
time :mod:~qamomile.circuit.transpiler.passes.separate runs the
op has therefore been stripped — reaching emit is a compiler-
internal invariant violation.
Example:
``q[1::2]`` on a ``Vector[Qubit]`` emits::
SliceArrayOperation(
operands=[q_value, uint_1, uint_2],
results=[sliced_value], # slice_of=q_value, slice_start=uint_1, slice_step=uint_2
)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKind Slice is classical — it selects indices without quantum action.signature: Signature Return the type signature of this slice operation.
qamomile.circuit.ir.parameter¶
First-class manifest of a kernel’s classical parameter interface.
This module defines ParamSlot and ParamKind, which together
describe every classical (non-quantum) argument of a @qkernel
function so the kernel’s parameter contract is recoverable from the
IR alone — without an external Python-side manifest.
Motivation:
The project rule documented in CLAUDE.md keeps bindings and
parameters strictly disjoint at the Transpiler.transpile()
API boundary, but the IR itself does not record which name was
decided which way. After partial_eval folds a binding into a
concrete constant, downstream readers cannot tell whether a
constant value originated from a compile-time binding or was a
literal in the kernel source. This is especially limiting for the
“qamomile as subgraph of an outer DSL’s computation graph” use
case, where the receiver needs to know the kernel’s full classical
interface (name, type, default, runtime-or-bound) to rebind values
in subsequent calls.
Per-kernel-argument metadata also makes it natural to attach
optional hints (currently just differentiable) for outer DSL
tooling such as parameter-shift gradient back-ends.
Scope:
ParamSlot covers only classical (non-quantum) arguments. Qubit
and Vector[Qubit] inputs are not part of the parameter slot
manifest; they appear in Block.input_values instead.
The companion Block.parameters: dict[str, Value] field is
retained for callers (passes, emitters) that need a direct Value
reference for runtime parameters; Block.param_slots is the
canonical, fully-typed contract that survives the pipeline.
Overview¶
| Class | Description |
|---|---|
ParamKind | Lifecycle classification for a classical kernel argument. |
ParamSlot | Metadata for a single classical kernel argument. |
Classes¶
ParamKind [source]¶
class ParamKind(enum.Enum)Lifecycle classification for a classical kernel argument.
Values:
RUNTIME_PARAMETER: The argument is intended to be bound at
execution time by the backend (or, more generally, by the
outer caller in a hybrid loop). It survives the
compilation pipeline as a symbolic parameter.
COMPILE_TIME_BOUND: The argument was provided as a binding
(or via a Python default) and is folded into the IR by
resolve_parameter_shapes / partial_eval. No
symbolic counterpart remains in the emitted circuit.
Attributes¶
COMPILE_TIME_BOUNDRUNTIME_PARAMETER
ParamSlot [source]¶
class ParamSlotMetadata for a single classical kernel argument.
A ParamSlot describes one position in the kernel’s classical
parameter contract — its declared type, whether it is a runtime
parameter or a compile-time-bound value, the Python default (if
any), the actually-bound value (when kind is
COMPILE_TIME_BOUND), and any outer-DSL hints. Slots are
immutable; pipeline passes that need to update a slot must clone
via dataclasses.replace.
The slot is identified by name, which matches the kernel’s
Python parameter name and the corresponding entry in
Block.label_args. A slot’s name MUST never overlap between
RUNTIME_PARAMETER and COMPILE_TIME_BOUND instances within
one Block (this mirrors the project-level bindings /
parameters disjointness rule).
Constructor¶
def __init__(
self,
name: str,
type: 'ValueType',
kind: ParamKind,
ndim: int = 0,
default: Any = None,
bound_value: Any = None,
differentiable: bool = False,
) -> NoneAttributes¶
bound_value: Anydefault: Anydifferentiable: boolkind: ParamKindname: strndim: inttype: ‘ValueType’
qamomile.circuit.ir.printer¶
Text pretty-printer for the Block IR.
This module provides a contributor-facing textual dump of the intermediate
representation, similar in spirit to MLIR’s textual IR format. Useful for
debugging the transpiler pipeline by inspecting the block at each stage
(HIERARCHICAL / AFFINE / ANALYZED).
Example:
>>> from qamomile.circuit.ir import pretty_print_block
>>> block = transpiler.to_block(my_kernel, bindings={"n": 3})
>>> print(pretty_print_block(block))
block my_kernel [HIERARCHICAL] (n: UIntType) -> Vector[BitType]
...The output is intended for human inspection, not for machine parsing; its format may change between Qamomile releases.
Overview¶
| Function | Description |
|---|---|
format_value | Format an IR value reference as %name@vN. |
pretty_print_block | Return a MLIR-style textual dump of block. |
| Class | Description |
|---|---|
ArrayValue | An array of typed IR values. |
BinOp | Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN). |
Block | Unified block representation for all pipeline stages. |
CompOp | Comparison operation (EQ, NEQ, LT, LE, GT, GE). |
CondOp | Conditional logical operation (AND, OR). |
DecodeQFixedOperation | Decode measured bits to float (classical operation). |
DictValue | A dictionary value stored as stable ordered entries. |
ExpvalOp | Expectation value operation. |
ForOperation | Represents a for loop operation. |
IfMerge | One branch-merge slot of an :class:IfOperation. |
IfOperation | Represents an if-else conditional operation. |
NotOp | |
PauliEvolveOp | Pauli evolution operation: exp(-i * gamma * H). |
TupleValue | A tuple of IR values for structured data. |
UnaryMathOp | Represent one pure unary mathematical expression. |
Value | A typed SSA value in the IR. |
WhileOperation | Represents a while loop operation. |
Constants¶
ValueLike:TypeAlias='Value | ArrayValue | TupleValue | DictValue'
Functions¶
format_value [source]¶
def format_value(value: Any) -> strFormat an IR value reference as %name@vN.
Handles Value, ArrayValue, TupleValue, DictValue, and
array-element Values (rendered as %parent[i]@vN). Constants
and parameters are shown with their tagged metadata when available.
Falls back to repr() for unrecognised inputs so callers can use
this helper for any operand-like field without a type switch.
pretty_print_block [source]¶
def pretty_print_block(block: Block, *, depth: int = 0) -> strReturn a MLIR-style textual dump of block.
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | The Block to format. Works on any BlockKind. |
depth | int | How many levels of callable bodies to expand inline. 0 (default) shows only the callable name and I/O. Positive values expand InvokeOperation bodies recursively, decrementing the allowance at each step. Useful for seeing what inline will produce without actually running the pass. |
Returns:
str — A newline-separated string. The format is for human debugging and
str — is not guaranteed to be stable across releases.
Classes¶
ArrayValue [source]¶
class ArrayValue(Value[T])An array of typed IR values.
When slice_of is set, this array is a strided view over another
array. Element accesses on a sliced ArrayValue resolve to
physical slots on the root parent via the affine map
parent_index = slice_start + slice_step * view_local_index,
applied recursively along slice_of chains. The emit-time
resolver walks this chain to produce the final qubit index; passes
that substitute or clone values must treat slice_of /
slice_start / slice_step as Value references that need to
track through the same mapping as parent_array.
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(),
slice_of: 'ArrayValue | None' = None,
slice_start: 'Value | None' = None,
slice_step: 'Value | None' = None,
) -> NoneAttributes¶
logical_id: strmetadata: ValueMetadataname: strshape: tuple[Value, ...]slice_of: ‘ArrayValue | None’slice_start: ‘Value | None’slice_step: ‘Value | None’type: Tuuid: str
Methods¶
is_slice¶
def is_slice(self) -> boolReturn True if this array is a strided view of another array.
Returns:
bool — True iff slice_of is non-None.
next_version¶
def next_version(self) -> ArrayValue[T]BinOp [source]¶
class BinOp(BinaryOperationBase)Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN).
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
kind: BinOpKind | None = None,
) -> NoneAttributes¶
kind: BinOpKind | Noneoperation_kind: OperationKindsignature: Signature
Block [source]¶
class BlockUnified 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[ValueLike] = list(),
output_values: list[ValueLike] = list(),
output_names: list[str] = list(),
operations: list['Operation'] = list(),
kind: BlockKind = BlockKind.HIERARCHICAL,
parameters: dict[str, Value] = dict(),
param_slots: tuple[ParamSlot, ...] = tuple(),
static_bindings: tuple[StaticBindingSlot, ...] = tuple(),
) -> NoneAttributes¶
effects: ‘KernelEffect’ Return lazily cached semantic effects for this block.input_values: list[ValueLike]kind: BlockKindlabel_args: list[str]measurement_result_indices: frozenset[int] Return public output positions derived from measurement.name: stroperations: list[‘Operation’]output_names: list[str]output_values: list[ValueLike]param_slots: tuple[ParamSlot, ...]parameters: dict[str, Value]static_bindings: tuple[StaticBindingSlot, ...]
Methods¶
call¶
def call(self, **kwargs: ValueLike = {}) -> 'InvokeOperation'Create an inline callable invocation against this block.
Parameters:
| Name | Type | Description |
|---|---|---|
**kwargs | ValueLike | Actual argument values keyed by self.label_args. |
Returns:
'InvokeOperation' — Inline-policy invocation whose callable
definition points at this block.
Raises:
KeyError— If a required label inself.label_argsis missing fromkwargs.
is_affine¶
def is_affine(self) -> boolReturn whether this block has passed affine validation.
Returns:
bool — True for AFFINE and ANALYZED blocks.
unbound_parameters¶
def unbound_parameters(self) -> list[str]Return list of unbound parameter names.
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,
) -> NoneAttributes¶
kind: CompOpKind | Noneoperation_kind: OperationKindsignature: Signature
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,
) -> NoneAttributes¶
kind: CondOpKind | Noneoperation_kind: OperationKindsignature: Signature
DecodeQFixedOperation [source]¶
class DecodeQFixedOperation(Operation)Decode measured bits to float (classical operation).
This operation converts a sequence of classical bits from qubit measurements into a floating-point number using fixed-point encoding.
The decoding formula for least-significant-first storage:
float_value = Σ bit[i] * 2^(int_bits - num_bits + i)
For QPE phase (int_bits=0):
bit[0] has weight 2**(-num_bits) and bit[-1] has weight 0.5.
Example:
bits = [1, 0, 1] with int_bits=0
→ 0.101 (MSB-first display) = 0.5 + 0.125 = 0.625operands: [ArrayValue of bits (vec[bit])] results: [Float value]
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_bits: int = 0,
int_bits: int = 0,
) -> NoneAttributes¶
int_bits: intnum_bits: intoperation_kind: OperationKindsignature: Signature
DictValue [source]¶
class DictValue(_MetadataValueMixin, ValueBase)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()))(),
) -> NoneAttributes¶
entries: tuple[tuple[TupleValue | Value, Value], ...]logical_id: strmetadata: ValueMetadataname: strtype: DictTypeuuid: str
Methods¶
is_constant¶
def is_constant(self) -> boolnext_version¶
def next_version(self) -> DictValueExpvalOp [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:
Input: quantum state (qubits) + Observable reference
Output: classical Float (expectation value)
Example IR:
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
hamiltonian: Value Alias for observable (deprecated, use observable instead).observable: Value The Observable parameter operand.operation_kind: OperationKind ExpvalOp is HYBRID - bridges quantum state to classical value.output: Value The expectation value result.qubits: Value The quantum register operand.signature: Signature
ForOperation [source]¶
class ForOperation(HasNestedOps, Operation)Represents a for loop operation.
Example:
for i in range(start, stop, step):
bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
loop_var: str = '',
loop_var_value: Value | None = None,
operations: list[Operation] = list(),
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_args: tuple[RegionArg, ...] = (),
captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
captures: tuple[ValueBase, ...]loop_carried_rebinds: tuple[LoopCarriedRebind, ...]loop_var: strloop_var_value: Value | Noneoperation_kind: OperationKindoperations: list[Operation]region_args: tuple[RegionArg, ...]signature: Signature
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include loop_var_value so cloning/substitution stays consistent.
Without this override, UUIDRemapper would clone every body
reference to the loop variable to a fresh UUID, but leave
loop_var_value pointing at the un-cloned original — emit-time
UUID-keyed lookups for the loop variable would then miss.
Loop-carried rebind records and region arguments are included
for the same reason.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the range-loop body with its explicit interface.
Returns:
tuple[Region, ...] — tuple[Region, ...]: One body region containing the induction
value, carried-value formals, captures, and carried yields.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operationrebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild the range-loop body and complete boundary interface.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Exactly one replacement body region. |
Returns:
Operation — Rebuilt range-loop operation.
Raises:
ValueError— If arity or boundary value kinds are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationIfMerge [source]¶
class IfMerge(NamedTuple)One branch-merge slot of an :class:IfOperation.
An IfOperation merges each variable touched by its branches back
into a single SSA value. IfMerge is the read-side view of one such
merge slot, decoupling every consumer from how the merge is stored in
the IR (today the parallel IfOperation.true_yields /
false_yields lists; the storage may change without touching
consumers).
Attributes¶
false_value: Valueindex: intis_identity: bool Whether both branches merge the same underlying value.result: Valuetrue_value: Value
Methods¶
select¶
def select(self, taken: bool) -> ValueReturn the branch source selected by a resolved condition.
Parameters:
| Name | Type | Description |
|---|---|---|
taken | bool | The condition’s truth value (True selects the true branch). |
Returns:
Value — true_value when taken is true, else
false_value.
IfOperation [source]¶
class IfOperation(HasNestedOps, Operation)Represents an if-else conditional operation.
Example:
if condition:
true_body
else:
false_bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
true_operations: list[Operation] = list(),
false_operations: list[Operation] = list(),
true_yields: list[Value] = list(),
false_yields: list[Value] = list(),
branch_rebinds: tuple[BranchRebind, ...] = (),
true_captures: tuple[ValueBase, ...] = (),
false_captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
branch_rebinds: tuple[BranchRebind, ...]condition: Valuefalse_captures: tuple[ValueBase, ...]false_operations: list[Operation]false_yields: list[Value]operation_kind: OperationKindsignature: Signaturetrue_captures: tuple[ValueBase, ...]true_operations: list[Operation]true_yields: list[Value]
Methods¶
add_merge¶
def add_merge(self, true_value: Value, false_value: Value, result: Value) -> NoneAppend a branch-merge slot to this if-else.
The only sanctioned construction path for merges: it keeps the
yield lists and results index-aligned so iter_merges can
rely on the invariants it checks.
Parameters:
| Name | Type | Description |
|---|---|---|
true_value | Value | Value selected when the condition is true. |
false_value | Value | Value selected when the condition is false. Must have the same type as true_value. |
result | Value | Fresh SSA value representing the merged output. Must have the same type as the branch values. |
Raises:
RuntimeError— If the condition operand has not been attached to this operation yet (operands[0]must exist before merges are added), or the branch / result types do not match.
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include branch-yield values and rebind records for cloning/substitution.
The yields are subclass-specific Value fields (not operands —
see the class docstring), so generic passes reach them through
this override, mirroring ForItemsOperation.key_var_values.
Branch rebind records follow the loop operations’ rationale: the
recorded pre-branch values reference program values by identity,
so inline cloning must remap them in lockstep with operands.
Read-based checks must not treat the records as reads (see
_op_read_uuids in the analyze pass module).
Returns:
list[ValueBase] — list[ValueBase]: Base input values plus the true/false
yields and rebind-record values.
iter_merges¶
def iter_merges(self) -> Iterator[IfMerge]Iterate the branch-merge slots of this if-else.
This is the single read API for merge semantics: passes must consume merges through it (never through the yield lists directly) so the underlying storage can change without touching consumers.
Yields:
IfMerge — One entry per merged output, in result order.
Raises:
RuntimeError— If the stored merge data is internally inconsistent (the yield-list lengths differ from the result count, or the condition operand is missing while merges are attached). This indicates IR corruption, not a user error. The per-merge corruption modes of the old embedded-operation storage (a foreign entry, a malformed or mismatched condition, a result copy diverging fromresults[i]) cannot be represented in the yield-list storage and need no checks.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]Return the two branch bodies (merge yields are not operations).
Returns:
list[list[Operation]] — list[list[Operation]]: [true_operations, false_operations].
The branch-merge yields are values, not operations, so
they are intentionally absent here.
nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the true and false branch interfaces.
Returns:
tuple[Region, ...] — tuple[Region, ...]: True and false regions in that order, with
branch-local captures and merge yields.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> OperationReturn a copy with the true and false branch bodies replaced.
Parameters:
| Name | Type | Description |
|---|---|---|
new_lists | list[list[Operation]] | The replacement branch bodies in nested_op_lists order ([true_operations, false_operations]). |
Returns:
Operation — A copy of this if-else with the branch bodies
swapped and all other fields (yields, rebinds) preserved.
rebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild both branches and their complete boundary interfaces.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | True and false replacement regions. |
Returns:
Operation — Rebuilt conditional operation.
Raises:
ValueError— If region count, block arguments, or yield signatures are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationSubstitute operand, result, branch-yield, and rebind-record values.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | dict[str, ValueBase] | UUID-keyed substitution map. |
Returns:
Operation — The rewritten operation.
NotOp [source]¶
class NotOp(Operation)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
input: Valueoperation_kind: OperationKindoutput: Valuesignature: Signature
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()) -> NoneAttributes¶
evolved_qubits: Value The evolved quantum register result.gamma: Value The evolution time parameter.observable: Value The Observable parameter operand.operation_kind: OperationKind PauliEvolveOp is QUANTUM - transforms quantum state.qubits: Value The quantum register operand.signature: Signature
TupleValue [source]¶
class TupleValue(_MetadataValueMixin, ValueBase)A tuple of IR values for structured data.
Constructor¶
def __init__(
self,
name: str,
elements: tuple[ValueLike, ...] = tuple(),
metadata: ValueMetadata = ValueMetadata(),
uuid: str = (lambda: str(uuid.uuid4()))(),
logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> NoneAttributes¶
elements: tuple[ValueLike, ...]logical_id: strmetadata: ValueMetadataname: strtype: ‘TupleType’uuid: str
Methods¶
is_constant¶
def is_constant(self) -> boolnext_version¶
def next_version(self) -> TupleValueUnaryMathOp [source]¶
class UnaryMathOp(Operation)Represent one pure unary mathematical expression.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | list[Value] | Single numeric input value. |
results | list[Value] | Single numeric result value. |
kind | UnaryMathOpKind | None | Mathematical operation to apply. |
Raises:
ValueError— Ifkindis missing or the operation does not have exactly one operand and one result.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
kind: UnaryMathOpKind | None = None,
) -> NoneAttributes¶
input: Value Return the input value.kind: UnaryMathOpKind | Noneoperation_kind: OperationKind Classify the operation as classical.output: Value Return the output value.signature: Signature Return the typed unary signature.
Value [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.
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,
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_args: tuple[RegionArg, ...] = (),
captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
captures: tuple[ValueBase, ...]loop_carried_rebinds: tuple[LoopCarriedRebind, ...]max_iterations: int | Noneoperation_kind: OperationKindoperations: list[Operation]region_args: tuple[RegionArg, ...]signature: Signature
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include rebind records and region args for cloning/substitution.
Same rationale as ForOperation.all_input_values: rebind
records and region arguments reference body/pre-loop values by
identity, so inline cloning must remap them in lockstep with
body operands.
Returns:
list[ValueBase] — list[ValueBase]: Base input values plus rebind-record and
region-argument values.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the while body with explicit boundary values.
Returns:
tuple[Region, ...] — tuple[Region, ...]: One body region whose block arguments and
yields are aligned with region_args. The updated
condition, when present, is appended as the final yield.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operationrebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild the while body and its complete boundary interface.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Exactly one replacement body region. |
Returns:
Operation — Rebuilt while operation.
Raises:
ValueError— If arity or boundary value kinds are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationSubstitute operand, rebind-record, and region-arg values.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | dict[str, ValueBase] | UUID-keyed substitution map. |
Returns:
Operation — The rewritten operation.
qamomile.circuit.ir.serialize¶
Private semantic graph codec used by qkernel protobuf serialization.
Block-level persistence is intentionally not a public API. Use
:mod:qamomile.circuit.serialization to serialize one static qkernel.
qamomile.circuit.ir.serialize.decode¶
Private graph record → semantic IR block decoder.
Reconstructs a Block from the graph envelope produced by
:mod:qamomile.circuit.ir.serialize.encode. The decoder NEVER
performs dynamic class resolution: every $type tag is routed
through a hard-coded factory table, and unknown tags raise ValueError.
This closed dispatch is the load-bearing security invariant for protobuf
deserialization.
Values are materialized lazily via depth-first recursion so any
referenced parent_array / element_indices / shape Value is
instantiated before the Value that points at it. A cycle (defensive;
not produced by the canonical encoder) raises ValueError.
Overview¶
| Function | Description |
|---|---|
dict_to_array | Decode a wrapper dict back into a numpy ndarray. |
dict_to_hamiltonian | Decode a wrapper dict back into a Hamiltonian. |
dict_to_scalar | Decode an exact NumPy scalar wrapper. |
is_array_wrapper | Return True if d is a numpy-array wrapper dict. |
is_hamiltonian_wrapper | Return True if d is a Hamiltonian wrapper dict. |
is_plain_int | Return True if value is a Python int but not a bool. |
is_scalar_wrapper | Return whether d is a NumPy-scalar wrapper dict. |
validate_region_args | Validate the SSA identities owned by a loop’s region arguments. |
| Class | Description |
|---|---|
ArrayRuntimeMetadata | Metadata for array literals and explicit element identity tracking. |
ArrayValue | An array of typed IR values. |
BinOp | Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN). |
BinOpKind | |
BitType | Type representing a classical bit. |
Block | Unified block representation for all pipeline stages. |
BlockKind | Classification of block structure for pipeline stages. |
BlockType | Type representing a block/function reference. |
BranchRebind | Trace-time record of a quantum variable rebound inside an if branch. |
CInitOperation | Initialize the classical values (const, arguments etc) |
CastMetadata | Metadata describing a cast carrier and its underlying qubits. |
CastOperation | Type cast operation for creating aliases over the same quantum resources. |
CompOp | Comparison operation (EQ, NEQ, LT, LE, GT, GE). |
CompOpKind | |
ConcreteControlledU | Controlled-U with concrete (int) number of controls. |
CondOp | Conditional logical operation (AND, OR). |
CondOpKind | |
DecodeQFixedOperation | Decode measured bits to float (classical operation). |
DictGetItemOperation | Look up one entry of a Dict by a (possibly symbolic) key. |
DictRuntimeMetadata | Metadata for transpile-time bound dict values. |
DictType | Type representing a dictionary mapping keys to values. |
DictValue | A dictionary value stored as stable ordered entries. |
FloatType | Type representing a floating-point number. |
ForOperation | Represents a for loop operation. |
IfOperation | Represents an if-else conditional operation. |
LoopCarriedRebind | Trace-time record of a variable rebound inside a loop body. |
NotOp | |
ObservableType | Type representing a Hamiltonian observable parameter. |
ParamHint | |
ParamKind | Lifecycle classification for a classical kernel argument. |
ParamSlot | Metadata for a single classical kernel argument. |
PauliEvolveOp | Pauli evolution operation: exp(-i * gamma * H). |
QFixedMetadata | Metadata for QFixed carriers. |
QFixedType | Quantum fixed-point type. |
QInitOperation | Initialize the qubit |
QUIntType | Quantum unsigned integer type. |
QubitType | Type representing a quantum bit (qubit). |
RegionArg | Explicit loop-carried value on a loop operation (MLIR-style iter_arg). |
ReleaseSliceViewOperation | Mark a slice view’s borrow as explicitly returned to its parent. |
ReturnQuantumArrayElementOperation | Validate a branch-selected quantum element’s array return at emit time. |
RuntimeClassicalExpr | A classical expression known to require runtime evaluation. |
RuntimeOpKind | Unified kind for RuntimeClassicalExpr covering all classical |
ScalarMetadata | Metadata for scalar constants and symbolic parameters. |
Signature | |
SliceArrayOperation | Construct a strided view of an ArrayValue. |
StaticBindingField | Reference one scalar field projected from a static binding. |
StaticBindingSlot | Declare one typed compile-time object required by a qkernel. |
StoreArrayElementOperation | Store a classical scalar into one element of a classical array. |
SymbolicControlledU | Controlled-U with symbolic (Value) number of controls. |
TupleType | Type representing a tuple of values. |
TupleValue | A tuple of IR values for structured data. |
UIntType | Type representing an unsigned integer. |
UnaryMathOp | Represent one pure unary mathematical expression. |
UnaryMathOpKind | Identify one abstract unary mathematical operation. |
Value | A typed SSA value in the IR. |
ValueBase | Nominal base for every typed IR value. |
ValueMetadata | Typed metadata owned by the compiler/runtime. |
ValueType | Base class for all value types in the IR. |
WhileOperation | Represents a while loop operation. |
Constants¶
ValueLike:TypeAlias='Value | ArrayValue | TupleValue | DictValue'
Functions¶
dict_to_array [source]¶
def dict_to_array(d: dict[str, Any]) -> np.ndarrayDecode a wrapper dict back into a numpy ndarray.
Parameters:
| Name | Type | Description |
|---|---|---|
d | dict[str, Any] | A wrapper dict previously produced by :func:array_to_dict after protobuf decoding. |
Returns:
np.ndarray — np.ndarray: The reconstructed array with the original dtype
and shape.
Raises:
ValueError— Ifdis not a valid wrapper dict, if the dtype is not in the allow-list, or if the byte length is inconsistent with shape × dtype.itemsize.
dict_to_hamiltonian [source]¶
def dict_to_hamiltonian(d: dict[str, Any]) -> HamiltonianDecode a wrapper dict back into a Hamiltonian.
Terms are re-added in wire order through the public add_term
API, which is the identity on the canonical term form the encoder
emits (operators sorted per term, no identities) and preserves the
term-dict insertion order.
Parameters:
| Name | Type | Description |
|---|---|---|
d | dict[str, Any] | A wrapper dict previously produced by :func:hamiltonian_to_dict after protobuf decoding. |
Returns:
Hamiltonian — The reconstructed Hamiltonian, equal to the
original (same terms in the same order, same coefficient
types, same constant, same declared register width).
Raises:
ValueError— Ifdis not a valid wrapper dict — missing or malformedterms, a term with an empty operator list (the constant is carried by the dedicatedconstantfield, so an empty list would double-encode it), a Pauli name outside the allow-map, a negative or non-int qubit index, a malformed coefficient, or anum_qubitsthat is neitherNonenor a non-negative int.
dict_to_scalar [source]¶
def dict_to_scalar(d: dict[str, Any]) -> np.genericDecode an exact NumPy scalar wrapper.
Parameters:
| Name | Type | Description |
|---|---|---|
d | dict[str, Any] | Wrapper produced by :func:scalar_to_dict. |
Returns:
np.generic — np.generic: Scalar with the original dtype and bit representation.
Raises:
ValueError— If the wrapper, dtype, or byte length is malformed.
is_array_wrapper [source]¶
def is_array_wrapper(d: Any) -> boolReturn True if d is a numpy-array wrapper dict.
Parameters:
| Name | Type | Description |
|---|---|---|
d | Any | A value to check. Typically the result of a recursive dict walk from decode. |
Returns:
bool — True when d is a dict carrying the
$np_array tag with a True-ish value.
is_hamiltonian_wrapper [source]¶
def is_hamiltonian_wrapper(d: Any) -> boolReturn True if d is a Hamiltonian wrapper dict.
Parameters:
| Name | Type | Description |
|---|---|---|
d | Any | A value to check. Typically the result of a recursive dict walk from decode. |
Returns:
bool — True when d is a dict carrying the
$hamiltonian tag with a True value.
is_plain_int [source]¶
def is_plain_int(value: object) -> boolReturn True if value is a Python int but not a bool.
bool is a subclass of int in Python, so isinstance(True, int)
is True. This helper distinguishes a genuine integer from a boolean,
which matters wherever a boolean must be rejected in an integer slot — for
example, validating decoded wire data or a register width.
Parameters:
| Name | Type | Description |
|---|---|---|
value | object | The value to test. |
Returns:
bool — True when value is an int and not a bool.
is_scalar_wrapper [source]¶
def is_scalar_wrapper(d: Any) -> boolReturn whether d is a NumPy-scalar wrapper dict.
Parameters:
| Name | Type | Description |
|---|---|---|
d | Any | Candidate wire payload. |
Returns:
bool — Whether d carries the exact scalar wrapper tag.
validate_region_args [source]¶
def validate_region_args(op: ForOperation | ForItemsOperation | WhileOperation) -> tuple[RegionArg, ...]Validate the SSA identities owned by a loop’s region arguments.
A loop owns several definition namespaces: its iteration variables,
every RegionArg.block_arg, and every RegionArg.result. Those
identities must be pairwise disjoint. Otherwise different stages can
assign incompatible meanings to one UUID: a UUID-keyed environment has
only one slot, so binding either the iteration variable or the carried
value overwrites the other and makes both reads observe the same value.
Parameters:
| Name | Type | Description |
|---|---|---|
op | ForOperation | ForItemsOperation | WhileOperation | Loop operation whose region arguments should be validated. |
Returns:
tuple[RegionArg, ...] — tuple[RegionArg, ...]: The validated op.region_args tuple.
Raises:
ValueError— If result counts or positions disagree, slot types differ, or any loop-owned definition identity collides with another definition or with a region initializer/body yield.
Classes¶
ArrayRuntimeMetadata [source]¶
class ArrayRuntimeMetadataMetadata for array literals and explicit element identity tracking.
element_parent_uuids / element_parent_indices are parallel to
element_uuids: for each tracked element they record the root array’s
UUID and the element’s index within that root (as resolved by
:func:resolve_root_qubit_address at trace time). They let an emit pass map
a packed element back to the physical qubit registered under the root
array’s QubitAddress(root_uuid, index) key even when the element’s own
UUID was never registered. The sentinel ("", -1) marks an element with
no array parent (a standalone qubit), for which a flat UUID lookup is used.
(root_uuid, -1) preserves a known root owner when the scalar index is
symbolic and therefore cannot be resolved at trace time.
Constructor¶
def __init__(
self,
const_array: Any = None,
element_uuids: tuple[str, ...] = (),
element_logical_ids: tuple[str, ...] = (),
element_parent_uuids: tuple[str, ...] = (),
element_parent_indices: tuple[int, ...] = (),
) -> NoneAttributes¶
const_array: Anyelement_logical_ids: tuple[str, ...]element_parent_indices: tuple[int, ...]element_parent_uuids: tuple[str, ...]element_uuids: tuple[str, ...]
ArrayValue [source]¶
class ArrayValue(Value[T])An array of typed IR values.
When slice_of is set, this array is a strided view over another
array. Element accesses on a sliced ArrayValue resolve to
physical slots on the root parent via the affine map
parent_index = slice_start + slice_step * view_local_index,
applied recursively along slice_of chains. The emit-time
resolver walks this chain to produce the final qubit index; passes
that substitute or clone values must treat slice_of /
slice_start / slice_step as Value references that need to
track through the same mapping as parent_array.
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(),
slice_of: 'ArrayValue | None' = None,
slice_start: 'Value | None' = None,
slice_step: 'Value | None' = None,
) -> NoneAttributes¶
logical_id: strmetadata: ValueMetadataname: strshape: tuple[Value, ...]slice_of: ‘ArrayValue | None’slice_start: ‘Value | None’slice_step: ‘Value | None’type: Tuuid: str
Methods¶
is_slice¶
def is_slice(self) -> boolReturn True if this array is a strided view of another array.
Returns:
bool — True iff slice_of is non-None.
next_version¶
def next_version(self) -> ArrayValue[T]BinOp [source]¶
class BinOp(BinaryOperationBase)Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN).
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
kind: BinOpKind | None = None,
) -> NoneAttributes¶
kind: BinOpKind | Noneoperation_kind: OperationKindsignature: Signature
BinOpKind [source]¶
class BinOpKind(enum.Enum)Attributes¶
ADDDIVFLOORDIVMINMODMULPOWSUB
BitType [source]¶
class BitType(ClassicalTypeMixin, ValueType)Type representing a classical bit.
Block [source]¶
class BlockUnified 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[ValueLike] = list(),
output_values: list[ValueLike] = list(),
output_names: list[str] = list(),
operations: list['Operation'] = list(),
kind: BlockKind = BlockKind.HIERARCHICAL,
parameters: dict[str, Value] = dict(),
param_slots: tuple[ParamSlot, ...] = tuple(),
static_bindings: tuple[StaticBindingSlot, ...] = tuple(),
) -> NoneAttributes¶
effects: ‘KernelEffect’ Return lazily cached semantic effects for this block.input_values: list[ValueLike]kind: BlockKindlabel_args: list[str]measurement_result_indices: frozenset[int] Return public output positions derived from measurement.name: stroperations: list[‘Operation’]output_names: list[str]output_values: list[ValueLike]param_slots: tuple[ParamSlot, ...]parameters: dict[str, Value]static_bindings: tuple[StaticBindingSlot, ...]
Methods¶
call¶
def call(self, **kwargs: ValueLike = {}) -> 'InvokeOperation'Create an inline callable invocation against this block.
Parameters:
| Name | Type | Description |
|---|---|---|
**kwargs | ValueLike | Actual argument values keyed by self.label_args. |
Returns:
'InvokeOperation' — Inline-policy invocation whose callable
definition points at this block.
Raises:
KeyError— If a required label inself.label_argsis missing fromkwargs.
is_affine¶
def is_affine(self) -> boolReturn whether this block has passed affine validation.
Returns:
bool — True for AFFINE and ANALYZED blocks.
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¶
AFFINEANALYZEDHIERARCHICALTRACED
BlockType [source]¶
class BlockType(ObjectTypeMixin, ValueType)Type representing a block/function reference.
BranchRebind [source]¶
class BranchRebindTrace-time record of a quantum variable rebound inside an if branch.
The frontend’s branch tracing merges only the new branch values
through merge operations; when both branches rebind a variable, the
value the variable held before the branch no longer appears anywhere
in the IfOperation. These records preserve that pre-branch
binding so the transpiler’s control-flow discard check
(reject_control_flow_quantum_discard in
qamomile.circuit.transpiler.passes.analyze) can verify that the
pre-branch quantum state is consumed or carried on every runtime
execution path instead of being silently dropped.
Constructor¶
def __init__(
self,
var_name: str,
before: Value,
rebound_in_true: bool,
rebound_in_false: bool,
) -> NoneAttributes¶
before: Valuerebound_in_false: boolrebound_in_true: boolvar_name: str
CInitOperation [source]¶
class CInitOperation(Operation)Initialize the classical values (const, arguments etc)
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
CastMetadata [source]¶
class CastMetadataMetadata describing a cast carrier and its underlying qubits.
Constructor¶
def __init__(
self,
source_uuid: str,
qubit_uuids: tuple[str, ...],
source_logical_id: str | None = None,
qubit_logical_ids: tuple[str, ...] = (),
) -> NoneAttributes¶
qubit_logical_ids: tuple[str, ...]qubit_uuids: tuple[str, ...]source_logical_id: str | Nonesource_uuid: str
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:
Vector[Qubit] -> QFixed (after QPE, for phase measurement)
Vector[Qubit] -> QUInt (for quantum arithmetic)
QUInt -> QFixed (reinterpret bits with different encoding)
QFixed -> QUInt (reinterpret bits with different encoding)
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(),
) -> NoneAttributes¶
num_qubits: int Number of qubits involved in the cast.operation_kind: OperationKind Cast stays in the same segment as its source (QUANTUM for quantum types).qubit_mapping: list[str]signature: Signature Return the type signature of this cast operation.source_type: ValueType | Nonetarget_type: ValueType | None
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,
) -> NoneAttributes¶
kind: CompOpKind | Noneoperation_kind: OperationKindsignature: Signature
CompOpKind [source]¶
class CompOpKind(enum.Enum)Attributes¶
EQGEGTLELTNEQ
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,
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] = dict(),
control_value: int | None = None,
) -> NoneAttributes¶
control_operands: list[Value]control_value: int | Nonenum_controls: intparam_operands: list[Value] Get classical/object operands after the concrete control prefix.signature: Signature Build the concrete controlled call signature.target_operands: list[Value] Return the wrapped callable’s target and parameter operands.
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,
) -> NoneAttributes¶
kind: CondOpKind | Noneoperation_kind: OperationKindsignature: Signature
CondOpKind [source]¶
class CondOpKind(enum.Enum)Attributes¶
ANDOR
DecodeQFixedOperation [source]¶
class DecodeQFixedOperation(Operation)Decode measured bits to float (classical operation).
This operation converts a sequence of classical bits from qubit measurements into a floating-point number using fixed-point encoding.
The decoding formula for least-significant-first storage:
float_value = Σ bit[i] * 2^(int_bits - num_bits + i)
For QPE phase (int_bits=0):
bit[0] has weight 2**(-num_bits) and bit[-1] has weight 0.5.
Example:
bits = [1, 0, 1] with int_bits=0
→ 0.101 (MSB-first display) = 0.5 + 0.125 = 0.625operands: [ArrayValue of bits (vec[bit])] results: [Float value]
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_bits: int = 0,
int_bits: int = 0,
) -> NoneAttributes¶
int_bits: intnum_bits: intoperation_kind: OperationKindsignature: Signature
DictGetItemOperation [source]¶
class DictGetItemOperation(Operation)Look up one entry of a Dict by a (possibly symbolic) key.
This is the IR form of d[key] on a Dict handle. The key
components may be symbolic (e.g. loop variables of a for-items
loop); the lookup is resolved at emit time when the key values and
the dict’s bound data are both concrete.
operands: [DictValue, *key_component_values] results: [looked-up scalar value]
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
key_arity: int = 1,
) -> NoneAttributes¶
dict_value: Value Value: The DictValue being indexed (operands[0]).key_arity: intkey_values: tuple[Value, ...] tuple[Value, ...]: The key component values.operation_kind: OperationKindsignature: Signature
DictRuntimeMetadata [source]¶
class DictRuntimeMetadataMetadata for transpile-time bound dict values.
Constructor¶
def __init__(self, bound_data: tuple[tuple[Any, Any], ...] = ()) -> NoneAttributes¶
bound_data: tuple[tuple[Any, Any], ...]
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,
) -> NoneAttributes¶
key_type: ValueType | Nonevalue_type: ValueType | None
Methods¶
is_classical¶
def is_classical(self) -> boolis_quantum¶
def is_quantum(self) -> boollabel¶
def label(self) -> strDictValue [source]¶
class DictValue(_MetadataValueMixin, ValueBase)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()))(),
) -> NoneAttributes¶
entries: tuple[tuple[TupleValue | Value, Value], ...]logical_id: strmetadata: ValueMetadataname: strtype: DictTypeuuid: str
Methods¶
is_constant¶
def is_constant(self) -> boolnext_version¶
def next_version(self) -> DictValueFloatType [source]¶
class FloatType(ClassicalTypeMixin, ValueType)Type representing a floating-point number.
ForOperation [source]¶
class ForOperation(HasNestedOps, Operation)Represents a for loop operation.
Example:
for i in range(start, stop, step):
bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
loop_var: str = '',
loop_var_value: Value | None = None,
operations: list[Operation] = list(),
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_args: tuple[RegionArg, ...] = (),
captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
captures: tuple[ValueBase, ...]loop_carried_rebinds: tuple[LoopCarriedRebind, ...]loop_var: strloop_var_value: Value | Noneoperation_kind: OperationKindoperations: list[Operation]region_args: tuple[RegionArg, ...]signature: Signature
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include loop_var_value so cloning/substitution stays consistent.
Without this override, UUIDRemapper would clone every body
reference to the loop variable to a fresh UUID, but leave
loop_var_value pointing at the un-cloned original — emit-time
UUID-keyed lookups for the loop variable would then miss.
Loop-carried rebind records and region arguments are included
for the same reason.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the range-loop body with its explicit interface.
Returns:
tuple[Region, ...] — tuple[Region, ...]: One body region containing the induction
value, carried-value formals, captures, and carried yields.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operationrebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild the range-loop body and complete boundary interface.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Exactly one replacement body region. |
Returns:
Operation — Rebuilt range-loop operation.
Raises:
ValueError— If arity or boundary value kinds are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationIfOperation [source]¶
class IfOperation(HasNestedOps, Operation)Represents an if-else conditional operation.
Example:
if condition:
true_body
else:
false_bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
true_operations: list[Operation] = list(),
false_operations: list[Operation] = list(),
true_yields: list[Value] = list(),
false_yields: list[Value] = list(),
branch_rebinds: tuple[BranchRebind, ...] = (),
true_captures: tuple[ValueBase, ...] = (),
false_captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
branch_rebinds: tuple[BranchRebind, ...]condition: Valuefalse_captures: tuple[ValueBase, ...]false_operations: list[Operation]false_yields: list[Value]operation_kind: OperationKindsignature: Signaturetrue_captures: tuple[ValueBase, ...]true_operations: list[Operation]true_yields: list[Value]
Methods¶
add_merge¶
def add_merge(self, true_value: Value, false_value: Value, result: Value) -> NoneAppend a branch-merge slot to this if-else.
The only sanctioned construction path for merges: it keeps the
yield lists and results index-aligned so iter_merges can
rely on the invariants it checks.
Parameters:
| Name | Type | Description |
|---|---|---|
true_value | Value | Value selected when the condition is true. |
false_value | Value | Value selected when the condition is false. Must have the same type as true_value. |
result | Value | Fresh SSA value representing the merged output. Must have the same type as the branch values. |
Raises:
RuntimeError— If the condition operand has not been attached to this operation yet (operands[0]must exist before merges are added), or the branch / result types do not match.
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include branch-yield values and rebind records for cloning/substitution.
The yields are subclass-specific Value fields (not operands —
see the class docstring), so generic passes reach them through
this override, mirroring ForItemsOperation.key_var_values.
Branch rebind records follow the loop operations’ rationale: the
recorded pre-branch values reference program values by identity,
so inline cloning must remap them in lockstep with operands.
Read-based checks must not treat the records as reads (see
_op_read_uuids in the analyze pass module).
Returns:
list[ValueBase] — list[ValueBase]: Base input values plus the true/false
yields and rebind-record values.
iter_merges¶
def iter_merges(self) -> Iterator[IfMerge]Iterate the branch-merge slots of this if-else.
This is the single read API for merge semantics: passes must consume merges through it (never through the yield lists directly) so the underlying storage can change without touching consumers.
Yields:
IfMerge — One entry per merged output, in result order.
Raises:
RuntimeError— If the stored merge data is internally inconsistent (the yield-list lengths differ from the result count, or the condition operand is missing while merges are attached). This indicates IR corruption, not a user error. The per-merge corruption modes of the old embedded-operation storage (a foreign entry, a malformed or mismatched condition, a result copy diverging fromresults[i]) cannot be represented in the yield-list storage and need no checks.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]Return the two branch bodies (merge yields are not operations).
Returns:
list[list[Operation]] — list[list[Operation]]: [true_operations, false_operations].
The branch-merge yields are values, not operations, so
they are intentionally absent here.
nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the true and false branch interfaces.
Returns:
tuple[Region, ...] — tuple[Region, ...]: True and false regions in that order, with
branch-local captures and merge yields.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> OperationReturn a copy with the true and false branch bodies replaced.
Parameters:
| Name | Type | Description |
|---|---|---|
new_lists | list[list[Operation]] | The replacement branch bodies in nested_op_lists order ([true_operations, false_operations]). |
Returns:
Operation — A copy of this if-else with the branch bodies
swapped and all other fields (yields, rebinds) preserved.
rebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild both branches and their complete boundary interfaces.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | True and false replacement regions. |
Returns:
Operation — Rebuilt conditional operation.
Raises:
ValueError— If region count, block arguments, or yield signatures are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationSubstitute operand, result, branch-yield, and rebind-record values.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | dict[str, ValueBase] | UUID-keyed substitution map. |
Returns:
Operation — The rewritten operation.
LoopCarriedRebind [source]¶
class LoopCarriedRebindTrace-time record of a variable rebound inside a loop body.
Two rebind families share this record type, distinguished by the
type of before:
Classical scalar (
beforeclassical): the frontend traces a loop body exactly once, so a Python-level reassignment liketotal = total + iproduces IR whose right-hand side reads the fixed pre-loop value instead of the previous iteration’s value. Most such carries are now represented as explicitRegionArgs (see above) and are fully supported; a classical record is only created for the shapes region binding declines —while-body carries (a runtime while loop cannot be unrolled) and measurement-backedBitcarries — and the transpiler’s classical loop-carried check rejects those with a targeted error instead of silently miscompiling.Quantum (
beforequantum): the loop body left the variable bound to a different quantum resource (logical_idchange — a fresh allocation or another register, not a gate self-update). The transpiler’s control-flow discard check (reject_control_flow_quantum_discard) rejects the ones whose incoming state the body never consumes.
Constructor¶
def __init__(
self,
var_name: str,
before: ValueBase,
after: ValueBase,
before_synthesized: bool = False,
) -> NoneAttributes¶
after: ValueBasebefore: ValueBasebefore_synthesized: boolvar_name: str
NotOp [source]¶
class NotOp(Operation)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
input: Valueoperation_kind: OperationKindoutput: Valuesignature: Signature
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) -> NoneParamHint [source]¶
class ParamHintConstructor¶
def __init__(self, name: str, type: ValueType) -> NoneAttributes¶
name: strtype: ValueType
ParamKind [source]¶
class ParamKind(enum.Enum)Lifecycle classification for a classical kernel argument.
Values:
RUNTIME_PARAMETER: The argument is intended to be bound at
execution time by the backend (or, more generally, by the
outer caller in a hybrid loop). It survives the
compilation pipeline as a symbolic parameter.
COMPILE_TIME_BOUND: The argument was provided as a binding
(or via a Python default) and is folded into the IR by
resolve_parameter_shapes / partial_eval. No
symbolic counterpart remains in the emitted circuit.
Attributes¶
COMPILE_TIME_BOUNDRUNTIME_PARAMETER
ParamSlot [source]¶
class ParamSlotMetadata for a single classical kernel argument.
A ParamSlot describes one position in the kernel’s classical
parameter contract — its declared type, whether it is a runtime
parameter or a compile-time-bound value, the Python default (if
any), the actually-bound value (when kind is
COMPILE_TIME_BOUND), and any outer-DSL hints. Slots are
immutable; pipeline passes that need to update a slot must clone
via dataclasses.replace.
The slot is identified by name, which matches the kernel’s
Python parameter name and the corresponding entry in
Block.label_args. A slot’s name MUST never overlap between
RUNTIME_PARAMETER and COMPILE_TIME_BOUND instances within
one Block (this mirrors the project-level bindings /
parameters disjointness rule).
Constructor¶
def __init__(
self,
name: str,
type: 'ValueType',
kind: ParamKind,
ndim: int = 0,
default: Any = None,
bound_value: Any = None,
differentiable: bool = False,
) -> NoneAttributes¶
bound_value: Anydefault: Anydifferentiable: boolkind: ParamKindname: strndim: inttype: ‘ValueType’
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()) -> NoneAttributes¶
evolved_qubits: Value The evolved quantum register result.gamma: Value The evolution time parameter.observable: Value The Observable parameter operand.operation_kind: OperationKind PauliEvolveOp is QUANTUM - transforms quantum state.qubits: Value The quantum register operand.signature: Signature
QFixedMetadata [source]¶
class QFixedMetadataMetadata for QFixed carriers.
Constructor¶
def __init__(self, qubit_uuids: tuple[str, ...], num_bits: int, int_bits: int) -> NoneAttributes¶
int_bits: intnum_bits: intqubit_uuids: tuple[str, ...]
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,
) -> NoneAttributes¶
fractional_bits: int | Value[UIntType]integer_bits: int | Value[UIntType]
Methods¶
label¶
def label(self) -> strQInitOperation [source]¶
class QInitOperation(Operation)Initialize the qubit
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
QUIntType [source]¶
class QUIntType(QuantumTypeMixin, ValueType)Quantum unsigned integer type.
Represents a quantum register encoding an unsigned integer value using binary encoding (little-endian by default).
Constructor¶
def __init__(self, width: int | Value[UIntType]) -> NoneAttributes¶
width: int | Value[UIntType]
Methods¶
label¶
def label(self) -> strQubitType [source]¶
class QubitType(QuantumTypeMixin, ValueType)Type representing a quantum bit (qubit).
RegionArg [source]¶
class RegionArgExplicit loop-carried value on a loop operation (MLIR-style iter_arg).
A RegionArg makes a loop-carried dependency explicit in the IR,
the way MLIR’s scf.for models iter_args / scf.yield:
On iteration 0 the body reads
block_argbound toinit.After each iteration,
block_argis rebound to that iteration’syieldedvalue.After the loop,
resultholds the final carried value (initwhen the loop ran zero iterations).
The loop body’s operations reference block_arg (the frontend
substitutes the traced pre-loop reads), and post-loop operations
reference result (the frontend rebinds the Python handle when it
closes the loop). result is also appended to the loop operation’s
results list so dependency analysis sees the loop as its
producer.
This subsumes the trace-once staleness that LoopCarriedRebind
records exist to reject: a rebind represented as a RegionArg is
a supported loop-carried value, not a miscompilation hazard.
Constructor¶
def __init__(
self,
var_name: str,
init: Value,
block_arg: Value,
yielded: Value,
result: Value,
) -> NoneAttributes¶
block_arg: Valueinit: Valueresult: Valuevar_name: stryielded: Value
ReleaseSliceViewOperation [source]¶
class ReleaseSliceViewOperation(Operation)Mark a slice view’s borrow as explicitly returned to its parent.
Emitted by :meth:Vector.__setitem__ when used with a slice index
(qs[a:b] = qmc.h(qs[a:b])). This op tells the post-fold
linearity checker
(:class:~qamomile.circuit.transpiler.passes.slice_borrow_check.SliceBorrowCheckPass)
that the view referenced in operands[0] no longer owns its
covered parent slots, mirroring the frontend’s
VectorView.consume(operation_name="slice assignment") borrow
release.
Like :class:SliceArrayOperation, this op is a declarative
classical-side marker that does not survive into the emit stream:
:class:~qamomile.circuit.transpiler.passes.strip_slice_ops.StripSliceArrayOpsPass
removes both :class:SliceArrayOperation and
:class:ReleaseSliceViewOperation after
:class:SliceBorrowCheckPass has observed them. Reaching emit
is a compiler-internal invariant violation and is rejected with a
RuntimeError from :mod:standard_emit.
Within a control-flow body (ForOperation / WhileOperation
/ IfOperation), this op only releases view borrows that were
created within the same body. Releasing a borrow that the
enclosing block has registered (an “outer-snapshot” borrow) is
rejected by SliceBorrowCheckPass with ValidationError — the
loop-merge semantics of the
pass cannot propagate entry deletions out of the body, so the only
way to keep the static check consistent is to forbid that pattern.
Example:
``qs[1:3] = qmc.h(qs[1:3])`` emits, after the broadcast loop::
ReleaseSliceViewOperation(
operands=[qmc_h_result_view], # slice_of=qs_value
results=[],
)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKind Release is classical — it updates borrow tracking metadata only.signature: Signature Return the type signature of this release operation.
ReturnQuantumArrayElementOperation [source]¶
class ReturnQuantumArrayElementOperation(Operation)Validate a branch-selected quantum element’s array return at emit time.
Most quantum element assignments are verified structurally by the frontend and emit no IR. A compile-time conditional can instead select different element indices on its branches; only the unrolled emit context knows which source index survived. This operation carries both the requested target indices and the conditional source indices so emission can prove they resolve to the same physical slot before treating the assignment as a borrow return.
Operand convention:
[array, returned_qubit, *target_indices, *source_indices]. The
target and source halves have equal nonzero arity, inferred from the
operand count. The operation has no results and emits no backend gate.
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
array: ArrayValue Return the quantum array receiving the borrowed element.index_arity: int Return the number of target (and source) index operands.operation_kind: OperationKind Classify the return validator as a quantum operation.returned_value: Value Return the quantum value being returned.signature: Signature Return the deferred validator’s operand-only signature.source_indices: tuple[Value, ...] Return the branch-merged borrow-source indices.target_indices: tuple[Value, ...] Return the user-written assignment indices.
RuntimeClassicalExpr [source]¶
class RuntimeClassicalExpr(Operation)A classical expression known to require runtime evaluation.
Lowered from CompOp / CondOp / NotOp / BinOp by
ClassicalLoweringPass when the op’s operand dataflow traces back
to a MeasureOperation (i.e. cannot be folded at compile-time, by
emit-time loop unrolling, or by compile_time_if_lowering). Backend
emit translates this 1:1 to a backend-native runtime expression
(e.g. qiskit.circuit.classical.expr.Expr).
Operand convention:
Binary kinds (EQ/NEQ/LT/LE/GT/GE/AND/OR/ADD/SUB/MUL/DIV/FLOORDIV/MOD/POW):
operands = [lhs, rhs].Unary kind (NOT):
operands = [val].Ternary kind (SELECT):
operands = [condition, true_value, false_value]— the runtime form of a branch merge (result = true_value if condition else false_value).Result:
results = [output_value].
The single-node + unified-kind shape (vs four parallel subclasses)
keeps the backend dispatch a single match op.kind instead of four
parallel hooks, and makes the IR self-documenting: a single
RuntimeClassicalExpr instance signals “runtime evaluation
required” regardless of which classical family it came from.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
kind: RuntimeOpKind | None = None,
) -> NoneAttributes¶
kind: RuntimeOpKind | Noneoperation_kind: OperationKindsignature: Signature
RuntimeOpKind [source]¶
class RuntimeOpKind(enum.Enum)Unified kind for RuntimeClassicalExpr covering all classical
op families that can appear at runtime.
The split between this enum and the per-family BinOpKind /
CompOpKind / CondOpKind is intentional: compile-time-foldable
classical ops keep their original IR types so the existing fold
pipeline (constant_fold → compile_time_if_lowering → emit-time
evaluate_classical_predicate) is undisturbed. Only ops identified
as runtime-evaluation-only by ClassicalLoweringPass get rewritten
to RuntimeClassicalExpr with a member of this enum.
Attributes¶
ADDANDDIVEQFLOORDIVGEGTLELTMODMULNEQNOTORPOWSELECTSUB
ScalarMetadata [source]¶
class ScalarMetadataMetadata for scalar constants and symbolic parameters.
Constructor¶
def __init__(
self,
const_value: int | float | bool | None = None,
parameter_name: str | None = None,
) -> NoneAttributes¶
const_value: int | float | bool | Noneparameter_name: str | None
Signature [source]¶
class SignatureConstructor¶
def __init__(
self,
operands: list[ParamHint | None] = list(),
results: list[ParamHint] = list(),
) -> NoneAttributes¶
operands: list[ParamHint | None]results: list[ParamHint]
SliceArrayOperation [source]¶
class SliceArrayOperation(Operation)Construct a strided view of an ArrayValue.
The op itself performs no quantum action — it records that the
result ArrayValue is a strided view of the operand parent
with the given start / step. The result’s
slice_of / slice_start / slice_step fields carry the
affine map used by the emit-time resolver.
SliceArrayOperation is classified as :attr:OperationKind.CLASSICAL
because slicing is pure index selection — no new quantum operation
is introduced. The pipeline keeps this op through
PartialEvaluationPass (which invokes
ConstantFoldingPass(..., strip_slice_ops=False)) so the
post-fold :class:~qamomile.circuit.transpiler.passes.slice_borrow_check.SliceBorrowCheckPass
can use it as a view-declaration marker; once that check has run,
StripSliceArrayOpsPass removes every SliceArrayOperation
/ ReleaseSliceViewOperation so segmentation
(:mod:~qamomile.circuit.transpiler.passes.separate) and the
downstream emit stage only see a pure quantum-op stream. By the
time :mod:~qamomile.circuit.transpiler.passes.separate runs the
op has therefore been stripped — reaching emit is a compiler-
internal invariant violation.
Example:
``q[1::2]`` on a ``Vector[Qubit]`` emits::
SliceArrayOperation(
operands=[q_value, uint_1, uint_2],
results=[sliced_value], # slice_of=q_value, slice_start=uint_1, slice_step=uint_2
)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKind Slice is classical — it selects indices without quantum action.signature: Signature Return the type signature of this slice operation.
StaticBindingField [source]¶
class StaticBindingFieldReference one scalar field projected from a static binding.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | Registered field name on the bound object. |
value | Value | Symbolic scalar used by the hierarchical IR until the binding is materialized. |
Constructor¶
def __init__(self, name: str, value: Value) -> NoneAttributes¶
name: strvalue: Value
StaticBindingSlot [source]¶
class StaticBindingSlotDeclare one typed compile-time object required by a qkernel.
The object itself is not an SSA value and never reaches a backend. Only registered scalar projections and deferred callable-member references may appear in the hierarchical body. A build must resolve the slot before the block advances to a compiler stage.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | QKernel argument name used by bindings. |
type_key | str | Stable key of the registered static-binding adapter. |
fields | tuple[StaticBindingField, ...] | Scalar projections referenced while tracing the unbound qkernel. |
Constructor¶
def __init__(
self,
name: str,
type_key: str,
fields: tuple[StaticBindingField, ...] = (),
) -> NoneAttributes¶
fields: tuple[StaticBindingField, ...]name: strtype_key: str
StoreArrayElementOperation [source]¶
class StoreArrayElementOperation(Operation)Store a classical scalar into one element of a classical array.
This is the IR form of array[index] = value for classical element
types (Bit / UInt / Float). Classical values are freely
copyable, so the store is an ordinary SSA rewrite: the operation
consumes the current array version and produces a new ArrayValue
version (same logical_id, fresh uuid) whose contents equal the
input array with the addressed element replaced. Quantum arrays never
use this operation — qubit element assignment is the return half of
the borrow-return idiom and emits no IR.
The operation is evaluated in one of two places:
Compile time:
ConstantFoldingPassfolds the store when the source array contents, the index, and the stored value are all compile-time resolvable, attaching the updatedconst_arraymetadata to the result value.Runtime: otherwise the store executes host-side in a classical segment via
ClassicalExecutor(e.g. for measurement-derivedVector[Bit]contents). It must never reach a quantum segment; backend emit rejects it explicitly.
Operand convention:
operands: [array (ArrayValue), stored_value (Value), *index_values]
results: [new_array (ArrayValue)]
Example:
@qmc.qkernel
def k() -> qmc.Vector[qmc.Bit]:
qs = qmc.qubit_array(2, "qs")
qs[0] = qmc.x(qs[0])
bits = qmc.measure(qs)
bits[1] = bits[0] # emits StoreArrayElementOperation
return bitsConstructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
array: ArrayValue ArrayValue: The array version the store reads from.index_values: tuple[Value, ...] tuple[Value, ...]: The element indices being written.operation_kind: OperationKindsignature: Signature Return the operation’s dynamic array/qubit/index signature.stored_value: Value Value: The scalar being written into the array.
SymbolicControlledU [source]¶
class SymbolicControlledU(ControlledUOperation)Controlled-U with symbolic (Value) number of controls.
Operand layout: [ctrl_arg_0, ..., ctrl_arg_{k-1}, tgt_0, ..., tgt_m, params...]
Result layout: [ctrl_arg_0', ..., ctrl_arg_{k-1}', tgt_0', ..., tgt_m']
The number of control arguments k is recorded in
num_control_args; the default k = 1 corresponds to the
historical single-pool form (operands[0] is a
Vector[Qubit] / VectorView whose length equals
num_controls, or whose control_indices-selected subset
does). When k > 1 the control prefix is a heterogeneous
sequence of scalar Qubit values and ArrayValues whose
total qubit count is num_controls; the emit pass walks them
in order to recover the per-physical-qubit control set.
When control_indices is None the entire control prefix
is used as active controls (one-arg form: len(ctrl_vector) == num_controls; multi-arg form: the qubit-count sum of the
prefix args equals num_controls). When non-None, the
listed indices select exactly num_controls slots from a
single-arg pool to act as controls; combining
control_indices with the multi-arg control prefix is
rejected at frontend time.
Each control_indices entry is stored as a Value of
UIntType regardless of whether the frontend passed an
int literal or a UInt handle, so all downstream
value-substitution passes see a uniform shape.
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=(UIntType()), name=''))(),
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] = dict(),
control_indices: tuple[Value, ...] | None = None,
num_control_args: int = 1,
) -> NoneAttributes¶
control_indices: tuple[Value, ...] | Nonecontrol_operands: list[Value]is_symbolic_num_controls: boolnum_control_args: intnum_controls: Valueparam_operands: list[Value] Get classical/object operands after the symbolic control prefix.signature: Signaturetarget_operands: list[Value] Return the wrapped callable’s target and parameter operands.
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationTupleType [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, ...]) -> NoneAttributes¶
element_types: tuple[ValueType, ...]
Methods¶
is_classical¶
def is_classical(self) -> boolis_quantum¶
def is_quantum(self) -> boollabel¶
def label(self) -> strTupleValue [source]¶
class TupleValue(_MetadataValueMixin, ValueBase)A tuple of IR values for structured data.
Constructor¶
def __init__(
self,
name: str,
elements: tuple[ValueLike, ...] = tuple(),
metadata: ValueMetadata = ValueMetadata(),
uuid: str = (lambda: str(uuid.uuid4()))(),
logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> NoneAttributes¶
elements: tuple[ValueLike, ...]logical_id: strmetadata: ValueMetadataname: strtype: ‘TupleType’uuid: str
Methods¶
is_constant¶
def is_constant(self) -> boolnext_version¶
def next_version(self) -> TupleValueUIntType [source]¶
class UIntType(ClassicalTypeMixin, ValueType)Type representing an unsigned integer.
UnaryMathOp [source]¶
class UnaryMathOp(Operation)Represent one pure unary mathematical expression.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | list[Value] | Single numeric input value. |
results | list[Value] | Single numeric result value. |
kind | UnaryMathOpKind | None | Mathematical operation to apply. |
Raises:
ValueError— Ifkindis missing or the operation does not have exactly one operand and one result.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
kind: UnaryMathOpKind | None = None,
) -> NoneAttributes¶
input: Value Return the input value.kind: UnaryMathOpKind | Noneoperation_kind: OperationKind Classify the operation as classical.output: Value Return the output value.signature: Signature Return the typed unary signature.
UnaryMathOpKind [source]¶
class UnaryMathOpKind(enum.Enum)Identify one abstract unary mathematical operation.
Attributes¶
CEILLOG2
Value [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.
ValueBase [source]¶
class ValueBaseNominal base for every typed IR value.
Runtime compiler passes inspect values in their innermost loops. A nominal base keeps those checks constant-time; a runtime-checkable protocol would repeatedly scan the protocol members on Python versions that do not cache structural checks.
Attributes¶
logical_id: strmetadata: ValueMetadataname: strtype: ValueType Return the static IR type carried by this value.uuid: str
Methods¶
get_const¶
def get_const(self) -> int | float | bool | NoneReturn the scalar constant carried by this value.
Returns:
int | float | bool | None — int | float | bool | None: Constant value, or None when the
value is not constant.
is_constant¶
def is_constant(self) -> boolReturn whether this value carries a scalar constant.
Returns:
bool — Whether scalar constant metadata is present.
is_parameter¶
def is_parameter(self) -> boolReturn whether this value represents a runtime parameter.
Returns:
bool — Whether parameter metadata is present.
next_version¶
def next_version(self) -> ValueBaseCreate the next SSA version of this value.
Returns:
ValueBase — A value with a fresh version UUID and preserved logical
identity.
parameter_name¶
def parameter_name(self) -> str | NoneReturn the public parameter name carried by this value.
Returns:
str | None — str | None: Parameter name, or None for a non-parameter value.
ValueMetadata [source]¶
class ValueMetadataTyped metadata owned by the compiler/runtime.
Constructor¶
def __init__(
self,
scalar: ScalarMetadata | None = None,
cast: CastMetadata | None = None,
qfixed: QFixedMetadata | None = None,
array_runtime: ArrayRuntimeMetadata | None = None,
dict_runtime: DictRuntimeMetadata | None = None,
) -> NoneAttributes¶
array_runtime: ArrayRuntimeMetadata | Nonecast: CastMetadata | Nonedict_runtime: DictRuntimeMetadata | Noneqfixed: QFixedMetadata | Nonescalar: ScalarMetadata | None
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) -> boolis_object¶
def is_object(self) -> boolis_quantum¶
def is_quantum(self) -> boollabel¶
def label(self) -> strWhileOperation [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,
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_args: tuple[RegionArg, ...] = (),
captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
captures: tuple[ValueBase, ...]loop_carried_rebinds: tuple[LoopCarriedRebind, ...]max_iterations: int | Noneoperation_kind: OperationKindoperations: list[Operation]region_args: tuple[RegionArg, ...]signature: Signature
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include rebind records and region args for cloning/substitution.
Same rationale as ForOperation.all_input_values: rebind
records and region arguments reference body/pre-loop values by
identity, so inline cloning must remap them in lockstep with
body operands.
Returns:
list[ValueBase] — list[ValueBase]: Base input values plus rebind-record and
region-argument values.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the while body with explicit boundary values.
Returns:
tuple[Region, ...] — tuple[Region, ...]: One body region whose block arguments and
yields are aligned with region_args. The updated
condition, when present, is appended as the final yield.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operationrebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild the while body and its complete boundary interface.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Exactly one replacement body region. |
Returns:
Operation — Rebuilt while operation.
Raises:
ValueError— If arity or boundary value kinds are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationSubstitute operand, rebind-record, and region-arg values.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | dict[str, ValueBase] | UUID-keyed substitution map. |
Returns:
Operation — The rewritten operation.
qamomile.circuit.ir.serialize.encode¶
Semantic IR block → private graph-record encoder.
Walks a :class:Block and produces the internal graph records consumed by
:mod:qamomile.circuit.serialization.graph_protobuf. Values and callable
definitions are deduplicated into module-wide tables and referenced elsewhere
by stable IDs. Keeping those registries outside individual blocks preserves
recursive call graphs and shared callable identity without expanding the
high-level IR into backend-specific instructions.
Every encoder branch is dispatched through a hard-coded table keyed
on the runtime class; there is no dynamic resolution, no getattr
on user data, and no importlib use. The decoder mirrors this
discipline (see :mod:qamomile.circuit.ir.serialize.decode).
Overview¶
| Function | Description |
|---|---|
array_to_dict | Encode a numpy ndarray into the wrapper dict. |
hamiltonian_to_dict | Encode a Hamiltonian into the wrapper dict. |
is_plain_int | Return True if value is a Python int but not a bool. |
scalar_to_dict | Encode an allow-listed NumPy scalar without widening its dtype. |
validate_region_args | Validate the SSA identities owned by a loop’s region arguments. |
| Class | Description |
|---|---|
ArrayRuntimeMetadata | Metadata for array literals and explicit element identity tracking. |
ArrayValue | An array of typed IR values. |
BinOp | Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN). |
BitType | Type representing a classical bit. |
Block | Unified block representation for all pipeline stages. |
BlockType | Type representing a block/function reference. |
BranchRebind | Trace-time record of a quantum variable rebound inside an if branch. |
CInitOperation | Initialize the classical values (const, arguments etc) |
CastMetadata | Metadata describing a cast carrier and its underlying qubits. |
CastOperation | Type cast operation for creating aliases over the same quantum resources. |
CompOp | Comparison operation (EQ, NEQ, LT, LE, GT, GE). |
ConcreteControlledU | Controlled-U with concrete (int) number of controls. |
CondOp | Conditional logical operation (AND, OR). |
DecodeQFixedOperation | Decode measured bits to float (classical operation). |
DictGetItemOperation | Look up one entry of a Dict by a (possibly symbolic) key. |
DictRuntimeMetadata | Metadata for transpile-time bound dict values. |
DictType | Type representing a dictionary mapping keys to values. |
DictValue | A dictionary value stored as stable ordered entries. |
FloatType | Type representing a floating-point number. |
ForOperation | Represents a for loop operation. |
Hamiltonian | Represents a quantum Hamiltonian as a sum of Pauli operator products. |
IfOperation | Represents an if-else conditional operation. |
LoopCarriedRebind | Trace-time record of a variable rebound inside a loop body. |
NotOp | |
ObservableType | Type representing a Hamiltonian observable parameter. |
PauliEvolveOp | Pauli evolution operation: exp(-i * gamma * H). |
QFixedMetadata | Metadata for QFixed carriers. |
QFixedType | Quantum fixed-point type. |
QInitOperation | Initialize the qubit |
QUIntType | Quantum unsigned integer type. |
QubitType | Type representing a quantum bit (qubit). |
RegionArg | Explicit loop-carried value on a loop operation (MLIR-style iter_arg). |
ReleaseSliceViewOperation | Mark a slice view’s borrow as explicitly returned to its parent. |
ReturnQuantumArrayElementOperation | Validate a branch-selected quantum element’s array return at emit time. |
RuntimeClassicalExpr | A classical expression known to require runtime evaluation. |
ScalarMetadata | Metadata for scalar constants and symbolic parameters. |
Signature | |
SliceArrayOperation | Construct a strided view of an ArrayValue. |
StoreArrayElementOperation | Store a classical scalar into one element of a classical array. |
SymbolicControlledU | Controlled-U with symbolic (Value) number of controls. |
TupleType | Type representing a tuple of values. |
TupleValue | A tuple of IR values for structured data. |
UIntType | Type representing an unsigned integer. |
UnaryMathOp | Represent one pure unary mathematical expression. |
Value | A typed SSA value in the IR. |
ValueBase | Nominal base for every typed IR value. |
ValueMetadata | Typed metadata owned by the compiler/runtime. |
ValueType | Base class for all value types in the IR. |
WhileOperation | Represents a while loop operation. |
Functions¶
array_to_dict [source]¶
def array_to_dict(arr: np.ndarray) -> dict[str, Any]Encode a numpy ndarray into the wrapper dict.
Parameters:
| Name | Type | Description |
|---|---|---|
arr | np.ndarray | Source array with an allow-listed primitive dtype. |
Returns:
dict[str, Any] — dict[str, Any]: A wrapper dict with $np_array, dtype,
shape (list[int]), and data (raw bytes from
ndarray.tobytes()). The wire encoders are responsible
for any further bytes ⇄ text conversion at format
boundaries.
Raises:
TypeError— Ifarris not anumpy.ndarray.ValueError— If the array’s dtype is not in the allow-list.
hamiltonian_to_dict [source]¶
def hamiltonian_to_dict(h: Hamiltonian) -> dict[str, Any]Encode a Hamiltonian into the wrapper dict.
Terms are emitted in the Hamiltonian’s own term-dict iteration
order; each term is a [operators, coefficient] pair where
operators is a list of [pauli_name, qubit_index] entries.
Parameters:
| Name | Type | Description |
|---|---|---|
h | Hamiltonian | The Hamiltonian to encode. Term coefficients and the constant must be int, float, or complex, or a numpy scalar of one of those kinds (coerced via .item()). |
Returns:
dict[str, Any] — dict[str, Any]: A wrapper dict with $hamiltonian,
terms, constant, and num_qubits (the declared
register width passed to the constructor, or None).
Raises:
TypeError— Ifhis not aHamiltonian, if a coefficient / the constant is not int, float, or complex, or if the declarednum_qubitsis not an int — all after coercing anynumpyscalar to its Python equivalent.ValueError— If the declarednum_qubitsis negative.
is_plain_int [source]¶
def is_plain_int(value: object) -> boolReturn True if value is a Python int but not a bool.
bool is a subclass of int in Python, so isinstance(True, int)
is True. This helper distinguishes a genuine integer from a boolean,
which matters wherever a boolean must be rejected in an integer slot — for
example, validating decoded wire data or a register width.
Parameters:
| Name | Type | Description |
|---|---|---|
value | object | The value to test. |
Returns:
bool — True when value is an int and not a bool.
scalar_to_dict [source]¶
def scalar_to_dict(value: np.generic) -> dict[str, Any]Encode an allow-listed NumPy scalar without widening its dtype.
Parameters:
| Name | Type | Description |
|---|---|---|
value | np.generic | NumPy scalar whose dtype and exact bytes must be preserved. |
Returns:
dict[str, Any] — dict[str, Any]: Tagged scalar wrapper containing dtype and raw bytes.
Raises:
TypeError— Ifvalueis not a NumPy scalar.ValueError— If its dtype is outside the portable allow-list.
validate_region_args [source]¶
def validate_region_args(op: ForOperation | ForItemsOperation | WhileOperation) -> tuple[RegionArg, ...]Validate the SSA identities owned by a loop’s region arguments.
A loop owns several definition namespaces: its iteration variables,
every RegionArg.block_arg, and every RegionArg.result. Those
identities must be pairwise disjoint. Otherwise different stages can
assign incompatible meanings to one UUID: a UUID-keyed environment has
only one slot, so binding either the iteration variable or the carried
value overwrites the other and makes both reads observe the same value.
Parameters:
| Name | Type | Description |
|---|---|---|
op | ForOperation | ForItemsOperation | WhileOperation | Loop operation whose region arguments should be validated. |
Returns:
tuple[RegionArg, ...] — tuple[RegionArg, ...]: The validated op.region_args tuple.
Raises:
ValueError— If result counts or positions disagree, slot types differ, or any loop-owned definition identity collides with another definition or with a region initializer/body yield.
Classes¶
ArrayRuntimeMetadata [source]¶
class ArrayRuntimeMetadataMetadata for array literals and explicit element identity tracking.
element_parent_uuids / element_parent_indices are parallel to
element_uuids: for each tracked element they record the root array’s
UUID and the element’s index within that root (as resolved by
:func:resolve_root_qubit_address at trace time). They let an emit pass map
a packed element back to the physical qubit registered under the root
array’s QubitAddress(root_uuid, index) key even when the element’s own
UUID was never registered. The sentinel ("", -1) marks an element with
no array parent (a standalone qubit), for which a flat UUID lookup is used.
(root_uuid, -1) preserves a known root owner when the scalar index is
symbolic and therefore cannot be resolved at trace time.
Constructor¶
def __init__(
self,
const_array: Any = None,
element_uuids: tuple[str, ...] = (),
element_logical_ids: tuple[str, ...] = (),
element_parent_uuids: tuple[str, ...] = (),
element_parent_indices: tuple[int, ...] = (),
) -> NoneAttributes¶
const_array: Anyelement_logical_ids: tuple[str, ...]element_parent_indices: tuple[int, ...]element_parent_uuids: tuple[str, ...]element_uuids: tuple[str, ...]
ArrayValue [source]¶
class ArrayValue(Value[T])An array of typed IR values.
When slice_of is set, this array is a strided view over another
array. Element accesses on a sliced ArrayValue resolve to
physical slots on the root parent via the affine map
parent_index = slice_start + slice_step * view_local_index,
applied recursively along slice_of chains. The emit-time
resolver walks this chain to produce the final qubit index; passes
that substitute or clone values must treat slice_of /
slice_start / slice_step as Value references that need to
track through the same mapping as parent_array.
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(),
slice_of: 'ArrayValue | None' = None,
slice_start: 'Value | None' = None,
slice_step: 'Value | None' = None,
) -> NoneAttributes¶
logical_id: strmetadata: ValueMetadataname: strshape: tuple[Value, ...]slice_of: ‘ArrayValue | None’slice_start: ‘Value | None’slice_step: ‘Value | None’type: Tuuid: str
Methods¶
is_slice¶
def is_slice(self) -> boolReturn True if this array is a strided view of another array.
Returns:
bool — True iff slice_of is non-None.
next_version¶
def next_version(self) -> ArrayValue[T]BinOp [source]¶
class BinOp(BinaryOperationBase)Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN).
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
kind: BinOpKind | None = None,
) -> NoneAttributes¶
kind: BinOpKind | Noneoperation_kind: OperationKindsignature: Signature
BitType [source]¶
class BitType(ClassicalTypeMixin, ValueType)Type representing a classical bit.
Block [source]¶
class BlockUnified 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[ValueLike] = list(),
output_values: list[ValueLike] = list(),
output_names: list[str] = list(),
operations: list['Operation'] = list(),
kind: BlockKind = BlockKind.HIERARCHICAL,
parameters: dict[str, Value] = dict(),
param_slots: tuple[ParamSlot, ...] = tuple(),
static_bindings: tuple[StaticBindingSlot, ...] = tuple(),
) -> NoneAttributes¶
effects: ‘KernelEffect’ Return lazily cached semantic effects for this block.input_values: list[ValueLike]kind: BlockKindlabel_args: list[str]measurement_result_indices: frozenset[int] Return public output positions derived from measurement.name: stroperations: list[‘Operation’]output_names: list[str]output_values: list[ValueLike]param_slots: tuple[ParamSlot, ...]parameters: dict[str, Value]static_bindings: tuple[StaticBindingSlot, ...]
Methods¶
call¶
def call(self, **kwargs: ValueLike = {}) -> 'InvokeOperation'Create an inline callable invocation against this block.
Parameters:
| Name | Type | Description |
|---|---|---|
**kwargs | ValueLike | Actual argument values keyed by self.label_args. |
Returns:
'InvokeOperation' — Inline-policy invocation whose callable
definition points at this block.
Raises:
KeyError— If a required label inself.label_argsis missing fromkwargs.
is_affine¶
def is_affine(self) -> boolReturn whether this block has passed affine validation.
Returns:
bool — True for AFFINE and ANALYZED blocks.
unbound_parameters¶
def unbound_parameters(self) -> list[str]Return list of unbound parameter names.
BlockType [source]¶
class BlockType(ObjectTypeMixin, ValueType)Type representing a block/function reference.
BranchRebind [source]¶
class BranchRebindTrace-time record of a quantum variable rebound inside an if branch.
The frontend’s branch tracing merges only the new branch values
through merge operations; when both branches rebind a variable, the
value the variable held before the branch no longer appears anywhere
in the IfOperation. These records preserve that pre-branch
binding so the transpiler’s control-flow discard check
(reject_control_flow_quantum_discard in
qamomile.circuit.transpiler.passes.analyze) can verify that the
pre-branch quantum state is consumed or carried on every runtime
execution path instead of being silently dropped.
Constructor¶
def __init__(
self,
var_name: str,
before: Value,
rebound_in_true: bool,
rebound_in_false: bool,
) -> NoneAttributes¶
before: Valuerebound_in_false: boolrebound_in_true: boolvar_name: str
CInitOperation [source]¶
class CInitOperation(Operation)Initialize the classical values (const, arguments etc)
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
CastMetadata [source]¶
class CastMetadataMetadata describing a cast carrier and its underlying qubits.
Constructor¶
def __init__(
self,
source_uuid: str,
qubit_uuids: tuple[str, ...],
source_logical_id: str | None = None,
qubit_logical_ids: tuple[str, ...] = (),
) -> NoneAttributes¶
qubit_logical_ids: tuple[str, ...]qubit_uuids: tuple[str, ...]source_logical_id: str | Nonesource_uuid: str
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:
Vector[Qubit] -> QFixed (after QPE, for phase measurement)
Vector[Qubit] -> QUInt (for quantum arithmetic)
QUInt -> QFixed (reinterpret bits with different encoding)
QFixed -> QUInt (reinterpret bits with different encoding)
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(),
) -> NoneAttributes¶
num_qubits: int Number of qubits involved in the cast.operation_kind: OperationKind Cast stays in the same segment as its source (QUANTUM for quantum types).qubit_mapping: list[str]signature: Signature Return the type signature of this cast operation.source_type: ValueType | Nonetarget_type: ValueType | None
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,
) -> NoneAttributes¶
kind: CompOpKind | Noneoperation_kind: OperationKindsignature: Signature
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,
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] = dict(),
control_value: int | None = None,
) -> NoneAttributes¶
control_operands: list[Value]control_value: int | Nonenum_controls: intparam_operands: list[Value] Get classical/object operands after the concrete control prefix.signature: Signature Build the concrete controlled call signature.target_operands: list[Value] Return the wrapped callable’s target and parameter operands.
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,
) -> NoneAttributes¶
kind: CondOpKind | Noneoperation_kind: OperationKindsignature: Signature
DecodeQFixedOperation [source]¶
class DecodeQFixedOperation(Operation)Decode measured bits to float (classical operation).
This operation converts a sequence of classical bits from qubit measurements into a floating-point number using fixed-point encoding.
The decoding formula for least-significant-first storage:
float_value = Σ bit[i] * 2^(int_bits - num_bits + i)
For QPE phase (int_bits=0):
bit[0] has weight 2**(-num_bits) and bit[-1] has weight 0.5.
Example:
bits = [1, 0, 1] with int_bits=0
→ 0.101 (MSB-first display) = 0.5 + 0.125 = 0.625operands: [ArrayValue of bits (vec[bit])] results: [Float value]
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_bits: int = 0,
int_bits: int = 0,
) -> NoneAttributes¶
int_bits: intnum_bits: intoperation_kind: OperationKindsignature: Signature
DictGetItemOperation [source]¶
class DictGetItemOperation(Operation)Look up one entry of a Dict by a (possibly symbolic) key.
This is the IR form of d[key] on a Dict handle. The key
components may be symbolic (e.g. loop variables of a for-items
loop); the lookup is resolved at emit time when the key values and
the dict’s bound data are both concrete.
operands: [DictValue, *key_component_values] results: [looked-up scalar value]
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
key_arity: int = 1,
) -> NoneAttributes¶
dict_value: Value Value: The DictValue being indexed (operands[0]).key_arity: intkey_values: tuple[Value, ...] tuple[Value, ...]: The key component values.operation_kind: OperationKindsignature: Signature
DictRuntimeMetadata [source]¶
class DictRuntimeMetadataMetadata for transpile-time bound dict values.
Constructor¶
def __init__(self, bound_data: tuple[tuple[Any, Any], ...] = ()) -> NoneAttributes¶
bound_data: tuple[tuple[Any, Any], ...]
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,
) -> NoneAttributes¶
key_type: ValueType | Nonevalue_type: ValueType | None
Methods¶
is_classical¶
def is_classical(self) -> boolis_quantum¶
def is_quantum(self) -> boollabel¶
def label(self) -> strDictValue [source]¶
class DictValue(_MetadataValueMixin, ValueBase)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()))(),
) -> NoneAttributes¶
entries: tuple[tuple[TupleValue | Value, Value], ...]logical_id: strmetadata: ValueMetadataname: strtype: DictTypeuuid: str
Methods¶
is_constant¶
def is_constant(self) -> boolnext_version¶
def next_version(self) -> DictValueFloatType [source]¶
class FloatType(ClassicalTypeMixin, ValueType)Type representing a floating-point number.
ForOperation [source]¶
class ForOperation(HasNestedOps, Operation)Represents a for loop operation.
Example:
for i in range(start, stop, step):
bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
loop_var: str = '',
loop_var_value: Value | None = None,
operations: list[Operation] = list(),
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_args: tuple[RegionArg, ...] = (),
captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
captures: tuple[ValueBase, ...]loop_carried_rebinds: tuple[LoopCarriedRebind, ...]loop_var: strloop_var_value: Value | Noneoperation_kind: OperationKindoperations: list[Operation]region_args: tuple[RegionArg, ...]signature: Signature
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include loop_var_value so cloning/substitution stays consistent.
Without this override, UUIDRemapper would clone every body
reference to the loop variable to a fresh UUID, but leave
loop_var_value pointing at the un-cloned original — emit-time
UUID-keyed lookups for the loop variable would then miss.
Loop-carried rebind records and region arguments are included
for the same reason.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the range-loop body with its explicit interface.
Returns:
tuple[Region, ...] — tuple[Region, ...]: One body region containing the induction
value, carried-value formals, captures, and carried yields.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operationrebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild the range-loop body and complete boundary interface.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Exactly one replacement body region. |
Returns:
Operation — Rebuilt range-loop operation.
Raises:
ValueError— If arity or boundary value kinds are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationHamiltonian [source]¶
class HamiltonianRepresents a quantum Hamiltonian as a sum of Pauli operator products.
The Hamiltonian is stored as a dictionary where keys are tuples of PauliOperators and values are their corresponding coefficients.
Example:
>>> H = Hamiltonian()
>>> H.add_term((PauliOperator(Pauli.X, 0), PauliOperator(Pauli.Y, 1)), 0.5)
>>> H.add_term((PauliOperator(Pauli.Z, 2),), 1.0)
>>> print(H.terms)
{(X0, Y1): 0.5, (Z2,): 1.0}Constructor¶
def __init__(self, num_qubits: int | None = None) -> NoneAttributes¶
constant: float | complexnum_qubits: int Calculates the number of qubits in the Hamiltonian.terms: dict[tuple[PauliOperator, ...], complex] Getter for the terms of the Hamiltonian.
Methods¶
add_term¶
def add_term(self, operators: tuple[PauliOperator, ...], coeff: float | complex)Adds a term to the Hamiltonian.
This method adds a product of Pauli operators with a given coefficient to the Hamiltonian. If the term already exists, the coefficients are summed.
Parameters:
| Name | Type | Description |
|---|---|---|
operators | Tuple[PauliOperator, ...] | A tuple of PauliOperators representing the term. |
coeff | Union[float, complex] | The coefficient of the term. |
Example:
>>> H = Hamiltonian()
>>> H.add_term((PauliOperator(Pauli.X, 0), PauliOperator(Pauli.Y, 1)), 0.5)
>>> H.add_term((PauliOperator(Pauli.X, 0), PauliOperator(Pauli.Y, 1)), 0.5j)
>>> print(H.terms)
{(X0, Y1): (0.5+0.5j)}copy¶
def copy(self) -> HamiltonianReturn an independent copy sharing no mutable state with self.
Produces a new Hamiltonian with the same terms, constant,
and declared _num_qubits. The underlying _terms dict
is fresh, so subsequent add_term / constant mutations
on either instance do not affect the other. PauliOperator
instances inside the term tuples are reused — they are
dataclass(frozen=True) values and safely shared.
Returns:
Hamiltonian — A shallow-cloned Hamiltonian instance.
Example:
>>> H = Hamiltonian()
>>> H.add_term((PauliOperator(Pauli.Z, 0),), 1.0)
>>> H2 = H.copy()
>>> H2.add_term((PauliOperator(Pauli.X, 1),), 0.5)
>>> H.num_qubits # unchanged by H2's mutation
1identity¶
@classmethod
def identity(
cls,
coeff: float | complex = 1.0,
num_qubits: int | None = None,
) -> HamiltonianCreate a scalar times identity Hamiltonian.
remap_qubits¶
def remap_qubits(self, qubit_map: dict[int, int]) -> HamiltonianRemap qubit indices according to the given mapping.
This is used to translate Pauli indices (logical indices within an expval call) to physical qubit indices in the actual quantum circuit.
Parameters:
| Name | Type | Description |
|---|---|---|
qubit_map | dict[int, int] | Mapping from logical index to physical index. e.g., {0: 5, 1: 3} maps logical index 0 → physical qubit 5 |
Returns:
Hamiltonian — New Hamiltonian with remapped qubit indices.
single_pauli¶
@classmethod
def single_pauli(cls, pauli: Pauli, index: int, coeff: float | complex = 1.0) -> HamiltonianCreate a single Pauli term Hamiltonian.
to_latex¶
def to_latex(self) -> strConverts the Hamiltonian to a LaTeX representation.
This function does not add constant term when we show the Hamiltonian. This function does not add $ symbols.
Returns:
str —
A LaTeX representation of the Hamiltonian.
import qamomile.observable as qm_o
import IPython.display as ipd
h = qm_o.Hamiltonian()
h += -qm_o.X(0) * qm_o.Y(1) - 2.0 * qm_o.Z(0) * qm_o.Z(1)
# Show the Hamiltonian in LaTeX at Jupyter Notebook
ipd.display(ipd.Latex("$" + h.to_latex() + "$"))to_numpy¶
def to_numpy(self) -> np.ndarrayConvert the Hamiltonian to a dense NumPy matrix.
Qubit 0 is mapped to the least-significant bit of computational-basis
indices, matching :meth:qamomile.linalg.HermitianMatrix.to_hamiltonian.
The returned array has shape (2**n, 2**n) where n is
:attr:num_qubits.
zero¶
@classmethod
def zero(cls, num_qubits: int | None = None) -> HamiltonianCreate a zero Hamiltonian.
IfOperation [source]¶
class IfOperation(HasNestedOps, Operation)Represents an if-else conditional operation.
Example:
if condition:
true_body
else:
false_bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
true_operations: list[Operation] = list(),
false_operations: list[Operation] = list(),
true_yields: list[Value] = list(),
false_yields: list[Value] = list(),
branch_rebinds: tuple[BranchRebind, ...] = (),
true_captures: tuple[ValueBase, ...] = (),
false_captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
branch_rebinds: tuple[BranchRebind, ...]condition: Valuefalse_captures: tuple[ValueBase, ...]false_operations: list[Operation]false_yields: list[Value]operation_kind: OperationKindsignature: Signaturetrue_captures: tuple[ValueBase, ...]true_operations: list[Operation]true_yields: list[Value]
Methods¶
add_merge¶
def add_merge(self, true_value: Value, false_value: Value, result: Value) -> NoneAppend a branch-merge slot to this if-else.
The only sanctioned construction path for merges: it keeps the
yield lists and results index-aligned so iter_merges can
rely on the invariants it checks.
Parameters:
| Name | Type | Description |
|---|---|---|
true_value | Value | Value selected when the condition is true. |
false_value | Value | Value selected when the condition is false. Must have the same type as true_value. |
result | Value | Fresh SSA value representing the merged output. Must have the same type as the branch values. |
Raises:
RuntimeError— If the condition operand has not been attached to this operation yet (operands[0]must exist before merges are added), or the branch / result types do not match.
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include branch-yield values and rebind records for cloning/substitution.
The yields are subclass-specific Value fields (not operands —
see the class docstring), so generic passes reach them through
this override, mirroring ForItemsOperation.key_var_values.
Branch rebind records follow the loop operations’ rationale: the
recorded pre-branch values reference program values by identity,
so inline cloning must remap them in lockstep with operands.
Read-based checks must not treat the records as reads (see
_op_read_uuids in the analyze pass module).
Returns:
list[ValueBase] — list[ValueBase]: Base input values plus the true/false
yields and rebind-record values.
iter_merges¶
def iter_merges(self) -> Iterator[IfMerge]Iterate the branch-merge slots of this if-else.
This is the single read API for merge semantics: passes must consume merges through it (never through the yield lists directly) so the underlying storage can change without touching consumers.
Yields:
IfMerge — One entry per merged output, in result order.
Raises:
RuntimeError— If the stored merge data is internally inconsistent (the yield-list lengths differ from the result count, or the condition operand is missing while merges are attached). This indicates IR corruption, not a user error. The per-merge corruption modes of the old embedded-operation storage (a foreign entry, a malformed or mismatched condition, a result copy diverging fromresults[i]) cannot be represented in the yield-list storage and need no checks.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]Return the two branch bodies (merge yields are not operations).
Returns:
list[list[Operation]] — list[list[Operation]]: [true_operations, false_operations].
The branch-merge yields are values, not operations, so
they are intentionally absent here.
nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the true and false branch interfaces.
Returns:
tuple[Region, ...] — tuple[Region, ...]: True and false regions in that order, with
branch-local captures and merge yields.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> OperationReturn a copy with the true and false branch bodies replaced.
Parameters:
| Name | Type | Description |
|---|---|---|
new_lists | list[list[Operation]] | The replacement branch bodies in nested_op_lists order ([true_operations, false_operations]). |
Returns:
Operation — A copy of this if-else with the branch bodies
swapped and all other fields (yields, rebinds) preserved.
rebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild both branches and their complete boundary interfaces.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | True and false replacement regions. |
Returns:
Operation — Rebuilt conditional operation.
Raises:
ValueError— If region count, block arguments, or yield signatures are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationSubstitute operand, result, branch-yield, and rebind-record values.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | dict[str, ValueBase] | UUID-keyed substitution map. |
Returns:
Operation — The rewritten operation.
LoopCarriedRebind [source]¶
class LoopCarriedRebindTrace-time record of a variable rebound inside a loop body.
Two rebind families share this record type, distinguished by the
type of before:
Classical scalar (
beforeclassical): the frontend traces a loop body exactly once, so a Python-level reassignment liketotal = total + iproduces IR whose right-hand side reads the fixed pre-loop value instead of the previous iteration’s value. Most such carries are now represented as explicitRegionArgs (see above) and are fully supported; a classical record is only created for the shapes region binding declines —while-body carries (a runtime while loop cannot be unrolled) and measurement-backedBitcarries — and the transpiler’s classical loop-carried check rejects those with a targeted error instead of silently miscompiling.Quantum (
beforequantum): the loop body left the variable bound to a different quantum resource (logical_idchange — a fresh allocation or another register, not a gate self-update). The transpiler’s control-flow discard check (reject_control_flow_quantum_discard) rejects the ones whose incoming state the body never consumes.
Constructor¶
def __init__(
self,
var_name: str,
before: ValueBase,
after: ValueBase,
before_synthesized: bool = False,
) -> NoneAttributes¶
after: ValueBasebefore: ValueBasebefore_synthesized: boolvar_name: str
NotOp [source]¶
class NotOp(Operation)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
input: Valueoperation_kind: OperationKindoutput: Valuesignature: Signature
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) -> NonePauliEvolveOp [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()) -> NoneAttributes¶
evolved_qubits: Value The evolved quantum register result.gamma: Value The evolution time parameter.observable: Value The Observable parameter operand.operation_kind: OperationKind PauliEvolveOp is QUANTUM - transforms quantum state.qubits: Value The quantum register operand.signature: Signature
QFixedMetadata [source]¶
class QFixedMetadataMetadata for QFixed carriers.
Constructor¶
def __init__(self, qubit_uuids: tuple[str, ...], num_bits: int, int_bits: int) -> NoneAttributes¶
int_bits: intnum_bits: intqubit_uuids: tuple[str, ...]
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,
) -> NoneAttributes¶
fractional_bits: int | Value[UIntType]integer_bits: int | Value[UIntType]
Methods¶
label¶
def label(self) -> strQInitOperation [source]¶
class QInitOperation(Operation)Initialize the qubit
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
QUIntType [source]¶
class QUIntType(QuantumTypeMixin, ValueType)Quantum unsigned integer type.
Represents a quantum register encoding an unsigned integer value using binary encoding (little-endian by default).
Constructor¶
def __init__(self, width: int | Value[UIntType]) -> NoneAttributes¶
width: int | Value[UIntType]
Methods¶
label¶
def label(self) -> strQubitType [source]¶
class QubitType(QuantumTypeMixin, ValueType)Type representing a quantum bit (qubit).
RegionArg [source]¶
class RegionArgExplicit loop-carried value on a loop operation (MLIR-style iter_arg).
A RegionArg makes a loop-carried dependency explicit in the IR,
the way MLIR’s scf.for models iter_args / scf.yield:
On iteration 0 the body reads
block_argbound toinit.After each iteration,
block_argis rebound to that iteration’syieldedvalue.After the loop,
resultholds the final carried value (initwhen the loop ran zero iterations).
The loop body’s operations reference block_arg (the frontend
substitutes the traced pre-loop reads), and post-loop operations
reference result (the frontend rebinds the Python handle when it
closes the loop). result is also appended to the loop operation’s
results list so dependency analysis sees the loop as its
producer.
This subsumes the trace-once staleness that LoopCarriedRebind
records exist to reject: a rebind represented as a RegionArg is
a supported loop-carried value, not a miscompilation hazard.
Constructor¶
def __init__(
self,
var_name: str,
init: Value,
block_arg: Value,
yielded: Value,
result: Value,
) -> NoneAttributes¶
block_arg: Valueinit: Valueresult: Valuevar_name: stryielded: Value
ReleaseSliceViewOperation [source]¶
class ReleaseSliceViewOperation(Operation)Mark a slice view’s borrow as explicitly returned to its parent.
Emitted by :meth:Vector.__setitem__ when used with a slice index
(qs[a:b] = qmc.h(qs[a:b])). This op tells the post-fold
linearity checker
(:class:~qamomile.circuit.transpiler.passes.slice_borrow_check.SliceBorrowCheckPass)
that the view referenced in operands[0] no longer owns its
covered parent slots, mirroring the frontend’s
VectorView.consume(operation_name="slice assignment") borrow
release.
Like :class:SliceArrayOperation, this op is a declarative
classical-side marker that does not survive into the emit stream:
:class:~qamomile.circuit.transpiler.passes.strip_slice_ops.StripSliceArrayOpsPass
removes both :class:SliceArrayOperation and
:class:ReleaseSliceViewOperation after
:class:SliceBorrowCheckPass has observed them. Reaching emit
is a compiler-internal invariant violation and is rejected with a
RuntimeError from :mod:standard_emit.
Within a control-flow body (ForOperation / WhileOperation
/ IfOperation), this op only releases view borrows that were
created within the same body. Releasing a borrow that the
enclosing block has registered (an “outer-snapshot” borrow) is
rejected by SliceBorrowCheckPass with ValidationError — the
loop-merge semantics of the
pass cannot propagate entry deletions out of the body, so the only
way to keep the static check consistent is to forbid that pattern.
Example:
``qs[1:3] = qmc.h(qs[1:3])`` emits, after the broadcast loop::
ReleaseSliceViewOperation(
operands=[qmc_h_result_view], # slice_of=qs_value
results=[],
)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKind Release is classical — it updates borrow tracking metadata only.signature: Signature Return the type signature of this release operation.
ReturnQuantumArrayElementOperation [source]¶
class ReturnQuantumArrayElementOperation(Operation)Validate a branch-selected quantum element’s array return at emit time.
Most quantum element assignments are verified structurally by the frontend and emit no IR. A compile-time conditional can instead select different element indices on its branches; only the unrolled emit context knows which source index survived. This operation carries both the requested target indices and the conditional source indices so emission can prove they resolve to the same physical slot before treating the assignment as a borrow return.
Operand convention:
[array, returned_qubit, *target_indices, *source_indices]. The
target and source halves have equal nonzero arity, inferred from the
operand count. The operation has no results and emits no backend gate.
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
array: ArrayValue Return the quantum array receiving the borrowed element.index_arity: int Return the number of target (and source) index operands.operation_kind: OperationKind Classify the return validator as a quantum operation.returned_value: Value Return the quantum value being returned.signature: Signature Return the deferred validator’s operand-only signature.source_indices: tuple[Value, ...] Return the branch-merged borrow-source indices.target_indices: tuple[Value, ...] Return the user-written assignment indices.
RuntimeClassicalExpr [source]¶
class RuntimeClassicalExpr(Operation)A classical expression known to require runtime evaluation.
Lowered from CompOp / CondOp / NotOp / BinOp by
ClassicalLoweringPass when the op’s operand dataflow traces back
to a MeasureOperation (i.e. cannot be folded at compile-time, by
emit-time loop unrolling, or by compile_time_if_lowering). Backend
emit translates this 1:1 to a backend-native runtime expression
(e.g. qiskit.circuit.classical.expr.Expr).
Operand convention:
Binary kinds (EQ/NEQ/LT/LE/GT/GE/AND/OR/ADD/SUB/MUL/DIV/FLOORDIV/MOD/POW):
operands = [lhs, rhs].Unary kind (NOT):
operands = [val].Ternary kind (SELECT):
operands = [condition, true_value, false_value]— the runtime form of a branch merge (result = true_value if condition else false_value).Result:
results = [output_value].
The single-node + unified-kind shape (vs four parallel subclasses)
keeps the backend dispatch a single match op.kind instead of four
parallel hooks, and makes the IR self-documenting: a single
RuntimeClassicalExpr instance signals “runtime evaluation
required” regardless of which classical family it came from.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
kind: RuntimeOpKind | None = None,
) -> NoneAttributes¶
kind: RuntimeOpKind | Noneoperation_kind: OperationKindsignature: Signature
ScalarMetadata [source]¶
class ScalarMetadataMetadata for scalar constants and symbolic parameters.
Constructor¶
def __init__(
self,
const_value: int | float | bool | None = None,
parameter_name: str | None = None,
) -> NoneAttributes¶
const_value: int | float | bool | Noneparameter_name: str | None
Signature [source]¶
class SignatureConstructor¶
def __init__(
self,
operands: list[ParamHint | None] = list(),
results: list[ParamHint] = list(),
) -> NoneAttributes¶
operands: list[ParamHint | None]results: list[ParamHint]
SliceArrayOperation [source]¶
class SliceArrayOperation(Operation)Construct a strided view of an ArrayValue.
The op itself performs no quantum action — it records that the
result ArrayValue is a strided view of the operand parent
with the given start / step. The result’s
slice_of / slice_start / slice_step fields carry the
affine map used by the emit-time resolver.
SliceArrayOperation is classified as :attr:OperationKind.CLASSICAL
because slicing is pure index selection — no new quantum operation
is introduced. The pipeline keeps this op through
PartialEvaluationPass (which invokes
ConstantFoldingPass(..., strip_slice_ops=False)) so the
post-fold :class:~qamomile.circuit.transpiler.passes.slice_borrow_check.SliceBorrowCheckPass
can use it as a view-declaration marker; once that check has run,
StripSliceArrayOpsPass removes every SliceArrayOperation
/ ReleaseSliceViewOperation so segmentation
(:mod:~qamomile.circuit.transpiler.passes.separate) and the
downstream emit stage only see a pure quantum-op stream. By the
time :mod:~qamomile.circuit.transpiler.passes.separate runs the
op has therefore been stripped — reaching emit is a compiler-
internal invariant violation.
Example:
``q[1::2]`` on a ``Vector[Qubit]`` emits::
SliceArrayOperation(
operands=[q_value, uint_1, uint_2],
results=[sliced_value], # slice_of=q_value, slice_start=uint_1, slice_step=uint_2
)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKind Slice is classical — it selects indices without quantum action.signature: Signature Return the type signature of this slice operation.
StoreArrayElementOperation [source]¶
class StoreArrayElementOperation(Operation)Store a classical scalar into one element of a classical array.
This is the IR form of array[index] = value for classical element
types (Bit / UInt / Float). Classical values are freely
copyable, so the store is an ordinary SSA rewrite: the operation
consumes the current array version and produces a new ArrayValue
version (same logical_id, fresh uuid) whose contents equal the
input array with the addressed element replaced. Quantum arrays never
use this operation — qubit element assignment is the return half of
the borrow-return idiom and emits no IR.
The operation is evaluated in one of two places:
Compile time:
ConstantFoldingPassfolds the store when the source array contents, the index, and the stored value are all compile-time resolvable, attaching the updatedconst_arraymetadata to the result value.Runtime: otherwise the store executes host-side in a classical segment via
ClassicalExecutor(e.g. for measurement-derivedVector[Bit]contents). It must never reach a quantum segment; backend emit rejects it explicitly.
Operand convention:
operands: [array (ArrayValue), stored_value (Value), *index_values]
results: [new_array (ArrayValue)]
Example:
@qmc.qkernel
def k() -> qmc.Vector[qmc.Bit]:
qs = qmc.qubit_array(2, "qs")
qs[0] = qmc.x(qs[0])
bits = qmc.measure(qs)
bits[1] = bits[0] # emits StoreArrayElementOperation
return bitsConstructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
array: ArrayValue ArrayValue: The array version the store reads from.index_values: tuple[Value, ...] tuple[Value, ...]: The element indices being written.operation_kind: OperationKindsignature: Signature Return the operation’s dynamic array/qubit/index signature.stored_value: Value Value: The scalar being written into the array.
SymbolicControlledU [source]¶
class SymbolicControlledU(ControlledUOperation)Controlled-U with symbolic (Value) number of controls.
Operand layout: [ctrl_arg_0, ..., ctrl_arg_{k-1}, tgt_0, ..., tgt_m, params...]
Result layout: [ctrl_arg_0', ..., ctrl_arg_{k-1}', tgt_0', ..., tgt_m']
The number of control arguments k is recorded in
num_control_args; the default k = 1 corresponds to the
historical single-pool form (operands[0] is a
Vector[Qubit] / VectorView whose length equals
num_controls, or whose control_indices-selected subset
does). When k > 1 the control prefix is a heterogeneous
sequence of scalar Qubit values and ArrayValues whose
total qubit count is num_controls; the emit pass walks them
in order to recover the per-physical-qubit control set.
When control_indices is None the entire control prefix
is used as active controls (one-arg form: len(ctrl_vector) == num_controls; multi-arg form: the qubit-count sum of the
prefix args equals num_controls). When non-None, the
listed indices select exactly num_controls slots from a
single-arg pool to act as controls; combining
control_indices with the multi-arg control prefix is
rejected at frontend time.
Each control_indices entry is stored as a Value of
UIntType regardless of whether the frontend passed an
int literal or a UInt handle, so all downstream
value-substitution passes see a uniform shape.
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=(UIntType()), name=''))(),
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] = dict(),
control_indices: tuple[Value, ...] | None = None,
num_control_args: int = 1,
) -> NoneAttributes¶
control_indices: tuple[Value, ...] | Nonecontrol_operands: list[Value]is_symbolic_num_controls: boolnum_control_args: intnum_controls: Valueparam_operands: list[Value] Get classical/object operands after the symbolic control prefix.signature: Signaturetarget_operands: list[Value] Return the wrapped callable’s target and parameter operands.
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationTupleType [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, ...]) -> NoneAttributes¶
element_types: tuple[ValueType, ...]
Methods¶
is_classical¶
def is_classical(self) -> boolis_quantum¶
def is_quantum(self) -> boollabel¶
def label(self) -> strTupleValue [source]¶
class TupleValue(_MetadataValueMixin, ValueBase)A tuple of IR values for structured data.
Constructor¶
def __init__(
self,
name: str,
elements: tuple[ValueLike, ...] = tuple(),
metadata: ValueMetadata = ValueMetadata(),
uuid: str = (lambda: str(uuid.uuid4()))(),
logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> NoneAttributes¶
elements: tuple[ValueLike, ...]logical_id: strmetadata: ValueMetadataname: strtype: ‘TupleType’uuid: str
Methods¶
is_constant¶
def is_constant(self) -> boolnext_version¶
def next_version(self) -> TupleValueUIntType [source]¶
class UIntType(ClassicalTypeMixin, ValueType)Type representing an unsigned integer.
UnaryMathOp [source]¶
class UnaryMathOp(Operation)Represent one pure unary mathematical expression.
Parameters:
| Name | Type | Description |
|---|---|---|
operands | list[Value] | Single numeric input value. |
results | list[Value] | Single numeric result value. |
kind | UnaryMathOpKind | None | Mathematical operation to apply. |
Raises:
ValueError— Ifkindis missing or the operation does not have exactly one operand and one result.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
kind: UnaryMathOpKind | None = None,
) -> NoneAttributes¶
input: Value Return the input value.kind: UnaryMathOpKind | Noneoperation_kind: OperationKind Classify the operation as classical.output: Value Return the output value.signature: Signature Return the typed unary signature.
Value [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.
ValueBase [source]¶
class ValueBaseNominal base for every typed IR value.
Runtime compiler passes inspect values in their innermost loops. A nominal base keeps those checks constant-time; a runtime-checkable protocol would repeatedly scan the protocol members on Python versions that do not cache structural checks.
Attributes¶
logical_id: strmetadata: ValueMetadataname: strtype: ValueType Return the static IR type carried by this value.uuid: str
Methods¶
get_const¶
def get_const(self) -> int | float | bool | NoneReturn the scalar constant carried by this value.
Returns:
int | float | bool | None — int | float | bool | None: Constant value, or None when the
value is not constant.
is_constant¶
def is_constant(self) -> boolReturn whether this value carries a scalar constant.
Returns:
bool — Whether scalar constant metadata is present.
is_parameter¶
def is_parameter(self) -> boolReturn whether this value represents a runtime parameter.
Returns:
bool — Whether parameter metadata is present.
next_version¶
def next_version(self) -> ValueBaseCreate the next SSA version of this value.
Returns:
ValueBase — A value with a fresh version UUID and preserved logical
identity.
parameter_name¶
def parameter_name(self) -> str | NoneReturn the public parameter name carried by this value.
Returns:
str | None — str | None: Parameter name, or None for a non-parameter value.
ValueMetadata [source]¶
class ValueMetadataTyped metadata owned by the compiler/runtime.
Constructor¶
def __init__(
self,
scalar: ScalarMetadata | None = None,
cast: CastMetadata | None = None,
qfixed: QFixedMetadata | None = None,
array_runtime: ArrayRuntimeMetadata | None = None,
dict_runtime: DictRuntimeMetadata | None = None,
) -> NoneAttributes¶
array_runtime: ArrayRuntimeMetadata | Nonecast: CastMetadata | Nonedict_runtime: DictRuntimeMetadata | Noneqfixed: QFixedMetadata | Nonescalar: ScalarMetadata | None
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) -> boolis_object¶
def is_object(self) -> boolis_quantum¶
def is_quantum(self) -> boollabel¶
def label(self) -> strWhileOperation [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,
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_args: tuple[RegionArg, ...] = (),
captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
captures: tuple[ValueBase, ...]loop_carried_rebinds: tuple[LoopCarriedRebind, ...]max_iterations: int | Noneoperation_kind: OperationKindoperations: list[Operation]region_args: tuple[RegionArg, ...]signature: Signature
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include rebind records and region args for cloning/substitution.
Same rationale as ForOperation.all_input_values: rebind
records and region arguments reference body/pre-loop values by
identity, so inline cloning must remap them in lockstep with
body operands.
Returns:
list[ValueBase] — list[ValueBase]: Base input values plus rebind-record and
region-argument values.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the while body with explicit boundary values.
Returns:
tuple[Region, ...] — tuple[Region, ...]: One body region whose block arguments and
yields are aligned with region_args. The updated
condition, when present, is appended as the final yield.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operationrebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild the while body and its complete boundary interface.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Exactly one replacement body region. |
Returns:
Operation — Rebuilt while operation.
Raises:
ValueError— If arity or boundary value kinds are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationSubstitute operand, rebind-record, and region-arg values.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | dict[str, ValueBase] | UUID-keyed substitution map. |
Returns:
Operation — The rewritten operation.
qamomile.circuit.ir.serialize.hamiltonian_io¶
Build validated Hamiltonian records for the protobuf payload union.
ParamSlot.bound_value and ArrayRuntimeMetadata.const_array may
carry :class:qamomile.observable.Hamiltonian objects — the bound
values of Observable kernel parameters (e.g. the documented Trotter
pattern kernel.build(Hs=[1.2 * Z(0), 0.8 * X(0)], ...)). This
module defines the tagged-dict wire representation for those payloads:
a sum of Pauli products plus a constant offset and the declared qubit
register width.
The protobuf bridge converts this semantic record into a typed Hamiltonian
message with ordered terms and exact numeric variants.
Two fidelity properties are load-bearing:
Term order is preserved.
Hamiltonian’s term dict iteration order is observable throughreprand__iter__, so a faithful round-trip must not reorder terms. The encoder emits terms in iteration order and the decoder re-adds them in wire order. (content_hashis deliberately order-independent: canonical bytes sort the term tokens, matchingHamiltonian.__eq__'s dict-based term comparison — seecanonical._hamiltonian_token.)Coefficient types are preserved.
repr(1.2)differs fromrepr((1.2+0j)), so int / float coefficients are written as plain numbers while complex ones get an explicit$complexsub-wrapper.
Security: decoding never resolves classes dynamically. Pauli names are
mapped through an explicit allow-map, and only Pauli /
PauliOperator / Hamiltonian instances are constructed.
Overview¶
| Function | Description |
|---|---|
dict_to_hamiltonian | Decode a wrapper dict back into a Hamiltonian. |
hamiltonian_to_dict | Encode a Hamiltonian into the wrapper dict. |
is_hamiltonian_wrapper | Return True if d is a Hamiltonian wrapper dict. |
is_plain_int | Return True if value is a Python int but not a bool. |
| Class | Description |
|---|---|
Hamiltonian | Represents a quantum Hamiltonian as a sum of Pauli operator products. |
Pauli | Enum class for Pauli operators. |
PauliOperator | Represents a single Pauli operator acting on a specific qubit. |
Functions¶
dict_to_hamiltonian [source]¶
def dict_to_hamiltonian(d: dict[str, Any]) -> HamiltonianDecode a wrapper dict back into a Hamiltonian.
Terms are re-added in wire order through the public add_term
API, which is the identity on the canonical term form the encoder
emits (operators sorted per term, no identities) and preserves the
term-dict insertion order.
Parameters:
| Name | Type | Description |
|---|---|---|
d | dict[str, Any] | A wrapper dict previously produced by :func:hamiltonian_to_dict after protobuf decoding. |
Returns:
Hamiltonian — The reconstructed Hamiltonian, equal to the
original (same terms in the same order, same coefficient
types, same constant, same declared register width).
Raises:
ValueError— Ifdis not a valid wrapper dict — missing or malformedterms, a term with an empty operator list (the constant is carried by the dedicatedconstantfield, so an empty list would double-encode it), a Pauli name outside the allow-map, a negative or non-int qubit index, a malformed coefficient, or anum_qubitsthat is neitherNonenor a non-negative int.
hamiltonian_to_dict [source]¶
def hamiltonian_to_dict(h: Hamiltonian) -> dict[str, Any]Encode a Hamiltonian into the wrapper dict.
Terms are emitted in the Hamiltonian’s own term-dict iteration
order; each term is a [operators, coefficient] pair where
operators is a list of [pauli_name, qubit_index] entries.
Parameters:
| Name | Type | Description |
|---|---|---|
h | Hamiltonian | The Hamiltonian to encode. Term coefficients and the constant must be int, float, or complex, or a numpy scalar of one of those kinds (coerced via .item()). |
Returns:
dict[str, Any] — dict[str, Any]: A wrapper dict with $hamiltonian,
terms, constant, and num_qubits (the declared
register width passed to the constructor, or None).
Raises:
TypeError— Ifhis not aHamiltonian, if a coefficient / the constant is not int, float, or complex, or if the declarednum_qubitsis not an int — all after coercing anynumpyscalar to its Python equivalent.ValueError— If the declarednum_qubitsis negative.
is_hamiltonian_wrapper [source]¶
def is_hamiltonian_wrapper(d: Any) -> boolReturn True if d is a Hamiltonian wrapper dict.
Parameters:
| Name | Type | Description |
|---|---|---|
d | Any | A value to check. Typically the result of a recursive dict walk from decode. |
Returns:
bool — True when d is a dict carrying the
$hamiltonian tag with a True value.
is_plain_int [source]¶
def is_plain_int(value: object) -> boolReturn True if value is a Python int but not a bool.
bool is a subclass of int in Python, so isinstance(True, int)
is True. This helper distinguishes a genuine integer from a boolean,
which matters wherever a boolean must be rejected in an integer slot — for
example, validating decoded wire data or a register width.
Parameters:
| Name | Type | Description |
|---|---|---|
value | object | The value to test. |
Returns:
bool — True when value is an int and not a bool.
Classes¶
Hamiltonian [source]¶
class HamiltonianRepresents a quantum Hamiltonian as a sum of Pauli operator products.
The Hamiltonian is stored as a dictionary where keys are tuples of PauliOperators and values are their corresponding coefficients.
Example:
>>> H = Hamiltonian()
>>> H.add_term((PauliOperator(Pauli.X, 0), PauliOperator(Pauli.Y, 1)), 0.5)
>>> H.add_term((PauliOperator(Pauli.Z, 2),), 1.0)
>>> print(H.terms)
{(X0, Y1): 0.5, (Z2,): 1.0}Constructor¶
def __init__(self, num_qubits: int | None = None) -> NoneAttributes¶
constant: float | complexnum_qubits: int Calculates the number of qubits in the Hamiltonian.terms: dict[tuple[PauliOperator, ...], complex] Getter for the terms of the Hamiltonian.
Methods¶
add_term¶
def add_term(self, operators: tuple[PauliOperator, ...], coeff: float | complex)Adds a term to the Hamiltonian.
This method adds a product of Pauli operators with a given coefficient to the Hamiltonian. If the term already exists, the coefficients are summed.
Parameters:
| Name | Type | Description |
|---|---|---|
operators | Tuple[PauliOperator, ...] | A tuple of PauliOperators representing the term. |
coeff | Union[float, complex] | The coefficient of the term. |
Example:
>>> H = Hamiltonian()
>>> H.add_term((PauliOperator(Pauli.X, 0), PauliOperator(Pauli.Y, 1)), 0.5)
>>> H.add_term((PauliOperator(Pauli.X, 0), PauliOperator(Pauli.Y, 1)), 0.5j)
>>> print(H.terms)
{(X0, Y1): (0.5+0.5j)}copy¶
def copy(self) -> HamiltonianReturn an independent copy sharing no mutable state with self.
Produces a new Hamiltonian with the same terms, constant,
and declared _num_qubits. The underlying _terms dict
is fresh, so subsequent add_term / constant mutations
on either instance do not affect the other. PauliOperator
instances inside the term tuples are reused — they are
dataclass(frozen=True) values and safely shared.
Returns:
Hamiltonian — A shallow-cloned Hamiltonian instance.
Example:
>>> H = Hamiltonian()
>>> H.add_term((PauliOperator(Pauli.Z, 0),), 1.0)
>>> H2 = H.copy()
>>> H2.add_term((PauliOperator(Pauli.X, 1),), 0.5)
>>> H.num_qubits # unchanged by H2's mutation
1identity¶
@classmethod
def identity(
cls,
coeff: float | complex = 1.0,
num_qubits: int | None = None,
) -> HamiltonianCreate a scalar times identity Hamiltonian.
remap_qubits¶
def remap_qubits(self, qubit_map: dict[int, int]) -> HamiltonianRemap qubit indices according to the given mapping.
This is used to translate Pauli indices (logical indices within an expval call) to physical qubit indices in the actual quantum circuit.
Parameters:
| Name | Type | Description |
|---|---|---|
qubit_map | dict[int, int] | Mapping from logical index to physical index. e.g., {0: 5, 1: 3} maps logical index 0 → physical qubit 5 |
Returns:
Hamiltonian — New Hamiltonian with remapped qubit indices.
single_pauli¶
@classmethod
def single_pauli(cls, pauli: Pauli, index: int, coeff: float | complex = 1.0) -> HamiltonianCreate a single Pauli term Hamiltonian.
to_latex¶
def to_latex(self) -> strConverts the Hamiltonian to a LaTeX representation.
This function does not add constant term when we show the Hamiltonian. This function does not add $ symbols.
Returns:
str —
A LaTeX representation of the Hamiltonian.
import qamomile.observable as qm_o
import IPython.display as ipd
h = qm_o.Hamiltonian()
h += -qm_o.X(0) * qm_o.Y(1) - 2.0 * qm_o.Z(0) * qm_o.Z(1)
# Show the Hamiltonian in LaTeX at Jupyter Notebook
ipd.display(ipd.Latex("$" + h.to_latex() + "$"))to_numpy¶
def to_numpy(self) -> np.ndarrayConvert the Hamiltonian to a dense NumPy matrix.
Qubit 0 is mapped to the least-significant bit of computational-basis
indices, matching :meth:qamomile.linalg.HermitianMatrix.to_hamiltonian.
The returned array has shape (2**n, 2**n) where n is
:attr:num_qubits.
zero¶
@classmethod
def zero(cls, num_qubits: int | None = None) -> HamiltonianCreate a zero Hamiltonian.
Pauli [source]¶
class Pauli(enum.Enum)Enum class for Pauli operators.
Attributes¶
IXYZ
PauliOperator [source]¶
class PauliOperatorRepresents a single Pauli operator acting on a specific qubit.
Frozen so that Hamiltonian.copy() can share term operator
references across the original and the copy without risk of one
side mutating an operator the other still observes. None of the
existing callers mutate pauli or index after construction,
so freezing is a no-op behaviourally but makes the immutability
claim that Hamiltonian.copy()'s docstring relies on real.
Example:
>>> X0 = PauliOperator(Pauli.X, 0)
>>> print(X0)
X0Constructor¶
def __init__(self, pauli: Pauli, index: int) -> NoneAttributes¶
index: intpauli: Pauli
qamomile.circuit.ir.serialize.numpy_io¶
Build validated NumPy records for the protobuf payload union.
The semantic encoder uses tagged intermediate records before the protobuf
bridge materializes NumpyValue messages. Arrays carry shape plus raw bytes;
scalars carry their dtype plus one exact item’s bytes.
Allowed dtypes are restricted to an explicit allow-list. The decoder
rejects any dtype string outside the list, so a malicious payload
cannot coax numpy into instantiating an unexpected dtype object.
Overview¶
| Function | Description |
|---|---|
array_to_dict | Encode a numpy ndarray into the wrapper dict. |
dict_to_array | Decode a wrapper dict back into a numpy ndarray. |
dict_to_scalar | Decode an exact NumPy scalar wrapper. |
is_array_wrapper | Return True if d is a numpy-array wrapper dict. |
is_plain_int | Return True if value is a Python int but not a bool. |
is_scalar_wrapper | Return whether d is a NumPy-scalar wrapper dict. |
scalar_to_dict | Encode an allow-listed NumPy scalar without widening its dtype. |
Functions¶
array_to_dict [source]¶
def array_to_dict(arr: np.ndarray) -> dict[str, Any]Encode a numpy ndarray into the wrapper dict.
Parameters:
| Name | Type | Description |
|---|---|---|
arr | np.ndarray | Source array with an allow-listed primitive dtype. |
Returns:
dict[str, Any] — dict[str, Any]: A wrapper dict with $np_array, dtype,
shape (list[int]), and data (raw bytes from
ndarray.tobytes()). The wire encoders are responsible
for any further bytes ⇄ text conversion at format
boundaries.
Raises:
TypeError— Ifarris not anumpy.ndarray.ValueError— If the array’s dtype is not in the allow-list.
dict_to_array [source]¶
def dict_to_array(d: dict[str, Any]) -> np.ndarrayDecode a wrapper dict back into a numpy ndarray.
Parameters:
| Name | Type | Description |
|---|---|---|
d | dict[str, Any] | A wrapper dict previously produced by :func:array_to_dict after protobuf decoding. |
Returns:
np.ndarray — np.ndarray: The reconstructed array with the original dtype
and shape.
Raises:
ValueError— Ifdis not a valid wrapper dict, if the dtype is not in the allow-list, or if the byte length is inconsistent with shape × dtype.itemsize.
dict_to_scalar [source]¶
def dict_to_scalar(d: dict[str, Any]) -> np.genericDecode an exact NumPy scalar wrapper.
Parameters:
| Name | Type | Description |
|---|---|---|
d | dict[str, Any] | Wrapper produced by :func:scalar_to_dict. |
Returns:
np.generic — np.generic: Scalar with the original dtype and bit representation.
Raises:
ValueError— If the wrapper, dtype, or byte length is malformed.
is_array_wrapper [source]¶
def is_array_wrapper(d: Any) -> boolReturn True if d is a numpy-array wrapper dict.
Parameters:
| Name | Type | Description |
|---|---|---|
d | Any | A value to check. Typically the result of a recursive dict walk from decode. |
Returns:
bool — True when d is a dict carrying the
$np_array tag with a True-ish value.
is_plain_int [source]¶
def is_plain_int(value: object) -> boolReturn True if value is a Python int but not a bool.
bool is a subclass of int in Python, so isinstance(True, int)
is True. This helper distinguishes a genuine integer from a boolean,
which matters wherever a boolean must be rejected in an integer slot — for
example, validating decoded wire data or a register width.
Parameters:
| Name | Type | Description |
|---|---|---|
value | object | The value to test. |
Returns:
bool — True when value is an int and not a bool.
is_scalar_wrapper [source]¶
def is_scalar_wrapper(d: Any) -> boolReturn whether d is a NumPy-scalar wrapper dict.
Parameters:
| Name | Type | Description |
|---|---|---|
d | Any | Candidate wire payload. |
Returns:
bool — Whether d carries the exact scalar wrapper tag.
scalar_to_dict [source]¶
def scalar_to_dict(value: np.generic) -> dict[str, Any]Encode an allow-listed NumPy scalar without widening its dtype.
Parameters:
| Name | Type | Description |
|---|---|---|
value | np.generic | NumPy scalar whose dtype and exact bytes must be preserved. |
Returns:
dict[str, Any] — dict[str, Any]: Tagged scalar wrapper containing dtype and raw bytes.
Raises:
TypeError— Ifvalueis not a NumPy scalar.ValueError— If its dtype is outside the portable allow-list.
qamomile.circuit.ir.static_binding¶
Describe compile-time object dependencies of hierarchical qkernels.
Overview¶
| Class | Description |
|---|---|
StaticBindingField | Reference one scalar field projected from a static binding. |
StaticBindingSlot | Declare one typed compile-time object required by a qkernel. |
Value | A typed SSA value in the IR. |
Classes¶
StaticBindingField [source]¶
class StaticBindingFieldReference one scalar field projected from a static binding.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | Registered field name on the bound object. |
value | Value | Symbolic scalar used by the hierarchical IR until the binding is materialized. |
Constructor¶
def __init__(self, name: str, value: Value) -> NoneAttributes¶
name: strvalue: Value
StaticBindingSlot [source]¶
class StaticBindingSlotDeclare one typed compile-time object required by a qkernel.
The object itself is not an SSA value and never reaches a backend. Only registered scalar projections and deferred callable-member references may appear in the hierarchical body. A build must resolve the slot before the block advances to a compiler stage.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | QKernel argument name used by bindings. |
type_key | str | Stable key of the registered static-binding adapter. |
fields | tuple[StaticBindingField, ...] | Scalar projections referenced while tracing the unbound qkernel. |
Constructor¶
def __init__(
self,
name: str,
type_key: str,
fields: tuple[StaticBindingField, ...] = (),
) -> NoneAttributes¶
fields: tuple[StaticBindingField, ...]name: strtype_key: str
Value [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.ir.types¶
qamomile.circuit.ir.types module.
qamomile.circuit.ir.types is most fundamental module defining types used in Qamomile IR.
Overview¶
| Class | Description |
|---|---|
BitType | Type representing a classical bit. |
DictType | Type representing a dictionary mapping keys to values. |
FloatType | Type representing a floating-point number. |
ObservableType | Type representing a Hamiltonian observable parameter. |
QFixedType | Quantum fixed-point type. |
QUIntType | Quantum unsigned integer type. |
QubitType | Type representing a quantum bit (qubit). |
TupleType | Type representing a tuple of values. |
UIntType | Type representing an unsigned integer. |
ValueType | Base class for all value types in the IR. |
Classes¶
BitType [source]¶
class BitType(ClassicalTypeMixin, ValueType)Type representing a classical bit.
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,
) -> NoneAttributes¶
key_type: ValueType | Nonevalue_type: ValueType | None
Methods¶
is_classical¶
def is_classical(self) -> boolis_quantum¶
def is_quantum(self) -> boollabel¶
def label(self) -> strFloatType [source]¶
class FloatType(ClassicalTypeMixin, ValueType)Type representing a floating-point number.
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) -> NoneQFixedType [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,
) -> NoneAttributes¶
fractional_bits: int | Value[UIntType]integer_bits: int | Value[UIntType]
Methods¶
label¶
def label(self) -> strQUIntType [source]¶
class QUIntType(QuantumTypeMixin, ValueType)Quantum unsigned integer type.
Represents a quantum register encoding an unsigned integer value using binary encoding (little-endian by default).
Constructor¶
def __init__(self, width: int | Value[UIntType]) -> NoneAttributes¶
width: int | Value[UIntType]
Methods¶
label¶
def label(self) -> strQubitType [source]¶
class QubitType(QuantumTypeMixin, ValueType)Type representing a quantum bit (qubit).
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, ...]) -> NoneAttributes¶
element_types: tuple[ValueType, ...]
Methods¶
is_classical¶
def is_classical(self) -> boolis_quantum¶
def is_quantum(self) -> boollabel¶
def label(self) -> strUIntType [source]¶
class UIntType(ClassicalTypeMixin, ValueType)Type representing an unsigned integer.
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) -> boolis_object¶
def is_object(self) -> boolis_quantum¶
def is_quantum(self) -> boollabel¶
def label(self) -> strqamomile.circuit.ir.types.hamiltonian¶
Observable type for Hamiltonian parameter representation.
This module defines the ObservableType for the Qamomile IR, which represents a reference to a Hamiltonian observable provided via bindings during transpilation.
Unlike the previous HamiltonianExprType, this is purely a reference type - the actual qamomile.observable.Hamiltonian is provided from Python code.
Overview¶
| Class | Description |
|---|---|
ObjectTypeMixin | |
ObservableType | Type representing a Hamiltonian observable parameter. |
ValueType | Base class for all value types in the IR. |
Classes¶
ObjectTypeMixin [source]¶
class ObjectTypeMixinMethods¶
is_object¶
def is_object(self) -> boolObservableType [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) -> NoneValueType [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) -> boolis_object¶
def is_object(self) -> boolis_quantum¶
def is_quantum(self) -> boollabel¶
def label(self) -> strqamomile.circuit.ir.types.primitives¶
Overview¶
| Class | Description |
|---|---|
BitType | Type representing a classical bit. |
BlockType | Type representing a block/function reference. |
ClassicalTypeMixin | |
DictType | Type representing a dictionary mapping keys to values. |
FloatType | Type representing a floating-point number. |
ObjectTypeMixin | |
QuantumTypeMixin | |
QubitType | Type representing a quantum bit (qubit). |
TupleType | Type representing a tuple of values. |
UIntType | Type representing an unsigned integer. |
ValueType | Base class for all value types in the IR. |
Classes¶
BitType [source]¶
class BitType(ClassicalTypeMixin, ValueType)Type representing a classical bit.
BlockType [source]¶
class BlockType(ObjectTypeMixin, ValueType)Type representing a block/function reference.
ClassicalTypeMixin [source]¶
class ClassicalTypeMixinMethods¶
is_classical¶
def is_classical(self) -> boolDictType [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,
) -> NoneAttributes¶
key_type: ValueType | Nonevalue_type: ValueType | None
Methods¶
is_classical¶
def is_classical(self) -> boolis_quantum¶
def is_quantum(self) -> boollabel¶
def label(self) -> strFloatType [source]¶
class FloatType(ClassicalTypeMixin, ValueType)Type representing a floating-point number.
ObjectTypeMixin [source]¶
class ObjectTypeMixinMethods¶
is_object¶
def is_object(self) -> boolQuantumTypeMixin [source]¶
class QuantumTypeMixinMethods¶
is_quantum¶
def is_quantum(self) -> boolQubitType [source]¶
class QubitType(QuantumTypeMixin, ValueType)Type representing a quantum bit (qubit).
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, ...]) -> NoneAttributes¶
element_types: tuple[ValueType, ...]
Methods¶
is_classical¶
def is_classical(self) -> boolis_quantum¶
def is_quantum(self) -> boollabel¶
def label(self) -> strUIntType [source]¶
class UIntType(ClassicalTypeMixin, ValueType)Type representing an unsigned integer.
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) -> boolis_object¶
def is_object(self) -> boolis_quantum¶
def is_quantum(self) -> boollabel¶
def label(self) -> strqamomile.circuit.ir.types.q_register¶
Overview¶
| Class | Description |
|---|---|
QFixedType | Quantum fixed-point type. |
QUIntType | Quantum unsigned integer type. |
QuantumTypeMixin | |
UIntType | Type representing an unsigned integer. |
Value | A typed SSA value in the IR. |
ValueType | Base class for all value types in the IR. |
Classes¶
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,
) -> NoneAttributes¶
fractional_bits: int | Value[UIntType]integer_bits: int | Value[UIntType]
Methods¶
label¶
def label(self) -> strQUIntType [source]¶
class QUIntType(QuantumTypeMixin, ValueType)Quantum unsigned integer type.
Represents a quantum register encoding an unsigned integer value using binary encoding (little-endian by default).
Constructor¶
def __init__(self, width: int | Value[UIntType]) -> NoneAttributes¶
width: int | Value[UIntType]
Methods¶
label¶
def label(self) -> strQuantumTypeMixin [source]¶
class QuantumTypeMixinMethods¶
is_quantum¶
def is_quantum(self) -> boolUIntType [source]¶
class UIntType(ClassicalTypeMixin, ValueType)Type representing an unsigned integer.
Value [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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) -> boolis_object¶
def is_object(self) -> boolis_quantum¶
def is_quantum(self) -> boollabel¶
def label(self) -> strqamomile.circuit.ir.uuid_remapper¶
Clone IR values and blocks into a fresh identity namespace.
Overview¶
| Function | Description |
|---|---|
collect_value_like_uuids | Collect UUIDs contained in a value-like IR object. |
remap_indexed_identifier | Remap an identifier while preserving a legacy index suffix. |
remap_value_metadata_references | Rewrite UUID and logical-id references inside value metadata. |
| Class | Description |
|---|---|
ArrayValue | An array of typed IR values. |
Block | Unified block representation for all pipeline stages. |
CastOperation | Type cast operation for creating aliases over the same quantum resources. |
ControlledUOperation | Base class for controlled-U operations. |
DictValue | A dictionary value stored as stable ordered entries. |
ForItemsOperation | Represents iteration over dict/iterable items. |
ForOperation | Represents a for loop operation. |
HasNestedOps | Mixin for operations that contain nested operation lists. |
InverseBlockOperation | Represent an inverse qkernel/block as a first-class IR operation. |
SelectOperation | Quantum multiplexer: apply case_blocks[i] when the index reads i. |
TupleValue | A tuple of IR values for structured data. |
UUIDRemapper | Clones values and operations with fresh UUIDs and logical_ids. |
Value | A typed SSA value in the IR. |
ValueBase | Nominal base for every typed IR value. |
ValueMetadata | Typed metadata owned by the compiler/runtime. |
Constants¶
ValueLike:TypeAlias='Value | ArrayValue | TupleValue | DictValue'
Functions¶
collect_value_like_uuids [source]¶
def collect_value_like_uuids(value: 'ValueLike') -> set[str]Collect UUIDs contained in a value-like IR object.
Parameters:
| Name | Type | Description |
|---|---|---|
value | ValueLike | Value-like object to inspect. |
Returns:
set[str] — set[str]: UUIDs for value itself, recursively contained tuple/dict
elements, and array view/element dependencies.
remap_indexed_identifier [source]¶
def remap_indexed_identifier(identifier: str, remap_identifier: Callable[[str], str]) -> strRemap an identifier while preserving a legacy index suffix.
Parameters:
| Name | Type | Description |
|---|---|---|
identifier | str | Scalar identifier or legacy "<base>_<index>" carrier key. |
remap_identifier | typing.Callable[[str], str] | Function that remaps scalar identifiers and carrier-key bases. |
Returns:
str — Remapped identifier. Numeric index suffixes are preserved after
remapping the base identifier.
remap_value_metadata_references [source]¶
def remap_value_metadata_references(
metadata: ValueMetadata,
remap_uuid: Callable[[str], str],
remap_logical_id: Callable[[str], str],
) -> ValueMetadataRewrite UUID and logical-id references inside value metadata.
Parameters:
| Name | Type | Description |
|---|---|---|
metadata | ValueMetadata | Metadata bundle whose embedded references should be rewritten. |
remap_uuid | typing.Callable[[str], str] | Function that maps scalar UUID references (and carrier-key bases) to replacement UUIDs. |
remap_logical_id | typing.Callable[[str], str] | Function that maps scalar logical-id references (and carrier-key bases) to replacement logical IDs. |
Returns:
ValueMetadata — Metadata with every embedded UUID / logical-id reference
rewritten. Legacy "<uuid>_<index>" carrier keys keep their
index suffix while remapping the base UUID. The original bundle is
returned unchanged when no reference is rewritten.
Classes¶
ArrayValue [source]¶
class ArrayValue(Value[T])An array of typed IR values.
When slice_of is set, this array is a strided view over another
array. Element accesses on a sliced ArrayValue resolve to
physical slots on the root parent via the affine map
parent_index = slice_start + slice_step * view_local_index,
applied recursively along slice_of chains. The emit-time
resolver walks this chain to produce the final qubit index; passes
that substitute or clone values must treat slice_of /
slice_start / slice_step as Value references that need to
track through the same mapping as parent_array.
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(),
slice_of: 'ArrayValue | None' = None,
slice_start: 'Value | None' = None,
slice_step: 'Value | None' = None,
) -> NoneAttributes¶
logical_id: strmetadata: ValueMetadataname: strshape: tuple[Value, ...]slice_of: ‘ArrayValue | None’slice_start: ‘Value | None’slice_step: ‘Value | None’type: Tuuid: str
Methods¶
is_slice¶
def is_slice(self) -> boolReturn True if this array is a strided view of another array.
Returns:
bool — True iff slice_of is non-None.
next_version¶
def next_version(self) -> ArrayValue[T]Block [source]¶
class BlockUnified 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[ValueLike] = list(),
output_values: list[ValueLike] = list(),
output_names: list[str] = list(),
operations: list['Operation'] = list(),
kind: BlockKind = BlockKind.HIERARCHICAL,
parameters: dict[str, Value] = dict(),
param_slots: tuple[ParamSlot, ...] = tuple(),
static_bindings: tuple[StaticBindingSlot, ...] = tuple(),
) -> NoneAttributes¶
effects: ‘KernelEffect’ Return lazily cached semantic effects for this block.input_values: list[ValueLike]kind: BlockKindlabel_args: list[str]measurement_result_indices: frozenset[int] Return public output positions derived from measurement.name: stroperations: list[‘Operation’]output_names: list[str]output_values: list[ValueLike]param_slots: tuple[ParamSlot, ...]parameters: dict[str, Value]static_bindings: tuple[StaticBindingSlot, ...]
Methods¶
call¶
def call(self, **kwargs: ValueLike = {}) -> 'InvokeOperation'Create an inline callable invocation against this block.
Parameters:
| Name | Type | Description |
|---|---|---|
**kwargs | ValueLike | Actual argument values keyed by self.label_args. |
Returns:
'InvokeOperation' — Inline-policy invocation whose callable
definition points at this block.
Raises:
KeyError— If a required label inself.label_argsis missing fromkwargs.
is_affine¶
def is_affine(self) -> boolReturn whether this block has passed affine validation.
Returns:
bool — True for AFFINE and ANALYZED blocks.
unbound_parameters¶
def unbound_parameters(self) -> list[str]Return list of unbound parameter names.
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:
Vector[Qubit] -> QFixed (after QPE, for phase measurement)
Vector[Qubit] -> QUInt (for quantum arithmetic)
QUInt -> QFixed (reinterpret bits with different encoding)
QFixed -> QUInt (reinterpret bits with different encoding)
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(),
) -> NoneAttributes¶
num_qubits: int Number of qubits involved in the cast.operation_kind: OperationKind Cast stays in the same segment as its source (QUANTUM for quantum types).qubit_mapping: list[str]signature: Signature Return the type signature of this cast operation.source_type: ValueType | Nonetarget_type: ValueType | None
ControlledUOperation [source]¶
class ControlledUOperation(Operation)Base class for controlled-U operations.
Two concrete subclasses handle distinct operand layouts:
ConcreteControlledU: Fixednum_controls: int, individual qubit operands.SymbolicControlledU: Symbolicnum_controls: Value, vector-based control operands; optionalcontrol_indicesselects a subset of the control vector to act as controls (the rest pass through).
All isinstance(op, ControlledUOperation) checks match every subclass.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
power: int | Value = 1,
block: Block | None = None,
num_controls: int | Value = 1,
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] = dict(),
) -> NoneAttributes¶
block: Block | Nonebody_operands: list[Value] Get the wrapped callable’s complete argument list.callable_attrs: dict[str, Any]callable_ref: CallableRef | Nonecontrol_operands: list[Value] Get the control qubit values.is_symbolic_num_controls: bool Whether num_controls is symbolic (Value) rather than concrete.num_controls: int | Valueoperation_kind: OperationKindparam_operands: list[Value] Get the controlled operation’s classical/object arguments.power: int | Valuesignature: Signaturetarget_operands: list[Value] Get the target qubit values (arguments to U).
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationDictValue [source]¶
class DictValue(_MetadataValueMixin, ValueBase)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()))(),
) -> NoneAttributes¶
entries: tuple[tuple[TupleValue | Value, Value], ...]logical_id: strmetadata: ValueMetadataname: strtype: DictTypeuuid: str
Methods¶
is_constant¶
def is_constant(self) -> boolnext_version¶
def next_version(self) -> DictValueForItemsOperation [source]¶
class ForItemsOperation(HasNestedOps, Operation)Represents iteration over dict/iterable items.
Example:
for (i, j), Jij in qmc.items(ising):
bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
key_vars: list[str] = list(),
value_var: str = '',
key_is_vector: bool = False,
key_var_values: tuple[Value, ...] | None = None,
value_var_value: Value | None = None,
operations: list[Operation] = list(),
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_args: tuple[RegionArg, ...] = (),
captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
captures: tuple[ValueBase, ...]key_is_vector: boolkey_var_values: tuple[Value, ...] | Nonekey_vars: list[str]loop_carried_rebinds: tuple[LoopCarriedRebind, ...]operation_kind: OperationKindoperations: list[Operation]region_args: tuple[RegionArg, ...]signature: Signaturevalue_var: strvalue_var_value: Value | None
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include the per-key/value Value fields for cloning/substitution.
Same rationale as ForOperation.all_input_values: keep the IR
identity fields in lockstep with body references so UUID-keyed
lookups stay valid after inline cloning. Loop-carried rebind
records and region arguments are included for the same reason.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the items-loop body with its explicit interface.
Returns:
tuple[Region, ...] — tuple[Region, ...]: One body region containing key/value formals,
carried-value formals, captures, and carried yields.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operationrebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild the items-loop body and complete boundary interface.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Exactly one replacement body region. |
Returns:
Operation — Rebuilt items-loop operation.
Raises:
ValueError— If arity or boundary value kinds are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationForOperation [source]¶
class ForOperation(HasNestedOps, Operation)Represents a for loop operation.
Example:
for i in range(start, stop, step):
bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
loop_var: str = '',
loop_var_value: Value | None = None,
operations: list[Operation] = list(),
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_args: tuple[RegionArg, ...] = (),
captures: tuple[ValueBase, ...] = (),
) -> NoneAttributes¶
captures: tuple[ValueBase, ...]loop_carried_rebinds: tuple[LoopCarriedRebind, ...]loop_var: strloop_var_value: Value | Noneoperation_kind: OperationKindoperations: list[Operation]region_args: tuple[RegionArg, ...]signature: Signature
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Include loop_var_value so cloning/substitution stays consistent.
Without this override, UUIDRemapper would clone every body
reference to the loop variable to a fresh UUID, but leave
loop_var_value pointing at the un-cloned original — emit-time
UUID-keyed lookups for the loop variable would then miss.
Loop-carried rebind records and region arguments are included
for the same reason.
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return the range-loop body with its explicit interface.
Returns:
tuple[Region, ...] — tuple[Region, ...]: One body region containing the induction
value, carried-value formals, captures, and carried yields.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> Operationrebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationRebuild the range-loop body and complete boundary interface.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Exactly one replacement body region. |
Returns:
Operation — Rebuilt range-loop operation.
Raises:
ValueError— If arity or boundary value kinds are inconsistent.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationHasNestedOps [source]¶
class HasNestedOpsMixin for operations that contain nested operation lists.
nested_regions() is the canonical traversal API because it exposes
operations together with block arguments, captures, and yields.
nested_op_lists() / rebuild_nested() remain compatibility helpers
for specialized consumers while they migrate to the region interface.
Methods¶
nested_op_lists¶
def nested_op_lists(self) -> list[list[Operation]]Return all nested operation lists in this control flow op.
nested_regions¶
def nested_regions(self) -> tuple[Region, ...]Return uniform views of every nested operation region.
Subclasses with explicit block arguments, captures, or yields override
this method. The fallback keeps legacy operation-owned blocks visible
while consumers migrate from nested_op_lists.
Returns:
tuple[Region, ...] — tuple[Region, ...]: Region views in nested_op_lists order.
rebuild_nested¶
def rebuild_nested(self, new_lists: list[list[Operation]]) -> OperationReturn a copy with nested operation lists replaced.
new_lists must have the same length/order as nested_op_lists().
rebuild_regions¶
def rebuild_regions(self, regions: Sequence[Region]) -> OperationReturn a copy with replacement region operation sequences.
Concrete control-flow operations override this method to rebuild both their body operations and boundary values. The fallback supports legacy region owners whose boundary remains operation-specific.
Parameters:
| Name | Type | Description |
|---|---|---|
regions | Sequence[Region] | Replacement regions in nested_regions order. |
Returns:
Operation — Rebuilt control-flow operation.
Raises:
ValueError— If the replacement region count differs from the operation’s current region count.
InverseBlockOperation [source]¶
class InverseBlockOperation(Operation)Represent an inverse qkernel/block as a first-class IR operation.
The operation stores both the original forward block and a Qamomile-built
inverse implementation block. Emitters may use source_block with a
backend-native inverse/adjoint primitive, then fall back to
implementation_block when native inversion is unavailable.
Operands are ordered as scalar control qubits, target quantum operands,
then classical/object parameters. Results mirror the quantum operand
layout: control results first, then one target result per target operand.
Vector target operands therefore count as one operand/result while
contributing their scalar width to num_target_qubits.
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_control_qubits: int = 0,
num_target_qubits: int = 0,
custom_name: str = '',
source_block: Block | None = None,
implementation_block: Block | None = None,
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] = dict(),
control_value: int | None = None,
) -> NoneAttributes¶
callable_attrs: dict[str, Any]callable_ref: CallableRef | Nonecontrol_qubits: list[‘Value’] Return control quantum operands.control_value: int | Nonecustom_name: strimplementation_block: Block | Nonename: str Return a human-readable inverse operation name.num_control_qubits: intnum_target_qubits: intoperation_kind: OperationKind Return the operation kind.parameters: list[‘Value’] Return classical/object parameter operands.signature: Signature Return the operation signature.source_block: Block | Nonetarget_qubits: list[‘Value’] Return target quantum operands.
SelectOperation [source]¶
class SelectOperation(Operation)Quantum multiplexer: apply case_blocks[i] when the index reads i.
Concrete operand layout:
[idx_0, ..., idx_{k-1}, tgt_0, ..., tgt_m, params...].
Symbolic-width operand layout:
[idx_arg_0, ..., idx_arg_{a-1}, tgt_0, ..., tgt_m, params...].
Results mirror the quantum operand grouping.
A concrete index register is normalized to one scalar Qubit operand
per physical index qubit. A symbolic-width register instead retains each
leading caller argument as one scalar or array operand until its bound
shape is known. Whole-Vector[Qubit] / scalar targets follow and keep
their shapes, and classical parameters shared across every case come last.
Index bit order is LSB-first: idx_0 is the least-significant
bit, matching Qamomile’s qubit-zero convention. Case i is selected
when index qubit j reads bit j of i. len(case_blocks)
need not be a power of two; index values >= len(case_blocks) apply
no operation (identity).
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_index_qubits: int | Value = 0,
case_blocks: list[Block] = list(),
num_index_args: int = 0,
case_callable_attrs: list[dict[str, Any]] = list(),
) -> NoneAttributes¶
case_blocks: list[Block]case_callable_attrs: list[dict[str, Any]]index_operands: list[Value] Return the grouped index-prefix operands.is_symbolic_num_index_qubits: bool Return whether the index width is a symbolic IR value.num_cases: int Return the number of selectable cases.num_index_args: intnum_index_qubits: int | Valueoperation_kind: OperationKind Return the operation kind.param_operands: list[Value] Return the shared classical parameter operands.signature: Signature Return the operation signature.target_operands: list[Value] Return the quantum target operands applied by every case.
Methods¶
all_input_values¶
def all_input_values(self) -> list[ValueBase]Return every value consumed by the SELECT operation.
Returns:
list[ValueBase] — list[ValueBase]: Ordinary operands plus the symbolic index-width
value when present.
replace_values¶
def replace_values(self, mapping: dict[str, ValueBase]) -> OperationReplace operand and symbolic-width values by UUID.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | dict[str, ValueBase] | UUID-keyed replacement values. |
Returns:
Operation — Rebuilt SELECT operation with matching values replaced.
TupleValue [source]¶
class TupleValue(_MetadataValueMixin, ValueBase)A tuple of IR values for structured data.
Constructor¶
def __init__(
self,
name: str,
elements: tuple[ValueLike, ...] = tuple(),
metadata: ValueMetadata = ValueMetadata(),
uuid: str = (lambda: str(uuid.uuid4()))(),
logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> NoneAttributes¶
elements: tuple[ValueLike, ...]logical_id: strmetadata: ValueMetadataname: strtype: ‘TupleType’uuid: str
Methods¶
is_constant¶
def is_constant(self) -> boolnext_version¶
def next_version(self) -> TupleValueUUIDRemapper [source]¶
class UUIDRemapperClones values and operations with fresh UUIDs and logical_ids.
Used during inlining to create unique identities for values when a block is called multiple times.
Constructor¶
def __init__(self)Initialize empty identity, value, and block remapping caches.
Attributes¶
logical_id_remap: dict[str, str] Get the mapping from old logical IDs to new logical IDs.uuid_remap: dict[str, str] Get the mapping from old UUIDs to new UUIDs.
Methods¶
clone_block¶
def clone_block(self, block: Block) -> BlockClone an executable block namespace with fresh value identities.
Callable definitions and inverse source blocks are semantic provenance shared with the original graph. Transform implementations, controlled bodies, and SELECT cases are executable children and are cloned recursively.
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | Block whose interface, operations, and executable owned blocks should be cloned. |
Returns:
Block — Structurally equivalent block whose values have fresh UUIDs
and logical IDs.
Raises:
ValueError— If the owned block graph is recursive.
clone_operation¶
def clone_operation(self, op: Operation) -> OperationClone an operation with fresh UUIDs for all values.
Cloning goes through the Operation.all_input_values() /
Operation.replace_values() protocol so every Value-typed
field — including subclass extras (ControlledUOperation.power,
ForOperation.loop_var_value, ForItemsOperation.key_var_values
etc.) — is cloned consistently with the body references that
point to it. Without this, a subclass field could keep an old
UUID while body operands referencing the same logical Value got
fresh UUIDs, breaking identity-by-UUID lookups at emit time.
Parameters:
| Name | Type | Description |
|---|---|---|
op | Operation | Operation to clone. |
Returns:
Operation — A clone of op with every owned Value (operands,
results, subclass-extra fields) and every nested-body Value
reassigned a fresh UUID / logical_id, and with
CastOperation.qubit_mapping carrier keys remapped.
clone_operations¶
def clone_operations(self, operations: list[Operation]) -> list[Operation]Clone a list of operations with fresh UUIDs.
Parameters:
| Name | Type | Description |
|---|---|---|
operations | list[Operation] | Operations to clone in order. |
Returns:
list[Operation] — list[Operation]: Cloned operations, each with fresh UUIDs, in the
same order as operations.
clone_value¶
def clone_value(self, value: ValueBase) -> ValueBaseClone any value type with a fresh UUID and logical_id.
Handles Value, ArrayValue, TupleValue, and DictValue through
the unified ValueBase protocol. Nested values (tuple elements, dict
entries, parent_array / element_indices / shape / slice
fields) and embedded metadata references are cloned consistently.
Results are cached by source UUID so a repeated clone returns the
same instance.
Parameters:
| Name | Type | Description |
|---|---|---|
value | ValueBase | The value to clone. |
Returns:
ValueBase — The cloned value of the same concrete type, with a
fresh UUID / logical_id and its nested values and metadata
references remapped through this remapper.
Value [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.
ValueBase [source]¶
class ValueBaseNominal base for every typed IR value.
Runtime compiler passes inspect values in their innermost loops. A nominal base keeps those checks constant-time; a runtime-checkable protocol would repeatedly scan the protocol members on Python versions that do not cache structural checks.
Attributes¶
logical_id: strmetadata: ValueMetadataname: strtype: ValueType Return the static IR type carried by this value.uuid: str
Methods¶
get_const¶
def get_const(self) -> int | float | bool | NoneReturn the scalar constant carried by this value.
Returns:
int | float | bool | None — int | float | bool | None: Constant value, or None when the
value is not constant.
is_constant¶
def is_constant(self) -> boolReturn whether this value carries a scalar constant.
Returns:
bool — Whether scalar constant metadata is present.
is_parameter¶
def is_parameter(self) -> boolReturn whether this value represents a runtime parameter.
Returns:
bool — Whether parameter metadata is present.
next_version¶
def next_version(self) -> ValueBaseCreate the next SSA version of this value.
Returns:
ValueBase — A value with a fresh version UUID and preserved logical
identity.
parameter_name¶
def parameter_name(self) -> str | NoneReturn the public parameter name carried by this value.
Returns:
str | None — str | None: Parameter name, or None for a non-parameter value.
ValueMetadata [source]¶
class ValueMetadataTyped metadata owned by the compiler/runtime.
Constructor¶
def __init__(
self,
scalar: ScalarMetadata | None = None,
cast: CastMetadata | None = None,
qfixed: QFixedMetadata | None = None,
array_runtime: ArrayRuntimeMetadata | None = None,
dict_runtime: DictRuntimeMetadata | None = None,
) -> NoneAttributes¶
array_runtime: ArrayRuntimeMetadata | Nonecast: CastMetadata | Nonedict_runtime: DictRuntimeMetadata | Noneqfixed: QFixedMetadata | Nonescalar: ScalarMetadata | None
qamomile.circuit.ir.value¶
Value types and typed metadata for the Qamomile IR.
Overview¶
| Function | Description |
|---|---|
array_physical_region | Resolve a one-dimensional array to its ordered physical region. |
array_static_length | Resolve a one-dimensional array’s compile-time length. |
arrays_share_physical_region | Return whether two arrays denote the same ordered physical region. |
collect_value_like_uuids | Collect UUIDs contained in a value-like IR object. |
remap_indexed_identifier | Remap an identifier while preserving a legacy index suffix. |
remap_value_metadata_references | Rewrite UUID and logical-id references inside value metadata. |
resolve_root_array_index | Fold a view-local element index into the root array’s index space. |
resolve_root_qubit_address | Resolve an array-element value to its root (array_uuid, index). |
resolve_root_qubit_array | Return the root array that owns one quantum scalar value. |
split_indexed_identifier | Split a legacy indexed identifier into base and index suffix. |
static_quantum_width | Return a quantum value’s compile-time scalar-qubit width. |
| Class | Description |
|---|---|
ArrayRuntimeMetadata | Metadata for array literals and explicit element identity tracking. |
ArrayValue | An array of typed IR values. |
CastMetadata | Metadata describing a cast carrier and its underlying qubits. |
DictRuntimeMetadata | Metadata for transpile-time bound dict values. |
DictValue | A dictionary value stored as stable ordered entries. |
QFixedMetadata | Metadata for QFixed carriers. |
ScalarMetadata | Metadata for scalar constants and symbolic parameters. |
TupleType | Type representing a tuple of values. |
TupleValue | A tuple of IR values for structured data. |
Value | A typed SSA value in the IR. |
ValueBase | Nominal base for every typed IR value. |
ValueMetadata | Typed metadata owned by the compiler/runtime. |
Constants¶
ValueLike:TypeAlias='Value | ArrayValue | TupleValue | DictValue'
Functions¶
array_physical_region [source]¶
def array_physical_region(array: 'ArrayValue') -> tuple[str, tuple[int, ...]] | NoneResolve a one-dimensional array to its ordered physical region.
The region is expressed independently of SSA version UUIDs: the first
element is the root array’s logical_id and the second is the ordered
tuple of root-space indices addressed by the array. This makes a root
register and its full view compare equal while keeping partial, strided,
reordered, and different-root registers distinct.
Parameters:
| Name | Type | Description |
|---|---|---|
array | ArrayValue | Root array or nested sliced view to resolve. The array must be one-dimensional and have a compile-time integer length; every slice bound in its ancestry must also be constant. |
Returns:
tuple[str, tuple[int, ...]] | None — tuple[str, tuple[int, ...]] | None: (root_logical_id, indices)
when the complete ordered coverage is statically known, otherwise
None. Symbolic shapes or slice bounds remain unresolved so
callers can defer to emit-time physical mappings.
array_static_length [source]¶
def array_static_length(array: 'ArrayValue') -> int | NoneResolve a one-dimensional array’s compile-time length.
Parameters:
| Name | Type | Description |
|---|---|---|
array | ArrayValue | Array whose sole shape dimension is inspected. |
Returns:
int | None — int | None: Non-negative static length, or None when the array is not
one-dimensional, its length is symbolic/non-integral, or it is
malformed with a negative length. Boolean constants are rejected
even though bool is an int subclass.
arrays_share_physical_region [source]¶
def arrays_share_physical_region(left: 'ArrayValue', right: 'ArrayValue') -> boolReturn whether two arrays denote the same ordered physical region.
Parameters:
| Name | Type | Description |
|---|---|---|
left | ArrayValue | First root array or sliced view. |
right | ArrayValue | Second root array or sliced view. |
Returns:
bool — True for the same SSA value/version lineage, when both arrays
resolve to the same root logical identity and ordered root indices,
or when both resolve to empty regions (whose root is unobservable).
Returns False for non-empty divergent regions and unresolved
symbolic coverage.
collect_value_like_uuids [source]¶
def collect_value_like_uuids(value: 'ValueLike') -> set[str]Collect UUIDs contained in a value-like IR object.
Parameters:
| Name | Type | Description |
|---|---|---|
value | ValueLike | Value-like object to inspect. |
Returns:
set[str] — set[str]: UUIDs for value itself, recursively contained tuple/dict
elements, and array view/element dependencies.
remap_indexed_identifier [source]¶
def remap_indexed_identifier(identifier: str, remap_identifier: Callable[[str], str]) -> strRemap an identifier while preserving a legacy index suffix.
Parameters:
| Name | Type | Description |
|---|---|---|
identifier | str | Scalar identifier or legacy "<base>_<index>" carrier key. |
remap_identifier | typing.Callable[[str], str] | Function that remaps scalar identifiers and carrier-key bases. |
Returns:
str — Remapped identifier. Numeric index suffixes are preserved after
remapping the base identifier.
remap_value_metadata_references [source]¶
def remap_value_metadata_references(
metadata: ValueMetadata,
remap_uuid: Callable[[str], str],
remap_logical_id: Callable[[str], str],
) -> ValueMetadataRewrite UUID and logical-id references inside value metadata.
Parameters:
| Name | Type | Description |
|---|---|---|
metadata | ValueMetadata | Metadata bundle whose embedded references should be rewritten. |
remap_uuid | typing.Callable[[str], str] | Function that maps scalar UUID references (and carrier-key bases) to replacement UUIDs. |
remap_logical_id | typing.Callable[[str], str] | Function that maps scalar logical-id references (and carrier-key bases) to replacement logical IDs. |
Returns:
ValueMetadata — Metadata with every embedded UUID / logical-id reference
rewritten. Legacy "<uuid>_<index>" carrier keys keep their
index suffix while remapping the base UUID. The original bundle is
returned unchanged when no reference is rewritten.
resolve_root_array_index [source]¶
def resolve_root_array_index(array: 'ArrayValue', index: int) -> tuple['ArrayValue', int] | NoneFold a view-local element index into the root array’s index space.
Walks the slice_of chain root-ward, composing each strided view’s
affine map parent_index = start + step * local_index. This is the
array-level counterpart of :func:resolve_root_qubit_address (which
starts from an array-element Value); both must stay consistent with
the composite carrier keys "<root_uuid>_<root_index>" registered by
QInitOperation at emit time.
Parameters:
| Name | Type | Description |
|---|---|---|
array | ArrayValue | Array the index is local to. May be a root array (slice_of unset) or an arbitrarily nested strided view. |
index | int | Element index in array’s own index space. |
Returns:
tuple['ArrayValue', int] | None — tuple[ArrayValue, int] | None: (root_array, composed_index) when
every slice bound on the chain is compile-time constant and
satisfies the frontend contract (non-negative slice_start,
positive slice_step). None when any slice_start /
slice_step on the chain is missing, symbolic, or violates
that contract; callers must then defer resolution rather than
guess. Out-of-contract bounds would compose index onto a
wrong root slot, so they are refused here too (the frontend
rejects them at trace time; this guard covers programmatically
constructed IR).
resolve_root_qubit_address [source]¶
def resolve_root_qubit_address(value: 'Value') -> tuple[str, int] | NoneResolve an array-element value to its root (array_uuid, index).
Walks the parent_array / slice_of chain and composes the nested
affine slice maps, so view[i] resolves to
(root_uuid, start + step * i) for the composed (start, step). The
returned pair is the build-stable identity of the physical qubit slot: the
root array’s QInitOperation always registers it as
QubitAddress(root_uuid, index), so this address resolves even when the
element’s own (per-version) UUID was never registered.
The transpiler’s resource allocator uses the same walk to resolve gate and measurement operands; this shared helper keeps both call sites consistent.
Parameters:
| Name | Type | Description |
|---|---|---|
value | Value | The value to resolve. Expected to be an array element (parent_array set with a single constant element_indices entry). |
Returns:
tuple[str, int] | None — tuple[str, int] | None: (root_array_uuid, composed_index) when
value is an array element with a constant index whose entire
slice_of chain has constant slice_start / slice_step.
None when value is not an array element, when its index is
non-constant, or when any slice bound in the chain is non-constant
(those cases are deferred to the emit-time resolver, which has
bindings available). Also None for a negative constant index
or a chain frame with negative slice_start / non-positive
slice_step — composing those would silently address a wrong
root slot, so they are refused rather than guessed (the frontend
rejects them at trace time; this guard covers programmatically
constructed IR).
resolve_root_qubit_array [source]¶
def resolve_root_qubit_array(value: Value) -> ArrayValue | NoneReturn the root array that owns one quantum scalar value.
Unlike :func:resolve_root_qubit_address, this helper does not require a
concrete scalar index or concrete slice bounds. It is used when dependency
analysis can identify the allocation owner but must conservatively treat
the selected scalar as unresolved.
Parameters:
| Name | Type | Description |
|---|---|---|
value | Value | Candidate scalar quantum array element. |
Returns:
ArrayValue | None — ArrayValue | None: Root array reached through parent_array and
slice_of links, or None for an independent scalar.
split_indexed_identifier [source]¶
def split_indexed_identifier(identifier: str) -> tuple[str, str] | NoneSplit a legacy indexed identifier into base and index suffix.
Parameters:
| Name | Type | Description |
|---|---|---|
identifier | str | Identifier to inspect. Legacy carrier keys use the "<base>_<index>" spelling, where index is decimal. |
Returns:
tuple[str, str] | None — tuple[str, str] | None: (base, index) when identifier carries a
numeric suffix, otherwise None.
static_quantum_width [source]¶
def static_quantum_width(value: ValueBase) -> int | NoneReturn a quantum value’s compile-time scalar-qubit width.
The helper understands both ordinary qubit arrays and packed quantum register carriers. Runtime carrier metadata is preferred when present because it records the physical scalar values represented by a packed value even when its type-level width is symbolic.
Parameters:
| Name | Type | Description |
|---|---|---|
value | ValueBase | Quantum scalar, array, or packed register value. |
Returns:
int | None — int | None: Non-negative scalar-qubit width, or None when the
value is non-quantum or any required dimension remains symbolic.
Classes¶
ArrayRuntimeMetadata [source]¶
class ArrayRuntimeMetadataMetadata for array literals and explicit element identity tracking.
element_parent_uuids / element_parent_indices are parallel to
element_uuids: for each tracked element they record the root array’s
UUID and the element’s index within that root (as resolved by
:func:resolve_root_qubit_address at trace time). They let an emit pass map
a packed element back to the physical qubit registered under the root
array’s QubitAddress(root_uuid, index) key even when the element’s own
UUID was never registered. The sentinel ("", -1) marks an element with
no array parent (a standalone qubit), for which a flat UUID lookup is used.
(root_uuid, -1) preserves a known root owner when the scalar index is
symbolic and therefore cannot be resolved at trace time.
Constructor¶
def __init__(
self,
const_array: Any = None,
element_uuids: tuple[str, ...] = (),
element_logical_ids: tuple[str, ...] = (),
element_parent_uuids: tuple[str, ...] = (),
element_parent_indices: tuple[int, ...] = (),
) -> NoneAttributes¶
const_array: Anyelement_logical_ids: tuple[str, ...]element_parent_indices: tuple[int, ...]element_parent_uuids: tuple[str, ...]element_uuids: tuple[str, ...]
ArrayValue [source]¶
class ArrayValue(Value[T])An array of typed IR values.
When slice_of is set, this array is a strided view over another
array. Element accesses on a sliced ArrayValue resolve to
physical slots on the root parent via the affine map
parent_index = slice_start + slice_step * view_local_index,
applied recursively along slice_of chains. The emit-time
resolver walks this chain to produce the final qubit index; passes
that substitute or clone values must treat slice_of /
slice_start / slice_step as Value references that need to
track through the same mapping as parent_array.
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(),
slice_of: 'ArrayValue | None' = None,
slice_start: 'Value | None' = None,
slice_step: 'Value | None' = None,
) -> NoneAttributes¶
logical_id: strmetadata: ValueMetadataname: strshape: tuple[Value, ...]slice_of: ‘ArrayValue | None’slice_start: ‘Value | None’slice_step: ‘Value | None’type: Tuuid: str
Methods¶
is_slice¶
def is_slice(self) -> boolReturn True if this array is a strided view of another array.
Returns:
bool — True iff slice_of is non-None.
next_version¶
def next_version(self) -> ArrayValue[T]CastMetadata [source]¶
class CastMetadataMetadata describing a cast carrier and its underlying qubits.
Constructor¶
def __init__(
self,
source_uuid: str,
qubit_uuids: tuple[str, ...],
source_logical_id: str | None = None,
qubit_logical_ids: tuple[str, ...] = (),
) -> NoneAttributes¶
qubit_logical_ids: tuple[str, ...]qubit_uuids: tuple[str, ...]source_logical_id: str | Nonesource_uuid: str
DictRuntimeMetadata [source]¶
class DictRuntimeMetadataMetadata for transpile-time bound dict values.
Constructor¶
def __init__(self, bound_data: tuple[tuple[Any, Any], ...] = ()) -> NoneAttributes¶
bound_data: tuple[tuple[Any, Any], ...]
DictValue [source]¶
class DictValue(_MetadataValueMixin, ValueBase)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()))(),
) -> NoneAttributes¶
entries: tuple[tuple[TupleValue | Value, Value], ...]logical_id: strmetadata: ValueMetadataname: strtype: DictTypeuuid: str
Methods¶
is_constant¶
def is_constant(self) -> boolnext_version¶
def next_version(self) -> DictValueQFixedMetadata [source]¶
class QFixedMetadataMetadata for QFixed carriers.
Constructor¶
def __init__(self, qubit_uuids: tuple[str, ...], num_bits: int, int_bits: int) -> NoneAttributes¶
int_bits: intnum_bits: intqubit_uuids: tuple[str, ...]
ScalarMetadata [source]¶
class ScalarMetadataMetadata for scalar constants and symbolic parameters.
Constructor¶
def __init__(
self,
const_value: int | float | bool | None = None,
parameter_name: str | None = None,
) -> NoneAttributes¶
const_value: int | float | bool | Noneparameter_name: str | None
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, ...]) -> NoneAttributes¶
element_types: tuple[ValueType, ...]
Methods¶
is_classical¶
def is_classical(self) -> boolis_quantum¶
def is_quantum(self) -> boollabel¶
def label(self) -> strTupleValue [source]¶
class TupleValue(_MetadataValueMixin, ValueBase)A tuple of IR values for structured data.
Constructor¶
def __init__(
self,
name: str,
elements: tuple[ValueLike, ...] = tuple(),
metadata: ValueMetadata = ValueMetadata(),
uuid: str = (lambda: str(uuid.uuid4()))(),
logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> NoneAttributes¶
elements: tuple[ValueLike, ...]logical_id: strmetadata: ValueMetadataname: strtype: ‘TupleType’uuid: str
Methods¶
is_constant¶
def is_constant(self) -> boolnext_version¶
def next_version(self) -> TupleValueValue [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.
ValueBase [source]¶
class ValueBaseNominal base for every typed IR value.
Runtime compiler passes inspect values in their innermost loops. A nominal base keeps those checks constant-time; a runtime-checkable protocol would repeatedly scan the protocol members on Python versions that do not cache structural checks.
Attributes¶
logical_id: strmetadata: ValueMetadataname: strtype: ValueType Return the static IR type carried by this value.uuid: str
Methods¶
get_const¶
def get_const(self) -> int | float | bool | NoneReturn the scalar constant carried by this value.
Returns:
int | float | bool | None — int | float | bool | None: Constant value, or None when the
value is not constant.
is_constant¶
def is_constant(self) -> boolReturn whether this value carries a scalar constant.
Returns:
bool — Whether scalar constant metadata is present.
is_parameter¶
def is_parameter(self) -> boolReturn whether this value represents a runtime parameter.
Returns:
bool — Whether parameter metadata is present.
next_version¶
def next_version(self) -> ValueBaseCreate the next SSA version of this value.
Returns:
ValueBase — A value with a fresh version UUID and preserved logical
identity.
parameter_name¶
def parameter_name(self) -> str | NoneReturn the public parameter name carried by this value.
Returns:
str | None — str | None: Parameter name, or None for a non-parameter value.
ValueMetadata [source]¶
class ValueMetadataTyped metadata owned by the compiler/runtime.
Constructor¶
def __init__(
self,
scalar: ScalarMetadata | None = None,
cast: CastMetadata | None = None,
qfixed: QFixedMetadata | None = None,
array_runtime: ArrayRuntimeMetadata | None = None,
dict_runtime: DictRuntimeMetadata | None = None,
) -> NoneAttributes¶
array_runtime: ArrayRuntimeMetadata | Nonecast: CastMetadata | Nonedict_runtime: DictRuntimeMetadata | Noneqfixed: QFixedMetadata | Nonescalar: ScalarMetadata | None
qamomile.circuit.ir.value_mapping¶
Provide shared IR value substitution utilities.
Overview¶
| Function | Description |
|---|---|
resolve_root_array_index | Fold a view-local element index into the root array’s index space. |
resolve_root_qubit_address | Resolve an array-element value to its root (array_uuid, index). |
split_indexed_identifier | Split a legacy indexed identifier into base and index suffix. |
| Class | Description |
|---|---|
ArrayRuntimeMetadata | Metadata for array literals and explicit element identity tracking. |
ArrayValue | An array of typed IR values. |
CastMetadata | Metadata describing a cast carrier and its underlying qubits. |
CastOperation | Type cast operation for creating aliases over the same quantum resources. |
DictValue | A dictionary value stored as stable ordered entries. |
QFixedMetadata | Metadata for QFixed carriers. |
TupleValue | A tuple of IR values for structured data. |
Value | A typed SSA value in the IR. |
ValueBase | Nominal base for every typed IR value. |
ValueMetadata | Typed metadata owned by the compiler/runtime. |
ValueSubstitutor | Substitute IR values in operations using a UUID-keyed mapping. |
Constants¶
ValueLike:TypeAlias='Value | ArrayValue | TupleValue | DictValue'
Functions¶
resolve_root_array_index [source]¶
def resolve_root_array_index(array: 'ArrayValue', index: int) -> tuple['ArrayValue', int] | NoneFold a view-local element index into the root array’s index space.
Walks the slice_of chain root-ward, composing each strided view’s
affine map parent_index = start + step * local_index. This is the
array-level counterpart of :func:resolve_root_qubit_address (which
starts from an array-element Value); both must stay consistent with
the composite carrier keys "<root_uuid>_<root_index>" registered by
QInitOperation at emit time.
Parameters:
| Name | Type | Description |
|---|---|---|
array | ArrayValue | Array the index is local to. May be a root array (slice_of unset) or an arbitrarily nested strided view. |
index | int | Element index in array’s own index space. |
Returns:
tuple['ArrayValue', int] | None — tuple[ArrayValue, int] | None: (root_array, composed_index) when
every slice bound on the chain is compile-time constant and
satisfies the frontend contract (non-negative slice_start,
positive slice_step). None when any slice_start /
slice_step on the chain is missing, symbolic, or violates
that contract; callers must then defer resolution rather than
guess. Out-of-contract bounds would compose index onto a
wrong root slot, so they are refused here too (the frontend
rejects them at trace time; this guard covers programmatically
constructed IR).
resolve_root_qubit_address [source]¶
def resolve_root_qubit_address(value: 'Value') -> tuple[str, int] | NoneResolve an array-element value to its root (array_uuid, index).
Walks the parent_array / slice_of chain and composes the nested
affine slice maps, so view[i] resolves to
(root_uuid, start + step * i) for the composed (start, step). The
returned pair is the build-stable identity of the physical qubit slot: the
root array’s QInitOperation always registers it as
QubitAddress(root_uuid, index), so this address resolves even when the
element’s own (per-version) UUID was never registered.
The transpiler’s resource allocator uses the same walk to resolve gate and measurement operands; this shared helper keeps both call sites consistent.
Parameters:
| Name | Type | Description |
|---|---|---|
value | Value | The value to resolve. Expected to be an array element (parent_array set with a single constant element_indices entry). |
Returns:
tuple[str, int] | None — tuple[str, int] | None: (root_array_uuid, composed_index) when
value is an array element with a constant index whose entire
slice_of chain has constant slice_start / slice_step.
None when value is not an array element, when its index is
non-constant, or when any slice bound in the chain is non-constant
(those cases are deferred to the emit-time resolver, which has
bindings available). Also None for a negative constant index
or a chain frame with negative slice_start / non-positive
slice_step — composing those would silently address a wrong
root slot, so they are refused rather than guessed (the frontend
rejects them at trace time; this guard covers programmatically
constructed IR).
split_indexed_identifier [source]¶
def split_indexed_identifier(identifier: str) -> tuple[str, str] | NoneSplit a legacy indexed identifier into base and index suffix.
Parameters:
| Name | Type | Description |
|---|---|---|
identifier | str | Identifier to inspect. Legacy carrier keys use the "<base>_<index>" spelling, where index is decimal. |
Returns:
tuple[str, str] | None — tuple[str, str] | None: (base, index) when identifier carries a
numeric suffix, otherwise None.
Classes¶
ArrayRuntimeMetadata [source]¶
class ArrayRuntimeMetadataMetadata for array literals and explicit element identity tracking.
element_parent_uuids / element_parent_indices are parallel to
element_uuids: for each tracked element they record the root array’s
UUID and the element’s index within that root (as resolved by
:func:resolve_root_qubit_address at trace time). They let an emit pass map
a packed element back to the physical qubit registered under the root
array’s QubitAddress(root_uuid, index) key even when the element’s own
UUID was never registered. The sentinel ("", -1) marks an element with
no array parent (a standalone qubit), for which a flat UUID lookup is used.
(root_uuid, -1) preserves a known root owner when the scalar index is
symbolic and therefore cannot be resolved at trace time.
Constructor¶
def __init__(
self,
const_array: Any = None,
element_uuids: tuple[str, ...] = (),
element_logical_ids: tuple[str, ...] = (),
element_parent_uuids: tuple[str, ...] = (),
element_parent_indices: tuple[int, ...] = (),
) -> NoneAttributes¶
const_array: Anyelement_logical_ids: tuple[str, ...]element_parent_indices: tuple[int, ...]element_parent_uuids: tuple[str, ...]element_uuids: tuple[str, ...]
ArrayValue [source]¶
class ArrayValue(Value[T])An array of typed IR values.
When slice_of is set, this array is a strided view over another
array. Element accesses on a sliced ArrayValue resolve to
physical slots on the root parent via the affine map
parent_index = slice_start + slice_step * view_local_index,
applied recursively along slice_of chains. The emit-time
resolver walks this chain to produce the final qubit index; passes
that substitute or clone values must treat slice_of /
slice_start / slice_step as Value references that need to
track through the same mapping as parent_array.
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(),
slice_of: 'ArrayValue | None' = None,
slice_start: 'Value | None' = None,
slice_step: 'Value | None' = None,
) -> NoneAttributes¶
logical_id: strmetadata: ValueMetadataname: strshape: tuple[Value, ...]slice_of: ‘ArrayValue | None’slice_start: ‘Value | None’slice_step: ‘Value | None’type: Tuuid: str
Methods¶
is_slice¶
def is_slice(self) -> boolReturn True if this array is a strided view of another array.
Returns:
bool — True iff slice_of is non-None.
next_version¶
def next_version(self) -> ArrayValue[T]CastMetadata [source]¶
class CastMetadataMetadata describing a cast carrier and its underlying qubits.
Constructor¶
def __init__(
self,
source_uuid: str,
qubit_uuids: tuple[str, ...],
source_logical_id: str | None = None,
qubit_logical_ids: tuple[str, ...] = (),
) -> NoneAttributes¶
qubit_logical_ids: tuple[str, ...]qubit_uuids: tuple[str, ...]source_logical_id: str | Nonesource_uuid: str
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:
Vector[Qubit] -> QFixed (after QPE, for phase measurement)
Vector[Qubit] -> QUInt (for quantum arithmetic)
QUInt -> QFixed (reinterpret bits with different encoding)
QFixed -> QUInt (reinterpret bits with different encoding)
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(),
) -> NoneAttributes¶
num_qubits: int Number of qubits involved in the cast.operation_kind: OperationKind Cast stays in the same segment as its source (QUANTUM for quantum types).qubit_mapping: list[str]signature: Signature Return the type signature of this cast operation.source_type: ValueType | Nonetarget_type: ValueType | None
DictValue [source]¶
class DictValue(_MetadataValueMixin, ValueBase)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()))(),
) -> NoneAttributes¶
entries: tuple[tuple[TupleValue | Value, Value], ...]logical_id: strmetadata: ValueMetadataname: strtype: DictTypeuuid: str
Methods¶
is_constant¶
def is_constant(self) -> boolnext_version¶
def next_version(self) -> DictValueQFixedMetadata [source]¶
class QFixedMetadataMetadata for QFixed carriers.
Constructor¶
def __init__(self, qubit_uuids: tuple[str, ...], num_bits: int, int_bits: int) -> NoneAttributes¶
int_bits: intnum_bits: intqubit_uuids: tuple[str, ...]
TupleValue [source]¶
class TupleValue(_MetadataValueMixin, ValueBase)A tuple of IR values for structured data.
Constructor¶
def __init__(
self,
name: str,
elements: tuple[ValueLike, ...] = tuple(),
metadata: ValueMetadata = ValueMetadata(),
uuid: str = (lambda: str(uuid.uuid4()))(),
logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> NoneAttributes¶
elements: tuple[ValueLike, ...]logical_id: strmetadata: ValueMetadataname: strtype: ‘TupleType’uuid: str
Methods¶
is_constant¶
def is_constant(self) -> boolnext_version¶
def next_version(self) -> TupleValueValue [source]¶
class Value(_MetadataValueMixin, ValueBase, 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). Compiler-internal identity and writes use UUIDs or
explicit parameter metadata. Compatibility readers may consult a non-empty
label only after those identity channels, so anonymous temporaries cannot
collide through a shared display key.
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, ...] = (),
) -> NoneAttributes¶
element_indices: tuple[Value, ...]logical_id: strmetadata: ValueMetadataname: strparent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
is_array_element¶
def is_array_element(self) -> boolnext_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.
ValueBase [source]¶
class ValueBaseNominal base for every typed IR value.
Runtime compiler passes inspect values in their innermost loops. A nominal base keeps those checks constant-time; a runtime-checkable protocol would repeatedly scan the protocol members on Python versions that do not cache structural checks.
Attributes¶
logical_id: strmetadata: ValueMetadataname: strtype: ValueType Return the static IR type carried by this value.uuid: str
Methods¶
get_const¶
def get_const(self) -> int | float | bool | NoneReturn the scalar constant carried by this value.
Returns:
int | float | bool | None — int | float | bool | None: Constant value, or None when the
value is not constant.
is_constant¶
def is_constant(self) -> boolReturn whether this value carries a scalar constant.
Returns:
bool — Whether scalar constant metadata is present.
is_parameter¶
def is_parameter(self) -> boolReturn whether this value represents a runtime parameter.
Returns:
bool — Whether parameter metadata is present.
next_version¶
def next_version(self) -> ValueBaseCreate the next SSA version of this value.
Returns:
ValueBase — A value with a fresh version UUID and preserved logical
identity.
parameter_name¶
def parameter_name(self) -> str | NoneReturn the public parameter name carried by this value.
Returns:
str | None — str | None: Parameter name, or None for a non-parameter value.
ValueMetadata [source]¶
class ValueMetadataTyped metadata owned by the compiler/runtime.
Constructor¶
def __init__(
self,
scalar: ScalarMetadata | None = None,
cast: CastMetadata | None = None,
qfixed: QFixedMetadata | None = None,
array_runtime: ArrayRuntimeMetadata | None = None,
dict_runtime: DictRuntimeMetadata | None = None,
) -> NoneAttributes¶
array_runtime: ArrayRuntimeMetadata | Nonecast: CastMetadata | Nonedict_runtime: DictRuntimeMetadata | Noneqfixed: QFixedMetadata | Nonescalar: ScalarMetadata | None
ValueSubstitutor [source]¶
class ValueSubstitutorSubstitute IR values in operations using a UUID-keyed mapping.
Parameters:
| Name | Type | Description |
|---|---|---|
value_map | Mapping[str, ValueBase] | Mapping from original value UUIDs to replacement values. |
transitive | bool | Whether substitutions should chase chains such as A -> B -> C to the terminal value. Defaults to False. |
Constructor¶
def __init__(self, value_map: Mapping[str, ValueBase], transitive: bool = False)Initialize the substitutor.
Parameters:
| Name | Type | Description |
|---|---|---|
value_map | Mapping[str, ValueBase] | Mapping from original value UUIDs to replacement values. |
transitive | bool | Whether substitutions should chase chains to their terminal value. Defaults to False. |
Methods¶
substitute_operation¶
def substitute_operation(self, op: Operation) -> OperationSubstitute values in an operation.
Parameters:
| Name | Type | Description |
|---|---|---|
op | Operation | Operation whose operands, results, and subclass-specific value fields should be substituted. |
Returns:
Operation — Operation with all mapped value references replaced.
substitute_value¶
def substitute_value(self, value: ValueBase) -> ValueBaseSubstitute a single value.
Parameters:
| Name | Type | Description |
|---|---|---|
value | ValueBase | Value to replace or rebuild. |
Returns:
ValueBase — Replacement value, rebuilt value with substituted
ValueBase — metadata, or the original value when nothing maps.