Frontend: Python-embedded tracing that turns qkernel functions into IR Blocks.
The qkernel decorator (qkernel.py) first rewrites the user’s
function with an AST transform (ast_transform.py) that replaces
native if / while / for statements with tracer-visible
builder calls, then executes the transformed function under a Tracer
(tracer.py) with handle arguments. Every handle method and operation
builder appends abstract IR Operations to the active tracer, and
func_to_block.py packages the trace into a HIERARCHICAL Block
(including the ParamSlot manifest for classical arguments).
Design constraints:
Handles (
handle/) are linear-typed wrappers over IRValues: gates consume their quantum arguments and return fresh handles that must be re-bound (SSA-like versioning). Reuse of a consumed handle raisesQubitConsumedErrorat trace time, before the transpiler’saffine_validatere-checks the same invariant on the IR.The frontend owns tracing, the handle type system, and Python-syntax lowering (control-flow rewriting, loop region args). It emits abstract IR only; whole-block validation, IR rewriting, segmentation, and backend concretization belong to
qamomile.circuit.transpiler.Calls to nested qkernels stay as
InvokeOperationboxes carrying aCallPolicy; the frontend never inlines —inlineis a transpiler pass.
qamomile.circuit.frontend.ast_transform¶
Overview¶
| Function | Description |
|---|---|
analyze_region_signatures | Analyze structured interfaces in one parsed function definition. |
branch_rebind_pre_bindings | Capture pre-branch bindings for if-rebind records. |
collect_quantum_rebind_violations | Analyze func for forbidden quantum rebind patterns. |
dead_rebind_binding | Probe a branch body’s post-branch binding of a dead-after variable. |
emit_if | Trace an if/else conditional and merge its branch results. |
explicit_loop_bindings | Resolve generated lexical loop bindings without frame inspection. |
for_items | Create a traced for-items loop in the Qamomile frontend. |
for_loop | Create a traced for loop in the Qamomile frontend. |
loop_rebind_snapshot | Snapshot pre-loop variable handles for rebind detection. |
loop_region_enter | Bind loop-carried classical state to a fresh region argument. |
loop_region_result | Rebind a loop-carried variable to its post-loop result handle. |
record_loop_rebinds | Record classical and quantum rebinds on the current loop-body tracer. |
should_trace_for_loop | Decide whether a qmc.range body must be traced. |
should_trace_items_loop | Decide whether a qmc.items body must be traced. |
transform_control_flow | Rewrite Python control flow into tracer-visible region builders. |
while_loop | Create a while loop whose condition is a measurement result. |
| Class | Description |
|---|---|
ControlFlowTransformer | |
QuantumRebindAnalyzer | Detects forbidden quantum variable reassignment at the AST level. |
RebindSourceKind | Discriminator for the source of a detected rebind violation. |
RebindViolation | A detected forbidden quantum variable rebinding. |
RegionLocation | Identify one source-level structured control-flow region. |
RegionSignature | Describe values crossing one structured region boundary. |
VariableCollector | Collect variables used and mutated within a block. |
Functions¶
analyze_region_signatures [source]¶
def analyze_region_signatures(
definition: ast.FunctionDef | ast.AsyncFunctionDef,
) -> dict[RegionLocation, RegionSignature]Analyze structured interfaces in one parsed function definition.
Parameters:
| Name | Type | Description |
|---|---|---|
definition | ast.FunctionDef | ast.AsyncFunctionDef | Parsed function body to analyze. |
Returns:
dict[RegionLocation, RegionSignature] — dict[RegionLocation, RegionSignature]: Source region signatures.
branch_rebind_pre_bindings [source]¶
def branch_rebind_pre_bindings(frame_locals: dict[str, Any], names: tuple) -> dict[str, Any]Capture pre-branch bindings for if-rebind records.
Called from AST-injected code at the emit_if call site with the
caller’s locals(). A name missing from the call site’s locals is
resolved through the enclosing emit_if calls’ captured pre-bindings
(innermost first): a dead-after variable never enters the generated
branch-body scopes, so for a nested if only the enclosing capture
still knows its pre-branch handle. The transformer’s candidate
analysis is lexical, so a name may genuinely be unbound everywhere
(a preceding pure-store if can be dead-store-eliminated from its
outputs); such names are silently skipped instead of raising
UnboundLocalError at the call site.
Parameters:
| Name | Type | Description |
|---|---|---|
frame_locals | dict[str, typing.Any] | The caller’s locals(). |
names | tuple | Candidate variable names to capture. |
Returns:
dict[str, typing.Any] — dict[str, typing.Any]: The resolvable candidate names mapped to
their pre-branch handles.
collect_quantum_rebind_violations [source]¶
def collect_quantum_rebind_violations(func: Callable, quantum_param_names: set[str]) -> list[RebindViolation]Analyze func for forbidden quantum rebind patterns.
Returns a (possibly empty) list of violations. Never raises on
analysis failure – returns [] instead.
dead_rebind_binding [source]¶
def dead_rebind_binding(frame_locals: dict[str, Any], name: str) -> AnyProbe a branch body’s post-branch binding of a dead-after variable.
Called from AST-injected code as an extra element of a branch body’s
return tuple. A variable reassigned in a branch but never read after
the if is dead-store-eliminated from the branch outputs, so its
post-branch binding is not otherwise observable by emit_if; this
probe reads it from the body’s locals(). In the branch that does
not store the variable the name is unbound in the body scope, so the
probe returns a sentinel instead of raising NameError.
Parameters:
| Name | Type | Description |
|---|---|---|
frame_locals | dict[str, typing.Any] | The body’s locals() at the return point. |
name | str | The probed variable name. |
Returns:
typing.Any — typing.Any: The post-branch handle, or the unbound sentinel when
the body never bound the name.
emit_if [source]¶
def emit_if(
cond_func: Callable,
true_func: Callable,
false_func: Callable,
variables: list,
output_names: tuple = (),
rebind_pre_bindings: dict | None = None,
dead_names: tuple = (),
capture_indices: tuple[int, ...] = (),
) -> AnyTrace an if/else conditional and merge its branch results.
This function is called from AST-transformed code. The AST transformer converts: if condition: true_body else: false_body
Into:
def _cond_N(vars): return condition def _body_N(vars): true_body; return vars def _body_N+1(vars): false_body; return vars result = emit_if(_cond_N, _body_N, _body_N+1, [var_list])
Parameters:
| Name | Type | Description |
|---|---|---|
cond_func | typing.Callable | Function returning the condition as a Bit or bool-like handle. |
true_func | typing.Callable | Function tracing the true branch and returning its updated variables. |
false_func | typing.Callable | Function tracing the false branch and returning its updated variables. |
variables | list | Variables captured by the two branch functions. |
output_names | tuple | Variable names positionally aligned with the branch return tuples, used for branch-rebind records. Empty when the transformer found no rebind candidates. |
rebind_pre_bindings | dict | None | Pre-branch handles of every pre-existing variable reassigned in a branch, keyed by name; captured at the call site by the AST transformer. None when there are no candidates. |
dead_names | tuple | Names of dead-after rebind candidates whose post-branch bindings the branch bodies append as a probe tail after their ordinary return values (see dead_rebind_binding). The tail is consumed for rebind records only and never merged or returned. Empty when there are no dead candidates. |
capture_indices | tuple[int, ...] | Positions in variables that form each branch region’s explicit input interface. Defaults to an empty tuple. |
Returns:
typing.Any — typing.Any: The sole merged value, a tuple of merged values, or None
when the branches return no values.
Raises:
TypeError— If corresponding branch values have incompatible types or divergent values with no Qamomile IR representation.ValueError— If branch result lengths or probe-tail lengths disagree.
Example:
@qkernel
def my_kernel(q: Qubit) -> Qubit:
result = measure(q)
if result:
q = z(q)
return qexplicit_loop_bindings [source]¶
def explicit_loop_bindings(bindings: tuple[tuple[str, Callable[[], Any]], ...]) -> dict[str, Any]Resolve generated lexical loop bindings without frame inspection.
Generated control-flow code passes one lazy zero-argument resolver for each statically analyzed interface name. A name that is not bound on the traced path may still be available from the enclosing branch’s explicit pre-binding stack; genuinely absent names are omitted, matching the old tolerant snapshot behavior.
Parameters:
| Name | Type | Description |
|---|---|---|
bindings | tuple[tuple[str, Callable[[], Any]], ...] | Named lazy lexical resolvers in deterministic interface order. |
Returns:
dict[str, typing.Any] — dict[str, typing.Any]: Resolved bindings keyed by source name.
for_items [source]¶
def for_items(
d: Dict,
key_var_names: list[str],
value_var_name: str,
*,
captures: tuple[tuple[str, Any], ...] = (),
) -> Generator[tuple[Any, Any], None, None]Create a traced for-items loop in the Qamomile frontend.
This context manager creates a ForItemsOperation that iterates over dictionary (key, value) pairs. The operation is always unrolled at transpile time since quantum backends cannot natively iterate over classical data structures.
Parameters:
| Name | Type | Description |
|---|---|---|
d | Dict | Dict handle whose compile-time-known entries are iterated. |
key_var_names | list[str] | Names of key-unpacking variables, for example ["i", "j"] for tuple keys. |
value_var_name | str | Display name of the item-value variable. |
captures | tuple[tuple[str, typing.Any], ...] | Statically analyzed read-only body inputs. Defaults to an empty tuple. |
Yields:
tuple[typing.Any, typing.Any] — tuple[typing.Any, typing.Any]: Key handle(s) and the typed scalar
value handle used while tracing the loop body.
Raises:
TypeError— Ifdis a runtime-parameter Dict (declared viaparameters=[...]without bound data), or its key annotation cannot be represented by the loop target. A runtime Dict’s key structure is unknown at compile time, so an items() loop cannot be unrolled; only constant-key subscript lookups (d[key]) are supported for runtime-parameter dicts.NotImplementedError— If the Dict value annotation is a container or another type without a scalar frontend handle.ValueError— If the constructed loop has inconsistent region-result metadata.
Example:
@qkernel
def ising_cost(
q: Vector[Qubit],
ising: Dict[Tuple[UInt, UInt], Float],
gamma: Float,
) -> Vector[Qubit]:
for (i, j), Jij in qmc.items(ising):
q[i], q[j] = qmc.rzz(q[i], q[j], gamma * Jij)
return qfor_loop [source]¶
def for_loop(
start,
stop,
step = 1,
var_name: str = '_loop_idx',
*,
captures: tuple[tuple[str, Any], ...] = (),
) -> Generator[UInt, None, None]Create a traced for loop in the Qamomile frontend.
Parameters:
| Name | Type | Description |
|---|---|---|
start | typing.Any | Inclusive loop start as an integer or UInt. |
stop | typing.Any | Exclusive loop stop as an integer or UInt. |
step | typing.Any | Nonzero loop step as an integer or UInt. Defaults to 1. |
var_name | str | Display name of the loop variable. Defaults to "_loop_idx". |
captures | tuple[tuple[str, typing.Any], ...] | Statically analyzed read-only body inputs. Defaults to an empty tuple. |
Yields:
UInt — The loop iteration variable (can be used as array index)
Raises:
TypeError— If a bound cannot be represented as a scalar IR value.ValueError— If the constructed loop has inconsistent region-result metadata.
Example:
@QKernel
def my_kernel(qubits: Array[Qubit, Literal[3]]) -> Array[Qubit, Literal[3]]:
for i in qm.range(3):
qubits[i] = h(qubits[i])
return qubits
@QKernel
def my_kernel2(qubits: Array[Qubit, Literal[5]]) -> Array[Qubit, Literal[5]]:
for i in qm.range(1, 4): # i = 1, 2, 3
qubits[i] = h(qubits[i])
return qubitsClassical scalar updates (total = total + i) become explicit
RegionArg records on the ForOperation: the loop enters with
the initializer, each iteration reads the previous iteration’s
value, and post-loop code reads the loop result.
loop_rebind_snapshot [source]¶
def loop_rebind_snapshot(frame_locals: dict[str, Any], names: tuple[str, ...]) -> dict[str, Any]Snapshot pre-loop variable handles for rebind detection.
Called from AST-injected probe code as the first statement of a traced
loop body. The snapshot records which handle each candidate variable
name pointed at before the body ran, so record_loop_rebinds can
detect rebinds by comparing IR value identity afterwards.
Candidates are resolved through :func:branch_rebind_pre_bindings:
the caller’s frame locals first, then the enclosing if-branch
pre-binding stack. The fallback matters inside an if branch — a
variable the branch only stores (via the loop) is not a branch
input parameter, so it is unbound in the branch’s frame at loop
entry, yet its pre-branch handle is exactly the state a loop-body
rebind would discard. Names bound nowhere are silently omitted.
Parameters:
| Name | Type | Description |
|---|---|---|
frame_locals | dict[str, typing.Any] | The caller’s locals() at loop entry. |
names | tuple[str, ...] | Candidate variable names to snapshot. |
Returns:
dict[str, typing.Any] — dict[str, typing.Any]: The resolvable candidate names mapped to
their pre-loop-body handles (or plain Python values).
loop_region_enter [source]¶
def loop_region_enter(snapshot: dict[str, Any], name: str, allow_array: bool = False) -> AnyBind loop-carried classical state to a fresh region argument.
Called from AST-injected code at the top of a structured loop body
(immediately after loop_rebind_snapshot)
for each read-before-write classical candidate: total = loop_region_enter(_qm_rebind_snap_N, "total"). When the pre-loop
binding is a classical UInt / Float scalar (or a plain
Python int / float), the body is given a fresh
region-argument handle so its reads become explicit loop-carried
reads instead of stale pre-loop reads — the MLIR iter_args
model. The loop builder later converts the pending entry into a
RegionArg on the loop operation.
Classical arrays are also promoted so persistent element stores thread
the current array version through the loop. Quantum values, dicts,
Qubit, Bit, opaque Python objects, and bool are returned
unchanged; quantum rebinds keep feeding the discard check and
measurement-backed Bit carries keep their targeted rejection.
Parameters:
| Name | Type | Description |
|---|---|---|
snapshot | dict[str, typing.Any] | Pre-loop-body bindings from loop_rebind_snapshot. |
name | str | The candidate variable name. |
allow_array | bool | Whether a persistent element update may promote a classical array. Whole-array rebinds leave this false and retain their targeted rejection. Defaults to False. |
Returns:
typing.Any — typing.Any: A fresh region-argument handle for supported scalar or
array bindings, or the original binding unchanged.
Raises:
NameError— Ifnameresolves nowhere — mirroring theNameErrorthe body’s first read would have raised.
loop_region_result [source]¶
def loop_region_result(name: str, current: Any) -> AnyRebind a loop-carried variable to its post-loop result handle.
Called from AST-injected code immediately after a structured loop’s
with block: total = loop_region_result("total", total). Consumes the result handle
the loop builder published for name (if any) so post-loop reads
reference the loop operation’s result value instead of the body’s
final yielded value.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | The carried variable name. |
current | typing.Any | The variable’s current binding (the body’s final handle), returned unchanged when the closed loop published no result for name. |
Returns:
typing.Any — typing.Any: The published result handle, or current.
record_loop_rebinds [source]¶
def record_loop_rebinds(
snapshot: dict[str, Any],
frame_locals: dict[str, Any],
names: tuple[str, ...],
classical_names: tuple[str, ...],
) -> NoneRecord classical and quantum rebinds on the current loop-body tracer.
Called from AST-injected probe code as the last statement of a traced
loop body. Two families of rebinds are recorded as
:class:LoopCarriedRebind entries on the active body tracer (the
loop builders copy them onto the loop operation, where the
transpiler’s rejection passes read them):
Quantum (any candidate name): the variable’s pre-body value is quantum and its post-body value denotes a different resource — a fresh allocation or another register rather than a gate self-update or exact full reslice. These feed the transpiler’s loop-body quantum discard check.
Classical values (only names in
classical_names): supported same-typeUInt/Floatvalues that were region-bound at body entry complete their pendingRegionArginstead of producing a record. Every other representable rebind produces a residual record, including measurement-backedBitvalues and containers. The transpiler rejects shapes that need unsupported routing; a store-only scalarBitis accepted only for a statically non-empty unrolled loop, where reusing the measurement-result UUID correctly selects the last iteration and no zero-trip initializer must be routed.classical_namesincludes both read-before-write carries and store-only values that are live after the loop.
No IR operations are emitted; this only annotates the tracer.
Parameters:
| Name | Type | Description |
|---|---|---|
snapshot | dict[str, typing.Any] | Pre-loop-body handles from loop_rebind_snapshot. |
frame_locals | dict[str, typing.Any] | The caller’s locals() at the end of the loop body. |
names | tuple[str, ...] | All candidate variable names. |
classical_names | tuple[str, ...] | The subset of names the loop body either reads before writing or overwrites and exposes after the loop; only these may produce classical records or complete pending region arguments. |
should_trace_for_loop [source]¶
def should_trace_for_loop(start: Any, stop: Any, step: Any) -> boolDecide whether a qmc.range body must be traced.
The frontend executes loop bodies once to capture a ForOperation.
When all bounds are concrete and Python’s range would execute
zero times, tracing the body would incorrectly leak borrow /
destructive-consume state into the enclosing scope. Symbolic or
invalid bounds stay conservative and trace the body so the normal
compiler validation path reports any errors.
Parameters:
| Name | Type | Description |
|---|---|---|
start | typing.Any | Loop start bound. |
stop | typing.Any | Loop stop bound. |
step | typing.Any | Loop step bound. |
Returns:
bool — False only for statically-known zero-trip loops; True
bool — otherwise.
should_trace_items_loop [source]¶
def should_trace_items_loop(mapping: Any) -> boolDecide whether a qmc.items body must be traced.
The frontend executes loop bodies once to capture a
ForItemsOperation. When the mapping is a Dict handle whose
bound contents are compile-time-known and EMPTY, Python’s iteration
would execute zero times, so tracing the body would incorrectly
leak bindings (and rebind records) into the enclosing scope — the
qmc.range zero-trip guard’s exact analogue
(:func:should_trace_for_loop). Symbolic or unbound mappings stay
conservative and trace the body so the normal compiler validation
path reports any errors.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | typing.Any | The iterated mapping — normally a Dict handle; anything without bound dict metadata is treated as symbolic. |
Returns:
bool — False only for a mapping with present-and-empty bound
bool — dict contents; True otherwise.
transform_control_flow [source]¶
def transform_control_flow(
func: Callable[..., Any],
*,
region_signatures: dict[RegionLocation, RegionSignature] | None = None,
) -> Callable[..., Any]Rewrite Python control flow into tracer-visible region builders.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable[..., Any] | Raw qkernel function. |
region_signatures | dict[RegionLocation, RegionSignature] | None | Precomputed explicit region interfaces. Defaults to None. |
Returns:
Callable[..., Any] — Callable[..., Any]: Transformed function executed by the tracer.
Raises:
SyntaxError— If source retrieval or parsing fails.NotImplementedError— If a referenced closure value is unavailable.
while_loop [source]¶
def while_loop(
cond: Callable,
*,
captures: tuple[tuple[str, Any], ...] = (),
) -> Generator[WhileLoop, None, None]Create a while loop whose condition is a measurement result.
The condition must be a Bit produced by qmc.measure().
Non-measurement conditions (classical variables, constants,
comparisons) are accepted at build time but will be rejected by
ValidateWhileContractPass during transpilation.
Parameters:
| Name | Type | Description |
|---|---|---|
cond | typing.Callable | A callable (lambda) that returns the loop condition. Must return a Bit handle originating from qmc.measure(). |
captures | tuple[tuple[str, typing.Any], ...] | Statically analyzed read-only body inputs. Defaults to an empty tuple. |
Yields:
WhileLoop — A marker object for the while loop context.
Raises:
TypeError— If either condition evaluation cannot be represented as a scalar IR value.ValueError— If the constructed loop has inconsistent region-result metadata.
Example::
@qm.qkernel
def repeat_until_zero() -> qm.Bit:
q = qm.qubit("q")
q = qm.h(q)
bit = qm.measure(q)
while bit:
q2 = qm.qubit("q2")
q2 = qm.h(q2)
bit = qm.measure(q2)
return bitThe body register is a body-local name (q2), not a rebind of the
pre-loop q: rebinding a pre-existing quantum variable to a
register allocated in the body is rejected by the transpiler’s
control-flow discard check, because the runtime loop re-executes its
body on one persistent register without reset and cannot realize
“fresh per iteration” semantics for the rebound name.
Classical scalar updates (count = count + 1) are represented as
explicit region arguments and yields. Target validation may still reject
a carry when the selected backend cannot thread that classical type
through a runtime measurement-controlled loop.
Classes¶
ControlFlowTransformer [source]¶
class ControlFlowTransformer(ast.NodeTransformer)Constructor¶
def __init__(
self,
global_names: set[str] | None = None,
param_names: set[str] | None = None,
namespace: dict[str, Any] | None = None,
region_signatures: dict[RegionLocation, RegionSignature] | None = None,
) -> NoneInitialize source tracking and explicit region interfaces.
Parameters:
| Name | Type | Description |
|---|---|---|
global_names | set[str] | None | Names resolved outside the qkernel local scope. Defaults to None. |
param_names | set[str] | None | Function parameter names used for shadowing diagnostics. Defaults to None. |
namespace | dict[str, Any] | None | Definition-time values used to resolve callable conditions. Defaults to None. |
region_signatures | dict[RegionLocation, RegionSignature] | None | Static interfaces for structured source regions. Defaults to None. |
Attributes¶
counter: intfor_func_nameif_func_nametype_registry: dict[str, ast.AST]while_func_name
Methods¶
visit_AnnAssign¶
def visit_AnnAssign(self, node: ast.AnnAssign) -> AnyDetect annotated assignments such as a: int = 0 and register
the type information.
visit_For¶
def visit_For(self, node: ast.For) -> AnyTransform a supported qkernel for loop and attach rebind probes.
Parameters:
| Name | Type | Description |
|---|---|---|
node | ast.For | Range or items loop to validate and transform. |
Returns:
Any — Guarded AST statement implementing the range or items loop.
Raises:
SyntaxError— If the loop form, target, shadowing, or escaping bindings violate qkernel loop rules.AssertionError— If validated dispatch reaches an unknown loop kind.
visit_FunctionDef¶
def visit_FunctionDef(self, node: ast.FunctionDef) -> ast.FunctionDefProcess the function body with definition tracking.
Collects parameter names as the initial set of defined variables
and delegates to _visit_body_with_tracking for sequential
statement processing.
visit_If¶
def visit_If(self, node: ast.If) -> Anyvisit_While¶
def visit_While(self, node: ast.While) -> AnyTransform a qkernel while loop into a traced context-manager body.
Parameters:
| Name | Type | Description |
|---|---|---|
node | ast.While | While statement to validate and transform. |
Returns:
Any — Replacement ast.With node invoking while_loop.
Raises:
SyntaxError— If the loop has anelseclause, its condition performs a quantum operation, or a body-local value escapes.
QuantumRebindAnalyzer [source]¶
class QuantumRebindAnalyzer(ast.NodeVisitor)Detects forbidden quantum variable reassignment at the AST level.
Forbidden patterns (target is an existing quantum variable):
a = bwherebis quantum with a different origina = f(b, ...)wherebis quantum with a different origina = qm.qubit("...")silently discardingaa = some_opaque_call()where the call has no known quantum sourcea = b = exprchained assignment touching a quantum namea: qm.Qubit = ...(annotated form of the above)
Allowed patterns:
a = f(a, ...)(self-update)new = f(b, ...)(new binding — target was not quantum before)alias = q(new alias — target was not quantum before)a, b = f(a, b)/a, b = (g(b), h(a))(1-to-1 quantum permutation)
The analyzer is a single-pass ast.NodeVisitor and does not
model Python control flow precisely. To keep compile-time-if
dead-branch rebinds — which the IR’s CompileTimeIfLoweringPass
will later resolve by selecting one branch and discarding the
other — from being rejected at decoration time, visit_If /
visit_For / visit_While route every branch through
:meth:_visit_branch_scope, which snapshots quantum_vars
before and restores it after each body / orelse, AND
truncates any violations recorded inside the branch back to the
pre-branch length. Top-level (non-branch-internal) rebinds are
flagged as usual; branch-internal rebinds are deliberately not
reported at decoration time. Runtime-branch and loop-body discards
are instead rejected at the IR layer by
reject_control_flow_quantum_discard (in
qamomile.circuit.transpiler.passes.analyze), which can tell
compile-time branches from runtime ones.
Constructor¶
def __init__(self, quantum_param_names: set[str]) -> NoneInitialize the analyzer with the kernel’s quantum parameter names.
Parameters:
| Name | Type | Description |
|---|---|---|
quantum_param_names | set[str] | Names of kernel parameters whose annotated type is a quantum handle (Qubit / Vector[Qubit]). Each is seeded into quantum_vars as its own origin. |
Attributes¶
quantum_vars: dict[str, str]violations: list[RebindViolation]
Methods¶
visit_AnnAssign¶
def visit_AnnAssign(self, node: ast.AnnAssign) -> NoneDispatch q: qm.Qubit = expr through the single-assign path.
Parameters:
| Name | Type | Description |
|---|---|---|
node | ast.AnnAssign | The annotated assignment statement. Annotation-only forms (q: qm.Qubit with no RHS) are ignored — there is nothing to rebind. |
visit_Assign¶
def visit_Assign(self, node: ast.Assign) -> NoneDispatch a = expr / a, b = expr / a = b = expr.
Parameters:
| Name | Type | Description |
|---|---|---|
node | ast.Assign | The assignment statement. |
visit_Call¶
def visit_Call(self, node: ast.Call) -> NoneApply consume effects when a classical-returning call is seen.
_check_single_assign / _check_tuple_assign already
invoke :meth:_consume_quantum_args when a classical-returning
call appears on the RHS of an assignment. This visitor handles
the cases where the same call appears outside an assignment:
as a bare expression statement (qm.measure(q)), inside an
if / while condition, inside a for iterable, or
nested inside any other expression visited via
generic_visit. Without this hook, those forms would leave
q in quantum_vars and trip a false-positive
FRESH_ALLOCATION violation on a later rebind of q.
Re-visiting from inside a covered assignment path is benign:
_consume_quantum_args is idempotent — by the time
visit_Call runs as part of generic_visit after the
assignment dispatch, the relevant origins are already gone
from quantum_vars and the second call is a no-op.
Parameters:
| Name | Type | Description |
|---|---|---|
node | ast.Call | The call expression. |
visit_For¶
def visit_For(self, node: ast.For) -> NoneVisit a for loop’s body and else with branch-local scope.
node.iter is walked first (before the branch-scope
snapshot) so that any consume effect inside the iterable
expression is reflected in the outer analyzer state. The
loop target itself is not modeled — Qamomile’s frontend
rewrites qmc.range(...) loops via the control-flow
transformer, so the iterator variable is a classical index
and never quantum.
Parameters:
| Name | Type | Description |
|---|---|---|
node | ast.For | The for statement. |
visit_If¶
def visit_If(self, node: ast.If) -> NoneVisit if/else body with branch-local scope.
node.test is walked first (before the branch-scope
snapshot) so that any consume effect inside the condition
(e.g. if qm.measure(q):) is reflected in the outer
analyzer state, not silently rolled back when the branch
scope restores. See :meth:_visit_branch_scope for the
snapshot-restore protocol applied to body and orelse.
Parameters:
| Name | Type | Description |
|---|---|---|
node | ast.If | The if statement. |
visit_While¶
def visit_While(self, node: ast.While) -> NoneVisit a while loop’s body and else with branch-local scope.
Same protocol as :meth:visit_If. node.test is walked
before the branch-scope snapshot.
Parameters:
| Name | Type | Description |
|---|---|---|
node | ast.While | The while statement. |
RebindSourceKind [source]¶
class RebindSourceKind(enum.StrEnum)Discriminator for the source of a detected rebind violation.
Each value classifies why the analyzer believes an existing quantum binding is being silently discarded, and lets downstream error-message formatting render a domain-appropriate explanation instead of forcing a generic “different quantum variable” sentence onto, e.g., a fresh allocation.
Members:
DIRECT_ALIAS: q = other_q or q = qs[i].
QUANTUM_ARG: q = f(other_q, ...) where other_q has a
different origin than q.
FRESH_ALLOCATION: q = qm.qubit(...) /
qm.qubit_array(...) — the original quantum state is
silently discarded in favor of a freshly allocated one.
UNKNOWN_CALL: q = some_func(...) where the call references
no known quantum variable and is not a recognized quantum
constructor; conservatively treated as a rebind because
the original q is not threaded through the RHS.
CHAINED_ASSIGNMENT: q1 = q2 = expr where at least one
target is an existing quantum variable; chained binding
semantics are too ambiguous to verify self-update.
Attributes¶
CHAINED_ASSIGNMENTDIRECT_ALIASFRESH_ALLOCATIONQUANTUM_ARGUNKNOWN_CALL
RebindViolation [source]¶
class RebindViolationA detected forbidden quantum variable rebinding.
Constructor¶
def __init__(
self,
target_name: str,
source_name: str | None,
source_kind: RebindSourceKind,
func_name: str | None,
lineno: int,
source_expr: str | None = None,
) -> NoneAttributes¶
func_name: str | Nonelineno: intsource_expr: str | Nonesource_kind: RebindSourceKindsource_name: str | Nonetarget_name: str
RegionLocation [source]¶
class RegionLocationIdentify one source-level structured control-flow region.
Parameters:
| Name | Type | Description |
|---|---|---|
kind | str | Region kind: for, while, or if. |
lineno | int | One-based source line in the original source file. |
col_offset | int | Zero-based source column. |
Constructor¶
def __init__(self, kind: str, lineno: int, col_offset: int) -> NoneAttributes¶
col_offset: intkind: strlineno: int
RegionSignature [source]¶
class RegionSignatureDescribe values crossing one structured region boundary.
Parameters:
| Name | Type | Description |
|---|---|---|
inputs | tuple[str, ...] | Explicit values passed to the region. |
carried | tuple[str, ...] | Values updated across a loop back edge or merged across branches. |
captures | tuple[str, ...] | Read-only region inputs. |
results | tuple[str, ...] | Updated values live after the region. |
Constructor¶
def __init__(
self,
inputs: tuple[str, ...],
carried: tuple[str, ...],
captures: tuple[str, ...],
results: tuple[str, ...],
) -> NoneAttributes¶
captures: tuple[str, ...]carried: tuple[str, ...]inputs: tuple[str, ...]results: tuple[str, ...]
VariableCollector [source]¶
class VariableCollector(ast.NodeVisitor)Collect variables used and mutated within a block.
Excludes:
Function names in calls (func in Call)
Global base objects in attribute accesses (value in Attribute)
Global variables (modules, builtins, etc.)
Constructor¶
def __init__(self, global_names: set[str] | None = None)Initialize an empty variable/dataflow collector.
Parameters:
| Name | Type | Description |
|---|---|---|
global_names | set[str] | None | Names treated as globals rather than function-local dataflow. Defaults to None. |
Attributes¶
incoming_vars: set[str] Variables that must come from an outer scope (first use is Load).load_vars: set[str] Variables referenced in Load context (actually read).locally_defined_vars: set[str] Variables first defined (Store) within this scope.store_order: tuple[str, ...] Return assigned variable names in first-source-store order.store_vars: set[str] Variables assigned in Store context.vars
Methods¶
visit_AnnAssign¶
def visit_AnnAssign(self, node: ast.AnnAssign)Visit the RHS first, like visit_Assign.
total: qmc.UInt = total + i reads the RHS before storing, so
the generic (target-first) traversal would misclassify the
first context as “Store” and drop the read-before-write
evidence the loop-carry candidate analysis needs. The
annotation itself is type syntax, not dataflow, and is skipped.
Parameters:
| Name | Type | Description |
|---|---|---|
node | ast.AnnAssign | Annotated assignment to visit. |
visit_Assign¶
def visit_Assign(self, node: ast.Assign)Visit the RHS first to match Python’s evaluation order.
q1 = qm.h(q1) → RHS q1 (Load) is first → first_context is “Load”
cond2 = qm.measure(q2) → RHS q2 (Load) first, LHS cond2 (Store) after
visit_Attribute¶
def visit_Attribute(self, node: ast.Attribute)Record the base name of an attribute access.
Global names such as module names (qm.h) are excluded as before,
while user variables (qs.shape) are treated as Load.
visit_AugAssign¶
def visit_AugAssign(self, node: ast.AugAssign)AugAssign (e.g. x += 1) is an implicit Read-before-Write.
Visit the RHS first and record Name targets as both Load and Store. first_context is “Load” (the existing value is read first).
Parameters:
| Name | Type | Description |
|---|---|---|
node | ast.AugAssign | Augmented assignment to visit in Python evaluation order. |
visit_Call¶
def visit_Call(self, node: ast.Call)Exclude the function name of a call.
visit_FunctionDef¶
def visit_FunctionDef(self, node: ast.FunctionDef)Skip traversal of inner function definitions.
visit_Name¶
def visit_Name(self, node: ast.Name)Collect a non-excluded variable name and its access context.
Parameters:
| Name | Type | Description |
|---|---|---|
node | ast.Name | Name occurrence whose load/store context should contribute to variable dataflow. |
visit_NamedExpr¶
def visit_NamedExpr(self, node: ast.NamedExpr)Visit a named expression in Python evaluation order.
A walrus assignment such as total := total + i evaluates the
value before storing the target. Preserving that order keeps the
read-before-write evidence used to identify loop-carry candidates.
Parameters:
| Name | Type | Description |
|---|---|---|
node | ast.NamedExpr | The named-expression node to visit. |
qamomile.circuit.frontend.callable_signature¶
Frontend signature helpers for callable-style operations.
Overview¶
| Function | Description |
|---|---|
handle_type_map | Map Handle type to ValueType. |
is_array_type | Check if type is a Vector, Matrix, or Tensor subclass. |
| Class | Description |
|---|---|
CallableSignature | Describe frontend input and output handle types for an opaque callable. |
ParamHint | |
Signature |
Functions¶
handle_type_map [source]¶
def handle_type_map(handle_type: type[Handle] | type) -> ValueTypeMap Handle type to ValueType.
is_array_type [source]¶
def is_array_type(t: Any) -> boolCheck if type is a Vector, Matrix, or Tensor subclass.
Classes¶
CallableSignature [source]¶
class CallableSignatureDescribe frontend input and output handle types for an opaque callable.
This class is intentionally a small frontend helper. It lets users write
signature-shaped APIs such as opaque(name, signature=...) without
exposing the compiler-facing CallableDef model.
Parameters:
| Name | Type | Description |
|---|---|---|
inputs | list[Any] | Frontend handle annotations accepted by the callable. |
outputs | list[Any] | Frontend handle annotations produced by the callable. |
Constructor¶
def __init__(self, inputs: list[Any], outputs: list[Any]) -> NoneAttributes¶
inputs: list[Any]outputs: list[Any]
Methods¶
accepts_single_qubit_vector¶
def accepts_single_qubit_vector(self) -> boolReturn whether this signature is a one-vector quantum callable.
Returns:
bool — True when both input and output are exactly one
bool — Vector[Qubit]-style annotation.
scalar_qubit_input_count¶
def scalar_qubit_input_count(self) -> int | NoneReturn scalar-qubit arity when the signature is scalar-only.
Returns:
int | None — int | None: Number of scalar Qubit inputs, or None when
int | None — the signature contains a vector register.
to_ir_signature¶
def to_ir_signature(self) -> SignatureConvert the frontend signature into an IR operation signature.
Returns:
Signature — Best-effort IR signature using operation parameter
Signature — hints.
Raises:
TypeError— If a frontend type cannot map to an IR value type.
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.frontend.composite_gate¶
Define named composite qkernels without a parallel frontend hierarchy.
Overview¶
| Function | Description |
|---|---|
composite_gate | Define a named composite using the normal qkernel programming model. |
configure_composite | Configure a QKernel to remain visible as a named composite call. |
qkernel | Decorator to define a Qamomile quantum kernel. |
| Class | Description |
|---|---|
CallPolicy | Describe the default lowering policy for a callable call. |
CallableImplementation | Describe one implementation candidate for a callable. |
CompositeGateType | Classify standard boxed quantum callables. |
QKernel | Decorator class for Qamomile quantum kernels. |
Functions¶
composite_gate [source]¶
def composite_gate(
func: Callable[..., Any] | None = None,
*,
name: str = '',
implementations: Sequence[CallableImplementation] | None = None,
) -> QKernel[..., Any] | Callable[[Callable[..., Any]], QKernel[..., Any]]Define a named composite using the normal qkernel programming model.
The decorated object is a QKernel. Calls keep their named box in the IR,
while build(), draw(), estimate_resources(), control(), and
inverse() use the same interface as every other qkernel.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable[..., Any] | None | Function or qkernel to decorate. Defaults to None for decorator-with-arguments use. |
name | str | Public callable name. Defaults to the function name. |
implementations | Sequence[CallableImplementation] | None | Optional compiler implementation candidates. |
Returns:
QKernel[..., Any] | Callable[[Callable[..., Any]], QKernel[..., Any]] — QKernel[..., Any] | Callable[[Callable[..., Any]], QKernel[..., Any]]:
Configured qkernel or decorator.
Raises:
TypeError— If the decorator target is not callable.
Example:
>>> import qamomile.circuit as qmc
>>> @qmc.composite_gate(name="bell_pair")
... def bell_pair(
... a: qmc.Qubit, b: qmc.Qubit
... ) -> tuple[qmc.Qubit, qmc.Qubit]:
... a = qmc.h(a)
... return qmc.cx(a, b)configure_composite [source]¶
def configure_composite(
kernel: QKernel[..., Any],
*,
name: str | None = None,
namespace: str | None = None,
gate_type: CompositeGateType = CompositeGateType.CUSTOM,
policy: CallPolicy = CallPolicy.PRESERVE_BOX,
implementations: Sequence[CallableImplementation] | None = None,
semantic_arguments: Mapping[str, Any] | None = None,
) -> QKernel[..., Any]Configure a QKernel to remain visible as a named composite call.
This mutates and returns the same QKernel object. No wrapper class or alternate call protocol is introduced.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernel[..., Any] | Kernel to configure. |
name | str | None | Public callable name. Defaults to the kernel name. |
namespace | str | None | Explicit stable callable namespace. None derives one from the decorated function’s module, qualified name, and source location. Defaults to None. |
gate_type | CompositeGateType | Internal stdlib classification. Defaults to CUSTOM. |
policy | CallPolicy | Lowering policy. Defaults to PRESERVE_BOX. |
implementations | Sequence[CallableImplementation] | None | Optional implementation candidates. |
semantic_arguments | Mapping[str, Any] | None | Serializer-friendly arguments that are part of the operation’s meaning rather than its decomposition. Defaults to no semantic arguments. |
Returns:
QKernel[..., Any] — QKernel[..., Any]: The same configured kernel instance.
qkernel [source]¶
def qkernel(func: Callable[P, R]) -> QKernel[P, R]Decorator to define a Qamomile quantum kernel.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable[P, R] | Function to decorate. |
Returns:
QKernel[P, R] — QKernel[P, R]: QKernel wrapping the function.
Classes¶
CallPolicy [source]¶
class CallPolicy(enum.Enum)Describe the default lowering policy for a callable call.
Attributes¶
INLINENATIVE_FIRSTPRESERVE_BOX
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
CompositeGateType [source]¶
class CompositeGateType(enum.Enum)Classify standard boxed quantum callables.
Attributes¶
CUSTOMIQFTQFTQPE
QKernel [source]¶
class QKernel(QKernelBuildMixin, QKernelVisualizationMixin, Generic[P, R])Decorator class for Qamomile quantum kernels.
Constructor¶
def __init__(self, func: Callable[P, R]) -> NoneAttributes¶
block: Block Compile the function to a hierarchical Block if not already compiled.effects: KernelEffect Return cached semantic effects of this qkernel.funcinput_types: dict[str, Any] Return resolved and frozen frontend input annotations.nameoutput_types: list[Any] Return the resolved frontend annotation for every output slot.raw_funcreturn_type: Any Return the resolved and frozen complete return annotation.signature
qamomile.circuit.frontend.constructors¶
Overview¶
| Function | Description |
|---|---|
bit | Create a Bit handle from a boolean/int literal or declare a named Bit parameter. |
bit_array | Create a fixed-length classical bit vector initialized to zero. |
float_ | Create a Float handle from a float literal or declare a named Float parameter. |
get_current_tracer | |
qubit | Create a new qubit and emit a QInitOperation. |
qubit_array | Create a new 1-D qubit register and emit its QInitOperation. |
uint | Create a UInt handle from an integer literal or a named parameter. |
| Class | Description |
|---|---|
ArrayValue | An array of typed IR values. |
QInitOperation | Initialize the qubit |
Value | A typed SSA value in the IR. |
Functions¶
bit [source]¶
def bit(arg: bool | str | int) -> BitCreate a Bit handle from a boolean/int literal or declare a named Bit parameter.
bit_array [source]¶
def bit_array(shape: UInt | int | tuple[UInt | int, ...], name: str = 'bits') -> Vector[Bit]Create a fixed-length classical bit vector initialized to zero.
The vector is represented as an initialized IR constant array, so it can
receive measured Bit values through ordinary element assignment and
can be returned from a qkernel. Its length must be known while tracing;
the emitted classical initializer materializes contents, not a dynamic
array shape.
Parameters:
| Name | Type | Description |
|---|---|---|
shape | UInt | int | tuple[UInt | int, ...] | Number of bits in the vector, given either as a scalar or a one-element tuple. A UInt must resolve to a compile-time constant. |
name | str | Display name for the underlying array value. Defaults to "bits". |
Returns:
Vector[Bit] — Vector[Bit]: A fixed-length vector whose elements are initialized to
False.
Raises:
TypeError— Ifshapeornamehas the wrong type.ValueError— If the shape is empty, negative, or not known at trace time.NotImplementedError— If a shape with more than one dimension is requested.
Example:
>>> import qamomile.circuit as qmc
>>>
>>> @qmc.qkernel
... def readout() -> qmc.Vector[qmc.Bit]:
... qubits = qmc.qubit_array(2, "qubits")
... measured = qmc.measure(qubits)
... bits = qmc.bit_array(2)
... bits[0] = measured[0]
... bits[1] = measured[1]
... return bitsfloat_ [source]¶
def float_(arg: float | str) -> FloatCreate a Float handle from a float literal or declare a named Float parameter.
get_current_tracer [source]¶
def get_current_tracer() -> Tracerqubit [source]¶
def qubit(name: str) -> QubitCreate a new qubit and emit a QInitOperation.
qubit_array [source]¶
def qubit_array(shape: UInt | int | tuple[UInt | int, ...], name: str) -> Vector[Qubit]Create a new 1-D qubit register and emit its QInitOperation.
Parameters:
| Name | Type | Description |
|---|---|---|
shape | UInt | int | tuple[UInt | int, ...] | Number of qubits in the register, given either as a scalar or as a 1-tuple. Tuples with more than one dimension are rejected (see Raises). |
name | str | Name for the underlying ArrayValue. |
Returns:
Vector[Qubit] — Vector[Qubit]: A 1-D quantum register handle of the requested
size.
Raises:
TypeError— Ifshapeornamehas the wrong type.ValueError— Ifshapeis an empty tuple.NotImplementedError— Ifshapehas more than one dimension. The quantum addressing path is rank-1, so a higher-rank register would silently alias distinct elements onto the same physical qubit. Allocate a 1-DVector[Qubit]of the total size and compute flat indices explicitly instead (e.g.q[i * ncols + j]).
uint [source]¶
def uint(arg: int | str) -> UIntCreate a UInt handle from an integer literal or a named parameter.
Parameters:
| Name | Type | Description |
|---|---|---|
arg | int | str | An integer literal to bake in as a compile-time constant, or a str naming a symbolic UInt parameter. A bool is rejected: True / False are not valid integer values here even though bool subclasses int. (Sign is not validated here -- a negative literal is accepted and baked in as-is.) |
Returns:
UInt — A constant-valued handle for an int argument, or a named
symbolic handle for a str argument.
Raises:
TypeError— Ifargis neither a plainintnor astr(in particular, if it is abool).
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]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
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.frontend.decomposition¶
Configuration for compiler implementation-strategy selection.
Overview¶
| Class | Description |
|---|---|
DecompositionConfig | Configure named implementation strategies for callable lowering. |
Classes¶
DecompositionConfig [source]¶
class DecompositionConfigConfigure named implementation strategies for callable lowering.
Implementations live on each callable definition. This object only records user selection; it is intentionally not a second global strategy registry.
Parameters:
| Name | Type | Description |
|---|---|---|
strategy_overrides | dict[str, str] | Callable-name to strategy-name overrides. |
strategy_params | dict[str, dict[str, Any]] | Optional strategy parameters keyed by strategy name. |
default_strategy | str | Fallback strategy name. Defaults to "standard". |
Constructor¶
def __init__(
self,
strategy_overrides: dict[str, str] = dict(),
strategy_params: dict[str, dict[str, Any]] = dict(),
default_strategy: str = 'standard',
) -> NoneAttributes¶
default_strategy: strstrategy_overrides: dict[str, str]strategy_params: dict[str, dict[str, Any]]
Methods¶
get_strategy_for_gate¶
def get_strategy_for_gate(self, gate_name: str) -> strReturn the selected strategy name for a callable.
Parameters:
| Name | Type | Description |
|---|---|---|
gate_name | str | Callable name. |
Returns:
str — Explicit override or the configured default.
get_strategy_params¶
def get_strategy_params(self, strategy_name: str) -> dict[str, Any]Return parameters for one strategy.
Parameters:
| Name | Type | Description |
|---|---|---|
strategy_name | str | Strategy name. |
Returns:
dict[str, Any] — dict[str, Any]: Copy of the configured parameter mapping.
qamomile.circuit.frontend.func_to_block¶
Overview¶
| Function | Description |
|---|---|
build_param_slots | Build a ParamSlot tuple for the classical arguments of a kernel. |
create_dummy_handle | Create a dummy Handle instance based on ValueType. |
create_dummy_input | Create a dummy input based on parameter type annotation. |
create_static_binding_proxy | Create an unbound tracing proxy for a registered annotation. |
func_to_block | Convert a typed frontend function to a hierarchical block. |
get_current_tracer | |
handle_type_map | Map Handle type to ValueType. |
is_array_type | Check if type is a Vector, Matrix, or Tensor subclass. |
is_dict_type | Check if type is a Dict handle type. |
is_static_binding_annotation | Return whether an annotation denotes a registered static binding. |
is_tuple_type | Check if type is a Tuple handle type. |
trace | Context manager to set the current tracer. |
| Class | Description |
|---|---|
ArrayValue | An array of typed IR values. |
Bit | |
BitType | Type representing a classical bit. |
Block | Unified block representation for all pipeline stages. |
BlockKind | Classification of block structure for pipeline stages. |
Dict | Dict handle for qkernel functions. |
DictType | Type representing a dictionary mapping keys to values. |
DictValue | A dictionary value stored as stable ordered entries. |
Float | Floating-point handle with arithmetic operations. |
FloatType | Type representing a floating-point number. |
Observable | Handle representing a Hamiltonian observable parameter. |
ObservableType | Type representing a Hamiltonian observable parameter. |
ParamKind | Lifecycle classification for a classical kernel argument. |
ParamSlot | Metadata for a single classical kernel argument. |
QFixed | |
QInitOperation | Initialize the qubit |
Qubit | |
ReturnOperation | Explicit return operation marking the end of a block with return values. |
StaticBindingProxy | Expose a registered static object surface during unbound tracing. |
Tracer | Collects operations (and loop-rebind records) during tracing. |
Tuple | Tuple handle for qkernel functions. |
TupleType | Type representing a tuple of values. |
TupleValue | A tuple of IR values for structured data. |
UInt | Unsigned integer handle with arithmetic operations. |
UIntType | Type representing an unsigned integer. |
Value | A typed SSA value in the IR. |
ValueType | Base class for all value types in the IR. |
Constants¶
TYPE_MAPPING:dict[Any, Any]={int: UIntType, float: FloatType, bool: BitType}ValueLike:TypeAlias='Value | ArrayValue | TupleValue | DictValue'
Functions¶
build_param_slots [source]¶
def build_param_slots(
signature: inspect.Signature,
input_types: dict[str, Any],
*,
parameters: list[str] | None = None,
kwargs: dict[str, Any] | None = None,
qubit_sizes: dict[str, int] | None = None,
bind_defaults: bool,
) -> tuple[ParamSlot, ...]Build a ParamSlot tuple for the classical arguments of a kernel.
Mirrors the argument-classification logic in
qkernel_build.create_traced_block so the resulting slot list reflects
the same decisions that drive symbolic-vs-bound input creation.
Classical scalar / array arguments are always included; a Dict
argument is included only when it is a runtime parameter (its slot
carries a DictType). Pure-quantum arguments, Tuple arguments,
and compile-time-bound Dict arguments are excluded and live in
Block.input_values instead.
Parameters:
| Name | Type | Description |
|---|---|---|
signature | inspect.Signature | The kernel function’s signature. |
input_types | dict[str, Any] | Resolved frontend type annotations keyed by argument name (typically QKernel.input_types or the equivalent computed in func_to_block). |
parameters | list[str] | None | Names explicitly requested as runtime parameters via parameters=[...]. None is treated as an empty list. |
kwargs | dict[str, Any] | None | Concrete values supplied via bindings / direct kwargs. None is treated as an empty dict. |
qubit_sizes | dict[str, int] | None | Optional mapping from Vector[Qubit] parameter names to their integer sizes; these are quantum inputs and are not included in the slot list. |
bind_defaults | bool | When True, Python signature defaults are treated as COMPILE_TIME_BOUND with bound_value=default. When False (e.g., the func_to_block path that does not bake in defaults), defaulted arguments stay RUNTIME_PARAMETER and the default appears only in ParamSlot.default. |
Returns:
tuple[ParamSlot, ...] — tuple[ParamSlot, ...]: One slot per classical argument, in the
order they appear in signature.parameters.
Raises:
TypeError— If a non-static classical annotation cannot be represented by an IR parameter type.
create_dummy_handle [source]¶
def create_dummy_handle(value_type: ValueType, name: str = 'dummy', emit_init: bool = True) -> HandleCreate a dummy Handle instance based on ValueType.
Parameters:
| Name | Type | Description |
|---|---|---|
value_type | ValueType | The IR type for the value. |
name | str | Name for the value. |
emit_init | bool | If True, emit QInitOperation for qubit types (requires active tracer). |
Used for creating input parameters during tracing.
create_dummy_input [source]¶
def create_dummy_input(
param_type: Any,
name: str = 'param',
emit_init: bool = True,
*,
shape: tuple[int, ...] | None = None,
) -> HandleCreate a dummy input based on parameter type annotation.
Parameters:
| Name | Type | Description |
|---|---|---|
param_type | Any | The type annotation for the parameter. |
name | str | Name for the value. |
emit_init | bool | If True, emit QInitOperation for qubit arrays (default: True). Set to False when creating a nested Block’s internal dummy inputs, or when the dummy will receive its qubits from a caller-side callable invocation. |
shape | tuple[int, ...] | None | Optional concrete shape for array types. When provided, the dummy array’s shape Values carry compile-time constants instead of symbolic placeholders. Used by call-time sub-kernel specialization so that shape-dependent stdlib helpers (qft / iqft / qpe) resolve get_size to a concrete integer and emit the correct gate sequence. Ignored for non-array types. Default: None (symbolic shape). |
Returns:
Handle — A frontend Handle wrapping a dummy Value or ArrayValue
suitable for use as a function-parameter input during
tracing.
Raises:
TypeError— Ifparam_typeis not a supported parameter type, or if a Tuple/array annotation is missing its element type(s).NotImplementedError— Ifparam_typeis a rank>1 quantum array annotation (Matrix[Qubit]/Tensor[Qubit]). The quantum addressing path is rank-1, so a higher-rank register would silently alias distinct elements onto the same physical qubit. This path constructs the handle viaobject.__new__(bypassingArrayBase.__post_init__), so it needs its own guard.
create_static_binding_proxy [source]¶
def create_static_binding_proxy(annotation: Any, name: str) -> StaticBindingProxyCreate an unbound tracing proxy for a registered annotation.
Parameters:
| Name | Type | Description |
|---|---|---|
annotation | Any | Registered qkernel parameter annotation. |
name | str | QKernel parameter name identifying the slot. |
Returns:
StaticBindingProxy — Closed symbolic adapter surface.
Raises:
TypeError— Ifannotationis not registered.
func_to_block [source]¶
def func_to_block(func: Callable) -> BlockConvert a typed frontend function to a hierarchical block.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable | Typed frontend function to trace. Registered static binding annotations are represented by typed proxy slots. |
Returns:
Block — Hierarchical trace containing ordinary inputs and any deferred
static binding slots.
Raises:
TypeError— If an input or return annotation is missing or unsupported, a static binding parameter declares a default, or the traced return value does not match its annotation.
Example:
def my_func(a: UInt, b: UInt) -> tuple[UInt]:
c = a + b
return (c, )
block = func_to_block(my_func)get_current_tracer [source]¶
def get_current_tracer() -> Tracerhandle_type_map [source]¶
def handle_type_map(handle_type: type[Handle] | type) -> ValueTypeMap Handle type to ValueType.
is_array_type [source]¶
def is_array_type(t: Any) -> boolCheck if type is a Vector, Matrix, or Tensor subclass.
is_dict_type [source]¶
def is_dict_type(t: Any) -> boolCheck if type is a Dict handle type.
is_static_binding_annotation [source]¶
def is_static_binding_annotation(annotation: Any) -> boolReturn whether an annotation denotes a registered static binding.
Parameters:
| Name | Type | Description |
|---|---|---|
annotation | Any | Resolved qkernel parameter annotation. |
Returns:
bool — Whether the annotation is registered.
is_tuple_type [source]¶
def is_tuple_type(t: Any) -> boolCheck if type is a Tuple handle type.
trace [source]¶
def trace(tracer: Tracer | None = None) -> Generator[Tracer, None, None]Context manager to set the current tracer.
Classes¶
ArrayValue [source]¶
class ArrayValue(Value[T])An array of typed IR values.
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]Bit [source]¶
class Bit(Handle)Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: bool = False,
) -> NoneAttributes¶
init_value: bool
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
Dict [source]¶
class Dict(Handle, Generic[K, V])Dict handle for qkernel functions.
Represents a dictionary mapping keys to values, commonly used
for Ising coefficients like {(i, j): Jij}. Supports iteration via
items() and subscript lookup (d[key]), including indexing
one dict with the iteration keys of another.
Example:
@qmc.qkernel
def ising_cost(
q: qmc.Vector[qmc.Qubit],
ising: qmc.Dict[qmc.Tuple[qmc.UInt, qmc.UInt], qmc.Float],
gammas: qmc.Dict[qmc.Tuple[qmc.UInt, qmc.UInt], qmc.Float],
) -> qmc.Vector[qmc.Qubit]:
for (i, j), Jij in qmc.items(ising):
q[i], q[j] = qmc.rzz(q[i], q[j], Jij * gammas[(i, j)])
return qConstructor¶
def __init__(
self,
value: DictValue,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_entries: list[tuple[Handle, Handle]] = list(),
_size: UInt | None = None,
_key_type: type | None = None,
_value_type: type | None = None,
_runtime_parameter: bool = False,
) -> NoneAttributes¶
size: UInt Return the number of entries as a UInt handle.value: DictValue
Methods¶
items¶
def items(self) -> DictItemsIterator[K, V]Return an iterator over (key, value) pairs.
DictType [source]¶
class DictType(ValueType)Type representing a dictionary mapping keys to values.
Unlike simple types, DictType stores the key and value types, so equality and hashing depend on those types. When key_type and value_type are None, represents a generic Dict type.
Quantum/classical classification is derived from key/value types.
Constructor¶
def __init__(
self,
key_type: ValueType | None = None,
value_type: ValueType | None = None,
) -> 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) -> DictValueFloat [source]¶
class Float(ArithmeticMixin, Handle)Floating-point handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: float = 0.0,
) -> NoneAttributes¶
init_value: float
FloatType [source]¶
class FloatType(ClassicalTypeMixin, ValueType)Type representing a floating-point number.
Observable [source]¶
class Observable(Handle)Handle representing a Hamiltonian observable parameter.
This is a reference type - the actual qamomile.observable.Hamiltonian is provided via bindings during transpilation. It cannot be constructed or manipulated within qkernels.
Example:
import qamomile.circuit as qm
import qamomile.observable as qm_o
# Build Hamiltonian in Python
H = qm_o.Z(0) * qm_o.Z(1) + 0.5 * qm_o.X(0)
@qm.qkernel
def vqe(q: qm.Vector[qm.Qubit], H: qm.Observable) -> qm.Float:
# Use Hamiltonian from bindings
return qm.expval(q, H)
# Pass via bindings
executable = transpiler.transpile(vqe, bindings={"H": H})Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneObservableType [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) -> NoneParamKind [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’
QFixed [source]¶
class QFixed(Handle)Constructor¶
def __init__(
self,
value: Value[QFixedType],
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneAttributes¶
value: Value[QFixedType]
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
Qubit [source]¶
class Qubit(Handle)Constructor¶
def __init__(
self,
value: Value[QubitType],
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneAttributes¶
value: Value[QubitType]
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.
StaticBindingProxy [source]¶
class StaticBindingProxyExpose a registered static object surface during unbound tracing.
Parameters:
| Name | Type | Description |
|---|---|---|
spec | StaticBindingSpec | Registered object contract. |
name | str | QKernel parameter name identifying the binding slot. |
Constructor¶
def __init__(self, spec: StaticBindingSpec, name: str) -> NoneCreate symbolic fields and deferred callable members.
Parameters:
| Name | Type | Description |
|---|---|---|
spec | StaticBindingSpec | Registered object contract. |
name | str | QKernel parameter name identifying the binding slot. |
Attributes¶
slot: StaticBindingSlot Return the IR manifest entry owned by this proxy.
Tracer [source]¶
class TracerCollects operations (and loop-rebind records) during tracing.
Constructor¶
def __init__(
self,
_operations: list[Operation] = list(),
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_entries: dict[str, Any] = dict(),
loop_region_results: dict[str, Any] = dict(),
) -> NoneAttributes¶
loop_carried_rebinds: tuple[LoopCarriedRebind, ...]loop_region_results: dict[str, Any]operations: list[Operation]region_entries: dict[str, Any]
Methods¶
add_operation¶
def add_operation(self, op) -> NoneTuple [source]¶
class Tuple(Handle, Generic[K, V])Tuple handle for qkernel functions.
Represents a tuple of values, commonly used for multi-index keys like (i, j) in Ising models.
Example:
@qmc.qkernel
def my_kernel(idx: qmc.Tuple[qmc.UInt, qmc.UInt]) -> qmc.UInt:
i, j = idx
return i + jConstructor¶
def __init__(
self,
value: TupleValue,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_elements: tuple[Handle, ...] = tuple(),
) -> NoneAttributes¶
value: TupleValue
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) -> TupleValueUInt [source]¶
class UInt(ArithmeticMixin, Handle)Unsigned integer handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: int = 0,
) -> NoneAttributes¶
init_value: int
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.
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.frontend.handle¶
Handle type system: user-facing typed wrappers around IR Values.
Handles are what qkernel code manipulates: quantum primitives (Qubit,
QFixed), classical scalars (UInt, Float, Bit), arrays
(Vector, VectorView, Matrix, Tensor), structural
containers (Tuple, Dict), and Observable (Hamiltonian). Each
handle wraps one IR Value and forwards Python operators (arithmetic,
comparison, indexing) to tracer-emitted IR operations, so user code
reads as ordinary Python while building IR.
Design constraints:
Quantum handles are linear: operations consume them and return fresh handles wrapping a new-version
Value; reusing a consumed handle raisesQubitConsumedError. Classical handles may be read freely.Classical arithmetic folds eagerly when both operands are known compile-time constants; otherwise a symbolic
BinOp/CompOpis traced forpartial_evalto resolve later.Handles are trace-time objects only — they never survive into the transpiled program and carry no backend or layout information. The IR
Value(with its type and metadata) is the durable representation.
Overview¶
| Function | Description |
|---|---|
get_size | Return the size of a Vector handle as a Python integer. |
| Class | Description |
|---|---|
Bit | |
Dict | Dict handle for qkernel functions. |
Float | Floating-point handle with arithmetic operations. |
Handle | |
Matrix | 2-dimensional array type for classical element types. |
Observable | Handle representing a Hamiltonian observable parameter. |
QFixed | |
Qubit | |
Tensor | N-dimensional array type (3 or more dimensions) for classical element types. |
Tuple | Tuple handle for qkernel functions. |
UInt | Unsigned integer handle with arithmetic operations. |
Vector | 1-dimensional array type. |
VectorView | Strided view over a parent Vector, backed by a sliced ArrayValue. |
Functions¶
get_size [source]¶
def get_size(arr: Vector[_H]) -> intReturn the size of a Vector handle as a Python integer.
Resolves the leading axis of arr.shape through two forms a
Vector shape entry can take:
A plain Python
int(built-in bound shape; this is what you get fromqmc.qubit_array(N, ...)for literalN).A
UInthandle whose underlyingValuecarries a compile-time constant (set byuint(literal),_create_bound_input, or partial evaluation).
A UInt handle whose underlying Value is not a constant is
treated as an unresolved symbolic dimension and raises
ValueError even when the handle has the dataclass-default
init_value=0. Falling back to init_value for that case
would silently turn a runtime-symbolic Vector[Float] parameter
into a “size 0” array, hiding programming errors. Callers that
need to handle symbolic shapes (e.g., to emit a deferred callable
when the size is unknown) must catch the ValueError themselves.
Parameters:
| Name | Type | Description |
|---|---|---|
arr | Vector[Handle] | Vector handle whose first axis size is requested. |
Returns:
int — The first-axis size as a plain Python int.
Raises:
TypeError— If arr is not a 1-DVectorhandle (Vectoror itsVectorViewsubclass) — e.g., a scalarQubitwas passed where aVectoris required, a higher-rankMatrix/Tensorwas passed (this helper only resolves a 1-D first-axis size), or an unrelatedshape-bearing object such as a numpy array. This is a clearer signal than the bareAttributeErrorthatarr.shapewould otherwise raise, and it guards the stdlib / composite callers that resolve a register size through this helper.ValueError— If the shape cannot be resolved to a concrete integer — e.g., the Vector is a runtime-parametric handle without compile-time bindings, or carries aUIntdimension whose underlyingValuehas not been promoted to a constant.
Classes¶
Bit [source]¶
class Bit(Handle)Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: bool = False,
) -> NoneAttributes¶
init_value: bool
Dict [source]¶
class Dict(Handle, Generic[K, V])Dict handle for qkernel functions.
Represents a dictionary mapping keys to values, commonly used
for Ising coefficients like {(i, j): Jij}. Supports iteration via
items() and subscript lookup (d[key]), including indexing
one dict with the iteration keys of another.
Example:
@qmc.qkernel
def ising_cost(
q: qmc.Vector[qmc.Qubit],
ising: qmc.Dict[qmc.Tuple[qmc.UInt, qmc.UInt], qmc.Float],
gammas: qmc.Dict[qmc.Tuple[qmc.UInt, qmc.UInt], qmc.Float],
) -> qmc.Vector[qmc.Qubit]:
for (i, j), Jij in qmc.items(ising):
q[i], q[j] = qmc.rzz(q[i], q[j], Jij * gammas[(i, j)])
return qConstructor¶
def __init__(
self,
value: DictValue,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_entries: list[tuple[Handle, Handle]] = list(),
_size: UInt | None = None,
_key_type: type | None = None,
_value_type: type | None = None,
_runtime_parameter: bool = False,
) -> NoneAttributes¶
size: UInt Return the number of entries as a UInt handle.value: DictValue
Methods¶
items¶
def items(self) -> DictItemsIterator[K, V]Return an iterator over (key, value) pairs.
Float [source]¶
class Float(ArithmeticMixin, Handle)Floating-point handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: float = 0.0,
) -> NoneAttributes¶
init_value: float
Handle [source]¶
class Handle(abc.ABC)Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneAttributes¶
id: strindices: tuple[‘UInt’, ...]name: str | Noneparent: ‘ArrayBase | None’value: Value
Methods¶
consume¶
def consume(self, operation_name: str = 'unknown') -> SelfMark this handle as consumed and return a fresh handle.
Records the user-code source location (file:line) of the
consuming call so a later affine violation can point at both the
first-use and the reuse site.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the operation consuming this handle, used for error messages. Defaults to "unknown". |
Returns:
typing.Self — typing.Self: New handle pointing to the same underlying value.
Raises:
QubitConsumedError— If this quantum handle was already consumed.
validate_consumable¶
def validate_consumable(self, operation_name: str = 'unknown') -> NoneValidate a consume without changing affine ownership state.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the prospective consuming operation, used in diagnostics. Defaults to "unknown". |
Raises:
QubitConsumedError— If this quantum handle was already consumed.
Matrix [source]¶
class Matrix(ArrayBase[T])2-dimensional array type for classical element types.
Quantum element types are rejected: constructing a
Matrix[Qubit] raises NotImplementedError (see
ArrayBase.__post_init__) because the quantum addressing path is
rank-1. Use a 1-D Vector[Qubit] with explicit index arithmetic
instead.
Example:
import qamomile as qm
# Create a 3x4 matrix of floats
matrix: qm.Matrix[qm.Float] = qm.Matrix(shape=(3, 4))
# Access elements (always requires 2 indices)
x = matrix[0, 1]
matrix[0, 1] = xConstructor¶
def __init__(
self,
value: ArrayValue = None,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_shape: tuple[int | UInt, int | UInt] = (0, 0),
_borrowed_indices: dict[tuple[str, ...], 'tuple[UInt, ...] | Handle'] = dict(),
) -> NoneAttributes¶
value: ArrayValue
Observable [source]¶
class Observable(Handle)Handle representing a Hamiltonian observable parameter.
This is a reference type - the actual qamomile.observable.Hamiltonian is provided via bindings during transpilation. It cannot be constructed or manipulated within qkernels.
Example:
import qamomile.circuit as qm
import qamomile.observable as qm_o
# Build Hamiltonian in Python
H = qm_o.Z(0) * qm_o.Z(1) + 0.5 * qm_o.X(0)
@qm.qkernel
def vqe(q: qm.Vector[qm.Qubit], H: qm.Observable) -> qm.Float:
# Use Hamiltonian from bindings
return qm.expval(q, H)
# Pass via bindings
executable = transpiler.transpile(vqe, bindings={"H": H})Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneQFixed [source]¶
class QFixed(Handle)Constructor¶
def __init__(
self,
value: Value[QFixedType],
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneAttributes¶
value: Value[QFixedType]
Qubit [source]¶
class Qubit(Handle)Constructor¶
def __init__(
self,
value: Value[QubitType],
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneAttributes¶
value: Value[QubitType]
Tensor [source]¶
class Tensor(ArrayBase[T])N-dimensional array type (3 or more dimensions) for classical element types.
Quantum element types are rejected: constructing a
Tensor[Qubit] raises NotImplementedError (see
ArrayBase.__post_init__) because the quantum addressing path is
rank-1. Use a 1-D Vector[Qubit] with explicit index arithmetic
instead.
Example:
import qamomile as qm
# Create a 2x3x4 tensor of floats
tensor: qm.Tensor[qm.Float] = qm.Tensor(shape=(2, 3, 4))
# Access elements (requires all indices)
x = tensor[0, 1, 2]
tensor[0, 1, 2] = xConstructor¶
def __init__(
self,
value: ArrayValue = None,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_shape: tuple[int | UInt, ...] = tuple(),
_borrowed_indices: dict[tuple[str, ...], 'tuple[UInt, ...] | Handle'] = dict(),
) -> NoneAttributes¶
value: ArrayValue
Tuple [source]¶
class Tuple(Handle, Generic[K, V])Tuple handle for qkernel functions.
Represents a tuple of values, commonly used for multi-index keys like (i, j) in Ising models.
Example:
@qmc.qkernel
def my_kernel(idx: qmc.Tuple[qmc.UInt, qmc.UInt]) -> qmc.UInt:
i, j = idx
return i + jConstructor¶
def __init__(
self,
value: TupleValue,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_elements: tuple[Handle, ...] = tuple(),
) -> NoneAttributes¶
value: TupleValue
UInt [source]¶
class UInt(ArithmeticMixin, Handle)Unsigned integer handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: int = 0,
) -> NoneAttributes¶
init_value: int
Vector [source]¶
class Vector(ArrayBase[T])1-dimensional array type.
Example:
import qamomile.circuit as qmc
# Create a vector of 3 qubits
qubits: qmc.Vector[qmc.Qubit] = qmc.qubit_array(3, name="qubits")
# Access elements
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0
# Apply H gate to all qubits (CORRECT)
n = qubits.shape[0]
for i in qmc.range(n):
qubits[i] = qmc.h(qubits[i])
# Slicing returns a VectorView over a subset of the parent vector.
# The view shares borrow tracking with the parent; element access
# on the view transparently indexes the parent.
evens = qubits[0::2]
for i in qmc.range(evens.shape[0]):
evens[i] = qmc.h(evens[i])Constructor¶
def __init__(
self,
value: ArrayValue = None,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_shape: tuple[int | UInt] = (0,),
_borrowed_indices: dict[tuple[str, ...], 'tuple[UInt, ...] | Handle'] = dict(),
) -> NoneAttributes¶
value: ArrayValue
VectorView [source]¶
class VectorView(Vector[T])Strided view over a parent Vector, backed by a sliced ArrayValue.
A VectorView is produced by slicing a Vector (q[1::2],
q[a:b], etc.). It is a thin Vector subclass whose value
is a fresh ArrayValue with slice_of / slice_start /
slice_step metadata pointing back to the parent’s ArrayValue.
Element accesses go through Vector._get_element unchanged — the
IR element carries parent_array = sliced_av, and the emit-time
resolver walks the slice_of chain to produce the physical qubit
index. No affine translation happens in the view itself.
Because the sliced ArrayValue is a first-class IR Value,
the view can be passed as an operand of an inline callable invocation
to another qkernel without the inline-trace special-case path that
earlier iterations required. Passing views through
expval / measure likewise operates on the sliced qubit
subset, not the root parent as a whole.
Linearity:
Slicing bulk-borrows the covered parent slots whenever
start, step and length are compile-time int
constants. While the view is live, accessing the corresponding
parent slot directly (q[0] after evens = q[0::2]) raises
QubitConsumedError. Under the strict-return policy the
view’s ownership is cleared only by two operations:
slice-assigning it back into the parent (
parent[a:b:c] = view) — this is the only path that fully releases the borrow without destroying the qubits;destructively consuming it (
measure(view)/cast(view, ...)/expval(view, H)) — the physical slots become consumed markers, no return needed.
Every other consume (broadcast gates h(view),
pauli_evolve(view, H, gamma), sub-kernel calls
f(view), controlled-U index_spec) only transfers
ownership to a freshly-wrapped VectorView and that new
view still must be returned via slice assignment. A view
left bulk-borrowing at the parent’s consume point raises
UnreturnedBorrowError.
Symbolic slices (q[lo:hi] with lo/hi UInt) cannot
enumerate their covered slots at trace time and therefore skip
the bulk-borrow here; SliceBorrowCheckPass picks them up
post-fold after bindings resolve the bounds to concrete values.
Example:
@qmc.qkernel
def alternating_h(q: qmc.Vector[qmc.Qubit]) -> qmc.Vector[qmc.Qubit]:
evens = q[0::2]
for i in qmc.range(evens.shape[0]):
evens[i] = qmc.h(evens[i])
q[0::2] = evens # explicit return before the parent is used
return qMethods¶
consume¶
def consume(self, operation_name: str = 'unknown') -> SelfConsume the view and release its parent slice-borrows.
Validates that every view-local borrow has been returned,
then dispatches on operation_name to keep the parent’s
slice-borrow record consistent with the new strict-return
semantics:
Destructive (
measure/cast): leaveselfparked in the parent’s borrow table as a destroyed-slot breadcrumb.super().consume()flipsself._consumed = Trueandself._consumed_by = operation_name, which is what :func:_is_destroyed_slot_ownerreads to reject subsequent access at the same slot.Releasing (
slice assignment): drop every parent entry thatselfcurrently owns. The caller (the slice- assignment frontend path) also emits aReleaseSliceViewOperationso the IR-level checker sees the release. This branch is reserved for explicit borrow- return paths.Transfer (every other op — broadcast gates, rotation, phase, ControlledU, sub-kernel call argument consumption, etc.): rebind the parent’s borrow entry from
selfto the new view handle returned here. The new view inheritsself._slice_covered_indicesso it can be slice-assigned back to the parent later — strict-return requires that eventualparent[a:b:c] = new_view.
Operations that produce a fresh sliced ArrayValue (e.g.
:func:qamomile.circuit.frontend.operation.pauli_evolve.pauli_evolve,
:class:QKernel.__call__ for callees that return a sliced
array) cannot simply use the auto-returned new_view
because the new view they build wraps a different Value
than this consume’s return. Those op implementations call
:meth:_transfer_borrow_to after building their result so
the parent’s borrow table tracks the right handle.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the operation consuming this view (used in error messages and for dispatch). |
Returns:
typing.Self — A fresh view handle with the same backing state; under
typing.Self — transfer the parent’s borrow table now points at this
typing.Self — handle, under release / destruction the parent’s record
typing.Self — for the covered slots is finalised.
Raises:
QubitConsumedError— If any covered slot was already destroyed by a prior destructive consume on an overlapping element or view.
qamomile.circuit.frontend.handle.array¶
Overview¶
| Function | Description |
|---|---|
get_current_tracer | |
is_plain_int | Return True if value is a Python int but not a bool. |
| Class | Description |
|---|---|
AffineTypeError | Base class for affine type violations. |
ArrayBase | Base class for array types (Vector, Matrix, Tensor). |
ArrayValue | An array of typed IR values. |
BinOp | Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN). |
BinOpKind | |
Bit | |
BitType | Type representing a classical bit. |
CInitOperation | Initialize the classical values (const, arguments etc) |
CompOp | Comparison operation (EQ, NEQ, LT, LE, GT, GE). |
ConsumeMode | Classify how a VectorView.consume call resolves slice borrows. |
Float | Floating-point handle with arithmetic operations. |
FloatType | Type representing a floating-point number. |
Handle | |
IfOperation | Represents an if-else conditional operation. |
Matrix | 2-dimensional array type for classical element types. |
QInitOperation | Initialize the qubit |
Qubit | |
QubitBorrowConflictError | Qubit slot inaccessible because another live handle borrows it. |
QubitConsumedError | Qubit handle used after being consumed by a previous operation. |
QubitType | Type representing a quantum bit (qubit). |
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. |
SliceArrayOperation | Construct a strided view of an ArrayValue. |
StoreArrayElementOperation | Store a classical scalar into one element of a classical array. |
Tensor | N-dimensional array type (3 or more dimensions) for classical element types. |
UInt | Unsigned integer handle with arithmetic operations. |
UIntType | Type representing an unsigned integer. |
UnreturnedBorrowError | Borrowed array element not returned before array use. |
Value | A typed SSA value in the IR. |
Vector | 1-dimensional array type. |
VectorView | Strided view over a parent Vector, backed by a sliced ArrayValue. |
Functions¶
get_current_tracer [source]¶
def get_current_tracer() -> Traceris_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¶
AffineTypeError [source]¶
class AffineTypeError(QamomileCompileError)Base class for affine type violations.
Affine types enforce that quantum resources (qubits) are used at most once. This prevents common errors such as reusing a consumed qubit or aliasing.
Constructor¶
def __init__(
self,
message: str,
handle_name: str | None = None,
operation_name: str | None = None,
first_use_location: str | None = None,
)Initialize an affine-resource violation diagnosis.
Parameters:
| Name | Type | Description |
|---|---|---|
message | str | Human-readable affine-type failure. |
handle_name | str | None | Consumed or borrowed handle. Defaults to None. |
operation_name | str | None | Operation reporting the violation. Defaults to None. |
first_use_location | str | None | Original consuming use location. Defaults to None. |
Attributes¶
first_use_locationhandle_nameoperation_name
ArrayBase [source]¶
class ArrayBase(Handle, Generic[T])Base class for array types (Vector, Matrix, Tensor).
Provides common functionality for array indexing and element access.
Constructor¶
def __init__(
self,
value: ArrayValue,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_shape: tuple[int | UInt, ...] = tuple(),
_borrowed_indices: dict[tuple[str, ...], 'tuple[UInt, ...] | Handle'] = dict(),
) -> NoneAttributes¶
element_type: Type[T]shape: tuple[int | UInt, ...] Return the shape of the array.value: ArrayValue
Methods¶
consume¶
def consume(self, operation_name: str = 'unknown') -> SelfConsume the array after validating its affine ownership state.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the consuming operation. Defaults to "unknown". |
Returns:
typing.Self — typing.Self: Fresh handle carrying the consumed array value.
Raises:
QubitConsumedError— If this handle or a covered slot was consumed.UnreturnedBorrowError— If a live element or slice borrow remains.
create¶
@classmethod
def create(
cls,
shape: tuple[int | UInt, ...],
name: str,
el_type: Type[T],
) -> 'ArrayBase[T]'Create an ArrayValue for the given shape and name.
validate_all_returned¶
def validate_all_returned(self) -> NoneValidate all borrowed elements have been returned.
Strict-return policy: an active slice view that is still
registered as the owner of any parent slot is treated as an
unreturned borrow even if the view itself has no outstanding
element borrows. The caller must perform an explicit slice
assignment (parent[a:b:c] = view) to release the view’s
bulk-borrow before consuming the parent. Destructively consumed
scalar or view owners (parked in the dict with _consumed set and
_consumed_by classified as :attr:ConsumeMode.DESTRUCTIVE)
record physically-destroyed slots and are not outstanding borrows; they survive
end-of-block so a later whole-array consume can detect and
reject the destroyed slots.
Raises:
UnreturnedBorrowError— If any elements are still borrowed, either directly or by a slice view that has not been explicitly returned via slice assignment.
validate_consumable¶
def validate_consumable(self, operation_name: str = 'unknown') -> NoneValidate an array consume without changing ownership state.
For quantum arrays, all borrowed elements must be returned before the array can be consumed. This ensures that no unreturned borrows are silently discarded by operations like qkernel calls or controlled gates.
When any slot of the array has already been physically consumed
by an earlier destructive element or view operation
(measure(q[0]) or measure(q[1::2]) followed by
measure(q)), this raises QubitConsumedError rather than
silently re-consuming those slots.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the prospective consuming operation. Defaults to "unknown". |
Raises:
QubitConsumedError— If this handle or any covered slot was already consumed.UnreturnedBorrowError— If a live element or slice borrow remains.
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
Bit [source]¶
class Bit(Handle)Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: bool = False,
) -> NoneAttributes¶
init_value: bool
BitType [source]¶
class BitType(ClassicalTypeMixin, ValueType)Type representing a classical bit.
CInitOperation [source]¶
class CInitOperation(Operation)Initialize the classical values (const, arguments etc)
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
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
ConsumeMode [source]¶
class ConsumeMode(enum.Enum)Classify how a VectorView.consume call resolves slice borrows.
ArrayBase.consume and VectorView.consume accept a free-form
operation_name string used both for error messages and for
dispatching how the parent’s bulk-borrow table is updated. The
string itself is purely cosmetic; the dispatch logic only cares
about which of three resolution modes applies, captured by this
enum:
DESTRUCTIVE: the consume physically destroys the qubits (measure/cast). The consumed view stays parked in the parent’s borrow table so any later access to the same slot is surfaced as a use-after-destroy.RELEASING: the consume returns the borrow to the parent cleanly (slice assignment) — the entries are dropped and the parent regains free access to the covered slots.TRANSFER: the consume hands ownership forward to a freshly builtVectorView(broadcast gates,pauli_evolve,QKernel.__call__, controlled-Uindex_spec). The covered slots stay borrowed under the new handle.
Attributes¶
DESTRUCTIVERELEASINGTRANSFER
Float [source]¶
class Float(ArithmeticMixin, Handle)Floating-point handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: float = 0.0,
) -> NoneAttributes¶
init_value: float
FloatType [source]¶
class FloatType(ClassicalTypeMixin, ValueType)Type representing a floating-point number.
Handle [source]¶
class Handle(abc.ABC)Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneAttributes¶
id: strindices: tuple[‘UInt’, ...]name: str | Noneparent: ‘ArrayBase | None’value: Value
Methods¶
consume¶
def consume(self, operation_name: str = 'unknown') -> SelfMark this handle as consumed and return a fresh handle.
Records the user-code source location (file:line) of the
consuming call so a later affine violation can point at both the
first-use and the reuse site.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the operation consuming this handle, used for error messages. Defaults to "unknown". |
Returns:
typing.Self — typing.Self: New handle pointing to the same underlying value.
Raises:
QubitConsumedError— If this quantum handle was already consumed.
validate_consumable¶
def validate_consumable(self, operation_name: str = 'unknown') -> NoneValidate a consume without changing affine ownership state.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the prospective consuming operation, used in diagnostics. Defaults to "unknown". |
Raises:
QubitConsumedError— If this quantum handle was already consumed.
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.
Matrix [source]¶
class Matrix(ArrayBase[T])2-dimensional array type for classical element types.
Quantum element types are rejected: constructing a
Matrix[Qubit] raises NotImplementedError (see
ArrayBase.__post_init__) because the quantum addressing path is
rank-1. Use a 1-D Vector[Qubit] with explicit index arithmetic
instead.
Example:
import qamomile as qm
# Create a 3x4 matrix of floats
matrix: qm.Matrix[qm.Float] = qm.Matrix(shape=(3, 4))
# Access elements (always requires 2 indices)
x = matrix[0, 1]
matrix[0, 1] = xConstructor¶
def __init__(
self,
value: ArrayValue = None,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_shape: tuple[int | UInt, int | UInt] = (0, 0),
_borrowed_indices: dict[tuple[str, ...], 'tuple[UInt, ...] | Handle'] = dict(),
) -> NoneAttributes¶
value: ArrayValue
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
Qubit [source]¶
class Qubit(Handle)Constructor¶
def __init__(
self,
value: Value[QubitType],
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneAttributes¶
value: Value[QubitType]
QubitBorrowConflictError [source]¶
class QubitBorrowConflictError(AffineTypeError)Qubit slot inaccessible because another live handle borrows it.
Raised when a qubit slot cannot be accessed because another live
handle currently borrows it — a slice view that has not been
returned, an outstanding element borrow, or any future borrow form
Qamomile may add. The same error is used whether the conflict is
discovered while tracing concrete indices or after symbolic slice
bounds are resolved during transpilation. Unlike
:class:QubitConsumedError, the slot is not destroyed: releasing the
borrowing handle (slice assignment, element write-back, etc.) restores
access.
Example of incorrect code (overlapping slice views)::
a = q[0:3] # q[0..2] now borrowed by ``a``
b = q[2:5] # ERROR: q[2] is still borrowed by ``a``Correct code::
a = q[0:3]
q[0:3] = a # return ``a`` first
b = q[2:5] # now safeExample of incorrect code (element borrow not returned before borrowing a neighbour)::
q0 = qubits[0]
q0 = qmc.h(q0)
q1 = qubits[1] # ERROR: q0 is still borrowedCorrect code::
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0 # return the element first
q1 = qubits[1] # now safeQubitConsumedError [source]¶
class QubitConsumedError(AffineTypeError)Qubit handle used after being consumed by a previous operation.
Each qubit handle can only be used once. After a gate operation, you must reassign the result to use the new handle.
Example of incorrect code:
q1 = qm.h(q) q2 = qm.x(q) # ERROR: q was already consumed by h()
Correct code:
q = qm.h(q) # Reassign to capture new handle q = qm.x(q) # Use the reassigned handle
QubitType [source]¶
class QubitType(QuantumTypeMixin, ValueType)Type representing a quantum bit (qubit).
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.
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.
Tensor [source]¶
class Tensor(ArrayBase[T])N-dimensional array type (3 or more dimensions) for classical element types.
Quantum element types are rejected: constructing a
Tensor[Qubit] raises NotImplementedError (see
ArrayBase.__post_init__) because the quantum addressing path is
rank-1. Use a 1-D Vector[Qubit] with explicit index arithmetic
instead.
Example:
import qamomile as qm
# Create a 2x3x4 tensor of floats
tensor: qm.Tensor[qm.Float] = qm.Tensor(shape=(2, 3, 4))
# Access elements (requires all indices)
x = tensor[0, 1, 2]
tensor[0, 1, 2] = xConstructor¶
def __init__(
self,
value: ArrayValue = None,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_shape: tuple[int | UInt, ...] = tuple(),
_borrowed_indices: dict[tuple[str, ...], 'tuple[UInt, ...] | Handle'] = dict(),
) -> NoneAttributes¶
value: ArrayValue
UInt [source]¶
class UInt(ArithmeticMixin, Handle)Unsigned integer handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: int = 0,
) -> NoneAttributes¶
init_value: int
UIntType [source]¶
class UIntType(ClassicalTypeMixin, ValueType)Type representing an unsigned integer.
UnreturnedBorrowError [source]¶
class UnreturnedBorrowError(AffineTypeError)Borrowed array element not returned before array use.
When you borrow an element from a qubit array, you must return it (write it back) before using other elements or the array itself.
Example of incorrect code:
q0 = qubits[0] q0 = qmc.h(q0) q1 = qubits[1] # ERROR: q0 not returned yet
Correct code:
q0 = qubits[0] q0 = qmc.h(q0) qubits[0] = q0 # Return the borrowed element q1 = qubits[1] # Now safe to borrow another
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.
Vector [source]¶
class Vector(ArrayBase[T])1-dimensional array type.
Example:
import qamomile.circuit as qmc
# Create a vector of 3 qubits
qubits: qmc.Vector[qmc.Qubit] = qmc.qubit_array(3, name="qubits")
# Access elements
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0
# Apply H gate to all qubits (CORRECT)
n = qubits.shape[0]
for i in qmc.range(n):
qubits[i] = qmc.h(qubits[i])
# Slicing returns a VectorView over a subset of the parent vector.
# The view shares borrow tracking with the parent; element access
# on the view transparently indexes the parent.
evens = qubits[0::2]
for i in qmc.range(evens.shape[0]):
evens[i] = qmc.h(evens[i])Constructor¶
def __init__(
self,
value: ArrayValue = None,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_shape: tuple[int | UInt] = (0,),
_borrowed_indices: dict[tuple[str, ...], 'tuple[UInt, ...] | Handle'] = dict(),
) -> NoneAttributes¶
value: ArrayValue
VectorView [source]¶
class VectorView(Vector[T])Strided view over a parent Vector, backed by a sliced ArrayValue.
A VectorView is produced by slicing a Vector (q[1::2],
q[a:b], etc.). It is a thin Vector subclass whose value
is a fresh ArrayValue with slice_of / slice_start /
slice_step metadata pointing back to the parent’s ArrayValue.
Element accesses go through Vector._get_element unchanged — the
IR element carries parent_array = sliced_av, and the emit-time
resolver walks the slice_of chain to produce the physical qubit
index. No affine translation happens in the view itself.
Because the sliced ArrayValue is a first-class IR Value,
the view can be passed as an operand of an inline callable invocation
to another qkernel without the inline-trace special-case path that
earlier iterations required. Passing views through
expval / measure likewise operates on the sliced qubit
subset, not the root parent as a whole.
Linearity:
Slicing bulk-borrows the covered parent slots whenever
start, step and length are compile-time int
constants. While the view is live, accessing the corresponding
parent slot directly (q[0] after evens = q[0::2]) raises
QubitConsumedError. Under the strict-return policy the
view’s ownership is cleared only by two operations:
slice-assigning it back into the parent (
parent[a:b:c] = view) — this is the only path that fully releases the borrow without destroying the qubits;destructively consuming it (
measure(view)/cast(view, ...)/expval(view, H)) — the physical slots become consumed markers, no return needed.
Every other consume (broadcast gates h(view),
pauli_evolve(view, H, gamma), sub-kernel calls
f(view), controlled-U index_spec) only transfers
ownership to a freshly-wrapped VectorView and that new
view still must be returned via slice assignment. A view
left bulk-borrowing at the parent’s consume point raises
UnreturnedBorrowError.
Symbolic slices (q[lo:hi] with lo/hi UInt) cannot
enumerate their covered slots at trace time and therefore skip
the bulk-borrow here; SliceBorrowCheckPass picks them up
post-fold after bindings resolve the bounds to concrete values.
Example:
@qmc.qkernel
def alternating_h(q: qmc.Vector[qmc.Qubit]) -> qmc.Vector[qmc.Qubit]:
evens = q[0::2]
for i in qmc.range(evens.shape[0]):
evens[i] = qmc.h(evens[i])
q[0::2] = evens # explicit return before the parent is used
return qMethods¶
consume¶
def consume(self, operation_name: str = 'unknown') -> SelfConsume the view and release its parent slice-borrows.
Validates that every view-local borrow has been returned,
then dispatches on operation_name to keep the parent’s
slice-borrow record consistent with the new strict-return
semantics:
Destructive (
measure/cast): leaveselfparked in the parent’s borrow table as a destroyed-slot breadcrumb.super().consume()flipsself._consumed = Trueandself._consumed_by = operation_name, which is what :func:_is_destroyed_slot_ownerreads to reject subsequent access at the same slot.Releasing (
slice assignment): drop every parent entry thatselfcurrently owns. The caller (the slice- assignment frontend path) also emits aReleaseSliceViewOperationso the IR-level checker sees the release. This branch is reserved for explicit borrow- return paths.Transfer (every other op — broadcast gates, rotation, phase, ControlledU, sub-kernel call argument consumption, etc.): rebind the parent’s borrow entry from
selfto the new view handle returned here. The new view inheritsself._slice_covered_indicesso it can be slice-assigned back to the parent later — strict-return requires that eventualparent[a:b:c] = new_view.
Operations that produce a fresh sliced ArrayValue (e.g.
:func:qamomile.circuit.frontend.operation.pauli_evolve.pauli_evolve,
:class:QKernel.__call__ for callees that return a sliced
array) cannot simply use the auto-returned new_view
because the new view they build wraps a different Value
than this consume’s return. Those op implementations call
:meth:_transfer_borrow_to after building their result so
the parent’s borrow table tracks the right handle.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the operation consuming this view (used in error messages and for dispatch). |
Returns:
typing.Self — A fresh view handle with the same backing state; under
typing.Self — transfer the parent’s borrow table now points at this
typing.Self — handle, under release / destruction the parent’s record
typing.Self — for the covered slots is finalised.
Raises:
QubitConsumedError— If any covered slot was already destroyed by a prior destructive consume on an overlapping element or view.
qamomile.circuit.frontend.handle.containers¶
Container types for qkernel: Tuple and Dict handles.
Overview¶
| Class | Description |
|---|---|
Dict | Dict handle for qkernel functions. |
DictItemsIterator | Iterator for Dict.items() that yields (key, value) pairs. |
DictValue | A dictionary value stored as stable ordered entries. |
Handle | |
Tuple | Tuple handle for qkernel functions. |
TupleValue | A tuple of IR values for structured data. |
UInt | Unsigned integer handle with arithmetic operations. |
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¶
Dict [source]¶
class Dict(Handle, Generic[K, V])Dict handle for qkernel functions.
Represents a dictionary mapping keys to values, commonly used
for Ising coefficients like {(i, j): Jij}. Supports iteration via
items() and subscript lookup (d[key]), including indexing
one dict with the iteration keys of another.
Example:
@qmc.qkernel
def ising_cost(
q: qmc.Vector[qmc.Qubit],
ising: qmc.Dict[qmc.Tuple[qmc.UInt, qmc.UInt], qmc.Float],
gammas: qmc.Dict[qmc.Tuple[qmc.UInt, qmc.UInt], qmc.Float],
) -> qmc.Vector[qmc.Qubit]:
for (i, j), Jij in qmc.items(ising):
q[i], q[j] = qmc.rzz(q[i], q[j], Jij * gammas[(i, j)])
return qConstructor¶
def __init__(
self,
value: DictValue,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_entries: list[tuple[Handle, Handle]] = list(),
_size: UInt | None = None,
_key_type: type | None = None,
_value_type: type | None = None,
_runtime_parameter: bool = False,
) -> NoneAttributes¶
size: UInt Return the number of entries as a UInt handle.value: DictValue
Methods¶
items¶
def items(self) -> DictItemsIterator[K, V]Return an iterator over (key, value) pairs.
DictItemsIterator [source]¶
class DictItemsIterator(Generic[K, V])Iterator for Dict.items() that yields (key, value) pairs.
This is used internally for iterating over Dict entries in qkernel.
Constructor¶
def __init__(self, dict_handle: 'Dict[K, V]', _index: int = 0) -> NoneAttributes¶
dict_handle: ‘Dict[K, V]’
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) -> DictValueHandle [source]¶
class Handle(abc.ABC)Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneAttributes¶
id: strindices: tuple[‘UInt’, ...]name: str | Noneparent: ‘ArrayBase | None’value: Value
Methods¶
consume¶
def consume(self, operation_name: str = 'unknown') -> SelfMark this handle as consumed and return a fresh handle.
Records the user-code source location (file:line) of the
consuming call so a later affine violation can point at both the
first-use and the reuse site.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the operation consuming this handle, used for error messages. Defaults to "unknown". |
Returns:
typing.Self — typing.Self: New handle pointing to the same underlying value.
Raises:
QubitConsumedError— If this quantum handle was already consumed.
validate_consumable¶
def validate_consumable(self, operation_name: str = 'unknown') -> NoneValidate a consume without changing affine ownership state.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the prospective consuming operation, used in diagnostics. Defaults to "unknown". |
Raises:
QubitConsumedError— If this quantum handle was already consumed.
Tuple [source]¶
class Tuple(Handle, Generic[K, V])Tuple handle for qkernel functions.
Represents a tuple of values, commonly used for multi-index keys like (i, j) in Ising models.
Example:
@qmc.qkernel
def my_kernel(idx: qmc.Tuple[qmc.UInt, qmc.UInt]) -> qmc.UInt:
i, j = idx
return i + jConstructor¶
def __init__(
self,
value: TupleValue,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_elements: tuple[Handle, ...] = tuple(),
) -> NoneAttributes¶
value: TupleValue
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) -> TupleValueUInt [source]¶
class UInt(ArithmeticMixin, Handle)Unsigned integer handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: int = 0,
) -> NoneAttributes¶
init_value: int
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.
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.frontend.handle.hamiltonian¶
Observable handle for Hamiltonian parameters.
This module provides the Observable handle class that represents a reference to a Hamiltonian observable provided via bindings during transpilation. Unlike HamiltonianExpr in previous versions, this is a pure parameter handle with no arithmetic operations.
Overview¶
| Class | Description |
|---|---|
Handle | |
Observable | Handle representing a Hamiltonian observable parameter. |
Value | A typed SSA value in the IR. |
Classes¶
Handle [source]¶
class Handle(abc.ABC)Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneAttributes¶
id: strindices: tuple[‘UInt’, ...]name: str | Noneparent: ‘ArrayBase | None’value: Value
Methods¶
consume¶
def consume(self, operation_name: str = 'unknown') -> SelfMark this handle as consumed and return a fresh handle.
Records the user-code source location (file:line) of the
consuming call so a later affine violation can point at both the
first-use and the reuse site.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the operation consuming this handle, used for error messages. Defaults to "unknown". |
Returns:
typing.Self — typing.Self: New handle pointing to the same underlying value.
Raises:
QubitConsumedError— If this quantum handle was already consumed.
validate_consumable¶
def validate_consumable(self, operation_name: str = 'unknown') -> NoneValidate a consume without changing affine ownership state.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the prospective consuming operation, used in diagnostics. Defaults to "unknown". |
Raises:
QubitConsumedError— If this quantum handle was already consumed.
Observable [source]¶
class Observable(Handle)Handle representing a Hamiltonian observable parameter.
This is a reference type - the actual qamomile.observable.Hamiltonian is provided via bindings during transpilation. It cannot be constructed or manipulated within qkernels.
Example:
import qamomile.circuit as qm
import qamomile.observable as qm_o
# Build Hamiltonian in Python
H = qm_o.Z(0) * qm_o.Z(1) + 0.5 * qm_o.X(0)
@qm.qkernel
def vqe(q: qm.Vector[qm.Qubit], H: qm.Observable) -> qm.Float:
# Use Hamiltonian from bindings
return qm.expval(q, H)
# Pass via bindings
executable = transpiler.transpile(vqe, bindings={"H": H})Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneValue [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.frontend.handle.handle¶
Overview¶
| Function | Description |
|---|---|
evaluate_binop_values | Evaluate a binary arithmetic operation on two concrete values. |
get_current_tracer |
| Class | Description |
|---|---|
ArithmeticMixin | Mixin providing arithmetic operations for numeric Handle types. |
ArrayBase | Base class for array types (Vector, Matrix, Tensor). |
BinOp | Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN). |
BinOpKind | |
CompOp | Comparison operation (EQ, NEQ, LT, LE, GT, GE). |
CompOpKind | |
CondOp | Conditional logical operation (AND, OR). |
CondOpKind | |
Handle | |
NotOp | |
QubitConsumedError | Qubit handle used after being consumed by a previous operation. |
UInt | Unsigned integer handle with arithmetic operations. |
Value | A typed SSA value in the IR. |
Functions¶
evaluate_binop_values [source]¶
def evaluate_binop_values(
kind: BinOpKind | None,
left: float | int,
right: float | int,
) -> float | int | NoneEvaluate a binary arithmetic operation on two concrete values.
Parameters:
| Name | Type | Description |
|---|---|---|
kind | BinOpKind | None | The BinOpKind to apply. |
left | float | int | Left operand (numeric). |
right | float | int | Right operand (numeric). |
Returns:
float | int | None — The result, or None on division by zero, unknown kind, or
float | int | None — arithmetic error.
get_current_tracer [source]¶
def get_current_tracer() -> TracerClasses¶
ArithmeticMixin [source]¶
class ArithmeticMixinMixin providing arithmetic operations for numeric Handle types.
Requires:
value: Value attribute
_make_result(): Method to create result Handle of same type
_coerce(): Method to convert Python literals to Handle
Attributes¶
value: Value
ArrayBase [source]¶
class ArrayBase(Handle, Generic[T])Base class for array types (Vector, Matrix, Tensor).
Provides common functionality for array indexing and element access.
Constructor¶
def __init__(
self,
value: ArrayValue,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_shape: tuple[int | UInt, ...] = tuple(),
_borrowed_indices: dict[tuple[str, ...], 'tuple[UInt, ...] | Handle'] = dict(),
) -> NoneAttributes¶
element_type: Type[T]shape: tuple[int | UInt, ...] Return the shape of the array.value: ArrayValue
Methods¶
consume¶
def consume(self, operation_name: str = 'unknown') -> SelfConsume the array after validating its affine ownership state.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the consuming operation. Defaults to "unknown". |
Returns:
typing.Self — typing.Self: Fresh handle carrying the consumed array value.
Raises:
QubitConsumedError— If this handle or a covered slot was consumed.UnreturnedBorrowError— If a live element or slice borrow remains.
create¶
@classmethod
def create(
cls,
shape: tuple[int | UInt, ...],
name: str,
el_type: Type[T],
) -> 'ArrayBase[T]'Create an ArrayValue for the given shape and name.
validate_all_returned¶
def validate_all_returned(self) -> NoneValidate all borrowed elements have been returned.
Strict-return policy: an active slice view that is still
registered as the owner of any parent slot is treated as an
unreturned borrow even if the view itself has no outstanding
element borrows. The caller must perform an explicit slice
assignment (parent[a:b:c] = view) to release the view’s
bulk-borrow before consuming the parent. Destructively consumed
scalar or view owners (parked in the dict with _consumed set and
_consumed_by classified as :attr:ConsumeMode.DESTRUCTIVE)
record physically-destroyed slots and are not outstanding borrows; they survive
end-of-block so a later whole-array consume can detect and
reject the destroyed slots.
Raises:
UnreturnedBorrowError— If any elements are still borrowed, either directly or by a slice view that has not been explicitly returned via slice assignment.
validate_consumable¶
def validate_consumable(self, operation_name: str = 'unknown') -> NoneValidate an array consume without changing ownership state.
For quantum arrays, all borrowed elements must be returned before the array can be consumed. This ensures that no unreturned borrows are silently discarded by operations like qkernel calls or controlled gates.
When any slot of the array has already been physically consumed
by an earlier destructive element or view operation
(measure(q[0]) or measure(q[1::2]) followed by
measure(q)), this raises QubitConsumedError rather than
silently re-consuming those slots.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the prospective consuming operation. Defaults to "unknown". |
Raises:
QubitConsumedError— If this handle or any covered slot was already consumed.UnreturnedBorrowError— If a live element or slice borrow remains.
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
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
Handle [source]¶
class Handle(abc.ABC)Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneAttributes¶
id: strindices: tuple[‘UInt’, ...]name: str | Noneparent: ‘ArrayBase | None’value: Value
Methods¶
consume¶
def consume(self, operation_name: str = 'unknown') -> SelfMark this handle as consumed and return a fresh handle.
Records the user-code source location (file:line) of the
consuming call so a later affine violation can point at both the
first-use and the reuse site.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the operation consuming this handle, used for error messages. Defaults to "unknown". |
Returns:
typing.Self — typing.Self: New handle pointing to the same underlying value.
Raises:
QubitConsumedError— If this quantum handle was already consumed.
validate_consumable¶
def validate_consumable(self, operation_name: str = 'unknown') -> NoneValidate a consume without changing affine ownership state.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the prospective consuming operation, used in diagnostics. Defaults to "unknown". |
Raises:
QubitConsumedError— If this quantum handle was already consumed.
NotOp [source]¶
class NotOp(Operation)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
input: Valueoperation_kind: OperationKindoutput: Valuesignature: Signature
QubitConsumedError [source]¶
class QubitConsumedError(AffineTypeError)Qubit handle used after being consumed by a previous operation.
Each qubit handle can only be used once. After a gate operation, you must reassign the result to use the new handle.
Example of incorrect code:
q1 = qm.h(q) q2 = qm.x(q) # ERROR: q was already consumed by h()
Correct code:
q = qm.h(q) # Reassign to capture new handle q = qm.x(q) # Use the reassigned handle
UInt [source]¶
class UInt(ArithmeticMixin, Handle)Unsigned integer handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: int = 0,
) -> NoneAttributes¶
init_value: int
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.frontend.handle.primitives¶
Overview¶
| Class | Description |
|---|---|
ArithmeticMixin | Mixin providing arithmetic operations for numeric Handle types. |
BinOpKind | |
Bit | |
BitType | Type representing a classical bit. |
CompOpKind | |
CondOpKind | |
Float | Floating-point handle with arithmetic operations. |
FloatType | Type representing a floating-point number. |
Handle | |
QFixed | |
Qubit | |
QubitType | Type representing a quantum bit (qubit). |
UInt | Unsigned integer handle with arithmetic operations. |
UIntType | Type representing an unsigned integer. |
Value | A typed SSA value in the IR. |
Classes¶
ArithmeticMixin [source]¶
class ArithmeticMixinMixin providing arithmetic operations for numeric Handle types.
Requires:
value: Value attribute
_make_result(): Method to create result Handle of same type
_coerce(): Method to convert Python literals to Handle
Attributes¶
value: Value
BinOpKind [source]¶
class BinOpKind(enum.Enum)Attributes¶
ADDDIVFLOORDIVMINMODMULPOWSUB
Bit [source]¶
class Bit(Handle)Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: bool = False,
) -> NoneAttributes¶
init_value: bool
BitType [source]¶
class BitType(ClassicalTypeMixin, ValueType)Type representing a classical bit.
CompOpKind [source]¶
class CompOpKind(enum.Enum)Attributes¶
EQGEGTLELTNEQ
CondOpKind [source]¶
class CondOpKind(enum.Enum)Attributes¶
ANDOR
Float [source]¶
class Float(ArithmeticMixin, Handle)Floating-point handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: float = 0.0,
) -> NoneAttributes¶
init_value: float
FloatType [source]¶
class FloatType(ClassicalTypeMixin, ValueType)Type representing a floating-point number.
Handle [source]¶
class Handle(abc.ABC)Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneAttributes¶
id: strindices: tuple[‘UInt’, ...]name: str | Noneparent: ‘ArrayBase | None’value: Value
Methods¶
consume¶
def consume(self, operation_name: str = 'unknown') -> SelfMark this handle as consumed and return a fresh handle.
Records the user-code source location (file:line) of the
consuming call so a later affine violation can point at both the
first-use and the reuse site.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the operation consuming this handle, used for error messages. Defaults to "unknown". |
Returns:
typing.Self — typing.Self: New handle pointing to the same underlying value.
Raises:
QubitConsumedError— If this quantum handle was already consumed.
validate_consumable¶
def validate_consumable(self, operation_name: str = 'unknown') -> NoneValidate a consume without changing affine ownership state.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the prospective consuming operation, used in diagnostics. Defaults to "unknown". |
Raises:
QubitConsumedError— If this quantum handle was already consumed.
QFixed [source]¶
class QFixed(Handle)Constructor¶
def __init__(
self,
value: Value[QFixedType],
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneAttributes¶
value: Value[QFixedType]
Qubit [source]¶
class Qubit(Handle)Constructor¶
def __init__(
self,
value: Value[QubitType],
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneAttributes¶
value: Value[QubitType]
QubitType [source]¶
class QubitType(QuantumTypeMixin, ValueType)Type representing a quantum bit (qubit).
UInt [source]¶
class UInt(ArithmeticMixin, Handle)Unsigned integer handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: int = 0,
) -> NoneAttributes¶
init_value: int
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.
qamomile.circuit.frontend.handle.utils¶
Utility helpers for handle types.
Overview¶
| Function | Description |
|---|---|
get_size | Return the size of a Vector handle as a Python integer. |
Functions¶
get_size [source]¶
def get_size(arr: Vector[_H]) -> intReturn the size of a Vector handle as a Python integer.
Resolves the leading axis of arr.shape through two forms a
Vector shape entry can take:
A plain Python
int(built-in bound shape; this is what you get fromqmc.qubit_array(N, ...)for literalN).A
UInthandle whose underlyingValuecarries a compile-time constant (set byuint(literal),_create_bound_input, or partial evaluation).
A UInt handle whose underlying Value is not a constant is
treated as an unresolved symbolic dimension and raises
ValueError even when the handle has the dataclass-default
init_value=0. Falling back to init_value for that case
would silently turn a runtime-symbolic Vector[Float] parameter
into a “size 0” array, hiding programming errors. Callers that
need to handle symbolic shapes (e.g., to emit a deferred callable
when the size is unknown) must catch the ValueError themselves.
Parameters:
| Name | Type | Description |
|---|---|---|
arr | Vector[Handle] | Vector handle whose first axis size is requested. |
Returns:
int — The first-axis size as a plain Python int.
Raises:
TypeError— If arr is not a 1-DVectorhandle (Vectoror itsVectorViewsubclass) — e.g., a scalarQubitwas passed where aVectoris required, a higher-rankMatrix/Tensorwas passed (this helper only resolves a 1-D first-axis size), or an unrelatedshape-bearing object such as a numpy array. This is a clearer signal than the bareAttributeErrorthatarr.shapewould otherwise raise, and it guards the stdlib / composite callers that resolve a register size through this helper.ValueError— If the shape cannot be resolved to a concrete integer — e.g., the Vector is a runtime-parametric handle without compile-time bindings, or carries aUIntdimension whose underlyingValuehas not been promoted to a constant.
Classes¶
Handle [source]¶
class Handle(abc.ABC)Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneAttributes¶
id: strindices: tuple[‘UInt’, ...]name: str | Noneparent: ‘ArrayBase | None’value: Value
Methods¶
consume¶
def consume(self, operation_name: str = 'unknown') -> SelfMark this handle as consumed and return a fresh handle.
Records the user-code source location (file:line) of the
consuming call so a later affine violation can point at both the
first-use and the reuse site.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the operation consuming this handle, used for error messages. Defaults to "unknown". |
Returns:
typing.Self — typing.Self: New handle pointing to the same underlying value.
Raises:
QubitConsumedError— If this quantum handle was already consumed.
validate_consumable¶
def validate_consumable(self, operation_name: str = 'unknown') -> NoneValidate a consume without changing affine ownership state.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the prospective consuming operation, used in diagnostics. Defaults to "unknown". |
Raises:
QubitConsumedError— If this quantum handle was already consumed.
Vector [source]¶
class Vector(ArrayBase[T])1-dimensional array type.
Example:
import qamomile.circuit as qmc
# Create a vector of 3 qubits
qubits: qmc.Vector[qmc.Qubit] = qmc.qubit_array(3, name="qubits")
# Access elements
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0
# Apply H gate to all qubits (CORRECT)
n = qubits.shape[0]
for i in qmc.range(n):
qubits[i] = qmc.h(qubits[i])
# Slicing returns a VectorView over a subset of the parent vector.
# The view shares borrow tracking with the parent; element access
# on the view transparently indexes the parent.
evens = qubits[0::2]
for i in qmc.range(evens.shape[0]):
evens[i] = qmc.h(evens[i])Constructor¶
def __init__(
self,
value: ArrayValue = None,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_shape: tuple[int | UInt] = (0,),
_borrowed_indices: dict[tuple[str, ...], 'tuple[UInt, ...] | Handle'] = dict(),
) -> NoneAttributes¶
value: ArrayValue
qamomile.circuit.frontend.operation¶
Operation builders: tracer-facing functions that emit IR operations.
These are the free functions a qkernel body calls (re-exported from
qamomile.circuit): gate builders (qubit_gates.py), measurement /
reset / projection (measurement.py), the control-flow builders that
the frontend AST transform targets (control_flow.py: range /
for_items / if- and while-machinery, loop region args),
meta-operations (control.py, inverse.py), type conversion
(cast.py), and Hamiltonian helpers (expval.py,
pauli_evolve.py).
A builder’s job is thin and uniform: validate handle arguments at trace
time (e.g. QubitAliasError when one qubit fills two roles of a
gate), construct one abstract IR Operation with next-version output
Values, append it to the active Tracer, and return fresh
handles. Builders must not pre-expand into lower-level operations — one
user call maps to one abstract IR operation (a vector measurement stays
a single MeasureVectorOperation); decomposition and lowering are the
transpiler’s and the backends’ job.
qamomile.circuit.frontend.operation.cast¶
Cast operation for type conversions over the same quantum resources.
Overview¶
| Function | Description |
|---|---|
cast | Cast a quantum value to a different type without allocating new qubits. |
get_current_tracer |
| Class | Description |
|---|---|
CastOperation | Type cast operation for creating aliases over the same quantum resources. |
QFixed | |
QFixedType | Quantum fixed-point type. |
Qubit | |
UIntType | Type representing an unsigned integer. |
Value | A typed SSA value in the IR. |
Vector | 1-dimensional array type. |
VectorView | Strided view over a parent Vector, backed by a sliced ArrayValue. |
Functions¶
cast [source]¶
def cast(source: Vector[Qubit], target_type: type, *, int_bits: int = 0) -> QFixedCast a quantum value to a different type without allocating new qubits.
The cast performs a move: the source handle is consumed and cannot be reused after the cast. The returned handle references the same physical qubits.
Parameters:
| Name | Type | Description |
|---|---|---|
source | Vector[Qubit] | The value to cast (currently supports Vector[Qubit]) |
target_type | type | The target type class (currently supports QFixed) |
int_bits | int | For QFixed, number of integer bits (default: 0 = all fractional) |
Returns:
QFixed — A new handle of the target type referencing the same qubits.
Example:
@qmc.qkernel
def my_circuit():
phase_register = qmc.qubit_array(5, name="phase")
# ... apply some operations ...
# Cast the qubit array to QFixed for measurement
phase_qfixed = qmc.cast(phase_register, qmc.QFixed, int_bits=0)
phase_value = qmc.measure(phase_qfixed)
return phase_valueRaises:
TypeError— If the source type or target type is not supportedValueError— If int_bits is negative or larger than the number of qubits
get_current_tracer [source]¶
def get_current_tracer() -> TracerClasses¶
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
QFixed [source]¶
class QFixed(Handle)Constructor¶
def __init__(
self,
value: Value[QFixedType],
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneAttributes¶
value: Value[QFixedType]
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) -> strQubit [source]¶
class Qubit(Handle)Constructor¶
def __init__(
self,
value: Value[QubitType],
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneAttributes¶
value: Value[QubitType]
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.
Vector [source]¶
class Vector(ArrayBase[T])1-dimensional array type.
Example:
import qamomile.circuit as qmc
# Create a vector of 3 qubits
qubits: qmc.Vector[qmc.Qubit] = qmc.qubit_array(3, name="qubits")
# Access elements
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0
# Apply H gate to all qubits (CORRECT)
n = qubits.shape[0]
for i in qmc.range(n):
qubits[i] = qmc.h(qubits[i])
# Slicing returns a VectorView over a subset of the parent vector.
# The view shares borrow tracking with the parent; element access
# on the view transparently indexes the parent.
evens = qubits[0::2]
for i in qmc.range(evens.shape[0]):
evens[i] = qmc.h(evens[i])Constructor¶
def __init__(
self,
value: ArrayValue = None,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_shape: tuple[int | UInt] = (0,),
_borrowed_indices: dict[tuple[str, ...], 'tuple[UInt, ...] | Handle'] = dict(),
) -> NoneAttributes¶
value: ArrayValue
VectorView [source]¶
class VectorView(Vector[T])Strided view over a parent Vector, backed by a sliced ArrayValue.
A VectorView is produced by slicing a Vector (q[1::2],
q[a:b], etc.). It is a thin Vector subclass whose value
is a fresh ArrayValue with slice_of / slice_start /
slice_step metadata pointing back to the parent’s ArrayValue.
Element accesses go through Vector._get_element unchanged — the
IR element carries parent_array = sliced_av, and the emit-time
resolver walks the slice_of chain to produce the physical qubit
index. No affine translation happens in the view itself.
Because the sliced ArrayValue is a first-class IR Value,
the view can be passed as an operand of an inline callable invocation
to another qkernel without the inline-trace special-case path that
earlier iterations required. Passing views through
expval / measure likewise operates on the sliced qubit
subset, not the root parent as a whole.
Linearity:
Slicing bulk-borrows the covered parent slots whenever
start, step and length are compile-time int
constants. While the view is live, accessing the corresponding
parent slot directly (q[0] after evens = q[0::2]) raises
QubitConsumedError. Under the strict-return policy the
view’s ownership is cleared only by two operations:
slice-assigning it back into the parent (
parent[a:b:c] = view) — this is the only path that fully releases the borrow without destroying the qubits;destructively consuming it (
measure(view)/cast(view, ...)/expval(view, H)) — the physical slots become consumed markers, no return needed.
Every other consume (broadcast gates h(view),
pauli_evolve(view, H, gamma), sub-kernel calls
f(view), controlled-U index_spec) only transfers
ownership to a freshly-wrapped VectorView and that new
view still must be returned via slice assignment. A view
left bulk-borrowing at the parent’s consume point raises
UnreturnedBorrowError.
Symbolic slices (q[lo:hi] with lo/hi UInt) cannot
enumerate their covered slots at trace time and therefore skip
the bulk-borrow here; SliceBorrowCheckPass picks them up
post-fold after bindings resolve the bounds to concrete values.
Example:
@qmc.qkernel
def alternating_h(q: qmc.Vector[qmc.Qubit]) -> qmc.Vector[qmc.Qubit]:
evens = q[0::2]
for i in qmc.range(evens.shape[0]):
evens[i] = qmc.h(evens[i])
q[0::2] = evens # explicit return before the parent is used
return qMethods¶
consume¶
def consume(self, operation_name: str = 'unknown') -> SelfConsume the view and release its parent slice-borrows.
Validates that every view-local borrow has been returned,
then dispatches on operation_name to keep the parent’s
slice-borrow record consistent with the new strict-return
semantics:
Destructive (
measure/cast): leaveselfparked in the parent’s borrow table as a destroyed-slot breadcrumb.super().consume()flipsself._consumed = Trueandself._consumed_by = operation_name, which is what :func:_is_destroyed_slot_ownerreads to reject subsequent access at the same slot.Releasing (
slice assignment): drop every parent entry thatselfcurrently owns. The caller (the slice- assignment frontend path) also emits aReleaseSliceViewOperationso the IR-level checker sees the release. This branch is reserved for explicit borrow- return paths.Transfer (every other op — broadcast gates, rotation, phase, ControlledU, sub-kernel call argument consumption, etc.): rebind the parent’s borrow entry from
selfto the new view handle returned here. The new view inheritsself._slice_covered_indicesso it can be slice-assigned back to the parent later — strict-return requires that eventualparent[a:b:c] = new_view.
Operations that produce a fresh sliced ArrayValue (e.g.
:func:qamomile.circuit.frontend.operation.pauli_evolve.pauli_evolve,
:class:QKernel.__call__ for callees that return a sliced
array) cannot simply use the auto-returned new_view
because the new view they build wraps a different Value
than this consume’s return. Those op implementations call
:meth:_transfer_borrow_to after building their result so
the parent’s borrow table tracks the right handle.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the operation consuming this view (used in error messages and for dispatch). |
Returns:
typing.Self — A fresh view handle with the same backing state; under
typing.Self — transfer the parent’s borrow table now points at this
typing.Self — handle, under release / destruction the parent’s record
typing.Self — for the covered slots is finalised.
Raises:
QubitConsumedError— If any covered slot was already destroyed by a prior destructive consume on an overlapping element or view.
qamomile.circuit.frontend.operation.control¶
Controlled gate operations.
Overview¶
| Function | Description |
|---|---|
coerce_nonnegative_integral | Normalize a real scalar with an integer value to a nonnegative integer. |
control | Create a controlled version of a quantum gate. |
get_current_tracer | |
normalize_control_value | Normalize an integer activation state for a control register. |
qkernel_callable_attrs | Return compiler attrs for a qkernel invocation. |
qkernel_callable_def | Build the inline-by-default callable definition for a qkernel block. |
qkernel_callable_ref | Return the compiler-facing callable reference for a qkernel. |
reject_aliased_quantum_args | Reject overlapping live quantum resources at one call boundary. |
require_unitary_effects | Reject non-unitary effects with a uniform early diagnostic. |
select_specialized_block | Select the block implementation for a qkernel call site. |
| Class | Description |
|---|---|
ArrayValue | An array of typed IR values. |
Block | Unified block representation for all pipeline stages. |
CallTransform | Describe the requested transform of a callable implementation. |
CallableImplementation | Describe one implementation candidate for a callable. |
CallableRef | Identify a callable independently of its Python object. |
ConcreteControlledU | Controlled-U with concrete (int) number of controls. |
ControlledGate | Wrapper for controlled version of a QKernel. |
ControlledUOperation | Base class for controlled-U operations. |
Float | Floating-point handle with arithmetic operations. |
FloatType | Type representing a floating-point number. |
GlobalPhaseOperation | Multiply the complete quantum state by exp(i * phase). |
InvokeOperation | Represent a composite, stdlib, or oracle call. |
Oracle | Represent an opaque oracle callable. |
QKernel | Decorator class for Qamomile quantum kernels. |
QKernelLike | Describe the frontend surface required by compiler entrypoints. |
Qubit | |
ReturnOperation | Explicit return operation marking the end of a block with return values. |
SymbolicControlledU | Controlled-U with symbolic (Value) number of controls. |
TransformedOracle | Represent composable inverse and controlled transforms of an Oracle. |
UInt | Unsigned integer handle with arithmetic operations. |
UIntType | Type representing an unsigned integer. |
Value | A typed SSA value in the IR. |
Functions¶
coerce_nonnegative_integral [source]¶
def coerce_nonnegative_integral(value: object, *, label: str) -> intNormalize a real scalar with an integer value to a nonnegative integer.
Parameters:
| Name | Type | Description |
|---|---|---|
value | object | Candidate Python, NumPy, or SymPy real scalar. |
label | str | User-facing field label used in diagnostics. |
Returns:
int — Equivalent nonnegative Python integer.
Raises:
TypeError— Ifvalueis Boolean, is not a real scalar, is not finite, or does not have an integer value.ValueError— If the normalized integer is negative.
control [source]¶
def control(
qkernel: Oracle | TransformedOracle | ControlledGate | QKernelLike | Callable[..., Any],
num_controls: int | UInt = 1,
*,
control_value: int | None = None,
) -> ControlledGate | TransformedOracleCreate a controlled version of a quantum gate.
Accepts a @qmc.qkernel-decorated function, a qkernel-backed
composite gate callable created by the decorator, an existing
ControlledGate, an opaque Oracle, or a plain built-in gate callable
(qmc.rx, qmc.h, qmc.cp, ...).
When given a plain callable, a thin @qkernel
wrapper is synthesized automatically by inspecting the callable’s
signature, so users no longer need to write a one-line wrapper just to
control a primitive gate.
When a wrapped scalar Qubit parameter receives a Vector[Qubit] or
VectorView[Qubit], the complete scalar unitary is applied independently
to every element. This is the tensor-product operation produced by an
explicit per-element loop, so a scalar body’s global phase accumulates once
per element. To attach one phase to the whole register instead, wrap a
qkernel whose parameter itself is Vector[Qubit].
Parameters:
| Name | Type | Description |
|---|---|---|
qkernel | object | A qkernel-like object defining the gate to control, an existing controlled wrapper, an Oracle or transformed Oracle, or a built-in gate callable whose parameters are annotated with Qubit, Float / float, or UInt / int (possibly inside a Union such as Union[Qubit, Vector[Qubit]]). |
num_controls | int | UInt | Number of control qubits (default: 1). Can be a Python or NumPy integer (concrete) or UInt (symbolic). Concrete integral scalars are normalized to a Python int. |
control_value | int | None | Computational-basis value that activates the controlled unitary. Controls are flattened in call order, with Vector / VectorView elements taken from index zero upward; the first flattened control is bit zero. None preserves the ordinary all-ones behavior. Only concrete num_controls is supported. Defaults to None. |
Returns:
ControlledGate | TransformedOracle — For a qkernel or gate callable, a ControlledGate that can be called
ControlledGate | TransformedOracle — with (*controls, *targets, power=..., global_phase=..., **params).
ControlledGate | TransformedOracle — Controlling an existing ControlledGate prepends the new controls
ControlledGate | TransformedOracle — and returns one flattened wrapper while retaining the target direction
ControlledGate | TransformedOracle — and callable metadata.
ControlledGate | TransformedOracle — The call-site phase has semantics
ControlledGate | TransformedOracle — control((exp(i * global_phase) * U) ** power) and therefore becomes
ControlledGate | TransformedOracle — relative phase on the all-active control subspace. power,
ControlledGate | TransformedOracle — global_phase, and control_indices are reserved keyword names;
ControlledGate | TransformedOracle — a same-named target parameter can still be supplied positionally. For
ControlledGate | TransformedOracle — an Oracle, an opaque qubit-only controlled wrapper is returned;
ControlledGate | TransformedOracle — these call-site modifiers are not supported by that wrapper. Its
ControlledGate | TransformedOracle — positional prefix contains controls added by this transform followed
ControlledGate | TransformedOracle — by controls declared on the Oracle. Pass
ControlledGate | TransformedOracle — declared_control_value=... when the declared group uses an open
ControlledGate | TransformedOracle — activation pattern.
Raises:
TypeError— Ifqkernelis a callable that cannot be auto-wrapped (missing annotations, unsupported types, or no qubit parameters),num_controlsis boolean or neither integral nor aUInt,control_valueis not a PythonintorNone, anOraclecontrol count is symbolic, or an Oracle uses a vector target signature.ValueError— Ifnum_controlsis a concreteintless than one,control_valueis out of range, or a non-default value is used with symbolicnum_controls.
Example:
Built-in gates can be controlled directly, with no wrapper::
crx = qmc.control(qmc.rx)
ctrl_out, tgt_out = crx(ctrl, target, angle=0.5)
# Target-global phase becomes observable after control.
ctrl_out, tgt_out = crx(
ctrl, target, angle=0.5, global_phase=theta
)
cch = qmc.control(qmc.h, num_controls=2)
c0, c1, tgt = cch(ctrl0, ctrl1, target)
# Fire only when (ctrl0, ctrl1) represents integer 2. The first
# control is bit zero, so the required pattern is (0, 1).
on_two = qmc.control(qmc.x, num_controls=2, control_value=2)
ctrl0, ctrl1, target = on_two(ctrl0, ctrl1, target)
``@qmc.qkernel`` arguments are still supported for cases that need
custom logic::
@qmc.qkernel
def rx_then_h(q: Qubit, theta: float) -> Qubit:
q = qmc.rx(q, theta)
q = qmc.h(q)
return q
ctrl_out, tgt_out = qmc.control(rx_then_h)(ctrl, target, theta=0.5)
Qkernel-backed composite gate callables can also be controlled directly::
controlled_gate = qmc.control(my_composite_gate)
ctrl_out, tgt0_out, tgt1_out = controlled_gate(ctrl, tgt0, tgt1)
Controlled wrappers compose directly. The outer group remains first
in positional call order::
nested = qmc.control(
qmc.control(my_gate, num_controls=2),
num_controls=1,
)
outer, inner0, inner1, target = nested(
outer, inner0, inner1, target
)get_current_tracer [source]¶
def get_current_tracer() -> Tracernormalize_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.
qkernel_callable_attrs [source]¶
def qkernel_callable_attrs(kernel: Any) -> dict[str, Any]Return compiler attrs for a qkernel invocation.
Composite metadata lives directly on QKernel. This helper is the
single translation point from that frontend state into serializer-safe IR
attributes, so direct, controlled, and inverse calls share one identity.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object carrying callable metadata. |
Returns:
dict[str, Any] — dict[str, Any]: Serializer-friendly callable attributes.
qkernel_callable_def [source]¶
def qkernel_callable_def(kernel: Any, block: Block) -> CallableDefBuild the inline-by-default callable definition for a qkernel block.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object carrying callable metadata. |
block | Block | Implementation body for the qkernel. |
Returns:
CallableDef — Compiler-facing definition for the qkernel.
qkernel_callable_ref [source]¶
def qkernel_callable_ref(kernel: Any) -> CallableRefReturn the compiler-facing callable reference for a qkernel.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object carrying callable metadata. |
Returns:
CallableRef — Stable reference used by InvokeOperation call sites.
reject_aliased_quantum_args [source]¶
def reject_aliased_quantum_args(
kernel_name: str,
arguments: dict[str, Any],
*,
caller: str | None = None,
) -> NoneReject overlapping live quantum resources at one call boundary.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel_name | str | Name of the called qkernel for diagnostics. |
arguments | dict[str, Any] | Bound call arguments keyed by parameter name. |
caller | str | None | Optional operation label replacing the default QKernel[kernel_name] context. Defaults to None. |
Raises:
QubitConsumedError— If two quantum arguments may cover the same physical qubit.
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.
select_specialized_block [source]¶
def select_specialized_block(
kernel: Any,
arguments: dict[str, Any],
*,
require_handles: bool = True,
) -> BlockSelect the block implementation for a qkernel call site.
Centralizes call-site specialization so plain qkernel calls, controlled
calls, and inverse calls use the same rule. When concrete argument values
would change the callee trace (for example a concrete Vector[Qubit]
size or a bound structural classical value), the function returns a
temporary specialized block. Otherwise it returns the kernel’s cached
block.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object whose block should be selected. |
arguments | dict[str, Any] | Bound call arguments after literal promotion and frontend validation. Registered static bindings may remain concrete Python objects when require_handles is false. |
require_handles | bool | If True, specialization is skipped unless every argument is a frontend Handle. Defaults to True. |
Returns:
Block — Specialized call-site block or the cached kernel block.
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.
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.
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
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.
ControlledGate [source]¶
class ControlledGateWrapper for controlled version of a QKernel.
Created by calling control(qkernel). The resulting object
can be called like a gate function.
Example:
@qmc.qkernel
def phase_gate(q: Qubit, theta: float) -> Qubit:
return qmc.p(q, theta)
controlled_phase = qmc.control(phase_gate)
ctrl_out, tgt_out = controlled_phase(ctrl, target, theta=0.5)
# Add a call-site target phase. Under control this is observable.
ctrl_out, tgt_out = controlled_phase(
ctrl, target, theta=0.5, global_phase=phi
)
# Double-controlled
cc_phase = qmc.control(phase_gate, num_controls=2)
c0, c1, tgt = cc_phase(ctrl0, ctrl1, target, theta=0.5)Constructor¶
def __init__(
self,
qkernel: 'QKernel',
num_controls: int | UInt = 1,
*,
control_value: int | None = None,
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] | None = None,
target_inverse: bool = False,
) -> NoneWrap a QKernel as a controlled operation.
Parameters:
| Name | Type | Description |
|---|---|---|
qkernel | QKernel | The kernel to control. Built-in gate callables are not accepted directly here -- :func:control synthesizes a wrapper QKernel for them before instantiating ControlledGate -- so by this point qkernel must expose a dict input_types attribute and an inspect.Signature signature attribute. |
num_controls | int | UInt | Number of control qubits. A concrete Python or NumPy integer must be >= 1 and is normalized to a Python int; a symbolic UInt defers validation to emit time. Defaults to 1. A bool is rejected: it is not a valid control count even though bool subclasses int. |
control_value | int | None | Computational-basis value that activates the control. Bit zero describes the first flattened control qubit, following Qamomile’s LSB-first convention. None uses the ordinary all-ones state. Only supported with a concrete num_controls. Defaults to None. |
callable_ref | CallableRef | None | Optional source callable identity to record on emitted ControlledUOperation nodes. Defaults to the wrapped qkernel’s callable ref. |
callable_attrs | dict[str, Any] | None | Optional serializer-friendly attrs for the source callable. Defaults to qkernel attrs. |
target_inverse | bool | Whether the controlled target is the inverse of qkernel. Defaults to False. |
Raises:
TypeError— Ifnum_controlsis boolean or neither integral nor aUInt,control_valueis not a PythonintorNone, orqkerneldoes not expose a dictinput_types/ aninspect.Signaturesignature.ValueError— If a concretenum_controlsis less than one,control_valuedoes not fit its width, or a non-default value is combined with symbolicnum_controls.
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]) -> OperationFloat [source]¶
class Float(ArithmeticMixin, Handle)Floating-point handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: float = 0.0,
) -> NoneAttributes¶
init_value: float
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.
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.
Oracle [source]¶
class OracleRepresent an opaque oracle callable.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | Human-readable oracle name. |
num_qubits | int | None | Number of target qubits consumed and returned by the oracle. None means the arity is provided by signature and may be vector-shaped. Python and NumPy integer scalars are accepted; booleans and negative values are rejected. |
num_control_qubits | int | Number of explicit control qubits required by scalar calls. Defaults to 0. |
signature | CallableSignature | None | Optional frontend signature for target operands only. It must not repeat the leading controls declared by num_control_qubits; those controls are prefixed by the Oracle automatically. When omitted, a fixed-width scalar/vector-compatible oracle is created from num_qubits. |
cost | ResourceEstimate | Callable[[OpaqueCostContext], ResourceEstimate] | None | Optional explicit cost for this bodyless callable. Both forms describe one ordinary application of the Oracle as declared, including num_control_qubits. Controls added later with qmc.control are projected by resource estimation. This is a complete definition-level contract: the author must include any phase-relevant work that later coherent controls need. The estimator does not infer omitted global-phase overhead. An intrinsic nonidentity phase is represented as a logical primitive in the aggregate gate and arity counts. A one-qubit phase entry is an upper-bound representative for the target-free phase, not an angle-aware reconstruction; use a body-backed global phase when angle-specific classification is required. Defaults to None. |
Raises:
TypeError— If a suppliednum_qubitsornum_control_qubitsis boolean or not an integral scalar.ValueError— If either width is negative, or neithernum_qubitsnorsignaturesupplies enough target-arity information.
Constructor¶
def __init__(
self,
name: str,
num_qubits: int | None = None,
*,
num_control_qubits: int = 0,
signature: CallableSignature | None = None,
cost: ResourceEstimate | Callable[[OpaqueCostContext], ResourceEstimate] | None = None,
) -> NoneInitialize an opaque oracle callable.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | Human-readable oracle name. |
num_qubits | int | None | Fixed scalar/vector width. Defaults to None when signature describes the callable. Python and NumPy integer scalars are accepted; booleans and negative values are rejected. |
num_control_qubits | int | Number of explicit scalar controls. Defaults to 0. |
signature | CallableSignature | None | Optional frontend signature for target operands only. Do not include controls declared by num_control_qubits; the Oracle prefixes those controls to its internal callable signature. Defaults to None. |
cost | ResourceEstimate | Callable[[OpaqueCostContext], ResourceEstimate] | None | Optional fixed or context-dependent opaque cost. The returned estimate describes one ordinary application of this Oracle definition, including its declared controls but excluding controls added by an outer transform. The result must be a complete definition-level contract, including phase-relevant work that an outer coherent control must transform. Represent an intrinsic nonidentity phase as a logical primitive in the aggregate gate and arity counts. A one-qubit phase entry is an upper-bound representative; use a body-backed global phase for angle-specific classification. Defaults to None. |
Raises:
TypeError— If a suppliednum_qubitsornum_control_qubitsis not a non-boolean integral scalar.ValueError— If neithernum_qubitsnorsignaturesupplies enough target-arity information, or if either width is negative.
Attributes¶
cost: ResourceEstimate | Callable[[OpaqueCostContext], ResourceEstimate] | Nonename: strnum_control_qubits: intnum_qubits: int | Nonesignature: CallableSignature | None
QKernel [source]¶
class QKernel(QKernelBuildMixin, QKernelVisualizationMixin, Generic[P, R])Decorator class for Qamomile quantum kernels.
Constructor¶
def __init__(self, func: Callable[P, R]) -> NoneAttributes¶
block: Block Compile the function to a hierarchical Block if not already compiled.effects: KernelEffect Return cached semantic effects of this qkernel.funcinput_types: dict[str, Any] Return resolved and frozen frontend input annotations.nameoutput_types: list[Any] Return the resolved frontend annotation for every output slot.raw_funcreturn_type: Any Return the resolved and frozen complete return annotation.signature
QKernelLike [source]¶
class QKernelLike(Protocol)Describe the frontend surface required by compiler entrypoints.
This protocol is intentionally structural. It lets decorator-created
composites reuse the qkernel inspection and build interface without making
them inherit from QKernel or exposing the compiler-facing callable
descriptor model as a frontend concept.
Attributes¶
block: Block Return the cached hierarchical body block.effects: KernelEffect Return cached semantic effects of the qkernel body.input_types: dict[str, Any] Return frontend input annotations by parameter name.name: str Return the user-facing callable name.output_types: list[Any] Return frontend output annotations.signature: inspect.Signature Return the Python call signature.
Methods¶
build¶
def build(self, parameters: list[str] | None = None, **kwargs: Any = {}) -> BlockBuild a traced body block.
Parameters:
| Name | Type | Description |
|---|---|---|
parameters | list[str] | None | Runtime parameter names to preserve. Defaults to None. |
**kwargs | Any | Compile-time bindings for non-parameter arguments. |
Returns:
Block — Traced hierarchical body block.
Qubit [source]¶
class Qubit(Handle)Constructor¶
def __init__(
self,
value: Value[QubitType],
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneAttributes¶
value: Value[QubitType]
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.
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]) -> OperationTransformedOracle [source]¶
class TransformedOracleRepresent composable inverse and controlled transforms of an Oracle.
The wrapped Oracle remains the definition boundary: its explicit cost
includes only controls declared by Oracle.num_control_qubits. This
wrapper records controls added later by qmc.control and whether the
call is inverted, so the resulting InvokeOperation can apply those
transforms exactly once.
Parameters:
| Name | Type | Description |
|---|---|---|
oracle | Oracle | Definition-level opaque Oracle. |
added_num_control_qubits | int | Number of controls added outside the Oracle definition. Defaults to 0. |
added_control_value | int | None | LSB-first activation value for the added controls, or None for all ones. Defaults to None. |
inverse | bool | Whether to apply the inverse Oracle. Defaults to False. |
Raises:
TypeError— Ifadded_num_control_qubitsis boolean or not integral, or a positive count is attached to a vector-signature Oracle.ValueError— If the added-control count is negative or its activation value is invalid for that width.
Constructor¶
def __init__(
self,
oracle: Oracle,
added_num_control_qubits: int = 0,
added_control_value: int | None = None,
inverse: bool = False,
) -> NoneAttributes¶
added_control_value: int | Noneadded_num_control_qubits: intinverse: boolname: str Return the source Oracle name.oracle: Oracle
Methods¶
controlled¶
def controlled(
self,
num_controls: int,
*,
control_value: int | None = None,
) -> TransformedOraclePrepend another concrete control group.
Parameters:
| Name | Type | Description |
|---|---|---|
num_controls | int | Number of newly added leading controls. |
control_value | int | None | LSB-first activation value for the new control group. None means all ones. Defaults to None. |
Returns:
TransformedOracle — Wrapper carrying the combined added-control
condition.
Raises:
TypeError— Ifnum_controlsis not a non-boolean integer orcontrol_valueis not a Python integer orNone, or the source Oracle uses a vector target signature.ValueError— Ifnum_controlsis not positive orcontrol_valuedoes not fit its width.
inverted¶
def inverted(self) -> Oracle | TransformedOracleToggle inverse application while preserving added controls.
Returns:
Oracle | TransformedOracle — Oracle | TransformedOracle: The original Oracle when every
transform cancels, otherwise a transformed wrapper.
UInt [source]¶
class UInt(ArithmeticMixin, Handle)Unsigned integer handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: int = 0,
) -> NoneAttributes¶
init_value: int
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.
qamomile.circuit.frontend.operation.control_flow¶
Overview¶
| Function | Description |
|---|---|
array_extents_equal | Return whether two well-formed array extents are statically equal. |
array_resource_identity | Return the canonical logical identity of an array resource. |
array_resources_equal | Return whether arrays denote the same whole logical resource. |
branch_rebind_pre_bindings | Capture pre-branch bindings for if-rebind records. |
const_int | Return a compile-time integer constant from an IR value. |
dead_rebind_binding | Probe a branch body’s post-branch binding of a dead-after variable. |
emit_if | Trace an if/else conditional and merge its branch results. |
explicit_loop_bindings | Resolve generated lexical loop bindings without frame inspection. |
for_items | Create a traced for-items loop in the Qamomile frontend. |
for_loop | Create a traced for loop in the Qamomile frontend. |
get_current_tracer | |
handle_type_map | Map Handle type to ValueType. |
is_array_type | Check if type is a Vector, Matrix, or Tensor subclass. |
is_full_reslice_of_input | Check whether an output is only full-sliced from a formal input. |
items | Iterate over dictionary key-value pairs. |
loop_rebind_snapshot | Snapshot pre-loop variable handles for rebind detection. |
loop_region_enter | Bind loop-carried classical state to a fresh region argument. |
loop_region_result | Rebind a loop-carried variable to its post-loop result handle. |
range | Symbolic range for use in qkernel for-loops. |
record_loop_rebinds | Record classical and quantum rebinds on the current loop-body tracer. |
should_trace_for_loop | Decide whether a qmc.range body must be traced. |
should_trace_items_loop | Decide whether a qmc.items body must be traced. |
trace | Context manager to set the current tracer. |
validate_region_args | Validate the SSA identities owned by a loop’s region arguments. |
while_loop | Create a while loop whose condition is a measurement result. |
| Class | Description |
|---|---|
ArrayBase | Base class for array types (Vector, Matrix, Tensor). |
ArrayValue | An array of typed IR values. |
Bit | |
BitType | Type representing a classical bit. |
BranchRebind | Trace-time record of a quantum variable rebound inside an if branch. |
Dict | Dict handle for qkernel functions. |
DictItemsIterator | Iterator for Dict.items() that yields (key, value) pairs. |
Float | Floating-point handle with arithmetic operations. |
FloatType | Type representing a floating-point number. |
ForItemsOperation | Represents iteration over dict/iterable items. |
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. |
RegionArg | Explicit loop-carried value on a loop operation (MLIR-style iter_arg). |
Tracer | Collects operations (and loop-rebind records) during tracing. |
TupleType | Type representing a tuple of values. |
UInt | Unsigned integer handle with arithmetic operations. |
UIntType | Type representing an unsigned integer. |
Value | A typed SSA value in the IR. |
ValueBase | Nominal base for every typed IR value. |
ValueType | Base class for all value types in the IR. |
Vector | 1-dimensional array type. |
WhileLoop | Mark the body of a traced Qamomile while loop. |
WhileOperation | Represents a while loop operation. |
Functions¶
array_extents_equal [source]¶
def array_extents_equal(left: Value, right: Value) -> boolReturn whether two well-formed array extents are statically equal.
Parameters:
| Name | Type | Description |
|---|---|---|
left | Value | First scalar UInt extent. |
right | Value | Second scalar UInt extent. |
Returns:
bool — True for one SSA extent or equal non-negative constants.
array_resource_identity [source]¶
def array_resource_identity(value: ArrayValue) -> str | NoneReturn the canonical logical identity of an array resource.
Parameters:
| Name | Type | Description |
|---|---|---|
value | ArrayValue | Array whose exact full-slice prefix is ignored. |
Returns:
str | None — str | None: Terminal logical identity, or None for a cyclic chain.
array_resources_equal [source]¶
def array_resources_equal(left: ArrayValue, right: ArrayValue) -> boolReturn whether arrays denote the same whole logical resource.
Exact full re-slices are transparent, while partial or strided views are
distinct resources. This lets control-flow merges preserve identity for a
direct value and value[:] as well as for two sibling full re-slices.
Parameters:
| Name | Type | Description |
|---|---|---|
left | ArrayValue | First array resource. |
right | ArrayValue | Second array resource. |
Returns:
bool — True when both arrays reach one compatible logical resource.
branch_rebind_pre_bindings [source]¶
def branch_rebind_pre_bindings(frame_locals: dict[str, Any], names: tuple) -> dict[str, Any]Capture pre-branch bindings for if-rebind records.
Called from AST-injected code at the emit_if call site with the
caller’s locals(). A name missing from the call site’s locals is
resolved through the enclosing emit_if calls’ captured pre-bindings
(innermost first): a dead-after variable never enters the generated
branch-body scopes, so for a nested if only the enclosing capture
still knows its pre-branch handle. The transformer’s candidate
analysis is lexical, so a name may genuinely be unbound everywhere
(a preceding pure-store if can be dead-store-eliminated from its
outputs); such names are silently skipped instead of raising
UnboundLocalError at the call site.
Parameters:
| Name | Type | Description |
|---|---|---|
frame_locals | dict[str, typing.Any] | The caller’s locals(). |
names | tuple | Candidate variable names to capture. |
Returns:
dict[str, typing.Any] — dict[str, typing.Any]: The resolvable candidate names mapped to
their pre-branch handles.
const_int [source]¶
def const_int(value: Value | None) -> int | NoneReturn a compile-time integer constant from an IR value.
Parameters:
| Name | Type | Description |
|---|---|---|
value | Value | None | IR value that may carry a constant. |
Returns:
int | None — int | None: Plain integer constant, or None when unavailable.
dead_rebind_binding [source]¶
def dead_rebind_binding(frame_locals: dict[str, Any], name: str) -> AnyProbe a branch body’s post-branch binding of a dead-after variable.
Called from AST-injected code as an extra element of a branch body’s
return tuple. A variable reassigned in a branch but never read after
the if is dead-store-eliminated from the branch outputs, so its
post-branch binding is not otherwise observable by emit_if; this
probe reads it from the body’s locals(). In the branch that does
not store the variable the name is unbound in the body scope, so the
probe returns a sentinel instead of raising NameError.
Parameters:
| Name | Type | Description |
|---|---|---|
frame_locals | dict[str, typing.Any] | The body’s locals() at the return point. |
name | str | The probed variable name. |
Returns:
typing.Any — typing.Any: The post-branch handle, or the unbound sentinel when
the body never bound the name.
emit_if [source]¶
def emit_if(
cond_func: Callable,
true_func: Callable,
false_func: Callable,
variables: list,
output_names: tuple = (),
rebind_pre_bindings: dict | None = None,
dead_names: tuple = (),
capture_indices: tuple[int, ...] = (),
) -> AnyTrace an if/else conditional and merge its branch results.
This function is called from AST-transformed code. The AST transformer converts: if condition: true_body else: false_body
Into:
def _cond_N(vars): return condition def _body_N(vars): true_body; return vars def _body_N+1(vars): false_body; return vars result = emit_if(_cond_N, _body_N, _body_N+1, [var_list])
Parameters:
| Name | Type | Description |
|---|---|---|
cond_func | typing.Callable | Function returning the condition as a Bit or bool-like handle. |
true_func | typing.Callable | Function tracing the true branch and returning its updated variables. |
false_func | typing.Callable | Function tracing the false branch and returning its updated variables. |
variables | list | Variables captured by the two branch functions. |
output_names | tuple | Variable names positionally aligned with the branch return tuples, used for branch-rebind records. Empty when the transformer found no rebind candidates. |
rebind_pre_bindings | dict | None | Pre-branch handles of every pre-existing variable reassigned in a branch, keyed by name; captured at the call site by the AST transformer. None when there are no candidates. |
dead_names | tuple | Names of dead-after rebind candidates whose post-branch bindings the branch bodies append as a probe tail after their ordinary return values (see dead_rebind_binding). The tail is consumed for rebind records only and never merged or returned. Empty when there are no dead candidates. |
capture_indices | tuple[int, ...] | Positions in variables that form each branch region’s explicit input interface. Defaults to an empty tuple. |
Returns:
typing.Any — typing.Any: The sole merged value, a tuple of merged values, or None
when the branches return no values.
Raises:
TypeError— If corresponding branch values have incompatible types or divergent values with no Qamomile IR representation.ValueError— If branch result lengths or probe-tail lengths disagree.
Example:
@qkernel
def my_kernel(q: Qubit) -> Qubit:
result = measure(q)
if result:
q = z(q)
return qexplicit_loop_bindings [source]¶
def explicit_loop_bindings(bindings: tuple[tuple[str, Callable[[], Any]], ...]) -> dict[str, Any]Resolve generated lexical loop bindings without frame inspection.
Generated control-flow code passes one lazy zero-argument resolver for each statically analyzed interface name. A name that is not bound on the traced path may still be available from the enclosing branch’s explicit pre-binding stack; genuinely absent names are omitted, matching the old tolerant snapshot behavior.
Parameters:
| Name | Type | Description |
|---|---|---|
bindings | tuple[tuple[str, Callable[[], Any]], ...] | Named lazy lexical resolvers in deterministic interface order. |
Returns:
dict[str, typing.Any] — dict[str, typing.Any]: Resolved bindings keyed by source name.
for_items [source]¶
def for_items(
d: Dict,
key_var_names: list[str],
value_var_name: str,
*,
captures: tuple[tuple[str, Any], ...] = (),
) -> Generator[tuple[Any, Any], None, None]Create a traced for-items loop in the Qamomile frontend.
This context manager creates a ForItemsOperation that iterates over dictionary (key, value) pairs. The operation is always unrolled at transpile time since quantum backends cannot natively iterate over classical data structures.
Parameters:
| Name | Type | Description |
|---|---|---|
d | Dict | Dict handle whose compile-time-known entries are iterated. |
key_var_names | list[str] | Names of key-unpacking variables, for example ["i", "j"] for tuple keys. |
value_var_name | str | Display name of the item-value variable. |
captures | tuple[tuple[str, typing.Any], ...] | Statically analyzed read-only body inputs. Defaults to an empty tuple. |
Yields:
tuple[typing.Any, typing.Any] — tuple[typing.Any, typing.Any]: Key handle(s) and the typed scalar
value handle used while tracing the loop body.
Raises:
TypeError— Ifdis a runtime-parameter Dict (declared viaparameters=[...]without bound data), or its key annotation cannot be represented by the loop target. A runtime Dict’s key structure is unknown at compile time, so an items() loop cannot be unrolled; only constant-key subscript lookups (d[key]) are supported for runtime-parameter dicts.NotImplementedError— If the Dict value annotation is a container or another type without a scalar frontend handle.ValueError— If the constructed loop has inconsistent region-result metadata.
Example:
@qkernel
def ising_cost(
q: Vector[Qubit],
ising: Dict[Tuple[UInt, UInt], Float],
gamma: Float,
) -> Vector[Qubit]:
for (i, j), Jij in qmc.items(ising):
q[i], q[j] = qmc.rzz(q[i], q[j], gamma * Jij)
return qfor_loop [source]¶
def for_loop(
start,
stop,
step = 1,
var_name: str = '_loop_idx',
*,
captures: tuple[tuple[str, Any], ...] = (),
) -> Generator[UInt, None, None]Create a traced for loop in the Qamomile frontend.
Parameters:
| Name | Type | Description |
|---|---|---|
start | typing.Any | Inclusive loop start as an integer or UInt. |
stop | typing.Any | Exclusive loop stop as an integer or UInt. |
step | typing.Any | Nonzero loop step as an integer or UInt. Defaults to 1. |
var_name | str | Display name of the loop variable. Defaults to "_loop_idx". |
captures | tuple[tuple[str, typing.Any], ...] | Statically analyzed read-only body inputs. Defaults to an empty tuple. |
Yields:
UInt — The loop iteration variable (can be used as array index)
Raises:
TypeError— If a bound cannot be represented as a scalar IR value.ValueError— If the constructed loop has inconsistent region-result metadata.
Example:
@QKernel
def my_kernel(qubits: Array[Qubit, Literal[3]]) -> Array[Qubit, Literal[3]]:
for i in qm.range(3):
qubits[i] = h(qubits[i])
return qubits
@QKernel
def my_kernel2(qubits: Array[Qubit, Literal[5]]) -> Array[Qubit, Literal[5]]:
for i in qm.range(1, 4): # i = 1, 2, 3
qubits[i] = h(qubits[i])
return qubitsClassical scalar updates (total = total + i) become explicit
RegionArg records on the ForOperation: the loop enters with
the initializer, each iteration reads the previous iteration’s
value, and post-loop code reads the loop result.
get_current_tracer [source]¶
def get_current_tracer() -> Tracerhandle_type_map [source]¶
def handle_type_map(handle_type: type[Handle] | type) -> ValueTypeMap Handle type to ValueType.
is_array_type [source]¶
def is_array_type(t: Any) -> boolCheck if type is a Vector, Matrix, or Tensor subclass.
is_full_reslice_of_input [source]¶
def is_full_reslice_of_input(output: ArrayValue, formal_input: ArrayValue) -> boolCheck whether an output is only full-sliced from a formal input.
Parameters:
| Name | Type | Description |
|---|---|---|
output | ArrayValue | Callee output array value. |
formal_input | ArrayValue | Callee formal input array value. |
Returns:
bool — True when every slice from output back to
bool — formal_input is 0:len:1 with equal concrete lengths or the
bool — same symbolic length identity.
items [source]¶
def items(d: Dict) -> DictItemsIteratorIterate over dictionary key-value pairs.
This function returns an iterator over (key, value) pairs from a Dict. Used for iterating over Ising coefficients and similar data structures.
Example:
for (i, j), Jij in qmc.items(ising):
q[i], q[j] = qmc.rzz(q[i], q[j], gamma * Jij)Parameters:
| Name | Type | Description |
|---|---|---|
d | Dict | A Dict handle to iterate over |
Returns:
DictItemsIterator — DictItemsIterator yielding (key, value) pairs
loop_rebind_snapshot [source]¶
def loop_rebind_snapshot(frame_locals: dict[str, Any], names: tuple[str, ...]) -> dict[str, Any]Snapshot pre-loop variable handles for rebind detection.
Called from AST-injected probe code as the first statement of a traced
loop body. The snapshot records which handle each candidate variable
name pointed at before the body ran, so record_loop_rebinds can
detect rebinds by comparing IR value identity afterwards.
Candidates are resolved through :func:branch_rebind_pre_bindings:
the caller’s frame locals first, then the enclosing if-branch
pre-binding stack. The fallback matters inside an if branch — a
variable the branch only stores (via the loop) is not a branch
input parameter, so it is unbound in the branch’s frame at loop
entry, yet its pre-branch handle is exactly the state a loop-body
rebind would discard. Names bound nowhere are silently omitted.
Parameters:
| Name | Type | Description |
|---|---|---|
frame_locals | dict[str, typing.Any] | The caller’s locals() at loop entry. |
names | tuple[str, ...] | Candidate variable names to snapshot. |
Returns:
dict[str, typing.Any] — dict[str, typing.Any]: The resolvable candidate names mapped to
their pre-loop-body handles (or plain Python values).
loop_region_enter [source]¶
def loop_region_enter(snapshot: dict[str, Any], name: str, allow_array: bool = False) -> AnyBind loop-carried classical state to a fresh region argument.
Called from AST-injected code at the top of a structured loop body
(immediately after loop_rebind_snapshot)
for each read-before-write classical candidate: total = loop_region_enter(_qm_rebind_snap_N, "total"). When the pre-loop
binding is a classical UInt / Float scalar (or a plain
Python int / float), the body is given a fresh
region-argument handle so its reads become explicit loop-carried
reads instead of stale pre-loop reads — the MLIR iter_args
model. The loop builder later converts the pending entry into a
RegionArg on the loop operation.
Classical arrays are also promoted so persistent element stores thread
the current array version through the loop. Quantum values, dicts,
Qubit, Bit, opaque Python objects, and bool are returned
unchanged; quantum rebinds keep feeding the discard check and
measurement-backed Bit carries keep their targeted rejection.
Parameters:
| Name | Type | Description |
|---|---|---|
snapshot | dict[str, typing.Any] | Pre-loop-body bindings from loop_rebind_snapshot. |
name | str | The candidate variable name. |
allow_array | bool | Whether a persistent element update may promote a classical array. Whole-array rebinds leave this false and retain their targeted rejection. Defaults to False. |
Returns:
typing.Any — typing.Any: A fresh region-argument handle for supported scalar or
array bindings, or the original binding unchanged.
Raises:
NameError— Ifnameresolves nowhere — mirroring theNameErrorthe body’s first read would have raised.
loop_region_result [source]¶
def loop_region_result(name: str, current: Any) -> AnyRebind a loop-carried variable to its post-loop result handle.
Called from AST-injected code immediately after a structured loop’s
with block: total = loop_region_result("total", total). Consumes the result handle
the loop builder published for name (if any) so post-loop reads
reference the loop operation’s result value instead of the body’s
final yielded value.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | The carried variable name. |
current | typing.Any | The variable’s current binding (the body’s final handle), returned unchanged when the closed loop published no result for name. |
Returns:
typing.Any — typing.Any: The published result handle, or current.
range [source]¶
def range(
stop_or_start: int | UInt,
stop: int | UInt | None = None,
step: int | UInt = 1,
) -> Iterator[UInt]Symbolic range for use in qkernel for-loops.
This function accepts UInt (symbolic) values and is transformed by the AST transformer into for_loop() calls.
Example:
for i in qmc.range(n): # 0 to n-1
for i in qmc.range(start, stop): # start to stop-1
for i in qmc.range(start, stop, step):record_loop_rebinds [source]¶
def record_loop_rebinds(
snapshot: dict[str, Any],
frame_locals: dict[str, Any],
names: tuple[str, ...],
classical_names: tuple[str, ...],
) -> NoneRecord classical and quantum rebinds on the current loop-body tracer.
Called from AST-injected probe code as the last statement of a traced
loop body. Two families of rebinds are recorded as
:class:LoopCarriedRebind entries on the active body tracer (the
loop builders copy them onto the loop operation, where the
transpiler’s rejection passes read them):
Quantum (any candidate name): the variable’s pre-body value is quantum and its post-body value denotes a different resource — a fresh allocation or another register rather than a gate self-update or exact full reslice. These feed the transpiler’s loop-body quantum discard check.
Classical values (only names in
classical_names): supported same-typeUInt/Floatvalues that were region-bound at body entry complete their pendingRegionArginstead of producing a record. Every other representable rebind produces a residual record, including measurement-backedBitvalues and containers. The transpiler rejects shapes that need unsupported routing; a store-only scalarBitis accepted only for a statically non-empty unrolled loop, where reusing the measurement-result UUID correctly selects the last iteration and no zero-trip initializer must be routed.classical_namesincludes both read-before-write carries and store-only values that are live after the loop.
No IR operations are emitted; this only annotates the tracer.
Parameters:
| Name | Type | Description |
|---|---|---|
snapshot | dict[str, typing.Any] | Pre-loop-body handles from loop_rebind_snapshot. |
frame_locals | dict[str, typing.Any] | The caller’s locals() at the end of the loop body. |
names | tuple[str, ...] | All candidate variable names. |
classical_names | tuple[str, ...] | The subset of names the loop body either reads before writing or overwrites and exposes after the loop; only these may produce classical records or complete pending region arguments. |
should_trace_for_loop [source]¶
def should_trace_for_loop(start: Any, stop: Any, step: Any) -> boolDecide whether a qmc.range body must be traced.
The frontend executes loop bodies once to capture a ForOperation.
When all bounds are concrete and Python’s range would execute
zero times, tracing the body would incorrectly leak borrow /
destructive-consume state into the enclosing scope. Symbolic or
invalid bounds stay conservative and trace the body so the normal
compiler validation path reports any errors.
Parameters:
| Name | Type | Description |
|---|---|---|
start | typing.Any | Loop start bound. |
stop | typing.Any | Loop stop bound. |
step | typing.Any | Loop step bound. |
Returns:
bool — False only for statically-known zero-trip loops; True
bool — otherwise.
should_trace_items_loop [source]¶
def should_trace_items_loop(mapping: Any) -> boolDecide whether a qmc.items body must be traced.
The frontend executes loop bodies once to capture a
ForItemsOperation. When the mapping is a Dict handle whose
bound contents are compile-time-known and EMPTY, Python’s iteration
would execute zero times, so tracing the body would incorrectly
leak bindings (and rebind records) into the enclosing scope — the
qmc.range zero-trip guard’s exact analogue
(:func:should_trace_for_loop). Symbolic or unbound mappings stay
conservative and trace the body so the normal compiler validation
path reports any errors.
Parameters:
| Name | Type | Description |
|---|---|---|
mapping | typing.Any | The iterated mapping — normally a Dict handle; anything without bound dict metadata is treated as symbolic. |
Returns:
bool — False only for a mapping with present-and-empty bound
bool — dict contents; True otherwise.
trace [source]¶
def trace(tracer: Tracer | None = None) -> Generator[Tracer, None, None]Context manager to set the current tracer.
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.
while_loop [source]¶
def while_loop(
cond: Callable,
*,
captures: tuple[tuple[str, Any], ...] = (),
) -> Generator[WhileLoop, None, None]Create a while loop whose condition is a measurement result.
The condition must be a Bit produced by qmc.measure().
Non-measurement conditions (classical variables, constants,
comparisons) are accepted at build time but will be rejected by
ValidateWhileContractPass during transpilation.
Parameters:
| Name | Type | Description |
|---|---|---|
cond | typing.Callable | A callable (lambda) that returns the loop condition. Must return a Bit handle originating from qmc.measure(). |
captures | tuple[tuple[str, typing.Any], ...] | Statically analyzed read-only body inputs. Defaults to an empty tuple. |
Yields:
WhileLoop — A marker object for the while loop context.
Raises:
TypeError— If either condition evaluation cannot be represented as a scalar IR value.ValueError— If the constructed loop has inconsistent region-result metadata.
Example::
@qm.qkernel
def repeat_until_zero() -> qm.Bit:
q = qm.qubit("q")
q = qm.h(q)
bit = qm.measure(q)
while bit:
q2 = qm.qubit("q2")
q2 = qm.h(q2)
bit = qm.measure(q2)
return bitThe body register is a body-local name (q2), not a rebind of the
pre-loop q: rebinding a pre-existing quantum variable to a
register allocated in the body is rejected by the transpiler’s
control-flow discard check, because the runtime loop re-executes its
body on one persistent register without reset and cannot realize
“fresh per iteration” semantics for the rebound name.
Classical scalar updates (count = count + 1) are represented as
explicit region arguments and yields. Target validation may still reject
a carry when the selected backend cannot thread that classical type
through a runtime measurement-controlled loop.
Classes¶
ArrayBase [source]¶
class ArrayBase(Handle, Generic[T])Base class for array types (Vector, Matrix, Tensor).
Provides common functionality for array indexing and element access.
Constructor¶
def __init__(
self,
value: ArrayValue,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_shape: tuple[int | UInt, ...] = tuple(),
_borrowed_indices: dict[tuple[str, ...], 'tuple[UInt, ...] | Handle'] = dict(),
) -> NoneAttributes¶
element_type: Type[T]shape: tuple[int | UInt, ...] Return the shape of the array.value: ArrayValue
Methods¶
consume¶
def consume(self, operation_name: str = 'unknown') -> SelfConsume the array after validating its affine ownership state.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the consuming operation. Defaults to "unknown". |
Returns:
typing.Self — typing.Self: Fresh handle carrying the consumed array value.
Raises:
QubitConsumedError— If this handle or a covered slot was consumed.UnreturnedBorrowError— If a live element or slice borrow remains.
create¶
@classmethod
def create(
cls,
shape: tuple[int | UInt, ...],
name: str,
el_type: Type[T],
) -> 'ArrayBase[T]'Create an ArrayValue for the given shape and name.
validate_all_returned¶
def validate_all_returned(self) -> NoneValidate all borrowed elements have been returned.
Strict-return policy: an active slice view that is still
registered as the owner of any parent slot is treated as an
unreturned borrow even if the view itself has no outstanding
element borrows. The caller must perform an explicit slice
assignment (parent[a:b:c] = view) to release the view’s
bulk-borrow before consuming the parent. Destructively consumed
scalar or view owners (parked in the dict with _consumed set and
_consumed_by classified as :attr:ConsumeMode.DESTRUCTIVE)
record physically-destroyed slots and are not outstanding borrows; they survive
end-of-block so a later whole-array consume can detect and
reject the destroyed slots.
Raises:
UnreturnedBorrowError— If any elements are still borrowed, either directly or by a slice view that has not been explicitly returned via slice assignment.
validate_consumable¶
def validate_consumable(self, operation_name: str = 'unknown') -> NoneValidate an array consume without changing ownership state.
For quantum arrays, all borrowed elements must be returned before the array can be consumed. This ensures that no unreturned borrows are silently discarded by operations like qkernel calls or controlled gates.
When any slot of the array has already been physically consumed
by an earlier destructive element or view operation
(measure(q[0]) or measure(q[1::2]) followed by
measure(q)), this raises QubitConsumedError rather than
silently re-consuming those slots.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the prospective consuming operation. Defaults to "unknown". |
Raises:
QubitConsumedError— If this handle or any covered slot was already consumed.UnreturnedBorrowError— If a live element or slice borrow remains.
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]Bit [source]¶
class Bit(Handle)Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: bool = False,
) -> NoneAttributes¶
init_value: bool
BitType [source]¶
class BitType(ClassicalTypeMixin, ValueType)Type representing a classical bit.
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
Dict [source]¶
class Dict(Handle, Generic[K, V])Dict handle for qkernel functions.
Represents a dictionary mapping keys to values, commonly used
for Ising coefficients like {(i, j): Jij}. Supports iteration via
items() and subscript lookup (d[key]), including indexing
one dict with the iteration keys of another.
Example:
@qmc.qkernel
def ising_cost(
q: qmc.Vector[qmc.Qubit],
ising: qmc.Dict[qmc.Tuple[qmc.UInt, qmc.UInt], qmc.Float],
gammas: qmc.Dict[qmc.Tuple[qmc.UInt, qmc.UInt], qmc.Float],
) -> qmc.Vector[qmc.Qubit]:
for (i, j), Jij in qmc.items(ising):
q[i], q[j] = qmc.rzz(q[i], q[j], Jij * gammas[(i, j)])
return qConstructor¶
def __init__(
self,
value: DictValue,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_entries: list[tuple[Handle, Handle]] = list(),
_size: UInt | None = None,
_key_type: type | None = None,
_value_type: type | None = None,
_runtime_parameter: bool = False,
) -> NoneAttributes¶
size: UInt Return the number of entries as a UInt handle.value: DictValue
Methods¶
items¶
def items(self) -> DictItemsIterator[K, V]Return an iterator over (key, value) pairs.
DictItemsIterator [source]¶
class DictItemsIterator(Generic[K, V])Iterator for Dict.items() that yields (key, value) pairs.
This is used internally for iterating over Dict entries in qkernel.
Constructor¶
def __init__(self, dict_handle: 'Dict[K, V]', _index: int = 0) -> NoneAttributes¶
dict_handle: ‘Dict[K, V]’
Float [source]¶
class Float(ArithmeticMixin, Handle)Floating-point handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: float = 0.0,
) -> NoneAttributes¶
init_value: float
FloatType [source]¶
class FloatType(ClassicalTypeMixin, ValueType)Type representing a floating-point number.
ForItemsOperation [source]¶
class ForItemsOperation(HasNestedOps, Operation)Represents iteration over dict/iterable items.
Example:
for (i, j), Jij in qmc.items(ising):
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]) -> 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
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
Tracer [source]¶
class TracerCollects operations (and loop-rebind records) during tracing.
Constructor¶
def __init__(
self,
_operations: list[Operation] = list(),
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_entries: dict[str, Any] = dict(),
loop_region_results: dict[str, Any] = dict(),
) -> NoneAttributes¶
loop_carried_rebinds: tuple[LoopCarriedRebind, ...]loop_region_results: dict[str, Any]operations: list[Operation]region_entries: dict[str, Any]
Methods¶
add_operation¶
def add_operation(self, op) -> NoneTupleType [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) -> strUInt [source]¶
class UInt(ArithmeticMixin, Handle)Unsigned integer handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: int = 0,
) -> NoneAttributes¶
init_value: int
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.
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) -> strVector [source]¶
class Vector(ArrayBase[T])1-dimensional array type.
Example:
import qamomile.circuit as qmc
# Create a vector of 3 qubits
qubits: qmc.Vector[qmc.Qubit] = qmc.qubit_array(3, name="qubits")
# Access elements
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0
# Apply H gate to all qubits (CORRECT)
n = qubits.shape[0]
for i in qmc.range(n):
qubits[i] = qmc.h(qubits[i])
# Slicing returns a VectorView over a subset of the parent vector.
# The view shares borrow tracking with the parent; element access
# on the view transparently indexes the parent.
evens = qubits[0::2]
for i in qmc.range(evens.shape[0]):
evens[i] = qmc.h(evens[i])Constructor¶
def __init__(
self,
value: ArrayValue = None,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_shape: tuple[int | UInt] = (0,),
_borrowed_indices: dict[tuple[str, ...], 'tuple[UInt, ...] | Handle'] = dict(),
) -> NoneAttributes¶
value: ArrayValue
WhileLoop [source]¶
class WhileLoopMark the body of a traced Qamomile while loop.
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.frontend.operation.expval¶
Expectation value operation for computing <psi|H|psi>.
This module provides the expval() function for computing the expectation
value of a Hamiltonian observable with respect to a quantum state.
Overview¶
| Function | Description |
|---|---|
expval | Compute the expectation value of an observable on a quantum state. |
get_current_tracer | |
reject_aliased_quantum_args | Reject overlapping live quantum resources at one call boundary. |
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. |
| Class | Description |
|---|---|
ArrayValue | An array of typed IR values. |
ExpvalOp | Expectation value operation. |
FloatType | Type representing a floating-point number. |
Value | A typed SSA value in the IR. |
Functions¶
expval [source]¶
def expval(
qubits: Qubit | Vector[Qubit] | tuple[Qubit, ...],
hamiltonian: Observable,
) -> FloatCompute the expectation value of an observable on a quantum state.
This function computes <psi|H|psi> where psi is the quantum
state represented by qubits and H is the Hamiltonian
observable.
The quantum state is consumed by this operation: expval
classifies as :attr:ConsumeMode.DESTRUCTIVE, the same category as
measure / cast. Conceptually an Estimator runs many shots
of the state to estimate the expectation, so the qubits cannot be
reused afterwards. Any attempt to access the same qubits / view
slots after expval is rejected as use-after-destroy, both at
trace time and post-fold in the IR.
Parameters:
| Name | Type | Description |
|---|---|---|
qubits | Qubit | Vector[Qubit] | tuple[Qubit, ...] | The quantum register holding the prepared state. A single Qubit handle is accepted for 1-qubit observables. When a Vector is passed all previously-borrowed elements must have been returned (the strict-return policy is enforced by consume here). When a slice view (VectorView) is passed its covered parent slots become consumed-slot markers so the parent cannot reuse them later. |
hamiltonian | Observable | The Observable parameter representing the Hamiltonian. The actual qamomile.observable.Hamiltonian is provided via transpile(..., bindings={...}). |
Returns:
Float — A scalar handle holding the expectation value, suitable
for use as the kernel return value or as an operand to
further classical operations.
Raises:
RuntimeError— If no qkernel tracer is active.QubitConsumedError— Ifqubitswas already consumed (e.g. measured / cast earlier in the kernel), or if any covered slot of a passed view was destroyed by a prior destructive view operation.UnreturnedBorrowError— Ifqubitsis aVectorwith outstanding element or slice-view borrows that have not been returned.
Example:
import qamomile.circuit as qm
import qamomile.observable as qm_o
# Build Hamiltonian in Python
H = qm_o.Z(0) * qm_o.Z(1) + 0.5 * (qm_o.X(0) + qm_o.X(1))
@qm.qkernel
def vqe_step(q: qm.Vector[qm.Qubit], H: qm.Observable) -> qm.Float:
# Ansatz
q[0] = qm.ry(q[0], theta)
q[0], q[1] = qm.cx(q[0], q[1])
# Expectation value -> Float (q is consumed here)
return qm.expval(q, H)
# Pass Hamiltonian via bindings
executable = transpiler.transpile(vqe_step, bindings={"H": H})get_current_tracer [source]¶
def get_current_tracer() -> Tracerreject_aliased_quantum_args [source]¶
def reject_aliased_quantum_args(
kernel_name: str,
arguments: dict[str, Any],
*,
caller: str | None = None,
) -> NoneReject overlapping live quantum resources at one call boundary.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel_name | str | Name of the called qkernel for diagnostics. |
arguments | dict[str, Any] | Bound call arguments keyed by parameter name. |
caller | str | None | Optional operation label replacing the default QKernel[kernel_name] context. Defaults to None. |
Raises:
QubitConsumedError— If two quantum arguments may cover the same physical qubit.
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.
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]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.
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.frontend.operation.global_phase¶
Provide the qmc.global_phase qkernel combinator.
Overview¶
| Function | Description |
|---|---|
get_current_tracer | |
global_phase | Apply a qkernel call followed by exp(i * phase). |
| Class | Description |
|---|---|
Float | Floating-point handle with arithmetic operations. |
FloatType | Type representing a floating-point number. |
GlobalPhaseGate | Apply a wrapped qkernel followed by a zero-qubit global phase. |
QKernel | Decorator class for Qamomile quantum kernels. |
Value | A typed SSA value in the IR. |
Functions¶
get_current_tracer [source]¶
def get_current_tracer() -> Tracerglobal_phase [source]¶
def global_phase(target: QKernel | Callable[..., Any], phase: PhaseValue) -> GlobalPhaseGateApply a qkernel call followed by exp(i * phase).
The phase is represented as a zero-qubit operation and is retained even when it is not observable in the surrounding program. A reversible qkernel containing the operation acquires an observable relative phase when it is coherently controlled. Measurement, reset, allocation, classical outputs, and classical-only qkernels remain valid for ordinary standalone use.
Parameters:
| Name | Type | Description |
|---|---|---|
target | QKernel | Callable[..., Any] | QKernel or gate-like callable whose call is followed by the global phase. |
phase | float | int | Float | Phase angle in radians, supplied as a Qamomile Float handle or Python numeric literal. |
Returns:
GlobalPhaseGate — Callable wrapper with the target’s call interface.
Raises:
TypeError— Iftargetcannot be interpreted as a gate-like callable.
Example:
>>> import qamomile.circuit as qmc
>>> @qmc.qkernel
... def step(q: qmc.Qubit) -> qmc.Qubit:
... return qmc.x(q)
>>> @qmc.qkernel
... def phased_step(q: qmc.Qubit) -> qmc.Qubit:
... return qmc.global_phase(step, 0.7)(q)Classes¶
Float [source]¶
class Float(ArithmeticMixin, Handle)Floating-point handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: float = 0.0,
) -> NoneAttributes¶
init_value: float
FloatType [source]¶
class FloatType(ClassicalTypeMixin, ValueType)Type representing a floating-point number.
GlobalPhaseGate [source]¶
class GlobalPhaseGateApply a wrapped qkernel followed by a zero-qubit global phase.
Parameters:
| Name | Type | Description |
|---|---|---|
qkernel | QKernel | QKernel whose call is followed by the phase. |
phase | float | int | Float | Phase angle in radians. |
Example:
>>> import qamomile.circuit as qmc
>>> @qmc.qkernel
... def layer(q: qmc.Qubit) -> qmc.Qubit:
... return qmc.h(q)
>>> @qmc.qkernel
... def circuit(q: qmc.Qubit, theta: qmc.Float) -> qmc.Qubit:
... return qmc.global_phase(layer, theta)(q)Constructor¶
def __init__(self, qkernel: QKernel, phase: PhaseValue) -> NoneInitialize the global-phase wrapper.
Parameters:
| Name | Type | Description |
|---|---|---|
qkernel | QKernel | QKernel whose call is followed by the phase. |
phase | float | int | Float | Phase angle in radians. |
QKernel [source]¶
class QKernel(QKernelBuildMixin, QKernelVisualizationMixin, Generic[P, R])Decorator class for Qamomile quantum kernels.
Constructor¶
def __init__(self, func: Callable[P, R]) -> NoneAttributes¶
block: Block Compile the function to a hierarchical Block if not already compiled.effects: KernelEffect Return cached semantic effects of this qkernel.funcinput_types: dict[str, Any] Return resolved and frozen frontend input annotations.nameoutput_types: list[Any] Return the resolved frontend annotation for every output slot.raw_funcreturn_type: Any Return the resolved and frozen complete return annotation.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.
qamomile.circuit.frontend.operation.inverse¶
Frontend helpers for applying inverse quantum operations.
Overview¶
| Function | Description |
|---|---|
get_current_tracer | |
inverse | Create an inverse operation wrapper. |
invoke_qkernel_with_operation | Invoke a QKernel using a custom operation factory. |
is_static_binding_annotation | Return whether an annotation denotes a registered static binding. |
promote_literal_to_handle | Promote a Python literal to a scalar handle for qkernel calls. |
qkernel_callable_attrs | Return compiler attrs for a qkernel invocation. |
qkernel_callable_def | Build the inline-by-default callable definition for a qkernel block. |
qkernel_callable_ref | Return the compiler-facing callable reference for a qkernel. |
qkernel_invoke_block | Create an InvokeOperation for a qkernel call. |
quantum_operand_widths | Decode exact quantum-operand widths from callable resource metadata. |
reject_aliased_quantum_args | Reject overlapping live quantum resources at one call boundary. |
require_unitary_effects | Reject non-unitary effects with a uniform early diagnostic. |
select_specialized_block | Select the block implementation for a qkernel call site. |
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. |
static_quantum_width | Return a quantum value’s compile-time scalar-qubit width. |
validate_static_binding_argument | Validate a concrete binding or caller-owned symbolic binding proxy. |
| Class | Description |
|---|---|
ArrayBase | Base class for array types (Vector, Matrix, Tensor). |
ArrayValue | An array of typed IR values. |
BinOp | Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, MOD, POW, MIN). |
BinOpKind | |
Block | Unified block representation for all pipeline stages. |
BlockKind | Classification of block structure for pipeline stages. |
CallPolicy | Describe the default lowering policy for a callable call. |
CallTransform | Describe the requested transform of a callable implementation. |
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. |
ConcreteControlledU | Controlled-U with concrete (int) number of controls. |
ControlledGate | Wrapper for controlled version of a QKernel. |
ControlledUOperation | Base class for controlled-U operations. |
FloatType | Type representing a floating-point number. |
ForItemsOperation | Represents iteration over dict/iterable items. |
ForOperation | Represents a for loop operation. |
GateOperation | Quantum gate operation. |
GateOperationType | |
GlobalPhaseOperation | Multiply the complete quantum state by exp(i * phase). |
IfOperation | Represents an if-else conditional operation. |
InverseBlockOperation | Represent an inverse qkernel/block as a first-class IR operation. |
InverseGate | Callable wrapper that applies a QKernel’s inverse. |
InvokeOperation | Represent a composite, stdlib, or oracle call. |
MeasureOperation | |
MeasureQFixedOperation | Measure a quantum fixed-point number. |
MeasureVectorOperation | Measure a vector of qubits. |
Operation | |
OperationKind | Classification of operations for classical/quantum separation. |
Oracle | Represent an opaque oracle callable. |
PauliEvolveOp | Pauli evolution operation: exp(-i * gamma * H). |
QInitOperation | Initialize the qubit |
QKernel | Decorator class for Qamomile quantum kernels. |
QKernelLike | Describe the frontend surface required by compiler entrypoints. |
RegionArg | Explicit loop-carried value on a loop operation (MLIR-style iter_arg). |
ReturnOperation | Explicit return operation marking the end of a block with return values. |
SelectOperation | Quantum multiplexer: apply case_blocks[i] when the index reads i. |
StaticBindingProxy | Expose a registered static object surface during unbound tracing. |
SymbolicControlledU | Controlled-U with symbolic (Value) number of controls. |
TransformedOracle | Represent composable inverse and controlled transforms of an Oracle. |
UIntType | Type representing an unsigned integer. |
Value | A typed SSA value in the IR. |
ValueBase | Nominal base for every typed IR value. |
ValueSubstitutor | Substitute IR values in operations using a UUID-keyed mapping. |
VectorView | Strided view over a parent Vector, backed by a sliced ArrayValue. |
WhileOperation | Represents a while loop operation. |
Constants¶
ValueLike:TypeAlias='Value | ArrayValue | TupleValue | DictValue'
Functions¶
get_current_tracer [source]¶
def get_current_tracer() -> Tracerinverse [source]¶
def inverse(target: Oracle | TransformedOracle | QKernelLike | Callable[..., Any]) -> AnyCreate an inverse operation wrapper.
Native Qamomile gate functions are first synthesized into tiny
QKernel objects, then inverted with the same block walker used for
user-defined kernels. Qkernel-like composite gate callables created by
qmc.composite_gate reuse their wrapped qkernel body. Known QFT/IQFT
functions map directly to their counterpart so backend-native composite
emission remains available. Opaque Oracles retain their original
definition and cost boundary while the call records an inverse transform;
the result can be passed directly to qmc.control. Inverting an already
controlled Oracle produces the same transformed invocation as controlling
its inverse.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Oracle | TransformedOracle | QKernelLike | Callable[..., Any] | Opaque Oracle, transformed Oracle, native gate function, qkernel-like object, or supported stdlib function to invert. |
Returns:
Any — A callable inverse wrapper, or the opposite QFT/IQFT function.
Raises:
TypeError— Iftargetcannot be interpreted as a gate-like callable, or if a body-free class-based composite instance is passed directly.NotImplementedError— If an inverted kernel uses unsupported operations such asif/while/for itemscontrol flow,QInit, or aForOperationwhose bounds are not compile-time constants when the inverse wrapper is traced. Loop-carried classical values are supported for UInt carries with a constant additive recurrence and for unchanged Float carries. Nonzero Float recurrences, non-additive recurrences, and coupled carries are rejected uniformly before backend emission.
Example:
>>> import qamomile.circuit as qmc
>>> @qmc.qkernel
... def layer(q: qmc.Qubit, angle: qmc.Float) -> qmc.Qubit:
... q = qmc.h(q)
... q = qmc.rz(q, angle)
... return q
>>> @qmc.qkernel
... def circuit(angle: qmc.Float) -> qmc.Qubit:
... q = qmc.qubit("q")
... q = layer(q, angle)
... q = qmc.inverse(layer)(q, angle)
... return qinvoke_qkernel_with_operation [source]¶
def invoke_qkernel_with_operation(
kernel: Any,
invoke_block_factory: Any | None,
*args: Any = (),
**kwargs: Any = {},
) -> AnyInvoke a QKernel using a custom operation factory.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel instance. |
invoke_block_factory | Any | None | Optional callable that receives (block, inputs_map) and returns the invocation operation. |
*args | Any | Positional qkernel call arguments. |
**kwargs | Any | Keyword qkernel call arguments. |
Returns:
Any — A single frontend handle or a tuple of frontend handles matching
Any — the qkernel return annotation.
Raises:
TypeError— If an argument is not a frontend handle after literal promotion.RuntimeError— If no qkernel tracer is active, or if the generated invocation result count does not match the qkernel return annotation.
is_static_binding_annotation [source]¶
def is_static_binding_annotation(annotation: Any) -> boolReturn whether an annotation denotes a registered static binding.
Parameters:
| Name | Type | Description |
|---|---|---|
annotation | Any | Resolved qkernel parameter annotation. |
Returns:
bool — Whether the annotation is registered.
promote_literal_to_handle [source]¶
def promote_literal_to_handle(value: Any, expected_type: Any) -> AnyPromote a Python literal to a scalar handle for qkernel calls.
Parameters:
| Name | Type | Description |
|---|---|---|
value | Any | Argument value supplied at a qkernel call site. |
expected_type | Any | Callee annotation used to decide whether a scalar literal can be wrapped as UInt, Float, or Bit. |
Returns:
Any — A freshly-created scalar handle when a promotion rule applies,
Any — otherwise value unchanged.
qkernel_callable_attrs [source]¶
def qkernel_callable_attrs(kernel: Any) -> dict[str, Any]Return compiler attrs for a qkernel invocation.
Composite metadata lives directly on QKernel. This helper is the
single translation point from that frontend state into serializer-safe IR
attributes, so direct, controlled, and inverse calls share one identity.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object carrying callable metadata. |
Returns:
dict[str, Any] — dict[str, Any]: Serializer-friendly callable attributes.
qkernel_callable_def [source]¶
def qkernel_callable_def(kernel: Any, block: Block) -> CallableDefBuild the inline-by-default callable definition for a qkernel block.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object carrying callable metadata. |
block | Block | Implementation body for the qkernel. |
Returns:
CallableDef — Compiler-facing definition for the qkernel.
qkernel_callable_ref [source]¶
def qkernel_callable_ref(kernel: Any) -> CallableRefReturn the compiler-facing callable reference for a qkernel.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object carrying callable metadata. |
Returns:
CallableRef — Stable reference used by InvokeOperation call sites.
qkernel_invoke_block [source]¶
def qkernel_invoke_block(
kernel: Any,
block: Block,
inputs_map: Mapping[str, ValueLike],
) -> InvokeOperationCreate an InvokeOperation for a qkernel call.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object carrying callable metadata. |
block | Block | Callee body referenced by the callable definition. |
inputs_map | Mapping[str, ValueLike] | Actual argument values keyed by callee label. |
Returns:
InvokeOperation — Inline-by-default qkernel invocation.
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.
reject_aliased_quantum_args [source]¶
def reject_aliased_quantum_args(
kernel_name: str,
arguments: dict[str, Any],
*,
caller: str | None = None,
) -> NoneReject overlapping live quantum resources at one call boundary.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel_name | str | Name of the called qkernel for diagnostics. |
arguments | dict[str, Any] | Bound call arguments keyed by parameter name. |
caller | str | None | Optional operation label replacing the default QKernel[kernel_name] context. Defaults to None. |
Raises:
QubitConsumedError— If two quantum arguments may cover the same physical qubit.
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.
select_specialized_block [source]¶
def select_specialized_block(
kernel: Any,
arguments: dict[str, Any],
*,
require_handles: bool = True,
) -> BlockSelect the block implementation for a qkernel call site.
Centralizes call-site specialization so plain qkernel calls, controlled
calls, and inverse calls use the same rule. When concrete argument values
would change the callee trace (for example a concrete Vector[Qubit]
size or a bound structural classical value), the function returns a
temporary specialized block. Otherwise it returns the kernel’s cached
block.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object whose block should be selected. |
arguments | dict[str, Any] | Bound call arguments after literal promotion and frontend validation. Registered static bindings may remain concrete Python objects when require_handles is false. |
require_handles | bool | If True, specialization is skipped unless every argument is a frontend Handle. Defaults to True. |
Returns:
Block — Specialized call-site block or the cached kernel block.
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.
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.
validate_static_binding_argument [source]¶
def validate_static_binding_argument(annotation: Any, name: str, value: Any) -> AnyValidate a concrete binding or caller-owned symbolic binding proxy.
Parameters:
| Name | Type | Description |
|---|---|---|
annotation | Any | Registered qkernel parameter annotation. |
name | str | Callee parameter name used as the binding-slot identity. |
value | Any | Concrete registered object or symbolic binding proxy. |
Returns:
Any — The validated concrete object or unchanged symbolic proxy.
Raises:
TypeError— If a concrete object has the wrong type, or a symbolic proxy does not preserve the callee parameter’s slot name and type key.
Classes¶
ArrayBase [source]¶
class ArrayBase(Handle, Generic[T])Base class for array types (Vector, Matrix, Tensor).
Provides common functionality for array indexing and element access.
Constructor¶
def __init__(
self,
value: ArrayValue,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_shape: tuple[int | UInt, ...] = tuple(),
_borrowed_indices: dict[tuple[str, ...], 'tuple[UInt, ...] | Handle'] = dict(),
) -> NoneAttributes¶
element_type: Type[T]shape: tuple[int | UInt, ...] Return the shape of the array.value: ArrayValue
Methods¶
consume¶
def consume(self, operation_name: str = 'unknown') -> SelfConsume the array after validating its affine ownership state.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the consuming operation. Defaults to "unknown". |
Returns:
typing.Self — typing.Self: Fresh handle carrying the consumed array value.
Raises:
QubitConsumedError— If this handle or a covered slot was consumed.UnreturnedBorrowError— If a live element or slice borrow remains.
create¶
@classmethod
def create(
cls,
shape: tuple[int | UInt, ...],
name: str,
el_type: Type[T],
) -> 'ArrayBase[T]'Create an ArrayValue for the given shape and name.
validate_all_returned¶
def validate_all_returned(self) -> NoneValidate all borrowed elements have been returned.
Strict-return policy: an active slice view that is still
registered as the owner of any parent slot is treated as an
unreturned borrow even if the view itself has no outstanding
element borrows. The caller must perform an explicit slice
assignment (parent[a:b:c] = view) to release the view’s
bulk-borrow before consuming the parent. Destructively consumed
scalar or view owners (parked in the dict with _consumed set and
_consumed_by classified as :attr:ConsumeMode.DESTRUCTIVE)
record physically-destroyed slots and are not outstanding borrows; they survive
end-of-block so a later whole-array consume can detect and
reject the destroyed slots.
Raises:
UnreturnedBorrowError— If any elements are still borrowed, either directly or by a slice view that has not been explicitly returned via slice assignment.
validate_consumable¶
def validate_consumable(self, operation_name: str = 'unknown') -> NoneValidate an array consume without changing ownership state.
For quantum arrays, all borrowed elements must be returned before the array can be consumed. This ensures that no unreturned borrows are silently discarded by operations like qkernel calls or controlled gates.
When any slot of the array has already been physically consumed
by an earlier destructive element or view operation
(measure(q[0]) or measure(q[1::2]) followed by
measure(q)), this raises QubitConsumedError rather than
silently re-consuming those slots.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the prospective consuming operation. Defaults to "unknown". |
Raises:
QubitConsumedError— If this handle or any covered slot was already consumed.UnreturnedBorrowError— If a live element or slice borrow remains.
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
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
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.
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
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.
ControlledGate [source]¶
class ControlledGateWrapper for controlled version of a QKernel.
Created by calling control(qkernel). The resulting object
can be called like a gate function.
Example:
@qmc.qkernel
def phase_gate(q: Qubit, theta: float) -> Qubit:
return qmc.p(q, theta)
controlled_phase = qmc.control(phase_gate)
ctrl_out, tgt_out = controlled_phase(ctrl, target, theta=0.5)
# Add a call-site target phase. Under control this is observable.
ctrl_out, tgt_out = controlled_phase(
ctrl, target, theta=0.5, global_phase=phi
)
# Double-controlled
cc_phase = qmc.control(phase_gate, num_controls=2)
c0, c1, tgt = cc_phase(ctrl0, ctrl1, target, theta=0.5)Constructor¶
def __init__(
self,
qkernel: 'QKernel',
num_controls: int | UInt = 1,
*,
control_value: int | None = None,
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] | None = None,
target_inverse: bool = False,
) -> NoneWrap a QKernel as a controlled operation.
Parameters:
| Name | Type | Description |
|---|---|---|
qkernel | QKernel | The kernel to control. Built-in gate callables are not accepted directly here -- :func:control synthesizes a wrapper QKernel for them before instantiating ControlledGate -- so by this point qkernel must expose a dict input_types attribute and an inspect.Signature signature attribute. |
num_controls | int | UInt | Number of control qubits. A concrete Python or NumPy integer must be >= 1 and is normalized to a Python int; a symbolic UInt defers validation to emit time. Defaults to 1. A bool is rejected: it is not a valid control count even though bool subclasses int. |
control_value | int | None | Computational-basis value that activates the control. Bit zero describes the first flattened control qubit, following Qamomile’s LSB-first convention. None uses the ordinary all-ones state. Only supported with a concrete num_controls. Defaults to None. |
callable_ref | CallableRef | None | Optional source callable identity to record on emitted ControlledUOperation nodes. Defaults to the wrapped qkernel’s callable ref. |
callable_attrs | dict[str, Any] | None | Optional serializer-friendly attrs for the source callable. Defaults to qkernel attrs. |
target_inverse | bool | Whether the controlled target is the inverse of qkernel. Defaults to False. |
Raises:
TypeError— Ifnum_controlsis boolean or neither integral nor aUInt,control_valueis not a PythonintorNone, orqkerneldoes not expose a dictinput_types/ aninspect.Signaturesignature.ValueError— If a concretenum_controlsis less than one,control_valuedoes not fit its width, or a non-default value is combined with symbolicnum_controls.
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.
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]) -> 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.
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.
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.
InverseGate [source]¶
class InverseGateCallable wrapper that applies a QKernel’s inverse.
Parameters:
| Name | Type | Description |
|---|---|---|
qkernel | QKernel | Kernel whose inverse should be emitted. |
Constructor¶
def __init__(
self,
qkernel: QKernel,
*,
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] | None = None,
) -> NoneInitialize the inverse wrapper.
Parameters:
| Name | Type | Description |
|---|---|---|
qkernel | QKernel | Kernel whose inverse should be emitted. |
callable_ref | CallableRef | None | Optional stable identity of the source callable being inverted. Defaults to the qkernel ref. |
callable_attrs | dict[str, Any] | None | Optional attrs copied from the source callable. Defaults to qkernel attrs. |
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.
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
Oracle [source]¶
class OracleRepresent an opaque oracle callable.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | Human-readable oracle name. |
num_qubits | int | None | Number of target qubits consumed and returned by the oracle. None means the arity is provided by signature and may be vector-shaped. Python and NumPy integer scalars are accepted; booleans and negative values are rejected. |
num_control_qubits | int | Number of explicit control qubits required by scalar calls. Defaults to 0. |
signature | CallableSignature | None | Optional frontend signature for target operands only. It must not repeat the leading controls declared by num_control_qubits; those controls are prefixed by the Oracle automatically. When omitted, a fixed-width scalar/vector-compatible oracle is created from num_qubits. |
cost | ResourceEstimate | Callable[[OpaqueCostContext], ResourceEstimate] | None | Optional explicit cost for this bodyless callable. Both forms describe one ordinary application of the Oracle as declared, including num_control_qubits. Controls added later with qmc.control are projected by resource estimation. This is a complete definition-level contract: the author must include any phase-relevant work that later coherent controls need. The estimator does not infer omitted global-phase overhead. An intrinsic nonidentity phase is represented as a logical primitive in the aggregate gate and arity counts. A one-qubit phase entry is an upper-bound representative for the target-free phase, not an angle-aware reconstruction; use a body-backed global phase when angle-specific classification is required. Defaults to None. |
Raises:
TypeError— If a suppliednum_qubitsornum_control_qubitsis boolean or not an integral scalar.ValueError— If either width is negative, or neithernum_qubitsnorsignaturesupplies enough target-arity information.
Constructor¶
def __init__(
self,
name: str,
num_qubits: int | None = None,
*,
num_control_qubits: int = 0,
signature: CallableSignature | None = None,
cost: ResourceEstimate | Callable[[OpaqueCostContext], ResourceEstimate] | None = None,
) -> NoneInitialize an opaque oracle callable.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | Human-readable oracle name. |
num_qubits | int | None | Fixed scalar/vector width. Defaults to None when signature describes the callable. Python and NumPy integer scalars are accepted; booleans and negative values are rejected. |
num_control_qubits | int | Number of explicit scalar controls. Defaults to 0. |
signature | CallableSignature | None | Optional frontend signature for target operands only. Do not include controls declared by num_control_qubits; the Oracle prefixes those controls to its internal callable signature. Defaults to None. |
cost | ResourceEstimate | Callable[[OpaqueCostContext], ResourceEstimate] | None | Optional fixed or context-dependent opaque cost. The returned estimate describes one ordinary application of this Oracle definition, including its declared controls but excluding controls added by an outer transform. The result must be a complete definition-level contract, including phase-relevant work that an outer coherent control must transform. Represent an intrinsic nonidentity phase as a logical primitive in the aggregate gate and arity counts. A one-qubit phase entry is an upper-bound representative; use a body-backed global phase for angle-specific classification. Defaults to None. |
Raises:
TypeError— If a suppliednum_qubitsornum_control_qubitsis not a non-boolean integral scalar.ValueError— If neithernum_qubitsnorsignaturesupplies enough target-arity information, or if either width is negative.
Attributes¶
cost: ResourceEstimate | Callable[[OpaqueCostContext], ResourceEstimate] | Nonename: strnum_control_qubits: intnum_qubits: int | Nonesignature: CallableSignature | None
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
QKernel [source]¶
class QKernel(QKernelBuildMixin, QKernelVisualizationMixin, Generic[P, R])Decorator class for Qamomile quantum kernels.
Constructor¶
def __init__(self, func: Callable[P, R]) -> NoneAttributes¶
block: Block Compile the function to a hierarchical Block if not already compiled.effects: KernelEffect Return cached semantic effects of this qkernel.funcinput_types: dict[str, Any] Return resolved and frozen frontend input annotations.nameoutput_types: list[Any] Return the resolved frontend annotation for every output slot.raw_funcreturn_type: Any Return the resolved and frozen complete return annotation.signature
QKernelLike [source]¶
class QKernelLike(Protocol)Describe the frontend surface required by compiler entrypoints.
This protocol is intentionally structural. It lets decorator-created
composites reuse the qkernel inspection and build interface without making
them inherit from QKernel or exposing the compiler-facing callable
descriptor model as a frontend concept.
Attributes¶
block: Block Return the cached hierarchical body block.effects: KernelEffect Return cached semantic effects of the qkernel body.input_types: dict[str, Any] Return frontend input annotations by parameter name.name: str Return the user-facing callable name.output_types: list[Any] Return frontend output annotations.signature: inspect.Signature Return the Python call signature.
Methods¶
build¶
def build(self, parameters: list[str] | None = None, **kwargs: Any = {}) -> BlockBuild a traced body block.
Parameters:
| Name | Type | Description |
|---|---|---|
parameters | list[str] | None | Runtime parameter names to preserve. Defaults to None. |
**kwargs | Any | Compile-time bindings for non-parameter arguments. |
Returns:
Block — Traced hierarchical body block.
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
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.
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.
StaticBindingProxy [source]¶
class StaticBindingProxyExpose a registered static object surface during unbound tracing.
Parameters:
| Name | Type | Description |
|---|---|---|
spec | StaticBindingSpec | Registered object contract. |
name | str | QKernel parameter name identifying the binding slot. |
Constructor¶
def __init__(self, spec: StaticBindingSpec, name: str) -> NoneCreate symbolic fields and deferred callable members.
Parameters:
| Name | Type | Description |
|---|---|---|
spec | StaticBindingSpec | Registered object contract. |
name | str | QKernel parameter name identifying the binding slot. |
Attributes¶
slot: StaticBindingSlot Return the IR manifest entry owned by this proxy.
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]) -> OperationTransformedOracle [source]¶
class TransformedOracleRepresent composable inverse and controlled transforms of an Oracle.
The wrapped Oracle remains the definition boundary: its explicit cost
includes only controls declared by Oracle.num_control_qubits. This
wrapper records controls added later by qmc.control and whether the
call is inverted, so the resulting InvokeOperation can apply those
transforms exactly once.
Parameters:
| Name | Type | Description |
|---|---|---|
oracle | Oracle | Definition-level opaque Oracle. |
added_num_control_qubits | int | Number of controls added outside the Oracle definition. Defaults to 0. |
added_control_value | int | None | LSB-first activation value for the added controls, or None for all ones. Defaults to None. |
inverse | bool | Whether to apply the inverse Oracle. Defaults to False. |
Raises:
TypeError— Ifadded_num_control_qubitsis boolean or not integral, or a positive count is attached to a vector-signature Oracle.ValueError— If the added-control count is negative or its activation value is invalid for that width.
Constructor¶
def __init__(
self,
oracle: Oracle,
added_num_control_qubits: int = 0,
added_control_value: int | None = None,
inverse: bool = False,
) -> NoneAttributes¶
added_control_value: int | Noneadded_num_control_qubits: intinverse: boolname: str Return the source Oracle name.oracle: Oracle
Methods¶
controlled¶
def controlled(
self,
num_controls: int,
*,
control_value: int | None = None,
) -> TransformedOraclePrepend another concrete control group.
Parameters:
| Name | Type | Description |
|---|---|---|
num_controls | int | Number of newly added leading controls. |
control_value | int | None | LSB-first activation value for the new control group. None means all ones. Defaults to None. |
Returns:
TransformedOracle — Wrapper carrying the combined added-control
condition.
Raises:
TypeError— Ifnum_controlsis not a non-boolean integer orcontrol_valueis not a Python integer orNone, or the source Oracle uses a vector target signature.ValueError— Ifnum_controlsis not positive orcontrol_valuedoes not fit its width.
inverted¶
def inverted(self) -> Oracle | TransformedOracleToggle inverse application while preserving added controls.
Returns:
Oracle | TransformedOracle — Oracle | TransformedOracle: The original Oracle when every
transform cancels, otherwise a transformed wrapper.
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.
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.
VectorView [source]¶
class VectorView(Vector[T])Strided view over a parent Vector, backed by a sliced ArrayValue.
A VectorView is produced by slicing a Vector (q[1::2],
q[a:b], etc.). It is a thin Vector subclass whose value
is a fresh ArrayValue with slice_of / slice_start /
slice_step metadata pointing back to the parent’s ArrayValue.
Element accesses go through Vector._get_element unchanged — the
IR element carries parent_array = sliced_av, and the emit-time
resolver walks the slice_of chain to produce the physical qubit
index. No affine translation happens in the view itself.
Because the sliced ArrayValue is a first-class IR Value,
the view can be passed as an operand of an inline callable invocation
to another qkernel without the inline-trace special-case path that
earlier iterations required. Passing views through
expval / measure likewise operates on the sliced qubit
subset, not the root parent as a whole.
Linearity:
Slicing bulk-borrows the covered parent slots whenever
start, step and length are compile-time int
constants. While the view is live, accessing the corresponding
parent slot directly (q[0] after evens = q[0::2]) raises
QubitConsumedError. Under the strict-return policy the
view’s ownership is cleared only by two operations:
slice-assigning it back into the parent (
parent[a:b:c] = view) — this is the only path that fully releases the borrow without destroying the qubits;destructively consuming it (
measure(view)/cast(view, ...)/expval(view, H)) — the physical slots become consumed markers, no return needed.
Every other consume (broadcast gates h(view),
pauli_evolve(view, H, gamma), sub-kernel calls
f(view), controlled-U index_spec) only transfers
ownership to a freshly-wrapped VectorView and that new
view still must be returned via slice assignment. A view
left bulk-borrowing at the parent’s consume point raises
UnreturnedBorrowError.
Symbolic slices (q[lo:hi] with lo/hi UInt) cannot
enumerate their covered slots at trace time and therefore skip
the bulk-borrow here; SliceBorrowCheckPass picks them up
post-fold after bindings resolve the bounds to concrete values.
Example:
@qmc.qkernel
def alternating_h(q: qmc.Vector[qmc.Qubit]) -> qmc.Vector[qmc.Qubit]:
evens = q[0::2]
for i in qmc.range(evens.shape[0]):
evens[i] = qmc.h(evens[i])
q[0::2] = evens # explicit return before the parent is used
return qMethods¶
consume¶
def consume(self, operation_name: str = 'unknown') -> SelfConsume the view and release its parent slice-borrows.
Validates that every view-local borrow has been returned,
then dispatches on operation_name to keep the parent’s
slice-borrow record consistent with the new strict-return
semantics:
Destructive (
measure/cast): leaveselfparked in the parent’s borrow table as a destroyed-slot breadcrumb.super().consume()flipsself._consumed = Trueandself._consumed_by = operation_name, which is what :func:_is_destroyed_slot_ownerreads to reject subsequent access at the same slot.Releasing (
slice assignment): drop every parent entry thatselfcurrently owns. The caller (the slice- assignment frontend path) also emits aReleaseSliceViewOperationso the IR-level checker sees the release. This branch is reserved for explicit borrow- return paths.Transfer (every other op — broadcast gates, rotation, phase, ControlledU, sub-kernel call argument consumption, etc.): rebind the parent’s borrow entry from
selfto the new view handle returned here. The new view inheritsself._slice_covered_indicesso it can be slice-assigned back to the parent later — strict-return requires that eventualparent[a:b:c] = new_view.
Operations that produce a fresh sliced ArrayValue (e.g.
:func:qamomile.circuit.frontend.operation.pauli_evolve.pauli_evolve,
:class:QKernel.__call__ for callees that return a sliced
array) cannot simply use the auto-returned new_view
because the new view they build wraps a different Value
than this consume’s return. Those op implementations call
:meth:_transfer_borrow_to after building their result so
the parent’s borrow table tracks the right handle.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the operation consuming this view (used in error messages and for dispatch). |
Returns:
typing.Self — A fresh view handle with the same backing state; under
typing.Self — transfer the parent’s borrow table now points at this
typing.Self — handle, under release / destruction the parent’s record
typing.Self — for the covered slots is finalised.
Raises:
QubitConsumedError— If any covered slot was already destroyed by a prior destructive consume on an overlapping element or view.
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.frontend.operation.math¶
Build abstract unary mathematical expressions for qkernel tracing.
Overview¶
| Function | Description |
|---|---|
ceil | Round a numeric expression upward to a non-negative integer. |
get_current_tracer | |
log2 | Compute a base-two logarithm as an abstract real expression. |
| Class | Description |
|---|---|
Float | Floating-point handle with arithmetic operations. |
FloatType | Type representing a floating-point number. |
UInt | Unsigned integer handle with arithmetic operations. |
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. |
Functions¶
ceil [source]¶
def ceil(value: Float | UInt | int | float) -> UIntRound a numeric expression upward to a non-negative integer.
UInt is Qamomile’s structural integer type, so inputs whose ceiling is
negative are outside this operation’s domain. For finite real values this
accepts exactly value > -1. Concrete values fold immediately;
unresolved values emit one abstract CEIL operation.
Parameters:
| Name | Type | Description |
|---|---|---|
value | Float | UInt | int | float | Finite numeric expression whose ceiling is non-negative. |
Returns:
UInt — Least integer greater than or equal to value.
Raises:
TypeError— Ifvalueis not a supported numeric input.ValueError— If a concrete input is non-finite or rounds to a negative integer.
get_current_tracer [source]¶
def get_current_tracer() -> Tracerlog2 [source]¶
def log2(value: UInt | Float | int | float) -> FloatCompute a base-two logarithm as an abstract real expression.
Concrete values fold immediately. Unresolved qkernel values emit one
abstract LOG2 operation so structural expressions such as
ceil(log2(n)) remain visible until compile-time bindings are applied.
Parameters:
| Name | Type | Description |
|---|---|---|
value | UInt | Float | int | float | Strictly positive input. |
Returns:
Float — Base-two logarithm of value.
Raises:
TypeError— Ifvalueis not a supported numeric input.ValueError— If a concrete input is non-finite or not strictly positive.
Classes¶
Float [source]¶
class Float(ArithmeticMixin, Handle)Floating-point handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: float = 0.0,
) -> NoneAttributes¶
init_value: float
FloatType [source]¶
class FloatType(ClassicalTypeMixin, ValueType)Type representing a floating-point number.
UInt [source]¶
class UInt(ArithmeticMixin, Handle)Unsigned integer handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: int = 0,
) -> NoneAttributes¶
init_value: int
UIntType [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.
qamomile.circuit.frontend.operation.measurement¶
Measurement operations for quantum circuits.
Overview¶
| Function | Description |
|---|---|
get_current_tracer | |
measure | Measure a qubit or QFixed in the computational basis. |
measure_reset | Measure a qubit in the Z basis and reset it to |0>. |
project_x | Project a qubit in the X basis and keep the projected state. |
project_y | Project a qubit in the Y basis and keep the projected state. |
project_z | Project a qubit in the Z basis and keep the projected state. |
reset | Reset a qubit to the |0> state. |
| Class | Description |
|---|---|
ArrayValue | An array of typed IR values. |
IRMeasureOperation | |
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. |
ResetOperation | Reset a qubit to the |0> state and return the fresh handle. |
UIntType | Type representing an unsigned integer. |
Value | A typed SSA value in the IR. |
VectorClass | 1-dimensional array type. |
Functions¶
get_current_tracer [source]¶
def get_current_tracer() -> Tracermeasure [source]¶
def measure(target: Union[Qubit, QFixed, Vector[Qubit]]) -> Union[Bit, Float, Vector[Bit]]Measure a qubit or QFixed in the computational basis.
Performs a projective measurement in the Z-basis. The quantum resource is consumed by this operation and cannot be used afterwards.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Qubit | QFixed | Vector[Qubit] | Quantum resource to measure. - Qubit: Returns a classical Bit - QFixed: Returns a Float (decoded from measured bits) |
Returns:
Union[Bit, Float, Vector[Bit]] — Bit | Float | Vector[Bit]: Classical result matching the input shape.
Raises:
TypeError— Iftargetis not a supported quantum handle.QubitConsumedError— If the quantum resource was already consumed.RuntimeError— If no tracer is active.
Example:
@qkernel
def measure_qubit(q: Qubit) -> Bit:
q = h(q)
return measure(q)
@qkernel
def measure_qfixed(qf: QFixed) -> Float:
# After QPE, qf holds phase bits
return measure(qf)measure_reset [source]¶
def measure_reset(qubit: Qubit) -> tuple[Qubit, Bit]Measure a qubit in the Z basis and reset it to |0>.
Parameters:
| Name | Type | Description |
|---|---|---|
qubit | Qubit | Qubit to measure and reset. |
Returns:
tuple[Qubit, Bit] — tuple[Qubit, Bit]: Reset qubit handle and measurement bit.
Raises:
QubitConsumedError— Ifqubitwas already consumed.RuntimeError— If no tracer is active.
project_x [source]¶
def project_x(qubit: Qubit) -> tuple[Qubit, Bit]Project a qubit in the X basis and keep the projected state.
Parameters:
| Name | Type | Description |
|---|---|---|
qubit | Qubit | Qubit to project. The input handle is consumed. |
Returns:
tuple[Qubit, Bit] — tuple[Qubit, Bit]: Projected qubit handle and measurement bit.
Raises:
QubitConsumedError— Ifqubitwas already consumed.RuntimeError— If no tracer is active.
project_y [source]¶
def project_y(qubit: Qubit) -> tuple[Qubit, Bit]Project a qubit in the Y basis and keep the projected state.
Parameters:
| Name | Type | Description |
|---|---|---|
qubit | Qubit | Qubit to project. The input handle is consumed. |
Returns:
tuple[Qubit, Bit] — tuple[Qubit, Bit]: Projected qubit handle and measurement bit.
Raises:
QubitConsumedError— Ifqubitwas already consumed.RuntimeError— If no tracer is active.
project_z [source]¶
def project_z(qubit: Qubit) -> tuple[Qubit, Bit]Project a qubit in the Z basis and keep the projected state.
Parameters:
| Name | Type | Description |
|---|---|---|
qubit | Qubit | Qubit to project. The input handle is consumed. |
Returns:
tuple[Qubit, Bit] — tuple[Qubit, Bit]: Projected qubit handle and measurement bit.
Raises:
QubitConsumedError— Ifqubitwas already consumed.RuntimeError— If no tracer is active.
reset [source]¶
def reset(qubit: Qubit) -> QubitReset a qubit to the |0> state.
Parameters:
| Name | Type | Description |
|---|---|---|
qubit | Qubit | Qubit to reset. The input handle is consumed. |
Returns:
Qubit — Fresh handle for the reset qubit.
Raises:
QubitConsumedError— Ifqubitwas already consumed.RuntimeError— If no tracer is active.
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]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
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
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.
Vector [source]¶
class Vector(ArrayBase[T])1-dimensional array type.
Example:
import qamomile.circuit as qmc
# Create a vector of 3 qubits
qubits: qmc.Vector[qmc.Qubit] = qmc.qubit_array(3, name="qubits")
# Access elements
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0
# Apply H gate to all qubits (CORRECT)
n = qubits.shape[0]
for i in qmc.range(n):
qubits[i] = qmc.h(qubits[i])
# Slicing returns a VectorView over a subset of the parent vector.
# The view shares borrow tracking with the parent; element access
# on the view transparently indexes the parent.
evens = qubits[0::2]
for i in qmc.range(evens.shape[0]):
evens[i] = qmc.h(evens[i])Constructor¶
def __init__(
self,
value: ArrayValue = None,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_shape: tuple[int | UInt] = (0,),
_borrowed_indices: dict[tuple[str, ...], 'tuple[UInt, ...] | Handle'] = dict(),
) -> NoneAttributes¶
value: ArrayValue
qamomile.circuit.frontend.operation.pauli_evolve¶
Pauli evolution operation for applying exp(-i * gamma * H).
This module provides the pauli_evolve() function for applying the
time evolution operator of a Pauli Hamiltonian to a quantum state.
Overview¶
| Function | Description |
|---|---|
get_current_tracer | |
pauli_evolve | Apply exp(-i * gamma * H) to a qubit register. |
| Class | Description |
|---|---|
PauliEvolveOp | Pauli evolution operation: exp(-i * gamma * H). |
VectorView | Strided view over a parent Vector, backed by a sliced ArrayValue. |
Functions¶
get_current_tracer [source]¶
def get_current_tracer() -> Tracerpauli_evolve [source]¶
def pauli_evolve(q: Vector[Qubit], hamiltonian: Observable, gamma: Float) -> Vector[Qubit]Apply exp(-i * gamma * H) to a qubit register.
Implements Hamiltonian time evolution using the Pauli gadget technique. The actual Hamiltonian is provided via bindings at transpile time.
Each backend can use native implementations:
Qiskit: PauliEvolutionGate
QuriParts: PauliRotation gates
Others: fallback decomposition (basis change + CNOT ladder + RZ)
Parameters:
| Name | Type | Description |
|---|---|---|
q | Vector[Qubit] | VectorView[Qubit] | The quantum register to evolve. It may have more qubits than the Hamiltonian acts on: each Pauli term addresses register elements positionally (PauliOperator.index i acts on q[i]), and qubits beyond hamiltonian.num_qubits evolve under the identity. |
hamiltonian | Observable | Observable parameter referencing the Hamiltonian. The actual qamomile.observable.Hamiltonian is provided via bindings. A Hamiltonian acting on more qubits than q provides fails with EmitError at transpile time. |
gamma | Float | Evolution time / variational parameter. |
Returns:
Vector[Qubit] — Vector[Qubit]: The evolved qubit register.
Example:
import qamomile.circuit as qmc
import qamomile.observable as qm_o
H = 0.5 * qm_o.X(0) * qm_o.Z(1) + qm_o.Z(0)
@qmc.qkernel
def cost_layer(
q: qmc.Vector[qmc.Qubit],
H: qmc.Observable,
gamma: qmc.Float,
) -> qmc.Vector[qmc.Qubit]:
q = qmc.pauli_evolve(q, H, gamma)
return q
transpiler = QiskitTranspiler()
exe = transpiler.transpile(cost_layer, bindings={"H": H, "gamma": 0.5})Classes¶
PauliEvolveOp [source]¶
class PauliEvolveOp(Operation)Pauli evolution operation: exp(-i * gamma * H).
This operation applies the time evolution of a Pauli Hamiltonian to a quantum register.
Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> 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
VectorView [source]¶
class VectorView(Vector[T])Strided view over a parent Vector, backed by a sliced ArrayValue.
A VectorView is produced by slicing a Vector (q[1::2],
q[a:b], etc.). It is a thin Vector subclass whose value
is a fresh ArrayValue with slice_of / slice_start /
slice_step metadata pointing back to the parent’s ArrayValue.
Element accesses go through Vector._get_element unchanged — the
IR element carries parent_array = sliced_av, and the emit-time
resolver walks the slice_of chain to produce the physical qubit
index. No affine translation happens in the view itself.
Because the sliced ArrayValue is a first-class IR Value,
the view can be passed as an operand of an inline callable invocation
to another qkernel without the inline-trace special-case path that
earlier iterations required. Passing views through
expval / measure likewise operates on the sliced qubit
subset, not the root parent as a whole.
Linearity:
Slicing bulk-borrows the covered parent slots whenever
start, step and length are compile-time int
constants. While the view is live, accessing the corresponding
parent slot directly (q[0] after evens = q[0::2]) raises
QubitConsumedError. Under the strict-return policy the
view’s ownership is cleared only by two operations:
slice-assigning it back into the parent (
parent[a:b:c] = view) — this is the only path that fully releases the borrow without destroying the qubits;destructively consuming it (
measure(view)/cast(view, ...)/expval(view, H)) — the physical slots become consumed markers, no return needed.
Every other consume (broadcast gates h(view),
pauli_evolve(view, H, gamma), sub-kernel calls
f(view), controlled-U index_spec) only transfers
ownership to a freshly-wrapped VectorView and that new
view still must be returned via slice assignment. A view
left bulk-borrowing at the parent’s consume point raises
UnreturnedBorrowError.
Symbolic slices (q[lo:hi] with lo/hi UInt) cannot
enumerate their covered slots at trace time and therefore skip
the bulk-borrow here; SliceBorrowCheckPass picks them up
post-fold after bindings resolve the bounds to concrete values.
Example:
@qmc.qkernel
def alternating_h(q: qmc.Vector[qmc.Qubit]) -> qmc.Vector[qmc.Qubit]:
evens = q[0::2]
for i in qmc.range(evens.shape[0]):
evens[i] = qmc.h(evens[i])
q[0::2] = evens # explicit return before the parent is used
return qMethods¶
consume¶
def consume(self, operation_name: str = 'unknown') -> SelfConsume the view and release its parent slice-borrows.
Validates that every view-local borrow has been returned,
then dispatches on operation_name to keep the parent’s
slice-borrow record consistent with the new strict-return
semantics:
Destructive (
measure/cast): leaveselfparked in the parent’s borrow table as a destroyed-slot breadcrumb.super().consume()flipsself._consumed = Trueandself._consumed_by = operation_name, which is what :func:_is_destroyed_slot_ownerreads to reject subsequent access at the same slot.Releasing (
slice assignment): drop every parent entry thatselfcurrently owns. The caller (the slice- assignment frontend path) also emits aReleaseSliceViewOperationso the IR-level checker sees the release. This branch is reserved for explicit borrow- return paths.Transfer (every other op — broadcast gates, rotation, phase, ControlledU, sub-kernel call argument consumption, etc.): rebind the parent’s borrow entry from
selfto the new view handle returned here. The new view inheritsself._slice_covered_indicesso it can be slice-assigned back to the parent later — strict-return requires that eventualparent[a:b:c] = new_view.
Operations that produce a fresh sliced ArrayValue (e.g.
:func:qamomile.circuit.frontend.operation.pauli_evolve.pauli_evolve,
:class:QKernel.__call__ for callees that return a sliced
array) cannot simply use the auto-returned new_view
because the new view they build wraps a different Value
than this consume’s return. Those op implementations call
:meth:_transfer_borrow_to after building their result so
the parent’s borrow table tracks the right handle.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the operation consuming this view (used in error messages and for dispatch). |
Returns:
typing.Self — A fresh view handle with the same backing state; under
typing.Self — transfer the parent’s borrow table now points at this
typing.Self — handle, under release / destruction the parent’s record
typing.Self — for the covered slots is finalised.
Raises:
QubitConsumedError— If any covered slot was already destroyed by a prior destructive consume on an overlapping element or view.
qamomile.circuit.frontend.operation.qubit_gates¶
Overview¶
| Function | Description |
|---|---|
ccx | Toffoli (CCX) gate: flips target when both controls are |1>. |
cp | Apply a controlled phase gate. |
cx | CNOT (Controlled-X) gate. |
cz | CZ (Controlled-Z) gate. |
get_current_tracer | |
h | Hadamard gate. |
p | Phase gate: P(theta)|1> = e^{i*theta}|1>. |
rx | Rotation around X-axis: RX(angle) = exp(-i * angle/2 * X). |
ry | Rotation around Y-axis: RY(angle) = exp(-i * angle/2 * Y). |
rz | Rotation around Z-axis: RZ(angle) = exp(-i * angle/2 * Z). |
rzz | RZZ gate: exp(-i * angle/2 * Z ⊗ Z). |
s | S gate (square root of Z). |
sdg | S-dagger gate (inverse of S gate). |
swap | SWAP gate: exchanges two qubits. |
t | T gate (fourth root of Z). |
tdg | T-dagger gate (inverse of T gate). |
x | Pauli-X gate (NOT gate). |
y | Pauli-Y gate. |
z | Pauli-Z gate. |
| Class | Description |
|---|---|
FloatType | Type representing a floating-point number. |
GateOperationType | |
IRGateOperation | Quantum gate operation. |
QubitAliasError | Same qubit used multiple times in one operation. |
Value | A typed SSA value in the IR. |
VectorClass | 1-dimensional array type. |
Functions¶
ccx [source]¶
def ccx(control1: Qubit, control2: Qubit, target: Qubit) -> tuple[Qubit, Qubit, Qubit]Toffoli (CCX) gate: flips target when both controls are |1>.
Parameters:
| Name | Type | Description |
|---|---|---|
control1 | Qubit | First control qubit. |
control2 | Qubit | Second control qubit. |
target | Qubit | Target qubit. |
Returns:
tuple[Qubit, Qubit, Qubit] — Tuple of (control1_out, control2_out, target_out) after CCX.
cp [source]¶
def cp(
control: Qubit,
target: Qubit,
theta: float | Float | UInt,
) -> tuple[Qubit, Qubit]Apply a controlled phase gate.
Parameters:
| Name | Type | Description |
|---|---|---|
control | Qubit | Control input qubit. |
target | Qubit | Target input qubit. |
theta | float | Float | UInt | Phase angle in radians. |
Returns:
tuple[Qubit, Qubit] — tuple[Qubit, Qubit]: Fresh control and target handles.
Raises:
QubitAliasError— If control and target are the same logical qubit.QubitConsumedError— If either input was already consumed.RuntimeError— If no tracer is active.
cx [source]¶
def cx(control: Qubit, target: Qubit) -> tuple[Qubit, Qubit]CNOT (Controlled-X) gate.
cz [source]¶
def cz(control: Qubit, target: Qubit) -> tuple[Qubit, Qubit]CZ (Controlled-Z) gate.
get_current_tracer [source]¶
def get_current_tracer() -> Tracerh [source]¶
def h(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]Hadamard gate.
Applied to a single Qubit it returns the transformed qubit. Applied
to a Vector[Qubit] it broadcasts the gate over every element via a
transpile-time loop, equivalent to
for i in qmc.range(n): qs[i] = h(qs[i]).
Parameters:
| Name | Type | Description |
|---|---|---|
target | Union[Qubit, Vector[Qubit]] | A single Qubit or a Vector[Qubit] to apply H to. |
Returns:
Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.
Raises:
TypeError— Iftargetis neither aQubitnor aVector[Qubit].
p [source]¶
def p(
target: Union[Qubit, Vector[Qubit]],
theta: float | Float | UInt,
) -> Union[Qubit, Vector[Qubit]]Phase gate: P(theta)|1> = e^{i*theta}|1>.
Broadcasts the same theta over every qubit when called with a
Vector[Qubit].
Parameters:
| Name | Type | Description |
|---|---|---|
target | Union[Qubit, Vector[Qubit]] | A single Qubit or a Vector[Qubit] to apply the phase to. |
theta | float | Float | UInt | Phase angle in radians. |
Returns:
Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.
Raises:
TypeError— Iftargetis neither aQubitnor aVector[Qubit].
rx [source]¶
def rx(
target: Union[Qubit, Vector[Qubit]],
angle: float | Float | UInt,
) -> Union[Qubit, Vector[Qubit]]Rotation around X-axis: RX(angle) = exp(-i * angle/2 * X).
Broadcasts the same angle over every qubit when called with a
Vector[Qubit].
Parameters:
| Name | Type | Description |
|---|---|---|
target | Union[Qubit, Vector[Qubit]] | A single Qubit or a Vector[Qubit]. |
angle | float | Float | UInt | Rotation angle in radians. |
Returns:
Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.
Raises:
TypeError— Iftargetis neither aQubitnor aVector[Qubit].
ry [source]¶
def ry(
target: Union[Qubit, Vector[Qubit]],
angle: float | Float | UInt,
) -> Union[Qubit, Vector[Qubit]]Rotation around Y-axis: RY(angle) = exp(-i * angle/2 * Y).
Broadcasts the same angle over every qubit when called with a
Vector[Qubit].
Parameters:
| Name | Type | Description |
|---|---|---|
target | Union[Qubit, Vector[Qubit]] | A single Qubit or a Vector[Qubit]. |
angle | float | Float | UInt | Rotation angle in radians. |
Returns:
Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.
Raises:
TypeError— Iftargetis neither aQubitnor aVector[Qubit].
rz [source]¶
def rz(
target: Union[Qubit, Vector[Qubit]],
angle: float | Float | UInt,
) -> Union[Qubit, Vector[Qubit]]Rotation around Z-axis: RZ(angle) = exp(-i * angle/2 * Z).
Broadcasts the same angle over every qubit when called with a
Vector[Qubit].
Parameters:
| Name | Type | Description |
|---|---|---|
target | Union[Qubit, Vector[Qubit]] | A single Qubit or a Vector[Qubit]. |
angle | float | Float | UInt | Rotation angle in radians. |
Returns:
Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.
Raises:
TypeError— Iftargetis neither aQubitnor aVector[Qubit].
rzz [source]¶
def rzz(
qubit_0: Qubit,
qubit_1: Qubit,
angle: float | Float | UInt,
) -> tuple[Qubit, Qubit]RZZ gate: exp(-i * angle/2 * Z ⊗ Z).
The RZZ gate applies a rotation around the ZZ axis on two qubits.
Parameters:
| Name | Type | Description |
|---|---|---|
qubit_0 | Qubit | First input qubit. |
qubit_1 | Qubit | Second input qubit. |
angle | float | Float | UInt | Rotation angle in radians. |
Returns:
tuple[Qubit, Qubit] — tuple[Qubit, Qubit]: Fresh handles after the RZZ operation.
Raises:
QubitAliasError— If both inputs are the same logical qubit.QubitConsumedError— If either input was already consumed.RuntimeError— If no tracer is active.
s [source]¶
def s(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]S gate (square root of Z).
Broadcasts over a Vector[Qubit] when applied to one.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Union[Qubit, Vector[Qubit]] | A single Qubit or a Vector[Qubit]. |
Returns:
Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.
Raises:
TypeError— Iftargetis neither aQubitnor aVector[Qubit].
sdg [source]¶
def sdg(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]S-dagger gate (inverse of S gate).
Broadcasts over a Vector[Qubit] when applied to one.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Union[Qubit, Vector[Qubit]] | A single Qubit or a Vector[Qubit]. |
Returns:
Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.
Raises:
TypeError— Iftargetis neither aQubitnor aVector[Qubit].
swap [source]¶
def swap(qubit_0: Qubit, qubit_1: Qubit) -> tuple[Qubit, Qubit]SWAP gate: exchanges two qubits.
The SWAP gate swaps the states of two qubits.
Parameters:
| Name | Type | Description |
|---|---|---|
qubit_0 | Qubit | First qubit. |
qubit_1 | Qubit | Second qubit. |
Returns:
tuple[Qubit, Qubit] — Tuple of (qubit_0_out, qubit_1_out) after SWAP.
t [source]¶
def t(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]T gate (fourth root of Z).
Broadcasts over a Vector[Qubit] when applied to one.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Union[Qubit, Vector[Qubit]] | A single Qubit or a Vector[Qubit]. |
Returns:
Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.
Raises:
TypeError— Iftargetis neither aQubitnor aVector[Qubit].
tdg [source]¶
def tdg(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]T-dagger gate (inverse of T gate).
Broadcasts over a Vector[Qubit] when applied to one.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Union[Qubit, Vector[Qubit]] | A single Qubit or a Vector[Qubit]. |
Returns:
Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.
Raises:
TypeError— Iftargetis neither aQubitnor aVector[Qubit].
x [source]¶
def x(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]Pauli-X gate (NOT gate).
Broadcasts over a Vector[Qubit] when applied to one.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Union[Qubit, Vector[Qubit]] | A single Qubit or a Vector[Qubit]. |
Returns:
Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.
Raises:
TypeError— Iftargetis neither aQubitnor aVector[Qubit].
y [source]¶
def y(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]Pauli-Y gate.
Broadcasts over a Vector[Qubit] when applied to one.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Union[Qubit, Vector[Qubit]] | A single Qubit or a Vector[Qubit]. |
Returns:
Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.
Raises:
TypeError— Iftargetis neither aQubitnor aVector[Qubit].
z [source]¶
def z(target: Union[Qubit, Vector[Qubit]]) -> Union[Qubit, Vector[Qubit]]Pauli-Z gate.
Broadcasts over a Vector[Qubit] when applied to one.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Union[Qubit, Vector[Qubit]] | A single Qubit or a Vector[Qubit]. |
Returns:
Union[Qubit, Vector[Qubit]] — A Qubit for scalar input, a Vector[Qubit] for array input.
Raises:
TypeError— Iftargetis neither aQubitnor aVector[Qubit].
Classes¶
FloatType [source]¶
class FloatType(ClassicalTypeMixin, ValueType)Type representing a floating-point number.
GateOperationType [source]¶
class GateOperationType(enum.Enum)Attributes¶
CPCXCZHPRXRYRZRZZSSDGSWAPTTDGTOFFOLIXYZ
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.
QubitAliasError [source]¶
class QubitAliasError(AffineTypeError)Same qubit used multiple times in one operation.
Operations like cx() require distinct qubits for control and target. Using the same qubit in both positions is physically impossible and indicates a programming error.
Example of incorrect code:
q1, q2 = qm.cx(q, q) # ERROR: same qubit as control and target
Correct code:
q1, q2 = qm.cx(control, target) # Use distinct qubits
Value [source]¶
class Value(_MetadataValueMixin, 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.
Vector [source]¶
class Vector(ArrayBase[T])1-dimensional array type.
Example:
import qamomile.circuit as qmc
# Create a vector of 3 qubits
qubits: qmc.Vector[qmc.Qubit] = qmc.qubit_array(3, name="qubits")
# Access elements
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0
# Apply H gate to all qubits (CORRECT)
n = qubits.shape[0]
for i in qmc.range(n):
qubits[i] = qmc.h(qubits[i])
# Slicing returns a VectorView over a subset of the parent vector.
# The view shares borrow tracking with the parent; element access
# on the view transparently indexes the parent.
evens = qubits[0::2]
for i in qmc.range(evens.shape[0]):
evens[i] = qmc.h(evens[i])Constructor¶
def __init__(
self,
value: ArrayValue = None,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_shape: tuple[int | UInt] = (0,),
_borrowed_indices: dict[tuple[str, ...], 'tuple[UInt, ...] | Handle'] = dict(),
) -> NoneAttributes¶
value: ArrayValue
qamomile .circuit .frontend .operation .select¶
Frontend qmc.select: the quantum multiplexer (SELECT) gate.
qmc.select([U_0, U_1, ...], num_index_qubits=...) builds a
:class:SelectGate that applies U_i to a shared target register when an
index (select) register reads the integer i::
sel = qmc.select([qmc.x, qmc.y, qmc.z, qmc.h])
idx_out, tgt_out = sel(index_register, target)With the default num_index_qubits=None, the width is inferred as
ceil(log2(len(cases))). An explicit int may be wider, leaving the
extra index states as identity, while UInt defers the width to transpile
time. Leading positional Qubit / Vector / VectorView arguments
form the index prefix; the shared case signature identifies the trailing
target and parameter arguments. Index bit order follows Qamomile’s LSB-first
convention: the first flattened index qubit is bit zero.
The frontend reuses qmc.control’s operand / result machinery (so every
control-prefix and target handle pattern is supported identically) but emits a
single :class:SelectOperation. Circuit-family lowering preserves the SELECT
identity as a reusable call and keeps each case as a controlled fallback call.
Overview¶
| Function | Description |
|---|---|
get_current_tracer | |
qkernel_callable_attrs | Return compiler attrs for a qkernel invocation. |
select | Create a quantum multiplexer (SELECT) over a list of unitaries. |
select_specialized_block | Select the block implementation for a qkernel call site. |
| Class | Description |
|---|---|
Block | Unified block representation for all pipeline stages. |
ControlledGate | Wrapper for controlled version of a QKernel. |
ControlledUOperation | Base class for controlled-U operations. |
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. |
Operation | |
OperationKind | Classification of operations for classical/quantum separation. |
QInitOperation | Initialize the qubit |
QKernel | Decorator class for Qamomile quantum kernels. |
ResetOperation | Reset a qubit to the |0> state and return the fresh handle. |
SelectGate | Callable wrapper for a quantum multiplexer over a list of unitaries. |
SelectOperation | Quantum multiplexer: apply case_blocks[i] when the index reads i. |
UInt | Unsigned integer handle with arithmetic operations. |
Functions¶
get_current_tracer [source]¶
def get_current_tracer() -> Tracerqkernel_callable_attrs [source]¶
def qkernel_callable_attrs(kernel: Any) -> dict[str, Any]Return compiler attrs for a qkernel invocation.
Composite metadata lives directly on QKernel. This helper is the
single translation point from that frontend state into serializer-safe IR
attributes, so direct, controlled, and inverse calls share one identity.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object carrying callable metadata. |
Returns:
dict[str, Any] — dict[str, Any]: Serializer-friendly callable attributes.
select [source]¶
def select(
cases: Sequence['QKernel | Callable[..., Any]'],
num_index_qubits: int | UInt | None = None,
) -> SelectGateCreate a quantum multiplexer (SELECT) over a list of unitaries.
The returned gate applies cases[i] to a shared target register
when the index register reads the integer i with index qubit zero as
the least-significant bit. len(cases) need not be a power of
two; index values >= len(cases) apply no operation.
A scalar Qubit case called with a Vector[Qubit] or
VectorView[Qubit] target is applied independently to every element.
This is the same tensor-product unitary as an explicit per-element loop,
including one copy of the scalar case’s global phase per element. A phase
intended for the complete register belongs on a case whose parameter is
itself Vector[Qubit].
Circuit-family lowering retains the abstract SELECT identity while its
portable fallback invokes each case under the corresponding mixed
0/1 (anti-/normal) index pattern.
Parameters:
| Name | Type | Description |
|---|---|---|
cases | Sequence[QKernel | Callable[..., Any]] | The case unitaries in ascending index order. Each may be a @qmc.qkernel function, a qkernel-backed composite gate, or a built-in gate callable. All cases must share the same parameter signature and act on the same target register. |
num_index_qubits | int | UInt | None | Number of leading index qubits. None infers the minimal width from the case count. A wider concrete value leaves its unassigned index states as identity. UInt defers the width check to transpilation. Defaults to None. |
Returns:
SelectGate — A callable applied as sel(index, *targets, **params).
Raises:
ValueError— If fewer than two cases are supplied, a concrete width is too small, or the cases do not share an identical parameter signature. Case-body footprint and unitarity are validated when the returned gate is called.TypeError— If the width has an unsupported type or a case cannot be wrapped into a qkernel.
Example:
>>> import qamomile.circuit as qm
>>> @qm.qkernel
... def pick() -> qm.Vector[qm.Bit]:
... idx = qm.qubit_array(2, name="idx")
... idx = qm.h(idx)
... t = qm.qubit(name="t")
... idx, t = qm.select([qm.x, qm.y, qm.z, qm.h])(idx, t)
... return qm.measure(idx)select_specialized_block [source]¶
def select_specialized_block(
kernel: Any,
arguments: dict[str, Any],
*,
require_handles: bool = True,
) -> BlockSelect the block implementation for a qkernel call site.
Centralizes call-site specialization so plain qkernel calls, controlled
calls, and inverse calls use the same rule. When concrete argument values
would change the callee trace (for example a concrete Vector[Qubit]
size or a bound structural classical value), the function returns a
temporary specialized block. Otherwise it returns the kernel’s cached
block.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object whose block should be selected. |
arguments | dict[str, Any] | Bound call arguments after literal promotion and frontend validation. Registered static bindings may remain concrete Python objects when require_handles is false. |
require_handles | bool | If True, specialization is skipped unless every argument is a frontend Handle. Defaults to True. |
Returns:
Block — Specialized call-site block or the cached kernel block.
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.
ControlledGate [source]¶
class ControlledGateWrapper for controlled version of a QKernel.
Created by calling control(qkernel). The resulting object
can be called like a gate function.
Example:
@qmc.qkernel
def phase_gate(q: Qubit, theta: float) -> Qubit:
return qmc.p(q, theta)
controlled_phase = qmc.control(phase_gate)
ctrl_out, tgt_out = controlled_phase(ctrl, target, theta=0.5)
# Add a call-site target phase. Under control this is observable.
ctrl_out, tgt_out = controlled_phase(
ctrl, target, theta=0.5, global_phase=phi
)
# Double-controlled
cc_phase = qmc.control(phase_gate, num_controls=2)
c0, c1, tgt = cc_phase(ctrl0, ctrl1, target, theta=0.5)Constructor¶
def __init__(
self,
qkernel: 'QKernel',
num_controls: int | UInt = 1,
*,
control_value: int | None = None,
callable_ref: CallableRef | None = None,
callable_attrs: dict[str, Any] | None = None,
target_inverse: bool = False,
) -> NoneWrap a QKernel as a controlled operation.
Parameters:
| Name | Type | Description |
|---|---|---|
qkernel | QKernel | The kernel to control. Built-in gate callables are not accepted directly here -- :func:control synthesizes a wrapper QKernel for them before instantiating ControlledGate -- so by this point qkernel must expose a dict input_types attribute and an inspect.Signature signature attribute. |
num_controls | int | UInt | Number of control qubits. A concrete Python or NumPy integer must be >= 1 and is normalized to a Python int; a symbolic UInt defers validation to emit time. Defaults to 1. A bool is rejected: it is not a valid control count even though bool subclasses int. |
control_value | int | None | Computational-basis value that activates the control. Bit zero describes the first flattened control qubit, following Qamomile’s LSB-first convention. None uses the ordinary all-ones state. Only supported with a concrete num_controls. Defaults to None. |
callable_ref | CallableRef | None | Optional source callable identity to record on emitted ControlledUOperation nodes. Defaults to the wrapped qkernel’s callable ref. |
callable_attrs | dict[str, Any] | None | Optional serializer-friendly attrs for the source callable. Defaults to qkernel attrs. |
target_inverse | bool | Whether the controlled target is the inverse of qkernel. Defaults to False. |
Raises:
TypeError— Ifnum_controlsis boolean or neither integral nor aUInt,control_valueis not a PythonintorNone, orqkerneldoes not expose a dictinput_types/ aninspect.Signaturesignature.ValueError— If a concretenum_controlsis less than one,control_valuedoes not fit its width, or a non-default value is combined with symbolicnum_controls.
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]) -> 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.
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.
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
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
QKernel [source]¶
class QKernel(QKernelBuildMixin, QKernelVisualizationMixin, Generic[P, R])Decorator class for Qamomile quantum kernels.
Constructor¶
def __init__(self, func: Callable[P, R]) -> NoneAttributes¶
block: Block Compile the function to a hierarchical Block if not already compiled.effects: KernelEffect Return cached semantic effects of this qkernel.funcinput_types: dict[str, Any] Return resolved and frozen frontend input annotations.nameoutput_types: list[Any] Return the resolved frontend annotation for every output slot.raw_funcreturn_type: Any Return the resolved and frozen complete return annotation.signature
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
SelectGate [source]¶
class SelectGateCallable wrapper for a quantum multiplexer over a list of unitaries.
Created by :func:select. Calling the instance applies case i to
the target register controlled on the index register reading i.
Parameters:
| Name | Type | Description |
|---|---|---|
cases | Sequence[QKernel | Callable[..., Any]] | Case unitaries in ascending index order. Every case must expose the same signature. |
num_index_qubits | int | UInt | None | Number of leading index qubits. None infers the minimal width. Defaults to None. |
Example:
>>> import qamomile.circuit as qm
>>> @qm.qkernel
... def demo() -> qm.Bit:
... idx = qm.qubit_array(1, name="idx")
... t = qm.qubit(name="t")
... idx, t = qm.select([qm.x, qm.h])(idx, t)
... return qm.measure(t)Constructor¶
def __init__(
self,
cases: Sequence['QKernel | Callable[..., Any]'],
num_index_qubits: int | UInt | None = None,
) -> NoneWrap and validate the case unitaries.
Parameters:
| Name | Type | Description |
|---|---|---|
cases | Sequence[QKernel | Callable[..., Any]] | The case unitaries in ascending index order. Each may be a @qmc.qkernel function, a qkernel-backed composite gate, or a built-in gate callable (qmc.x, qmc.ry, ...). All cases must share the same parameter signature (name, type, and order). |
num_index_qubits | int | UInt | None | Number of index qubits. None infers ceil(log2(len(cases))). A wider concrete value leaves unassigned basis states as identity. UInt defers the width and flattened-prefix check to transpilation. Defaults to None. |
Raises:
ValueError— If fewer than two cases are supplied, a concrete width is too small, or the cases do not all share an identical parameter signature. Case-body footprint and unitarity are validated when the gate is called.TypeError— If the width has an unsupported type or a case cannot be wrapped into a qkernel.
Attributes¶
num_cases: int Number of selectable cases.num_index_qubits: int | UInt Number of index (select) qubits this multiplexer expects.
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.
UInt [source]¶
class UInt(ArithmeticMixin, Handle)Unsigned integer handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: int = 0,
) -> NoneAttributes¶
init_value: int
qamomile.circuit.frontend.oracle¶
Frontend oracle callable.
Overview¶
| Function | Description |
|---|---|
get_current_tracer | |
normalize_control_value | Normalize an integer activation state for a control register. |
opaque | Create an opaque callable for top-down circuit design. |
reject_aliased_quantum_args | Reject overlapping live quantum resources at one call boundary. |
signature_from_values | Build a callable signature from concrete operand and result values. |
| Class | Description |
|---|---|
CallPolicy | Describe the default lowering policy for a callable call. |
CallTransform | Describe the requested transform of a callable implementation. |
CallableDef | Describe a compiler-facing callable definition. |
CallableRef | Identify a callable independently of its Python object. |
CallableSignature | Describe frontend input and output handle types for an opaque callable. |
InvokeOperation | Represent a composite, stdlib, or oracle call. |
Oracle | Represent an opaque oracle callable. |
Qubit | |
Signature | |
TransformedOracle | Represent composable inverse and controlled transforms of an Oracle. |
UInt | Unsigned integer handle with arithmetic operations. |
Value | A typed SSA value in the IR. |
Vector | 1-dimensional array type. |
VectorView | Strided view over a parent Vector, backed by a sliced ArrayValue. |
Functions¶
get_current_tracer [source]¶
def get_current_tracer() -> Tracernormalize_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.
opaque [source]¶
def opaque(
name: str,
num_qubits: int | None = None,
*,
num_control_qubits: int = 0,
signature: CallableSignature | None = None,
cost: ResourceEstimate | Callable[[OpaqueCostContext], ResourceEstimate] | None = None,
) -> OracleCreate an opaque callable for top-down circuit design.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | Human-readable callable name. |
num_qubits | int | None | Number of target qubits consumed and returned by the callable. Defaults to None when signature carries the target shape contract. Python and NumPy integer scalars are accepted; booleans and negative values are rejected. |
num_control_qubits | int | Number of explicit scalar control qubits required by scalar calls. Defaults to 0. |
signature | CallableSignature | None | Optional frontend signature for target operands only. It must exclude controls declared by num_control_qubits because the Oracle prefixes those controls automatically. Defaults to None. |
cost | ResourceEstimate | Callable[[OpaqueCostContext], ResourceEstimate] | None | Optional fixed or context-dependent opaque cost. Both forms describe one ordinary application of this Oracle definition, including declared controls and any phase-relevant work that later coherent controls must transform. The estimator treats this as a complete definition-level contract and does not add hidden global-phase overhead. A one-qubit phase entry is an upper-bound representative rather than an angle-aware reconstruction. Defaults to None. |
Returns:
Oracle — Opaque callable backed by InvokeOperation with no body.
Raises:
TypeError— If a suppliednum_qubitsornum_control_qubitsis not a non-boolean integral scalar.ValueError— If neithernum_qubitsnorsignaturesupplies enough target-arity information, or if either width is negative.
reject_aliased_quantum_args [source]¶
def reject_aliased_quantum_args(
kernel_name: str,
arguments: dict[str, Any],
*,
caller: str | None = None,
) -> NoneReject overlapping live quantum resources at one call boundary.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel_name | str | Name of the called qkernel for diagnostics. |
arguments | dict[str, Any] | Bound call arguments keyed by parameter name. |
caller | str | None | Optional operation label replacing the default QKernel[kernel_name] context. Defaults to None. |
Raises:
QubitConsumedError— If two quantum arguments may cover the same physical qubit.
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¶
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.
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.
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
CallableSignature [source]¶
class CallableSignatureDescribe frontend input and output handle types for an opaque callable.
This class is intentionally a small frontend helper. It lets users write
signature-shaped APIs such as opaque(name, signature=...) without
exposing the compiler-facing CallableDef model.
Parameters:
| Name | Type | Description |
|---|---|---|
inputs | list[Any] | Frontend handle annotations accepted by the callable. |
outputs | list[Any] | Frontend handle annotations produced by the callable. |
Constructor¶
def __init__(self, inputs: list[Any], outputs: list[Any]) -> NoneAttributes¶
inputs: list[Any]outputs: list[Any]
Methods¶
accepts_single_qubit_vector¶
def accepts_single_qubit_vector(self) -> boolReturn whether this signature is a one-vector quantum callable.
Returns:
bool — True when both input and output are exactly one
bool — Vector[Qubit]-style annotation.
scalar_qubit_input_count¶
def scalar_qubit_input_count(self) -> int | NoneReturn scalar-qubit arity when the signature is scalar-only.
Returns:
int | None — int | None: Number of scalar Qubit inputs, or None when
int | None — the signature contains a vector register.
to_ir_signature¶
def to_ir_signature(self) -> SignatureConvert the frontend signature into an IR operation signature.
Returns:
Signature — Best-effort IR signature using operation parameter
Signature — hints.
Raises:
TypeError— If a frontend type cannot map to an IR value type.
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.
Oracle [source]¶
class OracleRepresent an opaque oracle callable.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | Human-readable oracle name. |
num_qubits | int | None | Number of target qubits consumed and returned by the oracle. None means the arity is provided by signature and may be vector-shaped. Python and NumPy integer scalars are accepted; booleans and negative values are rejected. |
num_control_qubits | int | Number of explicit control qubits required by scalar calls. Defaults to 0. |
signature | CallableSignature | None | Optional frontend signature for target operands only. It must not repeat the leading controls declared by num_control_qubits; those controls are prefixed by the Oracle automatically. When omitted, a fixed-width scalar/vector-compatible oracle is created from num_qubits. |
cost | ResourceEstimate | Callable[[OpaqueCostContext], ResourceEstimate] | None | Optional explicit cost for this bodyless callable. Both forms describe one ordinary application of the Oracle as declared, including num_control_qubits. Controls added later with qmc.control are projected by resource estimation. This is a complete definition-level contract: the author must include any phase-relevant work that later coherent controls need. The estimator does not infer omitted global-phase overhead. An intrinsic nonidentity phase is represented as a logical primitive in the aggregate gate and arity counts. A one-qubit phase entry is an upper-bound representative for the target-free phase, not an angle-aware reconstruction; use a body-backed global phase when angle-specific classification is required. Defaults to None. |
Raises:
TypeError— If a suppliednum_qubitsornum_control_qubitsis boolean or not an integral scalar.ValueError— If either width is negative, or neithernum_qubitsnorsignaturesupplies enough target-arity information.
Constructor¶
def __init__(
self,
name: str,
num_qubits: int | None = None,
*,
num_control_qubits: int = 0,
signature: CallableSignature | None = None,
cost: ResourceEstimate | Callable[[OpaqueCostContext], ResourceEstimate] | None = None,
) -> NoneInitialize an opaque oracle callable.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | Human-readable oracle name. |
num_qubits | int | None | Fixed scalar/vector width. Defaults to None when signature describes the callable. Python and NumPy integer scalars are accepted; booleans and negative values are rejected. |
num_control_qubits | int | Number of explicit scalar controls. Defaults to 0. |
signature | CallableSignature | None | Optional frontend signature for target operands only. Do not include controls declared by num_control_qubits; the Oracle prefixes those controls to its internal callable signature. Defaults to None. |
cost | ResourceEstimate | Callable[[OpaqueCostContext], ResourceEstimate] | None | Optional fixed or context-dependent opaque cost. The returned estimate describes one ordinary application of this Oracle definition, including its declared controls but excluding controls added by an outer transform. The result must be a complete definition-level contract, including phase-relevant work that an outer coherent control must transform. Represent an intrinsic nonidentity phase as a logical primitive in the aggregate gate and arity counts. A one-qubit phase entry is an upper-bound representative; use a body-backed global phase for angle-specific classification. Defaults to None. |
Raises:
TypeError— If a suppliednum_qubitsornum_control_qubitsis not a non-boolean integral scalar.ValueError— If neithernum_qubitsnorsignaturesupplies enough target-arity information, or if either width is negative.
Attributes¶
cost: ResourceEstimate | Callable[[OpaqueCostContext], ResourceEstimate] | Nonename: strnum_control_qubits: intnum_qubits: int | Nonesignature: CallableSignature | None
Qubit [source]¶
class Qubit(Handle)Constructor¶
def __init__(
self,
value: Value[QubitType],
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneAttributes¶
value: Value[QubitType]
Signature [source]¶
class SignatureConstructor¶
def __init__(
self,
operands: list[ParamHint | None] = list(),
results: list[ParamHint] = list(),
) -> NoneAttributes¶
operands: list[ParamHint | None]results: list[ParamHint]
TransformedOracle [source]¶
class TransformedOracleRepresent composable inverse and controlled transforms of an Oracle.
The wrapped Oracle remains the definition boundary: its explicit cost
includes only controls declared by Oracle.num_control_qubits. This
wrapper records controls added later by qmc.control and whether the
call is inverted, so the resulting InvokeOperation can apply those
transforms exactly once.
Parameters:
| Name | Type | Description |
|---|---|---|
oracle | Oracle | Definition-level opaque Oracle. |
added_num_control_qubits | int | Number of controls added outside the Oracle definition. Defaults to 0. |
added_control_value | int | None | LSB-first activation value for the added controls, or None for all ones. Defaults to None. |
inverse | bool | Whether to apply the inverse Oracle. Defaults to False. |
Raises:
TypeError— Ifadded_num_control_qubitsis boolean or not integral, or a positive count is attached to a vector-signature Oracle.ValueError— If the added-control count is negative or its activation value is invalid for that width.
Constructor¶
def __init__(
self,
oracle: Oracle,
added_num_control_qubits: int = 0,
added_control_value: int | None = None,
inverse: bool = False,
) -> NoneAttributes¶
added_control_value: int | Noneadded_num_control_qubits: intinverse: boolname: str Return the source Oracle name.oracle: Oracle
Methods¶
controlled¶
def controlled(
self,
num_controls: int,
*,
control_value: int | None = None,
) -> TransformedOraclePrepend another concrete control group.
Parameters:
| Name | Type | Description |
|---|---|---|
num_controls | int | Number of newly added leading controls. |
control_value | int | None | LSB-first activation value for the new control group. None means all ones. Defaults to None. |
Returns:
TransformedOracle — Wrapper carrying the combined added-control
condition.
Raises:
TypeError— Ifnum_controlsis not a non-boolean integer orcontrol_valueis not a Python integer orNone, or the source Oracle uses a vector target signature.ValueError— Ifnum_controlsis not positive orcontrol_valuedoes not fit its width.
inverted¶
def inverted(self) -> Oracle | TransformedOracleToggle inverse application while preserving added controls.
Returns:
Oracle | TransformedOracle — Oracle | TransformedOracle: The original Oracle when every
transform cancels, otherwise a transformed wrapper.
UInt [source]¶
class UInt(ArithmeticMixin, Handle)Unsigned integer handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: int = 0,
) -> NoneAttributes¶
init_value: int
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.
Vector [source]¶
class Vector(ArrayBase[T])1-dimensional array type.
Example:
import qamomile.circuit as qmc
# Create a vector of 3 qubits
qubits: qmc.Vector[qmc.Qubit] = qmc.qubit_array(3, name="qubits")
# Access elements
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0
# Apply H gate to all qubits (CORRECT)
n = qubits.shape[0]
for i in qmc.range(n):
qubits[i] = qmc.h(qubits[i])
# Slicing returns a VectorView over a subset of the parent vector.
# The view shares borrow tracking with the parent; element access
# on the view transparently indexes the parent.
evens = qubits[0::2]
for i in qmc.range(evens.shape[0]):
evens[i] = qmc.h(evens[i])Constructor¶
def __init__(
self,
value: ArrayValue = None,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_shape: tuple[int | UInt] = (0,),
_borrowed_indices: dict[tuple[str, ...], 'tuple[UInt, ...] | Handle'] = dict(),
) -> NoneAttributes¶
value: ArrayValue
VectorView [source]¶
class VectorView(Vector[T])Strided view over a parent Vector, backed by a sliced ArrayValue.
A VectorView is produced by slicing a Vector (q[1::2],
q[a:b], etc.). It is a thin Vector subclass whose value
is a fresh ArrayValue with slice_of / slice_start /
slice_step metadata pointing back to the parent’s ArrayValue.
Element accesses go through Vector._get_element unchanged — the
IR element carries parent_array = sliced_av, and the emit-time
resolver walks the slice_of chain to produce the physical qubit
index. No affine translation happens in the view itself.
Because the sliced ArrayValue is a first-class IR Value,
the view can be passed as an operand of an inline callable invocation
to another qkernel without the inline-trace special-case path that
earlier iterations required. Passing views through
expval / measure likewise operates on the sliced qubit
subset, not the root parent as a whole.
Linearity:
Slicing bulk-borrows the covered parent slots whenever
start, step and length are compile-time int
constants. While the view is live, accessing the corresponding
parent slot directly (q[0] after evens = q[0::2]) raises
QubitConsumedError. Under the strict-return policy the
view’s ownership is cleared only by two operations:
slice-assigning it back into the parent (
parent[a:b:c] = view) — this is the only path that fully releases the borrow without destroying the qubits;destructively consuming it (
measure(view)/cast(view, ...)/expval(view, H)) — the physical slots become consumed markers, no return needed.
Every other consume (broadcast gates h(view),
pauli_evolve(view, H, gamma), sub-kernel calls
f(view), controlled-U index_spec) only transfers
ownership to a freshly-wrapped VectorView and that new
view still must be returned via slice assignment. A view
left bulk-borrowing at the parent’s consume point raises
UnreturnedBorrowError.
Symbolic slices (q[lo:hi] with lo/hi UInt) cannot
enumerate their covered slots at trace time and therefore skip
the bulk-borrow here; SliceBorrowCheckPass picks them up
post-fold after bindings resolve the bounds to concrete values.
Example:
@qmc.qkernel
def alternating_h(q: qmc.Vector[qmc.Qubit]) -> qmc.Vector[qmc.Qubit]:
evens = q[0::2]
for i in qmc.range(evens.shape[0]):
evens[i] = qmc.h(evens[i])
q[0::2] = evens # explicit return before the parent is used
return qMethods¶
consume¶
def consume(self, operation_name: str = 'unknown') -> SelfConsume the view and release its parent slice-borrows.
Validates that every view-local borrow has been returned,
then dispatches on operation_name to keep the parent’s
slice-borrow record consistent with the new strict-return
semantics:
Destructive (
measure/cast): leaveselfparked in the parent’s borrow table as a destroyed-slot breadcrumb.super().consume()flipsself._consumed = Trueandself._consumed_by = operation_name, which is what :func:_is_destroyed_slot_ownerreads to reject subsequent access at the same slot.Releasing (
slice assignment): drop every parent entry thatselfcurrently owns. The caller (the slice- assignment frontend path) also emits aReleaseSliceViewOperationso the IR-level checker sees the release. This branch is reserved for explicit borrow- return paths.Transfer (every other op — broadcast gates, rotation, phase, ControlledU, sub-kernel call argument consumption, etc.): rebind the parent’s borrow entry from
selfto the new view handle returned here. The new view inheritsself._slice_covered_indicesso it can be slice-assigned back to the parent later — strict-return requires that eventualparent[a:b:c] = new_view.
Operations that produce a fresh sliced ArrayValue (e.g.
:func:qamomile.circuit.frontend.operation.pauli_evolve.pauli_evolve,
:class:QKernel.__call__ for callees that return a sliced
array) cannot simply use the auto-returned new_view
because the new view they build wraps a different Value
than this consume’s return. Those op implementations call
:meth:_transfer_borrow_to after building their result so
the parent’s borrow table tracks the right handle.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the operation consuming this view (used in error messages and for dispatch). |
Returns:
typing.Self — A fresh view handle with the same backing state; under
typing.Self — transfer the parent’s borrow table now points at this
typing.Self — handle, under release / destruction the parent’s record
typing.Self — for the covered slots is finalised.
Raises:
QubitConsumedError— If any covered slot was already destroyed by a prior destructive consume on an overlapping element or view.
qamomile.circuit.frontend.param_validation¶
Validate bound qkernel argument handles against declared parameter types.
These predicates and validators classify a kernel parameter’s declared
annotation (scalar Qubit vs. Vector[Qubit], quantum vs. classical)
and check that the handle bound to it at a call site matches that
declaration. They are shared by the plain qkernel call path
(QKernel.__call__ in :mod:qamomile.circuit.frontend.qkernel) and the
controlled-gate call path (ControlledGate in
:mod:qamomile.circuit.frontend.operation.control). Keeping them in this
neutral module means neither of those modules has to import the other just
to reach these checks.
Overview¶
| Function | Description |
|---|---|
handle_type_map | Map Handle type to ValueType. |
is_array_type | Check if type is a Vector, Matrix, or Tensor subclass. |
is_dict_type | Check if type is a Dict handle type. |
is_tuple_type | Check if type is a Tuple handle type. |
validate_bindings_parameters_disjoint | Enforce the project rule that bindings and parameters are disjoint. |
| Class | Description |
|---|---|
Bit | |
BitType | Type representing a classical bit. |
Float | Floating-point handle with arithmetic operations. |
FloatType | Type representing a floating-point number. |
ObservableType | Type representing a Hamiltonian observable parameter. |
Qubit | |
UInt | Unsigned integer handle with arithmetic operations. |
UIntType | Type representing an unsigned integer. |
Functions¶
handle_type_map [source]¶
def handle_type_map(handle_type: type[Handle] | type) -> ValueTypeMap Handle type to ValueType.
is_array_type [source]¶
def is_array_type(t: Any) -> boolCheck if type is a Vector, Matrix, or Tensor subclass.
is_dict_type [source]¶
def is_dict_type(t: Any) -> boolCheck if type is a Dict handle type.
is_tuple_type [source]¶
def is_tuple_type(t: Any) -> boolCheck if type is a Tuple handle type.
validate_bindings_parameters_disjoint [source]¶
def validate_bindings_parameters_disjoint(bindings: dict[str, Any] | None, parameters: list[str] | None) -> NoneEnforce the project rule that bindings and parameters are disjoint.
A kernel argument name must be resolved exactly one way: compile-time bound
(in bindings, baked into the emitted circuit) or runtime symbolic (in
parameters, surviving as a backend parameter). Listing the same name in
both is ambiguous and historically caused silent miscompilation — the
binding won the resolution race and the runtime parameter was silently
dropped from the emitted circuit (see #354). This is the single shared
checker so the rule is enforced identically at every entry point
(QKernel.build / Transpiler.to_block / Transpiler.emit /
Transpiler.transpile), not only in the top-level transpile wrapper.
Parameters:
| Name | Type | Description |
|---|---|---|
bindings | dict[str, Any] | None | Compile-time bindings keyed by argument name, or None. None is treated as empty. |
parameters | list[str] | None | Argument names to keep as runtime parameters, or None. None is treated as empty. |
Returns:
None — None
Raises:
ValueError— If any name appears in bothbindingsandparameters.
Example:
>>> validate_bindings_parameters_disjoint({"theta": 0.5}, ["phi"])
>>> validate_bindings_parameters_disjoint({"theta": 0.5}, ["theta"])
Traceback (most recent call last):
...
ValueError: Parameter name(s) ['theta'] appear in both ...Classes¶
Bit [source]¶
class Bit(Handle)Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: bool = False,
) -> NoneAttributes¶
init_value: bool
BitType [source]¶
class BitType(ClassicalTypeMixin, ValueType)Type representing a classical bit.
Float [source]¶
class Float(ArithmeticMixin, Handle)Floating-point handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: float = 0.0,
) -> NoneAttributes¶
init_value: float
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) -> NoneQubit [source]¶
class Qubit(Handle)Constructor¶
def __init__(
self,
value: Value[QubitType],
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneAttributes¶
value: Value[QubitType]
UInt [source]¶
class UInt(ArithmeticMixin, Handle)Unsigned integer handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: int = 0,
) -> NoneAttributes¶
init_value: int
UIntType [source]¶
class UIntType(ClassicalTypeMixin, ValueType)Type representing an unsigned integer.
qamomile.circuit.frontend.qkernel¶
Overview¶
| Function | Description |
|---|---|
flatten_kernel_return_type | Flatten a qkernel return annotation into its output-slot types. |
get_or_build_block | Return a qkernel’s cached hierarchical block, building it if needed. |
get_quantum_rebind_error | Capture an illegal quantum rebind for deferred input validation. |
qkernel | Decorator to define a Qamomile quantum kernel. |
transform_qkernel_function | Transform a Python function into the frontend DSL function. |
try_resolve_kernel_input_types | Resolve each qkernel input annotation independently. |
try_resolve_kernel_return_type | Resolve one return annotation independently from parameter hints. |
validate_quantum_rebinds | Reject illegal quantum variable rebindings in a qkernel body. |
| Class | Description |
|---|---|
Block | Unified block representation for all pipeline stages. |
CallPolicy | Describe the default lowering policy for a callable call. |
CompositeGateType | Classify standard boxed quantum callables. |
InvokeOperation | Represent a composite, stdlib, or oracle call. |
KernelEffect | Describe non-unitary behavior reachable from a kernel body. |
QKernel | Decorator class for Qamomile quantum kernels. |
QKernelBuildMixin | Provide build and resource-estimation helpers for QKernel. |
QKernelVisualizationMixin | Provide visualization helpers for QKernel. |
Functions¶
flatten_kernel_return_type [source]¶
def flatten_kernel_return_type(return_type: Any) -> list[Any]Flatten a qkernel return annotation into its output-slot types.
A Python tuple denotes multiple ABI results, while every other annotation,
including the structural Tuple handle, denotes one result. A None
annotation denotes no result slots.
Parameters:
| Name | Type | Description |
|---|---|---|
return_type | Any | Complete qkernel return annotation. |
Returns:
list[Any] — list[Any]: Frontend annotations ordered by output slot.
Raises:
TypeError— If a variable-length Python tuple is declared because its result arity cannot be represented by the qkernel ABI.
get_or_build_block [source]¶
def get_or_build_block(kernel: Any) -> BlockReturn a qkernel’s cached hierarchical block, building it if needed.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object with func, name, _block, _block_building, and _pending_self_calls attributes. |
Returns:
Block — Cached or freshly traced hierarchical block.
Raises:
FrontendTransformError— If a self-recursive qkernel accesses.blockdirectly while its own block is being built.
get_quantum_rebind_error [source]¶
def get_quantum_rebind_error(
func: Callable[..., Any],
*,
kernel_name: str,
input_types: dict[str, Any],
) -> QubitRebindError | NoneCapture an illegal quantum rebind for deferred input validation.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable[..., Any] | Raw user function. |
kernel_name | str | User-visible qkernel name for diagnostics. |
input_types | dict[str, Any] | Resolved annotations or raw deferred fallbacks keyed by parameter name. |
Returns:
QubitRebindError | None — QubitRebindError | None: Validation error, or None when the body is
QubitRebindError | None — valid for the resolved input types.
qkernel [source]¶
def qkernel(func: Callable[P, R]) -> QKernel[P, R]Decorator to define a Qamomile quantum kernel.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable[P, R] | Function to decorate. |
Returns:
QKernel[P, R] — QKernel[P, R]: QKernel wrapping the function.
transform_qkernel_function [source]¶
def transform_qkernel_function(
func: Callable[..., Any],
region_signatures: dict[RegionLocation, RegionSignature] | None = None,
) -> Callable[..., Any]Transform a Python function into the frontend DSL function.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable[..., Any] | Raw user function decorated as a qkernel. |
region_signatures | dict[RegionLocation, RegionSignature] | None | Precomputed explicit control-flow interfaces. Defaults to None. |
Returns:
Callable[..., Any] — Callable[..., Any]: AST-transformed function.
Raises:
FrontendTransformError— If the transform reports an unsupported frontend construct.SyntaxError— If the transform detects invalid syntax-level DSL usage.
try_resolve_kernel_input_types [source]¶
def try_resolve_kernel_input_types(
func: Callable[..., Any],
signature: inspect.Signature,
) -> tuple[dict[str, Any], dict[str, NameError]]Resolve each qkernel input annotation independently.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable[..., Any] | Raw user function. |
signature | inspect.Signature | Function signature. |
Returns:
dict[str, Any] — tuple[dict[str, Any], dict[str, NameError]]: Resolved annotations or raw
dict[str, NameError] — fallbacks by parameter, plus resolution errors for deferred
tuple[dict[str, Any], dict[str, NameError]] — annotations.
Raises:
TypeError— If any parameter is missing an annotation or an annotation expression is definitively invalid.
try_resolve_kernel_return_type [source]¶
def try_resolve_kernel_return_type(
func: Callable[..., Any],
signature: inspect.Signature,
) -> tuple[Any, bool, NameError | None]Resolve one return annotation independently from parameter hints.
An unresolved forward reference is retained so a live QKernel can
retry it at the first compilation entry point. Once resolution succeeds,
the kernel freezes that result as its return contract.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable[..., Any] | Raw user function. |
signature | inspect.Signature | Function signature. |
Returns:
Any — tuple[Any, bool, NameError | None]: Annotation or raw fallback,
bool — whether resolution succeeded, and the resolution error when it did
NameError | None — not.
Raises:
TypeError— If the return type is missing an annotation or the annotation expression is definitively invalid.
validate_quantum_rebinds [source]¶
def validate_quantum_rebinds(
func: Callable[..., Any],
*,
kernel_name: str,
input_types: dict[str, Any],
) -> NoneReject illegal quantum variable rebindings in a qkernel body.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable[..., Any] | Raw user function. |
kernel_name | str | User-visible qkernel name for diagnostics. |
input_types | dict[str, Any] | Resolved annotations or raw deferred fallbacks keyed by parameter name. |
Raises:
QubitRebindError— If the AST analyzer finds a forbidden quantum variable reassignment.
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.
CallPolicy [source]¶
class CallPolicy(enum.Enum)Describe the default lowering policy for a callable call.
Attributes¶
INLINENATIVE_FIRSTPRESERVE_BOX
CompositeGateType [source]¶
class CompositeGateType(enum.Enum)Classify standard boxed quantum callables.
Attributes¶
CUSTOMIQFTQFTQPE
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.
QKernel [source]¶
class QKernel(QKernelBuildMixin, QKernelVisualizationMixin, Generic[P, R])Decorator class for Qamomile quantum kernels.
Constructor¶
def __init__(self, func: Callable[P, R]) -> NoneAttributes¶
block: Block Compile the function to a hierarchical Block if not already compiled.effects: KernelEffect Return cached semantic effects of this qkernel.funcinput_types: dict[str, Any] Return resolved and frozen frontend input annotations.nameoutput_types: list[Any] Return the resolved frontend annotation for every output slot.raw_funcreturn_type: Any Return the resolved and frozen complete return annotation.signature
QKernelBuildMixin [source]¶
class QKernelBuildMixinProvide build and resource-estimation helpers for QKernel.
Methods¶
build¶
def build(self, parameters: list[str] | None = None, **kwargs: Any = {}) -> BlockBuild a traced Block by tracing this kernel.
Parameters:
| Name | Type | Description |
|---|---|---|
parameters | list[str] | None | List of argument names to keep as unbound parameters. None auto-detects required non-quantum arguments without values/defaults. [] requires every non-quantum argument to have a value/default. Defaults to None. |
**kwargs | Any | Concrete values for non-parameter arguments. |
Returns:
Block — The traced block ready for transpilation, estimation,
Block — or visualization.
Raises:
TypeError— If a non-parameterizable type is specified as a parameter.ValueError— If required arguments are missing, or if a name appears in bothparametersandkwargs, violating the bindings/parameters disjointness rule.
Example:
>>> @qm.qkernel
... def circuit(q: qm.Qubit, theta: float) -> qm.Qubit:
... q = qm.rx(q, theta)
... return q
>>> block = circuit.build(parameters=["theta"])estimate_resources¶
def estimate_resources(
self,
*,
inputs: dict[str, Any] | None = None,
strategies: dict[str, str] | None = None,
trace: bool = False,
unknown_policy: str | UnknownResourcePolicy | None = None,
control_decomposition: str | ControlDecomposition | None = None,
) -> ResourceEstimateEstimate all resources for this kernel’s circuit.
Convenience wrapper around ResourceEstimator().estimate(...).
Parameters:
| Name | Type | Description |
|---|---|---|
inputs | dict[str, Any] | None | QKernel input values used to specialize the symbolic estimate without constructing a problem-sized circuit. Exact one-dimensional root quantum-port widths declared by callable resource metadata are inferred when omitted. Defaults to None. |
strategies | dict[str, str] | None | Callable strategy overrides. Defaults to None. |
trace | bool | Whether to retain the explanation tree. Defaults to False. |
unknown_policy | str | UnknownResourcePolicy | None | Policy for bodyless callables without explicit costs. Defaults to None, which uses the estimator default. |
control_decomposition | str | ControlDecomposition | None | Coherent-control model override. Defaults to None, which uses the clean-ancilla Toffoli model. |
Returns:
ResourceEstimate — Algorithmic resource estimate using the requested
control-decomposition model.
Raises:
RuntimeError— If a fixed or callback-provided opaque cost contains public metrics or metadata that disagree with retained canonical provenance.ValueError— If an input, estimation configuration, callable resource contract, or structural requirement is invalid.TypeError— If the qkernel cannot be built as an estimator input.NotImplementedError— If the qkernel contains a construct not supported by resource estimation.
Example:
>>> @qm.qkernel
... def bell() -> qm.Vector[qm.Qubit]:
... q = qm.qubit_array(2)
... q[0] = qm.h(q[0])
... q[0], q[1] = qm.cx(q[0], q[1])
... return q
>>> est = bell.estimate_resources()
>>> print(est.qubits) # 2QKernelVisualizationMixin [source]¶
class QKernelVisualizationMixinProvide visualization helpers for QKernel.
Methods¶
draw¶
def draw(
self,
inline: bool = False,
fold_loops: bool = True,
expand_composite: bool = False,
inline_depth: int | None = None,
fold_ifs: bool = False,
**kwargs: Any = {},
) -> AnyVisualize the circuit using Matplotlib.
Parameters:
| Name | Type | Description |
|---|---|---|
inline | bool | If True, expand inline callable contents. If False, show them as boxes. Defaults to False. |
fold_loops | bool | If True, display ForOperation as folded blocks instead of unrolling. Defaults to True. |
expand_composite | bool | If True, expand boxed InvokeOperation bodies. Defaults to False. |
inline_depth | int | None | Maximum nesting depth for inline expansion. None means unlimited. Defaults to None. |
fold_ifs | bool | If True, display IfOperation as folded summary blocks. Defaults to False. |
**kwargs | Any | Concrete values for arguments. Arguments not provided here and without defaults are shown as symbolic parameters. |
Returns:
Any — Matplotlib figure object.
Raises:
ImportError— If matplotlib is not installed.ValueError— If aVector[Qubit]parameter requires a concrete size for visualization and no size is provided.ValidationError— If visualization-time compile-time if lowering rejects the traced graph.
qamomile.circuit.frontend.qkernel_api¶
User-facing QKernel convenience method mixins.
Overview¶
| Function | Description |
|---|---|
build_graph_for_visualization | Build a traced block suitable for visualization. |
build_graph_with_qubit_arrays | Build a traced block with concrete Vector[Qubit] sizes. |
build_qkernel | Build a traced block from a qkernel. |
draw_qkernel | Visualize a qkernel using the Matplotlib drawer. |
estimate_qkernel_resources | Estimate resources for a kernel. |
has_qubit_array_params | Return whether a kernel declares quantum-array parameters. |
| Class | Description |
|---|---|
Block | Unified block representation for all pipeline stages. |
QKernel | Decorator class for Qamomile quantum kernels. |
QKernelBuildMixin | Provide build and resource-estimation helpers for QKernel. |
QKernelVisualizationMixin | Provide visualization helpers for QKernel. |
Functions¶
build_graph_for_visualization [source]¶
def build_graph_for_visualization(kernel: Any, **kwargs: Any = {}) -> BlockBuild a traced block suitable for visualization.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object to trace. |
**kwargs | Any | Concrete values for kernel arguments. For Vector[Qubit] parameters, pass an integer size. |
Returns:
Block — Traced block with output names populated.
build_graph_with_qubit_arrays [source]¶
def build_graph_with_qubit_arrays(kernel: Any, kwargs: dict[str, Any]) -> BlockBuild a traced block with concrete Vector[Qubit] sizes.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object to trace. |
kwargs | dict[str, Any] | Concrete values for kernel arguments. Integer values for Vector[Qubit] parameters are interpreted as register sizes. |
Returns:
Block — Traced block with quantum-array parameters realized as
Block — concrete 1-D registers.
Raises:
NotImplementedError— If the kernel declares a rank greater than one quantum array parameter.ValueError— If a quantum-array parameter is missing its integer size.
build_qkernel [source]¶
def build_qkernel(kernel: Any, parameters: list[str] | None = None, **kwargs: Any = {}) -> BlockBuild a traced block from a qkernel.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object to trace. |
parameters | list[str] | None | Argument names to preserve as runtime parameters. Defaults to None, which auto-detects parameters. |
**kwargs | Any | Concrete values for non-parameter arguments. |
Returns:
Block — Traced block ready for transpilation, estimation, or
Block — visualization.
Raises:
TypeError— If a non-parameterizable type is listed as a parameter.ValueError— If required arguments are missing, or if a name appears in bothparametersandkwargs(the compile-time-bound values), which violates the bindings/parameters disjointness rule.
draw_qkernel [source]¶
def draw_qkernel(
kernel: Any,
*,
inline: bool = False,
fold_loops: bool = True,
expand_composite: bool = False,
inline_depth: int | None = None,
fold_ifs: bool = False,
**kwargs: Any = {},
) -> AnyVisualize a qkernel using the Matplotlib drawer.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object to draw. |
inline | bool | Whether inline callable contents should be expanded. Defaults to False. |
fold_loops | bool | Whether loops should be shown as folded blocks. Defaults to True. |
expand_composite | bool | Whether boxed composite calls should be expanded. Defaults to False. |
inline_depth | int | None | Maximum nesting depth for inline expansion. Defaults to None. |
fold_ifs | bool | Whether if/else branches should be folded. Defaults to False. |
**kwargs | Any | Concrete values for kernel arguments. |
Returns:
Any — Matplotlib figure object.
Raises:
ImportError— If matplotlib is not installed.ValueError— If visualization requires a missing concrete register size.
estimate_qkernel_resources [source]¶
def estimate_qkernel_resources(
kernel: 'QKernel[Any, Any]',
*,
inputs: dict[str, Any] | None = None,
strategies: dict[str, str] | None = None,
trace: bool = False,
unknown_policy: str | UnknownResourcePolicy | None = None,
control_decomposition: str | ControlDecomposition | None = None,
) -> 'ResourceEstimate'Estimate resources for a kernel.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernel[Any, Any] | Kernel to estimate. |
inputs | dict[str, Any] | None | QKernel input values used to specialize the symbolic estimate. Exact one-dimensional root quantum-port widths declared by callable resource metadata are inferred when omitted. Defaults to None. |
strategies | dict[str, str] | None | Callable strategy overrides. Defaults to None. |
trace | bool | Whether to retain the explanation tree. Defaults to False. |
unknown_policy | str | UnknownResourcePolicy | None | Policy for bodyless callables without explicit costs. Defaults to None, which uses the estimator default. |
control_decomposition | str | ControlDecomposition | None | Coherent-control model override. Defaults to None, which uses the clean-ancilla Toffoli model. |
Returns:
'ResourceEstimate' — Estimated width, gate, measurement, reset, depth,
call, and parameter resources.
Raises:
RuntimeError— If a fixed or callback-provided opaque cost contains public metrics or metadata that disagree with retained canonical provenance.ValueError— If an input, estimation configuration, callable resource contract, or structural requirement is invalid.TypeError— If the qkernel cannot be built as an estimator input.NotImplementedError— If the qkernel contains a construct not supported by resource estimation.
has_qubit_array_params [source]¶
def has_qubit_array_params(kernel: Any) -> boolReturn whether a kernel declares quantum-array parameters.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object with signature and input_types attributes. |
Returns:
bool — True when any parameter is a Vector[Qubit]-style
bool — quantum array.
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.
QKernel [source]¶
class QKernel(QKernelBuildMixin, QKernelVisualizationMixin, Generic[P, R])Decorator class for Qamomile quantum kernels.
Constructor¶
def __init__(self, func: Callable[P, R]) -> NoneAttributes¶
block: Block Compile the function to a hierarchical Block if not already compiled.effects: KernelEffect Return cached semantic effects of this qkernel.funcinput_types: dict[str, Any] Return resolved and frozen frontend input annotations.nameoutput_types: list[Any] Return the resolved frontend annotation for every output slot.raw_funcreturn_type: Any Return the resolved and frozen complete return annotation.signature
QKernelBuildMixin [source]¶
class QKernelBuildMixinProvide build and resource-estimation helpers for QKernel.
Methods¶
build¶
def build(self, parameters: list[str] | None = None, **kwargs: Any = {}) -> BlockBuild a traced Block by tracing this kernel.
Parameters:
| Name | Type | Description |
|---|---|---|
parameters | list[str] | None | List of argument names to keep as unbound parameters. None auto-detects required non-quantum arguments without values/defaults. [] requires every non-quantum argument to have a value/default. Defaults to None. |
**kwargs | Any | Concrete values for non-parameter arguments. |
Returns:
Block — The traced block ready for transpilation, estimation,
Block — or visualization.
Raises:
TypeError— If a non-parameterizable type is specified as a parameter.ValueError— If required arguments are missing, or if a name appears in bothparametersandkwargs, violating the bindings/parameters disjointness rule.
Example:
>>> @qm.qkernel
... def circuit(q: qm.Qubit, theta: float) -> qm.Qubit:
... q = qm.rx(q, theta)
... return q
>>> block = circuit.build(parameters=["theta"])estimate_resources¶
def estimate_resources(
self,
*,
inputs: dict[str, Any] | None = None,
strategies: dict[str, str] | None = None,
trace: bool = False,
unknown_policy: str | UnknownResourcePolicy | None = None,
control_decomposition: str | ControlDecomposition | None = None,
) -> ResourceEstimateEstimate all resources for this kernel’s circuit.
Convenience wrapper around ResourceEstimator().estimate(...).
Parameters:
| Name | Type | Description |
|---|---|---|
inputs | dict[str, Any] | None | QKernel input values used to specialize the symbolic estimate without constructing a problem-sized circuit. Exact one-dimensional root quantum-port widths declared by callable resource metadata are inferred when omitted. Defaults to None. |
strategies | dict[str, str] | None | Callable strategy overrides. Defaults to None. |
trace | bool | Whether to retain the explanation tree. Defaults to False. |
unknown_policy | str | UnknownResourcePolicy | None | Policy for bodyless callables without explicit costs. Defaults to None, which uses the estimator default. |
control_decomposition | str | ControlDecomposition | None | Coherent-control model override. Defaults to None, which uses the clean-ancilla Toffoli model. |
Returns:
ResourceEstimate — Algorithmic resource estimate using the requested
control-decomposition model.
Raises:
RuntimeError— If a fixed or callback-provided opaque cost contains public metrics or metadata that disagree with retained canonical provenance.ValueError— If an input, estimation configuration, callable resource contract, or structural requirement is invalid.TypeError— If the qkernel cannot be built as an estimator input.NotImplementedError— If the qkernel contains a construct not supported by resource estimation.
Example:
>>> @qm.qkernel
... def bell() -> qm.Vector[qm.Qubit]:
... q = qm.qubit_array(2)
... q[0] = qm.h(q[0])
... q[0], q[1] = qm.cx(q[0], q[1])
... return q
>>> est = bell.estimate_resources()
>>> print(est.qubits) # 2QKernelVisualizationMixin [source]¶
class QKernelVisualizationMixinProvide visualization helpers for QKernel.
Methods¶
draw¶
def draw(
self,
inline: bool = False,
fold_loops: bool = True,
expand_composite: bool = False,
inline_depth: int | None = None,
fold_ifs: bool = False,
**kwargs: Any = {},
) -> AnyVisualize the circuit using Matplotlib.
Parameters:
| Name | Type | Description |
|---|---|---|
inline | bool | If True, expand inline callable contents. If False, show them as boxes. Defaults to False. |
fold_loops | bool | If True, display ForOperation as folded blocks instead of unrolling. Defaults to True. |
expand_composite | bool | If True, expand boxed InvokeOperation bodies. Defaults to False. |
inline_depth | int | None | Maximum nesting depth for inline expansion. None means unlimited. Defaults to None. |
fold_ifs | bool | If True, display IfOperation as folded summary blocks. Defaults to False. |
**kwargs | Any | Concrete values for arguments. Arguments not provided here and without defaults are shown as symbolic parameters. |
Returns:
Any — Matplotlib figure object.
Raises:
ImportError— If matplotlib is not installed.ValueError— If aVector[Qubit]parameter requires a concrete size for visualization and no size is provided.ValidationError— If visualization-time compile-time if lowering rejects the traced graph.
qamomile.circuit.frontend.qkernel_block¶
Lazy block construction helpers for QKernel objects.
Overview¶
| Function | Description |
|---|---|
finalize_pending_self_calls | Back-patch forward-reference self-calls after block construction. |
func_to_block | Convert a typed frontend function to a hierarchical block. |
get_or_build_block | Return a qkernel’s cached hierarchical block, building it if needed. |
refresh_qkernel_function_namespace | Refresh an AST-transformed qkernel’s live Python name bindings. |
| Class | Description |
|---|---|
Block | Unified block representation for all pipeline stages. |
FrontendTransformError | Error during frontend AST-to-builder lowering. |
Functions¶
finalize_pending_self_calls [source]¶
def finalize_pending_self_calls(kernel: Any) -> NoneBack-patch forward-reference self-calls after block construction.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object with _pending_self_calls and a constructed _block. |
func_to_block [source]¶
def func_to_block(func: Callable) -> BlockConvert a typed frontend function to a hierarchical block.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable | Typed frontend function to trace. Registered static binding annotations are represented by typed proxy slots. |
Returns:
Block — Hierarchical trace containing ordinary inputs and any deferred
static binding slots.
Raises:
TypeError— If an input or return annotation is missing or unsupported, a static binding parameter declares a default, or the traced return value does not match its annotation.
Example:
def my_func(a: UInt, b: UInt) -> tuple[UInt]:
c = a + b
return (c, )
block = func_to_block(my_func)get_or_build_block [source]¶
def get_or_build_block(kernel: Any) -> BlockReturn a qkernel’s cached hierarchical block, building it if needed.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object with func, name, _block, _block_building, and _pending_self_calls attributes. |
Returns:
Block — Cached or freshly traced hierarchical block.
Raises:
FrontendTransformError— If a self-recursive qkernel accesses.blockdirectly while its own block is being built.
refresh_qkernel_function_namespace [source]¶
def refresh_qkernel_function_namespace(kernel: Any) -> NoneRefresh an AST-transformed qkernel’s live Python name bindings.
The transformed function is compiled into a private globals dictionary so generated control-flow helpers do not pollute the user’s module. Python module globals and closure values must nevertheless retain normal call-time lookup semantics, so this function synchronizes them immediately before each trace.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object exposing raw_func, func, and name attributes. |
Raises:
FrontendTransformError— If a closure cell required by the transformed function is empty at trace time.
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.
FrontendTransformError [source]¶
class FrontendTransformError(QamomileCompileError)Error during frontend AST-to-builder lowering.
qamomile.circuit.frontend.qkernel_build¶
Build and tracing helpers for QKernel objects.
Overview¶
| Function | Description |
|---|---|
auto_detect_parameters | Detect unbound classical arguments that should be runtime parameters. |
build_param_slots | Build a ParamSlot tuple for the classical arguments of a kernel. |
build_qkernel | Build a traced block from a qkernel. |
build_specialized_block | Trace a specialized sub-block for a call site. |
create_bound_input | Create a frontend handle for a compile-time-bound value. |
create_dummy_input | Create a dummy input based on parameter type annotation. |
create_parameter_input | Create a symbolic frontend handle for a runtime parameter. |
create_traced_block | Trace a kernel and return a Block. |
extract_return_names | Extract display names from the kernel’s return statement. |
get_array_element_type | Extract the element type from an array type annotation. |
is_array_type | Check if type is a Vector, Matrix, or Tensor subclass. |
is_static_binding_annotation | Return whether an annotation denotes a registered static binding. |
qubit_array | Create a new 1-D qubit register and emit its QInitOperation. |
refresh_qkernel_function_namespace | Refresh an AST-transformed qkernel’s live Python name bindings. |
resolve_qkernel_like_return_type | Return a qkernel-like object’s complete resolved return annotation. |
trace | Context manager to set the current tracer. |
validate_bindings_parameters_disjoint | Enforce the project rule that bindings and parameters are disjoint. |
validate_kwargs | Validate compile-time bindings for QKernel.build. |
validate_parameters | Validate the explicit runtime parameter list. |
validate_static_binding_argument | Validate a concrete binding or caller-owned symbolic binding proxy. |
| Class | Description |
|---|---|
Block | Unified block representation for all pipeline stages. |
BlockKind | Classification of block structure for pipeline stages. |
ReturnOperation | Explicit return operation marking the end of a block with return values. |
Tracer | Collects operations (and loop-rebind records) during tracing. |
Value | A typed SSA value in the IR. |
Constants¶
ValueLike:TypeAlias='Value | ArrayValue | TupleValue | DictValue'
Functions¶
auto_detect_parameters [source]¶
def auto_detect_parameters(
signature: inspect.Signature,
input_types: dict[str, type],
kwargs: dict[str, Any],
) -> list[str]Detect unbound classical arguments that should be runtime parameters.
Parameters:
| Name | Type | Description |
|---|---|---|
signature | inspect.Signature | Python signature of the qkernel. |
input_types | dict[str, type] | Resolved frontend annotations keyed by parameter name. |
kwargs | dict[str, Any] | Compile-time bindings supplied to QKernel.build. |
Returns:
list[str] — list[str]: Parameter names that should remain symbolic.
build_param_slots [source]¶
def build_param_slots(
signature: inspect.Signature,
input_types: dict[str, Any],
*,
parameters: list[str] | None = None,
kwargs: dict[str, Any] | None = None,
qubit_sizes: dict[str, int] | None = None,
bind_defaults: bool,
) -> tuple[ParamSlot, ...]Build a ParamSlot tuple for the classical arguments of a kernel.
Mirrors the argument-classification logic in
qkernel_build.create_traced_block so the resulting slot list reflects
the same decisions that drive symbolic-vs-bound input creation.
Classical scalar / array arguments are always included; a Dict
argument is included only when it is a runtime parameter (its slot
carries a DictType). Pure-quantum arguments, Tuple arguments,
and compile-time-bound Dict arguments are excluded and live in
Block.input_values instead.
Parameters:
| Name | Type | Description |
|---|---|---|
signature | inspect.Signature | The kernel function’s signature. |
input_types | dict[str, Any] | Resolved frontend type annotations keyed by argument name (typically QKernel.input_types or the equivalent computed in func_to_block). |
parameters | list[str] | None | Names explicitly requested as runtime parameters via parameters=[...]. None is treated as an empty list. |
kwargs | dict[str, Any] | None | Concrete values supplied via bindings / direct kwargs. None is treated as an empty dict. |
qubit_sizes | dict[str, int] | None | Optional mapping from Vector[Qubit] parameter names to their integer sizes; these are quantum inputs and are not included in the slot list. |
bind_defaults | bool | When True, Python signature defaults are treated as COMPILE_TIME_BOUND with bound_value=default. When False (e.g., the func_to_block path that does not bake in defaults), defaulted arguments stay RUNTIME_PARAMETER and the default appears only in ParamSlot.default. |
Returns:
tuple[ParamSlot, ...] — tuple[ParamSlot, ...]: One slot per classical argument, in the
order they appear in signature.parameters.
Raises:
TypeError— If a non-static classical annotation cannot be represented by an IR parameter type.
build_qkernel [source]¶
def build_qkernel(kernel: Any, parameters: list[str] | None = None, **kwargs: Any = {}) -> BlockBuild a traced block from a qkernel.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object to trace. |
parameters | list[str] | None | Argument names to preserve as runtime parameters. Defaults to None, which auto-detects parameters. |
**kwargs | Any | Concrete values for non-parameter arguments. |
Returns:
Block — Traced block ready for transpilation, estimation, or
Block — visualization.
Raises:
TypeError— If a non-parameterizable type is listed as a parameter.ValueError— If required arguments are missing, or if a name appears in bothparametersandkwargs(the compile-time-bound values), which violates the bindings/parameters disjointness rule.
build_specialized_block [source]¶
def build_specialized_block(
kernel: Any,
*,
parameters: list[str],
bindings: dict[str, Any],
qubit_sizes: dict[str, int],
) -> BlockTrace a specialized sub-block for a call site.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object to trace. |
parameters | list[str] | Classical argument names that remain symbolic in the specialized block. |
bindings | dict[str, Any] | Concrete Python values for classical arguments and caller-owned proxies for unresolved static bindings. |
qubit_sizes | dict[str, int] | First-axis sizes for Vector[Qubit] arguments supplied by the caller. |
Returns:
Block — Specialized hierarchical block ready to be invoked from the
Block — caller’s trace.
create_bound_input [source]¶
def create_bound_input(param_type: Any, name: str, value: Any) -> HandleCreate a frontend handle for a compile-time-bound value.
Parameters:
| Name | Type | Description |
|---|---|---|
param_type | Any | Frontend type annotation. |
name | str | QKernel parameter name. |
value | Any | Concrete compile-time binding. |
Returns:
Handle — Frontend handle carrying constant or runtime metadata.
Raises:
TypeError— Ifparam_typecannot be bound fromvalue.ValueError— If a scalar domain, array element, or container entry is invalid forparam_type.
create_dummy_input [source]¶
def create_dummy_input(
param_type: Any,
name: str = 'param',
emit_init: bool = True,
*,
shape: tuple[int, ...] | None = None,
) -> HandleCreate a dummy input based on parameter type annotation.
Parameters:
| Name | Type | Description |
|---|---|---|
param_type | Any | The type annotation for the parameter. |
name | str | Name for the value. |
emit_init | bool | If True, emit QInitOperation for qubit arrays (default: True). Set to False when creating a nested Block’s internal dummy inputs, or when the dummy will receive its qubits from a caller-side callable invocation. |
shape | tuple[int, ...] | None | Optional concrete shape for array types. When provided, the dummy array’s shape Values carry compile-time constants instead of symbolic placeholders. Used by call-time sub-kernel specialization so that shape-dependent stdlib helpers (qft / iqft / qpe) resolve get_size to a concrete integer and emit the correct gate sequence. Ignored for non-array types. Default: None (symbolic shape). |
Returns:
Handle — A frontend Handle wrapping a dummy Value or ArrayValue
suitable for use as a function-parameter input during
tracing.
Raises:
TypeError— Ifparam_typeis not a supported parameter type, or if a Tuple/array annotation is missing its element type(s).NotImplementedError— Ifparam_typeis a rank>1 quantum array annotation (Matrix[Qubit]/Tensor[Qubit]). The quantum addressing path is rank-1, so a higher-rank register would silently alias distinct elements onto the same physical qubit. This path constructs the handle viaobject.__new__(bypassingArrayBase.__post_init__), so it needs its own guard.
create_parameter_input [source]¶
def create_parameter_input(param_type: Any, name: str) -> HandleCreate a symbolic frontend handle for a runtime parameter.
Parameters:
| Name | Type | Description |
|---|---|---|
param_type | Any | Frontend type annotation. |
name | str | QKernel parameter name. |
Returns:
Handle — Symbolic handle carrying runtime parameter metadata.
Raises:
TypeError— Ifparam_typecannot be represented symbolically.
create_traced_block [source]¶
def create_traced_block(
kernel: Any,
parameters: list[str],
kwargs: dict[str, Any],
qubit_sizes: dict[str, int] | None = None,
*,
emit_qubit_init: bool = True,
emit_return_op: bool = False,
) -> BlockTrace a kernel and return a Block.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object to trace. |
parameters | list[str] | Argument names to keep as unbound parameters. |
kwargs | dict[str, Any] | Concrete values for non-parameter arguments and caller-owned proxies for unresolved static bindings. |
qubit_sizes | dict[str, int] | None | Optional mapping from Vector[Qubit] parameter names to integer sizes. Defaults to None. |
emit_qubit_init | bool | Whether quantum-array size entries should emit QInitOperation. Defaults to True. |
emit_return_op | bool | Whether to append an explicit ReturnOperation for inline-call specialization. Defaults to False. |
Returns:
Block — Traced block with label arguments, inputs, outputs, and
Block — parameter slots populated.
Raises:
TypeError— If a static binding declares a default, a concrete static binding has the wrong registered type, or a symbolic static binding does not preserve the parameter’s slot identity.ValueError— If a required static binding is absent fromkwargs.
extract_return_names [source]¶
def extract_return_names(kernel: 'QKernel[Any, Any]') -> list[str] | NoneExtract display names from the kernel’s return statement.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernel[Any, Any] | Kernel whose raw Python source should be inspected. |
Returns:
list[str] | None — list[str] | None: Return expression labels when a top-level return can
list[str] | None — be parsed, otherwise None.
get_array_element_type [source]¶
def get_array_element_type(param_type: Any) -> type | NoneExtract the element type from an array type annotation.
Parameters:
| Name | Type | Description |
|---|---|---|
param_type | Any | Frontend annotation such as Vector[Qubit]. |
Returns:
type | None — type | None: Element type when present, otherwise None.
is_array_type [source]¶
def is_array_type(t: Any) -> boolCheck if type is a Vector, Matrix, or Tensor subclass.
is_static_binding_annotation [source]¶
def is_static_binding_annotation(annotation: Any) -> boolReturn whether an annotation denotes a registered static binding.
Parameters:
| Name | Type | Description |
|---|---|---|
annotation | Any | Resolved qkernel parameter annotation. |
Returns:
bool — Whether the annotation is registered.
qubit_array [source]¶
def qubit_array(shape: UInt | int | tuple[UInt | int, ...], name: str) -> Vector[Qubit]Create a new 1-D qubit register and emit its QInitOperation.
Parameters:
| Name | Type | Description |
|---|---|---|
shape | UInt | int | tuple[UInt | int, ...] | Number of qubits in the register, given either as a scalar or as a 1-tuple. Tuples with more than one dimension are rejected (see Raises). |
name | str | Name for the underlying ArrayValue. |
Returns:
Vector[Qubit] — Vector[Qubit]: A 1-D quantum register handle of the requested
size.
Raises:
TypeError— Ifshapeornamehas the wrong type.ValueError— Ifshapeis an empty tuple.NotImplementedError— Ifshapehas more than one dimension. The quantum addressing path is rank-1, so a higher-rank register would silently alias distinct elements onto the same physical qubit. Allocate a 1-DVector[Qubit]of the total size and compute flat indices explicitly instead (e.g.q[i * ncols + j]).
refresh_qkernel_function_namespace [source]¶
def refresh_qkernel_function_namespace(kernel: Any) -> NoneRefresh an AST-transformed qkernel’s live Python name bindings.
The transformed function is compiled into a private globals dictionary so generated control-flow helpers do not pollute the user’s module. Python module globals and closure values must nevertheless retain normal call-time lookup semantics, so this function synchronizes them immediately before each trace.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object exposing raw_func, func, and name attributes. |
Raises:
FrontendTransformError— If a closure cell required by the transformed function is empty at trace time.
resolve_qkernel_like_return_type [source]¶
def resolve_qkernel_like_return_type(kernel: Any) -> AnyReturn a qkernel-like object’s complete resolved return annotation.
Decorator-created kernels expose a frozen return_type property. Legacy
qkernel-like objects instead expose only a signature and original function,
so postponed string annotations must be resolved before ABI decisions.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object exposing a signature and, when its annotation is postponed, the original raw_func. |
Returns:
Any — Complete resolved return annotation.
Raises:
TypeError— If the annotation is missing or cannot be resolved without a frozenreturn_typecontract.
trace [source]¶
def trace(tracer: Tracer | None = None) -> Generator[Tracer, None, None]Context manager to set the current tracer.
validate_bindings_parameters_disjoint [source]¶
def validate_bindings_parameters_disjoint(bindings: dict[str, Any] | None, parameters: list[str] | None) -> NoneEnforce the project rule that bindings and parameters are disjoint.
A kernel argument name must be resolved exactly one way: compile-time bound
(in bindings, baked into the emitted circuit) or runtime symbolic (in
parameters, surviving as a backend parameter). Listing the same name in
both is ambiguous and historically caused silent miscompilation — the
binding won the resolution race and the runtime parameter was silently
dropped from the emitted circuit (see #354). This is the single shared
checker so the rule is enforced identically at every entry point
(QKernel.build / Transpiler.to_block / Transpiler.emit /
Transpiler.transpile), not only in the top-level transpile wrapper.
Parameters:
| Name | Type | Description |
|---|---|---|
bindings | dict[str, Any] | None | Compile-time bindings keyed by argument name, or None. None is treated as empty. |
parameters | list[str] | None | Argument names to keep as runtime parameters, or None. None is treated as empty. |
Returns:
None — None
Raises:
ValueError— If any name appears in bothbindingsandparameters.
Example:
>>> validate_bindings_parameters_disjoint({"theta": 0.5}, ["phi"])
>>> validate_bindings_parameters_disjoint({"theta": 0.5}, ["theta"])
Traceback (most recent call last):
...
ValueError: Parameter name(s) ['theta'] appear in both ...validate_kwargs [source]¶
def validate_kwargs(
signature: inspect.Signature,
input_types: dict[str, type],
parameters: list[str],
kwargs: dict[str, Any],
) -> NoneValidate compile-time bindings for QKernel.build.
Parameters:
| Name | Type | Description |
|---|---|---|
signature | inspect.Signature | Python signature of the qkernel. |
input_types | dict[str, type] | Resolved frontend annotations keyed by parameter name. |
parameters | list[str] | Runtime parameter names. |
kwargs | dict[str, Any] | Compile-time bindings. |
Raises:
ValueError— If an unknown argument is supplied, or if a required non-parameter classical argument is missing.TypeError— If a static binding has a default value or a supplied object does not match its registered annotation.
validate_parameters [source]¶
def validate_parameters(input_types: dict[str, type], parameters: list[str]) -> NoneValidate the explicit runtime parameter list.
Parameters:
| Name | Type | Description |
|---|---|---|
input_types | dict[str, type] | Resolved qkernel input annotations. |
parameters | list[str] | Requested runtime parameter names. |
Raises:
ValueError— If a requested name is not a qkernel parameter.TypeError— If a requested parameter type cannot stay symbolic.
validate_static_binding_argument [source]¶
def validate_static_binding_argument(annotation: Any, name: str, value: Any) -> AnyValidate a concrete binding or caller-owned symbolic binding proxy.
Parameters:
| Name | Type | Description |
|---|---|---|
annotation | Any | Registered qkernel parameter annotation. |
name | str | Callee parameter name used as the binding-slot identity. |
value | Any | Concrete registered object or symbolic binding proxy. |
Returns:
Any — The validated concrete object or unchanged symbolic proxy.
Raises:
TypeError— If a concrete object has the wrong type, or a symbolic proxy does not preserve the callee parameter’s slot name and type key.
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
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.
Tracer [source]¶
class TracerCollects operations (and loop-rebind records) during tracing.
Constructor¶
def __init__(
self,
_operations: list[Operation] = list(),
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_entries: dict[str, Any] = dict(),
loop_region_results: dict[str, Any] = dict(),
) -> NoneAttributes¶
loop_carried_rebinds: tuple[LoopCarriedRebind, ...]loop_region_results: dict[str, Any]operations: list[Operation]region_entries: dict[str, Any]
Methods¶
add_operation¶
def add_operation(self, op) -> NoneValue [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.frontend.qkernel_callable¶
QKernel helpers for compiler-facing callable invocation objects.
Overview¶
| Function | Description |
|---|---|
block_call_operands_and_results | Materialize one block invocation’s operands and results. |
qkernel_callable_attrs | Return compiler attrs for a qkernel invocation. |
qkernel_callable_def | Build the inline-by-default callable definition for a qkernel block. |
qkernel_callable_ref | Return the compiler-facing callable reference for a qkernel. |
qkernel_invoke_block | Create an InvokeOperation for a qkernel call. |
signature_from_block | Build a callable signature from a traced implementation block. |
| Class | Description |
|---|---|
Block | Unified block representation for all pipeline stages. |
CallPolicy | Describe the default lowering policy for a callable call. |
CallableDef | Describe a compiler-facing callable definition. |
CallableRef | Identify a callable independently of its Python object. |
InvokeOperation | Represent a composite, stdlib, or oracle call. |
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.
qkernel_callable_attrs [source]¶
def qkernel_callable_attrs(kernel: Any) -> dict[str, Any]Return compiler attrs for a qkernel invocation.
Composite metadata lives directly on QKernel. This helper is the
single translation point from that frontend state into serializer-safe IR
attributes, so direct, controlled, and inverse calls share one identity.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object carrying callable metadata. |
Returns:
dict[str, Any] — dict[str, Any]: Serializer-friendly callable attributes.
qkernel_callable_def [source]¶
def qkernel_callable_def(kernel: Any, block: Block) -> CallableDefBuild the inline-by-default callable definition for a qkernel block.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object carrying callable metadata. |
block | Block | Implementation body for the qkernel. |
Returns:
CallableDef — Compiler-facing definition for the qkernel.
qkernel_callable_ref [source]¶
def qkernel_callable_ref(kernel: Any) -> CallableRefReturn the compiler-facing callable reference for a qkernel.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object carrying callable metadata. |
Returns:
CallableRef — Stable reference used by InvokeOperation call sites.
qkernel_invoke_block [source]¶
def qkernel_invoke_block(
kernel: Any,
block: Block,
inputs_map: Mapping[str, ValueLike],
) -> InvokeOperationCreate an InvokeOperation for a qkernel call.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object carrying callable metadata. |
block | Block | Callee body referenced by the callable definition. |
inputs_map | Mapping[str, ValueLike] | Actual argument values keyed by callee label. |
Returns:
InvokeOperation — Inline-by-default qkernel invocation.
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.
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.
CallPolicy [source]¶
class CallPolicy(enum.Enum)Describe the default lowering policy for a callable call.
Attributes¶
INLINENATIVE_FIRSTPRESERVE_BOX
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.
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
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.
qamomile.circuit.frontend.qkernel_definition¶
Definition-time helpers for QKernel construction.
Overview¶
| Function | Description |
|---|---|
collect_quantum_rebind_violations | Analyze func for forbidden quantum rebind patterns. |
flatten_kernel_return_type | Flatten a qkernel return annotation into its output-slot types. |
format_rebind_violation | Format a quantum-rebind violation for a user-facing error. |
get_quantum_rebind_error | Capture an illegal quantum rebind for deferred input validation. |
quantum_param_names | Return parameter names whose frontend type is quantum. |
refresh_qkernel_function_namespace | Refresh an AST-transformed qkernel’s live Python name bindings. |
resolve_qkernel_like_return_type | Return a qkernel-like object’s complete resolved return annotation. |
transform_control_flow | Rewrite Python control flow into tracer-visible region builders. |
transform_qkernel_function | Transform a Python function into the frontend DSL function. |
try_resolve_kernel_input_types | Resolve each qkernel input annotation independently. |
try_resolve_kernel_return_type | Resolve one return annotation independently from parameter hints. |
validate_quantum_rebinds | Reject illegal quantum variable rebindings in a qkernel body. |
| Class | Description |
|---|---|
FrontendTransformError | Error during frontend AST-to-builder lowering. |
QubitRebindError | Quantum variable reassigned from a different quantum source. |
RegionLocation | Identify one source-level structured control-flow region. |
RegionSignature | Describe values crossing one structured region boundary. |
Functions¶
collect_quantum_rebind_violations [source]¶
def collect_quantum_rebind_violations(func: Callable, quantum_param_names: set[str]) -> list[RebindViolation]Analyze func for forbidden quantum rebind patterns.
Returns a (possibly empty) list of violations. Never raises on
analysis failure – returns [] instead.
flatten_kernel_return_type [source]¶
def flatten_kernel_return_type(return_type: Any) -> list[Any]Flatten a qkernel return annotation into its output-slot types.
A Python tuple denotes multiple ABI results, while every other annotation,
including the structural Tuple handle, denotes one result. A None
annotation denotes no result slots.
Parameters:
| Name | Type | Description |
|---|---|---|
return_type | Any | Complete qkernel return annotation. |
Returns:
list[Any] — list[Any]: Frontend annotations ordered by output slot.
Raises:
TypeError— If a variable-length Python tuple is declared because its result arity cannot be represented by the qkernel ABI.
format_rebind_violation [source]¶
def format_rebind_violation(v: RebindViolation) -> tuple[str, str, str]Format a quantum-rebind violation for a user-facing error.
Parameters:
| Name | Type | Description |
|---|---|---|
v | RebindViolation | Violation record produced by the AST analyzer. |
Returns:
tuple[str, str, str] — tuple[str, str, str]: Offending pattern, reason, and suggested fix.
Raises:
AssertionError— If the analyzer produced an internally inconsistent violation record.
get_quantum_rebind_error [source]¶
def get_quantum_rebind_error(
func: Callable[..., Any],
*,
kernel_name: str,
input_types: dict[str, Any],
) -> QubitRebindError | NoneCapture an illegal quantum rebind for deferred input validation.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable[..., Any] | Raw user function. |
kernel_name | str | User-visible qkernel name for diagnostics. |
input_types | dict[str, Any] | Resolved annotations or raw deferred fallbacks keyed by parameter name. |
Returns:
QubitRebindError | None — QubitRebindError | None: Validation error, or None when the body is
QubitRebindError | None — valid for the resolved input types.
quantum_param_names [source]¶
def quantum_param_names(input_types: dict[str, Any]) -> set[str]Return parameter names whose frontend type is quantum.
Parameters:
| Name | Type | Description |
|---|---|---|
input_types | dict[str, Any] | Resolved annotations or raw deferred fallbacks keyed by parameter name. |
Returns:
set[str] — set[str]: Names annotated as Qubit or an array of Qubit.
refresh_qkernel_function_namespace [source]¶
def refresh_qkernel_function_namespace(kernel: Any) -> NoneRefresh an AST-transformed qkernel’s live Python name bindings.
The transformed function is compiled into a private globals dictionary so generated control-flow helpers do not pollute the user’s module. Python module globals and closure values must nevertheless retain normal call-time lookup semantics, so this function synchronizes them immediately before each trace.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object exposing raw_func, func, and name attributes. |
Raises:
FrontendTransformError— If a closure cell required by the transformed function is empty at trace time.
resolve_qkernel_like_return_type [source]¶
def resolve_qkernel_like_return_type(kernel: Any) -> AnyReturn a qkernel-like object’s complete resolved return annotation.
Decorator-created kernels expose a frozen return_type property. Legacy
qkernel-like objects instead expose only a signature and original function,
so postponed string annotations must be resolved before ABI decisions.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object exposing a signature and, when its annotation is postponed, the original raw_func. |
Returns:
Any — Complete resolved return annotation.
Raises:
TypeError— If the annotation is missing or cannot be resolved without a frozenreturn_typecontract.
transform_control_flow [source]¶
def transform_control_flow(
func: Callable[..., Any],
*,
region_signatures: dict[RegionLocation, RegionSignature] | None = None,
) -> Callable[..., Any]Rewrite Python control flow into tracer-visible region builders.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable[..., Any] | Raw qkernel function. |
region_signatures | dict[RegionLocation, RegionSignature] | None | Precomputed explicit region interfaces. Defaults to None. |
Returns:
Callable[..., Any] — Callable[..., Any]: Transformed function executed by the tracer.
Raises:
SyntaxError— If source retrieval or parsing fails.NotImplementedError— If a referenced closure value is unavailable.
transform_qkernel_function [source]¶
def transform_qkernel_function(
func: Callable[..., Any],
region_signatures: dict[RegionLocation, RegionSignature] | None = None,
) -> Callable[..., Any]Transform a Python function into the frontend DSL function.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable[..., Any] | Raw user function decorated as a qkernel. |
region_signatures | dict[RegionLocation, RegionSignature] | None | Precomputed explicit control-flow interfaces. Defaults to None. |
Returns:
Callable[..., Any] — Callable[..., Any]: AST-transformed function.
Raises:
FrontendTransformError— If the transform reports an unsupported frontend construct.SyntaxError— If the transform detects invalid syntax-level DSL usage.
try_resolve_kernel_input_types [source]¶
def try_resolve_kernel_input_types(
func: Callable[..., Any],
signature: inspect.Signature,
) -> tuple[dict[str, Any], dict[str, NameError]]Resolve each qkernel input annotation independently.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable[..., Any] | Raw user function. |
signature | inspect.Signature | Function signature. |
Returns:
dict[str, Any] — tuple[dict[str, Any], dict[str, NameError]]: Resolved annotations or raw
dict[str, NameError] — fallbacks by parameter, plus resolution errors for deferred
tuple[dict[str, Any], dict[str, NameError]] — annotations.
Raises:
TypeError— If any parameter is missing an annotation or an annotation expression is definitively invalid.
try_resolve_kernel_return_type [source]¶
def try_resolve_kernel_return_type(
func: Callable[..., Any],
signature: inspect.Signature,
) -> tuple[Any, bool, NameError | None]Resolve one return annotation independently from parameter hints.
An unresolved forward reference is retained so a live QKernel can
retry it at the first compilation entry point. Once resolution succeeds,
the kernel freezes that result as its return contract.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable[..., Any] | Raw user function. |
signature | inspect.Signature | Function signature. |
Returns:
Any — tuple[Any, bool, NameError | None]: Annotation or raw fallback,
bool — whether resolution succeeded, and the resolution error when it did
NameError | None — not.
Raises:
TypeError— If the return type is missing an annotation or the annotation expression is definitively invalid.
validate_quantum_rebinds [source]¶
def validate_quantum_rebinds(
func: Callable[..., Any],
*,
kernel_name: str,
input_types: dict[str, Any],
) -> NoneReject illegal quantum variable rebindings in a qkernel body.
Parameters:
| Name | Type | Description |
|---|---|---|
func | Callable[..., Any] | Raw user function. |
kernel_name | str | User-visible qkernel name for diagnostics. |
input_types | dict[str, Any] | Resolved annotations or raw deferred fallbacks keyed by parameter name. |
Raises:
QubitRebindError— If the AST analyzer finds a forbidden quantum variable reassignment.
Classes¶
FrontendTransformError [source]¶
class FrontendTransformError(QamomileCompileError)Error during frontend AST-to-builder lowering.
QubitRebindError [source]¶
class QubitRebindError(AffineTypeError)Quantum variable reassigned from a different quantum source.
When a quantum variable is reassigned, the RHS must consume the same variable (self-update pattern). Reassigning from a different quantum variable would silently discard the original quantum state.
The check runs at qkernel decoration time as a static AST analysis
(see qamomile.circuit.frontend.ast_transform.collect_quantum_rebind_violations)
and raises immediately — the wrapped QKernel object is never
constructed when a violation is present. The check is run
unconditionally for every decorated kernel: kernel-level quantum
parameters (Qubit / Vector[Qubit]) seed origins from the
signature, and the analyzer’s recognition of internal quantum
constructors (qubit(...) / qubit_array(...)) seeds further
origins from inside the body so kernels that derive all of their
quantum state from internal allocations are also covered.
Branch-internal rebinds (assignments inside an if / for /
while body) are NOT flagged at decoration time: compile-time
conditional branches legitimately rebind quantum names (the
compile-time-if lowering pass selects one branch and discards the
other), and the single-pass AST analyzer cannot distinguish
compile-time from runtime branches. To keep those compile-time
patterns working, branch-internal violations are suppressed.
The runtime side of that gap is closed at the IR layer instead:
reject_control_flow_quantum_discard (in
qamomile.circuit.transpiler.passes.analyze) classifies branch
conditions the same way the compile-time-if lowering pass does and
raises this same QubitRebindError for a runtime
if cond: q = qm.qubit("fresh") that discards the pre-branch
state — and for a for / while body rebind that discards the
incoming loop state the same way — while leaving compile-time branch
rebinds legal; so a caller catching QubitRebindError (or
AffineTypeError) sees the decoration-time and IR-time forms of
the violation uniformly. That IR check covers if conditions that
transitively derive from a measurement (including expression forms
like ~bit); a condition that is neither compile-time-resolvable
nor measurement-derived cannot drive runtime branching and keeps its
emit-time diagnosis. (AffineValidationPass itself still only
enforces “consumed at most once”.) Top-level (non-branch-internal)
bypasses continue to raise at decoration time.
Example of incorrect code:
a = qm.h(b) # ERROR: ‘a’ was quantum, now overwritten from ‘b’ a = b # ERROR: ‘a’ was quantum, now overwritten from ‘b’
Correct patterns:
a = qm.h(a) # Self-update (OK) new = qm.h(b) # New binding (OK, ‘new’ wasn’t quantum before)
RegionLocation [source]¶
class RegionLocationIdentify one source-level structured control-flow region.
Parameters:
| Name | Type | Description |
|---|---|---|
kind | str | Region kind: for, while, or if. |
lineno | int | One-based source line in the original source file. |
col_offset | int | Zero-based source column. |
Constructor¶
def __init__(self, kind: str, lineno: int, col_offset: int) -> NoneAttributes¶
col_offset: intkind: strlineno: int
RegionSignature [source]¶
class RegionSignatureDescribe values crossing one structured region boundary.
Parameters:
| Name | Type | Description |
|---|---|---|
inputs | tuple[str, ...] | Explicit values passed to the region. |
carried | tuple[str, ...] | Values updated across a loop back edge or merged across branches. |
captures | tuple[str, ...] | Read-only region inputs. |
results | tuple[str, ...] | Updated values live after the region. |
Constructor¶
def __init__(
self,
inputs: tuple[str, ...],
carried: tuple[str, ...],
captures: tuple[str, ...],
results: tuple[str, ...],
) -> NoneAttributes¶
captures: tuple[str, ...]carried: tuple[str, ...]inputs: tuple[str, ...]results: tuple[str, ...]
qamomile.circuit.frontend.qkernel_inputs¶
Build input helpers for QKernel tracing.
Overview¶
| Function | Description |
|---|---|
auto_detect_parameters | Detect unbound classical arguments that should be runtime parameters. |
create_bound_input | Create a frontend handle for a compile-time-bound value. |
create_dummy_input | Create a dummy input based on parameter type annotation. |
create_parameter_input | Create a symbolic frontend handle for a runtime parameter. |
get_array_element_type | Extract the element type from an array type annotation. |
is_array_type | Check if type is a Vector, Matrix, or Tensor subclass. |
is_dict_type | Check if type is a Dict handle type. |
is_parameterizable_type | Return whether an annotation can stay as a runtime parameter. |
is_static_binding_annotation | Return whether an annotation denotes a registered static binding. |
is_tuple_type | Check if type is a Tuple handle type. |
validate_bound_input_value | Validate one concrete qkernel binding without constructing a handle. |
validate_kwargs | Validate compile-time bindings for QKernel.build. |
validate_parameters | Validate the explicit runtime parameter list. |
validate_static_binding | Validate one concrete compile-time object binding. |
| Class | Description |
|---|---|
ArrayValue | An array of typed IR values. |
Bit | |
Dict | Dict handle for qkernel functions. |
DictValue | A dictionary value stored as stable ordered entries. |
Float | Floating-point handle with arithmetic operations. |
Qubit | |
Tuple | Tuple handle for qkernel functions. |
TupleValue | A tuple of IR values for structured data. |
UInt | Unsigned integer handle with arithmetic operations. |
Value | A typed SSA value in the IR. |
Vector | 1-dimensional array type. |
Functions¶
auto_detect_parameters [source]¶
def auto_detect_parameters(
signature: inspect.Signature,
input_types: dict[str, type],
kwargs: dict[str, Any],
) -> list[str]Detect unbound classical arguments that should be runtime parameters.
Parameters:
| Name | Type | Description |
|---|---|---|
signature | inspect.Signature | Python signature of the qkernel. |
input_types | dict[str, type] | Resolved frontend annotations keyed by parameter name. |
kwargs | dict[str, Any] | Compile-time bindings supplied to QKernel.build. |
Returns:
list[str] — list[str]: Parameter names that should remain symbolic.
create_bound_input [source]¶
def create_bound_input(param_type: Any, name: str, value: Any) -> HandleCreate a frontend handle for a compile-time-bound value.
Parameters:
| Name | Type | Description |
|---|---|---|
param_type | Any | Frontend type annotation. |
name | str | QKernel parameter name. |
value | Any | Concrete compile-time binding. |
Returns:
Handle — Frontend handle carrying constant or runtime metadata.
Raises:
TypeError— Ifparam_typecannot be bound fromvalue.ValueError— If a scalar domain, array element, or container entry is invalid forparam_type.
create_dummy_input [source]¶
def create_dummy_input(
param_type: Any,
name: str = 'param',
emit_init: bool = True,
*,
shape: tuple[int, ...] | None = None,
) -> HandleCreate a dummy input based on parameter type annotation.
Parameters:
| Name | Type | Description |
|---|---|---|
param_type | Any | The type annotation for the parameter. |
name | str | Name for the value. |
emit_init | bool | If True, emit QInitOperation for qubit arrays (default: True). Set to False when creating a nested Block’s internal dummy inputs, or when the dummy will receive its qubits from a caller-side callable invocation. |
shape | tuple[int, ...] | None | Optional concrete shape for array types. When provided, the dummy array’s shape Values carry compile-time constants instead of symbolic placeholders. Used by call-time sub-kernel specialization so that shape-dependent stdlib helpers (qft / iqft / qpe) resolve get_size to a concrete integer and emit the correct gate sequence. Ignored for non-array types. Default: None (symbolic shape). |
Returns:
Handle — A frontend Handle wrapping a dummy Value or ArrayValue
suitable for use as a function-parameter input during
tracing.
Raises:
TypeError— Ifparam_typeis not a supported parameter type, or if a Tuple/array annotation is missing its element type(s).NotImplementedError— Ifparam_typeis a rank>1 quantum array annotation (Matrix[Qubit]/Tensor[Qubit]). The quantum addressing path is rank-1, so a higher-rank register would silently alias distinct elements onto the same physical qubit. This path constructs the handle viaobject.__new__(bypassingArrayBase.__post_init__), so it needs its own guard.
create_parameter_input [source]¶
def create_parameter_input(param_type: Any, name: str) -> HandleCreate a symbolic frontend handle for a runtime parameter.
Parameters:
| Name | Type | Description |
|---|---|---|
param_type | Any | Frontend type annotation. |
name | str | QKernel parameter name. |
Returns:
Handle — Symbolic handle carrying runtime parameter metadata.
Raises:
TypeError— Ifparam_typecannot be represented symbolically.
get_array_element_type [source]¶
def get_array_element_type(param_type: Any) -> type | NoneExtract the element type from an array type annotation.
Parameters:
| Name | Type | Description |
|---|---|---|
param_type | Any | Frontend annotation such as Vector[Qubit]. |
Returns:
type | None — type | None: Element type when present, otherwise None.
is_array_type [source]¶
def is_array_type(t: Any) -> boolCheck if type is a Vector, Matrix, or Tensor subclass.
is_dict_type [source]¶
def is_dict_type(t: Any) -> boolCheck if type is a Dict handle type.
is_parameterizable_type [source]¶
def is_parameterizable_type(param_type: Any) -> boolReturn whether an annotation can stay as a runtime parameter.
Parameters:
| Name | Type | Description |
|---|---|---|
param_type | Any | Frontend type annotation to inspect. |
Returns:
bool — True when the type can be represented by backend runtime
bool — parameters.
is_static_binding_annotation [source]¶
def is_static_binding_annotation(annotation: Any) -> boolReturn whether an annotation denotes a registered static binding.
Parameters:
| Name | Type | Description |
|---|---|---|
annotation | Any | Resolved qkernel parameter annotation. |
Returns:
bool — Whether the annotation is registered.
is_tuple_type [source]¶
def is_tuple_type(t: Any) -> boolCheck if type is a Tuple handle type.
validate_bound_input_value [source]¶
def validate_bound_input_value(param_type: Any, name: str, value: Any) -> NoneValidate one concrete qkernel binding without constructing a handle.
This validation is intentionally side-effect free so entry points that
partition inputs before tracing, such as resource estimation, can apply
the same scalar and container contract as :func:create_bound_input
before selecting a later processing path.
Parameters:
| Name | Type | Description |
|---|---|---|
param_type | Any | Resolved qkernel input annotation. |
name | str | Public qkernel input name used in diagnostics. |
value | Any | Concrete Python value to validate. |
Raises:
TypeError— If a Float, Bit, array, Dict value, Tuple, or nested container element has the wrong Python kind.ValueError— If an array has the wrong shape, a UInt or Bit value is outside its supported domain, or a Tuple binding has the wrong arity.
validate_kwargs [source]¶
def validate_kwargs(
signature: inspect.Signature,
input_types: dict[str, type],
parameters: list[str],
kwargs: dict[str, Any],
) -> NoneValidate compile-time bindings for QKernel.build.
Parameters:
| Name | Type | Description |
|---|---|---|
signature | inspect.Signature | Python signature of the qkernel. |
input_types | dict[str, type] | Resolved frontend annotations keyed by parameter name. |
parameters | list[str] | Runtime parameter names. |
kwargs | dict[str, Any] | Compile-time bindings. |
Raises:
ValueError— If an unknown argument is supplied, or if a required non-parameter classical argument is missing.TypeError— If a static binding has a default value or a supplied object does not match its registered annotation.
validate_parameters [source]¶
def validate_parameters(input_types: dict[str, type], parameters: list[str]) -> NoneValidate the explicit runtime parameter list.
Parameters:
| Name | Type | Description |
|---|---|---|
input_types | dict[str, type] | Resolved qkernel input annotations. |
parameters | list[str] | Requested runtime parameter names. |
Raises:
ValueError— If a requested name is not a qkernel parameter.TypeError— If a requested parameter type cannot stay symbolic.
validate_static_binding [source]¶
def validate_static_binding(annotation: Any, name: str, value: Any) -> AnyValidate one concrete compile-time object binding.
Parameters:
| Name | Type | Description |
|---|---|---|
annotation | Any | Registered qkernel parameter annotation. |
name | str | Parameter name used in diagnostics. |
value | Any | Candidate binding value. |
Returns:
Any — The validated binding value.
Raises:
TypeError— If the annotation is not registered or the value has the wrong concrete type.
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]Bit [source]¶
class Bit(Handle)Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: bool = False,
) -> NoneAttributes¶
init_value: bool
Dict [source]¶
class Dict(Handle, Generic[K, V])Dict handle for qkernel functions.
Represents a dictionary mapping keys to values, commonly used
for Ising coefficients like {(i, j): Jij}. Supports iteration via
items() and subscript lookup (d[key]), including indexing
one dict with the iteration keys of another.
Example:
@qmc.qkernel
def ising_cost(
q: qmc.Vector[qmc.Qubit],
ising: qmc.Dict[qmc.Tuple[qmc.UInt, qmc.UInt], qmc.Float],
gammas: qmc.Dict[qmc.Tuple[qmc.UInt, qmc.UInt], qmc.Float],
) -> qmc.Vector[qmc.Qubit]:
for (i, j), Jij in qmc.items(ising):
q[i], q[j] = qmc.rzz(q[i], q[j], Jij * gammas[(i, j)])
return qConstructor¶
def __init__(
self,
value: DictValue,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_entries: list[tuple[Handle, Handle]] = list(),
_size: UInt | None = None,
_key_type: type | None = None,
_value_type: type | None = None,
_runtime_parameter: bool = False,
) -> NoneAttributes¶
size: UInt Return the number of entries as a UInt handle.value: DictValue
Methods¶
items¶
def items(self) -> DictItemsIterator[K, V]Return an iterator over (key, value) pairs.
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) -> DictValueFloat [source]¶
class Float(ArithmeticMixin, Handle)Floating-point handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: float = 0.0,
) -> NoneAttributes¶
init_value: float
Qubit [source]¶
class Qubit(Handle)Constructor¶
def __init__(
self,
value: Value[QubitType],
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
) -> NoneAttributes¶
value: Value[QubitType]
Tuple [source]¶
class Tuple(Handle, Generic[K, V])Tuple handle for qkernel functions.
Represents a tuple of values, commonly used for multi-index keys like (i, j) in Ising models.
Example:
@qmc.qkernel
def my_kernel(idx: qmc.Tuple[qmc.UInt, qmc.UInt]) -> qmc.UInt:
i, j = idx
return i + jConstructor¶
def __init__(
self,
value: TupleValue,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_elements: tuple[Handle, ...] = tuple(),
) -> NoneAttributes¶
value: TupleValue
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) -> TupleValueUInt [source]¶
class UInt(ArithmeticMixin, Handle)Unsigned integer handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: int = 0,
) -> NoneAttributes¶
init_value: int
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.
Vector [source]¶
class Vector(ArrayBase[T])1-dimensional array type.
Example:
import qamomile.circuit as qmc
# Create a vector of 3 qubits
qubits: qmc.Vector[qmc.Qubit] = qmc.qubit_array(3, name="qubits")
# Access elements
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0
# Apply H gate to all qubits (CORRECT)
n = qubits.shape[0]
for i in qmc.range(n):
qubits[i] = qmc.h(qubits[i])
# Slicing returns a VectorView over a subset of the parent vector.
# The view shares borrow tracking with the parent; element access
# on the view transparently indexes the parent.
evens = qubits[0::2]
for i in qmc.range(evens.shape[0]):
evens[i] = qmc.h(evens[i])Constructor¶
def __init__(
self,
value: ArrayValue = None,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_shape: tuple[int | UInt] = (0,),
_borrowed_indices: dict[tuple[str, ...], 'tuple[UInt, ...] | Handle'] = dict(),
) -> NoneAttributes¶
value: ArrayValue
qamomile.circuit.frontend.qkernel_invocation¶
Call-time invocation logic for QKernel objects.
Overview¶
| Function | Description |
|---|---|
emit_self_call_forward_ref | Emit a forward-reference invocation for a self-recursive qkernel call. |
get_current_tracer | |
invoke_qkernel | Invoke a QKernel inside a tracing context. |
invoke_qkernel_with_operation | Invoke a QKernel using a custom operation factory. |
is_array_type | Check if type is a Vector, Matrix, or Tensor subclass. |
is_dict_type | Check if type is a Dict handle type. |
is_full_reslice_of_input | Check whether an output is only full-sliced from a formal input. |
is_tuple_type | Check if type is a Tuple handle type. |
promote_literal_to_handle | Promote a Python literal to a scalar handle for qkernel calls. |
qkernel_invoke_block | Create an InvokeOperation for a qkernel call. |
reject_aliased_quantum_args | Reject overlapping live quantum resources at one call boundary. |
reject_consumed_view_arg | Reject an already-consumed vector view passed to a qkernel call. |
resolve_qkernel_like_return_type | Return a qkernel-like object’s complete resolved return annotation. |
select_specialized_block | Select the block implementation for a qkernel call site. |
view_result_value_for_full_reslice | Build the caller-side array value for a full re-sliced view output. |
| Class | Description |
|---|---|
ArrayBase | Base class for array types (Vector, Matrix, Tensor). |
ArrayValue | An array of typed IR values. |
Bit | |
Block | Unified block representation for all pipeline stages. |
Dict | Dict handle for qkernel functions. |
DictValue | A dictionary value stored as stable ordered entries. |
Float | Floating-point handle with arithmetic operations. |
Tuple | Tuple handle for qkernel functions. |
TupleValue | A tuple of IR values for structured data. |
UInt | Unsigned integer handle with arithmetic operations. |
Value | A typed SSA value in the IR. |
VectorView | Strided view over a parent Vector, backed by a sliced ArrayValue. |
Constants¶
ValueLike:TypeAlias='Value | ArrayValue | TupleValue | DictValue'
Functions¶
emit_self_call_forward_ref [source]¶
def emit_self_call_forward_ref(kernel: Any, inputs_map: dict[str, ValueLike]) -> InvokeOperationEmit a forward-reference invocation for a self-recursive qkernel call.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object currently building its block. |
inputs_map | dict[str, ValueLike] | Actual argument values keyed by parameter name. |
Returns:
InvokeOperation — Inline invocation whose definition body is
InvokeOperation — back-patched after the enclosing block is constructed.
Raises:
FrontendTransformError— If an unmatched array or structural output cannot be synthesized for the forward reference.
get_current_tracer [source]¶
def get_current_tracer() -> Tracerinvoke_qkernel [source]¶
def invoke_qkernel(kernel: Any, *args: Any = (), **kwargs: Any = {}) -> AnyInvoke a QKernel inside a tracing context.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel instance. |
*args | Any | Positional qkernel call arguments. |
**kwargs | Any | Keyword qkernel call arguments. |
Returns:
Any — A single frontend handle or a tuple of frontend handles matching
Any — the qkernel return annotation.
Raises:
TypeError— If an argument is not a frontend handle after literal promotion.RuntimeError— If no qkernel tracer is active, or if the generated invocation result count does not match the qkernel return annotation.
invoke_qkernel_with_operation [source]¶
def invoke_qkernel_with_operation(
kernel: Any,
invoke_block_factory: Any | None,
*args: Any = (),
**kwargs: Any = {},
) -> AnyInvoke a QKernel using a custom operation factory.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel instance. |
invoke_block_factory | Any | None | Optional callable that receives (block, inputs_map) and returns the invocation operation. |
*args | Any | Positional qkernel call arguments. |
**kwargs | Any | Keyword qkernel call arguments. |
Returns:
Any — A single frontend handle or a tuple of frontend handles matching
Any — the qkernel return annotation.
Raises:
TypeError— If an argument is not a frontend handle after literal promotion.RuntimeError— If no qkernel tracer is active, or if the generated invocation result count does not match the qkernel return annotation.
is_array_type [source]¶
def is_array_type(t: Any) -> boolCheck if type is a Vector, Matrix, or Tensor subclass.
is_dict_type [source]¶
def is_dict_type(t: Any) -> boolCheck if type is a Dict handle type.
is_full_reslice_of_input [source]¶
def is_full_reslice_of_input(output: ArrayValue, formal_input: ArrayValue) -> boolCheck whether an output is only full-sliced from a formal input.
Parameters:
| Name | Type | Description |
|---|---|---|
output | ArrayValue | Callee output array value. |
formal_input | ArrayValue | Callee formal input array value. |
Returns:
bool — True when every slice from output back to
bool — formal_input is 0:len:1 with equal concrete lengths or the
bool — same symbolic length identity.
is_tuple_type [source]¶
def is_tuple_type(t: Any) -> boolCheck if type is a Tuple handle type.
promote_literal_to_handle [source]¶
def promote_literal_to_handle(value: Any, expected_type: Any) -> AnyPromote a Python literal to a scalar handle for qkernel calls.
Parameters:
| Name | Type | Description |
|---|---|---|
value | Any | Argument value supplied at a qkernel call site. |
expected_type | Any | Callee annotation used to decide whether a scalar literal can be wrapped as UInt, Float, or Bit. |
Returns:
Any — A freshly-created scalar handle when a promotion rule applies,
Any — otherwise value unchanged.
qkernel_invoke_block [source]¶
def qkernel_invoke_block(
kernel: Any,
block: Block,
inputs_map: Mapping[str, ValueLike],
) -> InvokeOperationCreate an InvokeOperation for a qkernel call.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object carrying callable metadata. |
block | Block | Callee body referenced by the callable definition. |
inputs_map | Mapping[str, ValueLike] | Actual argument values keyed by callee label. |
Returns:
InvokeOperation — Inline-by-default qkernel invocation.
reject_aliased_quantum_args [source]¶
def reject_aliased_quantum_args(
kernel_name: str,
arguments: dict[str, Any],
*,
caller: str | None = None,
) -> NoneReject overlapping live quantum resources at one call boundary.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel_name | str | Name of the called qkernel for diagnostics. |
arguments | dict[str, Any] | Bound call arguments keyed by parameter name. |
caller | str | None | Optional operation label replacing the default QKernel[kernel_name] context. Defaults to None. |
Raises:
QubitConsumedError— If two quantum arguments may cover the same physical qubit.
reject_consumed_view_arg [source]¶
def reject_consumed_view_arg(kernel_name: str, handle: Handle) -> NoneReject an already-consumed vector view passed to a qkernel call.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel_name | str | Name of the called qkernel for diagnostics. |
handle | Handle | View argument to check. |
Raises:
QubitConsumedError— Ifhandlewas already consumed.
resolve_qkernel_like_return_type [source]¶
def resolve_qkernel_like_return_type(kernel: Any) -> AnyReturn a qkernel-like object’s complete resolved return annotation.
Decorator-created kernels expose a frozen return_type property. Legacy
qkernel-like objects instead expose only a signature and original function,
so postponed string annotations must be resolved before ABI decisions.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object exposing a signature and, when its annotation is postponed, the original raw_func. |
Returns:
Any — Complete resolved return annotation.
Raises:
TypeError— If the annotation is missing or cannot be resolved without a frozenreturn_typecontract.
select_specialized_block [source]¶
def select_specialized_block(
kernel: Any,
arguments: dict[str, Any],
*,
require_handles: bool = True,
) -> BlockSelect the block implementation for a qkernel call site.
Centralizes call-site specialization so plain qkernel calls, controlled
calls, and inverse calls use the same rule. When concrete argument values
would change the callee trace (for example a concrete Vector[Qubit]
size or a bound structural classical value), the function returns a
temporary specialized block. Otherwise it returns the kernel’s cached
block.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object whose block should be selected. |
arguments | dict[str, Any] | Bound call arguments after literal promotion and frontend validation. Registered static bindings may remain concrete Python objects when require_handles is false. |
require_handles | bool | If True, specialization is skipped unless every argument is a frontend Handle. Defaults to True. |
Returns:
Block — Specialized call-site block or the cached kernel block.
view_result_value_for_full_reslice [source]¶
def view_result_value_for_full_reslice(result_value: ArrayValue, input_view: Vector[Any]) -> ArrayValueBuild the caller-side array value for a full re-sliced view output.
Parameters:
| Name | Type | Description |
|---|---|---|
result_value | ArrayValue | Caller-local output materialized from the callee result. |
input_view | Vector[Any] | Caller-side view argument being preserved. |
Returns:
ArrayValue — Fresh SSA version preserving caller-side slice metadata.
Classes¶
ArrayBase [source]¶
class ArrayBase(Handle, Generic[T])Base class for array types (Vector, Matrix, Tensor).
Provides common functionality for array indexing and element access.
Constructor¶
def __init__(
self,
value: ArrayValue,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_shape: tuple[int | UInt, ...] = tuple(),
_borrowed_indices: dict[tuple[str, ...], 'tuple[UInt, ...] | Handle'] = dict(),
) -> NoneAttributes¶
element_type: Type[T]shape: tuple[int | UInt, ...] Return the shape of the array.value: ArrayValue
Methods¶
consume¶
def consume(self, operation_name: str = 'unknown') -> SelfConsume the array after validating its affine ownership state.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the consuming operation. Defaults to "unknown". |
Returns:
typing.Self — typing.Self: Fresh handle carrying the consumed array value.
Raises:
QubitConsumedError— If this handle or a covered slot was consumed.UnreturnedBorrowError— If a live element or slice borrow remains.
create¶
@classmethod
def create(
cls,
shape: tuple[int | UInt, ...],
name: str,
el_type: Type[T],
) -> 'ArrayBase[T]'Create an ArrayValue for the given shape and name.
validate_all_returned¶
def validate_all_returned(self) -> NoneValidate all borrowed elements have been returned.
Strict-return policy: an active slice view that is still
registered as the owner of any parent slot is treated as an
unreturned borrow even if the view itself has no outstanding
element borrows. The caller must perform an explicit slice
assignment (parent[a:b:c] = view) to release the view’s
bulk-borrow before consuming the parent. Destructively consumed
scalar or view owners (parked in the dict with _consumed set and
_consumed_by classified as :attr:ConsumeMode.DESTRUCTIVE)
record physically-destroyed slots and are not outstanding borrows; they survive
end-of-block so a later whole-array consume can detect and
reject the destroyed slots.
Raises:
UnreturnedBorrowError— If any elements are still borrowed, either directly or by a slice view that has not been explicitly returned via slice assignment.
validate_consumable¶
def validate_consumable(self, operation_name: str = 'unknown') -> NoneValidate an array consume without changing ownership state.
For quantum arrays, all borrowed elements must be returned before the array can be consumed. This ensures that no unreturned borrows are silently discarded by operations like qkernel calls or controlled gates.
When any slot of the array has already been physically consumed
by an earlier destructive element or view operation
(measure(q[0]) or measure(q[1::2]) followed by
measure(q)), this raises QubitConsumedError rather than
silently re-consuming those slots.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the prospective consuming operation. Defaults to "unknown". |
Raises:
QubitConsumedError— If this handle or any covered slot was already consumed.UnreturnedBorrowError— If a live element or slice borrow remains.
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]Bit [source]¶
class Bit(Handle)Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: bool = False,
) -> NoneAttributes¶
init_value: bool
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.
Dict [source]¶
class Dict(Handle, Generic[K, V])Dict handle for qkernel functions.
Represents a dictionary mapping keys to values, commonly used
for Ising coefficients like {(i, j): Jij}. Supports iteration via
items() and subscript lookup (d[key]), including indexing
one dict with the iteration keys of another.
Example:
@qmc.qkernel
def ising_cost(
q: qmc.Vector[qmc.Qubit],
ising: qmc.Dict[qmc.Tuple[qmc.UInt, qmc.UInt], qmc.Float],
gammas: qmc.Dict[qmc.Tuple[qmc.UInt, qmc.UInt], qmc.Float],
) -> qmc.Vector[qmc.Qubit]:
for (i, j), Jij in qmc.items(ising):
q[i], q[j] = qmc.rzz(q[i], q[j], Jij * gammas[(i, j)])
return qConstructor¶
def __init__(
self,
value: DictValue,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_entries: list[tuple[Handle, Handle]] = list(),
_size: UInt | None = None,
_key_type: type | None = None,
_value_type: type | None = None,
_runtime_parameter: bool = False,
) -> NoneAttributes¶
size: UInt Return the number of entries as a UInt handle.value: DictValue
Methods¶
items¶
def items(self) -> DictItemsIterator[K, V]Return an iterator over (key, value) pairs.
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) -> DictValueFloat [source]¶
class Float(ArithmeticMixin, Handle)Floating-point handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: float = 0.0,
) -> NoneAttributes¶
init_value: float
Tuple [source]¶
class Tuple(Handle, Generic[K, V])Tuple handle for qkernel functions.
Represents a tuple of values, commonly used for multi-index keys like (i, j) in Ising models.
Example:
@qmc.qkernel
def my_kernel(idx: qmc.Tuple[qmc.UInt, qmc.UInt]) -> qmc.UInt:
i, j = idx
return i + jConstructor¶
def __init__(
self,
value: TupleValue,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_elements: tuple[Handle, ...] = tuple(),
) -> NoneAttributes¶
value: TupleValue
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) -> TupleValueUInt [source]¶
class UInt(ArithmeticMixin, Handle)Unsigned integer handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: int = 0,
) -> NoneAttributes¶
init_value: int
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.
VectorView [source]¶
class VectorView(Vector[T])Strided view over a parent Vector, backed by a sliced ArrayValue.
A VectorView is produced by slicing a Vector (q[1::2],
q[a:b], etc.). It is a thin Vector subclass whose value
is a fresh ArrayValue with slice_of / slice_start /
slice_step metadata pointing back to the parent’s ArrayValue.
Element accesses go through Vector._get_element unchanged — the
IR element carries parent_array = sliced_av, and the emit-time
resolver walks the slice_of chain to produce the physical qubit
index. No affine translation happens in the view itself.
Because the sliced ArrayValue is a first-class IR Value,
the view can be passed as an operand of an inline callable invocation
to another qkernel without the inline-trace special-case path that
earlier iterations required. Passing views through
expval / measure likewise operates on the sliced qubit
subset, not the root parent as a whole.
Linearity:
Slicing bulk-borrows the covered parent slots whenever
start, step and length are compile-time int
constants. While the view is live, accessing the corresponding
parent slot directly (q[0] after evens = q[0::2]) raises
QubitConsumedError. Under the strict-return policy the
view’s ownership is cleared only by two operations:
slice-assigning it back into the parent (
parent[a:b:c] = view) — this is the only path that fully releases the borrow without destroying the qubits;destructively consuming it (
measure(view)/cast(view, ...)/expval(view, H)) — the physical slots become consumed markers, no return needed.
Every other consume (broadcast gates h(view),
pauli_evolve(view, H, gamma), sub-kernel calls
f(view), controlled-U index_spec) only transfers
ownership to a freshly-wrapped VectorView and that new
view still must be returned via slice assignment. A view
left bulk-borrowing at the parent’s consume point raises
UnreturnedBorrowError.
Symbolic slices (q[lo:hi] with lo/hi UInt) cannot
enumerate their covered slots at trace time and therefore skip
the bulk-borrow here; SliceBorrowCheckPass picks them up
post-fold after bindings resolve the bounds to concrete values.
Example:
@qmc.qkernel
def alternating_h(q: qmc.Vector[qmc.Qubit]) -> qmc.Vector[qmc.Qubit]:
evens = q[0::2]
for i in qmc.range(evens.shape[0]):
evens[i] = qmc.h(evens[i])
q[0::2] = evens # explicit return before the parent is used
return qMethods¶
consume¶
def consume(self, operation_name: str = 'unknown') -> SelfConsume the view and release its parent slice-borrows.
Validates that every view-local borrow has been returned,
then dispatches on operation_name to keep the parent’s
slice-borrow record consistent with the new strict-return
semantics:
Destructive (
measure/cast): leaveselfparked in the parent’s borrow table as a destroyed-slot breadcrumb.super().consume()flipsself._consumed = Trueandself._consumed_by = operation_name, which is what :func:_is_destroyed_slot_ownerreads to reject subsequent access at the same slot.Releasing (
slice assignment): drop every parent entry thatselfcurrently owns. The caller (the slice- assignment frontend path) also emits aReleaseSliceViewOperationso the IR-level checker sees the release. This branch is reserved for explicit borrow- return paths.Transfer (every other op — broadcast gates, rotation, phase, ControlledU, sub-kernel call argument consumption, etc.): rebind the parent’s borrow entry from
selfto the new view handle returned here. The new view inheritsself._slice_covered_indicesso it can be slice-assigned back to the parent later — strict-return requires that eventualparent[a:b:c] = new_view.
Operations that produce a fresh sliced ArrayValue (e.g.
:func:qamomile.circuit.frontend.operation.pauli_evolve.pauli_evolve,
:class:QKernel.__call__ for callees that return a sliced
array) cannot simply use the auto-returned new_view
because the new view they build wraps a different Value
than this consume’s return. Those op implementations call
:meth:_transfer_borrow_to after building their result so
the parent’s borrow table tracks the right handle.
Parameters:
| Name | Type | Description |
|---|---|---|
operation_name | str | Name of the operation consuming this view (used in error messages and for dispatch). |
Returns:
typing.Self — A fresh view handle with the same backing state; under
typing.Self — transfer the parent’s borrow table now points at this
typing.Self — handle, under release / destruction the parent’s record
typing.Self — for the covered slots is finalised.
Raises:
QubitConsumedError— If any covered slot was already destroyed by a prior destructive consume on an overlapping element or view.
qamomile.circuit.frontend.qkernel_like¶
Structural protocol for qkernel-like frontend objects.
Overview¶
| Class | Description |
|---|---|
Block | Unified block representation for all pipeline stages. |
KernelEffect | Describe non-unitary behavior reachable from a kernel body. |
QKernelLike | Describe the frontend surface required by compiler entrypoints. |
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.
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.
QKernelLike [source]¶
class QKernelLike(Protocol)Describe the frontend surface required by compiler entrypoints.
This protocol is intentionally structural. It lets decorator-created
composites reuse the qkernel inspection and build interface without making
them inherit from QKernel or exposing the compiler-facing callable
descriptor model as a frontend concept.
Attributes¶
block: Block Return the cached hierarchical body block.effects: KernelEffect Return cached semantic effects of the qkernel body.input_types: dict[str, Any] Return frontend input annotations by parameter name.name: str Return the user-facing callable name.output_types: list[Any] Return frontend output annotations.signature: inspect.Signature Return the Python call signature.
Methods¶
build¶
def build(self, parameters: list[str] | None = None, **kwargs: Any = {}) -> BlockBuild a traced body block.
Parameters:
| Name | Type | Description |
|---|---|---|
parameters | list[str] | None | Runtime parameter names to preserve. Defaults to None. |
**kwargs | Any | Compile-time bindings for non-parameter arguments. |
Returns:
Block — Traced hierarchical body block.
qamomile.circuit.frontend.qkernel_metadata¶
Metadata helpers for QKernel convenience APIs.
Overview¶
| Function | Description |
|---|---|
estimate_qkernel_resources | Estimate resources for a kernel. |
extract_return_names | Extract display names from the kernel’s return statement. |
| Class | Description |
|---|---|
QKernel | Decorator class for Qamomile quantum kernels. |
Functions¶
estimate_qkernel_resources [source]¶
def estimate_qkernel_resources(
kernel: 'QKernel[Any, Any]',
*,
inputs: dict[str, Any] | None = None,
strategies: dict[str, str] | None = None,
trace: bool = False,
unknown_policy: str | UnknownResourcePolicy | None = None,
control_decomposition: str | ControlDecomposition | None = None,
) -> 'ResourceEstimate'Estimate resources for a kernel.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernel[Any, Any] | Kernel to estimate. |
inputs | dict[str, Any] | None | QKernel input values used to specialize the symbolic estimate. Exact one-dimensional root quantum-port widths declared by callable resource metadata are inferred when omitted. Defaults to None. |
strategies | dict[str, str] | None | Callable strategy overrides. Defaults to None. |
trace | bool | Whether to retain the explanation tree. Defaults to False. |
unknown_policy | str | UnknownResourcePolicy | None | Policy for bodyless callables without explicit costs. Defaults to None, which uses the estimator default. |
control_decomposition | str | ControlDecomposition | None | Coherent-control model override. Defaults to None, which uses the clean-ancilla Toffoli model. |
Returns:
'ResourceEstimate' — Estimated width, gate, measurement, reset, depth,
call, and parameter resources.
Raises:
RuntimeError— If a fixed or callback-provided opaque cost contains public metrics or metadata that disagree with retained canonical provenance.ValueError— If an input, estimation configuration, callable resource contract, or structural requirement is invalid.TypeError— If the qkernel cannot be built as an estimator input.NotImplementedError— If the qkernel contains a construct not supported by resource estimation.
extract_return_names [source]¶
def extract_return_names(kernel: 'QKernel[Any, Any]') -> list[str] | NoneExtract display names from the kernel’s return statement.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernel[Any, Any] | Kernel whose raw Python source should be inspected. |
Returns:
list[str] | None — list[str] | None: Return expression labels when a top-level return can
list[str] | None — be parsed, otherwise None.
Classes¶
QKernel [source]¶
class QKernel(QKernelBuildMixin, QKernelVisualizationMixin, Generic[P, R])Decorator class for Qamomile quantum kernels.
Constructor¶
def __init__(self, func: Callable[P, R]) -> NoneAttributes¶
block: Block Compile the function to a hierarchical Block if not already compiled.effects: KernelEffect Return cached semantic effects of this qkernel.funcinput_types: dict[str, Any] Return resolved and frozen frontend input annotations.nameoutput_types: list[Any] Return the resolved frontend annotation for every output slot.raw_funcreturn_type: Any Return the resolved and frozen complete return annotation.signature
qamomile.circuit.frontend.qkernel_rebind¶
Diagnostics for qkernel quantum-rebind analysis.
Overview¶
| Function | Description |
|---|---|
format_rebind_violation | Format a quantum-rebind violation for a user-facing error. |
| Class | Description |
|---|---|
RebindSourceKind | Discriminator for the source of a detected rebind violation. |
RebindViolation | A detected forbidden quantum variable rebinding. |
Functions¶
format_rebind_violation [source]¶
def format_rebind_violation(v: RebindViolation) -> tuple[str, str, str]Format a quantum-rebind violation for a user-facing error.
Parameters:
| Name | Type | Description |
|---|---|---|
v | RebindViolation | Violation record produced by the AST analyzer. |
Returns:
tuple[str, str, str] — tuple[str, str, str]: Offending pattern, reason, and suggested fix.
Raises:
AssertionError— If the analyzer produced an internally inconsistent violation record.
Classes¶
RebindSourceKind [source]¶
class RebindSourceKind(enum.StrEnum)Discriminator for the source of a detected rebind violation.
Each value classifies why the analyzer believes an existing quantum binding is being silently discarded, and lets downstream error-message formatting render a domain-appropriate explanation instead of forcing a generic “different quantum variable” sentence onto, e.g., a fresh allocation.
Members:
DIRECT_ALIAS: q = other_q or q = qs[i].
QUANTUM_ARG: q = f(other_q, ...) where other_q has a
different origin than q.
FRESH_ALLOCATION: q = qm.qubit(...) /
qm.qubit_array(...) — the original quantum state is
silently discarded in favor of a freshly allocated one.
UNKNOWN_CALL: q = some_func(...) where the call references
no known quantum variable and is not a recognized quantum
constructor; conservatively treated as a rebind because
the original q is not threaded through the RHS.
CHAINED_ASSIGNMENT: q1 = q2 = expr where at least one
target is an existing quantum variable; chained binding
semantics are too ambiguous to verify self-update.
Attributes¶
CHAINED_ASSIGNMENTDIRECT_ALIASFRESH_ALLOCATIONQUANTUM_ARGUNKNOWN_CALL
RebindViolation [source]¶
class RebindViolationA detected forbidden quantum variable rebinding.
Constructor¶
def __init__(
self,
target_name: str,
source_name: str | None,
source_kind: RebindSourceKind,
func_name: str | None,
lineno: int,
source_expr: str | None = None,
) -> NoneAttributes¶
func_name: str | Nonelineno: intsource_expr: str | Nonesource_kind: RebindSourceKindsource_name: str | Nonetarget_name: str
qamomile.circuit.frontend.qkernel_self_call¶
Self-recursive qkernel invocation helpers.
Overview¶
| Function | Description |
|---|---|
emit_self_call_forward_ref | Emit a forward-reference invocation for a self-recursive qkernel call. |
finalize_pending_self_calls | Back-patch forward-reference self-calls after block construction. |
handle_type_map | Map Handle type to ValueType. |
is_array_type | Check if type is a Vector, Matrix, or Tensor subclass. |
is_dict_type | Check if type is a Dict handle type. |
is_tuple_type | Check if type is a Tuple handle type. |
match_output_to_input | Return the first unclaimed input whose handle type matches output. |
qkernel_callable_attrs | Return compiler attrs for a qkernel invocation. |
qkernel_callable_def | Build the inline-by-default callable definition for a qkernel block. |
qkernel_callable_ref | Return the compiler-facing callable reference for a qkernel. |
signature_from_values | Build a callable signature from concrete operand and result values. |
| Class | Description |
|---|---|
CallPolicy | Describe the default lowering policy for a callable call. |
CallableDef | Describe a compiler-facing callable definition. |
FrontendTransformError | Error during frontend AST-to-builder lowering. |
InvokeOperation | Represent a composite, stdlib, or oracle call. |
Value | A typed SSA value in the IR. |
Constants¶
ValueLike:TypeAlias='Value | ArrayValue | TupleValue | DictValue'
Functions¶
emit_self_call_forward_ref [source]¶
def emit_self_call_forward_ref(kernel: Any, inputs_map: dict[str, ValueLike]) -> InvokeOperationEmit a forward-reference invocation for a self-recursive qkernel call.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object currently building its block. |
inputs_map | dict[str, ValueLike] | Actual argument values keyed by parameter name. |
Returns:
InvokeOperation — Inline invocation whose definition body is
InvokeOperation — back-patched after the enclosing block is constructed.
Raises:
FrontendTransformError— If an unmatched array or structural output cannot be synthesized for the forward reference.
finalize_pending_self_calls [source]¶
def finalize_pending_self_calls(kernel: Any) -> NoneBack-patch forward-reference self-calls after block construction.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object with _pending_self_calls and a constructed _block. |
handle_type_map [source]¶
def handle_type_map(handle_type: type[Handle] | type) -> ValueTypeMap Handle type to ValueType.
is_array_type [source]¶
def is_array_type(t: Any) -> boolCheck if type is a Vector, Matrix, or Tensor subclass.
is_dict_type [source]¶
def is_dict_type(t: Any) -> boolCheck if type is a Dict handle type.
is_tuple_type [source]¶
def is_tuple_type(t: Any) -> boolCheck if type is a Tuple handle type.
match_output_to_input [source]¶
def match_output_to_input(output_type: Any, input_types: list[Any], claimed: list[bool]) -> int | NoneReturn the first unclaimed input whose handle type matches output.
Parameters:
| Name | Type | Description |
|---|---|---|
output_type | Any | Output annotation to match. |
input_types | list[Any] | Input annotations in positional order. |
claimed | list[bool] | Flags for already matched input positions. |
Returns:
int | None — int | None: Matching input index, or None.
qkernel_callable_attrs [source]¶
def qkernel_callable_attrs(kernel: Any) -> dict[str, Any]Return compiler attrs for a qkernel invocation.
Composite metadata lives directly on QKernel. This helper is the
single translation point from that frontend state into serializer-safe IR
attributes, so direct, controlled, and inverse calls share one identity.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object carrying callable metadata. |
Returns:
dict[str, Any] — dict[str, Any]: Serializer-friendly callable attributes.
qkernel_callable_def [source]¶
def qkernel_callable_def(kernel: Any, block: Block) -> CallableDefBuild the inline-by-default callable definition for a qkernel block.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object carrying callable metadata. |
block | Block | Implementation body for the qkernel. |
Returns:
CallableDef — Compiler-facing definition for the qkernel.
qkernel_callable_ref [source]¶
def qkernel_callable_ref(kernel: Any) -> CallableRefReturn the compiler-facing callable reference for a qkernel.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object carrying callable metadata. |
Returns:
CallableRef — Stable reference used by InvokeOperation call sites.
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¶
CallPolicy [source]¶
class CallPolicy(enum.Enum)Describe the default lowering policy for a callable call.
Attributes¶
INLINENATIVE_FIRSTPRESERVE_BOX
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.
FrontendTransformError [source]¶
class FrontendTransformError(QamomileCompileError)Error during frontend AST-to-builder lowering.
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.
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.frontend.qkernel_specialization¶
Call-time specialization extraction for qkernel calls.
Overview¶
| Function | Description |
|---|---|
build_specialized_block | Trace a specialized sub-block for a call site. |
extract_calltime_specialization | Extract specialization inputs for a qkernel call site. |
get_array_element_type | Extract the element type from an array type annotation. |
get_size | Return the size of a Vector handle as a Python integer. |
is_array_type | Check if type is a Vector, Matrix, or Tensor subclass. |
is_dict_type | Check if type is a Dict handle type. |
is_parameterizable_type | Return whether an annotation can stay as a runtime parameter. |
is_static_binding_annotation | Return whether an annotation denotes a registered static binding. |
is_tuple_type | Check if type is a Tuple handle type. |
select_specialized_block | Select the block implementation for a qkernel call site. |
validate_static_binding_argument | Validate a concrete binding or caller-owned symbolic binding proxy. |
| Class | Description |
|---|---|
Bit | |
Block | Unified block representation for all pipeline stages. |
Float | Floating-point handle with arithmetic operations. |
UInt | Unsigned integer handle with arithmetic operations. |
Vector | 1-dimensional array type. |
Functions¶
build_specialized_block [source]¶
def build_specialized_block(
kernel: Any,
*,
parameters: list[str],
bindings: dict[str, Any],
qubit_sizes: dict[str, int],
) -> BlockTrace a specialized sub-block for a call site.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object to trace. |
parameters | list[str] | Classical argument names that remain symbolic in the specialized block. |
bindings | dict[str, Any] | Concrete Python values for classical arguments and caller-owned proxies for unresolved static bindings. |
qubit_sizes | dict[str, int] | First-axis sizes for Vector[Qubit] arguments supplied by the caller. |
Returns:
Block — Specialized hierarchical block ready to be invoked from the
Block — caller’s trace.
extract_calltime_specialization [source]¶
def extract_calltime_specialization(
kernel: Any,
arguments: dict[str, Any],
) -> tuple[list[str], dict[str, Any], dict[str, int]] | NoneExtract specialization inputs for a qkernel call site.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object with signature and input_types attributes. |
arguments | dict[str, Any] | Bound call arguments after literal promotion and frontend validation. Registered static bindings remain concrete Python objects. |
Returns:
tuple[list[str], dict[str, Any], dict[str, int]] | None — tuple[list[str], dict[str, Any], dict[str, int]] | None: Runtime
tuple[list[str], dict[str, Any], dict[str, int]] | None — parameter names, compile-time bindings, and concrete qubit-array
tuple[list[str], dict[str, Any], dict[str, int]] | None — sizes when specialization would change the callee trace; otherwise
tuple[list[str], dict[str, Any], dict[str, int]] | None — None.
get_array_element_type [source]¶
def get_array_element_type(param_type: Any) -> type | NoneExtract the element type from an array type annotation.
Parameters:
| Name | Type | Description |
|---|---|---|
param_type | Any | Frontend annotation such as Vector[Qubit]. |
Returns:
type | None — type | None: Element type when present, otherwise None.
get_size [source]¶
def get_size(arr: Vector[_H]) -> intReturn the size of a Vector handle as a Python integer.
Resolves the leading axis of arr.shape through two forms a
Vector shape entry can take:
A plain Python
int(built-in bound shape; this is what you get fromqmc.qubit_array(N, ...)for literalN).A
UInthandle whose underlyingValuecarries a compile-time constant (set byuint(literal),_create_bound_input, or partial evaluation).
A UInt handle whose underlying Value is not a constant is
treated as an unresolved symbolic dimension and raises
ValueError even when the handle has the dataclass-default
init_value=0. Falling back to init_value for that case
would silently turn a runtime-symbolic Vector[Float] parameter
into a “size 0” array, hiding programming errors. Callers that
need to handle symbolic shapes (e.g., to emit a deferred callable
when the size is unknown) must catch the ValueError themselves.
Parameters:
| Name | Type | Description |
|---|---|---|
arr | Vector[Handle] | Vector handle whose first axis size is requested. |
Returns:
int — The first-axis size as a plain Python int.
Raises:
TypeError— If arr is not a 1-DVectorhandle (Vectoror itsVectorViewsubclass) — e.g., a scalarQubitwas passed where aVectoris required, a higher-rankMatrix/Tensorwas passed (this helper only resolves a 1-D first-axis size), or an unrelatedshape-bearing object such as a numpy array. This is a clearer signal than the bareAttributeErrorthatarr.shapewould otherwise raise, and it guards the stdlib / composite callers that resolve a register size through this helper.ValueError— If the shape cannot be resolved to a concrete integer — e.g., the Vector is a runtime-parametric handle without compile-time bindings, or carries aUIntdimension whose underlyingValuehas not been promoted to a constant.
is_array_type [source]¶
def is_array_type(t: Any) -> boolCheck if type is a Vector, Matrix, or Tensor subclass.
is_dict_type [source]¶
def is_dict_type(t: Any) -> boolCheck if type is a Dict handle type.
is_parameterizable_type [source]¶
def is_parameterizable_type(param_type: Any) -> boolReturn whether an annotation can stay as a runtime parameter.
Parameters:
| Name | Type | Description |
|---|---|---|
param_type | Any | Frontend type annotation to inspect. |
Returns:
bool — True when the type can be represented by backend runtime
bool — parameters.
is_static_binding_annotation [source]¶
def is_static_binding_annotation(annotation: Any) -> boolReturn whether an annotation denotes a registered static binding.
Parameters:
| Name | Type | Description |
|---|---|---|
annotation | Any | Resolved qkernel parameter annotation. |
Returns:
bool — Whether the annotation is registered.
is_tuple_type [source]¶
def is_tuple_type(t: Any) -> boolCheck if type is a Tuple handle type.
select_specialized_block [source]¶
def select_specialized_block(
kernel: Any,
arguments: dict[str, Any],
*,
require_handles: bool = True,
) -> BlockSelect the block implementation for a qkernel call site.
Centralizes call-site specialization so plain qkernel calls, controlled
calls, and inverse calls use the same rule. When concrete argument values
would change the callee trace (for example a concrete Vector[Qubit]
size or a bound structural classical value), the function returns a
temporary specialized block. Otherwise it returns the kernel’s cached
block.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object whose block should be selected. |
arguments | dict[str, Any] | Bound call arguments after literal promotion and frontend validation. Registered static bindings may remain concrete Python objects when require_handles is false. |
require_handles | bool | If True, specialization is skipped unless every argument is a frontend Handle. Defaults to True. |
Returns:
Block — Specialized call-site block or the cached kernel block.
validate_static_binding_argument [source]¶
def validate_static_binding_argument(annotation: Any, name: str, value: Any) -> AnyValidate a concrete binding or caller-owned symbolic binding proxy.
Parameters:
| Name | Type | Description |
|---|---|---|
annotation | Any | Registered qkernel parameter annotation. |
name | str | Callee parameter name used as the binding-slot identity. |
value | Any | Concrete registered object or symbolic binding proxy. |
Returns:
Any — The validated concrete object or unchanged symbolic proxy.
Raises:
TypeError— If a concrete object has the wrong type, or a symbolic proxy does not preserve the callee parameter’s slot name and type key.
Classes¶
Bit [source]¶
class Bit(Handle)Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: bool = False,
) -> NoneAttributes¶
init_value: bool
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.
Float [source]¶
class Float(ArithmeticMixin, Handle)Floating-point handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: float = 0.0,
) -> NoneAttributes¶
init_value: float
UInt [source]¶
class UInt(ArithmeticMixin, Handle)Unsigned integer handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: int = 0,
) -> NoneAttributes¶
init_value: int
Vector [source]¶
class Vector(ArrayBase[T])1-dimensional array type.
Example:
import qamomile.circuit as qmc
# Create a vector of 3 qubits
qubits: qmc.Vector[qmc.Qubit] = qmc.qubit_array(3, name="qubits")
# Access elements
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0
# Apply H gate to all qubits (CORRECT)
n = qubits.shape[0]
for i in qmc.range(n):
qubits[i] = qmc.h(qubits[i])
# Slicing returns a VectorView over a subset of the parent vector.
# The view shares borrow tracking with the parent; element access
# on the view transparently indexes the parent.
evens = qubits[0::2]
for i in qmc.range(evens.shape[0]):
evens[i] = qmc.h(evens[i])Constructor¶
def __init__(
self,
value: ArrayValue = None,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_shape: tuple[int | UInt] = (0,),
_borrowed_indices: dict[tuple[str, ...], 'tuple[UInt, ...] | Handle'] = dict(),
) -> NoneAttributes¶
value: ArrayValue
qamomile.circuit.frontend.qkernel_utils¶
Shared helpers for qkernel invocation and tracing.
Overview¶
| Function | Description |
|---|---|
array_extents_equal | Return whether two well-formed array extents are statically equal. |
array_resource_identity | Return the canonical logical identity of an array resource. |
array_resources_equal | Return whether arrays denote the same whole logical resource. |
array_static_length | Resolve a one-dimensional array’s compile-time length. |
bit | Create a Bit handle from a boolean/int literal or declare a named Bit parameter. |
const_int | Return a compile-time integer constant from an IR value. |
float_ | Create a Float handle from a float literal or declare a named Float parameter. |
get_array_element_type | Extract the element type from an array type annotation. |
handle_types_equal | Compare two handle type annotations. |
is_array_type | Check if type is a Vector, Matrix, or Tensor subclass. |
is_full_reslice_of_input | Check whether an output is only full-sliced from a formal input. |
is_valid_array_extent | Return whether a value is a well-formed array extent. |
match_output_to_input | Return the first unclaimed input whose handle type matches output. |
promote_literal_to_handle | Promote a Python literal to a scalar handle for qkernel calls. |
quantum_handle_display_name | Return a human-readable name for a quantum handle. |
quantum_param_names | Return parameter names whose frontend type is quantum. |
reject_aliased_quantum_args | Reject overlapping live quantum resources at one call boundary. |
reject_consumed_view_arg | Reject an already-consumed vector view passed to a qkernel call. |
resolve_root_array_index | Fold a view-local element index into the root array’s index space. |
uint | Create a UInt handle from an integer literal or a named parameter. |
view_result_value_for_full_reslice | Build the caller-side array value for a full re-sliced view output. |
| Class | Description |
|---|---|
ArrayValue | An array of typed IR values. |
Bit | |
Float | Floating-point handle with arithmetic operations. |
QubitConsumedError | Qubit handle used after being consumed by a previous operation. |
UInt | Unsigned integer handle with arithmetic operations. |
UIntType | Type representing an unsigned integer. |
Value | A typed SSA value in the IR. |
Vector | 1-dimensional array type. |
Functions¶
array_extents_equal [source]¶
def array_extents_equal(left: Value, right: Value) -> boolReturn whether two well-formed array extents are statically equal.
Parameters:
| Name | Type | Description |
|---|---|---|
left | Value | First scalar UInt extent. |
right | Value | Second scalar UInt extent. |
Returns:
bool — True for one SSA extent or equal non-negative constants.
array_resource_identity [source]¶
def array_resource_identity(value: ArrayValue) -> str | NoneReturn the canonical logical identity of an array resource.
Parameters:
| Name | Type | Description |
|---|---|---|
value | ArrayValue | Array whose exact full-slice prefix is ignored. |
Returns:
str | None — str | None: Terminal logical identity, or None for a cyclic chain.
array_resources_equal [source]¶
def array_resources_equal(left: ArrayValue, right: ArrayValue) -> boolReturn whether arrays denote the same whole logical resource.
Exact full re-slices are transparent, while partial or strided views are
distinct resources. This lets control-flow merges preserve identity for a
direct value and value[:] as well as for two sibling full re-slices.
Parameters:
| Name | Type | Description |
|---|---|---|
left | ArrayValue | First array resource. |
right | ArrayValue | Second array resource. |
Returns:
bool — True when both arrays reach one compatible logical resource.
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.
bit [source]¶
def bit(arg: bool | str | int) -> BitCreate a Bit handle from a boolean/int literal or declare a named Bit parameter.
const_int [source]¶
def const_int(value: Value | None) -> int | NoneReturn a compile-time integer constant from an IR value.
Parameters:
| Name | Type | Description |
|---|---|---|
value | Value | None | IR value that may carry a constant. |
Returns:
int | None — int | None: Plain integer constant, or None when unavailable.
float_ [source]¶
def float_(arg: float | str) -> FloatCreate a Float handle from a float literal or declare a named Float parameter.
get_array_element_type [source]¶
def get_array_element_type(param_type: Any) -> type | NoneExtract the element type from an array type annotation.
Parameters:
| Name | Type | Description |
|---|---|---|
param_type | Any | Frontend annotation such as Vector[Qubit]. |
Returns:
type | None — type | None: Element type when present, otherwise None.
handle_types_equal [source]¶
def handle_types_equal(left: Any, right: Any) -> boolCompare two handle type annotations.
Parameters:
| Name | Type | Description |
|---|---|---|
left | Any | First annotation. |
right | Any | Second annotation. |
Returns:
bool — True when origins and generic arguments match.
is_array_type [source]¶
def is_array_type(t: Any) -> boolCheck if type is a Vector, Matrix, or Tensor subclass.
is_full_reslice_of_input [source]¶
def is_full_reslice_of_input(output: ArrayValue, formal_input: ArrayValue) -> boolCheck whether an output is only full-sliced from a formal input.
Parameters:
| Name | Type | Description |
|---|---|---|
output | ArrayValue | Callee output array value. |
formal_input | ArrayValue | Callee formal input array value. |
Returns:
bool — True when every slice from output back to
bool — formal_input is 0:len:1 with equal concrete lengths or the
bool — same symbolic length identity.
is_valid_array_extent [source]¶
def is_valid_array_extent(value: Value | None) -> boolReturn whether a value is a well-formed array extent.
Parameters:
| Name | Type | Description |
|---|---|---|
value | Value | None | Candidate scalar extent value. |
Returns:
bool — True for a scalar UInt whose constant payload, when
bool — present, is a non-negative plain integer.
match_output_to_input [source]¶
def match_output_to_input(output_type: Any, input_types: list[Any], claimed: list[bool]) -> int | NoneReturn the first unclaimed input whose handle type matches output.
Parameters:
| Name | Type | Description |
|---|---|---|
output_type | Any | Output annotation to match. |
input_types | list[Any] | Input annotations in positional order. |
claimed | list[bool] | Flags for already matched input positions. |
Returns:
int | None — int | None: Matching input index, or None.
promote_literal_to_handle [source]¶
def promote_literal_to_handle(value: Any, expected_type: Any) -> AnyPromote a Python literal to a scalar handle for qkernel calls.
Parameters:
| Name | Type | Description |
|---|---|---|
value | Any | Argument value supplied at a qkernel call site. |
expected_type | Any | Callee annotation used to decide whether a scalar literal can be wrapped as UInt, Float, or Bit. |
Returns:
Any — A freshly-created scalar handle when a promotion rule applies,
Any — otherwise value unchanged.
quantum_handle_display_name [source]¶
def quantum_handle_display_name(handle: Handle) -> strReturn a human-readable name for a quantum handle.
Parameters:
| Name | Type | Description |
|---|---|---|
handle | Handle | Handle to name. |
Returns:
str — Non-empty display name for diagnostics.
quantum_param_names [source]¶
def quantum_param_names(input_types: dict[str, Any]) -> set[str]Return parameter names whose frontend type is quantum.
Parameters:
| Name | Type | Description |
|---|---|---|
input_types | dict[str, Any] | Resolved annotations or raw deferred fallbacks keyed by parameter name. |
Returns:
set[str] — set[str]: Names annotated as Qubit or an array of Qubit.
reject_aliased_quantum_args [source]¶
def reject_aliased_quantum_args(
kernel_name: str,
arguments: dict[str, Any],
*,
caller: str | None = None,
) -> NoneReject overlapping live quantum resources at one call boundary.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel_name | str | Name of the called qkernel for diagnostics. |
arguments | dict[str, Any] | Bound call arguments keyed by parameter name. |
caller | str | None | Optional operation label replacing the default QKernel[kernel_name] context. Defaults to None. |
Raises:
QubitConsumedError— If two quantum arguments may cover the same physical qubit.
reject_consumed_view_arg [source]¶
def reject_consumed_view_arg(kernel_name: str, handle: Handle) -> NoneReject an already-consumed vector view passed to a qkernel call.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel_name | str | Name of the called qkernel for diagnostics. |
handle | Handle | View argument to check. |
Raises:
QubitConsumedError— Ifhandlewas already consumed.
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).
uint [source]¶
def uint(arg: int | str) -> UIntCreate a UInt handle from an integer literal or a named parameter.
Parameters:
| Name | Type | Description |
|---|---|---|
arg | int | str | An integer literal to bake in as a compile-time constant, or a str naming a symbolic UInt parameter. A bool is rejected: True / False are not valid integer values here even though bool subclasses int. (Sign is not validated here -- a negative literal is accepted and baked in as-is.) |
Returns:
UInt — A constant-valued handle for an int argument, or a named
symbolic handle for a str argument.
Raises:
TypeError— Ifargis neither a plainintnor astr(in particular, if it is abool).
view_result_value_for_full_reslice [source]¶
def view_result_value_for_full_reslice(result_value: ArrayValue, input_view: Vector[Any]) -> ArrayValueBuild the caller-side array value for a full re-sliced view output.
Parameters:
| Name | Type | Description |
|---|---|---|
result_value | ArrayValue | Caller-local output materialized from the callee result. |
input_view | Vector[Any] | Caller-side view argument being preserved. |
Returns:
ArrayValue — Fresh SSA version preserving caller-side slice metadata.
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]Bit [source]¶
class Bit(Handle)Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: bool = False,
) -> NoneAttributes¶
init_value: bool
Float [source]¶
class Float(ArithmeticMixin, Handle)Floating-point handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: float = 0.0,
) -> NoneAttributes¶
init_value: float
QubitConsumedError [source]¶
class QubitConsumedError(AffineTypeError)Qubit handle used after being consumed by a previous operation.
Each qubit handle can only be used once. After a gate operation, you must reassign the result to use the new handle.
Example of incorrect code:
q1 = qm.h(q) q2 = qm.x(q) # ERROR: q was already consumed by h()
Correct code:
q = qm.h(q) # Reassign to capture new handle q = qm.x(q) # Use the reassigned handle
UInt [source]¶
class UInt(ArithmeticMixin, Handle)Unsigned integer handle with arithmetic operations.
Constructor¶
def __init__(
self,
value: Value,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
init_value: int = 0,
) -> NoneAttributes¶
init_value: int
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.
Vector [source]¶
class Vector(ArrayBase[T])1-dimensional array type.
Example:
import qamomile.circuit as qmc
# Create a vector of 3 qubits
qubits: qmc.Vector[qmc.Qubit] = qmc.qubit_array(3, name="qubits")
# Access elements
q0 = qubits[0]
q0 = qmc.h(q0)
qubits[0] = q0
# Apply H gate to all qubits (CORRECT)
n = qubits.shape[0]
for i in qmc.range(n):
qubits[i] = qmc.h(qubits[i])
# Slicing returns a VectorView over a subset of the parent vector.
# The view shares borrow tracking with the parent; element access
# on the view transparently indexes the parent.
evens = qubits[0::2]
for i in qmc.range(evens.shape[0]):
evens[i] = qmc.h(evens[i])Constructor¶
def __init__(
self,
value: ArrayValue = None,
parent: 'ArrayBase | None' = None,
indices: tuple['UInt', ...] = (),
name: str | None = None,
id: str = (lambda: str(uuid.uuid4()))(),
_consumed: bool = False,
_consumed_by: str | None = None,
_consumed_at: '_FrameRef | None' = None,
_consumed_pre_branch: bool = False,
_shape: tuple[int | UInt] = (0,),
_borrowed_indices: dict[tuple[str, ...], 'tuple[UInt, ...] | Handle'] = dict(),
) -> NoneAttributes¶
value: ArrayValue
qamomile.circuit.frontend.qkernel_visualization¶
Visualization helpers for QKernel objects.
Overview¶
| Function | Description |
|---|---|
auto_detect_parameters | Detect unbound classical arguments that should be runtime parameters. |
build_graph_for_visualization | Build a traced block suitable for visualization. |
build_graph_with_qubit_arrays | Build a traced block with concrete Vector[Qubit] sizes. |
create_traced_block | Trace a kernel and return a Block. |
draw_qkernel | Visualize a qkernel using the Matplotlib drawer. |
extract_return_names | Extract display names from the kernel’s return statement. |
get_array_element_type | Extract the element type from an array type annotation. |
has_qubit_array_params | Return whether a kernel declares quantum-array parameters. |
is_array_type | Check if type is a Vector, Matrix, or Tensor subclass. |
validate_parameters | Validate the explicit runtime parameter list. |
| Class | Description |
|---|---|
Block | Unified block representation for all pipeline stages. |
Functions¶
auto_detect_parameters [source]¶
def auto_detect_parameters(
signature: inspect.Signature,
input_types: dict[str, type],
kwargs: dict[str, Any],
) -> list[str]Detect unbound classical arguments that should be runtime parameters.
Parameters:
| Name | Type | Description |
|---|---|---|
signature | inspect.Signature | Python signature of the qkernel. |
input_types | dict[str, type] | Resolved frontend annotations keyed by parameter name. |
kwargs | dict[str, Any] | Compile-time bindings supplied to QKernel.build. |
Returns:
list[str] — list[str]: Parameter names that should remain symbolic.
build_graph_for_visualization [source]¶
def build_graph_for_visualization(kernel: Any, **kwargs: Any = {}) -> BlockBuild a traced block suitable for visualization.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object to trace. |
**kwargs | Any | Concrete values for kernel arguments. For Vector[Qubit] parameters, pass an integer size. |
Returns:
Block — Traced block with output names populated.
build_graph_with_qubit_arrays [source]¶
def build_graph_with_qubit_arrays(kernel: Any, kwargs: dict[str, Any]) -> BlockBuild a traced block with concrete Vector[Qubit] sizes.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object to trace. |
kwargs | dict[str, Any] | Concrete values for kernel arguments. Integer values for Vector[Qubit] parameters are interpreted as register sizes. |
Returns:
Block — Traced block with quantum-array parameters realized as
Block — concrete 1-D registers.
Raises:
NotImplementedError— If the kernel declares a rank greater than one quantum array parameter.ValueError— If a quantum-array parameter is missing its integer size.
create_traced_block [source]¶
def create_traced_block(
kernel: Any,
parameters: list[str],
kwargs: dict[str, Any],
qubit_sizes: dict[str, int] | None = None,
*,
emit_qubit_init: bool = True,
emit_return_op: bool = False,
) -> BlockTrace a kernel and return a Block.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object to trace. |
parameters | list[str] | Argument names to keep as unbound parameters. |
kwargs | dict[str, Any] | Concrete values for non-parameter arguments and caller-owned proxies for unresolved static bindings. |
qubit_sizes | dict[str, int] | None | Optional mapping from Vector[Qubit] parameter names to integer sizes. Defaults to None. |
emit_qubit_init | bool | Whether quantum-array size entries should emit QInitOperation. Defaults to True. |
emit_return_op | bool | Whether to append an explicit ReturnOperation for inline-call specialization. Defaults to False. |
Returns:
Block — Traced block with label arguments, inputs, outputs, and
Block — parameter slots populated.
Raises:
TypeError— If a static binding declares a default, a concrete static binding has the wrong registered type, or a symbolic static binding does not preserve the parameter’s slot identity.ValueError— If a required static binding is absent fromkwargs.
draw_qkernel [source]¶
def draw_qkernel(
kernel: Any,
*,
inline: bool = False,
fold_loops: bool = True,
expand_composite: bool = False,
inline_depth: int | None = None,
fold_ifs: bool = False,
**kwargs: Any = {},
) -> AnyVisualize a qkernel using the Matplotlib drawer.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object to draw. |
inline | bool | Whether inline callable contents should be expanded. Defaults to False. |
fold_loops | bool | Whether loops should be shown as folded blocks. Defaults to True. |
expand_composite | bool | Whether boxed composite calls should be expanded. Defaults to False. |
inline_depth | int | None | Maximum nesting depth for inline expansion. Defaults to None. |
fold_ifs | bool | Whether if/else branches should be folded. Defaults to False. |
**kwargs | Any | Concrete values for kernel arguments. |
Returns:
Any — Matplotlib figure object.
Raises:
ImportError— If matplotlib is not installed.ValueError— If visualization requires a missing concrete register size.
extract_return_names [source]¶
def extract_return_names(kernel: 'QKernel[Any, Any]') -> list[str] | NoneExtract display names from the kernel’s return statement.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernel[Any, Any] | Kernel whose raw Python source should be inspected. |
Returns:
list[str] | None — list[str] | None: Return expression labels when a top-level return can
list[str] | None — be parsed, otherwise None.
get_array_element_type [source]¶
def get_array_element_type(param_type: Any) -> type | NoneExtract the element type from an array type annotation.
Parameters:
| Name | Type | Description |
|---|---|---|
param_type | Any | Frontend annotation such as Vector[Qubit]. |
Returns:
type | None — type | None: Element type when present, otherwise None.
has_qubit_array_params [source]¶
def has_qubit_array_params(kernel: Any) -> boolReturn whether a kernel declares quantum-array parameters.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | Any | QKernel-like object with signature and input_types attributes. |
Returns:
bool — True when any parameter is a Vector[Qubit]-style
bool — quantum array.
is_array_type [source]¶
def is_array_type(t: Any) -> boolCheck if type is a Vector, Matrix, or Tensor subclass.
validate_parameters [source]¶
def validate_parameters(input_types: dict[str, type], parameters: list[str]) -> NoneValidate the explicit runtime parameter list.
Parameters:
| Name | Type | Description |
|---|---|---|
input_types | dict[str, type] | Resolved qkernel input annotations. |
parameters | list[str] | Requested runtime parameter names. |
Raises:
ValueError— If a requested name is not a qkernel parameter.TypeError— If a requested parameter type cannot stay symbolic.
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.
qamomile.circuit.frontend.region_analysis¶
Static control-flow signatures for explicit qkernel region lowering.
Overview¶
| Function | Description |
|---|---|
analyze_function_regions | Analyze a Python function’s explicit region interfaces. |
analyze_region_signatures | Analyze structured interfaces in one parsed function definition. |
| Class | Description |
|---|---|
RegionLocation | Identify one source-level structured control-flow region. |
RegionSignature | Describe values crossing one structured region boundary. |
Functions¶
analyze_function_regions [source]¶
def analyze_function_regions(function: Callable[..., Any]) -> dict[RegionLocation, RegionSignature]Analyze a Python function’s explicit region interfaces.
Parameters:
| Name | Type | Description |
|---|---|---|
function | Callable[..., Any] | Raw undecorated qkernel function whose source is available through :mod:inspect. |
Returns:
dict[RegionLocation, RegionSignature] — dict[RegionLocation, RegionSignature]: Source locations mapped to
deterministic region signatures.
Raises:
OSError— If Python source cannot be retrieved.SyntaxError— If source cannot be parsed or the definition is absent.
analyze_region_signatures [source]¶
def analyze_region_signatures(
definition: ast.FunctionDef | ast.AsyncFunctionDef,
) -> dict[RegionLocation, RegionSignature]Analyze structured interfaces in one parsed function definition.
Parameters:
| Name | Type | Description |
|---|---|---|
definition | ast.FunctionDef | ast.AsyncFunctionDef | Parsed function body to analyze. |
Returns:
dict[RegionLocation, RegionSignature] — dict[RegionLocation, RegionSignature]: Source region signatures.
Classes¶
RegionLocation [source]¶
class RegionLocationIdentify one source-level structured control-flow region.
Parameters:
| Name | Type | Description |
|---|---|---|
kind | str | Region kind: for, while, or if. |
lineno | int | One-based source line in the original source file. |
col_offset | int | Zero-based source column. |
Constructor¶
def __init__(self, kind: str, lineno: int, col_offset: int) -> NoneAttributes¶
col_offset: intkind: strlineno: int
RegionSignature [source]¶
class RegionSignatureDescribe values crossing one structured region boundary.
Parameters:
| Name | Type | Description |
|---|---|---|
inputs | tuple[str, ...] | Explicit values passed to the region. |
carried | tuple[str, ...] | Values updated across a loop back edge or merged across branches. |
captures | tuple[str, ...] | Read-only region inputs. |
results | tuple[str, ...] | Updated values live after the region. |
Constructor¶
def __init__(
self,
inputs: tuple[str, ...],
carried: tuple[str, ...],
captures: tuple[str, ...],
results: tuple[str, ...],
) -> NoneAttributes¶
captures: tuple[str, ...]carried: tuple[str, ...]inputs: tuple[str, ...]results: tuple[str, ...]
qamomile.circuit.frontend.static_binding¶
Register and trace compile-time object bindings for qkernels.
Overview¶
| Function | Description |
|---|---|
create_static_binding_proxy | Create an unbound tracing proxy for a registered annotation. |
get_static_binding_by_annotation | Return the adapter registered for a qkernel annotation. |
get_static_binding_by_type_key | Return the adapter registered under a stable serialization key. |
is_static_binding_annotation | Return whether an annotation denotes a registered static binding. |
materialize_static_field | Extract and validate one registered scalar field. |
materialize_static_member | Extract one registered qkernel-like member. |
register_static_binding | Register one closed compile-time object adapter. |
signature_from_values | Build a callable signature from concrete operand and result values. |
validate_static_binding | Validate one concrete compile-time object binding. |
validate_static_binding_argument | Validate a concrete binding or caller-owned symbolic binding proxy. |
validate_static_binding_slot | Validate a serialized IR slot against its installed adapter. |
without_static_bindings | Remove compile-time object bindings already consumed by qkernel build. |
| 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. |
CallPolicy | Describe the default lowering policy for a callable call. |
CallableBodyRef | Reference a callable body that can be materialized later. |
CallableDef | Describe a compiler-facing callable definition. |
CallableRef | Identify a callable independently of its Python object. |
InvokeOperation | Represent a composite, stdlib, or oracle call. |
ReturnOperation | Explicit return operation marking the end of a block with return values. |
StaticBindingField | Reference one scalar field projected from a static binding. |
StaticBindingFieldSpec | Describe one scalar field exposed by a static-binding proxy. |
StaticBindingMemberSpec | Describe one deferred qkernel-valued member of a static binding. |
StaticBindingProxy | Expose a registered static object surface during unbound tracing. |
StaticBindingSlot | Declare one typed compile-time object required by a qkernel. |
StaticBindingSpec | Register the closed qkernel surface of one compile-time object type. |
Value | A typed SSA value in the IR. |
ValueMetadata | Typed metadata owned by the compiler/runtime. |
Constants¶
ValueLike:TypeAlias='Value | ArrayValue | TupleValue | DictValue'
Functions¶
create_static_binding_proxy [source]¶
def create_static_binding_proxy(annotation: Any, name: str) -> StaticBindingProxyCreate an unbound tracing proxy for a registered annotation.
Parameters:
| Name | Type | Description |
|---|---|---|
annotation | Any | Registered qkernel parameter annotation. |
name | str | QKernel parameter name identifying the slot. |
Returns:
StaticBindingProxy — Closed symbolic adapter surface.
Raises:
TypeError— Ifannotationis not registered.
get_static_binding_by_annotation [source]¶
def get_static_binding_by_annotation(annotation: Any) -> StaticBindingSpec | NoneReturn the adapter registered for a qkernel annotation.
Parameters:
| Name | Type | Description |
|---|---|---|
annotation | Any | Resolved qkernel parameter annotation. |
Returns:
StaticBindingSpec | None — StaticBindingSpec | None: Registered adapter, or None for an
StaticBindingSpec | None — ordinary qkernel argument.
get_static_binding_by_type_key [source]¶
def get_static_binding_by_type_key(type_key: str) -> StaticBindingSpecReturn the adapter registered under a stable serialization key.
Parameters:
| Name | Type | Description |
|---|---|---|
type_key | str | Stable type key from serialized IR. |
Returns:
StaticBindingSpec — Matching registered adapter.
Raises:
KeyError— If the installed Qamomile distribution does not know the key.
is_static_binding_annotation [source]¶
def is_static_binding_annotation(annotation: Any) -> boolReturn whether an annotation denotes a registered static binding.
Parameters:
| Name | Type | Description |
|---|---|---|
annotation | Any | Resolved qkernel parameter annotation. |
Returns:
bool — Whether the annotation is registered.
materialize_static_field [source]¶
def materialize_static_field(spec: StaticBindingSpec, binding: Any, field_name: str) -> int | floatExtract and validate one registered scalar field.
Parameters:
| Name | Type | Description |
|---|---|---|
spec | StaticBindingSpec | Registered object contract. |
binding | Any | Validated concrete object. |
field_name | str | Registered field name. |
Returns:
int | float — int | float: Scalar value suitable for IR constant metadata.
Raises:
KeyError— Iffield_nameis not registered.TypeError— If the extracted value does not match its handle type.ValueError— If aUIntfield is negative.
materialize_static_member [source]¶
def materialize_static_member(
spec: StaticBindingSpec,
binding: Any,
member_name: str,
) -> tuple[Any, StaticBindingMemberSpec]Extract one registered qkernel-like member.
Parameters:
| Name | Type | Description |
|---|---|---|
spec | StaticBindingSpec | Registered object contract. |
binding | Any | Validated concrete object. |
member_name | str | Registered member name. |
Returns:
Any — tuple[Any, StaticBindingMemberSpec]: Concrete member and its adapter
StaticBindingMemberSpec — contract.
Raises:
KeyError— Ifmember_nameis not registered.TypeError— If the getter does not return a qkernel-like object.
register_static_binding [source]¶
def register_static_binding(spec: StaticBindingSpec) -> NoneRegister one closed compile-time object adapter.
Parameters:
| Name | Type | Description |
|---|---|---|
spec | StaticBindingSpec | Adapter contract to register. |
Raises:
TypeError— If the annotation or type key has the wrong type, or if a field getter, field handle, or deferred member ABI is unsupported.ValueError— If the annotation or stable type key is already registered, or if the contract is empty or malformed.
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.
validate_static_binding [source]¶
def validate_static_binding(annotation: Any, name: str, value: Any) -> AnyValidate one concrete compile-time object binding.
Parameters:
| Name | Type | Description |
|---|---|---|
annotation | Any | Registered qkernel parameter annotation. |
name | str | Parameter name used in diagnostics. |
value | Any | Candidate binding value. |
Returns:
Any — The validated binding value.
Raises:
TypeError— If the annotation is not registered or the value has the wrong concrete type.
validate_static_binding_argument [source]¶
def validate_static_binding_argument(annotation: Any, name: str, value: Any) -> AnyValidate a concrete binding or caller-owned symbolic binding proxy.
Parameters:
| Name | Type | Description |
|---|---|---|
annotation | Any | Registered qkernel parameter annotation. |
name | str | Callee parameter name used as the binding-slot identity. |
value | Any | Concrete registered object or symbolic binding proxy. |
Returns:
Any — The validated concrete object or unchanged symbolic proxy.
Raises:
TypeError— If a concrete object has the wrong type, or a symbolic proxy does not preserve the callee parameter’s slot name and type key.
validate_static_binding_slot [source]¶
def validate_static_binding_slot(spec: StaticBindingSpec, slot: StaticBindingSlot) -> NoneValidate a serialized IR slot against its installed adapter.
Parameters:
| Name | Type | Description |
|---|---|---|
spec | StaticBindingSpec | Installed adapter contract. |
slot | StaticBindingSlot | IR manifest entry to validate. |
Raises:
ValueError— If the type key, projected field names, or field types do not exactly match the registered adapter.
without_static_bindings [source]¶
def without_static_bindings(
input_types: Mapping[str, Any],
bindings: Mapping[str, Any] | None,
) -> dict[str, Any]Remove compile-time object bindings already consumed by qkernel build.
Parameters:
| Name | Type | Description |
|---|---|---|
input_types | Mapping[str, Any] | QKernel input annotations by name. |
bindings | Mapping[str, Any] | None | User-provided compile-time values. |
Returns:
dict[str, Any] — dict[str, Any]: Ordinary scalar, array, and structural bindings only.
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
CallPolicy [source]¶
class CallPolicy(enum.Enum)Describe the default lowering policy for a callable call.
Attributes¶
INLINENATIVE_FIRSTPRESERVE_BOX
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.
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
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.
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.
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
StaticBindingFieldSpec [source]¶
class StaticBindingFieldSpecDescribe one scalar field exposed by a static-binding proxy.
Parameters:
| Name | Type | Description |
|---|---|---|
handle_type | type[Handle] | Frontend scalar handle returned while tracing an unbound qkernel. |
getter | Callable[[Any], int | float] | Extractor used when a concrete object is bound. |
Constructor¶
def __init__(self, handle_type: type[Handle], getter: Callable[[Any], int | float]) -> NoneAttributes¶
getter: Callable[[Any], int | float]handle_type: type[Handle]
StaticBindingMemberSpec [source]¶
class StaticBindingMemberSpecDescribe one deferred qkernel-valued member of a static binding.
Parameters:
| Name | Type | Description |
|---|---|---|
input_types | Mapping[str, Any] | Ordered frontend input annotations. |
output_types | tuple[Any, ...] | Ordered frontend result annotations. |
return_annotation | Any | Complete Python return annotation. |
getter | Callable[[Any], Any] | Extractor returning the concrete qkernel-like member. |
qubit_width_fields | Mapping[str, str] | Input-name to scalar field-name mapping used to specialize quantum vector widths. |
Constructor¶
def __init__(
self,
input_types: Mapping[str, Any],
output_types: tuple[Any, ...],
return_annotation: Any,
getter: Callable[[Any], Any],
qubit_width_fields: Mapping[str, str] = dict(),
) -> NoneAttributes¶
getter: Callable[[Any], Any]input_types: Mapping[str, Any]output_types: tuple[Any, ...]qubit_width_fields: Mapping[str, str]return_annotation: Any
StaticBindingProxy [source]¶
class StaticBindingProxyExpose a registered static object surface during unbound tracing.
Parameters:
| Name | Type | Description |
|---|---|---|
spec | StaticBindingSpec | Registered object contract. |
name | str | QKernel parameter name identifying the binding slot. |
Constructor¶
def __init__(self, spec: StaticBindingSpec, name: str) -> NoneCreate symbolic fields and deferred callable members.
Parameters:
| Name | Type | Description |
|---|---|---|
spec | StaticBindingSpec | Registered object contract. |
name | str | QKernel parameter name identifying the binding slot. |
Attributes¶
slot: StaticBindingSlot Return the IR manifest entry owned by this proxy.
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
StaticBindingSpec [source]¶
class StaticBindingSpecRegister the closed qkernel surface of one compile-time object type.
Parameters:
| Name | Type | Description |
|---|---|---|
annotation | type[Any] | Public qkernel parameter annotation. |
type_key | str | Stable serialization key. |
fields | Mapping[str, StaticBindingFieldSpec] | Scalar projections available while tracing. |
members | Mapping[str, StaticBindingMemberSpec] | Deferred callable members available while tracing. |
Constructor¶
def __init__(
self,
annotation: type[Any],
type_key: str,
fields: Mapping[str, StaticBindingFieldSpec],
members: Mapping[str, StaticBindingMemberSpec],
) -> NoneAttributes¶
annotation: type[Any]fields: Mapping[str, StaticBindingFieldSpec]members: Mapping[str, StaticBindingMemberSpec]type_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.
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.frontend.struct¶
Define lightweight named records for qkernel trace-time state.
Overview¶
| Function | Description |
|---|---|
struct | Decorate a class as an immutable trace-time record. |
Functions¶
struct [source]¶
def struct(cls) -> type[_T]Decorate a class as an immutable trace-time record.
Structs group related frontend handles without introducing a new IR value or changing a qkernel’s backend ABI. They are ordinary Python objects that exist only while the frontend traces a kernel body. The record is shallowly frozen so a field cannot be rebound in place; quantum operations must build a successor record from the handles they return. Affine ownership remains attached to the contained quantum handles, just as it does for handles in a Python tuple. Copying a struct therefore does not clone or transfer a qubit. Equality remains based on object identity because comparing symbolic handle fields is not a valid trace-time operation.
Parameters:
| Name | Type | Description |
|---|---|---|
cls | type[_T] | Annotated class whose fields define the record. |
Returns:
type[_T] — type[_T]: Frozen dataclass-compatible class with generated
initialization and representation.
Raises:
TypeError— Ifclscannot be converted to a frozen dataclass, such as when it defines incompatible dataclass options.
Example:
>>> import qamomile.circuit as qmc
>>> @qmc.struct
... class Registers:
... control: qmc.Qubit
... target: qmc.Qubitqamomile.circuit.frontend.tracer¶
Overview¶
| Function | Description |
|---|---|
get_current_tracer | |
trace | Context manager to set the current tracer. |
| Class | Description |
|---|---|
LoopCarriedRebind | Trace-time record of a variable rebound inside a loop body. |
Operation | |
Tracer | Collects operations (and loop-rebind records) during tracing. |
Functions¶
get_current_tracer [source]¶
def get_current_tracer() -> Tracertrace [source]¶
def trace(tracer: Tracer | None = None) -> Generator[Tracer, None, None]Context manager to set the current tracer.
Classes¶
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.
Tracer [source]¶
class TracerCollects operations (and loop-rebind records) during tracing.
Constructor¶
def __init__(
self,
_operations: list[Operation] = list(),
loop_carried_rebinds: tuple[LoopCarriedRebind, ...] = (),
region_entries: dict[str, Any] = dict(),
loop_region_results: dict[str, Any] = dict(),
) -> NoneAttributes¶
loop_carried_rebinds: tuple[LoopCarriedRebind, ...]loop_region_results: dict[str, Any]operations: list[Operation]region_entries: dict[str, Any]
Methods¶
add_operation¶
def add_operation(self, op) -> None