qamomile.circuit.transpiler.capabilities¶
Backend capability definitions for transpiler optimization.
Overview¶
| Class | Description |
|---|---|
BackendCapability | Capabilities that a backend may support natively. |
CapableBackend | Protocol for backends that declare their capabilities. |
Classes¶
BackendCapability [source]¶
class BackendCapability(enum.Flag)Capabilities that a backend may support natively.
Use these flags to indicate which composite gates and features a backend supports, allowing the transpiler to use native implementations when available.
Attributes¶
BASIC_COMPOSITECLASSICAL_FEEDFORWARDDYNAMIC_CIRCUITSFOR_LOOPFULL_COMPOSITEFULL_CONTROL_FLOWNATIVE_IQFTNATIVE_QFTNATIVE_QPENONEWHILE_LOOP
CapableBackend [source]¶
class CapableBackend(Protocol)Protocol for backends that declare their capabilities.
Implement this protocol in backend-specific EmitPass classes to enable capability-based optimizations.
Attributes¶
capabilities: BackendCapability Return the capabilities this backend supports.
Methods¶
has_capability¶
def has_capability(self, cap: BackendCapability) -> boolCheck if this backend has a specific capability.
Parameters:
| Name | Type | Description |
|---|---|---|
cap | BackendCapability | The capability to check for. |
Returns:
bool — True if the backend has the capability, False otherwise.
qamomile.circuit.transpiler.classical_executor¶
Classical segment executor for Python-based classical operations.
Overview¶
| Class | Description |
|---|---|
BinOp | Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, POW). |
BinOpKind | |
ClassicalExecutor | Executes classical segments in Python. |
ClassicalSegment | A segment of pure classical operations. |
CompOp | Comparison operation (EQ, NEQ, LT, LE, GT, GE). |
CompOpKind | |
CondOp | Conditional logical operation (AND, OR). |
CondOpKind | |
DecodeQFixedOperation | Decode measured bits to float (classical operation). |
ExecutionContext | Holds global state during program execution. |
ExecutionError | Error during program execution. |
NotOp | |
Value | A typed value in the IR with SSA-style versioning. |
Classes¶
BinOp [source]¶
class BinOp(BinaryOperationBase)Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, POW).
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
kind: BinOpKind | None = None,
) -> NoneAttributes¶
kind: BinOpKind | Noneoperation_kind: OperationKindsignature: Signature
BinOpKind [source]¶
class BinOpKind(enum.Enum)Attributes¶
ADDDIVFLOORDIVMULPOWSUB
ClassicalExecutor [source]¶
class ClassicalExecutorExecutes classical segments in Python.
Methods¶
execute¶
def execute(self, segment: ClassicalSegment, context: ExecutionContext) -> dict[str, Any]Execute classical operations and return outputs.
Interprets the operations list directly using Python.
ClassicalSegment [source]¶
class ClassicalSegment(Segment)A segment of pure classical operations.
Contains arithmetic, comparisons, and control flow. Will be executed directly in Python.
Constructor¶
def __init__(
self,
operations: list[Operation] = list(),
input_refs: list[str] = list(),
output_refs: list[str] = list(),
) -> NoneAttributes¶
kind: SegmentKind
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
DecodeQFixedOperation [source]¶
class DecodeQFixedOperation(Operation)Decode measured bits to float (classical operation).
This operation converts a sequence of classical bits from qubit measurements into a floating-point number using fixed-point encoding.
The decoding formula:
float_value = Σ bit[i] * 2^(int_bits - 1 - i)
For QPE phase (int_bits=0): float_value = 0.b0b1b2... = b00.5 + b10.25 + b2*0.125 + ...
Example:
bits = [1, 0, 1] with int_bits=0
→ 0.101 (binary) = 0.5 + 0.125 = 0.625operands: [ArrayValue of bits (vec[bit])] results: [Float value]
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_bits: int = 0,
int_bits: int = 0,
) -> NoneAttributes¶
int_bits: intnum_bits: intoperation_kind: OperationKindsignature: Signature
ExecutionContext [source]¶
class ExecutionContextHolds global state during program execution.
Constructor¶
def __init__(self, initial_bindings: dict[str, Any] | None = None)Methods¶
get¶
def get(self, key: str) -> Anyget_many¶
def get_many(self, keys: list[str]) -> dict[str, Any]has¶
def has(self, key: str) -> boolset¶
def set(self, key: str, value: Any) -> Noneupdate¶
def update(self, values: dict[str, Any]) -> NoneExecutionError [source]¶
class ExecutionError(QamomileCompileError)Error during program execution.
NotOp [source]¶
class NotOp(Operation)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
input: Valueoperation_kind: OperationKindoutput: Valuesignature: Signature
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.
qamomile.circuit.transpiler.compile_check¶
Overview¶
| Function | Description |
|---|---|
is_block_compilable | Check if a BlockValue is compilable. |
| Class | Description |
|---|---|
BlockValue | Represents a subroutine as a function block. |
Functions¶
is_block_compilable [source]¶
def is_block_compilable(block: BlockValue) -> boolCheck if a BlockValue is compilable.
A BlockValue is considered compilable if all its operations are compilable. This function checks each operation in the block’s operations list.
Parameters:
| Name | Type | Description |
|---|---|---|
block | BlockValue | The BlockValue to check. |
Returns: bool: True if the block is compilable, False otherwise.
Classes¶
BlockValue [source]¶
class BlockValue(Value[BlockType])Represents a subroutine as a function block.
def func_block(a: UInt, b: UInt) -> tuple[UInt]: ...
BlockValue( name=“func_block”, inputs_type={“a”: UIntType(), “b”: UIntType()}, outputs_type=(UIntType(), ), operations=[...], )
Function to BlockValue conversion can be done via func_to_block function.
Each Values in operations are dummy values.
The execution of the BlockValue is corresponding to the BlockOperation.
Constructor¶
def __init__(
self,
type: BlockType = BlockType(),
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, ...] = (),
label_args: list[str] = list(),
input_values: list[Value] = list(),
return_values: list[Value] = list(),
operations: list[Operation] = list(),
) -> NoneAttributes¶
input_values: list[Value]label_args: list[str]name: stroperations: list[Operation]return_values: list[Value]type: BlockType
Methods¶
call¶
def call(self, **kwargs: Value = {}) -> 'CallBlockOperation'Create a CallBlockOperation to call this BlockValue.
Example:
block_value = BlockValue(
name="func_block",
inputs_type={"a": UIntType(), "b": UIntType()},
outputs_type=(UIntType(), ),
operations=[...],
)
a = Value(UIntType())
b = Value(UIntType())
call_op = block_value.call(a=a, b=b)qamomile.circuit.transpiler.compiled_segments¶
Compiled segment structures for transpiled quantum circuits.
Overview¶
| Class | Description |
|---|---|
ClassicalSegment | A segment of pure classical operations. |
CompiledClassicalSegment | A classical segment ready for Python execution. |
CompiledExpvalSegment | A compiled expectation value segment with concrete Hamiltonian. |
CompiledQuantumSegment | A quantum segment with emitted backend circuit. |
ExpvalSegment | A segment for expectation value computation. |
ParameterMetadata | Metadata for all parameters in a compiled segment. |
QuantumSegment | A segment of pure quantum operations. |
Classes¶
ClassicalSegment [source]¶
class ClassicalSegment(Segment)A segment of pure classical operations.
Contains arithmetic, comparisons, and control flow. Will be executed directly in Python.
Constructor¶
def __init__(
self,
operations: list[Operation] = list(),
input_refs: list[str] = list(),
output_refs: list[str] = list(),
) -> NoneAttributes¶
kind: SegmentKind
CompiledClassicalSegment [source]¶
class CompiledClassicalSegmentA classical segment ready for Python execution.
Constructor¶
def __init__(self, segment: ClassicalSegment) -> NoneAttributes¶
segment: ClassicalSegment
CompiledExpvalSegment [source]¶
class CompiledExpvalSegmentA compiled expectation value segment with concrete Hamiltonian.
This segment computes <psi|H|psi> where psi is the quantum state from a quantum circuit and H is a qamomile.observable.Hamiltonian.
Constructor¶
def __init__(
self,
segment: ExpvalSegment,
hamiltonian: 'qm_o.Hamiltonian',
quantum_segment_index: int = 0,
result_ref: str = '',
qubit_map: dict[int, int] = dict(),
) -> NoneAttributes¶
hamiltonian: ‘qm_o.Hamiltonian’quantum_segment_index: intqubit_map: dict[int, int]result_ref: strsegment: ExpvalSegment
CompiledQuantumSegment [source]¶
class CompiledQuantumSegment(Generic[T])A quantum segment with emitted backend circuit.
Constructor¶
def __init__(
self,
segment: QuantumSegment,
circuit: T,
qubit_map: dict[str, int] = dict(),
clbit_map: dict[str, int] = dict(),
measurement_qubit_map: dict[int, int] = dict(),
parameter_metadata: ParameterMetadata = ParameterMetadata(),
) -> NoneAttributes¶
circuit: Tclbit_map: dict[str, int]measurement_qubit_map: dict[int, int]parameter_metadata: ParameterMetadataqubit_map: dict[str, int]segment: QuantumSegment
ExpvalSegment [source]¶
class ExpvalSegment(Segment)A segment for expectation value computation.
Represents computing <psi|H|psi> where psi is the quantum state and H is a Hamiltonian observable.
This segment bridges a quantum circuit (state preparation) to a classical expectation value.
Constructor¶
def __init__(
self,
operations: list[Operation] = list(),
input_refs: list[str] = list(),
output_refs: list[str] = list(),
hamiltonian_value: Value | None = None,
qubits_value: Value | None = None,
result_ref: str = '',
) -> NoneAttributes¶
hamiltonian_value: Value | Nonekind: SegmentKindqubits_value: Value | Noneresult_ref: str
ParameterMetadata [source]¶
class ParameterMetadataMetadata for all parameters in a compiled segment.
Tracks parameter information for runtime binding.
Constructor¶
def __init__(self, parameters: list[ParameterInfo] = list()) -> NoneAttributes¶
parameters: list[ParameterInfo]
Methods¶
get_array_names¶
def get_array_names(self) -> set[str]Get unique array/scalar parameter names.
get_ordered_params¶
def get_ordered_params(self) -> list[Any]Get backend parameter objects in definition order.
Useful for backends that require positional parameter binding (e.g., QURI Parts).
Returns:
list[Any] — List of backend_param objects in the order they were defined.
Example:
# For QURI Parts that uses positional binding:
param_values = [bindings[p.name] for p in metadata.parameters]
bound_circuit = circuit.bind_parameters(param_values)get_param_by_name¶
def get_param_by_name(self, name: str) -> ParameterInfo | NoneGet parameter info by full name.
to_binding_dict¶
def to_binding_dict(self, bindings: dict[str, Any]) -> dict[Any, Any]Convert indexed bindings to backend parameter bindings.
Transforms user-provided bindings (with indexed names like “gammas[0]”) into a dictionary mapping backend parameter objects to values. Useful for backends that use dict-based parameter binding (e.g., Qiskit).
Parameters:
| Name | Type | Description |
|---|---|---|
bindings | dict[str, Any] | Dictionary mapping parameter names to values. e.g., {“gammas[0]”: 0.1, “gammas[1]”: 0.2, “theta”: 0.5} |
Returns:
dict[Any, Any] — Dictionary mapping backend_param objects to values.
Example:
# For Qiskit that uses dict-based binding:
qiskit_bindings = metadata.to_binding_dict(bindings)
bound_circuit = circuit.assign_parameters(qiskit_bindings)QuantumSegment [source]¶
class QuantumSegment(Segment)A segment of pure quantum operations.
Contains quantum gates and qubit allocations. Will be emitted to a quantum circuit.
Constructor¶
def __init__(
self,
operations: list[Operation] = list(),
input_refs: list[str] = list(),
output_refs: list[str] = list(),
qubit_values: list[Value] = list(),
num_qubits: int = 0,
) -> NoneAttributes¶
kind: SegmentKindnum_qubits: intqubit_values: list[Value]
qamomile.circuit.transpiler.emitter¶
qamomile.circuit.transpiler.emitter.emitter¶
Overview¶
| Class | Description |
|---|---|
BlockValue | Represents a subroutine as a function block. |
EmitResult | |
Emitter |
Classes¶
BlockValue [source]¶
class BlockValue(Value[BlockType])Represents a subroutine as a function block.
def func_block(a: UInt, b: UInt) -> tuple[UInt]: ...
BlockValue( name=“func_block”, inputs_type={“a”: UIntType(), “b”: UIntType()}, outputs_type=(UIntType(), ), operations=[...], )
Function to BlockValue conversion can be done via func_to_block function.
Each Values in operations are dummy values.
The execution of the BlockValue is corresponding to the BlockOperation.
Constructor¶
def __init__(
self,
type: BlockType = BlockType(),
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, ...] = (),
label_args: list[str] = list(),
input_values: list[Value] = list(),
return_values: list[Value] = list(),
operations: list[Operation] = list(),
) -> NoneAttributes¶
input_values: list[Value]label_args: list[str]name: stroperations: list[Operation]return_values: list[Value]type: BlockType
Methods¶
call¶
def call(self, **kwargs: Value = {}) -> 'CallBlockOperation'Create a CallBlockOperation to call this BlockValue.
Example:
block_value = BlockValue(
name="func_block",
inputs_type={"a": UIntType(), "b": UIntType()},
outputs_type=(UIntType(), ),
operations=[...],
)
a = Value(UIntType())
b = Value(UIntType())
call_op = block_value.call(a=a, b=b)EmitResult [source]¶
class EmitResult(abc.ABC, Generic[T])Attributes¶
circuit: T
Emitter [source]¶
class Emitter(abc.ABC, Generic[T])Constructor¶
def __init__(
self,
block: BlockValue,
bind: dict[str, int | float | list[int] | list[float]],
) -> NoneAttributes¶
bindblock
Methods¶
emit¶
def emit(self, block: BlockValue) -> EmitResult[T]qamomile.circuit.transpiler.errors¶
Compilation error classes for Qamomile transpiler.
Overview¶
| Class | Description |
|---|---|
AffineTypeError | Base class for affine type violations. |
DependencyError | Error when quantum operation depends on non-parameter classical value. |
EmitError | Error during backend code emission. |
ExecutionError | Error during program execution. |
InliningError | Error during inline pass (inlining CallBlockOperations). |
OperandResolutionInfo | Detailed information about a single operand that failed to resolve. |
QamomileCompileError | Base class for all Qamomile compilation errors. |
QubitAliasError | Same qubit used multiple times in one operation. |
QubitConsumedError | Qubit handle used after being consumed by a previous operation. |
QubitIndexResolutionError | Error when qubit indices cannot be resolved during emission. |
QubitRebindError | Quantum variable reassigned from a different quantum source. |
ResolutionFailureReason | Categorizes why qubit index resolution failed. |
SeparationError | Error during quantum/classical separation. |
UnreturnedBorrowError | Borrowed array element not returned before array use. |
ValidationError | Error during validation (e.g., non-classical I/O). |
Classes¶
AffineTypeError [source]¶
class AffineTypeError(QamomileCompileError)Base class for affine type violations.
Affine types enforce that quantum resources (qubits) are used at most once. This prevents common errors such as reusing a consumed qubit or aliasing.
Constructor¶
def __init__(
self,
message: str,
handle_name: str | None = None,
operation_name: str | None = None,
first_use_location: str | None = None,
)Attributes¶
first_use_locationhandle_nameoperation_name
DependencyError [source]¶
class DependencyError(QamomileCompileError)Error when quantum operation depends on non-parameter classical value.
This error indicates that the program requires JIT compilation which is not yet supported.
Constructor¶
def __init__(
self,
message: str,
quantum_op: str | None = None,
classical_value: str | None = None,
)Attributes¶
classical_valuequantum_op
EmitError [source]¶
class EmitError(QamomileCompileError)Error during backend code emission.
Constructor¶
def __init__(self, message: str, operation: str | None = None)Attributes¶
operation
ExecutionError [source]¶
class ExecutionError(QamomileCompileError)Error during program execution.
InliningError [source]¶
class InliningError(QamomileCompileError)Error during inline pass (inlining CallBlockOperations).
OperandResolutionInfo [source]¶
class OperandResolutionInfoDetailed information about a single operand that failed to resolve.
Constructor¶
def __init__(
self,
operand_name: str,
operand_uuid: str,
is_array_element: bool,
parent_array_name: str | None,
element_indices_names: list[str],
failure_reason: ResolutionFailureReason,
failure_details: str,
) -> NoneAttributes¶
element_indices_names: list[str]failure_details: strfailure_reason: ResolutionFailureReasonis_array_element: booloperand_name: stroperand_uuid: strparent_array_name: str | None
QamomileCompileError [source]¶
class QamomileCompileError(Exception)Base class for all Qamomile compilation errors.
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
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
QubitIndexResolutionError [source]¶
class QubitIndexResolutionError(EmitError)Error when qubit indices cannot be resolved during emission.
This error provides detailed diagnostic information about why qubit index resolution failed and suggests remediation steps.
Constructor¶
def __init__(
self,
gate_type: str,
operand_infos: list[OperandResolutionInfo],
available_bindings_keys: list[str],
available_qubit_map_keys: list[str],
)Attributes¶
available_bindings_keysavailable_qubit_map_keysgate_typeoperand_infos
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 silently discards the original quantum state.
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)
ResolutionFailureReason [source]¶
class ResolutionFailureReason(Enum)Categorizes why qubit index resolution failed.
Attributes¶
ARRAY_ELEMENT_NOT_IN_QUBIT_MAPDIRECT_UUID_NOT_FOUNDINDEX_NOT_NUMERICNESTED_ARRAY_RESOLUTION_FAILEDSYMBOLIC_INDEX_NOT_BOUNDUNKNOWN
SeparationError [source]¶
class SeparationError(QamomileCompileError)Error during quantum/classical separation.
UnreturnedBorrowError [source]¶
class UnreturnedBorrowError(AffineTypeError)Borrowed array element not returned before array use.
When you borrow an element from a qubit array, you must return it (write it back) before using other elements or the array itself.
Example of incorrect code:
q0 = qubits[0] q0 = qm.h(q0) q1 = qubits[1] # ERROR: q0 not returned yet
Correct code:
q0 = qubits[0] q0 = qm.h(q0) qubits[0] = q0 # Return the borrowed element q1 = qubits[1] # Now safe to borrow another
ValidationError [source]¶
class ValidationError(QamomileCompileError)Error during validation (e.g., non-classical I/O).
Constructor¶
def __init__(self, message: str, value_name: str | None = None)Attributes¶
value_name
qamomile.circuit.transpiler.executable¶
Executable program structure for compiled quantum-classical programs.
Overview¶
| Class | Description |
|---|---|
ClassicalExecutor | Executes classical segments in Python. |
CompiledClassicalSegment | A classical segment ready for Python execution. |
CompiledExpvalSegment | A compiled expectation value segment with concrete Hamiltonian. |
CompiledQuantumSegment | A quantum segment with emitted backend circuit. |
ExecutableProgram | A fully compiled program ready for execution. |
ExecutionContext | Holds global state during program execution. |
ExecutionError | Error during program execution. |
ExpvalJob | Job for expectation value computation. |
ParameterInfo | Information about a single unbound parameter in the circuit. |
ParameterMetadata | Metadata for all parameters in a compiled segment. |
QuantumExecutor | Abstract base class for quantum backend execution. |
RunJob | Job for single execution. |
SampleJob | Job for sampling execution (multiple shots). |
Classes¶
ClassicalExecutor [source]¶
class ClassicalExecutorExecutes classical segments in Python.
Methods¶
execute¶
def execute(self, segment: ClassicalSegment, context: ExecutionContext) -> dict[str, Any]Execute classical operations and return outputs.
Interprets the operations list directly using Python.
CompiledClassicalSegment [source]¶
class CompiledClassicalSegmentA classical segment ready for Python execution.
Constructor¶
def __init__(self, segment: ClassicalSegment) -> NoneAttributes¶
segment: ClassicalSegment
CompiledExpvalSegment [source]¶
class CompiledExpvalSegmentA compiled expectation value segment with concrete Hamiltonian.
This segment computes <psi|H|psi> where psi is the quantum state from a quantum circuit and H is a qamomile.observable.Hamiltonian.
Constructor¶
def __init__(
self,
segment: ExpvalSegment,
hamiltonian: 'qm_o.Hamiltonian',
quantum_segment_index: int = 0,
result_ref: str = '',
qubit_map: dict[int, int] = dict(),
) -> NoneAttributes¶
hamiltonian: ‘qm_o.Hamiltonian’quantum_segment_index: intqubit_map: dict[int, int]result_ref: strsegment: ExpvalSegment
CompiledQuantumSegment [source]¶
class CompiledQuantumSegment(Generic[T])A quantum segment with emitted backend circuit.
Constructor¶
def __init__(
self,
segment: QuantumSegment,
circuit: T,
qubit_map: dict[str, int] = dict(),
clbit_map: dict[str, int] = dict(),
measurement_qubit_map: dict[int, int] = dict(),
parameter_metadata: ParameterMetadata = ParameterMetadata(),
) -> NoneAttributes¶
circuit: Tclbit_map: dict[str, int]measurement_qubit_map: dict[int, int]parameter_metadata: ParameterMetadataqubit_map: dict[str, int]segment: QuantumSegment
ExecutableProgram [source]¶
class ExecutableProgram(Generic[T])A fully compiled program ready for execution.
This is the Orchestrator - manages execution of mixed classical/quantum programs.
Example:
executable = transpiler.compile(kernel)
# Sample: multiple shots, returns counts
job = executable.sample(executor, shots=1000)
result = job.result() # SampleResult with counts
# Run: single shot, returns typed result
job = executable.run(executor)
result = job.result() # Returns kernel's return typeConstructor¶
def __init__(
self,
compiled_quantum: list[CompiledQuantumSegment[T]] = list(),
compiled_classical: list[CompiledClassicalSegment] = list(),
compiled_expval: list[CompiledExpvalSegment] = list(),
execution_order: list[tuple[str, int]] = list(),
output_refs: list[str] = list(),
num_output_bits: int = 0,
) -> NoneAttributes¶
compiled_classical: list[CompiledClassicalSegment]compiled_expval: list[CompiledExpvalSegment]compiled_quantum: list[CompiledQuantumSegment[T]]execution_order: list[tuple[str, int]]has_parameters: bool Check if this program has unbound parameters.num_output_bits: intoutput_refs: list[str]parameter_names: list[str] Get list of parameter names that need binding.quantum_circuit: T Get the single quantum circuit.
Methods¶
get_circuits¶
def get_circuits(self) -> list[T]Get all quantum circuits in execution order.
get_first_circuit¶
def get_first_circuit(self) -> T | NoneGet the first quantum circuit, or None if no quantum segments.
run¶
def run(
self,
executor: QuantumExecutor[T],
bindings: dict[str, Any] | None = None,
) -> RunJob[Any] | ExpvalJobExecute once and return single result.
Parameters:
| Name | Type | Description |
|---|---|---|
executor | QuantumExecutor[T] | Backend-specific quantum executor. |
bindings | dict[str, Any] | None | Parameter bindings. Supports two formats: - Vector: {“gammas”: [0.1, 0.2], “betas”: [0.3, 0.4]} - Indexed: {“gammas[0]”: 0.1, “gammas[1]”: 0.2} |
Returns:
RunJob[Any] | ExpvalJob — RunJob that resolves to the kernel’s return type, or
RunJob[Any] | ExpvalJob — ExpvalJob if the program contains expectation value computation.
Raises:
ExecutionError— If no quantum circuit to executeValueError— If required parameters are missing
Example:
job = executable.run(executor, bindings={"gamma": [0.5]})
result = job.result()
print(result) # 0.25 (for QFixed) or (0, 1) (for bits)sample¶
def sample(
self,
executor: QuantumExecutor[T],
shots: int = 1024,
bindings: dict[str, Any] | None = None,
) -> SampleJob[Any]Execute with multiple shots and return counts.
Parameters:
| Name | Type | Description |
|---|---|---|
executor | QuantumExecutor[T] | Backend-specific quantum executor. |
shots | int | Number of shots to run. |
bindings | dict[str, Any] | None | Parameter bindings. Supports two formats: - Vector: {“gammas”: [0.1, 0.2], “betas”: [0.3, 0.4]} - Indexed: {“gammas[0]”: 0.1, “gammas[1]”: 0.2} |
Returns:
SampleJob[Any] — SampleJob that resolves to SampleResult with results.
Raises:
ExecutionError— If no quantum circuit to executeValueError— If required parameters are missing
Example:
job = executable.sample(executor, shots=1000, bindings={"gamma": [0.5]})
result = job.result()
print(result.results) # [(0.25, 500), (0.75, 500)]ExecutionContext [source]¶
class ExecutionContextHolds global state during program execution.
Constructor¶
def __init__(self, initial_bindings: dict[str, Any] | None = None)Methods¶
get¶
def get(self, key: str) -> Anyget_many¶
def get_many(self, keys: list[str]) -> dict[str, Any]has¶
def has(self, key: str) -> boolset¶
def set(self, key: str, value: Any) -> Noneupdate¶
def update(self, values: dict[str, Any]) -> NoneExecutionError [source]¶
class ExecutionError(QamomileCompileError)Error during program execution.
ExpvalJob [source]¶
class ExpvalJob(Job[float])Job for expectation value computation.
Returns a single float representing <psi|H|psi>.
Constructor¶
def __init__(self, exp_val: float)Initialize expval job.
Parameters:
| Name | Type | Description |
|---|---|---|
exp_val | float | The computed expectation value |
Methods¶
result¶
def result(self) -> floatReturn the expectation value.
status¶
def status(self) -> JobStatusReturn job status.
ParameterInfo [source]¶
class ParameterInfoInformation about a single unbound parameter in the circuit.
Constructor¶
def __init__(
self,
name: str,
array_name: str,
index: int | None,
backend_param: Any,
) -> NoneAttributes¶
array_name: strbackend_param: Anyindex: int | Nonename: str
ParameterMetadata [source]¶
class ParameterMetadataMetadata for all parameters in a compiled segment.
Tracks parameter information for runtime binding.
Constructor¶
def __init__(self, parameters: list[ParameterInfo] = list()) -> NoneAttributes¶
parameters: list[ParameterInfo]
Methods¶
get_array_names¶
def get_array_names(self) -> set[str]Get unique array/scalar parameter names.
get_ordered_params¶
def get_ordered_params(self) -> list[Any]Get backend parameter objects in definition order.
Useful for backends that require positional parameter binding (e.g., QURI Parts).
Returns:
list[Any] — List of backend_param objects in the order they were defined.
Example:
# For QURI Parts that uses positional binding:
param_values = [bindings[p.name] for p in metadata.parameters]
bound_circuit = circuit.bind_parameters(param_values)get_param_by_name¶
def get_param_by_name(self, name: str) -> ParameterInfo | NoneGet parameter info by full name.
to_binding_dict¶
def to_binding_dict(self, bindings: dict[str, Any]) -> dict[Any, Any]Convert indexed bindings to backend parameter bindings.
Transforms user-provided bindings (with indexed names like “gammas[0]”) into a dictionary mapping backend parameter objects to values. Useful for backends that use dict-based parameter binding (e.g., Qiskit).
Parameters:
| Name | Type | Description |
|---|---|---|
bindings | dict[str, Any] | Dictionary mapping parameter names to values. e.g., {“gammas[0]”: 0.1, “gammas[1]”: 0.2, “theta”: 0.5} |
Returns:
dict[Any, Any] — Dictionary mapping backend_param objects to values.
Example:
# For Qiskit that uses dict-based binding:
qiskit_bindings = metadata.to_binding_dict(bindings)
bound_circuit = circuit.assign_parameters(qiskit_bindings)QuantumExecutor [source]¶
class QuantumExecutor(ABC, Generic[T])Abstract base class for quantum backend execution.
To implement a custom executor:
execute() [Required] Execute circuit and return bitstring counts as dict[str, int]. Keys are bitstrings in big-endian format (e.g., “011” means q2=0, q1=1, q0=1).
bind_parameters() [Optional] Bind parameter values to parametric circuits. Override if your executor supports parametric circuits (e.g., QAOA variational circuits). Use ParameterMetadata.to_binding_dict() for easy conversion.
estimate() [Optional] Compute expectation values <psi|H|psi>. Override if your executor supports estimation primitives (e.g., Qiskit Estimator, QURI Parts).
Example (Minimal): class MyExecutor(QuantumExecutor[QuantumCircuit]): def init(self): from qiskit_aer import AerSimulator self.backend = AerSimulator()
def execute(self, circuit, shots):
from qiskit import transpile
if circuit.num_clbits == 0:
circuit = circuit.copy()
circuit.measure_all()
transpiled = transpile(circuit, self.backend)
return self.backend.run(transpiled, shots=shots).result().get_counts()Example (With Parameter Binding): def bind_parameters(self, circuit, bindings, metadata): # metadata.to_binding_dict() converts indexed names to backend params return circuit.assign_parameters(metadata.to_binding_dict(bindings))
Methods¶
bind_parameters¶
def bind_parameters(
self,
circuit: T,
bindings: dict[str, Any],
parameter_metadata: ParameterMetadata,
) -> TBind parameter values to the circuit.
Default implementation returns the circuit unchanged. Override for backends that support parametric circuits.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | T | The parameterized circuit |
bindings | dict[str, Any] | Dict mapping parameter names (indexed format) to values. e.g., {“gammas[0]”: 0.1, “gammas[1]”: 0.2} |
parameter_metadata | ParameterMetadata | Metadata about circuit parameters |
Returns:
T — New circuit with parameters bound
estimate¶
def estimate(
self,
circuit: T,
hamiltonian: 'qm_o.Hamiltonian',
params: Sequence[float] | None = None,
) -> floatEstimate the expectation value of a Hamiltonian.
This method computes <psi|H|psi> where psi is the quantum state prepared by the circuit and H is the Hamiltonian.
Backends can override this method to provide optimized implementations using their native estimator primitives.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | T | The quantum circuit (state preparation ansatz) |
hamiltonian | 'qm_o.Hamiltonian' | The qamomile.observable.Hamiltonian to measure |
params | Sequence[float] | None | Optional parameter values for parametric circuits |
Returns:
float — The estimated expectation value
Raises:
NotImplementedError— If the executor does not support estimation
execute¶
def execute(self, circuit: T, shots: int) -> dict[str, int]Execute the circuit and return bitstring counts.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | T | The quantum circuit to execute |
shots | int | Number of measurement shots |
Returns:
dict[str, int] — Dictionary mapping bitstrings to counts.
dict[str, int] — {“00”: 512, “11”: 512}
RunJob [source]¶
class RunJob(Job[T], Generic[T])Job for single execution.
Returns a single result value matching the kernel’s return type.
Constructor¶
def __init__(self, raw_counts: dict[str, int], result_converter: Callable[[str], T])Initialize run job.
Parameters:
| Name | Type | Description |
|---|---|---|
raw_counts | dict[str, int] | Bitstring counts from executor (should have single entry) |
result_converter | Callable[[str], T] | Function to convert bitstring to typed result |
Methods¶
result¶
def result(self) -> TReturn the single result.
status¶
def status(self) -> JobStatusReturn job status.
SampleJob [source]¶
class SampleJob(Job[SampleResult[T]], Generic[T])Job for sampling execution (multiple shots).
Returns a SampleResult containing counts for each unique result.
Constructor¶
def __init__(
self,
raw_counts: dict[str, int],
result_converter: Callable[[dict[str, int]], list[tuple[T, int]]],
shots: int,
)Initialize sample job.
Parameters:
| Name | Type | Description |
|---|---|---|
raw_counts | dict[str, int] | Bitstring counts from executor (e.g., {“00”: 512, “11”: 512}) |
result_converter | Callable[[dict[str, int]], list[tuple[T, int]]] | Function to convert raw counts to typed results |
shots | int | Number of shots executed |
Methods¶
result¶
def result(self) -> SampleResult[T]Return the sample result.
status¶
def status(self) -> JobStatusReturn job status.
qamomile.circuit.transpiler.execution_context¶
Execution context for quantum-classical program execution.
Overview¶
| Class | Description |
|---|---|
ExecutionContext | Holds global state during program execution. |
Classes¶
ExecutionContext [source]¶
class ExecutionContextHolds global state during program execution.
Constructor¶
def __init__(self, initial_bindings: dict[str, Any] | None = None)Methods¶
get¶
def get(self, key: str) -> Anyget_many¶
def get_many(self, keys: list[str]) -> dict[str, Any]has¶
def has(self, key: str) -> boolset¶
def set(self, key: str, value: Any) -> Noneupdate¶
def update(self, values: dict[str, Any]) -> Noneqamomile.circuit.transpiler.gate_emitter¶
GateEmitter protocol for backend-agnostic gate emission.
This module defines the GateEmitter protocol that backends implement to emit individual quantum gates. The StandardEmitPass uses this protocol to orchestrate circuit generation without backend-specific code.
Overview¶
| Class | Description |
|---|---|
GateEmitter | Protocol for backend-specific gate emission. |
GateKind | Classification of gates for emission. |
GateSpec | Specification for a gate type. |
Constants¶
GATE_SPECS:dict[GateKind, GateSpec]
Classes¶
GateEmitter [source]¶
class GateEmitter(Protocol[T])Protocol for backend-specific gate emission.
Each backend implements this protocol to emit individual gates to their circuit representation.
Type parameter T is the backend’s circuit type (e.g., QuantumCircuit).
Methods¶
append_gate¶
def append_gate(self, circuit: T, gate: Any, qubits: list[int]) -> NoneAppend a gate to the circuit.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | T | The circuit to append to |
gate | Any | The gate to append (from circuit_to_gate) |
qubits | list[int] | Target qubit indices |
circuit_to_gate¶
def circuit_to_gate(self, circuit: T, name: str = 'U') -> AnyConvert a circuit to a reusable gate.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | T | The circuit to convert |
name | str | Label for the gate |
Returns:
Any — Backend-specific gate object, or None if not supported
create_circuit¶
def create_circuit(self, num_qubits: int, num_clbits: int) -> TCreate a new empty circuit.
Parameters:
| Name | Type | Description |
|---|---|---|
num_qubits | int | Number of qubits in the circuit |
num_clbits | int | Number of classical bits in the circuit |
Returns:
T — A new backend-specific circuit object
create_parameter¶
def create_parameter(self, name: str) -> AnyCreate a symbolic parameter for the backend.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | Parameter name (e.g., “gammas[0]”) |
Returns:
Any — Backend-specific parameter object
emit_barrier¶
def emit_barrier(self, circuit: T, qubits: list[int]) -> NoneEmit barrier on specified qubits.
emit_ch¶
def emit_ch(self, circuit: T, control: int, target: int) -> NoneEmit controlled-Hadamard gate.
emit_cp¶
def emit_cp(self, circuit: T, control: int, target: int, angle: float | Any) -> NoneEmit controlled-Phase gate.
emit_crx¶
def emit_crx(self, circuit: T, control: int, target: int, angle: float | Any) -> NoneEmit controlled-RX gate.
emit_cry¶
def emit_cry(self, circuit: T, control: int, target: int, angle: float | Any) -> NoneEmit controlled-RY gate.
emit_crz¶
def emit_crz(self, circuit: T, control: int, target: int, angle: float | Any) -> NoneEmit controlled-RZ gate.
emit_cx¶
def emit_cx(self, circuit: T, control: int, target: int) -> NoneEmit CNOT gate.
emit_cy¶
def emit_cy(self, circuit: T, control: int, target: int) -> NoneEmit controlled-Y gate.
emit_cz¶
def emit_cz(self, circuit: T, control: int, target: int) -> NoneEmit CZ gate.
emit_else_start¶
def emit_else_start(self, circuit: T, context: Any) -> NoneStart the else branch.
emit_for_loop_end¶
def emit_for_loop_end(self, circuit: T, context: Any) -> NoneEnd a native for loop context.
emit_for_loop_start¶
def emit_for_loop_start(self, circuit: T, indexset: range) -> AnyStart a native for loop context.
Returns a context manager or loop parameter, depending on backend.
emit_h¶
def emit_h(self, circuit: T, qubit: int) -> NoneEmit Hadamard gate.
emit_if_end¶
def emit_if_end(self, circuit: T, context: Any) -> NoneEnd the if/else block.
emit_if_start¶
def emit_if_start(self, circuit: T, clbit: int, value: int = 1) -> AnyStart a native if context.
Returns context for the if/else block.
emit_measure¶
def emit_measure(self, circuit: T, qubit: int, clbit: int) -> NoneEmit measurement operation.
emit_p¶
def emit_p(self, circuit: T, qubit: int, angle: float | Any) -> NoneEmit Phase gate (P(θ) = diag(1, e^(iθ))).
emit_rx¶
def emit_rx(self, circuit: T, qubit: int, angle: float | Any) -> NoneEmit RX rotation gate.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | T | The circuit to emit to |
qubit | int | Target qubit index |
angle | float | Any | Rotation angle (float or backend parameter) |
emit_ry¶
def emit_ry(self, circuit: T, qubit: int, angle: float | Any) -> NoneEmit RY rotation gate.
emit_rz¶
def emit_rz(self, circuit: T, qubit: int, angle: float | Any) -> NoneEmit RZ rotation gate.
emit_rzz¶
def emit_rzz(self, circuit: T, qubit1: int, qubit2: int, angle: float | Any) -> NoneEmit RZZ gate (exp(-i * θ/2 * Z⊗Z)).
emit_s¶
def emit_s(self, circuit: T, qubit: int) -> NoneEmit S gate (√Z).
emit_sdg¶
def emit_sdg(self, circuit: T, qubit: int) -> NoneEmit S-dagger gate (inverse of S).
emit_swap¶
def emit_swap(self, circuit: T, qubit1: int, qubit2: int) -> NoneEmit SWAP gate.
emit_t¶
def emit_t(self, circuit: T, qubit: int) -> NoneEmit T gate (√S).
emit_tdg¶
def emit_tdg(self, circuit: T, qubit: int) -> NoneEmit T-dagger gate (inverse of T).
emit_toffoli¶
def emit_toffoli(self, circuit: T, control1: int, control2: int, target: int) -> NoneEmit Toffoli (CCX) gate.
emit_while_end¶
def emit_while_end(self, circuit: T, context: Any) -> NoneEnd the while loop context.
emit_while_start¶
def emit_while_start(self, circuit: T, clbit: int, value: int = 1) -> AnyStart a native while loop context.
emit_x¶
def emit_x(self, circuit: T, qubit: int) -> NoneEmit Pauli-X gate.
emit_y¶
def emit_y(self, circuit: T, qubit: int) -> NoneEmit Pauli-Y gate.
emit_z¶
def emit_z(self, circuit: T, qubit: int) -> NoneEmit Pauli-Z gate.
gate_controlled¶
def gate_controlled(self, gate: Any, num_controls: int) -> AnyCreate controlled version of a gate.
Parameters:
| Name | Type | Description |
|---|---|---|
gate | Any | The gate to control |
num_controls | int | Number of control qubits |
Returns:
Any — New controlled gate
gate_power¶
def gate_power(self, gate: Any, power: int) -> AnyCreate gate raised to a power (U^n).
Parameters:
| Name | Type | Description |
|---|---|---|
gate | Any | The gate to raise to a power |
power | int | The power to raise to |
Returns:
Any — New gate representing gate^power
supports_for_loop¶
def supports_for_loop(self) -> boolCheck if backend supports native for loops.
supports_if_else¶
def supports_if_else(self) -> boolCheck if backend supports native if/else.
supports_while_loop¶
def supports_while_loop(self) -> boolCheck if backend supports native while loops.
GateKind [source]¶
class GateKind(Enum)Classification of gates for emission.
Attributes¶
CHCPCRXCRYCRZCXCYCZHMEASUREPRXRYRZRZZSSDGSWAPTTDGTOFFOLIXYZ
GateSpec [source]¶
class GateSpecSpecification for a gate type.
Constructor¶
def __init__(
self,
kind: GateKind,
num_qubits: int,
has_angle: bool = False,
num_controls: int = 0,
) -> NoneAttributes¶
has_angle: boolkind: GateKindnum_controls: intnum_qubits: int
qamomile.circuit.transpiler.job¶
Job classes for quantum execution results.
Overview¶
| Class | Description |
|---|---|
ExpvalJob | Job for expectation value computation. |
Job | Abstract base class for quantum execution jobs. |
JobStatus | Status of a quantum job. |
RunJob | Job for single execution. |
SampleJob | Job for sampling execution (multiple shots). |
SampleResult | Result of a sample() execution. |
Classes¶
ExpvalJob [source]¶
class ExpvalJob(Job[float])Job for expectation value computation.
Returns a single float representing <psi|H|psi>.
Constructor¶
def __init__(self, exp_val: float)Initialize expval job.
Parameters:
| Name | Type | Description |
|---|---|---|
exp_val | float | The computed expectation value |
Methods¶
result¶
def result(self) -> floatReturn the expectation value.
status¶
def status(self) -> JobStatusReturn job status.
Job [source]¶
class Job(ABC, Generic[T])Abstract base class for quantum execution jobs.
A Job represents a quantum execution that can be awaited for results.
Methods¶
result¶
def result(self) -> TWait for and return the result.
Blocks until the job completes.
Returns:
T — The execution result with the appropriate type.
Raises:
ExecutionError— If the job failed.
status¶
def status(self) -> JobStatusReturn the current job status.
JobStatus [source]¶
class JobStatus(Enum)Status of a quantum job.
Attributes¶
COMPLETEDFAILEDPENDINGRUNNING
RunJob [source]¶
class RunJob(Job[T], Generic[T])Job for single execution.
Returns a single result value matching the kernel’s return type.
Constructor¶
def __init__(self, raw_counts: dict[str, int], result_converter: Callable[[str], T])Initialize run job.
Parameters:
| Name | Type | Description |
|---|---|---|
raw_counts | dict[str, int] | Bitstring counts from executor (should have single entry) |
result_converter | Callable[[str], T] | Function to convert bitstring to typed result |
Methods¶
result¶
def result(self) -> TReturn the single result.
status¶
def status(self) -> JobStatusReturn job status.
SampleJob [source]¶
class SampleJob(Job[SampleResult[T]], Generic[T])Job for sampling execution (multiple shots).
Returns a SampleResult containing counts for each unique result.
Constructor¶
def __init__(
self,
raw_counts: dict[str, int],
result_converter: Callable[[dict[str, int]], list[tuple[T, int]]],
shots: int,
)Initialize sample job.
Parameters:
| Name | Type | Description |
|---|---|---|
raw_counts | dict[str, int] | Bitstring counts from executor (e.g., {“00”: 512, “11”: 512}) |
result_converter | Callable[[dict[str, int]], list[tuple[T, int]]] | Function to convert raw counts to typed results |
shots | int | Number of shots executed |
Methods¶
result¶
def result(self) -> SampleResult[T]Return the sample result.
status¶
def status(self) -> JobStatusReturn job status.
SampleResult [source]¶
class SampleResult(Generic[T])Result of a sample() execution.
Contains results as a list of (value, count) tuples.
Example:
result.results # [(0.25, 500), (0.75, 500)]Constructor¶
def __init__(self, results: list[tuple[T, int]], shots: int) -> NoneAttributes¶
results: list[tuple[T, int]] List of (value, count) tuples.shots: int Total number of shots executed.
Methods¶
most_common¶
def most_common(self, n: int = 1) -> list[tuple[T, int]]Return the n most common results.
Parameters:
| Name | Type | Description |
|---|---|---|
n | int | Number of results to return. |
Returns:
list[tuple[T, int]] — List of (result, count) tuples sorted by count descending.
probabilities¶
def probabilities(self) -> list[tuple[T, float]]Return probability distribution over results.
Returns:
list[tuple[T, float]] — List of (value, probability) tuples.
qamomile.circuit.transpiler.orchestrator¶
Overview¶
| Function | Description |
|---|---|
separate_operations |
| Class | Description |
|---|---|
ClassicalRunnable | |
Operation | |
OperationKind | Classification of operations for classical/quantum separation. |
Orchestrator | |
QuantumRunnable | |
Runnable |
Functions¶
separate_operations [source]¶
def separate_operations(
operations: list[Operation],
quantum_runnable_cls: type[QuantumRunnable],
classical_runnable_cls: type[ClassicalRunnable],
) -> list[Runnable]Classes¶
ClassicalRunnable [source]¶
class ClassicalRunnable(Runnable)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
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
Orchestrator [source]¶
class OrchestratorConstructor¶
def __init__(
self,
global_variables: dict[str, float | int | bool | list] = dict(),
operations: list[Runnable] = list(),
return_ids: list[tuple[str, int]] = list(),
) -> NoneAttributes¶
global_variables: dict[str, float | int | bool | list]operations: list[Runnable]return_ids: list[tuple[str, int]]
Methods¶
run¶
def run(self, **kwargs = {})QuantumRunnable [source]¶
class QuantumRunnable(Runnable)Runnable [source]¶
class Runnable(abc.ABC)Constructor¶
def __init__(self, operations: list) -> NoneAttributes¶
operations
Methods¶
input_args¶
def input_args(self) -> dict[str, int | float | bool | list]reset_global_vars¶
def reset_global_vars(self)return_assingnments¶
def return_assingnments(self, return_values: list) -> dict[str, int | float | bool | list]run¶
def run(self, *args = (), **kwargs = {})set_global_vars¶
def set_global_vars(self, global_vars: dict[str, int | float | bool | list])qamomile.circuit.transpiler.parameter_binding¶
Parameter binding structures for compiled quantum circuits.
Overview¶
| Class | Description |
|---|---|
ParameterInfo | Information about a single unbound parameter in the circuit. |
ParameterMetadata | Metadata for all parameters in a compiled segment. |
Classes¶
ParameterInfo [source]¶
class ParameterInfoInformation about a single unbound parameter in the circuit.
Constructor¶
def __init__(
self,
name: str,
array_name: str,
index: int | None,
backend_param: Any,
) -> NoneAttributes¶
array_name: strbackend_param: Anyindex: int | Nonename: str
ParameterMetadata [source]¶
class ParameterMetadataMetadata for all parameters in a compiled segment.
Tracks parameter information for runtime binding.
Constructor¶
def __init__(self, parameters: list[ParameterInfo] = list()) -> NoneAttributes¶
parameters: list[ParameterInfo]
Methods¶
get_array_names¶
def get_array_names(self) -> set[str]Get unique array/scalar parameter names.
get_ordered_params¶
def get_ordered_params(self) -> list[Any]Get backend parameter objects in definition order.
Useful for backends that require positional parameter binding (e.g., QURI Parts).
Returns:
list[Any] — List of backend_param objects in the order they were defined.
Example:
# For QURI Parts that uses positional binding:
param_values = [bindings[p.name] for p in metadata.parameters]
bound_circuit = circuit.bind_parameters(param_values)get_param_by_name¶
def get_param_by_name(self, name: str) -> ParameterInfo | NoneGet parameter info by full name.
to_binding_dict¶
def to_binding_dict(self, bindings: dict[str, Any]) -> dict[Any, Any]Convert indexed bindings to backend parameter bindings.
Transforms user-provided bindings (with indexed names like “gammas[0]”) into a dictionary mapping backend parameter objects to values. Useful for backends that use dict-based parameter binding (e.g., Qiskit).
Parameters:
| Name | Type | Description |
|---|---|---|
bindings | dict[str, Any] | Dictionary mapping parameter names to values. e.g., {“gammas[0]”: 0.1, “gammas[1]”: 0.2, “theta”: 0.5} |
Returns:
dict[Any, Any] — Dictionary mapping backend_param objects to values.
Example:
# For Qiskit that uses dict-based binding:
qiskit_bindings = metadata.to_binding_dict(bindings)
bound_circuit = circuit.assign_parameters(qiskit_bindings)qamomile.circuit.transpiler.passes¶
Base classes for compiler passes.
Overview¶
| Class | Description |
|---|---|
AffineTypeError | Base class for affine type violations. |
AffineValidationPass | Validate affine type semantics at IR level. |
CompileTimeIfLoweringPass | Lowers compile-time resolvable IfOperations before separation. |
ConstantFoldingPass | Evaluates constant expressions at compile time. |
ControlFlowVisitor | Base class for visiting operations with control flow handling. |
DependencyError | Error when quantum operation depends on non-parameter classical value. |
OperationCollector | Collects operations matching a predicate. |
OperationTransformer | Base class for transforming operations with control flow handling. |
Pass | Base class for all compiler passes. |
QamomileCompileError | Base class for all Qamomile compilation errors. |
UUIDRemapper | Clones values and operations with fresh UUIDs and logical_ids. |
ValidateWhileContractPass | Validates that all WhileOperation conditions are measurement-backed. |
ValidationError | Error during validation (e.g., non-classical I/O). |
ValueCollector | Collects Value UUIDs from operation operands and results. |
ValueSubstitutor | Substitutes values in operations using a mapping. |
Classes¶
AffineTypeError [source]¶
class AffineTypeError(QamomileCompileError)Base class for affine type violations.
Affine types enforce that quantum resources (qubits) are used at most once. This prevents common errors such as reusing a consumed qubit or aliasing.
Constructor¶
def __init__(
self,
message: str,
handle_name: str | None = None,
operation_name: str | None = None,
first_use_location: str | None = None,
)Attributes¶
first_use_locationhandle_nameoperation_name
AffineValidationPass [source]¶
class AffineValidationPass(Pass[Block, Block])Validate affine type semantics at IR level.
This pass serves as a safety net to catch affine type violations that may have bypassed the frontend checks. It verifies:
Each quantum value is used (consumed) at most once
Quantum values are not silently discarded
Input: Block (any kind) Output: Same Block (unchanged, validation only)
Attributes¶
name: str
Methods¶
run¶
def run(self, input: Block) -> BlockValidate affine type semantics in the block.
Raises:
AffineTypeError— If a quantum value is consumed multiple times.
CompileTimeIfLoweringPass [source]¶
class CompileTimeIfLoweringPass(Pass[Block, Block])Lowers compile-time resolvable IfOperations before separation.
After constant folding, some IfOperation conditions are statically
known but remain as control-flow nodes. SeparatePass treats them
as segment boundaries, causing MultipleQuantumSegmentsError for
classical-only compile-time if after quantum init.
This pass:
Evaluates conditions including expression-derived ones (
CompOp,CondOp,NotOpchains).Replaces resolved
IfOperations with selected-branch operations.Substitutes phi output UUIDs with selected-branch values in all subsequent operations and block outputs.
Constructor¶
def __init__(self, bindings: dict[str, Any] | None = None)Attributes¶
name: str
Methods¶
run¶
def run(self, input: Block) -> BlockRun the compile-time if lowering pass.
ConstantFoldingPass [source]¶
class ConstantFoldingPass(Pass[Block, Block])Evaluates constant expressions at compile time.
This pass folds BinOp operations when all operands are constants or bound parameters, eliminating unnecessary classical operations that would otherwise split quantum segments.
Example:
Before (with bindings={"phase": 0.5}):
BinOp(phase * 2) -> classical segment split
After:
Constant 1.0 -> no segment splitConstructor¶
def __init__(self, bindings: dict[str, Any] | None = None)Attributes¶
name: str
Methods¶
run¶
def run(self, input: Block) -> BlockRun constant folding on the block.
ControlFlowVisitor [source]¶
class ControlFlowVisitor(ABC)Base class for visiting operations with control flow handling.
Subclasses override visit_operation to define per-operation behavior.
Control flow recursion is handled automatically by the base class.
Example:
class MeasurementCounter(ControlFlowVisitor):
def __init__(self):
self.count = 0
def visit_operation(self, op: Operation) -> None:
if isinstance(op, MeasureOperation):
self.count += 1Methods¶
visit_operation¶
def visit_operation(self, op: Operation) -> NoneProcess a single operation. Override in subclasses.
visit_operations¶
def visit_operations(self, operations: list[Operation]) -> NoneVisit all operations including nested control flow.
DependencyError [source]¶
class DependencyError(QamomileCompileError)Error when quantum operation depends on non-parameter classical value.
This error indicates that the program requires JIT compilation which is not yet supported.
Constructor¶
def __init__(
self,
message: str,
quantum_op: str | None = None,
classical_value: str | None = None,
)Attributes¶
classical_valuequantum_op
OperationCollector [source]¶
class OperationCollector(ControlFlowVisitor)Collects operations matching a predicate.
Example:
collector = OperationCollector(lambda op: isinstance(op, MeasureOperation))
collector.visit_operations(block.operations)
measurements = collector.collectedConstructor¶
def __init__(self, predicate: Callable[[Operation], bool])Attributes¶
collected: list[Operation]
Methods¶
visit_operation¶
def visit_operation(self, op: Operation) -> NoneOperationTransformer [source]¶
class OperationTransformer(ABC)Base class for transforming operations with control flow handling.
Subclasses override transform_operation to define per-operation transformation.
Control flow recursion and rebuilding is handled automatically.
Example:
class OperationRenamer(OperationTransformer):
def transform_operation(self, op: Operation) -> Operation:
# Return modified operation
return dataclasses.replace(op, ...)Methods¶
transform_operation¶
def transform_operation(self, op: Operation) -> Operation | NoneTransform a single operation. Return None to remove it.
transform_operations¶
def transform_operations(self, operations: list[Operation]) -> list[Operation]Transform all operations including nested control flow.
Pass [source]¶
class Pass(ABC, Generic[InputT, OutputT])Base class for all compiler passes.
Attributes¶
name: str Human-readable name for this pass.
Methods¶
run¶
def run(self, input: InputT) -> OutputTExecute the pass transformation.
QamomileCompileError [source]¶
class QamomileCompileError(Exception)Base class for all Qamomile compilation errors.
UUIDRemapper [source]¶
class UUIDRemapperClones values and operations with fresh UUIDs and logical_ids.
Used during inlining to create unique identities for values when a block is called multiple times.
Constructor¶
def __init__(self)Attributes¶
logical_id_remap: dict[str, str] Get the mapping from old logical_ids to new logical_ids.uuid_remap: dict[str, str] Get the mapping from old UUIDs to new UUIDs.
Methods¶
clone_operation¶
def clone_operation(self, op: Operation) -> OperationClone an operation with fresh UUIDs for all values.
clone_operations¶
def clone_operations(self, operations: list[Operation]) -> list[Operation]Clone a list of operations with fresh UUIDs.
clone_value¶
def clone_value(self, value: ValueBase) -> ValueBaseClone any value type with a fresh UUID and logical_id.
Handles Value, ArrayValue, TupleValue, and DictValue through the unified ValueBase protocol.
ValidateWhileContractPass [source]¶
class ValidateWhileContractPass(Pass[Block, Block])Validates that all WhileOperation conditions are measurement-backed.
Builds a producer map (result UUID → producing Operation instance) and checks every WhileOperation operand against it. A valid condition must be:
A
ValuewithBitTypeMeasurement-backed: produced by
MeasureOperationdirectly, or byIfOperation/PhiOpwhere every reachable leaf source is itself measurement-backed.
Both operands[0] (initial condition) and operands[1]
(loop-carried condition) are validated.
Raises ValidationError for any non-measurement while pattern.
Attributes¶
name: str
Methods¶
run¶
def run(self, block: Block) -> BlockValidate all WhileOperations and return block unchanged.
ValidationError [source]¶
class ValidationError(QamomileCompileError)Error during validation (e.g., non-classical I/O).
Constructor¶
def __init__(self, message: str, value_name: str | None = None)Attributes¶
value_name
ValueCollector [source]¶
class ValueCollector(ControlFlowVisitor)Collects Value UUIDs from operation operands and results.
Constructor¶
def __init__(self)Attributes¶
operand_uuids: set[str]result_uuids: set[str]
Methods¶
visit_operation¶
def visit_operation(self, op: Operation) -> NoneValueSubstitutor [source]¶
class ValueSubstitutorSubstitutes values in operations using a mapping.
Used during inlining to replace block parameters with caller arguments.
Constructor¶
def __init__(self, value_map: dict[str, ValueBase])Methods¶
substitute_operation¶
def substitute_operation(self, op: Operation) -> OperationSubstitute values in an operation using the value map.
Handles control-flow operations (IfOperation, ForOperation, etc.) by recursing into their nested operation lists and phi_ops.
substitute_value¶
def substitute_value(self, v: ValueBase) -> ValueBaseSubstitute a single value using the value map.
Handles all value types and array elements by substituting their parent_array if needed.
qamomile.circuit.transpiler.passes.affine_validate¶
Affine type validation pass: Verify quantum resources are used correctly.
Overview¶
| Class | Description |
|---|---|
AffineTypeError | Base class for affine type violations. |
AffineValidationPass | Validate affine type semantics at IR level. |
Block | Unified block representation for all pipeline stages. |
ForItemsOperation | Represents iteration over dict/iterable items. |
ForOperation | Represents a for loop operation. |
IfOperation | Represents an if-else conditional operation. |
Pass | Base class for all compiler passes. |
Value | A typed value in the IR with SSA-style versioning. |
WhileOperation | Represents a while loop operation. |
Classes¶
AffineTypeError [source]¶
class AffineTypeError(QamomileCompileError)Base class for affine type violations.
Affine types enforce that quantum resources (qubits) are used at most once. This prevents common errors such as reusing a consumed qubit or aliasing.
Constructor¶
def __init__(
self,
message: str,
handle_name: str | None = None,
operation_name: str | None = None,
first_use_location: str | None = None,
)Attributes¶
first_use_locationhandle_nameoperation_name
AffineValidationPass [source]¶
class AffineValidationPass(Pass[Block, Block])Validate affine type semantics at IR level.
This pass serves as a safety net to catch affine type violations that may have bypassed the frontend checks. It verifies:
Each quantum value is used (consumed) at most once
Quantum values are not silently discarded
Input: Block (any kind) Output: Same Block (unchanged, validation only)
Attributes¶
name: str
Methods¶
run¶
def run(self, input: Block) -> BlockValidate affine type semantics in the block.
Raises:
AffineTypeError— If a quantum value is consumed multiple times.
Block [source]¶
class BlockUnified block representation for all pipeline stages.
Replaces both BlockValue and Graph with a single structure.
The kind field indicates which pipeline stage this block is at.
Constructor¶
def __init__(
self,
name: str = '',
label_args: list[str] = list(),
input_values: list[Value] = list(),
output_values: list[Value] = list(),
operations: list[Operation] = list(),
kind: BlockKind = BlockKind.HIERARCHICAL,
parameters: dict[str, Value] = dict(),
_dependency_graph: dict[str, set[str]] | None = None,
) -> NoneAttributes¶
input_values: list[Value]kind: BlockKindlabel_args: list[str]name: stroperations: list[Operation]output_values: list[Value]parameters: dict[str, Value]
Methods¶
from_block_value¶
@classmethod
def from_block_value(
cls,
block_value: 'BlockValue',
parameters: dict[str, Value] | None = None,
) -> 'Block'Create a Block from a BlockValue.
Parameters:
| Name | Type | Description |
|---|---|---|
block_value | 'BlockValue' | The BlockValue to convert |
parameters | dict[str, Value] | None | Optional parameter bindings |
Returns:
'Block' — A new Block in HIERARCHICAL state
is_affine¶
def is_affine(self) -> boolCheck if block contains no CallBlockOperations.
unbound_parameters¶
def unbound_parameters(self) -> list[str]Return list of unbound parameter names.
ForItemsOperation [source]¶
class ForItemsOperation(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,
operations: list[Operation] = list(),
) -> NoneAttributes¶
key_is_vector: boolkey_vars: list[str]operation_kind: OperationKindoperations: list[Operation]signature: Signaturevalue_var: str
ForOperation [source]¶
class ForOperation(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 = '',
operations: list[Operation] = list(),
) -> NoneAttributes¶
loop_var: stroperation_kind: OperationKindoperations: list[Operation]signature: Signature
IfOperation [source]¶
class IfOperation(Operation)Represents an if-else conditional operation.
Example:
if condition:
true_body
else:
false_bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
true_operations: list[Operation] = list(),
false_operations: list[Operation] = list(),
phi_ops: list[PhiOp] = list(),
) -> NoneAttributes¶
condition: Valuefalse_operations: list[Operation]operation_kind: OperationKindphi_ops: list[PhiOp]signature: Signaturetrue_operations: list[Operation]
Pass [source]¶
class Pass(ABC, Generic[InputT, OutputT])Base class for all compiler passes.
Attributes¶
name: str Human-readable name for this pass.
Methods¶
run¶
def run(self, input: InputT) -> OutputTExecute the pass transformation.
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.
WhileOperation [source]¶
class WhileOperation(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(),
) -> NoneAttributes¶
operation_kind: OperationKindoperations: list[Operation]signature: Signature
qamomile.circuit.transpiler.passes.analyze¶
Analyze pass: Validate and analyze dependencies in an affine block.
Overview¶
| Class | Description |
|---|---|
AnalyzePass | Analyze and validate an affine block. |
Block | Unified block representation for all pipeline stages. |
BlockKind | Classification of block structure for pipeline stages. |
ControlFlowVisitor | Base class for visiting operations with control flow handling. |
DependencyError | Error when quantum operation depends on non-parameter classical value. |
MeasureOperation | |
OperationKind | Classification of operations for classical/quantum separation. |
Pass | Base class for all compiler passes. |
ValidationError | Error during validation (e.g., non-classical I/O). |
Value | A typed value in the IR with SSA-style versioning. |
ValueBase | Protocol defining the common interface for all value types. |
Classes¶
AnalyzePass [source]¶
class AnalyzePass(Pass[Block, Block])Analyze and validate an affine block.
This pass:
Builds a dependency graph between values
Validates that quantum ops don’t depend on non-parameter classical results
Checks that block inputs/outputs are classical
Input: Block with BlockKind.AFFINE Output: Block with BlockKind.ANALYZED (with _dependency_graph populated)
Attributes¶
name: str
Methods¶
run¶
def run(self, input: Block) -> BlockAnalyze the block and validate dependencies.
Block [source]¶
class BlockUnified block representation for all pipeline stages.
Replaces both BlockValue and Graph with a single structure.
The kind field indicates which pipeline stage this block is at.
Constructor¶
def __init__(
self,
name: str = '',
label_args: list[str] = list(),
input_values: list[Value] = list(),
output_values: list[Value] = list(),
operations: list[Operation] = list(),
kind: BlockKind = BlockKind.HIERARCHICAL,
parameters: dict[str, Value] = dict(),
_dependency_graph: dict[str, set[str]] | None = None,
) -> NoneAttributes¶
input_values: list[Value]kind: BlockKindlabel_args: list[str]name: stroperations: list[Operation]output_values: list[Value]parameters: dict[str, Value]
Methods¶
from_block_value¶
@classmethod
def from_block_value(
cls,
block_value: 'BlockValue',
parameters: dict[str, Value] | None = None,
) -> 'Block'Create a Block from a BlockValue.
Parameters:
| Name | Type | Description |
|---|---|---|
block_value | 'BlockValue' | The BlockValue to convert |
parameters | dict[str, Value] | None | Optional parameter bindings |
Returns:
'Block' — A new Block in HIERARCHICAL state
is_affine¶
def is_affine(self) -> boolCheck if block contains no CallBlockOperations.
unbound_parameters¶
def unbound_parameters(self) -> list[str]Return list of unbound parameter names.
BlockKind [source]¶
class BlockKind(Enum)Classification of block structure for pipeline stages.
Attributes¶
AFFINEANALYZEDHIERARCHICAL
ControlFlowVisitor [source]¶
class ControlFlowVisitor(ABC)Base class for visiting operations with control flow handling.
Subclasses override visit_operation to define per-operation behavior.
Control flow recursion is handled automatically by the base class.
Example:
class MeasurementCounter(ControlFlowVisitor):
def __init__(self):
self.count = 0
def visit_operation(self, op: Operation) -> None:
if isinstance(op, MeasureOperation):
self.count += 1Methods¶
visit_operation¶
def visit_operation(self, op: Operation) -> NoneProcess a single operation. Override in subclasses.
visit_operations¶
def visit_operations(self, operations: list[Operation]) -> NoneVisit all operations including nested control flow.
DependencyError [source]¶
class DependencyError(QamomileCompileError)Error when quantum operation depends on non-parameter classical value.
This error indicates that the program requires JIT compilation which is not yet supported.
Constructor¶
def __init__(
self,
message: str,
quantum_op: str | None = None,
classical_value: str | None = None,
)Attributes¶
classical_valuequantum_op
MeasureOperation [source]¶
class MeasureOperation(Operation)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
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
Pass [source]¶
class Pass(ABC, Generic[InputT, OutputT])Base class for all compiler passes.
Attributes¶
name: str Human-readable name for this pass.
Methods¶
run¶
def run(self, input: InputT) -> OutputTExecute the pass transformation.
ValidationError [source]¶
class ValidationError(QamomileCompileError)Error during validation (e.g., non-classical I/O).
Constructor¶
def __init__(self, message: str, value_name: str | None = None)Attributes¶
value_name
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.
ValueBase [source]¶
class ValueBase(Protocol)Protocol defining the common interface for all value types.
This protocol enables:
isinstance(v, ValueBase) checks for any value type
Unified type annotations with ValueBase instead of union types
Duck typing for value operations in transpiler passes
All value types (Value, ArrayValue, TupleValue, DictValue) implement this protocol.
Attributes¶
logical_id: str Identifies the same physical qubit/value across SSA versions.name: str Human-readable name for this value.params: dict[str, Any] Flexible parameter storage for metadata (const, parameter, etc.).uuid: str Unique identifier for this specific value instance.
Methods¶
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) -> ValueBaseCreate a new SSA version with fresh uuid but same logical_id.
parameter_name¶
def parameter_name(self) -> str | NoneGet the parameter name if this is a parameter.
qamomile.circuit.transpiler.passes.compile_time_if_lowering¶
Compile-time IfOperation lowering pass.
Lowers compile-time resolvable IfOperations before the separate pass,
replacing them with selected-branch operations and substituting phi outputs
with selected-branch values throughout the block.
This prevents SeparatePass from seeing classical-only compile-time
IfOperations that would otherwise split quantum segments.
Overview¶
| Function | Description |
|---|---|
resolve_if_condition | Resolve an if-condition to a compile-time boolean. |
| Class | Description |
|---|---|
ArrayValue | An array of values with shape information. |
BinOp | Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, POW). |
BinOpKind | |
Block | Unified block representation for all pipeline stages. |
CompOp | Comparison operation (EQ, NEQ, LT, LE, GT, GE). |
CompOpKind | |
CompileTimeIfLoweringPass | Lowers compile-time resolvable IfOperations before separation. |
CondOp | Conditional logical operation (AND, OR). |
CondOpKind | |
IfOperation | Represents an if-else conditional operation. |
NotOp | |
Pass | Base class for all compiler passes. |
PhiOp | SSA Phi function: merge point after conditional branch. |
Value | A typed value in the IR with SSA-style versioning. |
ValueBase | Protocol defining the common interface for all value types. |
Functions¶
resolve_if_condition [source]¶
def resolve_if_condition(condition: Any, bindings: dict[str, Any]) -> bool | NoneResolve an if-condition to a compile-time boolean.
Checks whether the condition can be statically evaluated at emit time.
Plain Python values (int/bool captured by @qkernel from closure),
constant-folded Values, and Values resolvable via bindings are all
treated as compile-time constants.
Parameters:
| Name | Type | Description |
|---|---|---|
condition | Any | The condition from IfOperation (plain value or Value object). |
bindings | dict[str, Any] | Current variable bindings (uuid → value and/or name → value). |
Returns:
bool | None — True/False for compile-time resolvable conditions,
bool | None — None for runtime conditions that must be dispatched to the
bool | None — backend’s conditional branching protocol.
Classes¶
ArrayValue [source]¶
class ArrayValue(Value[T])An array of values with shape information.
ArrayValue extends Value to represent multi-dimensional arrays of typed values (e.g., qubit registers, parameter vectors).
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, ...] = (),
shape: tuple[Value, ...] = tuple(),
) -> NoneAttributes¶
logical_id: strname: strparams: dict[str, Any]shape: tuple[Value, ...]type: Tuuid: str
Methods¶
next_version¶
def next_version(self) -> ArrayValue[T]Create a new ArrayValue with incremented version, preserving shape.
BinOp [source]¶
class BinOp(BinaryOperationBase)Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, POW).
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
kind: BinOpKind | None = None,
) -> NoneAttributes¶
kind: BinOpKind | Noneoperation_kind: OperationKindsignature: Signature
BinOpKind [source]¶
class BinOpKind(enum.Enum)Attributes¶
ADDDIVFLOORDIVMULPOWSUB
Block [source]¶
class BlockUnified block representation for all pipeline stages.
Replaces both BlockValue and Graph with a single structure.
The kind field indicates which pipeline stage this block is at.
Constructor¶
def __init__(
self,
name: str = '',
label_args: list[str] = list(),
input_values: list[Value] = list(),
output_values: list[Value] = list(),
operations: list[Operation] = list(),
kind: BlockKind = BlockKind.HIERARCHICAL,
parameters: dict[str, Value] = dict(),
_dependency_graph: dict[str, set[str]] | None = None,
) -> NoneAttributes¶
input_values: list[Value]kind: BlockKindlabel_args: list[str]name: stroperations: list[Operation]output_values: list[Value]parameters: dict[str, Value]
Methods¶
from_block_value¶
@classmethod
def from_block_value(
cls,
block_value: 'BlockValue',
parameters: dict[str, Value] | None = None,
) -> 'Block'Create a Block from a BlockValue.
Parameters:
| Name | Type | Description |
|---|---|---|
block_value | 'BlockValue' | The BlockValue to convert |
parameters | dict[str, Value] | None | Optional parameter bindings |
Returns:
'Block' — A new Block in HIERARCHICAL state
is_affine¶
def is_affine(self) -> boolCheck if block contains no CallBlockOperations.
unbound_parameters¶
def unbound_parameters(self) -> list[str]Return list of unbound parameter names.
CompOp [source]¶
class CompOp(BinaryOperationBase)Comparison operation (EQ, NEQ, LT, LE, GT, GE).
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
kind: CompOpKind | None = None,
) -> NoneAttributes¶
kind: CompOpKind | Noneoperation_kind: OperationKindsignature: Signature
CompOpKind [source]¶
class CompOpKind(enum.Enum)Attributes¶
EQGEGTLELTNEQ
CompileTimeIfLoweringPass [source]¶
class CompileTimeIfLoweringPass(Pass[Block, Block])Lowers compile-time resolvable IfOperations before separation.
After constant folding, some IfOperation conditions are statically
known but remain as control-flow nodes. SeparatePass treats them
as segment boundaries, causing MultipleQuantumSegmentsError for
classical-only compile-time if after quantum init.
This pass:
Evaluates conditions including expression-derived ones (
CompOp,CondOp,NotOpchains).Replaces resolved
IfOperations with selected-branch operations.Substitutes phi output UUIDs with selected-branch values in all subsequent operations and block outputs.
Constructor¶
def __init__(self, bindings: dict[str, Any] | None = None)Attributes¶
name: str
Methods¶
run¶
def run(self, input: Block) -> BlockRun the compile-time if lowering pass.
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
IfOperation [source]¶
class IfOperation(Operation)Represents an if-else conditional operation.
Example:
if condition:
true_body
else:
false_bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
true_operations: list[Operation] = list(),
false_operations: list[Operation] = list(),
phi_ops: list[PhiOp] = list(),
) -> NoneAttributes¶
condition: Valuefalse_operations: list[Operation]operation_kind: OperationKindphi_ops: list[PhiOp]signature: Signaturetrue_operations: list[Operation]
NotOp [source]¶
class NotOp(Operation)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
input: Valueoperation_kind: OperationKindoutput: Valuesignature: Signature
Pass [source]¶
class Pass(ABC, Generic[InputT, OutputT])Base class for all compiler passes.
Attributes¶
name: str Human-readable name for this pass.
Methods¶
run¶
def run(self, input: InputT) -> OutputTExecute the pass transformation.
PhiOp [source]¶
class PhiOp(Operation)SSA Phi function: merge point after conditional branch.
This operation selects one of two values based on a condition. Used to merge values from different branches of an if-else statement.
Example:
if condition:
x = x + 1 # true_value
else:
x = x + 2 # false_value
# x is now PhiOp(condition, true_value, false_value)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
condition: Valuefalse_value: Valueoperation_kind: OperationKindoutput: Valuesignature: Signaturetrue_value: Value
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.
ValueBase [source]¶
class ValueBase(Protocol)Protocol defining the common interface for all value types.
This protocol enables:
isinstance(v, ValueBase) checks for any value type
Unified type annotations with ValueBase instead of union types
Duck typing for value operations in transpiler passes
All value types (Value, ArrayValue, TupleValue, DictValue) implement this protocol.
Attributes¶
logical_id: str Identifies the same physical qubit/value across SSA versions.name: str Human-readable name for this value.params: dict[str, Any] Flexible parameter storage for metadata (const, parameter, etc.).uuid: str Unique identifier for this specific value instance.
Methods¶
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) -> ValueBaseCreate a new SSA version with fresh uuid but same logical_id.
parameter_name¶
def parameter_name(self) -> str | NoneGet the parameter name if this is a parameter.
qamomile.circuit.transpiler.passes.constant_fold¶
Constant folding pass for compile-time expression evaluation.
Overview¶
| Class | Description |
|---|---|
BinOp | Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, POW). |
BinOpKind | |
Block | Unified block representation for all pipeline stages. |
ConstantFoldingPass | Evaluates constant expressions at compile time. |
ControlledUOperation | Controlled-U operation that applies a unitary block conditionally. |
GateOperation | |
OperationTransformer | Base class for transforming operations with control flow handling. |
Pass | Base class for all compiler passes. |
Value | A typed value in the IR with SSA-style versioning. |
ValueBase | Protocol defining the common interface for all value types. |
Classes¶
BinOp [source]¶
class BinOp(BinaryOperationBase)Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, POW).
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
kind: BinOpKind | None = None,
) -> NoneAttributes¶
kind: BinOpKind | Noneoperation_kind: OperationKindsignature: Signature
BinOpKind [source]¶
class BinOpKind(enum.Enum)Attributes¶
ADDDIVFLOORDIVMULPOWSUB
Block [source]¶
class BlockUnified block representation for all pipeline stages.
Replaces both BlockValue and Graph with a single structure.
The kind field indicates which pipeline stage this block is at.
Constructor¶
def __init__(
self,
name: str = '',
label_args: list[str] = list(),
input_values: list[Value] = list(),
output_values: list[Value] = list(),
operations: list[Operation] = list(),
kind: BlockKind = BlockKind.HIERARCHICAL,
parameters: dict[str, Value] = dict(),
_dependency_graph: dict[str, set[str]] | None = None,
) -> NoneAttributes¶
input_values: list[Value]kind: BlockKindlabel_args: list[str]name: stroperations: list[Operation]output_values: list[Value]parameters: dict[str, Value]
Methods¶
from_block_value¶
@classmethod
def from_block_value(
cls,
block_value: 'BlockValue',
parameters: dict[str, Value] | None = None,
) -> 'Block'Create a Block from a BlockValue.
Parameters:
| Name | Type | Description |
|---|---|---|
block_value | 'BlockValue' | The BlockValue to convert |
parameters | dict[str, Value] | None | Optional parameter bindings |
Returns:
'Block' — A new Block in HIERARCHICAL state
is_affine¶
def is_affine(self) -> boolCheck if block contains no CallBlockOperations.
unbound_parameters¶
def unbound_parameters(self) -> list[str]Return list of unbound parameter names.
ConstantFoldingPass [source]¶
class ConstantFoldingPass(Pass[Block, Block])Evaluates constant expressions at compile time.
This pass folds BinOp operations when all operands are constants or bound parameters, eliminating unnecessary classical operations that would otherwise split quantum segments.
Example:
Before (with bindings={"phase": 0.5}):
BinOp(phase * 2) -> classical segment split
After:
Constant 1.0 -> no segment splitConstructor¶
def __init__(self, bindings: dict[str, Any] | None = None)Attributes¶
name: str
Methods¶
run¶
def run(self, input: Block) -> BlockRun constant folding on the block.
ControlledUOperation [source]¶
class ControlledUOperation(Operation)Controlled-U operation that applies a unitary block conditionally.
The operands structure is:
operands[0]: BlockValue (the unitary U to apply)
operands[1:1+num_controls]: Control qubits
operands[1+num_controls:]: Target qubits (arguments to U)
The results structure is:
results[0:num_controls]: Control qubits (returned)
results[num_controls:]: Target qubits (returned from U)
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_controls: int | Value = 1,
power: int | Value = 1,
target_indices: list[Value] | None = None,
controlled_indices: list[Value] | None = None,
) -> NoneAttributes¶
blockGet the BlockValue (unitary U).control_operandsGet the control qubit values.controlled_indices: list[Value] | Nonehas_index_spec: bool Whether target/control positions are specified via index lists.is_symbolic_num_controls: bool Whether num_controls is symbolic (Value) rather than concrete (int).num_controls: int | Valueoperation_kind: OperationKindparam_operandsGet parameter operands (non-qubit, non-block).power: int | Valuesignature: Signaturetarget_indices: list[Value] | Nonetarget_operandsGet the target qubit values (arguments to U).
GateOperation [source]¶
class GateOperation(Operation)Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
gate_type: GateOperationType | None = None,
theta: float | Value | None = None,
) -> NoneAttributes¶
gate_type: GateOperationType | Noneoperation_kind: OperationKindsignature: Signaturetheta: float | Value | None
OperationTransformer [source]¶
class OperationTransformer(ABC)Base class for transforming operations with control flow handling.
Subclasses override transform_operation to define per-operation transformation.
Control flow recursion and rebuilding is handled automatically.
Example:
class OperationRenamer(OperationTransformer):
def transform_operation(self, op: Operation) -> Operation:
# Return modified operation
return dataclasses.replace(op, ...)Methods¶
transform_operation¶
def transform_operation(self, op: Operation) -> Operation | NoneTransform a single operation. Return None to remove it.
transform_operations¶
def transform_operations(self, operations: list[Operation]) -> list[Operation]Transform all operations including nested control flow.
Pass [source]¶
class Pass(ABC, Generic[InputT, OutputT])Base class for all compiler passes.
Attributes¶
name: str Human-readable name for this pass.
Methods¶
run¶
def run(self, input: InputT) -> OutputTExecute the pass transformation.
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.
ValueBase [source]¶
class ValueBase(Protocol)Protocol defining the common interface for all value types.
This protocol enables:
isinstance(v, ValueBase) checks for any value type
Unified type annotations with ValueBase instead of union types
Duck typing for value operations in transpiler passes
All value types (Value, ArrayValue, TupleValue, DictValue) implement this protocol.
Attributes¶
logical_id: str Identifies the same physical qubit/value across SSA versions.name: str Human-readable name for this value.params: dict[str, Any] Flexible parameter storage for metadata (const, parameter, etc.).uuid: str Unique identifier for this specific value instance.
Methods¶
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) -> ValueBaseCreate a new SSA version with fresh uuid but same logical_id.
parameter_name¶
def parameter_name(self) -> str | NoneGet the parameter name if this is a parameter.
qamomile.circuit.transpiler.passes.control_flow_visitor¶
Control flow visitor for operation traversal.
Overview¶
| Class | Description |
|---|---|
ControlFlowVisitor | Base class for visiting operations with control flow handling. |
ForOperation | Represents a for loop operation. |
IfOperation | Represents an if-else conditional operation. |
OperationCollector | Collects operations matching a predicate. |
OperationTransformer | Base class for transforming operations with control flow handling. |
ValueCollector | Collects Value UUIDs from operation operands and results. |
WhileOperation | Represents a while loop operation. |
Classes¶
ControlFlowVisitor [source]¶
class ControlFlowVisitor(ABC)Base class for visiting operations with control flow handling.
Subclasses override visit_operation to define per-operation behavior.
Control flow recursion is handled automatically by the base class.
Example:
class MeasurementCounter(ControlFlowVisitor):
def __init__(self):
self.count = 0
def visit_operation(self, op: Operation) -> None:
if isinstance(op, MeasureOperation):
self.count += 1Methods¶
visit_operation¶
def visit_operation(self, op: Operation) -> NoneProcess a single operation. Override in subclasses.
visit_operations¶
def visit_operations(self, operations: list[Operation]) -> NoneVisit all operations including nested control flow.
ForOperation [source]¶
class ForOperation(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 = '',
operations: list[Operation] = list(),
) -> NoneAttributes¶
loop_var: stroperation_kind: OperationKindoperations: list[Operation]signature: Signature
IfOperation [source]¶
class IfOperation(Operation)Represents an if-else conditional operation.
Example:
if condition:
true_body
else:
false_bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
true_operations: list[Operation] = list(),
false_operations: list[Operation] = list(),
phi_ops: list[PhiOp] = list(),
) -> NoneAttributes¶
condition: Valuefalse_operations: list[Operation]operation_kind: OperationKindphi_ops: list[PhiOp]signature: Signaturetrue_operations: list[Operation]
OperationCollector [source]¶
class OperationCollector(ControlFlowVisitor)Collects operations matching a predicate.
Example:
collector = OperationCollector(lambda op: isinstance(op, MeasureOperation))
collector.visit_operations(block.operations)
measurements = collector.collectedConstructor¶
def __init__(self, predicate: Callable[[Operation], bool])Attributes¶
collected: list[Operation]
Methods¶
visit_operation¶
def visit_operation(self, op: Operation) -> NoneOperationTransformer [source]¶
class OperationTransformer(ABC)Base class for transforming operations with control flow handling.
Subclasses override transform_operation to define per-operation transformation.
Control flow recursion and rebuilding is handled automatically.
Example:
class OperationRenamer(OperationTransformer):
def transform_operation(self, op: Operation) -> Operation:
# Return modified operation
return dataclasses.replace(op, ...)Methods¶
transform_operation¶
def transform_operation(self, op: Operation) -> Operation | NoneTransform a single operation. Return None to remove it.
transform_operations¶
def transform_operations(self, operations: list[Operation]) -> list[Operation]Transform all operations including nested control flow.
ValueCollector [source]¶
class ValueCollector(ControlFlowVisitor)Collects Value UUIDs from operation operands and results.
Constructor¶
def __init__(self)Attributes¶
operand_uuids: set[str]result_uuids: set[str]
Methods¶
visit_operation¶
def visit_operation(self, op: Operation) -> NoneWhileOperation [source]¶
class WhileOperation(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(),
) -> NoneAttributes¶
operation_kind: OperationKindoperations: list[Operation]signature: Signature
qamomile.circuit.transpiler.passes.emit¶
Emit pass: Generate backend-specific code from separated program.
Overview¶
| Class | Description |
|---|---|
ClassicalSegment | A segment of pure classical operations. |
CompositeGateEmitter | Protocol for backend-specific CompositeGate emitters. |
CompositeGateOperation | Represents a composite gate (QPE, QFT, etc.) as a single operation. |
CompositeGateType | Registry of known composite gate types. |
EmitPass | Base class for backend-specific emission passes. |
ExecutableProgram | A fully compiled program ready for execution. |
ExpvalSegment | A segment for expectation value computation. |
Pass | Base class for all compiler passes. |
QuantumSegment | A segment of pure quantum operations. |
SimplifiedProgram | Enforces Classical → Quantum → Classical pattern. |
Value | A typed value in the IR with SSA-style versioning. |
Classes¶
ClassicalSegment [source]¶
class ClassicalSegment(Segment)A segment of pure classical operations.
Contains arithmetic, comparisons, and control flow. Will be executed directly in Python.
Constructor¶
def __init__(
self,
operations: list[Operation] = list(),
input_refs: list[str] = list(),
output_refs: list[str] = list(),
) -> NoneAttributes¶
kind: SegmentKind
CompositeGateEmitter [source]¶
class CompositeGateEmitter(Protocol[C])Protocol for backend-specific CompositeGate emitters.
Each backend can implement emitters for specific composite gate types (QPE, QFT, IQFT, etc.) using native backend libraries.
The emitter pattern allows:
Backends to use native implementations when available (e.g., Qiskit QFT)
Fallback to manual decomposition when native is unavailable
Easy addition of new backends without modifying core code
Example:
class QiskitQFTEmitter:
def can_emit(self, gate_type: CompositeGateType) -> bool:
return gate_type in (CompositeGateType.QFT, CompositeGateType.IQFT)
def emit(self, circuit, op, qubit_indices, bindings) -> bool:
from qiskit.circuit.library import QFTGate
qft_gate = QFTGate(len(qubit_indices))
circuit.append(qft_gate, qubit_indices)
return TrueMethods¶
can_emit¶
def can_emit(self, gate_type: CompositeGateType) -> boolCheck if this emitter can handle the given gate type.
Parameters:
| Name | Type | Description |
|---|---|---|
gate_type | CompositeGateType | The CompositeGateType to check |
Returns:
bool — True if this emitter supports native emission for the gate type
emit¶
def emit(
self,
circuit: C,
op: CompositeGateOperation,
qubit_indices: list[int],
bindings: dict[str, Any],
) -> boolEmit the composite gate to the circuit.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | C | The backend-specific circuit to emit to |
op | CompositeGateOperation | The CompositeGateOperation to emit |
qubit_indices | list[int] | Physical qubit indices for the operation |
bindings | dict[str, Any] | Parameter bindings for the operation |
Returns:
bool — True if emission succeeded, False to fall back to manual decomposition
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
EmitPass [source]¶
class EmitPass(Pass[SimplifiedProgram, ExecutableProgram[T]], Generic[T])Base class for backend-specific emission passes.
Subclasses implement _emit_quantum_segment() to generate backend-specific quantum circuits.
Input: SimplifiedProgram (enforces C→Q→C pattern) Output: ExecutableProgram with compiled segments
Constructor¶
def __init__(
self,
bindings: dict[str, Any] | None = None,
parameters: list[str] | None = None,
)Initialize with optional parameter bindings.
Parameters:
| Name | Type | Description |
|---|---|---|
bindings | dict[str, Any] | None | Values to bind parameters to. If not provided, parameters must be bound at execution time. |
parameters | list[str] | None | List of parameter names to preserve as backend parameters. |
Attributes¶
bindingsname: strparameters
Methods¶
run¶
def run(self, input: SimplifiedProgram) -> ExecutableProgram[T]Emit backend code from simplified program.
ExecutableProgram [source]¶
class ExecutableProgram(Generic[T])A fully compiled program ready for execution.
This is the Orchestrator - manages execution of mixed classical/quantum programs.
Example:
executable = transpiler.compile(kernel)
# Sample: multiple shots, returns counts
job = executable.sample(executor, shots=1000)
result = job.result() # SampleResult with counts
# Run: single shot, returns typed result
job = executable.run(executor)
result = job.result() # Returns kernel's return typeConstructor¶
def __init__(
self,
compiled_quantum: list[CompiledQuantumSegment[T]] = list(),
compiled_classical: list[CompiledClassicalSegment] = list(),
compiled_expval: list[CompiledExpvalSegment] = list(),
execution_order: list[tuple[str, int]] = list(),
output_refs: list[str] = list(),
num_output_bits: int = 0,
) -> NoneAttributes¶
compiled_classical: list[CompiledClassicalSegment]compiled_expval: list[CompiledExpvalSegment]compiled_quantum: list[CompiledQuantumSegment[T]]execution_order: list[tuple[str, int]]has_parameters: bool Check if this program has unbound parameters.num_output_bits: intoutput_refs: list[str]parameter_names: list[str] Get list of parameter names that need binding.quantum_circuit: T Get the single quantum circuit.
Methods¶
get_circuits¶
def get_circuits(self) -> list[T]Get all quantum circuits in execution order.
get_first_circuit¶
def get_first_circuit(self) -> T | NoneGet the first quantum circuit, or None if no quantum segments.
run¶
def run(
self,
executor: QuantumExecutor[T],
bindings: dict[str, Any] | None = None,
) -> RunJob[Any] | ExpvalJobExecute once and return single result.
Parameters:
| Name | Type | Description |
|---|---|---|
executor | QuantumExecutor[T] | Backend-specific quantum executor. |
bindings | dict[str, Any] | None | Parameter bindings. Supports two formats: - Vector: {“gammas”: [0.1, 0.2], “betas”: [0.3, 0.4]} - Indexed: {“gammas[0]”: 0.1, “gammas[1]”: 0.2} |
Returns:
RunJob[Any] | ExpvalJob — RunJob that resolves to the kernel’s return type, or
RunJob[Any] | ExpvalJob — ExpvalJob if the program contains expectation value computation.
Raises:
ExecutionError— If no quantum circuit to executeValueError— If required parameters are missing
Example:
job = executable.run(executor, bindings={"gamma": [0.5]})
result = job.result()
print(result) # 0.25 (for QFixed) or (0, 1) (for bits)sample¶
def sample(
self,
executor: QuantumExecutor[T],
shots: int = 1024,
bindings: dict[str, Any] | None = None,
) -> SampleJob[Any]Execute with multiple shots and return counts.
Parameters:
| Name | Type | Description |
|---|---|---|
executor | QuantumExecutor[T] | Backend-specific quantum executor. |
shots | int | Number of shots to run. |
bindings | dict[str, Any] | None | Parameter bindings. Supports two formats: - Vector: {“gammas”: [0.1, 0.2], “betas”: [0.3, 0.4]} - Indexed: {“gammas[0]”: 0.1, “gammas[1]”: 0.2} |
Returns:
SampleJob[Any] — SampleJob that resolves to SampleResult with results.
Raises:
ExecutionError— If no quantum circuit to executeValueError— If required parameters are missing
Example:
job = executable.sample(executor, shots=1000, bindings={"gamma": [0.5]})
result = job.result()
print(result.results) # [(0.25, 500), (0.75, 500)]ExpvalSegment [source]¶
class ExpvalSegment(Segment)A segment for expectation value computation.
Represents computing <psi|H|psi> where psi is the quantum state and H is a Hamiltonian observable.
This segment bridges a quantum circuit (state preparation) to a classical expectation value.
Constructor¶
def __init__(
self,
operations: list[Operation] = list(),
input_refs: list[str] = list(),
output_refs: list[str] = list(),
hamiltonian_value: Value | None = None,
qubits_value: Value | None = None,
result_ref: str = '',
) -> NoneAttributes¶
hamiltonian_value: Value | Nonekind: SegmentKindqubits_value: Value | Noneresult_ref: str
Pass [source]¶
class Pass(ABC, Generic[InputT, OutputT])Base class for all compiler passes.
Attributes¶
name: str Human-readable name for this pass.
Methods¶
run¶
def run(self, input: InputT) -> OutputTExecute the pass transformation.
QuantumSegment [source]¶
class QuantumSegment(Segment)A segment of pure quantum operations.
Contains quantum gates and qubit allocations. Will be emitted to a quantum circuit.
Constructor¶
def __init__(
self,
operations: list[Operation] = list(),
input_refs: list[str] = list(),
output_refs: list[str] = list(),
qubit_values: list[Value] = list(),
num_qubits: int = 0,
) -> NoneAttributes¶
kind: SegmentKindnum_qubits: intqubit_values: list[Value]
SimplifiedProgram [source]¶
class SimplifiedProgramEnforces Classical → Quantum → Classical pattern.
Structure:
[Optional] Classical preprocessing (parameter computation, etc.)
Single quantum segment (REQUIRED)
[Optional] Expval segment OR classical postprocessing
This replaces SeparatedProgram to enforce Qamomile’s execution model: all quantum operations must be in a single quantum circuit.
Constructor¶
def __init__(
self,
quantum: QuantumSegment,
classical_prep: ClassicalSegment | None = None,
expval: ExpvalSegment | None = None,
classical_post: ClassicalSegment | None = None,
boundaries: list[HybridBoundary] = list(),
parameters: dict[str, Value] = dict(),
output_refs: list[str] = list(),
) -> NoneAttributes¶
boundaries: list[HybridBoundary]classical_post: ClassicalSegment | Noneclassical_prep: ClassicalSegment | Noneexpval: ExpvalSegment | Noneoutput_refs: list[str]parameters: dict[str, Value]quantum: QuantumSegment
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.
qamomile.circuit.transpiler.passes.emit_base¶
Base classes for emit pass implementation.
This module provides backend-agnostic helper classes for resource allocation, value resolution, and loop analysis. These are used by StandardEmitPass to implement the emission logic without backend-specific code.
Overview¶
| Function | Description |
|---|---|
map_phi_outputs | Register phi output UUIDs to the same physical resources as their source operands. |
remap_static_phi_outputs | Remap phi outputs for a compile-time constant IfOperation. |
resolve_if_condition | Resolve an if-condition to a compile-time boolean. |
| Class | Description |
|---|---|
ArrayValue | An array of values with shape information. |
BinOp | Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, POW). |
BitType | Type representing a classical bit. |
CastOperation | Type cast operation for creating aliases over the same quantum resources. |
CompositeDecomposer | Decomposes composite gates into primitive operations. |
CompositeGateOperation | Represents a composite gate (QPE, QFT, etc.) as a single operation. |
ControlledUOperation | Controlled-U operation that applies a unitary block conditionally. |
ForItemsOperation | Represents iteration over dict/iterable items. |
ForOperation | Represents a for loop operation. |
GateOperation | |
IfOperation | Represents an if-else conditional operation. |
LoopAnalyzer | Analyzes loop structures to determine emission strategy. |
MeasureOperation | |
MeasureQFixedOperation | Measure a quantum fixed-point number. |
MeasureVectorOperation | Measure a vector of qubits. |
PhiOp | SSA Phi function: merge point after conditional branch. |
QInitOperation | Initialize the qubit |
QubitResolutionResult | Result of attempting to resolve a qubit index. |
ResolutionFailureReason | Categorizes why qubit index resolution failed. |
ResourceAllocator | Allocates qubit and classical bit indices from operations. |
Value | A typed value in the IR with SSA-style versioning. |
ValueResolver | Resolves Value objects to concrete indices or values. |
WhileOperation | Represents a while loop operation. |
Functions¶
map_phi_outputs [source]¶
def map_phi_outputs(
phi_ops: list[Operation],
qubit_map: dict[str, int],
clbit_map: dict[str, int],
resolve_scalar_qubit: Any = None,
) -> NoneRegister phi output UUIDs to the same physical resources as their source operands.
After an if-else block, PhiOp merges values from both branches. The phi output is a new Value with a new UUID that must map to the same physical qubit (or classical bit) as the branch values.
For ArrayValue phi outputs (e.g., qubit arrays), this copies all
composite element keys {source_uuid}_{i} →
{output_uuid}_{i} so that subsequent element accesses on the
phi output resolve to the correct physical qubits.
Parameters:
| Name | Type | Description |
|---|---|---|
phi_ops | list[Operation] | List of phi operations from an IfOperation. |
qubit_map | dict[str, int] | Mapping from UUID/composite key to physical qubit index. |
clbit_map | dict[str, int] | Mapping from UUID to physical classical bit index. |
resolve_scalar_qubit | Any | Optional callback (source, qubit_map) -> int | None for resolving scalar qubit values that are not directly in qubit_map (e.g., array element resolution). When None, ResourceAllocator._resolve_qubit_key is used as fallback. |
Raises:
EmitError— When a quantum PhiOp would merge different or partially unresolved physical qubit resources across branches. This means the qubit identity depends on the runtime branch condition and cannot be statically resolved.
remap_static_phi_outputs [source]¶
def remap_static_phi_outputs(
phi_ops: list[Operation],
condition_value: bool,
qubit_map: dict[str, int],
clbit_map: dict[str, int],
) -> NoneRemap phi outputs for a compile-time constant IfOperation.
When the condition is statically known, the dead branch is never
allocated. Phi outputs are aliased directly to the selected
branch’s source value, bypassing the two-branch merge validation
in map_phi_outputs.
This is the shared implementation used by both the resource allocator (during allocation) and the emit pass (during emission) to ensure scalar and array quantum phi outputs are handled identically.
Parameters:
| Name | Type | Description |
|---|---|---|
phi_ops | list[Operation] | Phi operations from the IfOperation. |
condition_value | bool | The resolved boolean condition. |
qubit_map | dict[str, int] | UUID-to-physical-qubit mapping (mutated in place). |
clbit_map | dict[str, int] | UUID-to-physical-clbit mapping (mutated in place). |
resolve_if_condition [source]¶
def resolve_if_condition(condition: Any, bindings: dict[str, Any]) -> bool | NoneResolve an if-condition to a compile-time boolean.
Checks whether the condition can be statically evaluated at emit time.
Plain Python values (int/bool captured by @qkernel from closure),
constant-folded Values, and Values resolvable via bindings are all
treated as compile-time constants.
Parameters:
| Name | Type | Description |
|---|---|---|
condition | Any | The condition from IfOperation (plain value or Value object). |
bindings | dict[str, Any] | Current variable bindings (uuid → value and/or name → value). |
Returns:
bool | None — True/False for compile-time resolvable conditions,
bool | None — None for runtime conditions that must be dispatched to the
bool | None — backend’s conditional branching protocol.
Classes¶
ArrayValue [source]¶
class ArrayValue(Value[T])An array of values with shape information.
ArrayValue extends Value to represent multi-dimensional arrays of typed values (e.g., qubit registers, parameter vectors).
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, ...] = (),
shape: tuple[Value, ...] = tuple(),
) -> NoneAttributes¶
logical_id: strname: strparams: dict[str, Any]shape: tuple[Value, ...]type: Tuuid: str
Methods¶
next_version¶
def next_version(self) -> ArrayValue[T]Create a new ArrayValue with incremented version, preserving shape.
BinOp [source]¶
class BinOp(BinaryOperationBase)Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, POW).
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
kind: BinOpKind | None = None,
) -> NoneAttributes¶
kind: BinOpKind | Noneoperation_kind: OperationKindsignature: Signature
BitType [source]¶
class BitType(ClassicalTypeMixin, ValueType)Type representing a classical bit.
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
CompositeDecomposer [source]¶
class CompositeDecomposerDecomposes composite gates into primitive operations.
Provides algorithms for QFT, IQFT, and QPE decomposition that backends can use for fallback when native implementations are unavailable.
Methods¶
iqft_structure¶
@staticmethod
def iqft_structure(n: int) -> list[tuple[str, tuple[int, ...], float | None]]Generate inverse QFT gate sequence.
Parameters:
| Name | Type | Description |
|---|---|---|
n | int | Number of qubits |
Returns:
list[tuple[str, tuple[int, ...], float | None]] — List of (gate_name, qubit_indices, angle) tuples
qft_structure¶
@staticmethod
def qft_structure(n: int) -> list[tuple[str, tuple[int, ...], float | None]]Generate QFT gate sequence.
Parameters:
| Name | Type | Description |
|---|---|---|
n | int | Number of qubits |
Returns:
list[tuple[str, tuple[int, ...], float | None]] — List of (gate_name, qubit_indices, angle) tuples
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.
ControlledUOperation [source]¶
class ControlledUOperation(Operation)Controlled-U operation that applies a unitary block conditionally.
The operands structure is:
operands[0]: BlockValue (the unitary U to apply)
operands[1:1+num_controls]: Control qubits
operands[1+num_controls:]: Target qubits (arguments to U)
The results structure is:
results[0:num_controls]: Control qubits (returned)
results[num_controls:]: Target qubits (returned from U)
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_controls: int | Value = 1,
power: int | Value = 1,
target_indices: list[Value] | None = None,
controlled_indices: list[Value] | None = None,
) -> NoneAttributes¶
blockGet the BlockValue (unitary U).control_operandsGet the control qubit values.controlled_indices: list[Value] | Nonehas_index_spec: bool Whether target/control positions are specified via index lists.is_symbolic_num_controls: bool Whether num_controls is symbolic (Value) rather than concrete (int).num_controls: int | Valueoperation_kind: OperationKindparam_operandsGet parameter operands (non-qubit, non-block).power: int | Valuesignature: Signaturetarget_indices: list[Value] | Nonetarget_operandsGet the target qubit values (arguments to U).
ForItemsOperation [source]¶
class ForItemsOperation(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,
operations: list[Operation] = list(),
) -> NoneAttributes¶
key_is_vector: boolkey_vars: list[str]operation_kind: OperationKindoperations: list[Operation]signature: Signaturevalue_var: str
ForOperation [source]¶
class ForOperation(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 = '',
operations: list[Operation] = list(),
) -> NoneAttributes¶
loop_var: stroperation_kind: OperationKindoperations: list[Operation]signature: Signature
GateOperation [source]¶
class GateOperation(Operation)Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
gate_type: GateOperationType | None = None,
theta: float | Value | None = None,
) -> NoneAttributes¶
gate_type: GateOperationType | Noneoperation_kind: OperationKindsignature: Signaturetheta: float | Value | None
IfOperation [source]¶
class IfOperation(Operation)Represents an if-else conditional operation.
Example:
if condition:
true_body
else:
false_bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
true_operations: list[Operation] = list(),
false_operations: list[Operation] = list(),
phi_ops: list[PhiOp] = list(),
) -> NoneAttributes¶
condition: Valuefalse_operations: list[Operation]operation_kind: OperationKindphi_ops: list[PhiOp]signature: Signaturetrue_operations: list[Operation]
LoopAnalyzer [source]¶
class LoopAnalyzerAnalyzes loop structures to determine emission strategy.
Determines whether loops should use native backend control flow or be unrolled at emission time.
Methods¶
should_unroll¶
def should_unroll(self, op: ForOperation, bindings: dict[str, Any]) -> boolDetermine if a ForOperation should be unrolled.
Parameters:
| Name | Type | Description |
|---|---|---|
op | ForOperation | The ForOperation to analyze |
bindings | dict[str, Any] | Current variable bindings |
Returns:
bool — True if loop should be unrolled, False for native emission
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): float_value = 0.b0b1b2... = b00.5 + b10.25 + b2*0.125 + ...
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_bits: int = 0,
int_bits: int = 0,
) -> 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
PhiOp [source]¶
class PhiOp(Operation)SSA Phi function: merge point after conditional branch.
This operation selects one of two values based on a condition. Used to merge values from different branches of an if-else statement.
Example:
if condition:
x = x + 1 # true_value
else:
x = x + 2 # false_value
# x is now PhiOp(condition, true_value, false_value)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
condition: Valuefalse_value: Valueoperation_kind: OperationKindoutput: Valuesignature: Signaturetrue_value: Value
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
QubitResolutionResult [source]¶
class QubitResolutionResultResult of attempting to resolve a qubit index.
Constructor¶
def __init__(
self,
success: bool,
index: int | None = None,
failure_reason: ResolutionFailureReason | None = None,
failure_details: str = '',
) -> NoneAttributes¶
failure_details: strfailure_reason: ResolutionFailureReason | Noneindex: int | Nonesuccess: bool
ResolutionFailureReason [source]¶
class ResolutionFailureReason(Enum)Categorizes why qubit index resolution failed.
Attributes¶
ARRAY_ELEMENT_NOT_IN_QUBIT_MAPDIRECT_UUID_NOT_FOUNDINDEX_NOT_NUMERICNESTED_ARRAY_RESOLUTION_FAILEDSYMBOLIC_INDEX_NOT_BOUNDUNKNOWN
ResourceAllocator [source]¶
class ResourceAllocatorAllocates qubit and classical bit indices from operations.
This class handles the first pass of circuit emission: determining how many physical qubits and classical bits are needed and mapping Value UUIDs to their physical indices.
New physical indices are assigned via monotonic counters
(_next_qubit_index / _next_clbit_index) so that alias
entries — which reuse an existing physical index — never inflate
the counter. Using len(map) would cause sparse (gapped)
physical indices because alias keys increase the map size without
adding new physical resources.
Constructor¶
def __init__(self) -> NoneMethods¶
allocate¶
def allocate(
self,
operations: list[Operation],
bindings: dict[str, Any] | None = None,
) -> tuple[dict[str, int], dict[str, int]]Allocate qubit and clbit indices for all operations.
Parameters:
| Name | Type | Description |
|---|---|---|
operations | list[Operation] | List of operations to allocate resources for |
bindings | dict[str, Any] | None | Optional variable bindings for resolving dynamic sizes |
Returns:
tuple[dict[str, int], dict[str, int]] — Tuple of (qubit_map, clbit_map) where each maps UUID to index
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.
ValueResolver [source]¶
class ValueResolverResolves Value objects to concrete indices or values.
Handles the mapping from IR Value objects to physical qubit indices, classical values, and parameter names during emission.
Constructor¶
def __init__(self, parameters: set[str] | None = None)Initialize the resolver.
Parameters:
| Name | Type | Description |
|---|---|---|
parameters | set[str] | None | Set of parameter names to preserve as symbolic |
Attributes¶
parameters
Methods¶
get_parameter_key¶
def get_parameter_key(self, value: 'Value', bindings: dict[str, Any]) -> str | NoneGet parameter key if this value should be a symbolic parameter.
Parameters:
| Name | Type | Description |
|---|---|---|
value | 'Value' | The Value to check |
bindings | dict[str, Any] | Current bindings (for resolving array indices) |
Returns:
str | None — Parameter key (e.g., “gammas[0]”) if symbolic, None otherwise
resolve_classical_value¶
def resolve_classical_value(self, value: 'Value', bindings: dict[str, Any]) -> AnyResolve a classical Value to a concrete Python value.
Parameters:
| Name | Type | Description |
|---|---|---|
value | 'Value' | The Value to resolve |
bindings | dict[str, Any] | Current variable bindings |
Returns:
Any — Resolved value (int, float, etc.), or None if cannot resolve
resolve_int_value¶
def resolve_int_value(self, val: Any, bindings: dict[str, Any]) -> int | NoneResolve a value to an integer (for loop bounds, etc.).
Parameters:
| Name | Type | Description |
|---|---|---|
val | Any | The value to resolve |
bindings | dict[str, Any] | Current variable bindings |
Returns:
int | None — Integer value, or None if cannot resolve
resolve_qubit_index¶
def resolve_qubit_index(
self,
v: 'Value',
qubit_map: dict[str, int],
bindings: dict[str, Any],
) -> int | NoneResolve a Value to a physical qubit index.
Parameters:
| Name | Type | Description |
|---|---|---|
v | 'Value' | The Value to resolve |
qubit_map | dict[str, int] | Mapping from UUID to qubit index |
bindings | dict[str, Any] | Current variable bindings |
Returns:
int | None — Physical qubit index, or None if cannot resolve
resolve_qubit_index_detailed¶
def resolve_qubit_index_detailed(
self,
v: 'Value',
qubit_map: dict[str, int],
bindings: dict[str, Any],
) -> QubitResolutionResultResolve a Value to a physical qubit index with detailed failure info.
Parameters:
| Name | Type | Description |
|---|---|---|
v | 'Value' | The Value to resolve |
qubit_map | dict[str, int] | Mapping from UUID to qubit index |
bindings | dict[str, Any] | Current variable bindings |
Returns:
QubitResolutionResult — QubitResolutionResult with success status and either index or failure details
WhileOperation [source]¶
class WhileOperation(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(),
) -> NoneAttributes¶
operation_kind: OperationKindoperations: list[Operation]signature: Signature
qamomile.circuit.transpiler.passes.inline¶
Inline pass: Inline CallBlockOperations to create an affine block.
Overview¶
| Function | Description |
|---|---|
find_return_operation | Find the ReturnOperation in a list of operations (expected at the end). |
| Class | Description |
|---|---|
ArrayValue | An array of values with shape information. |
Block | Unified block representation for all pipeline stages. |
BlockKind | Classification of block structure for pipeline stages. |
BlockValue | Represents a subroutine as a function block. |
CallBlockOperation | |
CompositeGateOperation | Represents a composite gate (QPE, QFT, etc.) as a single operation. |
CompositeGateType | Registry of known composite gate types. |
ForItemsOperation | Represents iteration over dict/iterable items. |
ForOperation | Represents a for loop operation. |
IfOperation | Represents an if-else conditional operation. |
InlinePass | Inline all CallBlockOperations to create an affine block. |
Pass | Base class for all compiler passes. |
ReturnOperation | Explicit return operation marking the end of a block with return values. |
UUIDRemapper | Clones values and operations with fresh UUIDs and logical_ids. |
Value | A typed value in the IR with SSA-style versioning. |
ValueSubstitutor | Substitutes values in operations using a mapping. |
WhileOperation | Represents a while loop operation. |
Functions¶
find_return_operation [source]¶
def find_return_operation(operations: list[Operation]) -> ReturnOperation | NoneFind the ReturnOperation in a list of operations (expected at the end).
Classes¶
ArrayValue [source]¶
class ArrayValue(Value[T])An array of values with shape information.
ArrayValue extends Value to represent multi-dimensional arrays of typed values (e.g., qubit registers, parameter vectors).
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, ...] = (),
shape: tuple[Value, ...] = tuple(),
) -> NoneAttributes¶
logical_id: strname: strparams: dict[str, Any]shape: tuple[Value, ...]type: Tuuid: str
Methods¶
next_version¶
def next_version(self) -> ArrayValue[T]Create a new ArrayValue with incremented version, preserving shape.
Block [source]¶
class BlockUnified block representation for all pipeline stages.
Replaces both BlockValue and Graph with a single structure.
The kind field indicates which pipeline stage this block is at.
Constructor¶
def __init__(
self,
name: str = '',
label_args: list[str] = list(),
input_values: list[Value] = list(),
output_values: list[Value] = list(),
operations: list[Operation] = list(),
kind: BlockKind = BlockKind.HIERARCHICAL,
parameters: dict[str, Value] = dict(),
_dependency_graph: dict[str, set[str]] | None = None,
) -> NoneAttributes¶
input_values: list[Value]kind: BlockKindlabel_args: list[str]name: stroperations: list[Operation]output_values: list[Value]parameters: dict[str, Value]
Methods¶
from_block_value¶
@classmethod
def from_block_value(
cls,
block_value: 'BlockValue',
parameters: dict[str, Value] | None = None,
) -> 'Block'Create a Block from a BlockValue.
Parameters:
| Name | Type | Description |
|---|---|---|
block_value | 'BlockValue' | The BlockValue to convert |
parameters | dict[str, Value] | None | Optional parameter bindings |
Returns:
'Block' — A new Block in HIERARCHICAL state
is_affine¶
def is_affine(self) -> boolCheck if block contains no CallBlockOperations.
unbound_parameters¶
def unbound_parameters(self) -> list[str]Return list of unbound parameter names.
BlockKind [source]¶
class BlockKind(Enum)Classification of block structure for pipeline stages.
Attributes¶
AFFINEANALYZEDHIERARCHICAL
BlockValue [source]¶
class BlockValue(Value[BlockType])Represents a subroutine as a function block.
def func_block(a: UInt, b: UInt) -> tuple[UInt]: ...
BlockValue( name=“func_block”, inputs_type={“a”: UIntType(), “b”: UIntType()}, outputs_type=(UIntType(), ), operations=[...], )
Function to BlockValue conversion can be done via func_to_block function.
Each Values in operations are dummy values.
The execution of the BlockValue is corresponding to the BlockOperation.
Constructor¶
def __init__(
self,
type: BlockType = BlockType(),
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, ...] = (),
label_args: list[str] = list(),
input_values: list[Value] = list(),
return_values: list[Value] = list(),
operations: list[Operation] = list(),
) -> NoneAttributes¶
input_values: list[Value]label_args: list[str]name: stroperations: list[Operation]return_values: list[Value]type: BlockType
Methods¶
call¶
def call(self, **kwargs: Value = {}) -> 'CallBlockOperation'Create a CallBlockOperation to call this BlockValue.
Example:
block_value = BlockValue(
name="func_block",
inputs_type={"a": UIntType(), "b": UIntType()},
outputs_type=(UIntType(), ),
operations=[...],
)
a = Value(UIntType())
b = Value(UIntType())
call_op = block_value.call(a=a, b=b)CallBlockOperation [source]¶
class CallBlockOperation(Operation)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
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
ForItemsOperation [source]¶
class ForItemsOperation(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,
operations: list[Operation] = list(),
) -> NoneAttributes¶
key_is_vector: boolkey_vars: list[str]operation_kind: OperationKindoperations: list[Operation]signature: Signaturevalue_var: str
ForOperation [source]¶
class ForOperation(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 = '',
operations: list[Operation] = list(),
) -> NoneAttributes¶
loop_var: stroperation_kind: OperationKindoperations: list[Operation]signature: Signature
IfOperation [source]¶
class IfOperation(Operation)Represents an if-else conditional operation.
Example:
if condition:
true_body
else:
false_bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
true_operations: list[Operation] = list(),
false_operations: list[Operation] = list(),
phi_ops: list[PhiOp] = list(),
) -> NoneAttributes¶
condition: Valuefalse_operations: list[Operation]operation_kind: OperationKindphi_ops: list[PhiOp]signature: Signaturetrue_operations: list[Operation]
InlinePass [source]¶
class InlinePass(Pass[Block, Block])Inline all CallBlockOperations to create an affine block.
This pass recursively inlines function calls while preserving control flow structures (For, If, While).
Input: Block with BlockKind.HIERARCHICAL (may contain CallBlockOperations) Output: Block with BlockKind.AFFINE (no CallBlockOperations)
Attributes¶
name: str
Methods¶
run¶
def run(self, input: Block) -> BlockInline all CallBlockOperations.
Pass [source]¶
class Pass(ABC, Generic[InputT, OutputT])Base class for all compiler passes.
Attributes¶
name: str Human-readable name for this pass.
Methods¶
run¶
def run(self, input: InputT) -> OutputTExecute the pass transformation.
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.
UUIDRemapper [source]¶
class UUIDRemapperClones values and operations with fresh UUIDs and logical_ids.
Used during inlining to create unique identities for values when a block is called multiple times.
Constructor¶
def __init__(self)Attributes¶
logical_id_remap: dict[str, str] Get the mapping from old logical_ids to new logical_ids.uuid_remap: dict[str, str] Get the mapping from old UUIDs to new UUIDs.
Methods¶
clone_operation¶
def clone_operation(self, op: Operation) -> OperationClone an operation with fresh UUIDs for all values.
clone_operations¶
def clone_operations(self, operations: list[Operation]) -> list[Operation]Clone a list of operations with fresh UUIDs.
clone_value¶
def clone_value(self, value: ValueBase) -> ValueBaseClone any value type with a fresh UUID and logical_id.
Handles Value, ArrayValue, TupleValue, and DictValue through the unified ValueBase protocol.
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.
ValueSubstitutor [source]¶
class ValueSubstitutorSubstitutes values in operations using a mapping.
Used during inlining to replace block parameters with caller arguments.
Constructor¶
def __init__(self, value_map: dict[str, ValueBase])Methods¶
substitute_operation¶
def substitute_operation(self, op: Operation) -> OperationSubstitute values in an operation using the value map.
Handles control-flow operations (IfOperation, ForOperation, etc.) by recursing into their nested operation lists and phi_ops.
substitute_value¶
def substitute_value(self, v: ValueBase) -> ValueBaseSubstitute a single value using the value map.
Handles all value types and array elements by substituting their parent_array if needed.
WhileOperation [source]¶
class WhileOperation(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(),
) -> NoneAttributes¶
operation_kind: OperationKindoperations: list[Operation]signature: Signature
qamomile.circuit.transpiler.passes.separate¶
Separate pass: Split a block into quantum and classical segments.
Overview¶
| Class | Description |
|---|---|
ArrayValue | An array of values with shape information. |
BitType | Type representing a classical bit. |
Block | Unified block representation for all pipeline stages. |
ClassicalSegment | A segment of pure classical operations. |
ControlFlowVisitor | Base class for visiting operations with control flow handling. |
DecodeQFixedOperation | Decode measured bits to float (classical operation). |
ExpvalOp | Expectation value operation. |
ExpvalSegment | A segment for expectation value computation. |
ForItemsOperation | Represents iteration over dict/iterable items. |
ForOperation | Represents a for loop operation. |
HybridBoundary | Represents a measurement or encode operation at quantum/classical boundary. |
IfOperation | Represents an if-else conditional operation. |
MeasureQFixedOperation | Measure a quantum fixed-point number. |
MeasureVectorOperation | Measure a vector of qubits. |
MultipleQuantumSegmentsError | Raised when program has multiple quantum segments. |
OperationKind | Classification of operations for classical/quantum separation. |
Pass | Base class for all compiler passes. |
QuantumSegment | A segment of pure quantum operations. |
QubitType | Type representing a quantum bit (qubit). |
ReturnOperation | Explicit return operation marking the end of a block with return values. |
Segment | Base class for separated computation segments. |
SeparatePass | Separate a block into quantum and classical segments. |
SimplifiedProgram | Enforces Classical → Quantum → Classical pattern. |
UIntType | Type representing an unsigned integer. |
Value | A typed value in the IR with SSA-style versioning. |
ValueBase | Protocol defining the common interface for all value types. |
WhileOperation | Represents a while loop operation. |
Classes¶
ArrayValue [source]¶
class ArrayValue(Value[T])An array of values with shape information.
ArrayValue extends Value to represent multi-dimensional arrays of typed values (e.g., qubit registers, parameter vectors).
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, ...] = (),
shape: tuple[Value, ...] = tuple(),
) -> NoneAttributes¶
logical_id: strname: strparams: dict[str, Any]shape: tuple[Value, ...]type: Tuuid: str
Methods¶
next_version¶
def next_version(self) -> ArrayValue[T]Create a new ArrayValue with incremented version, preserving shape.
BitType [source]¶
class BitType(ClassicalTypeMixin, ValueType)Type representing a classical bit.
Block [source]¶
class BlockUnified block representation for all pipeline stages.
Replaces both BlockValue and Graph with a single structure.
The kind field indicates which pipeline stage this block is at.
Constructor¶
def __init__(
self,
name: str = '',
label_args: list[str] = list(),
input_values: list[Value] = list(),
output_values: list[Value] = list(),
operations: list[Operation] = list(),
kind: BlockKind = BlockKind.HIERARCHICAL,
parameters: dict[str, Value] = dict(),
_dependency_graph: dict[str, set[str]] | None = None,
) -> NoneAttributes¶
input_values: list[Value]kind: BlockKindlabel_args: list[str]name: stroperations: list[Operation]output_values: list[Value]parameters: dict[str, Value]
Methods¶
from_block_value¶
@classmethod
def from_block_value(
cls,
block_value: 'BlockValue',
parameters: dict[str, Value] | None = None,
) -> 'Block'Create a Block from a BlockValue.
Parameters:
| Name | Type | Description |
|---|---|---|
block_value | 'BlockValue' | The BlockValue to convert |
parameters | dict[str, Value] | None | Optional parameter bindings |
Returns:
'Block' — A new Block in HIERARCHICAL state
is_affine¶
def is_affine(self) -> boolCheck if block contains no CallBlockOperations.
unbound_parameters¶
def unbound_parameters(self) -> list[str]Return list of unbound parameter names.
ClassicalSegment [source]¶
class ClassicalSegment(Segment)A segment of pure classical operations.
Contains arithmetic, comparisons, and control flow. Will be executed directly in Python.
Constructor¶
def __init__(
self,
operations: list[Operation] = list(),
input_refs: list[str] = list(),
output_refs: list[str] = list(),
) -> NoneAttributes¶
kind: SegmentKind
ControlFlowVisitor [source]¶
class ControlFlowVisitor(ABC)Base class for visiting operations with control flow handling.
Subclasses override visit_operation to define per-operation behavior.
Control flow recursion is handled automatically by the base class.
Example:
class MeasurementCounter(ControlFlowVisitor):
def __init__(self):
self.count = 0
def visit_operation(self, op: Operation) -> None:
if isinstance(op, MeasureOperation):
self.count += 1Methods¶
visit_operation¶
def visit_operation(self, op: Operation) -> NoneProcess a single operation. Override in subclasses.
visit_operations¶
def visit_operations(self, operations: list[Operation]) -> NoneVisit all operations including nested control flow.
DecodeQFixedOperation [source]¶
class DecodeQFixedOperation(Operation)Decode measured bits to float (classical operation).
This operation converts a sequence of classical bits from qubit measurements into a floating-point number using fixed-point encoding.
The decoding formula:
float_value = Σ bit[i] * 2^(int_bits - 1 - i)
For QPE phase (int_bits=0): float_value = 0.b0b1b2... = b00.5 + b10.25 + b2*0.125 + ...
Example:
bits = [1, 0, 1] with int_bits=0
→ 0.101 (binary) = 0.5 + 0.125 = 0.625operands: [ArrayValue of bits (vec[bit])] results: [Float value]
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_bits: int = 0,
int_bits: int = 0,
) -> NoneAttributes¶
int_bits: intnum_bits: intoperation_kind: OperationKindsignature: Signature
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
ExpvalSegment [source]¶
class ExpvalSegment(Segment)A segment for expectation value computation.
Represents computing <psi|H|psi> where psi is the quantum state and H is a Hamiltonian observable.
This segment bridges a quantum circuit (state preparation) to a classical expectation value.
Constructor¶
def __init__(
self,
operations: list[Operation] = list(),
input_refs: list[str] = list(),
output_refs: list[str] = list(),
hamiltonian_value: Value | None = None,
qubits_value: Value | None = None,
result_ref: str = '',
) -> NoneAttributes¶
hamiltonian_value: Value | Nonekind: SegmentKindqubits_value: Value | Noneresult_ref: str
ForItemsOperation [source]¶
class ForItemsOperation(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,
operations: list[Operation] = list(),
) -> NoneAttributes¶
key_is_vector: boolkey_vars: list[str]operation_kind: OperationKindoperations: list[Operation]signature: Signaturevalue_var: str
ForOperation [source]¶
class ForOperation(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 = '',
operations: list[Operation] = list(),
) -> NoneAttributes¶
loop_var: stroperation_kind: OperationKindoperations: list[Operation]signature: Signature
HybridBoundary [source]¶
class HybridBoundaryRepresents a measurement or encode operation at quantum/classical boundary.
These operations bridge quantum and classical segments.
Constructor¶
def __init__(
self,
operation: Operation,
source_segment_index: int,
target_segment_index: int,
value_ref: str,
) -> NoneAttributes¶
operation: Operationsource_segment_index: inttarget_segment_index: intvalue_ref: str
IfOperation [source]¶
class IfOperation(Operation)Represents an if-else conditional operation.
Example:
if condition:
true_body
else:
false_bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
true_operations: list[Operation] = list(),
false_operations: list[Operation] = list(),
phi_ops: list[PhiOp] = list(),
) -> NoneAttributes¶
condition: Valuefalse_operations: list[Operation]operation_kind: OperationKindphi_ops: list[PhiOp]signature: Signaturetrue_operations: list[Operation]
MeasureQFixedOperation [source]¶
class MeasureQFixedOperation(Operation)Measure a quantum fixed-point number.
This operation measures all qubits in a QFixed register and produces a Float result. During transpilation, this is lowered to individual MeasureOperations plus a DecodeQFixedOperation.
operands: [QFixed value (contains qubit_values in params)] results: [Float value]
Encoding:
For QPE phase (int_bits=0): float_value = 0.b0b1b2... = b00.5 + b10.25 + b2*0.125 + ...
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_bits: int = 0,
int_bits: int = 0,
) -> 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
MultipleQuantumSegmentsError [source]¶
class MultipleQuantumSegmentsError(Exception)Raised when program has multiple quantum segments.
Qamomile enforces a single quantum circuit execution pattern:
[Classical Prep] → Quantum Circuit → [Classical Post/Expval]
Your program has multiple quantum segments, suggesting quantum operations that depend on measurement results (JIT compilation not supported).
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
Pass [source]¶
class Pass(ABC, Generic[InputT, OutputT])Base class for all compiler passes.
Attributes¶
name: str Human-readable name for this pass.
Methods¶
run¶
def run(self, input: InputT) -> OutputTExecute the pass transformation.
QuantumSegment [source]¶
class QuantumSegment(Segment)A segment of pure quantum operations.
Contains quantum gates and qubit allocations. Will be emitted to a quantum circuit.
Constructor¶
def __init__(
self,
operations: list[Operation] = list(),
input_refs: list[str] = list(),
output_refs: list[str] = list(),
qubit_values: list[Value] = list(),
num_qubits: int = 0,
) -> NoneAttributes¶
kind: SegmentKindnum_qubits: intqubit_values: list[Value]
QubitType [source]¶
class QubitType(QuantumTypeMixin, ValueType)Type representing a quantum bit (qubit).
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.
Segment [source]¶
class Segment(ABC)Base class for separated computation segments.
Constructor¶
def __init__(
self,
operations: list[Operation] = list(),
input_refs: list[str] = list(),
output_refs: list[str] = list(),
) -> NoneAttributes¶
input_refs: list[str]kind: SegmentKind Return the kind of this segment.operations: list[Operation]output_refs: list[str]
SeparatePass [source]¶
class SeparatePass(Pass[Block, SimplifiedProgram])Separate a block into quantum and classical segments.
This pass:
Materializes return operations (syncs output_values from ReturnOperation)
Splits the operation list into quantum and classical segments
Validates single quantum segment (enforces C→Q→C pattern)
Input: Block (typically ANALYZED or AFFINE) Output: SimplifiedProgram with single quantum segment and optional prep/post
Attributes¶
name: str
Methods¶
run¶
def run(self, input: Block) -> SimplifiedProgramSeparate the block into segments.
SimplifiedProgram [source]¶
class SimplifiedProgramEnforces Classical → Quantum → Classical pattern.
Structure:
[Optional] Classical preprocessing (parameter computation, etc.)
Single quantum segment (REQUIRED)
[Optional] Expval segment OR classical postprocessing
This replaces SeparatedProgram to enforce Qamomile’s execution model: all quantum operations must be in a single quantum circuit.
Constructor¶
def __init__(
self,
quantum: QuantumSegment,
classical_prep: ClassicalSegment | None = None,
expval: ExpvalSegment | None = None,
classical_post: ClassicalSegment | None = None,
boundaries: list[HybridBoundary] = list(),
parameters: dict[str, Value] = dict(),
output_refs: list[str] = list(),
) -> NoneAttributes¶
boundaries: list[HybridBoundary]classical_post: ClassicalSegment | Noneclassical_prep: ClassicalSegment | Noneexpval: ExpvalSegment | Noneoutput_refs: list[str]parameters: dict[str, Value]quantum: QuantumSegment
UIntType [source]¶
class UIntType(ClassicalTypeMixin, ValueType)Type representing an unsigned integer.
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.
ValueBase [source]¶
class ValueBase(Protocol)Protocol defining the common interface for all value types.
This protocol enables:
isinstance(v, ValueBase) checks for any value type
Unified type annotations with ValueBase instead of union types
Duck typing for value operations in transpiler passes
All value types (Value, ArrayValue, TupleValue, DictValue) implement this protocol.
Attributes¶
logical_id: str Identifies the same physical qubit/value across SSA versions.name: str Human-readable name for this value.params: dict[str, Any] Flexible parameter storage for metadata (const, parameter, etc.).uuid: str Unique identifier for this specific value instance.
Methods¶
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) -> ValueBaseCreate a new SSA version with fresh uuid but same logical_id.
parameter_name¶
def parameter_name(self) -> str | NoneGet the parameter name if this is a parameter.
WhileOperation [source]¶
class WhileOperation(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(),
) -> NoneAttributes¶
operation_kind: OperationKindoperations: list[Operation]signature: Signature
qamomile.circuit.transpiler.passes.standard_emit¶
Standard emit pass using GateEmitter protocol.
This module provides StandardEmitPass, a reusable emit pass implementation that uses the GateEmitter protocol for backend-specific gate emission.
Overview¶
| Function | Description |
|---|---|
map_phi_outputs | Register phi output UUIDs to the same physical resources as their source operands. |
remap_static_phi_outputs | Remap phi outputs for a compile-time constant IfOperation. |
resolve_if_condition | Resolve an if-condition to a compile-time boolean. |
| Class | Description |
|---|---|
BinOp | Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, POW). |
BinOpKind | |
CastOperation | Type cast operation for creating aliases over the same quantum resources. |
CompositeDecomposer | Decomposes composite gates into primitive operations. |
CompositeGateEmitter | Protocol for backend-specific CompositeGate emitters. |
CompositeGateOperation | Represents a composite gate (QPE, QFT, etc.) as a single operation. |
CompositeGateType | Registry of known composite gate types. |
ControlledUOperation | Controlled-U operation that applies a unitary block conditionally. |
EmitError | Error during backend code emission. |
EmitPass | Base class for backend-specific emission passes. |
ForItemsOperation | Represents iteration over dict/iterable items. |
ForOperation | Represents a for loop operation. |
GateEmitter | Protocol for backend-specific gate emission. |
GateOperation | |
GateOperationType | |
IfOperation | Represents an if-else conditional operation. |
LoopAnalyzer | Analyzes loop structures to determine emission strategy. |
MeasureOperation | |
MeasureQFixedOperation | Measure a quantum fixed-point number. |
MeasureVectorOperation | Measure a vector of qubits. |
OperandResolutionInfo | Detailed information about a single operand that failed to resolve. |
QInitOperation | Initialize the qubit |
QubitIndexResolutionError | Error when qubit indices cannot be resolved during emission. |
ResolutionFailureReason | Categorizes why qubit index resolution failed. |
ResourceAllocator | Allocates qubit and classical bit indices from operations. |
StandardEmitPass | Standard emit pass implementation using GateEmitter protocol. |
Value | A typed value in the IR with SSA-style versioning. |
ValueResolver | Resolves Value objects to concrete indices or values. |
WhileOperation | Represents a while loop operation. |
Functions¶
map_phi_outputs [source]¶
def map_phi_outputs(
phi_ops: list[Operation],
qubit_map: dict[str, int],
clbit_map: dict[str, int],
resolve_scalar_qubit: Any = None,
) -> NoneRegister phi output UUIDs to the same physical resources as their source operands.
After an if-else block, PhiOp merges values from both branches. The phi output is a new Value with a new UUID that must map to the same physical qubit (or classical bit) as the branch values.
For ArrayValue phi outputs (e.g., qubit arrays), this copies all
composite element keys {source_uuid}_{i} →
{output_uuid}_{i} so that subsequent element accesses on the
phi output resolve to the correct physical qubits.
Parameters:
| Name | Type | Description |
|---|---|---|
phi_ops | list[Operation] | List of phi operations from an IfOperation. |
qubit_map | dict[str, int] | Mapping from UUID/composite key to physical qubit index. |
clbit_map | dict[str, int] | Mapping from UUID to physical classical bit index. |
resolve_scalar_qubit | Any | Optional callback (source, qubit_map) -> int | None for resolving scalar qubit values that are not directly in qubit_map (e.g., array element resolution). When None, ResourceAllocator._resolve_qubit_key is used as fallback. |
Raises:
EmitError— When a quantum PhiOp would merge different or partially unresolved physical qubit resources across branches. This means the qubit identity depends on the runtime branch condition and cannot be statically resolved.
remap_static_phi_outputs [source]¶
def remap_static_phi_outputs(
phi_ops: list[Operation],
condition_value: bool,
qubit_map: dict[str, int],
clbit_map: dict[str, int],
) -> NoneRemap phi outputs for a compile-time constant IfOperation.
When the condition is statically known, the dead branch is never
allocated. Phi outputs are aliased directly to the selected
branch’s source value, bypassing the two-branch merge validation
in map_phi_outputs.
This is the shared implementation used by both the resource allocator (during allocation) and the emit pass (during emission) to ensure scalar and array quantum phi outputs are handled identically.
Parameters:
| Name | Type | Description |
|---|---|---|
phi_ops | list[Operation] | Phi operations from the IfOperation. |
condition_value | bool | The resolved boolean condition. |
qubit_map | dict[str, int] | UUID-to-physical-qubit mapping (mutated in place). |
clbit_map | dict[str, int] | UUID-to-physical-clbit mapping (mutated in place). |
resolve_if_condition [source]¶
def resolve_if_condition(condition: Any, bindings: dict[str, Any]) -> bool | NoneResolve an if-condition to a compile-time boolean.
Checks whether the condition can be statically evaluated at emit time.
Plain Python values (int/bool captured by @qkernel from closure),
constant-folded Values, and Values resolvable via bindings are all
treated as compile-time constants.
Parameters:
| Name | Type | Description |
|---|---|---|
condition | Any | The condition from IfOperation (plain value or Value object). |
bindings | dict[str, Any] | Current variable bindings (uuid → value and/or name → value). |
Returns:
bool | None — True/False for compile-time resolvable conditions,
bool | None — None for runtime conditions that must be dispatched to the
bool | None — backend’s conditional branching protocol.
Classes¶
BinOp [source]¶
class BinOp(BinaryOperationBase)Binary arithmetic operation (ADD, SUB, MUL, DIV, FLOORDIV, POW).
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
kind: BinOpKind | None = None,
) -> NoneAttributes¶
kind: BinOpKind | Noneoperation_kind: OperationKindsignature: Signature
BinOpKind [source]¶
class BinOpKind(enum.Enum)Attributes¶
ADDDIVFLOORDIVMULPOWSUB
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
CompositeDecomposer [source]¶
class CompositeDecomposerDecomposes composite gates into primitive operations.
Provides algorithms for QFT, IQFT, and QPE decomposition that backends can use for fallback when native implementations are unavailable.
Methods¶
iqft_structure¶
@staticmethod
def iqft_structure(n: int) -> list[tuple[str, tuple[int, ...], float | None]]Generate inverse QFT gate sequence.
Parameters:
| Name | Type | Description |
|---|---|---|
n | int | Number of qubits |
Returns:
list[tuple[str, tuple[int, ...], float | None]] — List of (gate_name, qubit_indices, angle) tuples
qft_structure¶
@staticmethod
def qft_structure(n: int) -> list[tuple[str, tuple[int, ...], float | None]]Generate QFT gate sequence.
Parameters:
| Name | Type | Description |
|---|---|---|
n | int | Number of qubits |
Returns:
list[tuple[str, tuple[int, ...], float | None]] — List of (gate_name, qubit_indices, angle) tuples
CompositeGateEmitter [source]¶
class CompositeGateEmitter(Protocol[C])Protocol for backend-specific CompositeGate emitters.
Each backend can implement emitters for specific composite gate types (QPE, QFT, IQFT, etc.) using native backend libraries.
The emitter pattern allows:
Backends to use native implementations when available (e.g., Qiskit QFT)
Fallback to manual decomposition when native is unavailable
Easy addition of new backends without modifying core code
Example:
class QiskitQFTEmitter:
def can_emit(self, gate_type: CompositeGateType) -> bool:
return gate_type in (CompositeGateType.QFT, CompositeGateType.IQFT)
def emit(self, circuit, op, qubit_indices, bindings) -> bool:
from qiskit.circuit.library import QFTGate
qft_gate = QFTGate(len(qubit_indices))
circuit.append(qft_gate, qubit_indices)
return TrueMethods¶
can_emit¶
def can_emit(self, gate_type: CompositeGateType) -> boolCheck if this emitter can handle the given gate type.
Parameters:
| Name | Type | Description |
|---|---|---|
gate_type | CompositeGateType | The CompositeGateType to check |
Returns:
bool — True if this emitter supports native emission for the gate type
emit¶
def emit(
self,
circuit: C,
op: CompositeGateOperation,
qubit_indices: list[int],
bindings: dict[str, Any],
) -> boolEmit the composite gate to the circuit.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | C | The backend-specific circuit to emit to |
op | CompositeGateOperation | The CompositeGateOperation to emit |
qubit_indices | list[int] | Physical qubit indices for the operation |
bindings | dict[str, Any] | Parameter bindings for the operation |
Returns:
bool — True if emission succeeded, False to fall back to manual decomposition
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
ControlledUOperation [source]¶
class ControlledUOperation(Operation)Controlled-U operation that applies a unitary block conditionally.
The operands structure is:
operands[0]: BlockValue (the unitary U to apply)
operands[1:1+num_controls]: Control qubits
operands[1+num_controls:]: Target qubits (arguments to U)
The results structure is:
results[0:num_controls]: Control qubits (returned)
results[num_controls:]: Target qubits (returned from U)
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_controls: int | Value = 1,
power: int | Value = 1,
target_indices: list[Value] | None = None,
controlled_indices: list[Value] | None = None,
) -> NoneAttributes¶
blockGet the BlockValue (unitary U).control_operandsGet the control qubit values.controlled_indices: list[Value] | Nonehas_index_spec: bool Whether target/control positions are specified via index lists.is_symbolic_num_controls: bool Whether num_controls is symbolic (Value) rather than concrete (int).num_controls: int | Valueoperation_kind: OperationKindparam_operandsGet parameter operands (non-qubit, non-block).power: int | Valuesignature: Signaturetarget_indices: list[Value] | Nonetarget_operandsGet the target qubit values (arguments to U).
EmitError [source]¶
class EmitError(QamomileCompileError)Error during backend code emission.
Constructor¶
def __init__(self, message: str, operation: str | None = None)Attributes¶
operation
EmitPass [source]¶
class EmitPass(Pass[SimplifiedProgram, ExecutableProgram[T]], Generic[T])Base class for backend-specific emission passes.
Subclasses implement _emit_quantum_segment() to generate backend-specific quantum circuits.
Input: SimplifiedProgram (enforces C→Q→C pattern) Output: ExecutableProgram with compiled segments
Constructor¶
def __init__(
self,
bindings: dict[str, Any] | None = None,
parameters: list[str] | None = None,
)Initialize with optional parameter bindings.
Parameters:
| Name | Type | Description |
|---|---|---|
bindings | dict[str, Any] | None | Values to bind parameters to. If not provided, parameters must be bound at execution time. |
parameters | list[str] | None | List of parameter names to preserve as backend parameters. |
Attributes¶
bindingsname: strparameters
Methods¶
run¶
def run(self, input: SimplifiedProgram) -> ExecutableProgram[T]Emit backend code from simplified program.
ForItemsOperation [source]¶
class ForItemsOperation(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,
operations: list[Operation] = list(),
) -> NoneAttributes¶
key_is_vector: boolkey_vars: list[str]operation_kind: OperationKindoperations: list[Operation]signature: Signaturevalue_var: str
ForOperation [source]¶
class ForOperation(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 = '',
operations: list[Operation] = list(),
) -> NoneAttributes¶
loop_var: stroperation_kind: OperationKindoperations: list[Operation]signature: Signature
GateEmitter [source]¶
class GateEmitter(Protocol[T])Protocol for backend-specific gate emission.
Each backend implements this protocol to emit individual gates to their circuit representation.
Type parameter T is the backend’s circuit type (e.g., QuantumCircuit).
Methods¶
append_gate¶
def append_gate(self, circuit: T, gate: Any, qubits: list[int]) -> NoneAppend a gate to the circuit.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | T | The circuit to append to |
gate | Any | The gate to append (from circuit_to_gate) |
qubits | list[int] | Target qubit indices |
circuit_to_gate¶
def circuit_to_gate(self, circuit: T, name: str = 'U') -> AnyConvert a circuit to a reusable gate.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | T | The circuit to convert |
name | str | Label for the gate |
Returns:
Any — Backend-specific gate object, or None if not supported
create_circuit¶
def create_circuit(self, num_qubits: int, num_clbits: int) -> TCreate a new empty circuit.
Parameters:
| Name | Type | Description |
|---|---|---|
num_qubits | int | Number of qubits in the circuit |
num_clbits | int | Number of classical bits in the circuit |
Returns:
T — A new backend-specific circuit object
create_parameter¶
def create_parameter(self, name: str) -> AnyCreate a symbolic parameter for the backend.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | Parameter name (e.g., “gammas[0]”) |
Returns:
Any — Backend-specific parameter object
emit_barrier¶
def emit_barrier(self, circuit: T, qubits: list[int]) -> NoneEmit barrier on specified qubits.
emit_ch¶
def emit_ch(self, circuit: T, control: int, target: int) -> NoneEmit controlled-Hadamard gate.
emit_cp¶
def emit_cp(self, circuit: T, control: int, target: int, angle: float | Any) -> NoneEmit controlled-Phase gate.
emit_crx¶
def emit_crx(self, circuit: T, control: int, target: int, angle: float | Any) -> NoneEmit controlled-RX gate.
emit_cry¶
def emit_cry(self, circuit: T, control: int, target: int, angle: float | Any) -> NoneEmit controlled-RY gate.
emit_crz¶
def emit_crz(self, circuit: T, control: int, target: int, angle: float | Any) -> NoneEmit controlled-RZ gate.
emit_cx¶
def emit_cx(self, circuit: T, control: int, target: int) -> NoneEmit CNOT gate.
emit_cy¶
def emit_cy(self, circuit: T, control: int, target: int) -> NoneEmit controlled-Y gate.
emit_cz¶
def emit_cz(self, circuit: T, control: int, target: int) -> NoneEmit CZ gate.
emit_else_start¶
def emit_else_start(self, circuit: T, context: Any) -> NoneStart the else branch.
emit_for_loop_end¶
def emit_for_loop_end(self, circuit: T, context: Any) -> NoneEnd a native for loop context.
emit_for_loop_start¶
def emit_for_loop_start(self, circuit: T, indexset: range) -> AnyStart a native for loop context.
Returns a context manager or loop parameter, depending on backend.
emit_h¶
def emit_h(self, circuit: T, qubit: int) -> NoneEmit Hadamard gate.
emit_if_end¶
def emit_if_end(self, circuit: T, context: Any) -> NoneEnd the if/else block.
emit_if_start¶
def emit_if_start(self, circuit: T, clbit: int, value: int = 1) -> AnyStart a native if context.
Returns context for the if/else block.
emit_measure¶
def emit_measure(self, circuit: T, qubit: int, clbit: int) -> NoneEmit measurement operation.
emit_p¶
def emit_p(self, circuit: T, qubit: int, angle: float | Any) -> NoneEmit Phase gate (P(θ) = diag(1, e^(iθ))).
emit_rx¶
def emit_rx(self, circuit: T, qubit: int, angle: float | Any) -> NoneEmit RX rotation gate.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | T | The circuit to emit to |
qubit | int | Target qubit index |
angle | float | Any | Rotation angle (float or backend parameter) |
emit_ry¶
def emit_ry(self, circuit: T, qubit: int, angle: float | Any) -> NoneEmit RY rotation gate.
emit_rz¶
def emit_rz(self, circuit: T, qubit: int, angle: float | Any) -> NoneEmit RZ rotation gate.
emit_rzz¶
def emit_rzz(self, circuit: T, qubit1: int, qubit2: int, angle: float | Any) -> NoneEmit RZZ gate (exp(-i * θ/2 * Z⊗Z)).
emit_s¶
def emit_s(self, circuit: T, qubit: int) -> NoneEmit S gate (√Z).
emit_sdg¶
def emit_sdg(self, circuit: T, qubit: int) -> NoneEmit S-dagger gate (inverse of S).
emit_swap¶
def emit_swap(self, circuit: T, qubit1: int, qubit2: int) -> NoneEmit SWAP gate.
emit_t¶
def emit_t(self, circuit: T, qubit: int) -> NoneEmit T gate (√S).
emit_tdg¶
def emit_tdg(self, circuit: T, qubit: int) -> NoneEmit T-dagger gate (inverse of T).
emit_toffoli¶
def emit_toffoli(self, circuit: T, control1: int, control2: int, target: int) -> NoneEmit Toffoli (CCX) gate.
emit_while_end¶
def emit_while_end(self, circuit: T, context: Any) -> NoneEnd the while loop context.
emit_while_start¶
def emit_while_start(self, circuit: T, clbit: int, value: int = 1) -> AnyStart a native while loop context.
emit_x¶
def emit_x(self, circuit: T, qubit: int) -> NoneEmit Pauli-X gate.
emit_y¶
def emit_y(self, circuit: T, qubit: int) -> NoneEmit Pauli-Y gate.
emit_z¶
def emit_z(self, circuit: T, qubit: int) -> NoneEmit Pauli-Z gate.
gate_controlled¶
def gate_controlled(self, gate: Any, num_controls: int) -> AnyCreate controlled version of a gate.
Parameters:
| Name | Type | Description |
|---|---|---|
gate | Any | The gate to control |
num_controls | int | Number of control qubits |
Returns:
Any — New controlled gate
gate_power¶
def gate_power(self, gate: Any, power: int) -> AnyCreate gate raised to a power (U^n).
Parameters:
| Name | Type | Description |
|---|---|---|
gate | Any | The gate to raise to a power |
power | int | The power to raise to |
Returns:
Any — New gate representing gate^power
supports_for_loop¶
def supports_for_loop(self) -> boolCheck if backend supports native for loops.
supports_if_else¶
def supports_if_else(self) -> boolCheck if backend supports native if/else.
supports_while_loop¶
def supports_while_loop(self) -> boolCheck if backend supports native while loops.
GateOperation [source]¶
class GateOperation(Operation)Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
gate_type: GateOperationType | None = None,
theta: float | Value | None = None,
) -> NoneAttributes¶
gate_type: GateOperationType | Noneoperation_kind: OperationKindsignature: Signaturetheta: float | Value | None
GateOperationType [source]¶
class GateOperationType(enum.Enum)Attributes¶
CPCXCZHPRXRYRZRZZSSDGSWAPTTDGTOFFOLIXYZ
IfOperation [source]¶
class IfOperation(Operation)Represents an if-else conditional operation.
Example:
if condition:
true_body
else:
false_bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
true_operations: list[Operation] = list(),
false_operations: list[Operation] = list(),
phi_ops: list[PhiOp] = list(),
) -> NoneAttributes¶
condition: Valuefalse_operations: list[Operation]operation_kind: OperationKindphi_ops: list[PhiOp]signature: Signaturetrue_operations: list[Operation]
LoopAnalyzer [source]¶
class LoopAnalyzerAnalyzes loop structures to determine emission strategy.
Determines whether loops should use native backend control flow or be unrolled at emission time.
Methods¶
should_unroll¶
def should_unroll(self, op: ForOperation, bindings: dict[str, Any]) -> boolDetermine if a ForOperation should be unrolled.
Parameters:
| Name | Type | Description |
|---|---|---|
op | ForOperation | The ForOperation to analyze |
bindings | dict[str, Any] | Current variable bindings |
Returns:
bool — True if loop should be unrolled, False for native emission
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): float_value = 0.b0b1b2... = b00.5 + b10.25 + b2*0.125 + ...
Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
num_bits: int = 0,
int_bits: int = 0,
) -> 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
OperandResolutionInfo [source]¶
class OperandResolutionInfoDetailed information about a single operand that failed to resolve.
Constructor¶
def __init__(
self,
operand_name: str,
operand_uuid: str,
is_array_element: bool,
parent_array_name: str | None,
element_indices_names: list[str],
failure_reason: ResolutionFailureReason,
failure_details: str,
) -> NoneAttributes¶
element_indices_names: list[str]failure_details: strfailure_reason: ResolutionFailureReasonis_array_element: booloperand_name: stroperand_uuid: strparent_array_name: str | None
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
QubitIndexResolutionError [source]¶
class QubitIndexResolutionError(EmitError)Error when qubit indices cannot be resolved during emission.
This error provides detailed diagnostic information about why qubit index resolution failed and suggests remediation steps.
Constructor¶
def __init__(
self,
gate_type: str,
operand_infos: list[OperandResolutionInfo],
available_bindings_keys: list[str],
available_qubit_map_keys: list[str],
)Attributes¶
available_bindings_keysavailable_qubit_map_keysgate_typeoperand_infos
ResolutionFailureReason [source]¶
class ResolutionFailureReason(Enum)Categorizes why qubit index resolution failed.
Attributes¶
ARRAY_ELEMENT_NOT_IN_QUBIT_MAPDIRECT_UUID_NOT_FOUNDINDEX_NOT_NUMERICNESTED_ARRAY_RESOLUTION_FAILEDSYMBOLIC_INDEX_NOT_BOUNDUNKNOWN
ResourceAllocator [source]¶
class ResourceAllocatorAllocates qubit and classical bit indices from operations.
This class handles the first pass of circuit emission: determining how many physical qubits and classical bits are needed and mapping Value UUIDs to their physical indices.
New physical indices are assigned via monotonic counters
(_next_qubit_index / _next_clbit_index) so that alias
entries — which reuse an existing physical index — never inflate
the counter. Using len(map) would cause sparse (gapped)
physical indices because alias keys increase the map size without
adding new physical resources.
Constructor¶
def __init__(self) -> NoneMethods¶
allocate¶
def allocate(
self,
operations: list[Operation],
bindings: dict[str, Any] | None = None,
) -> tuple[dict[str, int], dict[str, int]]Allocate qubit and clbit indices for all operations.
Parameters:
| Name | Type | Description |
|---|---|---|
operations | list[Operation] | List of operations to allocate resources for |
bindings | dict[str, Any] | None | Optional variable bindings for resolving dynamic sizes |
Returns:
tuple[dict[str, int], dict[str, int]] — Tuple of (qubit_map, clbit_map) where each maps UUID to index
StandardEmitPass [source]¶
class StandardEmitPass(EmitPass[T], Generic[T])Standard emit pass implementation using GateEmitter protocol.
This class provides the orchestration logic for circuit emission while delegating backend-specific operations to a GateEmitter.
Parameters:
| Name | Type | Description |
|---|---|---|
gate_emitter | GateEmitter[T] | Backend-specific gate emitter |
bindings | dict[str, Any] | None | Parameter bindings for the circuit |
parameters | list[str] | None | List of parameter names to preserve as backend parameters |
composite_emitters | list[CompositeGateEmitter[T]] | None | Optional list of CompositeGateEmitter for native implementations |
Constructor¶
def __init__(
self,
gate_emitter: GateEmitter[T],
bindings: dict[str, Any] | None = None,
parameters: list[str] | None = None,
composite_emitters: list[CompositeGateEmitter[T]] | None = None,
)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.
ValueResolver [source]¶
class ValueResolverResolves Value objects to concrete indices or values.
Handles the mapping from IR Value objects to physical qubit indices, classical values, and parameter names during emission.
Constructor¶
def __init__(self, parameters: set[str] | None = None)Initialize the resolver.
Parameters:
| Name | Type | Description |
|---|---|---|
parameters | set[str] | None | Set of parameter names to preserve as symbolic |
Attributes¶
parameters
Methods¶
get_parameter_key¶
def get_parameter_key(self, value: 'Value', bindings: dict[str, Any]) -> str | NoneGet parameter key if this value should be a symbolic parameter.
Parameters:
| Name | Type | Description |
|---|---|---|
value | 'Value' | The Value to check |
bindings | dict[str, Any] | Current bindings (for resolving array indices) |
Returns:
str | None — Parameter key (e.g., “gammas[0]”) if symbolic, None otherwise
resolve_classical_value¶
def resolve_classical_value(self, value: 'Value', bindings: dict[str, Any]) -> AnyResolve a classical Value to a concrete Python value.
Parameters:
| Name | Type | Description |
|---|---|---|
value | 'Value' | The Value to resolve |
bindings | dict[str, Any] | Current variable bindings |
Returns:
Any — Resolved value (int, float, etc.), or None if cannot resolve
resolve_int_value¶
def resolve_int_value(self, val: Any, bindings: dict[str, Any]) -> int | NoneResolve a value to an integer (for loop bounds, etc.).
Parameters:
| Name | Type | Description |
|---|---|---|
val | Any | The value to resolve |
bindings | dict[str, Any] | Current variable bindings |
Returns:
int | None — Integer value, or None if cannot resolve
resolve_qubit_index¶
def resolve_qubit_index(
self,
v: 'Value',
qubit_map: dict[str, int],
bindings: dict[str, Any],
) -> int | NoneResolve a Value to a physical qubit index.
Parameters:
| Name | Type | Description |
|---|---|---|
v | 'Value' | The Value to resolve |
qubit_map | dict[str, int] | Mapping from UUID to qubit index |
bindings | dict[str, Any] | Current variable bindings |
Returns:
int | None — Physical qubit index, or None if cannot resolve
resolve_qubit_index_detailed¶
def resolve_qubit_index_detailed(
self,
v: 'Value',
qubit_map: dict[str, int],
bindings: dict[str, Any],
) -> QubitResolutionResultResolve a Value to a physical qubit index with detailed failure info.
Parameters:
| Name | Type | Description |
|---|---|---|
v | 'Value' | The Value to resolve |
qubit_map | dict[str, int] | Mapping from UUID to qubit index |
bindings | dict[str, Any] | Current variable bindings |
Returns:
QubitResolutionResult — QubitResolutionResult with success status and either index or failure details
WhileOperation [source]¶
class WhileOperation(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(),
) -> NoneAttributes¶
operation_kind: OperationKindoperations: list[Operation]signature: Signature
qamomile.circuit.transpiler.passes.substitution¶
Substitution pass for replacing QKernel subroutines and composite gate strategies.
This pass allows replacing:
CallBlockOperation targets (QKernel subroutines) with alternative implementations
CompositeGateOperation strategies with specified decomposition strategies
Example:
# Replace a custom oracle with an optimized version
config = SubstitutionConfig(
rules=[
SubstitutionRule(source_name="my_oracle", target=optimized_oracle),
SubstitutionRule(source_name="qft", strategy="approximate"),
]
)
pass = SubstitutionPass(config)
new_block = pass.run(block)Overview¶
| Function | Description |
|---|---|
check_signature_compatibility | Check signature compatibility between two BlockValues. |
create_substitution_pass | Convenience factory for creating a SubstitutionPass. |
| Class | Description |
|---|---|
Block | Unified block representation for all pipeline stages. |
BlockValue | Represents a subroutine as a function block. |
CallBlockOperation | |
CompositeGateOperation | Represents a composite gate (QPE, QFT, etc.) as a single operation. |
ForItemsOperation | Represents iteration over dict/iterable items. |
ForOperation | Represents a for loop operation. |
IfOperation | Represents an if-else conditional operation. |
Pass | Base class for all compiler passes. |
QKernel | Decorator class for Qamomile quantum kernels. |
SignatureCompatibilityError | Error raised when signatures are incompatible during substitution. |
SubstitutionConfig | Configuration for the substitution pass. |
SubstitutionPass | Pass that substitutes CallBlockOperations and CompositeGateOperations. |
SubstitutionRule | A single substitution rule. |
WhileOperation | Represents a while loop operation. |
Functions¶
check_signature_compatibility [source]¶
def check_signature_compatibility(
source: 'BlockValue',
target: 'BlockValue',
strict: bool = True,
) -> tuple[bool, str | None]Check signature compatibility between two BlockValues.
Parameters:
| Name | Type | Description |
|---|---|---|
source | 'BlockValue' | The source BlockValue being replaced |
target | 'BlockValue' | The target BlockValue to replace with |
strict | bool | If True, require exact type matches |
Returns:
bool — Tuple of (is_compatible, error_message).
str | None — If compatible, error_message is None.
create_substitution_pass [source]¶
def create_substitution_pass(
block_replacements: dict[str, 'BlockValue | QKernel'] | None = None,
*,
strategy_overrides: dict[str, str] | None = None,
validate_signatures: bool = True,
) -> SubstitutionPassConvenience factory for creating a SubstitutionPass.
Parameters:
| Name | Type | Description |
|---|---|---|
block_replacements | dict[str, 'BlockValue | QKernel'] | None | Map of block name to replacement |
strategy_overrides | dict[str, str] | None | Map of gate name to strategy name |
validate_signatures | bool | If True, validate signature compatibility when replacing blocks. Default is True. |
Returns:
SubstitutionPass — Configured SubstitutionPass
Example:
pass = create_substitution_pass(
block_replacements={"my_oracle": optimized_oracle},
strategy_overrides={"qft": "approximate", "iqft": "approximate"},
)Classes¶
Block [source]¶
class BlockUnified block representation for all pipeline stages.
Replaces both BlockValue and Graph with a single structure.
The kind field indicates which pipeline stage this block is at.
Constructor¶
def __init__(
self,
name: str = '',
label_args: list[str] = list(),
input_values: list[Value] = list(),
output_values: list[Value] = list(),
operations: list[Operation] = list(),
kind: BlockKind = BlockKind.HIERARCHICAL,
parameters: dict[str, Value] = dict(),
_dependency_graph: dict[str, set[str]] | None = None,
) -> NoneAttributes¶
input_values: list[Value]kind: BlockKindlabel_args: list[str]name: stroperations: list[Operation]output_values: list[Value]parameters: dict[str, Value]
Methods¶
from_block_value¶
@classmethod
def from_block_value(
cls,
block_value: 'BlockValue',
parameters: dict[str, Value] | None = None,
) -> 'Block'Create a Block from a BlockValue.
Parameters:
| Name | Type | Description |
|---|---|---|
block_value | 'BlockValue' | The BlockValue to convert |
parameters | dict[str, Value] | None | Optional parameter bindings |
Returns:
'Block' — A new Block in HIERARCHICAL state
is_affine¶
def is_affine(self) -> boolCheck if block contains no CallBlockOperations.
unbound_parameters¶
def unbound_parameters(self) -> list[str]Return list of unbound parameter names.
BlockValue [source]¶
class BlockValue(Value[BlockType])Represents a subroutine as a function block.
def func_block(a: UInt, b: UInt) -> tuple[UInt]: ...
BlockValue( name=“func_block”, inputs_type={“a”: UIntType(), “b”: UIntType()}, outputs_type=(UIntType(), ), operations=[...], )
Function to BlockValue conversion can be done via func_to_block function.
Each Values in operations are dummy values.
The execution of the BlockValue is corresponding to the BlockOperation.
Constructor¶
def __init__(
self,
type: BlockType = BlockType(),
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, ...] = (),
label_args: list[str] = list(),
input_values: list[Value] = list(),
return_values: list[Value] = list(),
operations: list[Operation] = list(),
) -> NoneAttributes¶
input_values: list[Value]label_args: list[str]name: stroperations: list[Operation]return_values: list[Value]type: BlockType
Methods¶
call¶
def call(self, **kwargs: Value = {}) -> 'CallBlockOperation'Create a CallBlockOperation to call this BlockValue.
Example:
block_value = BlockValue(
name="func_block",
inputs_type={"a": UIntType(), "b": UIntType()},
outputs_type=(UIntType(), ),
operations=[...],
)
a = Value(UIntType())
b = Value(UIntType())
call_op = block_value.call(a=a, b=b)CallBlockOperation [source]¶
class CallBlockOperation(Operation)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
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.
ForItemsOperation [source]¶
class ForItemsOperation(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,
operations: list[Operation] = list(),
) -> NoneAttributes¶
key_is_vector: boolkey_vars: list[str]operation_kind: OperationKindoperations: list[Operation]signature: Signaturevalue_var: str
ForOperation [source]¶
class ForOperation(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 = '',
operations: list[Operation] = list(),
) -> NoneAttributes¶
loop_var: stroperation_kind: OperationKindoperations: list[Operation]signature: Signature
IfOperation [source]¶
class IfOperation(Operation)Represents an if-else conditional operation.
Example:
if condition:
true_body
else:
false_bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
true_operations: list[Operation] = list(),
false_operations: list[Operation] = list(),
phi_ops: list[PhiOp] = list(),
) -> NoneAttributes¶
condition: Valuefalse_operations: list[Operation]operation_kind: OperationKindphi_ops: list[PhiOp]signature: Signaturetrue_operations: list[Operation]
Pass [source]¶
class Pass(ABC, Generic[InputT, OutputT])Base class for all compiler passes.
Attributes¶
name: str Human-readable name for this pass.
Methods¶
run¶
def run(self, input: InputT) -> OutputTExecute the pass transformation.
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) # 2SignatureCompatibilityError [source]¶
class SignatureCompatibilityError(Exception)Error raised when signatures are incompatible during substitution.
SubstitutionConfig [source]¶
class SubstitutionConfigConfiguration for the substitution pass.
Constructor¶
def __init__(self, rules: list[SubstitutionRule] = list()) -> NoneAttributes¶
rules: list[SubstitutionRule]
Methods¶
get_rule_for_name¶
def get_rule_for_name(self, name: str) -> SubstitutionRule | NoneFind a rule matching the given name.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | Name to look up |
Returns:
SubstitutionRule | None — Matching SubstitutionRule or None
SubstitutionPass [source]¶
class SubstitutionPass(Pass[Block, Block])Pass that substitutes CallBlockOperations and CompositeGateOperations.
This pass traverses the block and applies substitution rules:
For CallBlockOperation: replaces the block reference with the target
For CompositeGateOperation: sets the strategy_name field
The pass preserves the block structure and only modifies matching operations.
Input: Block (any kind) Output: Block with substitutions applied (same kind as input)
Constructor¶
def __init__(self, config: SubstitutionConfig) -> NoneInitialize the pass with configuration.
Parameters:
| Name | Type | Description |
|---|---|---|
config | SubstitutionConfig | Substitution configuration with rules |
Attributes¶
name: str Return pass name.
Methods¶
run¶
def run(self, input: Block) -> BlockApply substitutions to the block.
Parameters:
| Name | Type | Description |
|---|---|---|
input | Block | Block to transform |
Returns:
Block — Block with substitutions applied
SubstitutionRule [source]¶
class SubstitutionRuleA single substitution rule.
Constructor¶
def __init__(
self,
source_name: str,
target: 'BlockValue | QKernel | None' = None,
strategy: str | None = None,
validate_signature: bool = True,
) -> NoneAttributes¶
source_name: strstrategy: str | Nonetarget: ‘BlockValue | QKernel | None’validate_signature: bool
WhileOperation [source]¶
class WhileOperation(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(),
) -> NoneAttributes¶
operation_kind: OperationKindoperations: list[Operation]signature: Signature
qamomile.circuit.transpiler.passes.validate_while¶
WhileOperation contract validation pass.
Validates that all WhileOperation conditions are measurement-backed
Bit values. A condition is measurement-backed if it originates from
qmc.measure() either directly or through phi-merged branches where
every leaf is itself measurement-backed (e.g. if sel: bit = measure(q1) else: bit = measure(q2)).
All other while patterns (classical variables, constants, comparison
results, non-measurement branch leaves) are rejected with a clear
ValidationError before reaching backend-specific emit passes.
This pass runs after lower_compile_time_ifs and before analyze.
Overview¶
| Class | Description |
|---|---|
BitType | Type representing a classical bit. |
Block | Unified block representation for all pipeline stages. |
ForItemsOperation | Represents iteration over dict/iterable items. |
ForOperation | Represents a for loop operation. |
IfOperation | Represents an if-else conditional operation. |
MeasureOperation | |
Pass | Base class for all compiler passes. |
PhiOp | SSA Phi function: merge point after conditional branch. |
ValidateWhileContractPass | Validates that all WhileOperation conditions are measurement-backed. |
ValidationError | Error during validation (e.g., non-classical I/O). |
Value | A typed value in the IR with SSA-style versioning. |
WhileOperation | Represents a while loop operation. |
Classes¶
BitType [source]¶
class BitType(ClassicalTypeMixin, ValueType)Type representing a classical bit.
Block [source]¶
class BlockUnified block representation for all pipeline stages.
Replaces both BlockValue and Graph with a single structure.
The kind field indicates which pipeline stage this block is at.
Constructor¶
def __init__(
self,
name: str = '',
label_args: list[str] = list(),
input_values: list[Value] = list(),
output_values: list[Value] = list(),
operations: list[Operation] = list(),
kind: BlockKind = BlockKind.HIERARCHICAL,
parameters: dict[str, Value] = dict(),
_dependency_graph: dict[str, set[str]] | None = None,
) -> NoneAttributes¶
input_values: list[Value]kind: BlockKindlabel_args: list[str]name: stroperations: list[Operation]output_values: list[Value]parameters: dict[str, Value]
Methods¶
from_block_value¶
@classmethod
def from_block_value(
cls,
block_value: 'BlockValue',
parameters: dict[str, Value] | None = None,
) -> 'Block'Create a Block from a BlockValue.
Parameters:
| Name | Type | Description |
|---|---|---|
block_value | 'BlockValue' | The BlockValue to convert |
parameters | dict[str, Value] | None | Optional parameter bindings |
Returns:
'Block' — A new Block in HIERARCHICAL state
is_affine¶
def is_affine(self) -> boolCheck if block contains no CallBlockOperations.
unbound_parameters¶
def unbound_parameters(self) -> list[str]Return list of unbound parameter names.
ForItemsOperation [source]¶
class ForItemsOperation(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,
operations: list[Operation] = list(),
) -> NoneAttributes¶
key_is_vector: boolkey_vars: list[str]operation_kind: OperationKindoperations: list[Operation]signature: Signaturevalue_var: str
ForOperation [source]¶
class ForOperation(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 = '',
operations: list[Operation] = list(),
) -> NoneAttributes¶
loop_var: stroperation_kind: OperationKindoperations: list[Operation]signature: Signature
IfOperation [source]¶
class IfOperation(Operation)Represents an if-else conditional operation.
Example:
if condition:
true_body
else:
false_bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
true_operations: list[Operation] = list(),
false_operations: list[Operation] = list(),
phi_ops: list[PhiOp] = list(),
) -> NoneAttributes¶
condition: Valuefalse_operations: list[Operation]operation_kind: OperationKindphi_ops: list[PhiOp]signature: Signaturetrue_operations: list[Operation]
MeasureOperation [source]¶
class MeasureOperation(Operation)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
operation_kind: OperationKindsignature: Signature
Pass [source]¶
class Pass(ABC, Generic[InputT, OutputT])Base class for all compiler passes.
Attributes¶
name: str Human-readable name for this pass.
Methods¶
run¶
def run(self, input: InputT) -> OutputTExecute the pass transformation.
PhiOp [source]¶
class PhiOp(Operation)SSA Phi function: merge point after conditional branch.
This operation selects one of two values based on a condition. Used to merge values from different branches of an if-else statement.
Example:
if condition:
x = x + 1 # true_value
else:
x = x + 2 # false_value
# x is now PhiOp(condition, true_value, false_value)Constructor¶
def __init__(self, operands: list[Value] = list(), results: list[Value] = list()) -> NoneAttributes¶
condition: Valuefalse_value: Valueoperation_kind: OperationKindoutput: Valuesignature: Signaturetrue_value: Value
ValidateWhileContractPass [source]¶
class ValidateWhileContractPass(Pass[Block, Block])Validates that all WhileOperation conditions are measurement-backed.
Builds a producer map (result UUID → producing Operation instance) and checks every WhileOperation operand against it. A valid condition must be:
A
ValuewithBitTypeMeasurement-backed: produced by
MeasureOperationdirectly, or byIfOperation/PhiOpwhere every reachable leaf source is itself measurement-backed.
Both operands[0] (initial condition) and operands[1]
(loop-carried condition) are validated.
Raises ValidationError for any non-measurement while pattern.
Attributes¶
name: str
Methods¶
run¶
def run(self, block: Block) -> BlockValidate all WhileOperations and return block unchanged.
ValidationError [source]¶
class ValidationError(QamomileCompileError)Error during validation (e.g., non-classical I/O).
Constructor¶
def __init__(self, message: str, value_name: str | None = None)Attributes¶
value_name
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.
WhileOperation [source]¶
class WhileOperation(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(),
) -> NoneAttributes¶
operation_kind: OperationKindoperations: list[Operation]signature: Signature
qamomile.circuit.transpiler.passes.value_mapping¶
Value mapping utilities for IR transformations.
Overview¶
| Class | Description |
|---|---|
ArrayValue | An array of values with shape information. |
DictValue | A dictionary mapping keys to values. |
ForItemsOperation | Represents iteration over dict/iterable items. |
ForOperation | Represents a for loop operation. |
GateOperation | |
IfOperation | Represents an if-else conditional operation. |
TupleValue | A tuple of values for structured data. |
UUIDRemapper | Clones values and operations with fresh UUIDs and logical_ids. |
Value | A typed value in the IR with SSA-style versioning. |
ValueBase | Protocol defining the common interface for all value types. |
ValueSubstitutor | Substitutes values in operations using a mapping. |
WhileOperation | Represents a while loop operation. |
Classes¶
ArrayValue [source]¶
class ArrayValue(Value[T])An array of values with shape information.
ArrayValue extends Value to represent multi-dimensional arrays of typed values (e.g., qubit registers, parameter vectors).
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, ...] = (),
shape: tuple[Value, ...] = tuple(),
) -> NoneAttributes¶
logical_id: strname: strparams: dict[str, Any]shape: tuple[Value, ...]type: Tuuid: str
Methods¶
next_version¶
def next_version(self) -> ArrayValue[T]Create a new ArrayValue with incremented version, preserving shape.
DictValue [source]¶
class DictValueA dictionary mapping keys to values.
Used for structured data like Ising coefficients {(i, j): Jij}. Entries are stored as a list of (key, value) pairs for consistent ordering. Implements the ValueBase protocol for unified handling.
Constructor¶
def __init__(
self,
name: str,
entries: list[tuple[TupleValue | Value, Value]] = list(),
params: dict[str, Any] = dict(),
uuid: str = (lambda: str(uuid.uuid4()))(),
logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> NoneAttributes¶
entries: list[tuple[TupleValue | Value, Value]]logical_id: strname: strparams: dict[str, Any]type: DictType Return type interface for compatibility with Value.uuid: str
Methods¶
is_constant¶
def is_constant(self) -> boolCheck if all entries have constant values.
is_parameter¶
def is_parameter(self) -> boolCheck if this dict is a parameter (bound at transpile time).
next_version¶
def next_version(self) -> DictValueCreate a new DictValue with a fresh uuid but same logical_id.
parameter_name¶
def parameter_name(self) -> str | NoneGet the parameter name if this is a parameter.
ForItemsOperation [source]¶
class ForItemsOperation(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,
operations: list[Operation] = list(),
) -> NoneAttributes¶
key_is_vector: boolkey_vars: list[str]operation_kind: OperationKindoperations: list[Operation]signature: Signaturevalue_var: str
ForOperation [source]¶
class ForOperation(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 = '',
operations: list[Operation] = list(),
) -> NoneAttributes¶
loop_var: stroperation_kind: OperationKindoperations: list[Operation]signature: Signature
GateOperation [source]¶
class GateOperation(Operation)Constructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
gate_type: GateOperationType | None = None,
theta: float | Value | None = None,
) -> NoneAttributes¶
gate_type: GateOperationType | Noneoperation_kind: OperationKindsignature: Signaturetheta: float | Value | None
IfOperation [source]¶
class IfOperation(Operation)Represents an if-else conditional operation.
Example:
if condition:
true_body
else:
false_bodyConstructor¶
def __init__(
self,
operands: list[Value] = list(),
results: list[Value] = list(),
true_operations: list[Operation] = list(),
false_operations: list[Operation] = list(),
phi_ops: list[PhiOp] = list(),
) -> NoneAttributes¶
condition: Valuefalse_operations: list[Operation]operation_kind: OperationKindphi_ops: list[PhiOp]signature: Signaturetrue_operations: list[Operation]
TupleValue [source]¶
class TupleValueA tuple of values for structured data.
Used for structured data like Ising model indices (i, j). Implements the ValueBase protocol for unified handling.
Constructor¶
def __init__(
self,
name: str,
elements: tuple[Value, ...] = tuple(),
params: dict[str, Any] = dict(),
uuid: str = (lambda: str(uuid.uuid4()))(),
logical_id: str = (lambda: str(uuid.uuid4()))(),
) -> NoneAttributes¶
elements: tuple[Value, ...]logical_id: strname: strparams: dict[str, Any]uuid: str
Methods¶
is_constant¶
def is_constant(self) -> boolCheck if all elements are constants.
is_parameter¶
def is_parameter(self) -> boolCheck if this tuple is a parameter (has symbolic elements).
next_version¶
def next_version(self) -> TupleValueCreate a new TupleValue with a fresh uuid but same logical_id.
parameter_name¶
def parameter_name(self) -> str | NoneGet the parameter name if this is a parameter.
UUIDRemapper [source]¶
class UUIDRemapperClones values and operations with fresh UUIDs and logical_ids.
Used during inlining to create unique identities for values when a block is called multiple times.
Constructor¶
def __init__(self)Attributes¶
logical_id_remap: dict[str, str] Get the mapping from old logical_ids to new logical_ids.uuid_remap: dict[str, str] Get the mapping from old UUIDs to new UUIDs.
Methods¶
clone_operation¶
def clone_operation(self, op: Operation) -> OperationClone an operation with fresh UUIDs for all values.
clone_operations¶
def clone_operations(self, operations: list[Operation]) -> list[Operation]Clone a list of operations with fresh UUIDs.
clone_value¶
def clone_value(self, value: ValueBase) -> ValueBaseClone any value type with a fresh UUID and logical_id.
Handles Value, ArrayValue, TupleValue, and DictValue through the unified ValueBase protocol.
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.
ValueBase [source]¶
class ValueBase(Protocol)Protocol defining the common interface for all value types.
This protocol enables:
isinstance(v, ValueBase) checks for any value type
Unified type annotations with ValueBase instead of union types
Duck typing for value operations in transpiler passes
All value types (Value, ArrayValue, TupleValue, DictValue) implement this protocol.
Attributes¶
logical_id: str Identifies the same physical qubit/value across SSA versions.name: str Human-readable name for this value.params: dict[str, Any] Flexible parameter storage for metadata (const, parameter, etc.).uuid: str Unique identifier for this specific value instance.
Methods¶
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) -> ValueBaseCreate a new SSA version with fresh uuid but same logical_id.
parameter_name¶
def parameter_name(self) -> str | NoneGet the parameter name if this is a parameter.
ValueSubstitutor [source]¶
class ValueSubstitutorSubstitutes values in operations using a mapping.
Used during inlining to replace block parameters with caller arguments.
Constructor¶
def __init__(self, value_map: dict[str, ValueBase])Methods¶
substitute_operation¶
def substitute_operation(self, op: Operation) -> OperationSubstitute values in an operation using the value map.
Handles control-flow operations (IfOperation, ForOperation, etc.) by recursing into their nested operation lists and phi_ops.
substitute_value¶
def substitute_value(self, v: ValueBase) -> ValueBaseSubstitute a single value using the value map.
Handles all value types and array elements by substituting their parent_array if needed.
WhileOperation [source]¶
class WhileOperation(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(),
) -> NoneAttributes¶
operation_kind: OperationKindoperations: list[Operation]signature: Signature
qamomile.circuit.transpiler.quantum_executor¶
Abstract base class for quantum backend execution.
This module provides a simple interface for implementing custom quantum executors. Executors bridge Qamomile’s compiled circuits to various quantum backends including local simulators and cloud quantum devices.
Basic Example (Local Simulator): from qiskit_aer import AerSimulator
class MyExecutor(QuantumExecutor[QuantumCircuit]):
def __init__(self):
self.backend = AerSimulator()
def execute(self, circuit: QuantumCircuit, shots: int) -> dict[str, int]:
from qiskit import transpile
if circuit.num_clbits == 0:
circuit = circuit.copy()
circuit.measure_all()
transpiled = transpile(circuit, self.backend)
job = self.backend.run(transpiled, shots=shots)
return job.result().get_counts()Cloud Backend Example (IBM Quantum): from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2
class IBMQuantumExecutor(QuantumExecutor[QuantumCircuit]):
def __init__(self, backend_name: str = "ibm_brisbane"):
self.service = QiskitRuntimeService()
self.backend_name = backend_name
def execute(self, circuit: QuantumCircuit, shots: int) -> dict[str, int]:
from qiskit.transpiler.preset_passmanagers import (
generate_preset_pass_manager,
)
backend = self.service.backend(self.backend_name)
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
transpiled = pm.run(circuit)
sampler = SamplerV2(backend)
job = sampler.run([transpiled], shots=shots)
return job.result()[0].data.meas.get_counts()
def bind_parameters(self, circuit, bindings, metadata):
# Use helper method for easy conversion
return circuit.assign_parameters(metadata.to_binding_dict(bindings))Bitstring Format:
The execute() method returns dict[str, int] where keys are bitstrings in big-endian format (leftmost bit = highest qubit index). Example: {“011”: 512, “100”: 488} for 3 qubits
Overview¶
| Class | Description |
|---|---|
ParameterMetadata | Metadata for all parameters in a compiled segment. |
QuantumExecutor | Abstract base class for quantum backend execution. |
Classes¶
ParameterMetadata [source]¶
class ParameterMetadataMetadata for all parameters in a compiled segment.
Tracks parameter information for runtime binding.
Constructor¶
def __init__(self, parameters: list[ParameterInfo] = list()) -> NoneAttributes¶
parameters: list[ParameterInfo]
Methods¶
get_array_names¶
def get_array_names(self) -> set[str]Get unique array/scalar parameter names.
get_ordered_params¶
def get_ordered_params(self) -> list[Any]Get backend parameter objects in definition order.
Useful for backends that require positional parameter binding (e.g., QURI Parts).
Returns:
list[Any] — List of backend_param objects in the order they were defined.
Example:
# For QURI Parts that uses positional binding:
param_values = [bindings[p.name] for p in metadata.parameters]
bound_circuit = circuit.bind_parameters(param_values)get_param_by_name¶
def get_param_by_name(self, name: str) -> ParameterInfo | NoneGet parameter info by full name.
to_binding_dict¶
def to_binding_dict(self, bindings: dict[str, Any]) -> dict[Any, Any]Convert indexed bindings to backend parameter bindings.
Transforms user-provided bindings (with indexed names like “gammas[0]”) into a dictionary mapping backend parameter objects to values. Useful for backends that use dict-based parameter binding (e.g., Qiskit).
Parameters:
| Name | Type | Description |
|---|---|---|
bindings | dict[str, Any] | Dictionary mapping parameter names to values. e.g., {“gammas[0]”: 0.1, “gammas[1]”: 0.2, “theta”: 0.5} |
Returns:
dict[Any, Any] — Dictionary mapping backend_param objects to values.
Example:
# For Qiskit that uses dict-based binding:
qiskit_bindings = metadata.to_binding_dict(bindings)
bound_circuit = circuit.assign_parameters(qiskit_bindings)QuantumExecutor [source]¶
class QuantumExecutor(ABC, Generic[T])Abstract base class for quantum backend execution.
To implement a custom executor:
execute() [Required] Execute circuit and return bitstring counts as dict[str, int]. Keys are bitstrings in big-endian format (e.g., “011” means q2=0, q1=1, q0=1).
bind_parameters() [Optional] Bind parameter values to parametric circuits. Override if your executor supports parametric circuits (e.g., QAOA variational circuits). Use ParameterMetadata.to_binding_dict() for easy conversion.
estimate() [Optional] Compute expectation values <psi|H|psi>. Override if your executor supports estimation primitives (e.g., Qiskit Estimator, QURI Parts).
Example (Minimal): class MyExecutor(QuantumExecutor[QuantumCircuit]): def init(self): from qiskit_aer import AerSimulator self.backend = AerSimulator()
def execute(self, circuit, shots):
from qiskit import transpile
if circuit.num_clbits == 0:
circuit = circuit.copy()
circuit.measure_all()
transpiled = transpile(circuit, self.backend)
return self.backend.run(transpiled, shots=shots).result().get_counts()Example (With Parameter Binding): def bind_parameters(self, circuit, bindings, metadata): # metadata.to_binding_dict() converts indexed names to backend params return circuit.assign_parameters(metadata.to_binding_dict(bindings))
Methods¶
bind_parameters¶
def bind_parameters(
self,
circuit: T,
bindings: dict[str, Any],
parameter_metadata: ParameterMetadata,
) -> TBind parameter values to the circuit.
Default implementation returns the circuit unchanged. Override for backends that support parametric circuits.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | T | The parameterized circuit |
bindings | dict[str, Any] | Dict mapping parameter names (indexed format) to values. e.g., {“gammas[0]”: 0.1, “gammas[1]”: 0.2} |
parameter_metadata | ParameterMetadata | Metadata about circuit parameters |
Returns:
T — New circuit with parameters bound
estimate¶
def estimate(
self,
circuit: T,
hamiltonian: 'qm_o.Hamiltonian',
params: Sequence[float] | None = None,
) -> floatEstimate the expectation value of a Hamiltonian.
This method computes <psi|H|psi> where psi is the quantum state prepared by the circuit and H is the Hamiltonian.
Backends can override this method to provide optimized implementations using their native estimator primitives.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | T | The quantum circuit (state preparation ansatz) |
hamiltonian | 'qm_o.Hamiltonian' | The qamomile.observable.Hamiltonian to measure |
params | Sequence[float] | None | Optional parameter values for parametric circuits |
Returns:
float — The estimated expectation value
Raises:
NotImplementedError— If the executor does not support estimation
execute¶
def execute(self, circuit: T, shots: int) -> dict[str, int]Execute the circuit and return bitstring counts.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | T | The quantum circuit to execute |
shots | int | Number of measurement shots |
Returns:
dict[str, int] — Dictionary mapping bitstrings to counts.
dict[str, int] — {“00”: 512, “11”: 512}
qamomile.circuit.transpiler.result¶
EmitResult data structures for transpiler output.
Overview¶
| Class | Description |
|---|---|
ClassicalMapping | Maps a logical Value to a classical value or measurement result slot. |
EmitResult | Structured result from Transpiler.emit(). |
OutputMapping | Maps Graph output position to physical resource. |
QubitMapping | Maps a logical Value to a physical qubit index. |
Classes¶
ClassicalMapping [source]¶
class ClassicalMappingMaps a logical Value to a classical value or measurement result slot.
Constructor¶
def __init__(
self,
value_uuid: str,
value_name: str,
value: Union[int, float, bool, None],
clbit_index: Union[int, None] = None,
) -> NoneAttributes¶
clbit_index: Union[int, None]value: Union[int, float, bool, None]value_name: strvalue_uuid: str
EmitResult [source]¶
class EmitResult(Generic[T])Structured result from Transpiler.emit().
Contains the backend-specific circuit along with mapping information that tracks the correspondence between logical Values and physical qubit/clbit indices.
Constructor¶
def __init__(
self,
circuit: T,
qubit_mappings: list[QubitMapping],
classical_mappings: list[ClassicalMapping],
output_mappings: list[OutputMapping],
num_qubits: int,
num_clbits: int = 0,
) -> NoneAttributes¶
circuit: Tclassical_mappings: list[ClassicalMapping]num_clbits: intnum_qubits: intoutput_mappings: list[OutputMapping]qubit_mappings: list[QubitMapping]
Methods¶
get_measurement_clbit_indices¶
def get_measurement_clbit_indices(self) -> list[int]Get clbit indices for all measurement outputs in order.
get_output_mapping_by_index¶
def get_output_mapping_by_index(self, index: int) -> Union[OutputMapping, None]Get output mapping by tuple index.
get_output_qubit_indices¶
def get_output_qubit_indices(self) -> list[int]Get qubit indices for all quantum outputs in order.
get_qubit_index_by_name¶
def get_qubit_index_by_name(self, name: str) -> Union[int, None]Look up qubit index by Value name.
OutputMapping [source]¶
class OutputMappingMaps Graph output position to physical resource.
Constructor¶
def __init__(
self,
output_index: int,
value_uuid: str,
value_name: str,
kind: str,
physical_index: Union[int, None],
classical_value: Union[int, float, bool, None] = None,
) -> NoneAttributes¶
classical_value: Union[int, float, bool, None]kind: stroutput_index: intphysical_index: Union[int, None]value_name: strvalue_uuid: str
QubitMapping [source]¶
class QubitMappingMaps a logical Value to a physical qubit index.
Constructor¶
def __init__(self, value_uuid: str, value_name: str, qubit_index: int) -> NoneAttributes¶
qubit_index: intvalue_name: strvalue_uuid: str
qamomile.circuit.transpiler.segments¶
Data structures for separated quantum/classical segments.
Overview¶
| Class | Description |
|---|---|
ClassicalSegment | A segment of pure classical operations. |
ExpvalSegment | A segment for expectation value computation. |
HybridBoundary | Represents a measurement or encode operation at quantum/classical boundary. |
MultipleQuantumSegmentsError | Raised when program has multiple quantum segments. |
QuantumSegment | A segment of pure quantum operations. |
Segment | Base class for separated computation segments. |
SegmentKind | Type of computation segment. |
SimplifiedProgram | Enforces Classical → Quantum → Classical pattern. |
Value | A typed value in the IR with SSA-style versioning. |
Classes¶
ClassicalSegment [source]¶
class ClassicalSegment(Segment)A segment of pure classical operations.
Contains arithmetic, comparisons, and control flow. Will be executed directly in Python.
Constructor¶
def __init__(
self,
operations: list[Operation] = list(),
input_refs: list[str] = list(),
output_refs: list[str] = list(),
) -> NoneAttributes¶
kind: SegmentKind
ExpvalSegment [source]¶
class ExpvalSegment(Segment)A segment for expectation value computation.
Represents computing <psi|H|psi> where psi is the quantum state and H is a Hamiltonian observable.
This segment bridges a quantum circuit (state preparation) to a classical expectation value.
Constructor¶
def __init__(
self,
operations: list[Operation] = list(),
input_refs: list[str] = list(),
output_refs: list[str] = list(),
hamiltonian_value: Value | None = None,
qubits_value: Value | None = None,
result_ref: str = '',
) -> NoneAttributes¶
hamiltonian_value: Value | Nonekind: SegmentKindqubits_value: Value | Noneresult_ref: str
HybridBoundary [source]¶
class HybridBoundaryRepresents a measurement or encode operation at quantum/classical boundary.
These operations bridge quantum and classical segments.
Constructor¶
def __init__(
self,
operation: Operation,
source_segment_index: int,
target_segment_index: int,
value_ref: str,
) -> NoneAttributes¶
operation: Operationsource_segment_index: inttarget_segment_index: intvalue_ref: str
MultipleQuantumSegmentsError [source]¶
class MultipleQuantumSegmentsError(Exception)Raised when program has multiple quantum segments.
Qamomile enforces a single quantum circuit execution pattern:
[Classical Prep] → Quantum Circuit → [Classical Post/Expval]
Your program has multiple quantum segments, suggesting quantum operations that depend on measurement results (JIT compilation not supported).
QuantumSegment [source]¶
class QuantumSegment(Segment)A segment of pure quantum operations.
Contains quantum gates and qubit allocations. Will be emitted to a quantum circuit.
Constructor¶
def __init__(
self,
operations: list[Operation] = list(),
input_refs: list[str] = list(),
output_refs: list[str] = list(),
qubit_values: list[Value] = list(),
num_qubits: int = 0,
) -> NoneAttributes¶
kind: SegmentKindnum_qubits: intqubit_values: list[Value]
Segment [source]¶
class Segment(ABC)Base class for separated computation segments.
Constructor¶
def __init__(
self,
operations: list[Operation] = list(),
input_refs: list[str] = list(),
output_refs: list[str] = list(),
) -> NoneAttributes¶
input_refs: list[str]kind: SegmentKind Return the kind of this segment.operations: list[Operation]output_refs: list[str]
SegmentKind [source]¶
class SegmentKind(Enum)Type of computation segment.
Attributes¶
CLASSICALEXPVALQUANTUM
SimplifiedProgram [source]¶
class SimplifiedProgramEnforces Classical → Quantum → Classical pattern.
Structure:
[Optional] Classical preprocessing (parameter computation, etc.)
Single quantum segment (REQUIRED)
[Optional] Expval segment OR classical postprocessing
This replaces SeparatedProgram to enforce Qamomile’s execution model: all quantum operations must be in a single quantum circuit.
Constructor¶
def __init__(
self,
quantum: QuantumSegment,
classical_prep: ClassicalSegment | None = None,
expval: ExpvalSegment | None = None,
classical_post: ClassicalSegment | None = None,
boundaries: list[HybridBoundary] = list(),
parameters: dict[str, Value] = dict(),
output_refs: list[str] = list(),
) -> NoneAttributes¶
boundaries: list[HybridBoundary]classical_post: ClassicalSegment | Noneclassical_prep: ClassicalSegment | Noneexpval: ExpvalSegment | Noneoutput_refs: list[str]parameters: dict[str, Value]quantum: QuantumSegment
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.
qamomile.circuit.transpiler.transpiler¶
Base transpiler class for backend-specific compilation.
Overview¶
| Class | Description |
|---|---|
AffineValidationPass | Validate affine type semantics at IR level. |
AnalyzePass | Analyze and validate an affine block. |
Block | Unified block representation for all pipeline stages. |
BlockKind | Classification of block structure for pipeline stages. |
CompileTimeIfLoweringPass | Lowers compile-time resolvable IfOperations before separation. |
ConstantFoldingPass | Evaluates constant expressions at compile time. |
DecompositionConfig | Configuration for decomposition strategy selection. |
EmitPass | Base class for backend-specific emission passes. |
ExecutableProgram | A fully compiled program ready for execution. |
InlinePass | Inline all CallBlockOperations to create an affine block. |
QKernel | Decorator class for Qamomile quantum kernels. |
QamomileCompileError | Base class for all Qamomile compilation errors. |
SeparatePass | Separate a block into quantum and classical segments. |
SimplifiedProgram | Enforces Classical → Quantum → Classical pattern. |
SubstitutionConfig | Configuration for the substitution pass. |
SubstitutionPass | Pass that substitutes CallBlockOperations and CompositeGateOperations. |
SubstitutionRule | A single substitution rule. |
Transpiler | Base class for backend-specific transpilers. |
TranspilerConfig | Configuration for the transpiler pipeline. |
ValidateWhileContractPass | Validates that all WhileOperation conditions are measurement-backed. |
Classes¶
AffineValidationPass [source]¶
class AffineValidationPass(Pass[Block, Block])Validate affine type semantics at IR level.
This pass serves as a safety net to catch affine type violations that may have bypassed the frontend checks. It verifies:
Each quantum value is used (consumed) at most once
Quantum values are not silently discarded
Input: Block (any kind) Output: Same Block (unchanged, validation only)
Attributes¶
name: str
Methods¶
run¶
def run(self, input: Block) -> BlockValidate affine type semantics in the block.
Raises:
AffineTypeError— If a quantum value is consumed multiple times.
AnalyzePass [source]¶
class AnalyzePass(Pass[Block, Block])Analyze and validate an affine block.
This pass:
Builds a dependency graph between values
Validates that quantum ops don’t depend on non-parameter classical results
Checks that block inputs/outputs are classical
Input: Block with BlockKind.AFFINE Output: Block with BlockKind.ANALYZED (with _dependency_graph populated)
Attributes¶
name: str
Methods¶
run¶
def run(self, input: Block) -> BlockAnalyze the block and validate dependencies.
Block [source]¶
class BlockUnified block representation for all pipeline stages.
Replaces both BlockValue and Graph with a single structure.
The kind field indicates which pipeline stage this block is at.
Constructor¶
def __init__(
self,
name: str = '',
label_args: list[str] = list(),
input_values: list[Value] = list(),
output_values: list[Value] = list(),
operations: list[Operation] = list(),
kind: BlockKind = BlockKind.HIERARCHICAL,
parameters: dict[str, Value] = dict(),
_dependency_graph: dict[str, set[str]] | None = None,
) -> NoneAttributes¶
input_values: list[Value]kind: BlockKindlabel_args: list[str]name: stroperations: list[Operation]output_values: list[Value]parameters: dict[str, Value]
Methods¶
from_block_value¶
@classmethod
def from_block_value(
cls,
block_value: 'BlockValue',
parameters: dict[str, Value] | None = None,
) -> 'Block'Create a Block from a BlockValue.
Parameters:
| Name | Type | Description |
|---|---|---|
block_value | 'BlockValue' | The BlockValue to convert |
parameters | dict[str, Value] | None | Optional parameter bindings |
Returns:
'Block' — A new Block in HIERARCHICAL state
is_affine¶
def is_affine(self) -> boolCheck if block contains no CallBlockOperations.
unbound_parameters¶
def unbound_parameters(self) -> list[str]Return list of unbound parameter names.
BlockKind [source]¶
class BlockKind(Enum)Classification of block structure for pipeline stages.
Attributes¶
AFFINEANALYZEDHIERARCHICAL
CompileTimeIfLoweringPass [source]¶
class CompileTimeIfLoweringPass(Pass[Block, Block])Lowers compile-time resolvable IfOperations before separation.
After constant folding, some IfOperation conditions are statically
known but remain as control-flow nodes. SeparatePass treats them
as segment boundaries, causing MultipleQuantumSegmentsError for
classical-only compile-time if after quantum init.
This pass:
Evaluates conditions including expression-derived ones (
CompOp,CondOp,NotOpchains).Replaces resolved
IfOperations with selected-branch operations.Substitutes phi output UUIDs with selected-branch values in all subsequent operations and block outputs.
Constructor¶
def __init__(self, bindings: dict[str, Any] | None = None)Attributes¶
name: str
Methods¶
run¶
def run(self, input: Block) -> BlockRun the compile-time if lowering pass.
ConstantFoldingPass [source]¶
class ConstantFoldingPass(Pass[Block, Block])Evaluates constant expressions at compile time.
This pass folds BinOp operations when all operands are constants or bound parameters, eliminating unnecessary classical operations that would otherwise split quantum segments.
Example:
Before (with bindings={"phase": 0.5}):
BinOp(phase * 2) -> classical segment split
After:
Constant 1.0 -> no segment splitConstructor¶
def __init__(self, bindings: dict[str, Any] | None = None)Attributes¶
name: str
Methods¶
run¶
def run(self, input: Block) -> BlockRun constant folding on the block.
DecompositionConfig [source]¶
class DecompositionConfigConfiguration for decomposition strategy selection.
This configuration is passed to the transpiler to control which decomposition strategies are used for composite gates.
Constructor¶
def __init__(
self,
strategy_overrides: dict[str, str] = dict(),
strategy_params: dict[str, dict[str, Any]] = dict(),
default_strategy: str = 'standard',
) -> 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) -> strGet the strategy name for a specific gate.
Parameters:
| Name | Type | Description |
|---|---|---|
gate_name | str | The gate name (e.g., “qft”, “iqft”) |
Returns:
str — Strategy name to use
get_strategy_params¶
def get_strategy_params(self, strategy_name: str) -> dict[str, Any]Get parameters for a specific strategy.
Parameters:
| Name | Type | Description |
|---|---|---|
strategy_name | str | The strategy name |
Returns:
dict[str, Any] — Dictionary of parameters
EmitPass [source]¶
class EmitPass(Pass[SimplifiedProgram, ExecutableProgram[T]], Generic[T])Base class for backend-specific emission passes.
Subclasses implement _emit_quantum_segment() to generate backend-specific quantum circuits.
Input: SimplifiedProgram (enforces C→Q→C pattern) Output: ExecutableProgram with compiled segments
Constructor¶
def __init__(
self,
bindings: dict[str, Any] | None = None,
parameters: list[str] | None = None,
)Initialize with optional parameter bindings.
Parameters:
| Name | Type | Description |
|---|---|---|
bindings | dict[str, Any] | None | Values to bind parameters to. If not provided, parameters must be bound at execution time. |
parameters | list[str] | None | List of parameter names to preserve as backend parameters. |
Attributes¶
bindingsname: strparameters
Methods¶
run¶
def run(self, input: SimplifiedProgram) -> ExecutableProgram[T]Emit backend code from simplified program.
ExecutableProgram [source]¶
class ExecutableProgram(Generic[T])A fully compiled program ready for execution.
This is the Orchestrator - manages execution of mixed classical/quantum programs.
Example:
executable = transpiler.compile(kernel)
# Sample: multiple shots, returns counts
job = executable.sample(executor, shots=1000)
result = job.result() # SampleResult with counts
# Run: single shot, returns typed result
job = executable.run(executor)
result = job.result() # Returns kernel's return typeConstructor¶
def __init__(
self,
compiled_quantum: list[CompiledQuantumSegment[T]] = list(),
compiled_classical: list[CompiledClassicalSegment] = list(),
compiled_expval: list[CompiledExpvalSegment] = list(),
execution_order: list[tuple[str, int]] = list(),
output_refs: list[str] = list(),
num_output_bits: int = 0,
) -> NoneAttributes¶
compiled_classical: list[CompiledClassicalSegment]compiled_expval: list[CompiledExpvalSegment]compiled_quantum: list[CompiledQuantumSegment[T]]execution_order: list[tuple[str, int]]has_parameters: bool Check if this program has unbound parameters.num_output_bits: intoutput_refs: list[str]parameter_names: list[str] Get list of parameter names that need binding.quantum_circuit: T Get the single quantum circuit.
Methods¶
get_circuits¶
def get_circuits(self) -> list[T]Get all quantum circuits in execution order.
get_first_circuit¶
def get_first_circuit(self) -> T | NoneGet the first quantum circuit, or None if no quantum segments.
run¶
def run(
self,
executor: QuantumExecutor[T],
bindings: dict[str, Any] | None = None,
) -> RunJob[Any] | ExpvalJobExecute once and return single result.
Parameters:
| Name | Type | Description |
|---|---|---|
executor | QuantumExecutor[T] | Backend-specific quantum executor. |
bindings | dict[str, Any] | None | Parameter bindings. Supports two formats: - Vector: {“gammas”: [0.1, 0.2], “betas”: [0.3, 0.4]} - Indexed: {“gammas[0]”: 0.1, “gammas[1]”: 0.2} |
Returns:
RunJob[Any] | ExpvalJob — RunJob that resolves to the kernel’s return type, or
RunJob[Any] | ExpvalJob — ExpvalJob if the program contains expectation value computation.
Raises:
ExecutionError— If no quantum circuit to executeValueError— If required parameters are missing
Example:
job = executable.run(executor, bindings={"gamma": [0.5]})
result = job.result()
print(result) # 0.25 (for QFixed) or (0, 1) (for bits)sample¶
def sample(
self,
executor: QuantumExecutor[T],
shots: int = 1024,
bindings: dict[str, Any] | None = None,
) -> SampleJob[Any]Execute with multiple shots and return counts.
Parameters:
| Name | Type | Description |
|---|---|---|
executor | QuantumExecutor[T] | Backend-specific quantum executor. |
shots | int | Number of shots to run. |
bindings | dict[str, Any] | None | Parameter bindings. Supports two formats: - Vector: {“gammas”: [0.1, 0.2], “betas”: [0.3, 0.4]} - Indexed: {“gammas[0]”: 0.1, “gammas[1]”: 0.2} |
Returns:
SampleJob[Any] — SampleJob that resolves to SampleResult with results.
Raises:
ExecutionError— If no quantum circuit to executeValueError— If required parameters are missing
Example:
job = executable.sample(executor, shots=1000, bindings={"gamma": [0.5]})
result = job.result()
print(result.results) # [(0.25, 500), (0.75, 500)]InlinePass [source]¶
class InlinePass(Pass[Block, Block])Inline all CallBlockOperations to create an affine block.
This pass recursively inlines function calls while preserving control flow structures (For, If, While).
Input: Block with BlockKind.HIERARCHICAL (may contain CallBlockOperations) Output: Block with BlockKind.AFFINE (no CallBlockOperations)
Attributes¶
name: str
Methods¶
run¶
def run(self, input: Block) -> BlockInline all CallBlockOperations.
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) # 2QamomileCompileError [source]¶
class QamomileCompileError(Exception)Base class for all Qamomile compilation errors.
SeparatePass [source]¶
class SeparatePass(Pass[Block, SimplifiedProgram])Separate a block into quantum and classical segments.
This pass:
Materializes return operations (syncs output_values from ReturnOperation)
Splits the operation list into quantum and classical segments
Validates single quantum segment (enforces C→Q→C pattern)
Input: Block (typically ANALYZED or AFFINE) Output: SimplifiedProgram with single quantum segment and optional prep/post
Attributes¶
name: str
Methods¶
run¶
def run(self, input: Block) -> SimplifiedProgramSeparate the block into segments.
SimplifiedProgram [source]¶
class SimplifiedProgramEnforces Classical → Quantum → Classical pattern.
Structure:
[Optional] Classical preprocessing (parameter computation, etc.)
Single quantum segment (REQUIRED)
[Optional] Expval segment OR classical postprocessing
This replaces SeparatedProgram to enforce Qamomile’s execution model: all quantum operations must be in a single quantum circuit.
Constructor¶
def __init__(
self,
quantum: QuantumSegment,
classical_prep: ClassicalSegment | None = None,
expval: ExpvalSegment | None = None,
classical_post: ClassicalSegment | None = None,
boundaries: list[HybridBoundary] = list(),
parameters: dict[str, Value] = dict(),
output_refs: list[str] = list(),
) -> NoneAttributes¶
boundaries: list[HybridBoundary]classical_post: ClassicalSegment | Noneclassical_prep: ClassicalSegment | Noneexpval: ExpvalSegment | Noneoutput_refs: list[str]parameters: dict[str, Value]quantum: QuantumSegment
SubstitutionConfig [source]¶
class SubstitutionConfigConfiguration for the substitution pass.
Constructor¶
def __init__(self, rules: list[SubstitutionRule] = list()) -> NoneAttributes¶
rules: list[SubstitutionRule]
Methods¶
get_rule_for_name¶
def get_rule_for_name(self, name: str) -> SubstitutionRule | NoneFind a rule matching the given name.
Parameters:
| Name | Type | Description |
|---|---|---|
name | str | Name to look up |
Returns:
SubstitutionRule | None — Matching SubstitutionRule or None
SubstitutionPass [source]¶
class SubstitutionPass(Pass[Block, Block])Pass that substitutes CallBlockOperations and CompositeGateOperations.
This pass traverses the block and applies substitution rules:
For CallBlockOperation: replaces the block reference with the target
For CompositeGateOperation: sets the strategy_name field
The pass preserves the block structure and only modifies matching operations.
Input: Block (any kind) Output: Block with substitutions applied (same kind as input)
Constructor¶
def __init__(self, config: SubstitutionConfig) -> NoneInitialize the pass with configuration.
Parameters:
| Name | Type | Description |
|---|---|---|
config | SubstitutionConfig | Substitution configuration with rules |
Attributes¶
name: str Return pass name.
Methods¶
run¶
def run(self, input: Block) -> BlockApply substitutions to the block.
Parameters:
| Name | Type | Description |
|---|---|---|
input | Block | Block to transform |
Returns:
Block — Block with substitutions applied
SubstitutionRule [source]¶
class SubstitutionRuleA single substitution rule.
Constructor¶
def __init__(
self,
source_name: str,
target: 'BlockValue | QKernel | None' = None,
strategy: str | None = None,
validate_signature: bool = True,
) -> NoneAttributes¶
source_name: strstrategy: str | Nonetarget: ‘BlockValue | QKernel | None’validate_signature: bool
Transpiler [source]¶
class Transpiler(ABC, Generic[T])Base class for backend-specific transpilers.
Provides the full compilation pipeline from QKernel to executable program.
Usage:
transpiler = QiskitTranspiler()
Option 1: Full pipeline¶
executable = transpiler.compile(kernel, bindings={“theta”: 0.5}) results = executable.run(transpiler.executor())
Option 2: Step-by-step¶
block = transpiler.to_block(kernel) substituted = transpiler.substitute(block) affine = transpiler.inline(substituted) validated = transpiler.affine_validate(affine) folded = transpiler.constant_fold(validated, bindings={“theta”: 0.5}) analyzed = transpiler.analyze(folded) separated = transpiler.separate(analyzed) executable = transpiler.emit(separated, bindings={“theta”: 0.5})
Option 3: Just get the circuit (no execution)¶
circuit = transpiler.to_circuit(kernel, bindings={“theta”: 0.5})
With configuration (strategy overrides)¶
config = TranspilerConfig.with_strategies({“qft”: “approximate”}) transpiler = QiskitTranspiler(config=config)
Attributes¶
config: TranspilerConfig Get the transpiler configuration.
Methods¶
affine_validate¶
def affine_validate(self, block: Block) -> BlockPass 1.5: Validate affine type semantics.
This is a safety net to catch affine type violations that may have bypassed frontend checks. Validates that quantum values are used at most once.
analyze¶
def analyze(self, block: Block) -> BlockPass 2: Validate and analyze dependencies.
constant_fold¶
def constant_fold(self, block: Block, bindings: dict[str, Any] | None = None) -> BlockPass 1.5: Fold constant expressions.
Evaluates BinOp operations when all operands are constants
or bound parameters. This prevents quantum segment splitting
from parametric expressions like phase * 2.
emit¶
def emit(
self,
separated: SimplifiedProgram,
bindings: dict[str, Any] | None = None,
parameters: list[str] | None = None,
) -> ExecutableProgram[T]Pass 4: Generate backend-specific code.
Parameters:
| Name | Type | Description |
|---|---|---|
separated | SimplifiedProgram | The separated program to emit |
bindings | dict[str, Any] | None | Parameter values to bind at compile time |
parameters | list[str] | None | Parameter names to preserve as backend parameters |
executor¶
def executor(self, **kwargs: Any = {}) -> QuantumExecutor[T]Create a quantum executor for this backend.
inline¶
def inline(self, block: Block) -> BlockPass 1: Inline all CallBlockOperations.
lower_compile_time_ifs¶
def lower_compile_time_ifs(self, block: Block, bindings: dict[str, Any] | None = None) -> BlockPass 1.75: Lower compile-time resolvable IfOperations.
Evaluates IfOperation conditions (including expression-derived conditions via CompOp/CondOp/NotOp) and replaces resolved ones with selected-branch operations. Phi outputs are substituted with selected-branch values throughout the block.
This prevents SeparatePass from seeing classical-only compile-time IfOperations that would otherwise split quantum segments.
separate¶
def separate(self, block: Block) -> SimplifiedProgramPass 3: Lower and split into quantum and classical segments.
Validates C→Q→C pattern with single quantum segment.
set_config¶
def set_config(self, config: TranspilerConfig) -> NoneSet the transpiler configuration.
Parameters:
| Name | Type | Description |
|---|---|---|
config | TranspilerConfig | Transpiler configuration to use |
substitute¶
def substitute(self, block: Block) -> BlockPass 0.5: Apply substitutions (optional).
This pass replaces CallBlockOperation targets and sets strategy names on CompositeGateOperations based on config.
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | Block to transform |
Returns:
Block — Block with substitutions applied
to_block¶
def to_block(
self,
kernel: QKernel,
bindings: dict[str, Any] | None = None,
parameters: list[str] | None = None,
) -> BlockConvert a QKernel to a Block.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernel | The QKernel to convert |
bindings | dict[str, Any] | None | Concrete values to bind at trace time (resolves array shapes) |
parameters | list[str] | None | Names to keep as unbound parameters |
When bindings or parameters are provided, uses kernel.build() to properly resolve array shapes from the bound data. Otherwise uses the cached block_value for efficiency.
to_circuit¶
def to_circuit(self, kernel: QKernel, bindings: dict[str, Any] | None = None) -> TCompile and extract just the quantum circuit.
This is a convenience method for when you just want the backend circuit without the full executable.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernel | The QKernel to compile |
bindings | dict[str, Any] | None | Parameter values to bind |
Returns:
T — Backend-specific quantum circuit
transpile¶
def transpile(
self,
kernel: QKernel,
bindings: dict[str, Any] | None = None,
parameters: list[str] | None = None,
) -> ExecutableProgram[T]Full compilation pipeline from QKernel to executable.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernel | The QKernel to compile |
bindings | dict[str, Any] | None | Parameter values to bind (also resolves array shapes) |
parameters | list[str] | None | Parameter names to preserve as backend parameters |
Returns:
ExecutableProgram[T] — ExecutableProgram ready for execution
Raises:
QamomileCompileError— If compilation fails (validation, dependency errors)
Pipeline:
to_block: Convert QKernel to Block
substitute: Apply substitutions (if configured)
inline: Inline CallBlockOperations
affine_validate: Validate affine type semantics
constant_fold: Fold constant expressions 5.5. lower_compile_time_ifs: Lower compile-time IfOperations 5.8. validate_while_contract: Validate while conditions are measurement-backed
analyze: Validate and analyze dependencies
separate: Split into quantum/classical segments
emit: Generate backend-specific code
validate_while_contract¶
def validate_while_contract(self, block: Block) -> BlockPass 1.8: Validate WhileOperation conditions are measurement-backed.
Rejects while patterns whose condition is not a measurement result
(Bit from qmc.measure()). This prevents late ValueError
at emit time for unsupported while forms.
TranspilerConfig [source]¶
class TranspilerConfigConfiguration for the transpiler pipeline.
This configuration allows customizing the compilation behavior, including decomposition strategies and subroutine substitutions.
Example:
config = TranspilerConfig(
decomposition=DecompositionConfig(
strategy_overrides={"qft": "approximate"},
),
substitutions=SubstitutionConfig(
rules=[
SubstitutionRule("my_oracle", target=optimized_oracle),
],
),
)
transpiler = QiskitTranspiler(config=config)Constructor¶
def __init__(
self,
decomposition: DecompositionConfig = DecompositionConfig(),
substitutions: SubstitutionConfig = SubstitutionConfig(),
) -> NoneAttributes¶
decomposition: DecompositionConfigsubstitutions: SubstitutionConfig
Methods¶
with_strategies¶
@classmethod
def with_strategies(
cls,
strategy_overrides: dict[str, str] | None = None,
**kwargs: Any = {},
) -> 'TranspilerConfig'Create config with strategy overrides.
Parameters:
| Name | Type | Description |
|---|---|---|
strategy_overrides | dict[str, str] | None | Map of gate name to strategy name |
**kwargs | Any | Additional config options |
Returns:
'TranspilerConfig' — TranspilerConfig instance
Example:
config = TranspilerConfig.with_strategies(
strategy_overrides={"qft": "approximate", "iqft": "approximate"}
)ValidateWhileContractPass [source]¶
class ValidateWhileContractPass(Pass[Block, Block])Validates that all WhileOperation conditions are measurement-backed.
Builds a producer map (result UUID → producing Operation instance) and checks every WhileOperation operand against it. A valid condition must be:
A
ValuewithBitTypeMeasurement-backed: produced by
MeasureOperationdirectly, or byIfOperation/PhiOpwhere every reachable leaf source is itself measurement-backed.
Both operands[0] (initial condition) and operands[1]
(loop-carried condition) are validated.
Raises ValidationError for any non-measurement while pattern.
Attributes¶
name: str
Methods¶
run¶
def run(self, block: Block) -> BlockValidate all WhileOperations and return block unchanged.