Quantum Phase Estimation implementation.
Example:
@qmc.qkernel
def p_gate(q: qmc.Qubit, theta: float) -> qmc.Qubit:
return qmc.p(q, theta)
@qmc.qkernel
def circuit(theta: float) -> qmc.Float:
counting = qmc.qubit_array(3, name="counting")
target = qmc.qubit(name="target")
target = qmc.x(target)
phase = qmc.qpe(target, counting, p_gate, theta=theta)
return qmc.measure(phase)Overview¶
| Function | Description |
|---|---|
for_loop | Builder function to create a for loop in Qamomile frontend. |
get_current_tracer | |
qpe | Quantum Phase Estimation. |
| Class | Description |
|---|---|
CastOperation | Type cast operation for creating aliases over the same quantum resources. |
CompositeGateOperation | Represents a composite gate (QPE, QFT, etc.) as a single operation. |
CompositeGateType | Registry of known composite gate types. |
QKernel | Decorator class for Qamomile quantum kernels. |
ResourceMetadata | Resource estimation metadata for composite gates. |
Value | A typed value in the IR with SSA-style versioning. |
Functions¶
for_loop [source]¶
def for_loop(
start,
stop,
step = 1,
var_name: str = '_loop_idx',
) -> Generator[UInt, None, None]Builder function to create a for loop in Qamomile frontend.
Parameters:
| Name | Type | Description |
|---|---|---|
start | `` | Loop start value (can be Handle or int) |
stop | `` | Loop stop value (can be Handle or int) |
step | `` | Loop step value (default=1) |
var_name | str | Name of the loop variable (default=“_loop_idx”) |
Yields:
UInt — The loop iteration variable (can be used as array index)
Example:
@QKernel
def my_kernel(qubits: Array[Qubit, Literal[3]]) -> Array[Qubit, Literal[3]]:
for i in qm.range(3):
qubits[i] = h(qubits[i])
return qubits
@QKernel
def my_kernel2(qubits: Array[Qubit, Literal[5]]) -> Array[Qubit, Literal[5]]:
for i in qm.range(1, 4): # i = 1, 2, 3
qubits[i] = h(qubits[i])
return qubitsget_current_tracer [source]¶
def get_current_tracer() -> Tracerqpe [source]¶
def qpe(
target: Qubit,
counting: Vector[Qubit],
unitary: QKernel,
**params: Any = {},
) -> QFixedQuantum Phase Estimation.
Estimates the phase φ where U|ψ> = e^{2πiφ}|ψ>.
Parameters:
| Name | Type | Description |
|---|---|---|
target | Qubit | The eigenstate |ψ> of the unitary U |
counting | Vector[Qubit] | Vector of qubits for phase estimation result |
unitary | QKernel | The unitary operation U as a QKernel |
**params | Any | Parameters to pass to the unitary |
Returns:
QFixed — Phase register as quantum fixed-point number
Classes¶
CastOperation [source]¶
class CastOperation(Operation)Type cast operation for creating aliases over the same quantum resources.
This operation does NOT allocate new qubits. It creates a new Value that references the same underlying quantum resources with a different type.
Use cases:
Vector[Qubit] -> QFixed (after QPE, for phase measurement)
Vector[Qubit] -> QUInt (for quantum arithmetic)
QUInt -> QFixed (reinterpret bits with different encoding)
QFixed -> QUInt (reinterpret bits with different encoding)
operands: [source_value] - The value being cast results: [cast_result] - The new value with target type (same physical qubits)
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
source_type: ValueType | None = None,
target_type: ValueType | None = None,
qubit_mapping: list[str] = list(),
) -> NoneAttributes¶
num_qubits: int Number of qubits involved in the cast.operation_kind: OperationKind Cast stays in the same segment as its source (QUANTUM for quantum types).qubit_mapping: list[str]signature: Signature Return the type signature of this cast operation.source_type: ValueType | Nonetarget_type: ValueType | None
CompositeGateOperation [source]¶
class CompositeGateOperation(Operation)Represents a composite gate (QPE, QFT, etc.) as a single operation.
CompositeGate allows representing complex multi-gate operations as a single atomic operation in the IR. This enables:
Resource estimation without full implementation
Backend-native conversion (e.g., Qiskit’s QPE)
User-defined complex gates
The operands structure depends on has_implementation:
If has_implementation=True:
operands[0]: BlockValue (the implementation)
operands[1:1+num_control_qubits]: Control qubits (if any)
operands[1+num_control_qubits:1+num_control_qubits+num_target_qubits]: Target qubits
operands[1+num_control_qubits+num_target_qubits:]: Parameters
If has_implementation=False (stub):
operands[0:num_control_qubits]: Control qubits (if any)
operands[num_control_qubits:num_control_qubits+num_target_qubits]: Target qubits
operands[num_control_qubits+num_target_qubits:]: Parameters
The results structure:
results[0:num_control_qubits]: Control qubits (returned)
results[num_control_qubits:]: Target qubits (returned)
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
gate_type: CompositeGateType = CompositeGateType.CUSTOM,
num_control_qubits: int = 0,
num_target_qubits: int = 0,
custom_name: str = '',
resource_metadata: ResourceMetadata | None = None,
has_implementation: bool = True,
composite_gate_instance: Any = None,
strategy_name: str | None = None,
) -> NoneAttributes¶
composite_gate_instance: Anycontrol_qubits: list[‘Value’] Get the control qubit operands.custom_name: strgate_type: CompositeGateTypehas_implementation: boolimplementation: ‘BlockValue | None’ Get the implementation BlockValue, if any.name: str Human-readable name of this composite gate.num_control_qubits: intnum_target_qubits: intoperation_kind: OperationKind Return the operation kind (always QUANTUM).parameters: list[‘Value’] Get the parameter operands (angles, etc.).resource_metadata: ResourceMetadata | Nonesignature: Signature Return the operation signature.strategy_name: str | Nonetarget_qubits: list[‘Value’] Get the target qubit operands.
CompositeGateType [source]¶
class CompositeGateType(enum.Enum)Registry of known composite gate types.
Attributes¶
CUSTOMIQFTQFTQPE
QKernel [source]¶
class QKernel(Generic[P, R])Decorator class for Qamomile quantum kernels.
Constructor¶
def __init__(self, func: Callable[P, R]) -> NoneAttributes¶
block: BlockValue Compiles the function to a BlockValue (IR) if not already compiled.funcinput_typesnameoutput_typesraw_funcsignature
Methods¶
build¶
def build(self, parameters: list[str] | None = None, **kwargs: Any = {}) -> GraphBuild the computation graph by tracing this kernel.
Parameters:
| Name | Type | Description |
|---|---|---|
parameters | list[str] | None | List of argument names to keep as unbound parameters. - None (default): Auto-detect parameters (non-Qubit args without value/default) - []: No parameters (all non-Qubit args must have value/default) - [“name”]: Explicit parameter list Only float, int, UInt, and their arrays are allowed as parameters. |
**kwargs | Any | Concrete values for non-parameter arguments. |
Returns:
Graph — The traced computation graph ready for transpilation.
Raises:
TypeError— If a non-parameterizable type is specified as parameter.ValueError— If required arguments are missing.
Example:
@qm.qkernel
def circuit(q: Qubit, theta: float) -> Qubit:
q = qm.rx(q, theta)
return q
# Auto-detect theta as parameter
graph = circuit.build()
# Explicit parameter list
graph = circuit.build(parameters=["theta"])
# theta bound to concrete value
graph = circuit.build(theta=0.5)
# Transpile with binding
transpiler = QiskitTranspiler()
result = transpiler.emit(graph, binding={"theta": 0.5})draw¶
def draw(
self,
inline: bool = False,
fold_loops: bool = True,
expand_composite: bool = False,
inline_depth: int | None = None,
**kwargs: Any = {},
) -> AnyVisualize the circuit using Matplotlib.
This method builds the computation graph and creates a static visualization. Parameters are auto-detected: non-Qubit arguments without concrete values are shown as symbolic parameters.
Parameters:
| Name | Type | Description |
|---|---|---|
inline | bool | If True, expand CallBlockOperation contents (inlining). If False (default), show CallBlockOperation as boxes. |
fold_loops | bool | If True (default), display ForOperation as blocks instead of unrolling. If False, expand loops and show all iterations. |
expand_composite | bool | If True, expand CompositeGateOperation (QFT, IQFT, etc.). If False (default), show as boxes. Independent of inline. |
inline_depth | int | None | Maximum nesting depth for inline expansion. None means unlimited (default). 0 means no inlining, 1 means top-level only, etc. Only affects CallBlock/ControlledU, not CompositeGate. |
**kwargs | Any | Concrete values for arguments. Arguments not provided here (and without defaults) will be shown as symbolic parameters. |
Returns:
Any — matplotlib.figure.Figure object.
Raises:
ImportError— If matplotlib is not installed.
Example:
import qamomile.circuit as qm
@qm.qkernel
def inner(q: qm.Qubit) -> qm.Qubit:
return qm.x(q)
@qm.qkernel
def circuit(q: qm.Qubit, theta: float) -> qm.Qubit:
q = inner(q)
q = qm.h(q)
q = qm.rx(q, theta)
return q
# Draw with auto-detected symbolic parameter (theta)
fig = circuit.draw()
# Draw with bound parameter
fig = circuit.draw(theta=0.5)
# Draw with blocks as boxes (default)
fig = circuit.draw()
# Draw with blocks expanded (inlined)
fig = circuit.draw(inline=True)
# Draw with loops folded (shown as blocks)
fig = circuit.draw(fold_loops=True)
# Draw with composite gates expanded
fig = circuit.draw(expand_composite=True)estimate_resources¶
def estimate_resources(self, *, bindings: dict[str, Any] | None = None) -> ResourceEstimateEstimate all resources for this kernel’s circuit.
Convenience method that delegates to the module-level
estimate_resources function, eliminating the need to
access .block directly.
Parameters:
| Name | Type | Description |
|---|---|---|
bindings | dict[str, Any] | None | Optional concrete parameter bindings (scalars and dicts). Dict values trigger |key| cardinality substitution. |
Returns:
ResourceEstimate — ResourceEstimate with qubits, gates, and parameters.
Example:
>>> @qm.qkernel
... def bell() -> qm.Vector[qm.Qubit]:
... q = qm.qubit_array(2)
... q[0] = qm.h(q[0])
... q[0], q[1] = qm.cx(q[0], q[1])
... return q
>>> est = bell.estimate_resources()
>>> print(est.qubits) # 2ResourceMetadata [source]¶
class ResourceMetadataResource estimation metadata for composite gates.
Gate count fields mirror GateCount categories.
None semantics:
Fields left as None mean “unknown/unspecified”. During extraction, gate_counter treats None as 0, which may undercount resources if the true value is nonzero. To ensure accurate resource estimates, set all relevant fields explicitly.
When total_gates is set but some of single_qubit_gates, two_qubit_gates, or multi_qubit_gates are None, the extractor emits a UserWarning if the known sub-total is less than total_gates, indicating potentially missing gate category data.
Constructor¶
def __init__(
self,
query_complexity: int | None = None,
t_gates: int | None = None,
ancilla_qubits: int = 0,
total_gates: int | None = None,
single_qubit_gates: int | None = None,
two_qubit_gates: int | None = None,
multi_qubit_gates: int | None = None,
clifford_gates: int | None = None,
rotation_gates: int | None = None,
custom_metadata: dict[str, Any] = dict(),
) -> NoneAttributes¶
ancilla_qubits: intclifford_gates: int | Nonecustom_metadata: dict[str, Any]multi_qubit_gates: int | Nonequery_complexity: int | Nonerotation_gates: int | Nonesingle_qubit_gates: int | Nonet_gates: int | Nonetotal_gates: int | Nonetwo_qubit_gates: int | None
Value [source]¶
class Value(Generic[T])A typed value in the IR with SSA-style versioning.
Value represents a single typed value (qubit, float, int, bit, etc.) with support for:
SSA versioning via uuid/logical_id
Parameter binding
Constant folding
Array element tracking
Constructor¶
def __init__(
self,
type: T,
name: str,
version: int = 0,
params: dict[str, Any] = dict(),
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: strname: strparams: dict[str, Any]parent_array: ArrayValue | Nonetype: Tuuid: strversion: int
Methods¶
get_cast_qubit_logical_ids¶
def get_cast_qubit_logical_ids(self) -> list[str] | NoneGet the underlying qubit logical_ids for this cast value.
get_cast_qubit_uuids¶
def get_cast_qubit_uuids(self) -> list[str] | NoneGet the underlying qubit UUIDs for this cast value.
get_cast_source_logical_id¶
def get_cast_source_logical_id(self) -> str | NoneGet the source value logical_id if this is a cast result.
get_cast_source_uuid¶
def get_cast_source_uuid(self) -> str | NoneGet the source value UUID if this is a cast result.
get_const¶
def get_const(self) -> int | float | NoneGet constant value if available, otherwise None.
get_lowered_bits¶
def get_lowered_bits(self) -> list[Value] | NoneGet lowered bit list if available, otherwise None.
get_lowered_qubits¶
def get_lowered_qubits(self) -> list[Value] | NoneGet lowered qubit list if available, otherwise None.
is_array_element¶
def is_array_element(self) -> boolCheck if this value is an element of an array.
is_cast_result¶
def is_cast_result(self) -> boolCheck if this value is the result of a CastOperation.
is_constant¶
def is_constant(self) -> boolCheck if this value is a constant.
is_parameter¶
def is_parameter(self) -> boolCheck if this value is an unbound parameter.
next_version¶
def next_version(self) -> Value[T]Create a new Value with incremented version (SSA style).
parameter_name¶
def parameter_name(self) -> str | NoneGet the parameter name if this is a parameter, otherwise None.
set_cast_metadata¶
def set_cast_metadata(
self,
source_uuid: str,
qubit_uuids: list[str],
source_logical_id: str | None = None,
qubit_logical_ids: list[str] | None = None,
) -> NoneSet cast metadata for this value.
set_lowered_bits¶
def set_lowered_bits(self, bits: list[Value]) -> NoneSet lowered bit list.
set_lowered_qubits¶
def set_lowered_qubits(self, qubits: list[Value]) -> NoneSet lowered qubit list.