Resource estimates¶
Count the qubits, gates, depth, measurements and memory of a planned computation before running it, and read each count with its label. The Estimate resources guide explains how each count is formed, and Estimate fault-tolerant resources covers compiled Clifford+T counts and physical projections.
import nwqlib
from nwqlib.resources import ResourceContext
nwqlib.estimate(plan) returns a WorkloadEstimate with one quantity per metric and location. Read one with quantity:
import nwqlib
from nwqlib import Eigenproblem
from nwqlib.algorithms import Lanczos
from nwqlib.resources import ResourceContext
problem = Eigenproblem(A=[[1.5, -1], [-1, 0.5]])
method = Lanczos(initial_state=[1, 0], krylov_dimension=2)
selected = nwqlib.plan(problem, method=method, seed=7)
workload = nwqlib.estimate(selected, context=ResourceContext(basis="cx"))
cx = workload.quantity("cx")
width = workload.quantity("logical_width", location="logical_device")
operations = workload.quantity("operations")
print(cx.interpretation, cx.fact.value.numerator, cx.fact.unit.symbol)
print(width.interpretation, width.fact.value.numerator)
print(operations.interpretation)
upper_bound 3 count
exact 2
unavailable
The Plan uses at most 3 CX gates and exactly 2 qubits. No exact gate list, registered CX bound (an upper bound on CX gates that NWQLib records for its own blocks) or cost rule (ResourceLaw) of its circuit blocks, the subroutines of its circuit such as a state preparation, gives a total operation count in this basis, so that count is unavailable rather than zero, and operations.fact.reason says why. print(workload) lists every quantity with its label and conditions. A quantity with a value also keeps its evidence in fact.evidence, whose kind is the weakest among the sources that determined the value, for example a proof, a numerical estimate, an observation or an assertion.
An estimate describes the planned logical circuit. It is not a count of compiled gates, which Prepared.inspect_resources gives for a prepared circuit, and it includes no routing, error correction or provider billing.
Estimate a plan¶
The entry below is nwqlib.resources.estimate, the lower-level function that nwqlib.estimate(plan) calls on plan.construction. It takes the Plan's SelectedConstruction, not the Plan. Every entry on this page imports from nwqlib.resources.
estimate ¶
estimate(construction: SelectedConstruction, *, context: ResourceContext | None = None, memo: dict | None = None, catalog: str | None = None) -> WorkloadEstimate
Estimate the resources of a planned circuit description without building or running it.
Most callers use nwqlib.estimate(plan),
which calls this function on plan.construction. The estimate walks the
circuit description once per distinct context and keeps symbolic costs
in a compact expression table. It reads no numerical input data,
synthesizes no gates and does not unroll repeated parts. Its bookkeeping
work is at most 24 * limits.max_steps work units,
reported as WorkloadEstimate.work_units, where limits is
construction.program.limits (engineering
constants).
The result depends only on the construction, the context and catalog.
A caller that estimates several points of one Plan can pass one memo
dictionary for the duration of its operation, and an equal construction,
context and catalog then return the estimate already computed. The
memo dictionary belongs to that caller, and there is no process-wide
cache.
Parameters:
-
construction(SelectedConstruction) –The planned circuit description,
plan.construction. -
context(ResourceContext | None, default:None) –Gate basis, rotation precision, synthesis, resident data and batch schedule.
None, the default, meansResourceContext(): the"selected_logical"basis, no resident data and an unspecified schedule. -
memo(dict | None, default:None) –Optional dictionary owned by the caller, mapping
(construction.content_id, context.content_id, catalog)to the estimate already computed for that triple. -
catalog(str | None, default:None) –Default
None, which estimatesconstructionas the workload it describes. Otherwise the reason that the experiments ofconstructionare templates of queries whose parameter values a Run chooses one query at a time, asMethod.query_catalog_reasonreturns it fornwqlib.estimate(plan). The counts of the templates are then not the totals of a Run, and a count is exactly zero only when no query bound from the templates can contribute to it. The conditions for a zero read every definition that the Program declares, including one that the root never runs, because a query can select it. When no block call, measurement, reset or measurement batch is declared, the gate, depth, call, measurement, reset, setting, unique-setting, preparation-component, shot and exact-evaluation counts are zero.shotsis zero when the Program declares at least one terminal measurement batch and all of them return exact statistics, andexact_evaluationsis zero when it declares at least one and all of them sample counts. A declaration that no experiment selects may prevent a zero but never produces a false one. Every other count and the construction work are unavailable with this reason, except the setting and repetition declarations of a root measurement batch, which keep their values. Each width and byte peak keeps its value, evidence and schedule condition, and itspopulationandfact.scopename it a declared footprint of the templates at their supplied or symbolic parameter values, not a peak over a Run. The reason is added toassumptions.
Returns:
-
workload(WorkloadEstimate) –One quantity per metric and location. Every quantity has
lifecycle="planned"and keeps its label, location and original evidence. A metric whose value cannot be determined, such as a gate count that no exact gate list, registered CX bound or cost rule (ResourceLaw) of the blocks gives, is present as unavailable, not as zero.
Raises:
-
ValueError–If an exact count needs more integer bits than
construction.program.limits.max_integer_bits, two applicable cost rules of a block conflict, a block's declared cost rule contradicts its exact gate list, or its bookkeeping work would exceed the limit stated above.
WorkloadEstimate ¶
Bases: Record
Resource estimate of a planned computation: one quantity per metric and location.
nwqlib.estimate(plan) returns it when no
device profile is given, and so does estimate.
Read one metric with quantity(metric), or a width or byte peak with
quantity(metric, location=...), and list everything with quantities
or print(workload). A metric whose value cannot be determined, such as
a gate count that no exact gate list, registered CX bound or cost rule
gives, is present and labeled unavailable, never zero. The estimate is of the logical
circuit description, before compilation, routing or error correction.
exact_evaluations counts grouped exact-statistic requests, not returned
labels, bins or simulator trajectories. A circuit with no terminal
measurement batch declares no measurements, so zero shots and
settings there do not mean that running it is free. The fields below
are read-only.
Attributes:
-
construction_id(ContentID) –Content hash of the planned circuit description that was estimated.
-
context(ResourceContext) –The
ResourceContextthat fixed basis, precision, synthesis and schedule. -
quantities(tuple[ResourceQuantity, ...]) –One
ResourceQuantityper (metric, location), including unavailable ones. -
expressions(tuple[Expression, ...]) –Symbolic cost expressions that symbolic quantities name. Repeats and shared parts are not expanded.
-
parameters(tuple[Parameter, ...]) –Circuit parameters those expressions may use.
-
sources(tuple[Evidence, ...]) –The original evidence records of the cost rules. The arithmetic of the estimate does not make them verified.
-
defined_selections(tuple[ContentID, ...]) –Content hashes of the circuit blocks and classical routines the run may reach, not a record of built circuits.
-
work_units(NonnegativeInt) –Bookkeeping work of the estimate, not run time, at most
24 * limits.max_steps. -
evaluated_contexts(NonnegativeInt) –Distinct node and call contexts evaluated.
-
limits(AdmissionLimits) –The size limits of the planned circuit description.
-
assumptions(tuple[Text, ...]) –Conditions of the whole estimate, such as
"logical dependency schedule; no physical QEC/routing/factory projection". -
schema_version(Literal[2]) –Format version of the record, 2.
Examples:
A two-dimensional Lanczos Plan, estimated in the CX basis, has an exact width of two qubits and an upper bound of three CX gates. No exact gate list, registered CX bound or cost rule gives its total operation count:
>>> import nwqlib
>>> from nwqlib import Eigenproblem
>>> from nwqlib.algorithms import Lanczos
>>> from nwqlib.resources import ResourceContext
>>> problem = Eigenproblem(A=[[1.5, -1], [-1, 0.5]])
>>> method = Lanczos(initial_state=[1, 0], krylov_dimension=2)
>>> selected = nwqlib.plan(problem, method=method, seed=7)
>>> context = ResourceContext(basis="cx")
>>> workload = nwqlib.estimate(selected, context=context)
>>> cx = workload.quantity("cx")
>>> cx.interpretation, cx.fact.value.numerator
('upper_bound', 3)
>>> width = workload.quantity("logical_width", location="logical_device")
>>> width.interpretation, width.fact.value.numerator
('exact', 2)
>>> workload.quantity("operations").interpretation
'unavailable'
quantity ¶
quantity(metric: str, *, location: str | None = None) -> ResourceQuantity
Return the quantity of one metric at one location, without recomputing anything.
Parameters:
-
metric(str) –Metric name, such as
"cx"or"logical_width". -
location(str | None, default:None) –Location of a width or byte peak, for example
"logical_device"or"host".None, the default, selects a total.
Returns:
-
quantity(ResourceQuantity) –The quantity held in the estimate.
Raises:
-
ValueError–If no quantity has this metric and location. The message lists up to eight locations of the metric.
ResourceContext ¶
Bases: Record
Settings that fix how a resource estimate counts: gate basis, rotation precision, synthesis, resident data and schedule.
Build it with keyword arguments, for example ResourceContext(basis="cx"),
and pass it as context= to nwqlib.estimate
or estimate. Every argument is
optional, and ResourceContext() counts in the "selected_logical"
basis.
Attributes:
-
basis(MetricBasis) –Default
"selected_logical", which counts the planned construction's own operations. Basis in which gate metrics are counted:"selected_logical","cx","clifford_t"or"toffoli". Counts in different bases answer different questions and are never converted into or added to each other. -
precision(Float64 | None) –Default
None. Positive rotation synthesis precision, in the sense thatsynthesisdefines. An arbitrary rotation gets a T count only when the precision and the synthesis are known, and a block'sResourceLawapplies only when itsprecisionequals this value. -
synthesis(Source | None) –Default
None. Source naming the synthesis method. A block'sResourceLawapplies only under the same choice. -
resident(tuple[Workspace, ...]) –Default
().Workspaceentries that stay in memory for the whole workload and are added to every memory peak. -
capacities(tuple[Limit, ...]) –Default
(). Device capacities asLimitrecords, kept for a later device assessment. The estimate itself allocates nothing and queries no device. -
batch_schedule(Literal['unspecified', 'serial']) –Default
"unspecified"."serial"declares that the circuit executions of each measurement batch run one after another, so a batch memory peak holds without condition. With"unspecified"such a peak is labeledconditional. The required schedule stays recorded for the execution to follow.
Raises:
-
ValueError–If
precisionis not positive.
Read a quantity¶
Each ResourceQuantity holds its value in fact.value: an exact Rational (read numerator and denominator) or a Float64 (read value). Its interpretation says how to read that value:
interpretation |
Meaning |
|---|---|
exact |
The exact count |
upper_bound |
The count is at most this value, for example a CX bound before gate cancellation and routing, or the maximum over the arms of a branch |
estimate |
Derived from observed, empirically predicted or numerically estimated evidence |
conditional |
Holds only under a stated condition, such as a memory peak that needs the circuit executions of each measurement batch to run one after another (required_schedule) |
unavailable |
The value cannot be determined, for example a gate count that no exact gate list, registered CX bound or cost rule of the blocks gives. fact.reason says why, and the value is never read as zero |
An exact count or upper bound is only as strong as its evidence, fact.evidence.kind, so a count derived from an asserted rule stays an assertion. The conditions of a value are in fact.assumptions.
Totals over the whole run have location=None. Widths and memory are peaks at a location, so read them with quantity(metric, location=...):
| Metrics | Value | Unit |
|---|---|---|
Gates: operations, single_qubit, two_qubit, controlled, global_phases, clifford, t, toffoli, ccz, arbitrary_rotations, cx |
Whole run | count |
Depths: logical_depth, t_depth, non_clifford_depth |
Whole run | count |
Calls and measurement: calls, measurements, resets, settings, shots, exact_evaluations, unique_settings, root_setting_declarations, root_repetitions, adaptive_rounds, expected_operations |
Whole run | count |
Work: classical_work, construction_work, preparation_components |
Whole run | count |
Qubits: logical_width, system, clean_ancilla, dirty_ancilla at a register's location |
Peak | count |
Classical registers: classical_registers, classical_bits at "host" |
Peak | count |
Memory: memory, known_memory, input_bytes, analysis_bytes, io_bytes, materialization_bytes, stored_bytes at a workspace's location |
Peak | byte |
The Estimate resources guide defines what shots, settings, exact_evaluations and the other measurement counts include.
ResourceQuantity ¶
Bases: Record
One count or peak of a resource estimate, with its value, label and sources.
WorkloadEstimate.quantity
returns it. The value is fact.value, an exact Rational (read
numerator and denominator) or a Float64, in the unit fact.unit:
count, or byte for byte metrics. A symbolic value is
fact.symbol, and an unavailable one has fact.reason and no value.
interpretation says how to read the value (see Read a
quantity). print(quantity) shows the value, label
and conditions. The fields below are read-only.
Attributes:
-
metric(Metric) –Name of the quantity, such as
cx,shotsorlogical_width. -
fact(Fact) –The value, or the reason it is unavailable, with its unit, scope, conditions (
fact.assumptions) and the weakest evidence kind among the sources that determined it. -
population(Text) –What is counted, for example
"dynamic workload"for a total over the whole run or"simultaneous live footprint"for a peak. -
lifecycle(Literal['planned', 'prepared', 'submitted', 'observed']) –Workflow stage of the quantity:
"planned","prepared","submitted"or"observed". A planning estimate gives only"planned". -
basis(Text) –Gate basis of the estimate.
-
interpretation(Interpretation) –"exact","upper_bound","estimate","conditional"or"unavailable". -
location(Text | None) –Location of a width or byte peak,
Nonefor a total. -
sources(tuple[ContentID, ...]) –Content hashes of all evidence attached to the value, including evidence used only to check a block's gate decomposition against a declared rule.
-
derivation_sources(tuple[ContentID, ...]) –Content hashes of the evidence that determined the value, a subset of
sources. -
required_schedule(Literal['serial_acquisitions'] | None) –"serial_acquisitions"when this peak holds only if the circuit executions of each measurement batch run one after another, otherwiseNone. Follow it before comparing the peak with a device capacity. -
schema_version(Literal[2]) –Format version of the record, 2.
Raises:
-
ValueError–When a record is loaded whose label disagrees with its availability, whose value is negative, not real or, when exact, not an integer (
expected_operationsmay be fractional), whose unit does not match the metric, or whose derivation sources are not among its sources.
Declare costs and memory¶
A circuit block declares its own costs and memory with these records. The estimate reads them and allocates none of the declared memory.
ResourceLaw ¶
Bases: Record
The cost of one call of a circuit block in one metric, as the block declares it.
A circuit block of a Plan can declare cost rules for its metrics. The
estimate uses a rule only for a call whose control and adjoint flags, cost
parameters and call arguments, basis, precision and synthesis all match.
The value is a number per call, not a formula, so the estimate can check
it against the block's known gate decomposition and keep its source
without running caller code. Rules in different bases are alternatives, not additions.
Build it with keyword arguments when you write a block (see Compose
blocks). metric, basis, value, interpretation and
evidence are required.
Attributes:
-
metric(Metric) –Required. The count metric the rule supplies.
-
basis(MetricBasis) –Required. Basis the value is counted in.
-
value(NonnegativeInt | Float64) –Required. Nonnegative per-call value, an integer when
interpretationis"exact". -
interpretation(Literal['exact', 'upper_bound', 'estimate']) –Required.
"exact","upper_bound"or"estimate". -
evidence(Evidence) –Required. Where the value comes from. Observed, empirically predicted or numerically estimated evidence makes every quantity derived from it an estimate.
-
bindings(tuple[Binding, ...]) –Default
(). Cost parameters and call arguments that must match exactly for the rule to apply. -
unbound_parameters(tuple[Text, ...]) –Default
(). Formal parameters whose whole accepted range the rule covers instead of one value. Empty means exact matching only. -
controlled(StrictBool) –Default
False. Whether the rule is for the controlled block. -
adjoint(StrictBool) –Default
False. Whether the rule is for the adjoint block. -
precision(Float64 | None) –Default
None. Rotation precision the rule assumes. -
synthesis(Source | None) –Default
None. Synthesis method the rule assumes. -
assumptions(tuple[Text, ...]) –Default
(). Conditions carried into every quantity derived from the rule.
Raises:
-
ValueError–If the value is negative, an exact value is not an integer, a binding is repeated, or a parameter is both bound and listed in
unbound_parameters.
Workspace ¶
Bases: Record
Bytes needed at the same time at one location, as declared by a block or the caller.
A block's workspace lasts for each call. Entries in
ResourceContext.resident last for the whole workload. Sizes are
declarations, not observed allocations, and quantum widths are counted
separately. Build it with keyword arguments. All four fields are
required.
Attributes:
-
location(Text) –Where the bytes live, for example
"host". -
purpose(Literal['input', 'preparation', 'analysis', 'io', 'materialization', 'stored', 'workspace']) –"input","preparation","analysis","io","materialization","stored"or"workspace". -
bytes(NonnegativeInt | None) –Nonnegative byte count, or
Nonewhen unknown. An unknown size makes the memory peak at that location unavailable, never zero. -
source(Source) –Source of the declaration.