Qiskit engine transpiler implementation.
This module provides QiskitTranspiler for converting Qamomile QKernels into Qiskit QuantumCircuits.
Overview¶
| Class | Description |
|---|---|
EmitPass | Base class for engine-specific emission passes. |
EstimateRequest | Describe one Hamiltonian expectation execution. |
ExecutionCapabilities | Declare the execution features implemented by one executor. |
ExecutionHandle | Expose an engine execution without forcing immediate result retrieval. |
ExecutionReference | Store secret-free identifiers needed to restore remote execution. |
QiskitExecutionOptions | Configure Runtime primitives without constructing Qiskit option objects. |
QiskitExecutor | Execute Qiskit circuits locally or on a selected IBM Quantum backend. |
QiskitMaterializer | Convert target-legal circuit code-generation IR to QuantumCircuit. |
QiskitTranspiler | Qiskit engine transpiler. |
SampleRequest | Describe one sampling execution. |
SegmentationPass | Segment a block into a strategy-specific executable program plan. |
Transpiler | Base class for engine-specific transpilers. |
Classes¶
EmitPass [source]¶
class EmitPass(Pass[ProgramPlan, ExecutableProgram[T]], Generic[T])Base class for engine-specific emission passes.
Subclasses implement _emit_quantum_segment() to generate engine-specific quantum circuits.
Input: ProgramPlan 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 engine parameters. |
Raises:
ValueError— If a name appears in bothbindingsandparameters. This is the innermost emit-side choke point: it catches the overlap even when anEmitPassis constructed directly (e.g. viaTranspiler._create_emit_pass), bypassing thetranspile/emitwrappers. A name in both is ambiguous and would otherwise silently bake the binding while dropping the runtime parameter (see #354).
Attributes¶
bindingsname: strparameters
Methods¶
run¶
def run(self, input: ProgramPlan) -> ExecutableProgram[T]Emit engine code from a program plan.
Parameters:
| Name | Type | Description |
|---|---|---|
input | ProgramPlan | Segmented plan whose quantum and classical steps should be compiled. |
Returns:
ExecutableProgram[T] — ExecutableProgram[T]: Executable program containing all compiled
segments and the public output contract.
Raises:
EmitError— If expectation-value evaluation is combined with a measurement, projection, or reset operation, or if a planned segment cannot be emitted.
EstimateRequest [source]¶
class EstimateRequest(Generic[CircuitT])Describe one Hamiltonian expectation execution.
Parameters:
| Name | Type | Description |
|---|---|---|
invocation | CircuitInvocation[CircuitT] | Circuit and runtime inputs. |
hamiltonian | qm_o.Hamiltonian | Observable to evaluate. |
accuracy | EstimationAccuracy | None | Explicit accuracy policy. None uses the executor’s configured default. |
Constructor¶
def __init__(
self,
invocation: CircuitInvocation[CircuitT],
hamiltonian: qm_o.Hamiltonian,
accuracy: EstimationAccuracy | None = None,
) -> NoneAttributes¶
accuracy: EstimationAccuracy | Nonehamiltonian: qm_o.Hamiltonianinvocation: CircuitInvocation[CircuitT]
ExecutionCapabilities [source]¶
class ExecutionCapabilitiesDeclare the execution features implemented by one executor.
Parameters:
| Name | Type | Description |
|---|---|---|
supports_async_sampling | bool | Whether sampling submission returns before provider execution completes. Defaults to False. |
supports_async_estimation | bool | Whether expectation submission returns before provider execution completes. Defaults to False. |
supports_estimation | bool | Whether expectation-value execution is implemented. Defaults to False. |
supports_cancellation | bool | Whether provider-backed handles can request cancellation. Defaults to False. |
supports_restoration | bool | Whether execution references can recreate provider-backed handles. Defaults to False. |
supports_native_batch | bool | Whether multiple logical requests can be submitted through one provider-native batch or job. Defaults to False. |
supports_native_parameter_inputs | bool | Whether runtime values remain separate from emitted circuits during provider submission. Defaults to False. |
estimation_accuracy | frozenset[EstimationPolicyType] | Explicit per-request accuracy policies accepted by the executor. An empty set means only executor-configured estimation behavior is available. |
Raises:
ValueError— If an unknown estimation policy type is declared or estimation features are declared without estimation support.
Constructor¶
def __init__(
self,
supports_async_sampling: bool = False,
supports_async_estimation: bool = False,
supports_estimation: bool = False,
supports_cancellation: bool = False,
supports_restoration: bool = False,
supports_native_batch: bool = False,
supports_native_parameter_inputs: bool = False,
estimation_accuracy: frozenset[EstimationPolicyType] = frozenset(),
) -> NoneAttributes¶
estimation_accuracy: frozenset[EstimationPolicyType]supports_async_estimation: boolsupports_async_sampling: boolsupports_cancellation: boolsupports_estimation: boolsupports_native_batch: boolsupports_native_parameter_inputs: boolsupports_restoration: bool
ExecutionHandle [source]¶
class ExecutionHandle(ABC, Generic[ResultT])Expose an engine execution without forcing immediate result retrieval.
Attributes¶
native: object | None Return the wrapped provider-native task when available.
Methods¶
cancel¶
def cancel(self) -> NoneRequest best-effort cancellation.
Cancellation is intentionally not reported as a boolean because
providers may accept a request after execution has already started.
Call :meth:status to observe the eventual state.
metadata¶
def metadata(self) -> Mapping[str, Any]Return optional provider execution metadata.
Returns:
Mapping[str, Any] — Mapping[str, Any]: Provider metadata such as timestamps or usage.
raw_status¶
def raw_status(self) -> objectReturn provider-specific status information.
Returns:
object — Provider status value, or the normalized status when no
richer value exists.
references¶
def references(self) -> tuple[ExecutionReference, ...]Return serializable remote execution references.
Returns:
tuple[ExecutionReference, ...] — tuple[ExecutionReference, ...]: Secret-free provider references.
result¶
def result(self, timeout: float | None = None) -> ResultTWait for and return the engine-neutral raw result.
Parameters:
| Name | Type | Description |
|---|---|---|
timeout | float | None | Maximum local wait in seconds. None delegates the wait policy to the provider. |
Returns:
ResultT — Raw result normalized by the engine executor.
Raises:
TimeoutError— If the local wait expires before completion.
result_async¶
def result_async(self, timeout: float | None = None) -> ResultTWait asynchronously for the engine-neutral raw result.
Parameters:
| Name | Type | Description |
|---|---|---|
timeout | float | None | Maximum local wait in seconds. Defaults to provider behavior when None. |
Returns:
ResultT — Raw result normalized by the engine executor.
Raises:
TimeoutError— If the local wait expires before completion.
snapshot¶
def snapshot(self) -> ExecutionSnapshotCapture one remote execution without fetching its result.
Adapters exposing several logical references must override this method with an explicit reconstruction structure. A provider reference may itself contain multiple physical job IDs.
Returns:
ExecutionSnapshot — One opaque provider execution.
Raises:
ValueError— If references are absent or their grouping is unknown.
status¶
def status(self) -> JobStatusReturn the current provider-independent execution status.
Returns:
JobStatus — Current normalized status.
ExecutionReference [source]¶
class ExecutionReferenceStore secret-free identifiers needed to restore remote execution.
Parameters:
| Name | Type | Description |
|---|---|---|
provider | str | Stable provider or adapter name. |
job_ids | tuple[str, ...] | One or more provider job identifiers. |
target | str | None | Provider target or device identifier. Defaults to None. |
group_id | str | None | Session, batch, program, or parent identifier. Defaults to None. |
context | Mapping[str, str] | Additional non-secret identifiers needed to restore the job. Defaults to an empty mapping. |
Raises:
ValueError— If the provider name or any job identifier is empty.TypeError— If identifiers or context have incompatible types.
Constructor¶
def __init__(
self,
provider: str,
job_ids: tuple[str, ...],
target: str | None = None,
group_id: str | None = None,
context: Mapping[str, str] = dict(),
) -> NoneAttributes¶
context: Mapping[str, str]group_id: str | Nonejob_ids: tuple[str, ...]provider: strtarget: str | None
Methods¶
from_dict¶
@classmethod
def from_dict(cls, data: Mapping[str, Any]) -> ExecutionReferenceReconstruct a provider reference from JSON-compatible data.
Parameters:
| Name | Type | Description |
|---|---|---|
data | Mapping[str, Any] | Mapping produced by :meth:to_dict. |
Returns:
ExecutionReference — Validated provider execution reference.
Raises:
KeyError— If a required provider or job identifier field is absent.TypeError— If a field has an incompatible type.ValueError— If provider or job identifiers are empty.
to_dict¶
def to_dict(self) -> dict[str, Any]Convert the provider reference to JSON-compatible data.
Returns:
dict[str, Any] — dict[str, Any]: Provider identifiers and decoding context without
credentials or SDK objects.
QiskitExecutionOptions [source]¶
class QiskitExecutionOptionsConfigure Runtime primitives without constructing Qiskit option objects.
Per-request sampling shots and estimation precision remain arguments to the executable. Advanced mappings use Runtime’s option names; the SDK validates their supported fields when the executor is constructed.
Parameters:
| Name | Type | Description |
|---|---|---|
max_execution_time | int | None | Positive quantum execution time limit in seconds for both primitives, excluding queue time. Defaults to the SDK setting; does not set the local result-wait timeout. |
resilience_level | int | None | Estimator error mitigation level from zero through two. Defaults to the SDK setting. |
sampler_options | Mapping[str, Any] | Additional sampler settings. Defaults to an empty mapping. Nested values are copied. |
estimator_options | Mapping[str, Any] | Additional estimator settings. Defaults to an empty mapping. Nested values are copied. |
Raises:
TypeError— If advanced options are not mappings with string keys.ValueError— If a numeric setting is invalid or an advanced mapping contains a field exposed directly by this class.
Example:
>>> options = QiskitExecutionOptions(
... max_execution_time=300,
... resilience_level=1,
... sampler_options={"dynamical_decoupling": {"enable": True}},
... )Constructor¶
def __init__(
self,
max_execution_time: int | None = None,
resilience_level: int | None = None,
sampler_options: Mapping[str, Any] = dict(),
estimator_options: Mapping[str, Any] = dict(),
) -> NoneAttributes¶
estimator_options: Mapping[str, Any]max_execution_time: int | Noneresilience_level: int | Nonesampler_options: Mapping[str, Any]
Methods¶
estimator_kwargs¶
def estimator_kwargs(self) -> dict[str, Any]Build an independent Runtime estimator options dictionary.
Returns:
dict[str, Any] — dict[str, Any]: Estimator settings with execution and mitigation
settings when supplied.
sampler_kwargs¶
def sampler_kwargs(self) -> dict[str, Any]Build an independent Runtime sampler options dictionary.
Returns:
dict[str, Any] — dict[str, Any]: Sampler settings with the shared execution limit.
QiskitExecutor [source]¶
class QiskitExecutor(QuantumExecutor['QuantumCircuit'])Execute Qiskit circuits locally or on a selected IBM Quantum backend.
With no backend, use AerSimulator or BasicSimulator. Named backends are resolved through QiskitRuntimeService using the supplied credentials or the SDK’s saved account. IBMBackend objects select Runtime automatically. Credentials are passed to the SDK without saving an account to disk.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | Any | Qiskit backend object, IBM backend name, or None for the default local simulator. |
estimator | Any | Optional local expectation estimator. Defaults to None for StatevectorEstimator; unavailable with Runtime. |
api_key | str | None | IBM API key for a named backend. Must be supplied with instance_crn. Defaults to the SDK’s saved account. |
instance_crn | str | None | IBM instance CRN paired with api_key. Defaults to the SDK’s configured instance. |
mode | Any | Caller-owned Runtime Session or Batch paired with a backend object. A backend object can also select Runtime local testing mode. Defaults to None; unavailable with a backend name. |
options | QiskitExecutionOptions | None | Qamomile-owned Runtime settings. Defaults to None; cannot be combined with sampler_options or estimator_options. |
sampler_options | Any | Runtime sampler options. Defaults to None. |
estimator_options | Any | Runtime estimator options. Defaults to None. |
pass_manager | Any | Runtime target pass manager. Defaults to None. |
service | Any | Existing Runtime service for named backend lookup or job restoration. Cannot be combined with explicit credentials. |
Raises:
TypeError— Ifoptionsis not a QiskitExecutionOptions instance.ValueError— If credentials are incomplete, arguments conflict, or Runtime options are supplied for local execution.ImportError— If IBM execution is requested without its SDK extra.QiskitBackendNotFoundError— If the named backend cannot be found for the selected account and instance.Exception— If SDK authentication, lookup, or setup fails.
Example:
executor = QiskitExecutor() # Uses AerSimulator when available
counts = executor.execute(circuit, shots=1000)
executor = QiskitExecutor(
backend="your_backend_name",
api_key=api_key,
instance_crn=instance_crn,
)
job = executable.sample(executor, shots=1024)Constructor¶
def __init__(
self,
backend: Any = None,
estimator: Any = None,
*,
api_key: str | None = None,
instance_crn: str | None = None,
mode: Any = None,
options: QiskitExecutionOptions | None = None,
sampler_options: Any = None,
estimator_options: Any = None,
pass_manager: Any = None,
service: Any = None,
) -> NoneSelect local execution or authenticate a named IBM backend.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | Any | Qiskit backend object or IBM device name. Defaults to a local simulator when None. |
estimator | Any | Local expectation estimator, or None for defaults. |
api_key | str | None | IBM API key, paired with instance_crn for a named backend. Defaults to None for the saved account. |
instance_crn | str | None | IBM instance CRN paired with api_key. Defaults to None for the SDK’s configured instance. |
mode | Any | Runtime Session, Batch, or local testing backend paired with a backend object. Defaults to None; not used with a name. |
options | QiskitExecutionOptions | None | Qamomile-owned Runtime settings. Defaults to None; cannot be combined with direct sampler or estimator options. |
sampler_options | Any | Runtime sampler options, or None. |
estimator_options | Any | Runtime estimator options, or None. |
pass_manager | Any | Runtime hardware compilation pass manager, or None for the preset at optimization level one. |
service | Any | Existing Runtime service for lookup or restoration, or None. Cannot be combined with explicit credentials. |
Raises:
TypeError— Ifoptionsis not a QiskitExecutionOptions instance.ValueError— If credentials are incomplete, arguments conflict, or Runtime options are supplied for local execution.ImportError— If IBM execution is requested without its SDK extra.QiskitBackendNotFoundError— If the named backend cannot be found for the selected account and instance.Exception— If SDK authentication, lookup, or setup fails.
Attributes¶
backendcapabilities: ExecutionCapabilities Describe execution features of the selected local or IBM backend.
Methods¶
bind_parameters¶
def bind_parameters(
self,
circuit: 'QuantumCircuit',
bindings: dict[str, Any],
parameter_metadata: ParameterMetadata,
) -> 'QuantumCircuit'Bind parameter values to the Qiskit circuit.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | QuantumCircuit | Parameterized circuit. |
bindings | dict[str, Any] | Flattened runtime parameter values. |
parameter_metadata | ParameterMetadata | Backend parameter mapping. |
Returns:
'QuantumCircuit' — New circuit with parameters bound.
Raises:
ValueError— If required Runtime values are missing.Exception— If Qiskit rejects a parameter assignment.
estimate¶
def estimate(
self,
circuit: 'QuantumCircuit',
hamiltonian: 'qm_o.Hamiltonian',
params: Sequence[float] | None = None,
) -> floatEstimate the expectation value of a Hamiltonian.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | QuantumCircuit | State preparation ansatz. |
hamiltonian | qm_o.Hamiltonian | Observable to measure. |
params | Sequence[float] | None | Optional values in Qiskit parameter order. Defaults to None for an already bound circuit. |
Returns:
float — Estimated expectation value.
Raises:
Exception— If estimator setup, compilation, or execution fails.
execute¶
def execute(self, circuit: 'QuantumCircuit', shots: int) -> dict[str, int]Execute circuit and return bitstring counts.
Parameters:
| Name | Type | Description |
|---|---|---|
circuit | QuantumCircuit | Qiskit circuit to execute. |
shots | int | Number of measurement shots. |
Returns:
dict[str, int] — dict[str, int]: Native dictionary mapping bitstrings to counts,
without SDK-specific result metadata. A circuit without quantum
or classical bits returns {"": shots}.
Raises:
RuntimeError— If no Qiskit backend is available for execution, or if Aer would still receive an empty-parameter multiplexer after the workaround decomposition.Exception— If IBM compilation, submission, or execution fails.
restore¶
def restore(self, reference: ExecutionReference) -> ExecutionHandle[Any]Reconnect to an IBM job using the selected backend’s service.
Parameters:
| Name | Type | Description |
|---|---|---|
reference | ExecutionReference | Previously saved execution reference. |
Returns:
ExecutionHandle[Any] — ExecutionHandle[Any]: Restored IBM sample or expectation handle.
Raises:
NotImplementedError— If the selected backend has no restoration.ValueError— If the reference targets another provider or backend.Exception— If the SDK cannot retrieve the job.
submit_estimate¶
def submit_estimate(self, request: EstimateRequest[QuantumCircuit]) -> ExecutionHandle[float]Submit an expectation through the selected execution adapter.
Parameters:
| Name | Type | Description |
|---|---|---|
request | EstimateRequest[QuantumCircuit] | Circuit, observable, and optional accuracy policy. |
Returns:
ExecutionHandle[float] — ExecutionHandle[float]: Immediate local result or lazy IBM job.
Raises:
NotImplementedError— If the selected adapter rejects the accuracy.Exception— If validation, compilation, or submission fails.
submit_sample¶
def submit_sample(
self,
request: SampleRequest[QuantumCircuit],
) -> ExecutionHandle[dict[str, int]]Submit samples through the selected execution adapter.
Parameters:
| Name | Type | Description |
|---|---|---|
request | SampleRequest[QuantumCircuit] | Circuit, bindings, and shots. |
Returns:
ExecutionHandle[dict[str, int]] — ExecutionHandle[dict[str, int]]: Immediate local result or lazy IBM
job handle.
Raises:
Exception— If request validation, compilation, or submission fails.
QiskitMaterializer [source]¶
class QiskitMaterializerConvert target-legal circuit code-generation IR to QuantumCircuit.
Root and runtime-control-flow phases are retained in Qiskit’s native
QuantumCircuit.global_phase metadata on the corresponding circuit or
block.
Attributes¶
capabilities: CircuitCapabilities Declare Qiskit’s circuit-IR capabilities.
Methods¶
materialize¶
def materialize(
self,
program: CircuitProgram,
parameter_names: tuple[str, ...] = (),
) -> MaterializedCircuit[Any]Build and return a Qiskit circuit with scoped phase metadata.
Parameters:
| Name | Type | Description |
|---|---|---|
program | CircuitProgram | Verified circuit-family program. |
parameter_names | tuple[str, ...] | Public parameter ABI. Qiskit binds by name, so this is used for boundary validation only. Defaults to an empty tuple. |
Returns:
MaterializedCircuit[Any] — MaterializedCircuit[Any]: Qiskit circuit and parameter mapping.
Raises:
EmitError— If an instruction cannot be represented by Qiskit.ValueError— If circuit IR verification fails.
QiskitTranspiler [source]¶
class QiskitTranspiler(Transpiler['QuantumCircuit'])Qiskit engine transpiler.
Converts Qamomile QKernels into Qiskit QuantumCircuits.
Parameters:
| Name | Type | Description |
|---|---|---|
use_native_composite | bool | Whether to prefer native Qiskit library realizations for semantic composites such as QFT/IQFT. Defaults to True. |
use_native_pauli_evolution | bool | Whether to prefer PauliEvolutionGate over gate gadgets. Defaults to True. |
Example:
from qamomile.qiskit import QiskitTranspiler
import qamomile as qm
@qm.qkernel
def bell_state(q0: qm.Qubit, q1: qm.Qubit) -> tuple[qm.Bit, qm.Bit]:
q0 = qm.h(q0)
q0, q1 = qm.cx(q0, q1)
return qm.measure(q0), qm.measure(q1)
transpiler = QiskitTranspiler()
circuit = transpiler.to_circuit(bell_state)
print(circuit.draw())Constructor¶
def __init__(
self,
use_native_composite: bool = True,
use_native_pauli_evolution: bool = True,
) -> NoneInitialize the Qiskit transpiler.
Parameters:
| Name | Type | Description |
|---|---|---|
use_native_composite | bool | Whether to prefer engine-native realizations of semantic composites such as QFT, state preparation, arithmetic, and multi-controlled X. Defaults to True. |
use_native_pauli_evolution | bool | Whether to prefer native Pauli evolution over gate gadgets. Defaults to True. |
Methods¶
executor¶
def executor(
self,
backend: Any = None,
*,
estimator: Any = None,
api_key: str | None = None,
instance_crn: str | None = None,
mode: Any = None,
options: QiskitExecutionOptions | None = None,
sampler_options: Any = None,
estimator_options: Any = None,
pass_manager: Any = None,
service: Any = None,
) -> QiskitExecutorCreate a local or IBM Quantum executor with the same execution API.
Parameters:
| Name | Type | Description |
|---|---|---|
backend | Any | Qiskit backend object or IBM backend name. Defaults to a local simulator when None. |
estimator | Any | Optional local expectation estimator. |
api_key | str | None | IBM API key for a named backend. Must be paired with instance_crn; defaults to saved credentials. |
instance_crn | str | None | Instance CRN paired with api_key. Defaults to the SDK’s configured instance. |
mode | Any | Caller-owned Runtime Session, Batch, or local testing backend paired with a backend object. Defaults to None; unavailable with a backend name. |
options | QiskitExecutionOptions | None | Qamomile-owned Runtime settings. Defaults to None; cannot be combined with direct sampler or estimator options. |
sampler_options | Any | Runtime sampler options, or None. |
estimator_options | Any | Runtime estimator options, or None. |
pass_manager | Any | Runtime hardware compilation pass manager, or None for the backend preset. |
service | Any | Existing Runtime service for lookup or restoration, or None. Cannot be combined with explicit credentials. |
Returns:
QiskitExecutor — Executor configured for the selected execution target.
Raises:
TypeError— Ifoptionsis not a QiskitExecutionOptions instance.ValueError— If credentials are incomplete or arguments conflict.ImportError— If IBM execution is requested without its SDK extra.QiskitBackendNotFoundError— If the selected account and instance have no matching backend.Exception— If SDK authentication or executor setup fails.
Example:
executor = transpiler.executor(
backend="your_backend_name",
api_key=api_key,
instance_crn=instance_crn,
)
job = executable.sample(executor, shots=1024)SampleRequest [source]¶
class SampleRequest(Generic[CircuitT])Describe one sampling execution.
Parameters:
| Name | Type | Description |
|---|---|---|
invocation | CircuitInvocation[CircuitT] | Circuit and runtime inputs. |
shots | int | Number of requested samples. |
Raises:
ValueError— Ifshotsis not positive.
Constructor¶
def __init__(self, invocation: CircuitInvocation[CircuitT], shots: int) -> NoneAttributes¶
invocation: CircuitInvocation[CircuitT]shots: int
SegmentationPass [source]¶
class SegmentationPass(Pass[Block, ProgramPlan])Segment a block into a strategy-specific executable program plan.
This pass:
Materializes return operations (syncs output_values from ReturnOperation)
Splits the operation list into quantum and classical segments
Builds a ProgramPlan via the configured segmentation strategy
Input: Block (typically ANALYZED or AFFINE) Output: ProgramPlan
Constructor¶
def __init__(self, strategy: SegmentationStrategy | None = None) -> NoneAttributes¶
name: str
Methods¶
run¶
def run(self, input: Block) -> ProgramPlanLower and segment a block into a program plan.
Parameters:
| Name | Type | Description |
|---|---|---|
input | Block | Block whose while contract and hybrid operations should be lowered before segmentation. |
Returns:
ProgramPlan — Strategy-produced execution plan.
Raises:
ValidationError— If a runtime while violates its contract.SeparationError— If the strategy finds no quantum segment.MultipleQuantumSegmentsError— If the strategy finds multiple quantum segments.
Transpiler [source]¶
class Transpiler(ABC, Generic[T])Base class for engine-specific transpilers.
Provides the full compilation pipeline from qkernel-like frontend objects to executable programs.
Example:
>>> from qamomile.circuit.transpiler import TranspilerConfig
>>> from qamomile.qiskit import QiskitTranspiler
>>> transpiler = QiskitTranspiler()
>>> executable = transpiler.transpile(kernel, bindings={"theta": 0.5})
>>> circuit = executable.get_first_circuit()
>>> config = TranspilerConfig.with_strategies({"qft": "approximate_k2"})
>>> transpiler.set_config(config)Attributes¶
MAX_UNROLL_DEPTH: intconfig: 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.
array_bounds_check¶
def array_bounds_check(self, block: Block) -> BlockPass 1.85: Reject reachable accesses outside resolved array bounds.
Runs after :meth:partial_eval so binding-dependent view extents and
indices are concrete where possible, and before declarative slice
operations are stripped. Statically zero-trip loop bodies are skipped
because their element accesses are unreachable.
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | Post-fold affine or hierarchical block to validate. |
Returns:
Block — The input block unchanged after successful validation.
Raises:
ValidationError— If a reachable constant element index is outside a resolved root-array or view-local extent.
classical_lowering¶
def classical_lowering(self, block: Block) -> BlockPass 2.25: Lower measurement-derived classical ops.
Identifies CompOp / CondOp / NotOp / BinOp
instances whose operand dataflow traces back to a measurement and
rewrites them to RuntimeClassicalExpr. Compile-time-foldable
and emit-time-foldable (loop-bound, parameter-bound) classical
ops are left unchanged.
Runs after analyze so the measurement-taint analysis has the
full dependency graph available, and before
validate_symbolic_shapes / plan / emit so downstream
passes can rely on the cleaner IR (in particular: future
segmentation work can dispatch on RuntimeClassicalExpr type
instead of the BitType-only heuristic).
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: ProgramPlan,
bindings: dict[str, Any] | None = None,
parameters: list[str] | None = None,
) -> ExecutableProgram[T]Pass 4: Generate engine-specific code.
Parameters:
| Name | Type | Description |
|---|---|---|
separated | ProgramPlan | 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 engine parameters |
Raises:
ValueError— If a name appears in bothbindingsandparameters. This check also runs intranspileandto_block/build, butemitis a public step-by-step entry point that bypasses those, so the guard is repeated here to prevent a name from being silently baked in (its runtime parameter dropped) when the step-by-step API is driven directly.
executor¶
def executor(self, **kwargs: Any = {}) -> QuantumExecutor[T]Create a quantum executor for this engine.
inline¶
def inline(self, block: Block) -> BlockPass 1: Inline all inline-policy callable invocations.
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. Merge outputs are substituted with selected-branch values throughout the block.
This prevents SegmentationPass from seeing classical-only compile-time IfOperations that would otherwise split quantum segments.
partial_eval¶
def partial_eval(self, block: Block, bindings: dict[str, Any] | None = None) -> BlockPass 1.75: Fold constants and lower compile-time control flow.
plan¶
def plan(self, block: Block) -> ProgramPlanPass 3: Lower and split into a program plan.
Validates C→Q→C pattern with single quantum segment.
plan_circuit¶
def plan_circuit(
self,
prepared: PreparedModule,
bindings: dict[str, Any] | None = None,
) -> ProgramPlanLower a prepared semantic module into the circuit execution model.
This is the destructive circuit-family path: inline-policy calls are
flattened, compile-time structure is evaluated, affine and borrow
invariants are checked, measurement-dependent classical expressions
are classified, and the result is segmented into C-to-Q-to-C steps.
Program-graph targets must compile :class:PreparedModule directly
instead of invoking this method.
Parameters:
| Name | Type | Description |
|---|---|---|
prepared | PreparedModule | Hierarchical semantic program returned by :meth:prepare. |
bindings | dict[str, Any] | None | Compile-time bindings used for recursion unrolling and partial evaluation. Defaults to None. |
Returns:
ProgramPlan — Circuit-family host-orchestrated execution plan.
Raises:
QamomileCompileError— If validation, partial evaluation, or segmentation rejects the program.
prepare¶
def prepare(
self,
kernel: QKernelLike,
bindings: dict[str, Any] | None = None,
parameters: list[str] | None = None,
) -> PreparedModulePrepare a qkernel for target-specific planning and lowering.
This phase preserves callable boundaries. It performs tracing, entrypoint validation, configured substitutions, and parameter-shape resolution, then collects the reachable callable graph into a program-level semantic view.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernelLike | QKernel or qkernel-like frontend object to prepare as a top-level entrypoint. |
bindings | dict[str, Any] | None | Compile-time values used while tracing and resolving parameter shapes. Defaults to None. |
parameters | list[str] | None | Argument names preserved as runtime parameters. Defaults to None. |
Returns:
PreparedModule — Hierarchical entrypoint, reachable callables,
call graph, and public ABI.
Raises:
ValueError— If a name appears in bothbindingsandparameters.EntrypointValidationError— If the top-level kernel uses quantum inputs or outputs.
resolve_parameter_shapes¶
def resolve_parameter_shapes(self, block: Block, bindings: dict[str, Any] | None = None) -> BlockPass 0.75: Resolve symbolic Vector parameter shape dims.
Qamomile circuits are compile-time fixed-structure. Parameter
Vector[Float] / Vector[UInt] inputs carry symbolic
{name}_dim{i} shape Values so frontend code like
arr.shape[0] returns a usable handle. This pass looks at
bindings and, for every parameter array that has a concrete
binding, substitutes those symbolic dims with constants so that
downstream loop-bound resolution sees fixed lengths.
Parameters without a concrete binding are left as-is; their symbolic dims are harmless as long as no compile-time structure decision depends on them (the library QAOA pattern).
set_config¶
def set_config(self, config: TranspilerConfig) -> NoneSet the transpiler configuration.
Parameters:
| Name | Type | Description |
|---|---|---|
config | TranspilerConfig | Transpiler configuration to use |
slice_borrow_check¶
def slice_borrow_check(self, block: Block) -> BlockPass 1.9: Post-fold slice-view linearity checker.
Runs after :meth:partial_eval has resolved slice bounds to
concrete values. Catches the slice-view linearity violations
that the trace-time frontend check cannot detect on its own —
specifically, slices whose bounds were symbolic at trace
time (so the frontend bulk-borrow tracker had to skip them)
and aliasing scenarios that only become visible once those
bounds are folded to constants:
A view whose newly-concrete coverage overlaps another live view of the same root parent.
A view whose newly-concrete coverage hits a slot that was consumed by a destructive operation earlier in the block.
Slice ownership changes that cannot be represented safely across control-flow boundaries.
Creating a direct element borrow (q[i]) emits no IR operation,
so this pass cannot observe the borrow site itself. Later uses of
that element do appear as operation operands and are checked for
conflicts with live slice views. Trace-time validation in
:func:qamomile.circuit.frontend.func_to_block._validate_returned_arrays
covers unreturned direct-element borrows that have no observable
operand use.
The pass is a pass-through for the IR — it only raises on violations and leaves the block unchanged on success.
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | Post-fold affine or hierarchical block to validate. |
Returns:
Block — The input block unchanged after successful validation.
Raises:
QubitBorrowConflictError— If live slice ownership conflicts with another view or direct access.QubitConsumedError— If a slice or operand accesses a slot already destroyed by a destructive operation.ValidationError— If the block kind is invalid or ownership cannot be propagated safely through control flow.
strip_slice_ops¶
def strip_slice_ops(self, block: Block) -> BlockPass 1.95: Remove SliceArrayOperation nodes from the block.
PartialEvaluationPass keeps these declarative ops through
constant folding so :meth:slice_borrow_check can use them
as view-declaration markers. Once the linearity check has run,
segmentation and downstream passes expect a classical-op-free
quantum stream — this pass performs that cleanup.
substitute¶
def substitute(self, block: Block) -> BlockPass 0.5: Apply substitutions (optional).
This pass rewrites inline callable targets and sets strategy names on boxed InvokeOperations 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: QKernelLike,
bindings: dict[str, Any] | None = None,
parameters: list[str] | None = None,
) -> BlockConvert a qkernel-like frontend object to a Block.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernelLike | QKernel or qkernel-like frontend object to convert. |
bindings | dict[str, Any] | None | Concrete values to bind at trace time, including values used to resolve array shapes. |
parameters | list[str] | None | Names to keep as unbound runtime parameters. |
Returns:
Block — Hierarchical block for the frontend object.
Raises:
ValueError— If a name appears in bothbindingsandparameters(propagated fromkernel.build), violating the bindings/parameters disjointness rule.
Always uses kernel.build() so Python defaults, required arguments,
runtime parameters, and array shapes follow one validated entry path.
to_circuit¶
def to_circuit(self, kernel: QKernelLike, bindings: dict[str, Any] | None = None) -> TCompile and extract just the quantum circuit.
This is a convenience method for when you just want the engine circuit without the full executable.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernelLike | QKernel or qkernel-like frontend object to compile. |
bindings | dict[str, Any] | None | Parameter values to bind. |
Returns:
T — Engine-specific quantum circuit.
transpile¶
def transpile(
self,
kernel: QKernelLike,
bindings: dict[str, Any] | None = None,
parameters: list[str] | None = None,
) -> ExecutableProgram[T]Full compilation pipeline from a qkernel-like object to executable.
Parameters:
| Name | Type | Description |
|---|---|---|
kernel | QKernelLike | QKernel or qkernel-like frontend object to compile. |
bindings | dict[str, Any] | None | Parameter values to bind (also resolves array shapes). Names in bindings and parameters must be disjoint — a name is either compile-time bound or runtime symbolic, never both. |
parameters | list[str] | None | Parameter names to preserve as engine parameters. Scalars/arrays of float/int/UInt are supported, plus Dict[K, Float]: each constant-key subscript lookup (d[key]) becomes one engine parameter named "d[<key>]", and the execution-time binding bindings={"d": {...}} is decomposed per key onto those parameters. A Dict runtime parameter is recorded in Block.param_slots as a slot whose type is a DictType (compile-time-bound Dicts and Tuple arguments stay out of the slot manifest); its emitted per-key parameters are visible via ExecutableProgram.parameter_names. |
Returns:
ExecutableProgram[T] — ExecutableProgram[T]: Executable wrapping the engine circuit
and the parameter metadata needed to re-bind runtime
parameters, ready for execution.
Raises:
ValueError— If a name appears in bothbindingsandparameters. A name being in both is ambiguous (placeholder value vs runtime symbol) and used to silently miscompile control-flow predicates that depended on parameter-array elements; rejecting the overlap up front keeps the contract unambiguous.QamomileCompileError— If compilation fails (validation, dependency errors)
Pipeline:
prepare: Trace and validate the entrypoint, apply configured substitutions, resolve parameter shapes, and preserve the reachable callable graph.
plan_circuit: Inline inline-policy calls, unroll recursion, validate affine and borrow rules, partially evaluate compile-time structure, analyze dependencies, and segment the program into the host-orchestrated C-to-Q-to-C model.
lower: Convert each quantum segment to immutable, engine-neutral
CircuitProgramIR.legalize: Select native intrinsics and Pauli-evolution realizations from target capabilities and compilation policy.
verify: Prove circuit structure and target legality before constructing engine objects.
materialize: Convert the legalized circuit IR to engine-native artifacts and preserve the executable ABI.
unroll_recursion¶
def unroll_recursion(self, block: Block, bindings: dict[str, Any] | None = None) -> BlockFixed-point loop of inline and branch lowering for recursion.
Each iteration unrolls one layer of self-referential inline
callable invocation and then lowers its compile-time base-case
IfOperation. Loop-carried Bit conditions remain visible until the
final validation pass so first-iteration constants cannot erase a real
backedge read. Terminates when no
inline callable invocation remains (success), when every residual call
is trapped inside an operation-owned block whose recursive callable
contract is unsupported (control / inverse / select over a recursive
kernel — raises a targeted error, see below), or when
MAX_UNROLL_DEPTH is reached (genuinely non-terminating top-level
recursion — raises).
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | The block to unroll. May be HIERARCHICAL (still containing self-referential callable invocations) or already AFFINE (returned unchanged). |
bindings | dict[str, Any] | None | Compile-time bindings used by condition lowering to select the base case. Defaults to None, meaning no bindings are applied. |
Returns:
Block — The fully unrolled, AFFINE block once no
inline callable invocation remains. Returned unchanged when the
input already has no calls.
Raises:
FrontendTransformError— If every remaining inline callable invocation is trapped inside aControlledUOperation.block, anInverseBlockOperationblock, or aSelectOperation.case_blocksentry (a self-recursive kernel was passed toqmc.control,qmc.inverse, orqmc.select), or if a genuinely non-terminating top-level recursion does not converge withinMAX_UNROLL_DEPTHiterations. The two cases carry distinct, cause-specific messages.
validate_symbolic_shapes¶
def validate_symbolic_shapes(self, block: Block) -> BlockPass 2.5: Reject unresolvable ForOperation loop bounds.
Runs after analyze so dependency info is complete. Raises
QamomileCompileError with an actionable message when a
gamma_dim0-style symbolic Value reaches a ForOperation
bound without being folded to a constant by
ParameterShapeResolutionPass, or when a loop bound depends
(directly or through classical arithmetic) on a runtime
parameter — loop bounds are compile-time structure and must be
provided via bindings, not parameters.
Parameters:
| Name | Type | Description |
|---|---|---|
block | Block | The analyzed block to validate. |
Returns:
Block — block, unchanged, when validation succeeds.
Raises:
QamomileCompileError— If a loop bound is an unresolved parameter shape dim or depends on a runtime parameter.