Runtime

ExecutionRuntime is the coordinator of the canonical pipeline:

Program -> ExecutionPlan -> Target -> Backend -> Job -> Execution -> Result

It prepares a plan, optionally compiles it against a target (reusing the Compiler), submits it to the selected backend and collects the completed job into an enriched BackendResult.

One-shot execution

from microquantum import (
    ExecutionPlan,
    ExecutionRuntime,
    QuantumCircuit,
    StatevectorBackend,
)

qc = QuantumCircuit(2).h(0).cx(0, 1)
runtime = ExecutionRuntime(backend=StatevectorBackend())
result = runtime.execute(qc, shots=1024, seed=1)
print(result.counts)

plan = ExecutionPlan.from_circuit(qc, backend="local_simulator", shots=512, seed=2)
result = runtime.execute(plan)

Configuration

RuntimeConfig holds the runtime’s defaults as one frozen, JSON-safe value: the fallback backend (an instance or a registered name), the BackendRegistry used to resolve names, the default compile target, the history cap and the default compiler optimization level. Only options the runtime actually honours exist — there is no configuration surface for behaviour the runtime cannot support.

from microquantum import ExecutionRuntime, RuntimeConfig

rt = ExecutionRuntime(
    config=RuntimeConfig(
        backend="local_simulator",
        history_size=50,
        default_optimization_level=1,
    )
)
reconfigured = rt.configure(history_size=200)   # new runtime, original untouched
assert rt.config.history_size == 50

Legacy keyword arguments (backend=, registry=, history_size=, default_optimization_level=, default_target=) remain supported and override the config. A runtime built from a bare circuit applies default_optimization_level when the plan carries none.

Runtime internals

  • prepare(plan) — validate; compile(work, optimization_level=...) — optional compilation; submit(work, backend=...) -> Job; execute(work) — the one-shot entry point (prepare -> dispatch -> collect).

  • ExecutionStrategy decides DIRECT vs COMPILED dispatch (pluggable handlers; register_custom_strategy); ExecutionTrace records each execution’s prepared -> bound/compiled -> validated -> submitted -> completed/failed lifecycle with timing.

  • Backend resolution: plan.backend (instance or name) > explicit default > registry default > lazily-created statevector simulator.

Errors

Failures are tagged with the pipeline stage they occur in. Every stage error subclasses ExecutionError, which itself subclasses ValueError — so existing except ValueError code keeps working while callers that care can catch precisely:

  • PlanningError — invalid plans, unbound or unknown parameter bindings, dynamic circuits that were not converted.

  • CompilationError — work incompatible with an explicit target, or a compiled plan found incompatible at dispatch.

  • RuntimeDispatchError — the plan cannot run on the selected backend (capability or backend.validate(...) problems, no matching strategy handler).

  • BackendExecutionError — the submitted job failed, was cancelled or produced no result.

TypeError plan-shape errors (e.g. prepare(object())) are intentionally not wrapped, so misuse of the API stays a distinct signal. Wide except ValueError from earlier versions continues to catch every stage error.

Introspection

runtime_info() returns a RuntimeInfo snapshot describing the runtime as it is — nothing is guessed or hand-maintained:

from microquantum import runtime_info

info = runtime_info(runtime)
print(info.runtime, info.version)      # e.g. 'ExecutionRuntime' '1.1.0'
print(info.strategies)                 # sorted ExecutionStrategy values
print(info.default_backend)            # backend used when a plan names none
print(info.backends)                   # live capability summaries per backend

Backend summaries are derived from each backend’s BackendCapabilities in the live registry, so they can never go stale; info.to_dict() is JSON-safe.

Orchestration helpers

  • execute_batch(works) / submit_batch(works) — many plans together; with raise_on_error=False a failing item is reported in place.

  • execute_records(works) — one ExecutionRecord per input, in order, never dropping failures (see Execution Records).

  • run_parameter_sweep(circuit, bindings-or-floats) — one circuit over many bindings.

  • run_experiment(experiment) / run_hybrid(build, update) — the higher-level orchestration (Experiments).

  • Module-level execute(), submit(), execute_batch(), submit_batch(), execute_records(), run_hybrid() wrap a shared default_runtime.

Command line

The microquantum console script (python -m microquantum) exposes info, backends and run from the shell — see Command Line.

Design note

The runtime is not a backend: it never re-implements simulation or provider logic, and any user-provided Backend can be dropped in through a plan’s backend field.