Backends, profiles and export¶
This page covers the backends that run a Plan's circuits, the device profiles that forecast time and memory before a run, and the functions that export circuits as OpenQASM.
from nwqlib.backends import AerBackend, Allocation, DeviceProfile, assess
from nwqlib.io import export_qasm, write_qasm3_file
Pass a backend as backend= to solve or prepare. Without one, a quantum Plan runs on AerBackend(). The expectation of Z in the state |0> is exactly 1:
from nwqlib import Expectation, solve
from nwqlib.algorithms import ExpectationMethod
from nwqlib.backends import AerBackend
problem = Expectation(state=[1.0, 0.0], observable=[[1.0, 0.0], [0.0, -1.0]])
result = solve(problem, method=ExpectationMethod(), backend=AerBackend(),
seed=7)
print(result.value) # 1.0
Choose a backend¶
| Backend | Class | Readouts | Needs | Guide |
|---|---|---|---|---|
| Qiskit Aer, local | AerBackend |
Counts, and exact Pauli expectations, probabilities and amplitudes | nwqlib[aer] |
Aer |
| NWQ-Sim, local | NWQSimBackend |
Counts. CPU statevector also gives exact Pauli expectations, probabilities and amplitudes | A runner built for one backend and method | NWQ-Sim |
| NWQ-Sim on a Slurm cluster | NWQSimSlurmBackend with SlurmProfile |
As NWQ-Sim | A runner built at the site and a Slurm account | Slurm |
| IBM Quantum | IBMRuntimeBackend |
Counts and provider expectation estimates | nwqlib[ibm] and a saved IBM account or a token in NWQLIB_IBM_RUNTIME_TOKEN |
IBM Runtime |
| IonQ QPU | IonQBackend |
Raw counts | nwqlib[ionq] and an API key in NWQLIB_IONQ_API_KEY |
IonQ |
| Quantinuum H2 through Nexus | NexusBackend |
Counts | nwqlib[nexus] and an existing qnexus login |
Nexus |
Every backend except Aer runs jobs that continue after Python exits. Save the Run to a directory and reopen it with load_run, as Continue an interrupted run describes. The cloud and Slurm backends have offline checks only, and each Run states its qualification once. Choose a backend compares them, and Backend adapter contract states the rules every backend implements.
AerBackend ¶
Bases: Record
Local Qiskit Aer simulator, the default backend of prepare and solve.
Build it with AerBackend() for noiseless simulation, or with
AerBackend.from_noise_model(model) for a Qiskit Aer noise model, and pass
it as backend= to solve or
prepare. It needs the aer extra
(pip install "nwqlib[aer]") and no credentials. A noise model acts on
sampled counts only. An exact expectation, probability or amplitude would
describe neither the noiseless circuit nor the noisy samples, so those readouts
reject a noisy backend before any circuit is built.
The backend holds the caller's NoiseModel object without copying or
serializing it, so keep that model unchanged while this backend or its
prepared circuits are in use. Run.save stores the model as the SDK's
dictionary with NumPy array files, and load_run binds the rebuilt model to
the reopened Run's own copy of this configuration (run.backend), leaving
the backend passed to load_run unchanged. revise keeps the bound model
while noise_model_id is unchanged. The Aer guide covers
readouts, noise and circuit inspection.
Attributes:
-
noise_model_id(Text | None) –Default
None, no noise model.from_noise_modelsets it to a fresh UUID that identifies the binding, not the model's contents. A configuration rebuilt from JSON with this field set holds no model and raises when used.
from_noise_model ¶
from_noise_model(model)
Return an Aer backend that applies a Qiskit Aer noise model to sampled counts.
The model is held without copying, and qiskit_aer is imported only by
this call.
Parameters:
-
model(NoiseModel) –The noise model to apply.
Returns:
-
backend(AerBackend) –A new backend whose
noise_model_idis a fresh UUID.
Raises:
-
TypeError–If
modelis not a Qiskit AerNoiseModel.
NWQSimBackend ¶
Bases: Record
NWQ-Sim simulator run locally as a detached process, with statevector or density-matrix simulation.
Build it with keyword arguments, for example
NWQSimBackend(executable=..., spool=..., max_input_bytes=..., max_output_bytes=..., max_buffer_bytes=...),
and pass it as backend= to prepare.
executable, spool and the three byte limits are required. The executable
is a runner built for one backend and method pair with
python -m nwqlib.backends.nwqsim (see the NWQ-Sim guide).
Construction launches and inspects nothing.
Preparation translates each circuit to Qiskit's U and CX gates. The runner keeps
running after the Python process exits, so the computer that runs it must stay
on until the job finishes. The guide records the qualified NWQ-Sim revision
and the byte formulas behind max_buffer_bytes.
Attributes:
-
backend(Literal['CPU', 'MPI', 'NVGPU', 'AMDGPU', 'NVGPU_MPI']) –Default
"CPU"."CPU","MPI","NVGPU"or"AMDGPU"."NVGPU_MPI"is rejected, because its constructors read an uninitialized GPU memory counter in the inspected NWQ-Sim sources. -
method(Literal['SV', 'DM']) –Default
"SV"."SV"(statevector) or"DM"(density matrix)."MPI"supports"SV"only, because its factory silently substitutes SV for DM. -
ranks(PositiveInt) –Default
1. Positive. Number of cooperating MPI processes. Only"MPI"accepts more than one, and it requires a power of two. -
mpi_launcher(Text) –Default
"mpirun". Installed launcher for local MPI runs. -
executable(Text) –Required. Absolute path of the built runner.
-
spool(Text) –Required. Absolute path of the directory for request and result files. It identifies a detached job after Python exits, so it cannot be relative.
-
max_input_bytes(PositiveInt) –Required. Positive. Limit in bytes on each request file.
-
max_output_bytes(PositiveInt) –Required. Positive. Limit in bytes on each result file that NWQLib reads.
-
max_buffer_bytes(PositiveInt) –Required. Positive. Limit in bytes on the known state, work and sample arrays of each process, including host and device storage on a GPU. It excludes fused gates, SDK workspace and whole-process memory.
-
optimization_level(Count) –Default
0. Qiskit transpiler level, 0 to 3, of the translation to U and CX gates. A level other than 0 is recorded as the exclusion"optimization_level"in the preparation record, so the record has no certified state error and its error numbers are a reference, and the operation count describes the compiled circuit. Levels 2 and 3 resynthesize two-qubit blocks with Qiskit's own synthesis. At those levels an exact readout or trajectory is refused when transpilation relabels wires by removing permutations, because the runner reads the output in logical wire order, and a measured circuit can still supply computational-basis probabilities when transpilation reports no layout. Amplitude readouts require level 0 or 1, or a circuit without measurements, because removing terminal diagonal gates can change relative phases.
Raises:
-
ValueError–If the backend, method and rank combination is not supported, or if
executableorspoolis not an absolute path.
NWQSimSlurmBackend ¶
Bases: Record
NWQ-Sim run as a Slurm batch job on a cluster.
Build it with keyword arguments, for example
NWQSimSlurmBackend(profile=..., accounting_since=..., accounting_until=..., max_input_bytes=..., max_output_bytes=..., max_buffer_bytes=..., max_response_bytes=..., timeout_seconds=...),
and pass it as backend= to prepare. Every
argument except optimization_level is required. The profile holds the
runner, its build and the pending-job directory (spool). Submission calls sbatch once,
and a job whose acknowledgement was lost is found again by its job name in
Slurm accounting within the configured time window. Only offline scheduler
and protocol checks qualify this backend, and the site allocation, runner and
hardware have no live qualification. The Slurm guide shows a
complete run.
Attributes:
-
profile(SlurmProfile) –Required. The
SlurmProfile. Its total rank count and GPU request are checked against its route. -
accounting_since(Text) –Required. Start of the accounting search window, an ISO time without a time zone, read in the site's local time. Choose a window that covers the intended submission period.
-
accounting_until(Text) –Required. End of that window, later than
accounting_since. -
max_input_bytes(PositiveInt) –Required. Positive. Limit in bytes on each request file, as in
NWQSimBackend. -
max_output_bytes(PositiveInt) –Required. Positive. Limit in bytes on each result file.
-
max_buffer_bytes(PositiveInt) –Required. Positive. Limit in bytes on the runner's known arrays per process, as in
NWQSimBackend. -
max_response_bytes(PositiveInt) –Required. Positive. Limit in bytes on the output of each scheduler command. It must cover the
sbatch --parsablereply, 12 bytes plus the cluster name's length (22 bytes forperlmutter). -
timeout_seconds(Real) –Required. Positive deadline in seconds for each scheduler command.
-
optimization_level(Count) –Default
0. Qiskit transpiler level of the translation to U and CX gates, as inNWQSimBackend, with the same exclusion"optimization_level"at any other level.
Raises:
-
ValueError–If the rank or GPU request does not fit the route, the accounting window has a time zone or is not increasing, or
timeout_secondsis not positive.
SlurmProfile ¶
Bases: Record
Slurm site settings for an NWQ-Sim runner: allocation, runner, binding and shared pending-job directory.
Build it with keyword arguments, for example
SlurmProfile(cluster=..., account=..., walltime="00:05:00", nodes=1, ranks_per_node=1, threads=1, executable=..., build_identity=..., spool=...),
and pass it as profile= to NWQSimSlurmBackend.
cluster, account, walltime, nodes, ranks_per_node, threads,
executable, build_identity and spool are required. Node, rank and thread
counts describe the requested resources, not measured use. Every option value
must be one literal token, so that it cannot end its #SBATCH line and add
another directive. The Slurm guide gives Perlmutter and
Frontier profiles.
Attributes:
-
cluster(Text) –Required. One cluster name, letters, digits,
_and-only."all"and comma lists are rejected, because job lookups name exactly one cluster. -
account(Text) –Required. Slurm account to charge.
-
partition(Text | None) –Default
None. Slurm partition. -
qos(Text | None) –Default
None. Slurm quality of service. -
constraint(Text | None) –Default
None. Slurm node constraint, such as"gpu". -
walltime(Text) –Required. Positive time limit in Slurm's
[days-]hours:minutes:secondsform. -
nodes(PositiveInt) –Required. Positive. Number of nodes.
-
ranks_per_node(PositiveInt) –Required. Positive. MPI ranks per node.
-
threads(PositiveInt) –Required. Positive. Threads per rank.
-
gpus_per_task(PositiveInt | None) –Default
None. Positive. GPUs per task, given together withgpu_bind. The"NVGPU"and"AMDGPU"routes require exactly 1, and the CPU and MPI routes requireNone. -
gpu_bind(Text | None) –Default
None. Slurm GPU binding, given together withgpus_per_task. -
cpu_bind(Text) –Default
"cores". Slurm CPU binding. -
modules(tuple[Text, ...]) –Default
(). Environment modules to load before the run. -
executable(Text) –Required. Absolute path of the runner on the compute nodes.
-
build_identity(Text) –Required. Source commit of the runner's NWQ-Sim build. It records which build ran and does not qualify a GPU or distributed implementation.
-
spool(Text) –Required. Absolute path of a directory shared with the compute nodes.
-
backend(Literal['CPU', 'MPI', 'NVGPU', 'AMDGPU', 'NVGPU_MPI']) –Default
"CPU". NWQ-Sim route, as inNWQSimBackend. -
method(Literal['SV', 'DM']) –Default
"SV"."SV"or"DM", as inNWQSimBackend.
Raises:
-
ValueError–If the route is not supported,
clusteris not one name, an option value is not one token,walltimeis malformed or zero,gpus_per_taskandgpu_bindare not given together, or a path is not absolute.
script ¶
script(submission_id, *, max_input_bytes)
Return the Slurm batch script for one submission, without running it.
Use it to inspect what a submission would send to sbatch. Rendering a
script does not qualify a site. The job name nwqlib-<submission UUID> is
what a lost submission acknowledgement is searched for. --no-requeue keeps
Slurm from running the same request a second time after a node failure or
preemption, and srun --kill-on-bad-exit stops all ranks when one fails.
Batch stdout and stderr go to /dev/null, because only the runner's result
file is read.
Parameters:
-
submission_id(str) –Submission UUID that names the job and its subdirectory of
spool. -
max_input_bytes(int) –Positive limit in bytes on the request file, passed to the runner.
Returns:
-
script(str) –The script text, ending with a newline.
Raises:
-
ValueError–If
max_input_bytesis not a positive integer. -
ValueError–If
submission_idis not a canonical UUID.
IBMRuntimeBackend ¶
Bases: Record
IBM Quantum Runtime connection for sampled counts and provider expectation estimates.
Build it with keyword arguments, for example
IBMRuntimeBackend(device="ibm_example", instance="my-instance", max_input_bytes=65_536),
and pass it as backend= to prepare.
device, instance and max_input_bytes are required. It needs the ibm
extra. Counts use SamplerV2 and a provider estimate uses EstimatorV2.
Construction reads no credential and contacts no service. Preparation and
retrieval use the saved SDK account named by account_name, or otherwise the
token in the environment variable named by token_env, and no credential is
stored in the configuration or the Run's files.
Preparation compiles each circuit for the device with the Plan's runtime seed
and keeps the logical-to-physical layout. The Estimator's resilience level is
zero unless options_json selects another, so no error mitigation runs
implicitly, and the Plan sets the precision. The Run bounds serialized
buffers and decoded arrays. SDK HTTP buffering, retries, compilation memory,
wall time and billing are not bounded. A refresh keeps the results already
decoded when a later result fails to decode. A resumed read fetches the
whole job payload again, and results already saved skip only the local
decoding. Only offline SDK and transport checks qualify this backend, and live
accounts, queues and devices are unqualified. The IBM Runtime guide
describes jobs, retrieval and cancellation.
Attributes:
-
device(Text) –Required. IBM device name.
-
instance(Text) –Required. IBM instance.
"auto"is rejected, because retrieval and job recovery compare it with the job's own instance. -
account_name(Text | None) –Default
None. Name of a saved IBM SDK account. WithNone, the token is read from the variabletoken_envnames. -
token_env(Text) –Default
"NWQLIB_IBM_RUNTIME_TOKEN". Environment variable that holds the API token, read only during preparation or retrieval. -
mode(Literal['job', 'batch', 'session']) –Default
"job"."batch"or"session"attaches every job to the existing containercontainer_id. -
container_id(Text | None) –Default
None. ID of an existing Batch or Session. Required in batch and session mode, and must beNonein job mode. -
calibration_id(Text | None) –Default
None. Device calibration ID passed to the IBM SDK when the device is opened. -
options_json(Text) –Default
"{}". JSON object of the requested primitive options. It states the requested options, not the server's defaults. Experimental option overrides are rejected, because they can bypass the requested readout and its uncertainty. -
optimization_level(Count) –Default
1. Qiskit preset pass-manager level, 0 to 3. A level other than 1 is recorded as the exclusion"optimization_level"in the preparation record, and the operation count describes the compiled circuit. The IBM target has no derived roundoff constant, sostate_error()gives no bound at any level. -
initial_layout(tuple[Count, ...] | None) –Default
None. Physical qubit for each logical qubit, without repeats. -
max_input_bytes(PositiveInt) –Required. Positive. Limit in bytes on the QPY copy of each prepared circuit, which only a Run saved to a directory writes.
Raises:
-
ValueError–If
container_idis given in job mode or missing in batch or session mode, ifinstanceis"auto", or ifinitial_layoutrepeats a qubit.
IonQBackend ¶
Bases: Record
IonQ connection for raw sampled counts on an IonQ QPU, through the v0.4 REST API.
Build it with keyword arguments, for example
IonQBackend(device="qpu.forte-1", max_input_bytes=1_000_000, max_response_bytes=1_000_000),
and pass it as backend= to prepare.
device, max_input_bytes and max_response_bytes are required. It needs
the ionq extra. Construction imports no SDK and contacts no service. The API
key is read from the environment variable named by token_env only when a job
is submitted or retrieved, and it is never stored.
Each operation is one HTTP request, so no SDK retry can create a second job.
IonQ's v0.4 API offers no qualified way to find a job by name, so a lost
submission acknowledgement leaves the outcome uncertain, and Run.wait raises
RunFailed without submitting a replacement. Only raw histograms are read, because
IonQ's probability results are not counts of shots. The Run bounds decoded
data and stored observations. Only offline SDK and API checks qualify this
backend, and live QPU behavior is unqualified. The IonQ guide
gives the API sources, batch limits and histogram decoding.
Attributes:
-
device(Text) –Required. A v0.4 QPU name starting with
qpu.. The ideal simulator is rejected because it ignores the requested shots. -
gateset(Literal['qis', 'native']) –Default
"qis"."qis"translates circuits with Qiskit to Rx, Ry, Rz and CX, with angles in radians."native"passes IonQ native gates unchanged, with angles in turns. -
debiasing(StrictBool) –Default
False, the only supported value. A debiased job returns separate variant populations whose qubit-map direction the v0.4 job schema does not define, so they cannot be read as one set of counts. -
token_env(Text) –Default
"NWQLIB_IONQ_API_KEY". Environment variable that holds the API key. -
max_input_bytes(PositiveInt) –Required. Positive. Limit in bytes on the serialized request and the optional QPY copy of each prepared circuit.
-
max_response_bytes(PositiveInt) –Required. Positive. Limit in bytes on each HTTP response body that NWQLib reads. It does not bound network buffers, provider work, billing or process memory.
-
request_timeout_seconds(Real) –Default
30.0. Positive. Connect and read timeout of each request in seconds, not a deadline for the whole request. -
optimization_level(Count) –Default
0. Qiskit transpiler level, 0 to 3, of the"qis"translation. The"native"gateset accepts only 0. Levels 2 and 3 resynthesize two-qubit blocks with Qiskit's own synthesis. A level other than 0 is recorded as the exclusion"optimization_level"in the preparation record, and the operation count describes the compiled circuit. The IonQ target has no derived roundoff constant, sostate_error()gives no bound at any level.
NexusBackend ¶
Bases: Record
Quantinuum Nexus connection for sampled counts on an H2 device or emulator.
Build it with keyword arguments, for example
NexusBackend(project="<project UUID>", device="H2-1", max_input_bytes=1_000_000),
and pass it as backend= to prepare.
project, device and max_input_bytes are required. It needs the nexus
extra. Construction imports no SDK and does not log in. Authentication uses the
user's existing qnexus configuration.
Preparation uploads and compiles each circuit as separate remote steps, and execution sends one job per batch. The Run bounds the data it stores, not HTTP buffering, billing or SDK memory. qnexus 0.49 has no public per-request timeout, so a refresh avoids waiting in the provider queue but one HTTP request can still block indefinitely. Only offline SDK and converter checks qualify this backend, and live compilation and execution are unqualified. The Nexus guide gives the preparation boundary, costs and the qnexus dependency conflict.
Attributes:
-
project(Text) –Required. UUID of an existing Nexus project.
-
device(Text) –Required. An H2 device name,
H2-<n>, with suffixEorLEfor the emulators. Helios devices take HUGR or QIR programs, a separate route that this backend does not submit. -
target_region(Literal['us', 'sg']) –Default
"us". Execution region,"us"or"sg". -
credential_name(Text | None) –Default
None. Name of a Nexus-linked credential, never a secret. -
optimization_level(Count) –Default
1. Nexus compile level, 0 to 3. A level other than 1 is recorded as the exclusion"optimization_level"in the preparation record. The H2 target has no derived roundoff constant, sostate_error()gives no bound at any level. -
max_cost_hqc(Nonnegative | None) –Default
None, no cap. Nonnegative. Cost cap per submitted program, in Hardware Quantum Credits. -
max_input_bytes(PositiveInt) –Required. Positive. Limit in bytes on the JSON encoding of each prepared pytket circuit.
Raises:
-
ValueError–If
deviceis not an H2 device name.
Forecast cost and feasibility¶
A DeviceProfile describes a machine and its time models, and an Allocation the resources granted to a workload. nwqlib.estimate(plan, profile=profile, allocation=allocation) forecasts every point of the Plan and returns a PlanEstimate. assess forecasts one point. Nothing runs, and the numbers below are synthetic, not measurements of a machine. The one-qubit Plan prepares |1> as H, Z, H and reads <Z> exactly, which counts one invocation, one exact evaluation and three logical operations, so the engineering model predicts 0.25 + 0.5 + 3 × 0.125 = 1.125 seconds:
from datetime import datetime, timezone
from nwqlib import Expectation, plan
from nwqlib.algorithms import ExpectationMethod
from nwqlib.backends import (
AER_STATEVECTOR_TARGET, Allocation, DeviceConfiguration, DeviceProfile,
ModelDomain, TimeCoefficient, TimeModel, assess,
)
from nwqlib.core import Limit, Source, Unit
from nwqlib.evidence import Evidence
from nwqlib.operators import ingest_pauli
from nwqlib.problems.inputs import ingest_occupation
problem = Expectation(state=ingest_occupation("1", num_qubits=1),
observable=ingest_pauli((("Z", 1.0),), num_qubits=1))
selected = plan(problem, method=ExpectationMethod(preparation_choice="hzh"),
seed=7)
source = Source(name="example profile", version="1",
domain="synthetic numbers, not a measured machine",
reference="api/backends.md")
start = datetime(2026, 1, 1, tzinfo=timezone.utc)
end = datetime(2027, 1, 1, tzinfo=timezone.utc)
target = AER_STATEVECTOR_TARGET # NWQLib's declared Aer statevector target
machine = DeviceConfiguration(
name="example machine", version="1", target=target, hardware=source,
runtime=Source(name=target.name, version="1", domain="example runtime",
reference="api/backends.md"),
build=source, compiler=source, precision="complex128",
representation="statevector")
spec = Evidence(kind="external_specification", source=source)
grant = Allocation(
name="example grant", configuration_id=machine.content_id,
locations=("logical_device",), topology="single_device",
limits=(Limit(stage="execution", metric="memory",
unit=Unit(symbol="byte", dimension="bytes"),
kind="capacity_stock", value=2**30,
scope="logical_device"),),
recorded_at=start, valid_until=end, evidence=spec)
domain = ModelDomain(
configuration_id=machine.content_id, allocation_id=grant.content_id,
basis="selected_logical", batch_schedule="unspecified",
acquisition="direct_observation", runtime="seed_independent",
population="unconditional", readouts=("pauli_expectation",),
selection_ids=(), primitive_gates=("h", "z"),
min_qubits=1, max_qubits=1, min_operations=0, max_operations=10,
max_shots=0, max_exact_evaluations=1, max_readout_items=1,
max_resets=0, max_measurements=0, max_classical_work=0,
max_adaptive_rounds=0)
model = TimeModel(
name="example timing", kind="engineering",
scope="selected_acquisition",
coefficients=(
TimeCoefficient(feature="invocations", seconds_per_unit=0.25,
unit="s/invocation"),
TimeCoefficient(feature="exact_evaluations", seconds_per_unit=0.5,
unit="s/exact_evaluation"),
TimeCoefficient(feature="logical_operations", seconds_per_unit=0.125,
unit="s/logical_operation")),
domain=domain, recorded_at=start, valid_until=end,
evidence=Evidence(kind="numerical_estimate", source=source),
assumptions=("synthetic coefficients for this example",))
profile = DeviceProfile(configuration=machine, recorded_at=start,
valid_until=end, evidence=spec, models=(model,))
forecast = assess(selected, selected.resolve("expectation"),
profile=profile, allocation=grant,
assessed_at=datetime(2026, 6, 1, tzinfo=timezone.utc))
print(forecast.time.status) # conditional
print(forecast.predictions[0].seconds.value) # 1.125
The machine's target is a BackendTarget, here the built-in AER_STATEVECTOR_TARGET for exact readouts. An engineering model's prediction is conditional on its stated assumptions. The profiles guide defines the five axes, the memory comparison and the time models.
DeviceProfile ¶
Bases: Record
A stored description of one machine: its configuration, advertised limits and named time models.
Build it with keyword arguments, for example
DeviceProfile(configuration=..., recorded_at=..., valid_until=..., evidence=..., models=(model,)),
and pass it as profile= to nwqlib.estimate, nwqlib.compare or
assess. configuration,
recorded_at, valid_until and evidence are required. The profile is data
the caller supplies. NWQLib never discovers a machine or refreshes a
profile. New calibration makes a new profile with a new content hash, so an
earlier assessment is never rewritten. The profiles guide
explains the assessment, and the example under
Forecast cost and feasibility builds a
small profile.
Attributes:
-
configuration(DeviceConfiguration) –Required. The
DeviceConfiguration. -
limits(tuple[Limit, ...]) –Default
(). Advertised limits asLimitrecords, at most one per stage, metric and scope. -
recorded_at(Timestamp) –Required. Time zone-aware time the profile was recorded, stored in UTC.
-
valid_until(Timestamp) –Required. Time zone-aware end of validity, not before
recorded_at. -
evidence(Evidence) –Required. The specification the profile rests on, not a record of an execution.
-
models(tuple[TimeModel, ...]) –Default
().TimeModelrecords with distinct names.
Raises:
-
ValueError–If
valid_untilprecedesrecorded_at, two limits share a stage, metric and scope, or two models share a name.
DeviceConfiguration ¶
Bases: Record
The machine a device profile describes: target, hardware, runtime, build, compiler and numerical precision.
Build it with keyword arguments and pass it as configuration= to
DeviceProfile. name, version,
target, hardware, runtime and build are required. Its content hash
(content_id) is what an Allocation
and a ModelDomain name as their
configuration_id, so a time model can refer to the machine without referring
to the profile that contains it. An optional field left None stays unknown
in an assessment.
Attributes:
-
name(Text) –Required. Name of the stored specification.
-
version(Text) –Required. Version of the stored specification.
-
target(BackendTarget) –Required. The backend target the machine supports, the same target record that backend adapters declare.
-
hardware(Source) –Required. Source describing the hardware.
-
runtime(Source) –Required. Source of the intended runtime. Its
namemust equaltarget.name. It describes what preparation is expected to use, not an observed preparation record. -
build(Source) –Required. Source of the implementation and build configuration.
-
compiler(Source | None) –Default
None. Source of the intended compiler. -
precision(Literal['complex64', 'complex128', 'float64'] | None) –Default
None."complex64","complex128"or"float64". -
representation(Literal['statevector', 'density_matrix', 'tensor', 'hardware', 'classical'] | None) –Default
None."statevector","density_matrix","tensor","hardware"or"classical".
Raises:
-
ValueError–If
runtime.namediffers fromtarget.name.
BackendTarget ¶
Bases: Record
What a simulator, cloud provider or export target supports, for profile assessment.
Pass it as target= to a
DeviceConfiguration.
Start from a built-in target such as
AER_STATEVECTOR_TARGET
and change fields with revise, or build one with keyword arguments,
for example BackendTarget(name="my_target", provider="my_provider").
name and provider are required. For each optional collection,
None means unknown and an empty tuple means none, so profile
assessment can tell an undeclared subset from an unsupported one. A
coarse capability never certifies a readout or instruction that the
target does not list. The profiles guide shows how
these declarations decide the capability check.
Attributes:
-
name(Text) –Required. Backend or target name.
-
provider(Text) –Required. Provider family, such as
"qiskit_aer"or"ionq". -
capabilities(tuple[BackendCapability, ...] | None) –Default
None, unknown. Coarse execution capabilities, such as"statevector","counts"or"noise_model". -
description(str) –Default
"". Text for reports. -
native_basis_gates(tuple[Text, ...]) –Default
(). Native or preferred basis gates when known, in the given order. -
max_qubits(Count | None) –Default
None. Advertised or configured qubit limit. -
artifacts(tuple[Text, ...] | None) –Default
None, unknown. Accepted input forms, such as"selected_construction"(a Plan's construction), which profile assessment requires. -
readouts(tuple[Literal['pauli_expectation', 'counts', 'probabilities', 'host_scalars', 'amplitudes', 'estimated_observable', 'trajectory'], ...] | None) –Default
None, unknown. Supported observation kinds among"pauli_expectation","counts","probabilities","host_scalars","amplitudes","estimated_observable"and"trajectory", declared separately fromcapabilities."trajectory"is the exact schedule with several observation points, and each point also needs its own readout kind listed. -
readout_features(tuple[Literal['multi_position', 'views'], ...] | None) –Default
None, unknown. Trajectory features the target executes:"multi_position"(several observation points of one coherent state in one execution) and"views"(reversible basis changes before a Pauli or probability point, undone exactly afterwards). -
reducers(tuple[Text, ...] | Literal['registered'] | None) –Default
None, unknown. The registered reducers that the target runs at a trajectory point, which turn a saved state into statistics during execution: a tuple of reducer names, or"registered"for every reducer innwqlib.core.planning.READOUT_REDUCERS. -
host_dependencies(tuple[Text, ...] | None) –Default
None, unknown. Packages available to classical routines on this target. Profile assessment requires every dependency that a chosen routine declares to be listed. -
instructions(tuple[InstructionSupport, ...] | None) –Default
None, unknown. Exact instruction subset, including controls and adjoints, asInstructionSupportrecords, each naming one primitive gate or one implementationSourceand its width. -
program_nodes(tuple[Text, ...] | None) –Default
None, unknown. SupportedProgramnode kinds.
Raises:
-
ValueError–If a collection declares a value twice.
AER_STATEVECTOR_TARGET ¶
AER_STATEVECTOR_TARGET = BackendTarget(name='aer_statevector', provider='qiskit_aer', capabilities=capability_set(BackendCapability.STATEVECTOR), description='Qiskit Aer exact statevector simulator.', readouts=('pauli_expectation', 'probabilities', 'amplitudes', 'trajectory'), readout_features=('multi_position', 'views'), reducers='registered')
Built-in target of the Qiskit Aer statevector simulator, for exact readouts.
It declares the statevector capability and the readouts pauli_expectation,
probabilities, amplitudes and trajectory, with the trajectory features
multi_position and views and every registered reducer. It leaves
artifacts, instructions and program_nodes unknown. Use it as
DeviceConfiguration(target=...) for exact readouts, and use
AER_COUNTS_TARGET for sampled
shots. It is a stored declaration that imports no SDK, not a live device
inventory.
AER_COUNTS_TARGET ¶
AER_COUNTS_TARGET = BackendTarget(name='aer_counts', provider='qiskit_aer', capabilities=capability_set(BackendCapability.COUNTS, BackendCapability.NOISE_MODEL), description='Qiskit Aer finite-shot measured circuit simulator.', readouts=('counts',))
Built-in target of the Qiskit Aer simulator with measured shots.
It declares the counts and noise_model capabilities and the counts
readout. It leaves readout_features, reducers, artifacts, instructions
and program_nodes unknown. Use it as DeviceConfiguration(target=...) for a
Plan with sampled shots. It is a stored declaration that imports no SDK, not a
live device inventory.
TimeModel ¶
Bases: Record
A named linear model of time in seconds, the sum of coefficient times feature count, for one scope.
Build it with keyword arguments and pass it in models= of
DeviceProfile. Every field except
form, calibration and uncertainty is required. The one supported form,
acquisition_linear/1, is
seconds = c_invocation * invocations + c_shot * sampled_shots
+ c_exact * exact_evaluations + c_operation * logical_operations
over the feature counts of the resource estimate, so it is evaluated without running anything (Finite time models). An engineering model states assumed coefficients and gives conditional numbers under its assumptions. A calibrated model keeps its supplied calibration sources and uncertainty unchanged. Neither kind collects calibration data. An expired, future-dated or out-of-domain model gives an unavailable prediction with its reason.
Attributes:
-
form(Literal['acquisition_linear/1']) –Default
"acquisition_linear/1", the only accepted value. Arbitrary expressions and plugins are rejected. -
name(Text) –Required. Model name, unique within the profile.
-
kind(Literal['engineering', 'calibrated']) –Required.
"engineering"for assumed coefficients or"calibrated"for coefficients from a supplied calibration. -
scope(TimeScope) –Required. What the seconds cover:
"selected_acquisition","acquisition_overhead"or"native_call_wall". The first two exclude planning, compilation, queue delay, analysis and whole-run cost."native_call_wall"covers the synchronous backend call, including waiting and result extraction, and excludes preparation and saving. The scopes overlap, so their predictions must not be added, and none covers a whole run. -
coefficients(tuple[TimeCoefficient, ...]) –Required. One to four
TimeCoefficientrecords with distinct features. -
domain(ModelDomain) –Required. The
ModelDomainof workloads the model is valid for. -
recorded_at(Timestamp) –Required. Time zone-aware time the model was recorded, stored in UTC.
-
valid_until(Timestamp) –Required. Time zone-aware end of validity, not before
recorded_at. -
evidence(Evidence) –Required. Evidence of kind
"numerical_estimate"for an engineering model or"empirical_prediction"for a calibrated one. -
assumptions(tuple[Text, ...]) –Required. At least one stated assumption.
-
calibration(CalibrationReference | None) –Default
None. TheCalibrationReference, required for a calibrated model and not allowed for an engineering one. -
uncertainty(ModelUncertainty | None) –Default
None. TheModelUncertainty, required for a calibrated model.
Raises:
-
ValueError–If
valid_untilprecedesrecorded_at, a feature repeats,calibrationdoes not matchkind, the evidence kind does not matchkind, or a calibrated model has nouncertainty.
TimeCoefficient ¶
Bases: Record
One coefficient of a linear time model: seconds per invocation, shot, exact evaluation or logical operation.
Build it with keyword arguments, for example
TimeCoefficient(feature="sampled_shots", seconds_per_unit=0.001, unit="s/shot"),
and pass it in coefficients= of
TimeModel. Every field is required.
The unit is kept exactly as supplied and never converted. A zero coefficient
states that the feature contributes nothing, which differs from leaving the
feature out.
Attributes:
-
feature(TimeFeature) –Required.
"invocations","sampled_shots","exact_evaluations"or"logical_operations". -
seconds_per_unit(Nonnegative) –Required. Nonnegative coefficient in
unit. -
unit(Literal['s/invocation', 's/shot', 's/exact_evaluation', 's/logical_operation']) –Required. The one unit of the feature:
"s/invocation","s/shot","s/exact_evaluation"or"s/logical_operation"respectively.
Raises:
-
ValueError–If
unitis not the unit offeature.
ModelDomain ¶
Bases: Record
The workloads a time model is valid for: machine, allocation, readout, operation mix and size ranges.
Build it with keyword arguments and pass it as domain= to
TimeModel. Every field except
rotation_precision, synthesis and bindings is required. An assessment
evaluates the model only for a workload inside every range and list here,
and reports the prediction as unavailable otherwise. The record selects,
fits and extrapolates nothing. An empty list of selections or gates supports
none, never any. Size ranges are inclusive, and max_resets,
max_measurements, max_classical_work and max_adaptive_rounds each give
the inclusive range from 0 to the maximum. A model calibrated without resets,
for example, does not apply once resets are added, even when the gate counts
match. The time-model section of the profiles guide
lists every domain check.
Attributes:
-
configuration_id(ContentID) –Required.
content_idof theDeviceConfiguration: hardware, runtime, build, precision and target. -
allocation_id(ContentID) –Required.
content_idof theAllocation: every granted location, limit and topology. -
basis(MetricBasis) –Required. Gate basis in which logical operations are counted:
"selected_logical","cx","clifford_t"or"toffoli". -
rotation_precision(Float64 | None) –Default
None. Positive rotation-synthesis precision the operation counts assume. -
synthesis(Source | None) –Default
None. Source of the synthesis rule the operation counts assume. -
batch_schedule(Literal['unspecified', 'serial']) –Required.
"unspecified"or"serial". -
acquisition(Literal['direct_observation', 'measurement_batch']) –Required.
"direct_observation"or"measurement_batch". -
runtime(RuntimeOptions | Literal['seed_independent']) –Required. The runtime seed the model was measured with, as
RuntimeOptions(seed=...), or"seed_independent". A whole-Plan forecast does not guess future seeds, so only a seed-independent model applies there. -
population(Literal['unconditional', 'native_conditioned']) –Required. Readout population,
"unconditional"or"native_conditioned". -
readouts(tuple[Literal['pauli_expectation', 'counts', 'probabilities', 'host_scalars', 'amplitudes', 'estimated_observable'], ...]) –Required. Distinct supported readouts:
"pauli_expectation","counts","probabilities","host_scalars","amplitudes"or"estimated_observable". -
selection_ids(tuple[ContentID, ...]) –Required. Distinct content hashes of the supported block selections.
-
primitive_gates(tuple[Literal['x', 'h', 'z', 'sdg', 'cx', 'mc_z', 'phase'], ...]) –Required. Distinct supported primitive gates:
"x","h","z","sdg","cx","mc_z"or"phase". -
min_qubits(Count) –Required. Smallest supported qubit count.
-
max_qubits(Count) –Required. Largest supported qubit count, at least
min_qubits. -
min_operations(Count) –Required. Smallest supported logical operation count.
-
max_operations(Count) –Required. Largest supported logical operation count, at least
min_operations. -
max_shots(Count) –Required. Largest supported shot count.
-
max_exact_evaluations(Count) –Required. Largest supported number of exact evaluations.
-
max_readout_items(Count) –Required. Largest supported number of returned readout items.
-
max_resets(Count) –Required. Largest supported reset count.
-
max_measurements(Count) –Required. Largest supported measurement count.
-
max_classical_work(Count) –Required. Largest supported classical work.
-
max_adaptive_rounds(Count) –Required. Largest supported number of adaptive rounds.
-
bindings(tuple[Binding, ...]) –Default
(). Parameter values the model is restricted to, at most one per parameter.
Raises:
-
ValueError–If a minimum exceeds its maximum,
rotation_precisionis not positive, or a binding, readout, selection or gate is repeated.
ModelUncertainty ¶
Bases: Record
The supplied uncertainty of a time model, as an additive interval in seconds around its prediction.
Build it with keyword arguments, for example
ModelUncertainty(kind="future_run_prediction", lower_residual_seconds=-0.25, upper_residual_seconds=0.5, coverage=0.9, source=...),
and pass it as uncertainty= to
TimeModel. Every field except
coverage is required, and coverage is required for the two statistical
kinds. The residuals are added to the central prediction, so the example
gives the interval [prediction - 0.25, prediction + 0.5] seconds. The
interval keeps the meaning its source states and is never an execution
guarantee.
Attributes:
-
kind(Literal['future_run_prediction', 'sample_mean_confidence', 'model_error_envelope']) –Required.
"future_run_prediction"concerns one future run."sample_mean_confidence"concerns a mean and does not bound an individual run."model_error_envelope"states an engineering uncertainty without a probability. -
lower_residual_seconds(Real) –Required. Zero or negative residual in seconds.
-
upper_residual_seconds(Nonnegative) –Required. Nonnegative residual in seconds.
-
coverage(Real | None) –Default
None. Probability in (0, 1] that the interval holds, required for"future_run_prediction"and"sample_mean_confidence"and not allowed for"model_error_envelope", because a coverage would claim more than an engineering uncertainty supports. -
source(Source) –Required. Source of the stated interval.
Raises:
-
ValueError–If
coverageis missing for a statistical kind or given for"model_error_envelope".
CalibrationReference ¶
Bases: Record
Where a calibrated time model's coefficients came from: training data, validation data and validation errors.
Build it with keyword arguments and pass it as calibration= to
TimeModel. Every field is required.
Each Source names the exact data or procedure version. NWQLib never opens or
fetches a referenced source. A link to a parent record alone does not
establish which workloads trained the model.
Attributes:
-
source(Source) –Required. Source of the calibration procedure.
-
training(Source) –Required. Source of the training workloads.
-
validation(Source) –Required. Source of the held-out validation workloads.
-
validation_errors(Source) –Required. Source of the held-out error report.
Allocation ¶
Bases: Record
The resources granted to one workload: locations, their placement and their capacity limits.
Build it with keyword arguments, for example
Allocation(name=..., configuration_id=configuration.content_id, locations=("logical_device",), topology="single_device", limits=(...), recorded_at=..., valid_until=..., evidence=...),
and pass it as allocation= to nwqlib.estimate, nwqlib.compare or
assess. Every field is required. The
record states a grant that the caller supplies. NWQLib never queries a
scheduler or device for it, and it never configures ranks, threads or devices.
Capacities are never pooled across locations. For example, two 8-GiB devices
cannot hold a 10-GiB peak on one device. The
device-domain section of the profiles guide
explains how capacities are compared.
Attributes:
-
name(Text) –Required. Name of the grant.
-
configuration_id(ContentID) –Required.
content_idof theDeviceConfigurationthe grant is for. An assessment applies the grant's limits only when it matches the profile's configuration. -
locations(tuple[Text, ...]) –Required. Distinct names of the granted locations, the names the Program's registers and workspaces use, such as
"logical_device". -
topology(Literal['single_device', 'independent_devices', 'distributed'] | None) –Required.
"single_device"(exactly one location),"independent_devices","distributed", orNonewhen the placement is unknown. -
limits(tuple[Limit, ...]) –Required. Capacity, consumption and deadline limits as
Limitrecords, at most one per stage, metric and scope. A limit of kind"capacity_stock"names exactly one granted location as itsscope. -
recorded_at(Timestamp) –Required. Time zone-aware time the grant was recorded, stored in UTC.
-
valid_until(Timestamp) –Required. Time zone-aware end of the grant's validity, not before
recorded_at. -
evidence(Evidence) –Required. Evidence describing the grant, not its use.
Raises:
-
ValueError–If the locations are empty or repeated,
"single_device"has more than one location, two limits share a stage, metric and scope, a"capacity_stock"limit names a location outside the grant, orvalid_untilprecedesrecorded_at.
assess ¶
assess(plan: Plan, realization: Realization, *, profile: DeviceProfile, allocation: Allocation, context: ResourceContext | None = None, runtime: RuntimeOptions | None = None, assessed_at: datetime | None = None, accuracy: Accuracy | None = None, facts: tuple[FramedFact, ...] = (), reference: TargetReference | None = None, max_assessments=4096) -> ProfileAssessment
Forecast one resolved point of a Plan on a device profile and allocation, without running anything.
nwqlib.estimate(plan, profile=..., allocation=...) assesses every point of
the Plan whose parameters are fixed. Call assess for one point, for
example the point that plan.resolve(experiment_name) returns. The result
reports five independent axes: applicability, capability, capacity, time and
accuracy. Each axis has the status "feasible", "infeasible",
"conditional" or "unknown", and a failure on one axis, such as memory,
does not hide what another supports, such as an error bound. Time
predictions rest on the supplied coefficients, so none is an execution
guarantee. No pilot run, profile refresh, circuit compilation or replay of the
computation takes place. The profiles guide defines the axes, and
Forecast cost and feasibility assesses a
one-qubit Plan.
Parameters:
-
plan(Plan) –The Plan whose point is assessed.
-
realization(Realization) –One resolved point of
plan, such asplan.resolve(experiment_name). -
profile(DeviceProfile) –The device profile.
-
allocation(Allocation) –The resources granted to the workload.
-
context(ResourceContext | None, default:None) –Resource-counting context, such as the gate basis.
NoneusesResourceContext(). -
runtime(RuntimeOptions | None, default:None) –Backend seed of an already known preparation. With
None, only seed-independent models apply. Seeds are never guessed. -
assessed_at(datetime | None, default:None) –Time zone-aware assessment time, against which the validity of the profile, allocation and models is checked.
Nonerecords the current UTC time once. -
accuracy(Accuracy | None, default:None) –Accuracy criterion to assess.
Noneuses the Plan'sselection_accuracy, and with neither the accuracy axis is unknown. Another criterion changes only this assessment, never the Plan's shots or selection. -
facts(tuple[FramedFact, ...], default:()) –Supplied error facts, passed unchanged to the Plan's error model. A fact for one point cannot cover another.
-
reference(TargetReference | None, default:None) –Supplied reference value, passed unchanged to the Plan's error model.
-
max_assessments(int, default:4096) –Positive limit on assessment and prediction rows, here one plus the number of time models, checked before any model is evaluated.
Returns:
-
assessment(ProfileAssessment) –The forecast. Its
predictionshold the time forecasts in seconds, itscapacitythe memory comparison and itserrorthe complete accuracy assessment.
Raises:
-
TypeError–If
profileis not aDeviceProfileoraccuracyis not anAccuracy. -
ValueError–If the rows exceed
max_assessments, or the stored records do not match the Plan, profile and allocation.
PlanEstimate ¶
Bases: Record
The resource estimate of a whole Plan with the device forecasts of its resolved points.
nwqlib.estimate(plan, profile=profile, allocation=allocation) returns it.
Without a profile and allocation, estimate returns the
WorkloadEstimate alone. The
fields below are read-only. All assessments share one assessment time.
Points that an adaptive method has not chosen yet, and points along a range
axis that is not expanded, are listed in unpredicted instead of being
guessed. When a Run is prepared with this estimate, each submission looks up
the forecast of its own point, and later timings can be compared with it by
align_telemetry.
Attributes:
-
plan_id(ContentID) –Content hash of the Plan.
-
resources(WorkloadEstimate) –Resource estimate of the whole Plan, independent of any profile.
-
assessments(tuple[ProfileAssessment, ...]) –One
ProfileAssessmentper resolved point. -
profile(DeviceProfile | None) –The
DeviceProfile, orNonewhen only an allocation was supplied. -
allocation(Allocation | None) –The
Allocation, orNone. -
assessed_at(Timestamp) –The assessment time, in UTC.
-
unpredicted(tuple[Text, ...]) –Why each point without a forecast has none.
assessment_for ¶
assessment_for(plan, receipt)
Return the stored forecast of a prepared circuit's point, or None, without evaluating anything.
The forecast is checked against the Plan once per estimate, and against the preparation record each time.
Parameters:
-
plan(Plan) –The Plan this estimate belongs to.
-
receipt(PreparedArtifact) –The preparation record of one prepared circuit.
Returns:
-
assessment(ProfileAssessment | None) –The forecast of that circuit's point, or
Nonewhen the estimate has no forecast for it.
Raises:
-
ValueError–If the estimate belongs to another Plan, or the forecast does not match the preparation record.
ProfileAssessment ¶
Bases: Record
The forecast of one resolved Plan point on a device profile: five independent axes and the time predictions.
assess returns it, and
PlanEstimate.assessments holds
one per point. The fields below are read-only. Each axis is an
AxisAssessment whose status
summarizes its own details only, so a memory failure cannot hide a supported
error bound. No conclusion grants permission to run, configures a backend or
changes the computation. An excessive sufficient error bound stays
INCONCLUSIVE in error rather than proving that the actual error is too
large.
Attributes:
-
point(AssessmentPoint) –Content hashes of the inputs: problem, Plan, point, base and selected construction, resource estimate and context, profile, allocation, expected runtime and compiler sources, known runtime seed, and the assessment time.
-
realization(Realization) –The resolved point, with its parameter bindings.
-
resources(WorkloadEstimate) –Resource estimate of this point. Capability, capacity and time read the same counts.
-
applicability(AxisAssessment) –Whether a stated assumption of the method holds for this problem. The built-in Methods record no such statement, so this axis is unknown, or conditional when the Plan lists assumptions or requirements.
-
capability(AxisAssessment) –Whether the target supports the point's circuit form, Program nodes, readout, instructions, host kernel and control or adjoint use.
-
capacity(AxisAssessment) –Whether each granted location holds the point's simultaneous memory and storage peaks and its known lower requirements.
-
time(AxisAssessment) –The time-model predictions and the matching time limits.
-
accuracy(AxisAssessment) –The Plan's error-model assessment of
criterion. -
criterion(Accuracy | None) –The
Accuracycriterion assessed, orNone. -
error(ClaimAssessment | None) –The complete
ClaimAssessmentofcriterion, orNonewithout a criterion or error model. Before execution it names no observation or result. -
predictions(tuple[TimePrediction, ...]) –One
TimePredictionper time model of the profile, in the profile's order.
AxisAssessment ¶
Bases: Record
One axis of a device forecast: its status and every fact behind it.
Read it from the applicability, capability, capacity, time and
accuracy fields of a
ProfileAssessment. The fields
below are read-only. The status summarizes the details of this axis only. A
known failure ("infeasible") decides the axis. Otherwise any
"conditional" detail makes it conditional, then any "unknown" detail
makes it unknown, and it is "feasible" only when every detail is.
Attributes:
-
axis(Axis) –"scientific_applicability","execution_capability","capacity_materialization","time_cost"or"accuracy_evidence". -
status(Outcome) –"feasible","infeasible","conditional"or"unknown". -
details(tuple[AssessmentDetail, ...]) –The
AssessmentDetailrecords, partial knowledge included.
AssessmentDetail ¶
Bases: Record
One scoped conclusion of a device forecast, with the value and limit it compares.
Read it from AxisAssessment.details. The fields below are read-only. A
detail holds either a resource value (fact) or a method statement
(statement), never both, because they are different quantities.
Attributes:
-
quantity(Text) –The quantity compared, such as a memory peak.
-
scope(Text) –Where the quantity applies, such as one granted location.
-
status(Outcome) –"feasible","infeasible","conditional"or"unknown". -
reason(Text) –Why the detail has its status.
-
fact(Fact | None) –The resource value compared, or
None. -
resource_id(ContentID | None) –Content hash of the resource quantity in the estimate, or
None. -
prediction_ids(tuple[ContentID, ...]) –Content hashes of the time predictions this detail summarizes.
-
limit(Limit | None) –The supplied
Limitit was compared with, unchanged, orNone. -
evidence_ids(tuple[ContentID, ...]) –Content hashes of the declarations and records used.
-
assumptions(tuple[Text, ...]) –Assumptions the conclusion rests on.
-
statement(FramedFact | None) –The method's complete stated assumption or claim, or
None.
TimePrediction ¶
Bases: Record
The prediction of one time model for one point, in seconds, with its interval and the feature counts it used.
Read it from ProfileAssessment.predictions. The fields below are read-only.
The answer is seconds.value, a prediction for the model's scope, not an
observed elapsed time and not permission to run. When an input is missing,
seconds is None and reasons says why. An interval keeps the kind and
coverage of the model's uncertainty, so a confidence interval for a mean
never becomes a bound on a single run.
Attributes:
-
model_id(ContentID) –Content hash of the time model.
-
point_id(ContentID) –Content hash of the assessed point.
-
form(Literal['acquisition_linear/1']) –"acquisition_linear/1". -
scope(TimeScope) –The model's time scope, copied from the model.
-
seconds(Float64 | None) –Nonnegative predicted seconds, or
Nonewhen unavailable. -
unit(Unit) –Seconds.
-
lower_seconds(Float64 | None) –Lower end of the interval, at least zero, or
None. -
upper_seconds(Float64 | None) –Upper end of the interval, or
None. -
uncertainty(ModelUncertainty | None) –The model's
ModelUncertainty, orNone. -
features(tuple[Fact, ...]) –The feature counts the prediction used.
-
evidence(Evidence) –Evidence that names the model's source.
-
reasons(tuple[Text, ...]) –Why the prediction is unavailable. Empty when it is available.
-
assumptions(tuple[Text, ...]) –Assumptions the prediction rests on.
Compare forecasts with observed timings¶
After a Run prepared with a PlanEstimate finishes, align_telemetry(run) pairs each attempt's forecast with its observed timing.
align_telemetry ¶
align_telemetry(run_or_result=None, *, trace: ExecutionTrace | None = None, assessments: tuple[ProfileAssessment, ...] = (), receipts: tuple[PreparedArtifact, ...] = (), observations: ObservationView | None = None, timings: tuple[AttemptTiming, ...] = (), result: Record | None = None, max_comparisons: int = 100000) -> PredictionLedger
Pair the forecasts of a Run with its observed timings and return the signed residuals.
Pass a Run or a completed Result, for example align_telemetry(run), to read
its execution record, preparation records, observations and the forecast it
was prepared with. The returned PredictionLedger keeps every attempt, failures and
partial collections included. A residual observed_seconds - predicted_seconds
is formed only when the attempt was bound to its forecast before it started,
its data collection completed, and an exact timing of the forecast's scope
exists. Every other attempt keeps its forecast with the reason it has no
residual, so a runtime or compiler mismatch, a missing scope or preparation
record, a failed collection or a right-censored timing stays visible. A
right-censored timing is a lower bound, never an exact residual. Nothing is
executed, assessed again or fitted, no provider is contacted, and no
histogram or backend payload is copied into it. A residual makes no
coverage claim, and a historical residual does not establish that the device
calibration was valid when the job ran. The
telemetry section of the profiles guide
describes the pairing rules.
Parameters:
-
run_or_result(Run | Result | None, default:None) –The Run or Result to read. With
None, passtraceand the other records explicitly. -
trace(ExecutionTrace | None, default:None) –Execution record, when no Run or Result is given.
-
assessments(tuple[ProfileAssessment, ...], default:()) –Forecasts to pair. Empty uses the forecast the Run was prepared with.
-
receipts(tuple[PreparedArtifact, ...], default:()) –Preparation records, when no Run or Result is given.
-
observations(ObservationView | None, default:None) –Observations, when no Run or Result is given.
-
timings(tuple[AttemptTiming, ...], default:()) –Additional supplied timings. Each must belong to an attempt of this run. Identical timings of one attempt count once, and different attempts stay distinct.
-
result(Record | None, default:None) –The analysis Result whose contributions are recorded, when no Run or Result is given.
-
max_comparisons(int, default:100000) –Positive limit on the forecast and timing pairs formed.
Returns:
-
record(PredictionLedger) –The forecasts paired with the timings.
Raises:
-
TypeError–If no execution record or
RunDatais available. -
ValueError–If a Run or Result is mixed with explicit records, a timing or record belongs to another run, attempt or Plan, identities conflict, or the pairs exceed
max_comparisons.
PredictionLedger ¶
Bases: Record
The forecasts of one Run paired with its observed timings, attempt by attempt.
align_telemetry returns it. The
fields below are read-only. Each row holds one attempt's execution event, its
timings, the observations it collected and its forecast comparisons, where
residual_seconds is the signed observed - predicted seconds or None
with the reasons. Collected observations and the contributions of the
Result stay separate lists. Use revise to record a new version of supplied
data. It never fits coefficients or changes the original
assessments, model domains, calibration status or coverage. A forecast is
valid at its original assessment time, and a historical residual does not
establish that calibration was valid when the job ran.
Attributes:
-
trace_id(ContentID) –Content hash of the Run's execution record.
-
run_id(Text) –ID of the Run.
-
plan_id(ContentID) –Content hash of the Plan.
-
assessment_ids(tuple[ContentID, ...]) –Content hashes of the forecasts used.
-
predictions(tuple[TimePrediction, ...]) –The original
TimePredictionrecords. -
rows(tuple[TelemetryRow, ...]) –One row per attempt, failures, partial collections and right-censored timings included.
-
result_id(ContentID | None) –Content hash of the analysis Result, or
None. It does not imply that the Result is scientifically valid.
validate_context ¶
validate_context(*, trace, assessments)
Check that a saved PredictionLedger still matches its execution record and forecasts, without recomputing anything.
Parameters:
-
trace(ExecutionTrace) –The Run's execution record.
-
assessments(tuple[ProfileAssessment, ...]) –The forecasts the record used.
Returns:
-
record(PredictionLedger) –This record.
Raises:
-
ValueError–If the record differs from the execution record, uses a forecast of another Plan or attempt, or changed its predictions.
AttemptTiming ¶
Bases: Record
A timing that the caller measured for one attempt of a Run, to pair with its forecast.
Build it with keyword arguments, for example
AttemptTiming(run_id=..., attempt=..., prepared_id=..., timing=...),
and pass it in timings= of
align_telemetry. Every field is
required. The timing is either an exact duration or a right-censored lower
bound, with its source. Distinct attempts stay distinct even when their
timings agree.
Attributes:
-
run_id(Text) –Required. ID of the Run.
-
attempt(Text) –Required. ID of the attempt in the Run's execution record.
-
prepared_id(ContentID) –Required. Content hash of the preparation record the attempt used.
-
timing(TimingObservation) –Required. The
TimingObservation: scope, nonnegative seconds,"exact"or"right_censored", and source. A right-censored timing needs the reason for its cutoff.
Export OpenQASM¶
export_qasm converts any Qiskit circuit to OpenQASM 3 or 2. write_qasm3_file and write_qasm3 write a Plan's circuit (plan.construction) as OpenQASM 3 without a quantum SDK, for the constructions listed in Export OpenQASM, and materialize_qasm3_file imports such a file back into Qiskit after checking its bytes.
export_qasm ¶
export_qasm(circuit: QuantumCircuit, *, format: str = 'qasm3', path: str | Path | None = None, max_text_bytes: int = DEFAULT_MAX_BYTES, max_operations: int = 100000) -> str | Path
Return the OpenQASM 3 or 2 text of a Qiskit circuit, or write it to a file.
Use it for any built Qiskit circuit, for example one from
prepared.circuit(0) or lower_qiskit.
Without path it returns the text. With path it writes a temporary file in
the same directory and replaces the destination only after the export
succeeds, so a failed export leaves an earlier file unchanged. It does not
transpile or simulate. Qiskit's OpenQASM 3 exporter streams the text but still
builds a complete syntax tree, and its OpenQASM 2 exporter builds the whole
string first, so for OpenQASM 2 max_text_bytes limits only the returned or
written text. Neither limit bounds expanded gate definitions or Qiskit's
workspace.
Parameters:
-
circuit(QuantumCircuit) –The circuit to export.
-
format(str, default:'qasm3') –"qasm3"or"qasm2". -
path(str | Path | None, default:None) –A file path whose parent directory exists, or
Noneto return the text. -
max_text_bytes(int, default:DEFAULT_MAX_BYTES) –Default 10 GB (decimal,
10_000_000_000bytes). Positive limit on the UTF-8 bytes of the exported text. -
max_operations(int, default:100000) –Positive limit on the top-level instructions of
circuit, checked before export.
Returns:
-
output(str | Path) –The OpenQASM text, or the destination path when
pathis given.
Raises:
-
ValueError–If
formatis not"qasm2"or"qasm3", a limit is not a positive integer, the circuit has more thanmax_operationsinstructions, or the text exceedsmax_text_bytes. -
TypeError–If
circuitis not a QiskitQuantumCircuit.
Examples:
>>> from qiskit import QuantumCircuit
>>> from nwqlib.io import export_qasm
>>> bell = QuantumCircuit(2)
>>> _ = bell.h(0)
>>> _ = bell.cx(0, 1)
>>> print(export_qasm(bell))
OPENQASM 3.0;
include "stdgates.inc";
qubit[2] q;
h q[0];
cx q[0], q[1];
write_qasm3_file ¶
write_qasm3_file(construction, path, *, budget: QasmWriteBudget, cancel=None) -> QasmWriteReceipt
Write a Program's circuit as an OpenQASM 3 file, replacing the destination only when the write is complete.
It writes the text as write_qasm3 does,
into a temporary file in the destination's directory, and replaces the
destination only after the text and its QasmWriteReceipt are complete. On failure or
cancellation it removes the temporary file and leaves an existing destination
unchanged. No fsync or durability across power loss is promised.
Parameters:
-
construction(SelectedConstruction) –The Program and its selected definitions, such as
plan.construction. -
path(str | Path) –Destination file. Its directory must exist.
-
budget(QasmWriteBudget) –The limits.
-
cancel(Callable[[], bool] | None, default:None) –Called between writes, and a true result stops the write.
Returns:
-
receipt(QasmWriteReceipt) –The receipt, with
completion="file".
Raises:
-
ValueError–If the construction is outside the writer subset or exceeds
budget, before any file is created. -
QasmWriteError–If writing fails after it started. Its
prefixdescribes the text already delivered, itstemporarynames the temporary file if it could not be removed, andsecondaryholds later cleanup failures. An exception that is not anException, such asKeyboardInterrupt, keeps its type, with cleanup failures in its notes.
write_qasm3 ¶
write_qasm3(construction, sink, *, budget: QasmWriteBudget, cancel=None) -> QasmWriteReceipt
Write a Program's circuit as OpenQASM 3 text to a binary stream, without any quantum SDK.
The construction must use the writer subset of the
OpenQASM guide: exact gate recipes,
sequences, bound repeats written as loops, allocation, computational
measurement and reset, and at most one batch setting. Other constructions,
such as generic state preparation or Pauli SELECT blocks, are rejected before
any text is written. The sink's write must return a positive integer no
larger than the buffer offered, and a partial write is completed before more
text is produced. Cancellation is checked between writes, so a blocking write
cannot be interrupted.
Parameters:
-
construction(SelectedConstruction) –The Program and its selected definitions, such as
plan.construction. -
sink(BinaryIO) –Binary stream with a
writemethod. -
budget(QasmWriteBudget) –The limits.
-
cancel(Callable[[], bool] | None, default:None) –Called between writes, and a true result stops the write.
Returns:
-
receipt(QasmWriteReceipt) –The receipt, with
completion="stream".
Raises:
-
ValueError–If the construction is outside the writer subset or exceeds
budget, before any text is written. -
QasmWriteError–If writing fails after it started. Its
prefixdescribes the text already delivered.
QasmWriteBudget ¶
Bases: Record
Limits for writing a Program as OpenQASM 3 text with write_qasm3 or write_qasm3_file.
Build it with keyword arguments, for example
QasmWriteBudget(max_metadata_bytes=1_000_000, max_walk_steps=100_000, max_qubits=1, max_clbits=0, max_bytes=4096, max_instructions=100, max_chunk_bytes=256),
and pass it as budget=. Every field is required. The graph and metadata
checks run before any text is written. The limits do not grow with the count
of a Repeat, which the text writes as one loop.
Attributes:
-
max_metadata_bytes(Count) –Required. Limit in bytes on a conservative JSON size of the Program graph and of the final
QasmWriteReceipt, each checked before it is used. -
max_walk_steps(Count) –Required. Limit on the steps of each walk over the graph and of the counting and writing passes. A
Repeatcount is not multiplied in. -
max_qubits(Count) –Required. Limit on the total declared qubits.
-
max_clbits(Count) –Required. Limit on the total declared classical bits.
-
max_bytes(Count) –Required. Limit on the bytes of text written.
-
max_instructions(Count) –Required. Limit on the gate, measurement and reset statements in the text, gate definitions included.
-
max_chunk_bytes(PositiveInt) –Required. Positive. Limit in bytes on each buffer offered to the sink. It does not bound how long a blocking sink takes.
QasmWriteReceipt ¶
Bases: Record
The record of a completed OpenQASM 3 file or stream: what was written, its layouts, counts and digest.
write_qasm3 and write_qasm3_file return it, and
materialize_qasm3_file
checks a file against it. The fields below are read-only. The text describes
one circuit template. Writing it runs nothing and collects no observation.
The counts are syntactic. They count no shots, gate synthesis or SDK
memory, and they are not hardware estimates.
Attributes:
-
construction_id(str) –Content hash of the written construction.
-
subset(Literal['nwqlib.direct-qasm3.v1']) –"nwqlib.direct-qasm3.v1", the supported subset of OpenQASM 3.0 withstdgates.inc. -
angle_convention(Literal['binary64-repr']) –"binary64-repr", meaning that each angle is the shortest decimal that rounds back to the same binary64 value. -
selected_definitions(tuple[str, ...]) –Content hashes of the block recipes reachable from the root.
-
quantum_layout(tuple[tuple[str, str, Count], ...]) –(original name, generated name, width)of each quantum register, in declaration order. Qubit index 0 is the least significant bit. -
classical_layout(tuple[tuple[str, str, Count], ...]) –The same for each classical register.
-
batch_repetitions(Count | None) –Repetitions of the measurement batch, kept here and not written as a loop, or
None. -
observation_kind(str | None) –Observation kind of the batch, or
None. -
setting_label(str | None) –Label of the one written setting, or
None. -
bytes_written(Count) –Bytes of text written, punctuation included.
-
emitted_instructions(Count) –Gate, measurement and reset statements written, counting a definition body once for each time it appears in the text.
-
expanded_operations(Count) –Primitive gates plus one per measured or reset bit, after expanding loops and calls.
-
dynamic_visits(Count) –Visits to Program nodes, empty calls and loop bodies included.
-
digest(str) –sha256:digest of the text. -
completion(Literal['stream', 'file']) –"stream"fromwrite_qasm3or"file"fromwrite_qasm3_file. -
native_bytes(None) –Always
None, because the SDK memory is not known. -
peak_rss(None) –Always
None, because peak process memory is not known.
QasmWriteError ¶
QasmWriteError(message, prefix, *, secondary=(), temporary=None)
Bases: RuntimeError
Raised when writing OpenQASM 3 text fails after the limit checks passed.
prefix is the QasmPrefix of the text
already delivered, and __cause__ is the original failure. secondary
holds the failures of closing or cleaning up, in the order they occurred.
temporary names the temporary file of write_qasm3_file that could not be
removed, or is None.
QasmPrefix ¶
QasmPrefix(bytes_written: int, emitted_instructions: int, digest: str)
The text that a failed OpenQASM 3 write had already delivered, never a completed file.
Read it from QasmWriteError.prefix. The fields below are read-only.
Attributes:
-
bytes_written(int) –Bytes the sink accepted.
-
emitted_instructions(int) –Statements the sink accepted completely.
-
digest(str) –sha256:digest of exactly the accepted bytes.
materialize_qasm3_file ¶
materialize_qasm3_file(construction, path, receipt: QasmWriteReceipt, *, writer_budget: QasmWriteBudget, budget: QasmMaterializationBudget) -> QasmMaterialization
Import an OpenQASM 3 file written by write_qasm3_file into Qiskit, after checking its bytes against the construction.
The sizes are derived again from the construction and checked against
budget before the file is opened. The text is then written again into a
digest to rebuild the QasmWriteReceipt, and the file is read once and its
bytes and digest compared with receipt, so a QasmWriteReceipt alone
cannot vouch for other text. Those same bytes go to Qiskit's OpenQASM 3
importer and the UnrollForLoops pass. Gate definitions stay logical. Z
with more than two controls in total is rejected before import, because
the installed importer can synthesize such gates eagerly. It needs the
qasm extra
(pip install "nwqlib[qasm]"). The checked combination is OpenQASM parser
1.0.1, qiskit-qasm3-import 0.6.0 and Qiskit 2.5.2.
Parameters:
-
construction(SelectedConstruction) –The construction the file was written from.
-
path(str | Path) –The file.
-
receipt(QasmWriteReceipt) –The record that
write_qasm3_filereturned. -
writer_budget(QasmWriteBudget) –The budget the file was written with.
-
budget(QasmMaterializationBudget) –The import limits.
Returns:
-
materialization(QasmMaterialization) –The imported circuit and its verified
QasmWriteReceipt.
Raises:
-
ValueError–If the construction exceeds
budget,budgetasks for a memory bound, a Z gate has more than two controls, or thereceiptor the file bytes do not match the construction.
QasmMaterializationBudget ¶
Bases: Record
Limits for importing an OpenQASM 3 file back into Qiskit with materialize_qasm3_file.
Build it with keyword arguments, for example
QasmMaterializationBudget(max_bytes=4096, max_qubits=1, max_clbits=0, max_dynamic_visits=100, max_operations=100),
and pass it as budget=. The first five fields are required. The counts are
derived from the construction and checked before the file is opened. No limit
here estimates the importer's memory.
Attributes:
-
max_bytes(Count) –Required. Limit on the bytes of the file text.
-
max_qubits(Count) –Required. Limit on the total declared qubits.
-
max_clbits(Count) –Required. Limit on the total declared classical bits.
-
max_dynamic_visits(Count) –Required. Limit on Program node visits after expanding loops, empty and identity loops included.
-
max_operations(Count) –Required. Limit on primitive gate, measurement and reset applications after expanding loops. Gates that Qiskit synthesizes for controls are not counted.
-
required_max_native_bytes(Count | None) –Default
None, the only accepted value. Any other value is rejected before import, because this importer cannot bound its memory. -
required_max_peak_rss(Count | None) –Default
None, the only accepted value, for the same reason.
QasmMaterialization ¶
QasmMaterialization(circuit: object, source: QasmWriteReceipt, output_nodes: int, native_bytes: None = None, peak_rss: None = None)
A Qiskit circuit imported from a verified OpenQASM 3 file, with its loops unrolled.
materialize_qasm3_file
returns it. The fields below are read-only. Gates are not decomposed and
nothing is simulated.
Attributes:
-
circuit(object) –The imported Qiskit circuit without loops. Gate definitions from the file stay as logical gates.
-
source(QasmWriteReceipt) –The verified
QasmWriteReceipt. -
output_nodes(int) –Top-level instructions of
circuitafter unrolling. It can differ fromsource.expanded_operations. -
native_bytes(None) –Always
None, because the allocation size is not known. -
peak_rss(None) –Always
None, because peak process memory is not known.