Solve, plan and read results¶
These calls turn a Problem and a configured Method into a Result. solve does it in one step, and plan, prepare and submit do it step by step, with compare, estimate and scan to choose before running. The Plan, compare and solve guide shows them in context, and Choose a problem and output explains the Problems and their outputs.
from nwqlib import (
Accuracy, ConstrainedOptimization, Eigenproblem, Eigenvalue, Expectation,
LinearDynamics, LinearSystem, Optimization, SpectralEstimation,
compare, estimate, load_result, load_run, methods, plan, prepare, scan,
solve, submit,
)
from nwqlib.core import Record
from nwqlib.execution import ExecutionLimits, Run, RunFailed
from nwqlib.search import Candidate, Objective
The outputs Eigenphase, NormSquared, NormalizedExpectation, OptimizationCandidate, QuadraticForm, Samples, Solution and StateVector also import from nwqlib. The eigenvalues of [[2, 1], [1, 2]] are 1 and 3, and Lanczos with a two-dimensional Krylov space finds the smaller one:
from nwqlib import Eigenproblem, solve
from nwqlib.algorithms import Lanczos
problem = Eigenproblem(A=[[2.0, 1.0], [1.0, 2.0]])
method = Lanczos(initial_state=[1, 0], krylov_dimension=2)
result = solve(problem, method=method, seed=7)
print(round(result.eigenvalue, 10)) # 1.0
| Task | Entries |
|---|---|
| Solve a problem in one call | solve |
| Build, copy and identify records | Record |
| State the question | Problems and outputs, Accuracy |
| Read the answer, check it and save it | Result and its answer table |
| Plan, compare or estimate before running | plan, compare, estimate |
| Rank candidate Plans | scan |
| Run step by step, with limits | prepare, submit, Run, ExecutionLimits |
| Reopen a saved Result or Run | load_result, load_run |
Method authors find the Method protocol, the hooks of Plan and Result and PreparedHandle in Extending NWQLib.
Solve a problem¶
solve ¶
solve(problem_or_plan, *, method=None, output=None, accuracy=None, backend=None, execution=None, shots=None, seed=None, limits=None, progress=None)
Solve a Problem with a Method and return its Result.
solve plans the computation (when given a Problem), prepares and runs
the circuits or the classical model, waits for completion and returns
the Method's Result. It does not run a reference check of the answer.
Use plan, prepare and submit to control each step, or to save a
run and continue it after an interruption.
Parameters:
-
problem_or_plan(object) –A Problem such as
Eigenproblem, aPlanfromplan, or aComparisonRowfromcompare. A Plan or row already fixes the method, output and measurement settings, somethod,output,accuracy,execution,shotsandseedmust then be omitted. -
method(Method | None, default:None) –Configured Method such as
Lanczos(), required with a Problem. -
output(OutputRecord | None, default:None) –Output requested from a Problem, such as
Eigenvalue(). Omitted, the Problem's default output is used. -
accuracy(Accuracy | None, default:None) –Optional accuracy request. A Method that defines
sampling_shotsuses it to choose the shots, and any other Method raisesApplicabilityError. It does not assert the accuracy achieved. -
backend(object | None, default:None) –Backend to run on. Omitted, the local default for the execution mode is used.
-
execution(str | None, default:None) –"quantum"(the default for a Problem) or"classical", which evaluates that Method's numerical model. -
shots(int | None, default:None) –Positive number of shots for sampled readout, or
Nonefor exact readout. A Method setting can choose the measurement instead, for exampleLanczos(sampling=...). -
seed(int | None, default:None) –Nonnegative seed of the random streams that planning and measurement of a Problem use. A seed does not establish statistical independence.
-
limits(ExecutionLimits | None, default:None) –Optional
ExecutionLimitsfor the Run's preparation and execution. -
progress(object | None, default:None) –Optional progress callback, called as
callback(stage, done, total).Falsedisables progress reports, andNonepermits the default notebook display.
Returns:
-
result(Result) –The Method's Result, with its Plan and run data attached. For example, a
LanczosResultholds the answer ineigenvalue.
Raises:
-
TypeError–If a Problem is given without
method. -
ValueError–If a Plan or row is given with
method,output,accuracy,execution,shotsorseed. Pass them to a newplan(...)instead.
Examples:
The smallest eigenvalue of [[1.5, -1], [-1, 0.5]] is
(2 - sqrt(5)) / 2 = -0.1180339887.... Lanczos with a full
two-dimensional trial space recovers it from exact probabilities:
>>> from nwqlib import Eigenproblem, solve
>>> from nwqlib.algorithms import Lanczos
>>> problem = Eigenproblem(A=[[1.5, -1], [-1, 0.5]])
>>> method = Lanczos(initial_state=[1, 0], krylov_dimension=2)
>>> result = solve(problem, method=method, seed=7)
>>> print(round(result.eigenvalue, 10))
-0.1180339887
Build, copy and identify records¶
Every Problem, output, Plan and Result is a Record.
Record ¶
The base of every NWQLib record: immutable, built with keyword arguments and validated when built.
Problems, outputs, Methods, Plans, Results and the other records derive
from it. Build a record with keyword arguments. Unknown fields are
rejected, and a record cannot be changed after it is built.
record.revise(**changes) returns a validated new record with the
changes and leaves the old one unchanged. Every construction, including
model_validate and model_validate_json from saved JSON, runs the
full validation, and model_dump(mode="json") returns a detached JSON
description. Unchecked model_construct and Pydantic's legacy copy
are disabled.
Each record has a content hash, content_id. A Result names its Plan,
an observation its circuit and a resource quantity its evidence by this
hash, so data stays attached to the record it came from. The hash covers
the record's concrete type, so two record classes with equal fields stay
distinct, its schema version, so a format change cannot collide with
old data, and its parent_id, so a revision stays distinguishable from
a separately built record with the same fields. A content_id given in
saved JSON is checked when the record is loaded, so edited JSON cannot
keep a stale hash.
Attributes:
-
schema_version(Literal[1]) –Version of the record's format, fixed by its type.
-
parent_id(ContentID | None) –Content hash of the record that this one revises, or
None.revisesets it. -
content_id(str) –The record's content hash, read-only: the SHA-256 digest of compact, sorted-key UTF-8 JSON of the record's fully qualified type and all its declared fields. Tuples keep their order, and numbers use Python's round-trip binary64 JSON form.
revise ¶
revise(**changes) -> Self
Return a validated copy with changes, recording this record as its parent.
The new record's parent_id is this record's content hash, and this
record is unchanged. Problems, outputs and Accuracy return a copy
without a parent link, because a changed input is a new input with
its own content hash.
Parameters:
-
**changes(object, default:{}) –New field values, by field name.
content_idandparent_idcannot be given.
Returns:
-
record(Record) –The new record, of the same type.
Raises:
-
ValueError–If
content_idorparent_idis given, or the new values fail validation.
Examples:
>>> from nwqlib.core import Unit
>>> hartree = Unit(symbol="Ha", dimension="energy")
>>> revised = hartree.revise(symbol="Hartree")
>>> print(revised.symbol, revised.parent_id == hartree.content_id)
Hartree True
Problems and outputs¶
Problems, outputs and accuracy requests.
A Problem states a mathematical question with its inputs and units, an output
names the quantity to compute, and an Accuracy states a requested tolerance.
A Problem holds no Method setting and no run limit. The Method is given to
plan or solve, and the limits to prepare or solve. A Problem keeps
the numerical data of its inputs. Its JSON form describes them, and a Problem
rebuilt from that description alone cannot access the numbers.
ProblemRecord ¶
The optional fields that every Problem accepts besides its own inputs.
Build a Problem class, such as
Eigenproblem, with keyword
arguments. Every Problem also accepts the optional fields below. A
Problem is immutable. problem.revise(**changes) returns a validated
copy with the changes, and a Problem with changed inputs has its own
content hash. A Problem holds no Method setting.
Attributes:
-
unit(OptionalUnit) –Default
None, which leaves the unit unspecified. Unit of the primary answer: the eigenvalue, the solution amplitudes, the observable's expectation or the objective. A string such as"Hartree"becomes aUnitof dimension"custom". NWQLib converts no units. Units lists the unit of each output. Without a unit, error evidence about the Problem is stated in an explicitly unspecified unit. -
scope(Scope | None) –Default
None, which makes no physical claim. AScopethat states the physical or model meaning of the Problem. Without it, error evidence about the Problem is scoped to the Problem kind in its original input coordinates. -
coordinates(tuple[Text, ...] | None) –Default
None. One label per input coordinate, in the input's index order. Labels do not change the basis or add missing state amplitudes. -
assumptions(tuple[Text, ...]) –Default
(). Assumptions stated with the Problem, as text. -
facts(tuple[Fact, ...]) –Default
(). Evidence about the inputs (Factrecords). No reference computation is run to produce it.
Raises:
-
TypeError–If
unitis neither a string, aUnit, a dict ofUnitfields norNone. -
ValueError–If
coordinatesdoes not label every input coordinate exactly once.
Eigenproblem ¶
The smallest eigenvalue of a Hermitian matrix or operator A.
Build it with keyword arguments, for example Eigenproblem(A=matrix),
and pass it to solve or plan with a Method
such as Lanczos. A is the only required argument. The other fields
below have defaults, and the optional unit, scope, coordinates,
assumptions and facts of
ProblemRecord are accepted
too. Without output=, the requested output is
Eigenvalue, in the Problem's
unit.
Attributes:
-
A(OperatorData) –Required. Finite Hermitian matrix or supported structured operator, in a form that
OperatorDataaccepts. -
target(Literal['smallest']) –Default
"smallest", the only accepted value. A Method returns its own estimate of this target. -
subspace(InputRef | None) –Default
None. An explicitly defined scientific subspace. A Method's trial basis or initial state does not change the full-space target. -
sector(Text | None) –Default
None. A scientific sector, which requires a compatible state preparation.
Raises:
-
ValueError–If
Ais not exactly Hermitian. If the Hermitian part of a matrixAis the intended problem, pass(A + A.conj().T) / 2. For a QiskitSparsePauliOpnamedop, passSparsePauliOp(op.paulis, coeffs=op.coeffs.real), which keeps every Pauli term without tolerance-based simplification.
Examples:
The eigenvalues of [[2, 1], [1, 2]] are 1 and 3. Lanczos with a
two-dimensional Krylov space recovers the smallest:
>>> from nwqlib import Eigenproblem, solve
>>> from nwqlib.algorithms import Lanczos
>>> problem = Eigenproblem(A=[[2.0, 1.0], [1.0, 2.0]], unit="Hartree")
>>> method = Lanczos(initial_state=[1, 0], krylov_dimension=2)
>>> result = solve(problem, method=method, seed=7)
>>> print(round(result.eigenvalue, 10))
1.0
LinearDynamics ¶
The solution u(time) of the linear equation du/dt = -A u + source with constant A and source.
Build it with keyword arguments, for example
LinearDynamics(A=matrix, initial_state=u0, time=1.0), and pass it to
solve or plan
with a Method such as LCHS. A, initial_state and time are
required. The optional unit, scope, coordinates, assumptions and
facts of ProblemRecord are
accepted too, and unit labels the solution amplitudes. Without
output=, the requested output is
Solution: u(time) in the original
coordinates, with its magnitude and phase.
Attributes:
-
A(OperatorData) –Required. Finite square matrix or supported structured generator, in a form that
OperatorDataaccepts. -
initial_state(StateData) –Required. The vector
u(initial_time), with its magnitude and phase, in the coordinates ofAand in a form thatStateDataaccepts. -
time(Real) –Required. Final time, at least
initial_time. -
source(StateData | None) –Default
None, which means zero. Constant source vector, with its magnitude and phase, in the coordinates ofA. -
initial_time(Real) –Default
0.0. Initial time. -
time_unit(OptionalUnit) –Default
None. Label of the time unit, of dimension"time"or"custom". NWQLib converts no units, so the numericalA*timemust be dimensionless.
Raises:
-
ValueError–If
timeis less thaninitial_time, ifinitial_stateorsourcehas another dimension or coordinate order thanA, or iftime_unithas another dimension.
Examples:
For A = diag(1, 2) the solution at time=0.5 from u = (1, 1) is
(exp(-0.5), exp(-1)) = (0.6065..., 0.3679...). The default LCHS
approximation, evaluated classically, gives:
>>> import numpy as np
>>> from nwqlib import LinearDynamics, solve
>>> from nwqlib.algorithms import LCHS
>>> problem = LinearDynamics(A=[[1.0, 0.0], [0.0, 2.0]],
... initial_state=[1.0, 1.0], time=0.5)
>>> result = solve(problem, method=LCHS(), execution="classical")
>>> print(np.round(result.solution.real, 2))
[0.61 0.37]
LinearSystem ¶
The solution x of the linear system A x = b.
Build it with keyword arguments, LinearSystem(A=matrix, b=vector), and
pass it to solve or
plan with a Method such as QLS. A and b
are required. The optional unit, scope, coordinates, assumptions
and facts of ProblemRecord
are accepted too, and unit labels the solution. Without output=, the
requested output is Solution: x
in the original coordinates, with its magnitude and phase. The Method
chooses any encoding or dilation of A.
Attributes:
-
A(OperatorData) –Required. Finite square matrix or supported structured operator, in a form that
OperatorDataaccepts. -
b(StateData) –Required. Right-hand side, with its magnitude and phase, in the coordinates of
Aand in a form thatStateDataaccepts.
Raises:
-
ValueError–If
bhas another dimension or coordinate order thanA.
Examples:
The solution of this system is (25/28, 5/28) = (0.8929..., 0.1786...).
QLS selects its inverse polynomial for its default
epsilon_inv=0.01, a construction target that does not bound the
total error, and returns an approximation:
>>> import numpy as np
>>> from nwqlib import LinearSystem, solve
>>> from nwqlib.algorithms.qls import QLS
>>> problem = LinearSystem(A=[[1.1, 0.1], [0.1, 0.9]], b=[1.0, 0.25])
>>> result = solve(problem, method=QLS(), seed=7)
>>> print(np.round(result.x.real, 3))
[0.897 0.181]
Expectation ¶
The expectation of a Hermitian observable O in a state u given in the same coordinates.
Build it with keyword arguments, Expectation(state=u, observable=O),
and pass it to solve or
plan with ExpectationMethod. Both arguments
are required. The optional unit, scope, coordinates, assumptions
and facts of ProblemRecord
are accepted too, and unit labels the normalized expectation. Without
output=, the requested output is
NormalizedExpectation
with this observable, the value u† O u / (u† u). Request
QuadraticForm for the
unnormalized u† O u.
Attributes:
-
state(StateData) –Required. The state
u, with its magnitude and phase, in a form thatStateDataaccepts. -
observable(OperatorData) –Required. Exactly Hermitian observable
O, with the dimension and coordinate order ofstate, in a form thatOperatorDataaccepts.
Raises:
-
ValueError–If
observableis not exactly Hermitian, orstatehas another dimension or coordinate order. For a QiskitSparsePauliOpnamedopwhose Hermitian part is the intended observable, passSparsePauliOp(op.paulis, coeffs=op.coeffs.real).
Examples:
For u = (2, 2) and O = diag(2, 0), the normalized expectation is
8 / 8 = 1 and the quadratic form is 8:
>>> from nwqlib import Expectation, QuadraticForm, solve
>>> from nwqlib.algorithms import ExpectationMethod
>>> problem = Expectation(state=[2.0, 2.0],
... observable=[[2.0, 0.0], [0.0, 0.0]])
>>> result = solve(problem, method=ExpectationMethod())
>>> print(round(result.value, 10))
1.0
>>> output = QuadraticForm(observable=problem.observable)
>>> physical = solve(problem, method=ExpectationMethod(),
... output=output, execution="classical")
>>> print(round(physical.value, 10))
8.0
SpectralEstimation ¶
An eigenphase or energy of a Hamiltonian or unitary, estimated from a prepared initial state.
Build it with keyword arguments, for example
SpectralEstimation(hamiltonian=H, initial_state=psi), and pass it to
solve or plan with
a phase-estimation Method: QCELS, SPE, RFE or RWPE.
initial_state is required, and exactly one of hamiltonian and
unitary. The optional unit, scope, coordinates, assumptions and
facts of ProblemRecord are
accepted too. Without output=, the requested output is
Eigenphase, a phase in turns. The
overlaps of initial_state with the eigenvectors define the spectral
population that the measurements sample. The Method chooses its sampling
schedule and branch convention. A unitary alone does not define an
energy.
The component each Method targets follows from its estimator. SPE, for
example, targets the lowest value in the prepared support, which is the
lowest energy of a Hamiltonian but the lowest principal eigenphase of a
unitary. For U = exp(-i tau H) with tau |E| < pi/2 for every
prepared energy E, that eigenphase belongs to the highest energy of the
support.
Attributes:
-
hamiltonian(OperatorData | None) –Default
None. Exactly HermitianH, in a form thatOperatorDataaccepts. Give it orunitary. -
unitary(OperatorData | None) –Default
None. UnitaryU, in a form thatOperatorDataaccepts. Give it orhamiltonian. The Method checks that it is unitary. -
initial_state(StateData) –Required. State whose overlaps with the eigenvectors define the sampled spectral population, in the coordinates of the operator and in a form that
StateDataaccepts.
Raises:
-
ValueError–If both or neither of
hamiltonianandunitaryare given, ifhamiltonianis not exactly Hermitian, or ifinitial_statehas another dimension or coordinate order than the operator.
Examples:
The initial state (1, 0) is the eigenvector of energy 0.2 of
H = diag(0.2, 0.7):
>>> from nwqlib import SpectralEstimation, solve
>>> from nwqlib.algorithms.qpe import QCELS
>>> problem = SpectralEstimation(
... hamiltonian=[[0.2, 0.0], [0.0, 0.7]], initial_state=[1, 0])
>>> result = solve(problem, method=QCELS(), seed=7)
>>> print(round(result.eigenvalue, 10))
0.2
Optimization ¶
The minimum of a SymPy objective over a finite box of real variables.
Build it with keyword arguments, for example
Optimization(objective=(x - 0.2)**2, variables=(x,), bounds=((-1.0, 1.0),))
with x = sympy.Symbol("x", real=True), and pass it to
solve or plan with
QHD. The three arguments are required. The optional unit, scope,
coordinates, assumptions and facts of
ProblemRecord are accepted
too, and unit labels the objective. Without output=, the requested
output is
OptimizationCandidate,
a candidate point and its objective value, which is not a proof of
optimality.
Attributes:
-
objective(SymbolicData) –Required. Scalar SymPy expression in the variables, not a string of source code.
-
variables(tuple[SymbolicData, ...]) –Required. SymPy symbols with distinct names. Their order is the coordinate order.
-
bounds(tuple[tuple[Real, Real], ...]) –Required. One finite
(lower, upper)pair withlower < upperper variable, in the order ofvariables.
Raises:
-
TypeError–If
objectiveor a variable is not a SymPy expression. -
ValueError–If
boundsdoes not give one interval per variable, an interval haslower >= upper, two variables share a name, a variable is not a SymPy symbol, orobjectivecontains a symbol that is not invariables.
Examples:
QHD's default grid has two interior points per variable, -1/3 and
1/3 on [-1, 1], and the objective is smaller at 1/3:
>>> import sympy as sp
>>> from nwqlib import Optimization, solve
>>> from nwqlib.algorithms.qhd import QHD
>>> x = sp.Symbol("x", real=True)
>>> problem = Optimization(objective=(x - 0.2)**2, variables=(x,),
... bounds=((-1.0, 1.0),))
>>> result = solve(problem, method=QHD(), seed=7)
>>> print([round(value, 10) for value in result.candidate])
[0.3333333333]
ConstrainedOptimization ¶
The minimum of a SymPy objective over a finite box of real variables, subject to equality and inequality constraints.
Build it with keyword arguments, for example
ConstrainedOptimization(objective=..., variables=(x,), bounds=((-1.0, 1.0),), inequalities=(sympy.Le(x, 0.5),)).
objective, variables, bounds and at least one constraint are
required. The optional unit, scope, coordinates, assumptions and
facts of ProblemRecord are
accepted too. Without output=, the requested output is
OptimizationCandidate.
The QHD augmented-Lagrangian layer, solve_augmented_lagrangian, solves
it as a sequence of QHD box problems (Constrained
problems). This record is not
an Optimization, so a Method for box problems alone, such as QHD,
rejects it at planning with ApplicabilityError, and no constraint is
silently dropped.
The stored constraints are residual expressions with the conventions
h_i(x) = 0 for equalities and g_j(x) <= 0 for inequalities, the
form of problem (4.1) in Birgin and Martinez, Practical Augmented
Lagrangian Methods for Constrained Optimization, SIAM 2014,
doi:10.1137/1.9781611973365, with the box as its set Omega. The QHD
augmented-Lagrangian layer follows that book, so a residual here enters
its multiplier updates and stopping tests with the book's signs. A
constraint given as a scalar SymPy expression is the residual itself.
Live input may also give Eq(a, b) as an equality, stored as a - b,
and Le(a, b) or Ge(a, b) as an inequality, stored as a - b or
b - a.
Attributes:
-
objective(SymbolicData) –Required. Scalar SymPy expression in the variables, not a string of source code.
-
variables(tuple[SymbolicData, ...]) –Required. SymPy symbols with distinct names. Their order is the coordinate order.
-
bounds(tuple[tuple[Real, Real], ...]) –Required. One finite
(lower, upper)pair withlower < upperper variable, in the order ofvariables. -
equalities(tuple[SymbolicData, ...]) –Default
(). Residualsh_iwith the constrainth_i(x) = 0, given as a tuple or list. -
inequalities(tuple[SymbolicData, ...]) –Default
(). Residualsg_jwith the constraintg_j(x) <= 0, given as a tuple or list.
Raises:
-
TypeError–If a constraint field is not a tuple or list, or a constraint is not a SymPy expression or relation.
-
ValueError–If no constraint is given, if a constraint is a strict relation (
Lt,Gt), anNerelation, a relation that SymPy has already evaluated to True or False, another Boolean object, a matrix or a relation in the wrong field, if a constraint contains a symbol outsidevariables, or if the box is invalid as forOptimization. For a strict inequality, give a non-strict form with an explicit margin, for exampleLe(x, 1 - margin)forx < 1.
Examples:
The inequality x >= 0.5 is stored as the residual 0.5 - x <= 0:
>>> import sympy as sp
>>> from nwqlib import ConstrainedOptimization
>>> x = sp.Symbol("x", real=True)
>>> problem = ConstrainedOptimization(
... objective=(x - 0.2)**2, variables=(x,), bounds=((-1.0, 1.0),),
... inequalities=(sp.Ge(x, 0.5),))
>>> print(problem.inequalities)
(0.5 - x,)
OutputRecord ¶
The optional field that every output accepts.
An output names the quantity to compute, for example Eigenvalue(),
and is passed as output= to solve,
plan or compare.
It holds no measured value and takes its scope from the Problem. The
Method's Result holds the value. Build an output class, not this base.
Units gives the unit of each output.
Attributes:
-
unit(OptionalUnit) –Default
None. Label of a quantity whose unit neither the Problem nor the output kind defines, for example an observable of aLinearDynamicsProblem. A string becomes aUnitof dimension"custom". It never converts numerical data.
Raises:
-
ValueError–At planning, if
unithas another symbol than the unit that the Problem defines or the output kind fixes. NWQLib converts no units, so omit the output unit or label the Problem instead.
Eigenvalue ¶
An eigenvalue, in the Problem's unit.
It is the default output of Eigenproblem, whose target is the
smallest eigenvalue. Pass Eigenvalue() as output= to request it
explicitly. Its error metric is the absolute error.
Eigenphase ¶
A phase phi in turns, with U v = exp(2 pi i phi) v and phi in [0, 1).
It is the default output of SpectralEstimation. Pass Eigenphase() as
output= to request it explicitly. Its unit is the turn, fixed by the
output kind. For a Hamiltonian input, U is exp(-i tau H) at the time
tau that the Method selects, so an energy E has phase
(-tau E / (2 pi)) mod 1 and the phase order need not follow the
energy order. A Method that targets the lowest principal eigenphase of a
supplied unitary exp(-i tau H), as SPE does, therefore reports the
phase of the highest prepared energy of H when tau |E| < pi/2 for
every prepared E. The error metric of this output is the circular
distance min(|d|, 1 - |d|) of the difference d between two phases in
[0, 1), so estimates on either side of phase zero are close.
Solution ¶
The solution vector in the original coordinates, with its magnitude and phase.
It is the default output of LinearDynamics and LinearSystem. Pass
Solution() as output= to request it explicitly. Its unit is the
Problem's unit, and its error metric is the l2 norm of the difference.
StateVector ¶
The amplitudes of a simulated state, with a declared normalization and phase convention.
Build it with keyword arguments, for example
StateVector(normalization="physical"), and pass it as output=. Every
argument is optional. With normalization="physical" the vector keeps
the magnitude of the solution, in the Problem's unit. With "unit" it
has length 1 and is dimensionless. Its error metric is the l2 norm of
the difference, or with global_phase="modulo_global_phase" the l2 norm
after the global phases are aligned. Full amplitudes are a simulator
readout, not a hardware measurement.
Attributes:
-
normalization(Literal['physical', 'unit']) –Default
"unit"."physical"or"unit". -
global_phase(Literal['physical', 'modulo_global_phase']) –Default
"physical"."physical", which compares phases as they are, or"modulo_global_phase", which treats vectors that differ by one global phase factor as equal.
NormSquared ¶
The squared norm u† u of a solution u, using its magnitude.
Pass NormSquared() as output= with a LinearDynamics or
LinearSystem Problem. Its unit is the square of the Problem's unit
when the Problem has one.
NormalizedExpectation ¶
The normalized expectation u† O u / (u† u) of a Hermitian observable O.
u is the state of an Expectation Problem, or the solution of a
LinearDynamics or LinearSystem Problem. The value is undefined when u
is zero. Build it with keyword arguments, for example
NormalizedExpectation(observable=O), and pass it as output= to
solve or plan. An Expectation Problem
requests it by default with its own observable. observable is the only
required argument. For an Expectation Problem with a unit, the value
is in that unit. Otherwise the optional unit of
OutputRecord labels it, and
without one the unit stays unspecified.
Attributes:
-
observable(OperatorData) –Required. Exactly Hermitian observable
O, in a form thatOperatorDataaccepts.
Raises:
-
ValueError–If
observableis not exactly Hermitian. For a QiskitSparsePauliOpnamedopwhose Hermitian part is the intended observable, passSparsePauliOp(op.paulis, coeffs=op.coeffs.real).
QuadraticForm ¶
The quadratic form u† O u of a Hermitian observable O, using the magnitude of u.
u is the state of an Expectation Problem, or the solution of a
LinearDynamics or LinearSystem Problem. Build it with keyword
arguments, for example QuadraticForm(observable=O), and pass it as
output= to solve or
plan. observable is the only required
argument. The value's unit stays unspecified unless the optional unit
of OutputRecord labels it,
because NWQLib infers neither the observable's unit nor the unit of the
product u† O u. This holds even when the Problem's unit labels u,
as it does for LinearDynamics and LinearSystem.
Attributes:
-
observable(OperatorData) –Required. Exactly Hermitian observable
O, in a form thatOperatorDataaccepts.
Raises:
-
ValueError–If
observableis not exactly Hermitian. For a QiskitSparsePauliOpnamedopwhose Hermitian part is the intended observable, passSparsePauliOp(op.paulis, coeffs=op.coeffs.real).
Samples ¶
Measured outcomes in the original coordinates, counted over the shots in which the Method succeeded.
Pass Samples() as output=, together with a number of shots. The
success event is, for example, the post-selection flag of QLS or LCHS.
shots sets the number of shots, and the stored counts include only the
shots in which that event occurred. Its unit is 1, and its error metric
is the total variation distance between distributions.
OptimizationCandidate ¶
A candidate point of the box and its objective value, with the objective gap as error.
It is the default output of Optimization and ConstrainedOptimization.
Pass OptimizationCandidate() as output= to request it explicitly. The
objective gap is the candidate's objective value minus a reference
minimum in objective units, for example the grid minimum that an
explicit QHD check evaluates. A candidate is not an optimality
certificate.
Accuracy ¶
A requested accuracy: one tolerance, a confidence and the error component it applies to.
Build it with keyword arguments, for example
Accuracy(absolute_tolerance=0.01, component="sampling"). Exactly one of
absolute_tolerance and relative_tolerance is required. The quantity
and unit it refers to come from the output. Pass it as accuracy= to
plan, solve or
compare, where only a Method that defines
sampling_shots uses it, to choose the shots. ExpectationMethod
accepts only an absolute tolerance on the sampling component for
finite Pauli counts. Pass it to Result.assess(accuracy=...) to check a
Result against it, for the total or the sampling component. An Accuracy
states a request and records no achieved accuracy. A total or relative
target is not silently interpreted as the narrower sampling request.
Attributes:
-
absolute_tolerance(Real | None) –Default
None. Positive bound on the error, in the unit of the output. -
relative_tolerance(Real | None) –Default
None. Positive bound on the error divided by the magnitude of the target. -
confidence(Real) –Default
0.95. Probability, strictly between 0 and 1, with which the bound must hold. -
component(Literal['total', 'sampling']) –Default
"total"."total"for the whole error of the output, or"sampling"for the sampling error only.
Raises:
-
ValueError–If both or neither tolerance is given, or a value is out of its range.
Read and check a Result¶
A Result's answer field depends on its Method, as the table in the Result entry shows. The Save, load and reanalyze results guide covers saved Results and reanalysis, and Check accuracy and verify a result covers assess and verify.
Result ¶
Bases: Record
The answer of a Method, with the Plan and measured data it came from.
solve and Run.wait return a Result, and
load_result reopens a saved one. Each
Method returns its own Result type, and its fields hold the answer:
| Method | Result type | Answer | Unit |
|---|---|---|---|
ExpectationMethod |
ExpectationAnalysis |
value |
The Problem's unit for the default NormalizedExpectation |
Lanczos |
LanczosResult |
eigenvalue |
The Problem's unit |
QCELS, SPE, RFE, RWPE |
QPEAnalysis |
eigenvalue for a Hamiltonian input, phase |
The Problem's unit for eigenvalue, turns in [0, 1) for phase |
FixedGCIM |
FixedGCIMResult |
eigenvalue |
The Problem's unit |
ADAPT |
ADAPTResult |
eigenvalue |
The Problem's unit |
LCHS |
LCHSAnalysis |
solution for the default Solution, value for a scalar output |
The Problem's unit for solution |
QLS |
QLSAnalysis |
x for the default Solution, value for any output |
The Problem's unit for x |
QHD |
QHDAnalysis |
candidate, the observed grid point with the smallest objective, and value, the objective there |
Coordinates of the variables for candidate, the Problem's unit for value |
For another requested output, the Result type names the field that holds
it, and Choose a problem and output gives its unit.
Each Result type states when its answer is unavailable. print(result) shows
the answer with its main conditions. analyze recomputes the Result
from the same data with other settings, assess compares it with an
accuracy criterion, verify runs a named check, report returns its
stored values as a dictionary and save writes it to a folder. The
Plan (result.plan) and run data (result.data) are attached to the
Result rather than stored in its fields, and save writes them with it.
The fields below identify where the answer came from, and they are read-only. A Method author's Result type sets them, as the Run your own circuit guide shows.
Attributes:
-
plan_id(ContentID) –Content hash of the Plan the Result was computed from.
-
construction_id(ContentID) –Content hash of the construction of that Plan.
-
observation_id(ContentID) –Content hash of the observations attached to the Result.
-
contribution_ids(tuple[ContentID, ...]) –Content hashes of the parts of the observations that this Result uses.
-
facts(tuple[FramedFact, ...]) –Error evidence that the Method attached (
FramedFactrecords), each stated for its quantity, unit and scope.assessreads it. -
origin(AnalysisOrigin | None) –The
AnalysisOriginof the analysis, orNonewhen it was not recorded.
plan ¶
plan
The Plan this Result was computed from.
Raises:
-
ValueError–If no Plan is attached, as for a Result built from its fields alone.
load_resultattaches the saved Plan.
data ¶
data
The RunData this Result was computed from.
It holds the observations, preparation records, attempt history and saved arrays of the Run.
Raises:
-
ValueError–If no run data is attached.
analyze ¶
analyze(**settings)
Recompute the Result from the same measured data with other analysis settings.
The Method analyzes the attached run data again and returns a new
Result, attached to the same Plan and data. Nothing is measured, and
this Result is unchanged. A loaded Result can be analyzed too. The
settings a Method accepts are listed in its guide, for example the
overlap_* settings of Lanczos.
Parameters:
-
**settings(object, default:{}) –Analysis settings of the Method. Omitted, the analysis uses the original settings.
Returns:
-
result(Result) –The new Result.
Raises:
-
ValueError–If no Plan or run data is attached. The Method raises its own error for a setting it does not accept.
assess ¶
assess(**criterion)
Check whether the Result's error evidence meets an accuracy criterion.
assess combines the error bounds that the Method attached in
facts, and any bounds supplied here, and compares them with the
criterion. It measures nothing, reruns nothing and leaves the Result
unchanged, so a stricter criterion later is a new assessment of the
same data. A known bound on one error component is never counted as a
bound on the total error. The Check accuracy and verify a
result guide explains the criteria.
Parameters:
-
**criterion(object, default:{}) –The criterion, given either as
accuracy=Accuracy(...)or by the fields ofAccuracy: exactly one ofabsolute_toleranceandrelative_tolerance,confidence(default0.95) andcomponent("total", the default, or"sampling"). The optional keywordfactsgives error evidence (FramedFactrecords) that replaces the Result's evidence of the same name,referencegives aTargetReferencethat supplies the target's scale for a relative tolerance,absolute_fallbackgives a positive absolute tolerance used when that scale is unavailable or zero, andmax_integer_bits, default4096, limits the integers of the exact arithmetic.
Returns:
-
assessment(ClaimAssessment) –The
ClaimAssessment. Itsstatusis"PASS"when every required error source has a supported bound and together they meet the tolerance at the requested confidence,"INCONCLUSIVE"when they do not show it, for example because a bound exceeds the tolerance or a source is unknown, and"NOT_APPLICABLE"forcomponent="sampling"when the Method's error model has no sampling source.
Raises:
-
ValueError–If
accuracyis given together with the individual fields, or the Method has no error model.
Examples:
An exact classical solve has no sampling error, while its total error stays unproven:
>>> from nwqlib import Eigenproblem, solve
>>> from nwqlib.algorithms import FixedGCIM
>>> problem = Eigenproblem(A=[[1.0, 0.0], [0.0, -1.0]])
>>> method = FixedGCIM(basis=([1.0, 0.0], [0.0, 1.0]))
>>> result = solve(problem, method=method, execution="classical")
>>> print(result.eigenvalue)
-1.0
>>> print(result.assess(absolute_tolerance=0.01,
... component="sampling").status)
PASS
>>> print(result.assess(absolute_tolerance=0.01).status)
INCONCLUSIVE
verify ¶
verify(*, checks)
Run a named check of the Result, such as a residual or a comparison with a reference.
The check is described by one options record of a type that the
Method supports. It computes what the record names, at the cost the
record states, and only when called. Every built-in options type
returns (receipt, facts). receipt records the check, its raw
values and the numerical calls it made, and facts is a tuple of
FramedFact records that cite receipt. The Check accuracy and
verify a result guide describes each check.
| Method | Options types |
|---|---|
| LCHS | LCHSVerification, LCHSRefinement |
| Lanczos, FixedGCIM | ProjectedVerificationOptions, EnergyShiftOptions |
| ADAPT | ProjectedVerificationOptions, AdaptVerificationOptions |
| QHD | NumberSectorOptions, QHDVerification |
| QLS | QLSVerification |
| QCELS, SPE, RFE, RWPE | QPEVerification |
Except for LCHSRefinement, facts answers the checks that the
options list in verification_checks, and
Certificate.with_verification
attaches it with the same options. LCHSRefinement returns error
components of the output for assess instead.
Parameters:
-
checks(object) –One options record from the table.
Returns:
-
verification(tuple) –(receipt, facts)as described above.
Raises:
-
ValueError–If no Plan or run data is attached. The Method raises its own error for an options type it does not support.
Examples:
The Gram matrix of an orthonormal trial basis is the identity, so its deficit from positive semidefiniteness is zero:
>>> from nwqlib import Eigenproblem, solve
>>> from nwqlib.algorithms import FixedGCIM
>>> from nwqlib.evidence.verification import (
... ProjectedVerificationOptions)
>>> problem = Eigenproblem(A=[[1.0, 0.0], [0.0, -1.0]])
>>> method = FixedGCIM(basis=([1.0, 0.0], [0.0, 1.0]))
>>> result = solve(problem, method=method, execution="classical")
>>> options = ProjectedVerificationOptions(
... name="projected", comparisons=("gram_psd_deficit",),
... tolerance=1e-10)
>>> receipt, facts = result.verify(checks=options)
>>> print(facts[0].fact.quantity, facts[0].fact.value.numerator)
projected.gram_psd_deficit 0
report ¶
report()
Return the Result's stored values, Plan and run records as a dictionary.
The dictionary holds the printed summary and the JSON forms of the
Plan, the Result, the attempt history, the observations, the
preparation records, the manifests of the saved arrays, the forecast,
the Allocation and the iteration state of an adaptive Method. It
reads stored records only. It loads no array, runs no check,
reassesses no accuracy, reanalyzes nothing and does not refresh a
Run. Each array manifest
comes with available, which says whether the array can be read,
without reading it. A probability observation shows its array
manifests and summary values. Each observation is listed with its
content_id, the content hash that contribution_ids name. The
records nested in an observation, such as its statistics, are listed
without their own content hashes, so the report computes none per
stored entry. The dictionary describes the Result, and it cannot be
loaded back. Save with save, and read a saved folder without
loading Method code with nwqlib.saved_evidence.read_report.
Returns:
-
report(dict) –Keys
summary,plan,result,trace,observations,receipts,artifacts,forecast,allocationandcontroller. Values that need run data areNonewhen none is attached.
Examples:
>>> from nwqlib import Eigenproblem, solve
>>> from nwqlib.algorithms import FixedGCIM
>>> problem = Eigenproblem(A=[[1.0, 0.0], [0.0, -1.0]])
>>> method = FixedGCIM(basis=([1.0, 0.0], [0.0, 1.0]))
>>> result = solve(problem, method=method, execution="classical")
>>> report = result.report()
>>> print(report["summary"].splitlines()[0])
Ritz eigenvalue: -1
>>> print(report["result"]["eigenvalue"])
-1.0
save ¶
save(path)
Save this Result with its Plan and run data to a new directory.
load_result(path) reopens the saved Result, and Result.analyze
can then recompute it with other settings without new measurements.
Saving checks that the Result, Plan and data belong together before
it writes any file. If saving fails, the new directory is removed.
The saved files may total at most 10 GB (decimal).
Parameters:
-
path(str | PathLike) –Directory to create. Its parent must exist and the directory itself must not.
Returns:
-
path(Path) –The created directory.
Raises:
-
FileExistsError–If
pathalready exists.
RunData ¶
RunData(observations: object, trace: object, receipts: tuple = (), artifacts: tuple = (), controller: object = None, method_context: object = None, forecast: object = None, allocation: object = None)
The measured data of a Run, as attached to its Result.
result.data and run.data return it. It shares the Run's immutable
observations, preparation records and arrays, so taking it copies no
array and builds no circuit, and it reevaluates no model. The fields
below are read-only.
Attributes:
-
observations(object) –Every observation the Run collected, as an
ObservationView. Itschunkshold the statistics of each measurement. -
trace(object) –The
ExecutionTrace: every attempt, its status and the work counted against the limits, failed and uncertain attempts included. -
receipts(tuple) –The preparation records (
PreparedArtifact) of the circuits and of the host computations (classical computations that the Method runs on this machine) that ran. Taking the snapshot builds none of them again. -
artifacts(tuple) –Handles of the saved arrays (
ArtifactHandle). Reading a handle copies no data. -
controller(object) –The saved iteration state and decision history of an adaptive Method, as JSON text, or
None. -
method_context(object) –Analysis data that the Method keeps with the Result, without its private working caches, or
None. -
forecast(object) –The
PlanEstimategiven to the Run, orNone. -
allocation(object) –The
Allocationgiven to the Run, orNone.
artifact ¶
artifact(manifest)
Return the handle of one saved array, without copying its data.
Parameters:
-
manifest(ArtifactManifest | str) –The array's manifest, or its content hash.
Returns:
-
handle(ArtifactHandle) –The handle. Read the values with
handle.array.
Raises:
-
ValueError–If this Run's data holds no such array.
AnalysisOrigin ¶
Bases: Record
The analysis call that computed a Result, and its software versions.
A Result records it in origin. Loading a saved Result keeps the
original record and does not create a new one. The fields below are
read-only.
Attributes:
-
invocation_id(Text) –Unique identifier of this analysis call. It does not identify a measurement.
-
analyzer(Source) –Name, version and reference of the code that computed the Result (
Source). -
method_id(ContentID | None) –Content hash of the configured Method, or
Nonewhen no Method is involved. -
environment(tuple[Source, ...]) –The Python and package versions (
Sourcerecords) found when the analysis ran. -
unavailable_versions(tuple[Text, ...]) –Names of requested packages whose version could not be read. A missing version is not version zero.
ArtifactManifest ¶
Bases: Record
The description of a saved array: what it is, where it came from and its content hash.
A Result names its arrays by their manifests, for example
LCHSAnalysis.artifact, and result.data.artifact(manifest) returns
the array's handle. A manifest gives no access to the array itself. The
manifest of a readout array names the preparation record as its
construction and the readout declaration in producer_id. The fields
below are read-only.
Attributes:
-
plan_id(ContentID) –Content hash of the Plan.
-
realization_id(ContentID) –Content hash of the concrete parameter values of the experiment.
-
construction_id(ContentID) –Content hash of the construction that produced the output, or for a readout array the preparation record of its measurement.
-
producer_id(ContentID) –Content hash of the host computation or readout declaration that produced the array.
-
output(ArrayOutput | ReadoutArray) –The array's shape, basis and normalization and phase convention (
ArrayOutput), or the component of a readout array (ReadoutArray). -
acquisition(tuple[Text, Text, Text, Text]) –The
(run, attempt, measurement, slot)that produced the array. -
source(Source) –The code and method that produced the array (
Source). -
digest(ContentID) –Content hash of the saved numerical bytes. It does not prove that the values are scientifically correct.
-
data_bytes(Count) –Size of the array data in bytes, which matches the output's shape and dtype.
-
encoding(Literal['complex128-le-c', 'float64-le-c', 'uint64-le-c']) –Byte order of the saved data,
"complex128-le-c","float64-le-c"or"uint64-le-c", as the output's dtype selects.
ArtifactHandle ¶
ArtifactHandle(*args, **kwargs)
A saved array with its manifest.
result.data.artifact(manifest), run.hydrate(manifest) and
result.data.artifacts give handles, and handle.array reads the
values as a read-only NumPy array. A handle cannot be built directly. A
handle of a reopened Run or loaded Result reads its array from the saved
data on first access. The fields below are read-only.
Attributes:
-
manifest(ArtifactManifest) –The array's
ArtifactManifest: content hash, output convention and the measurement that produced it.
array ¶
array
The array, as a read-only NumPy array.
Reading it copies and computes nothing. A saved array is read once from the saved data, at the first access.
Raises:
-
ValueError–If the array data is not available.
ReportSection ¶
ReportSection(*, title: str, lines: tuple[str, ...] = (), data: Mapping[str, Any] = dict())
A titled section of a report, with lines of text and machine-readable data.
Build it with keyword arguments, for example
ReportSection(title="Reference", lines=("E_ref = -1.0",), data={"E_ref": -1.0}).
title is required. The GCiM guide builds one
to show a stored reference panel next to an obtained energy.
Parameters:
-
title(str) –Section title.
-
lines(tuple[str, ...], default:()) –Lines of text for a printed report.
-
data(Mapping[str, Any], default:dict()) –Machine-readable data of the section.
Plan, compare and estimate before running¶
plan returns a Plan without running anything, compare plans several Methods and estimates each Plan, and estimate counts the resources of one Plan. estimate adds up counting formulas, and Prepared.inspect_resources counts the operations of the circuits that preparation built.
plan ¶
plan(problem, *, method, output=None, accuracy=None, execution='quantum', shots=None, seed=None)
Plan how a Method computes the requested output of a Problem, without running it.
The Method chooses its construction, circuits and readout once, and the
returned Plan fixes the Problem, Method,
output, readout and the state of the random streams after the Method's
planning draws. solve,
prepare and
submit run this Plan and never plan again, so
a different choice needs a new Plan. Planning computes what the Method
needs to build its circuits and takes no measurement.
estimate reads the Plan's resource counts.
Parameters:
-
problem(ProblemRecord) –A Problem such as
Eigenproblem. -
method(Method) –Configured Method such as
Lanczos(). Required. -
output(OutputRecord | None, default:None) –Requested output, such as
Eigenvalue(). Omitted, the Problem's default output is used. -
accuracy(Accuracy | None, default:None) –Optional accuracy request. A Method that defines
sampling_shotsuses it to choose the shots, and the Plan records the request inselection_accuracy. Any other Method raisesApplicabilityError. It does not assert the accuracy achieved. -
execution(str, default:'quantum') –"quantum"(the default) or"classical", which evaluates the Method's numerical model on the host. -
shots(int | None, default:None) –Positive number of shots for sampled readout, or
None(the default) for exact readout. -
seed(int | None, default:None) –Nonnegative seed of the random streams. Omitted, NumPy draws fresh entropy, and the Plan records it in
randomness.
Returns:
-
plan(Plan) –The Plan. Its
content_ididentifies it, and every Result computed from it names it inplan_id.
Raises:
-
TypeError–If
methodis not a Method. -
ValueError–If
executionis neither"quantum"nor"classical", ifshotsis not a positive integer orNone, ifseedis negative or not an integer, or ifoutputhas a unit whose symbol differs from the one the Problem or the output kind defines. -
ApplicabilityError–If the Method cannot compute this output of this Problem, or if
accuracyis given to a Method withoutsampling_shots.
Examples:
The eigenvalues of [[2, 1], [1, 2]] are 1 and 3:
>>> from nwqlib import Eigenproblem, plan, solve
>>> from nwqlib.algorithms import Lanczos
>>> problem = Eigenproblem(A=[[2.0, 1.0], [1.0, 2.0]])
>>> method = Lanczos(initial_state=[1, 0], krylov_dimension=2)
>>> selected = plan(problem, method=method, seed=7)
>>> print(type(selected.output).__name__, selected.execution, selected.shots)
Eigenvalue quantum None
>>> print(round(solve(selected).eigenvalue, 10))
1.0
Plan ¶
Bases: Record
The computation a Method planned for one Problem: its construction, experiments and error model.
plan returns it, and result.plan holds the
Plan that a Result came from. Pass it to
solve or
prepare to run it, or to
estimate to count its resources.
print(plan) shows its Method, Problem, output, execution mode, shots
and number of experiments.
A Plan is the choice a Method made once for one Problem, output,
execution mode, shot request and seed. Preparation, execution,
analysis, saving and loading use this Plan and never run the Method's
planning again. Any change to a scientific choice, including the shots
or a circuit parameter value that conflicts with the planned one, needs
a new Plan with a new content hash. This is what lets a Result, its
observations and a resource forecast name the Plan they belong to by
plan_id. If planning could be repeated silently, data could end up
attached to a construction it was not measured from. The limits of a
Run, the settings of a later analysis and a later accuracy criterion
are not Plan fields, so they do not change its content hash. A row of a
comparison or search holds at most one Plan, and selecting a row returns
it with the same Plan object (Execute the selected
row). A Plan keeps live
access to its inputs and to the circuit blocks that the Method bound to
it, and its JSON description cannot rebuild them.
A Method author's planning step builds a Plan with keyword arguments, as Run your own circuit shows. The fields below are read-only.
Attributes:
-
problem(ProblemRecord) –Required. The Problem, with its inputs.
-
method(Method) –Required. The configured Method that planned this computation.
-
output(OutputRecord) –Required. The requested output.
-
execution(Literal['quantum', 'classical']) –Required.
"quantum"or"classical". -
shots(Count | None) –Default
None, which means exact readout. Positive number of shots per sampled measurement. -
selection_accuracy(Accuracy | None) –Default
None. The accuracy request that chose the shots. It is a request, not an achieved error bound. -
randomness(RandomState) –Required. Root seed and the states of the named random streams after planning.
-
construction(SelectedConstruction) –Required. The planned circuit, described as a
Programof named steps, with the definitions of its circuit blocks and the host computations it declares (SelectedConstruction). -
experiments(tuple[Experiment, ...]) –Default
(). TheExperimentrecords in order, with unique names and the readout of each. -
reconstruction(Any) –Default
None. Data the Method needs to interpret the observations. -
error_model(ErrorModel | None) –Default
None, which means no error model. The known and unavailable error sources of the output (ErrorModel). -
facts(tuple[FramedFact, ...]) –Default
(). Evidence (FramedFactrecords) established during planning, with its conditions. -
assumptions(tuple[Text, ...]) –Default
(). Mathematical or experimental assumptions, kept without checking them. -
requirements(tuple[Text, ...]) –Default
(). Unmet operational or scientific requirements that the Method reports.preparerefuses a Plan that has any. -
content_id(str) –The Plan's content hash, read-only. It covers the fields above, with the concrete types of the Problem, Method and output, and not the bound circuit blocks.
Raises:
-
TypeError–If
methodis not a configured Method. -
ValueError–If experiment names repeat or
shotsis 0.
compare ¶
compare(problem, *, methods, output=None, accuracy=None, execution='quantum', shots=None, seed=None, profile=None, allocation=None, context=None, assessed_at=None, facts=(), reference=None, max_assessments=4096)
Plan one Problem with several Methods and estimate the resources of each Plan.
compare returns a Comparison with one
row per Method, in the order given. Each row holds the Method's Plan and
its resource estimate, as estimate gives
it. A Method that cannot handle the Problem gives a row with a reason
and no Plan instead of an error. Nothing is measured, no reference value
is computed and the rows are not ranked. Pass a row to
solve or prepare
to run it, or rank the rows with scan. Each Method
plans with its own child of one numpy.random.SeedSequence(seed), so no
Method's planning draws shift another's, and with an integer seed every
row is reproducible. The Plan, compare and solve guide
shows a comparison.
Parameters:
-
problem(ProblemRecord) –The Problem every Method plans.
-
methods(list | tuple) –Configured Methods, at least one.
-
output(OutputRecord | None, default:None) –Requested output. Omitted, the Problem's default output is used.
-
accuracy(Accuracy | None, default:None) –Optional accuracy request, as for
plan. A Method withoutsampling_shotsthen gives a row with a reason. -
execution(str, default:'quantum') –"quantum"(the default) or"classical". -
shots(int | None, default:None) –Positive number of shots for sampled readout, or
None(the default) for exact readout. -
seed(int | None, default:None) –Nonnegative seed shared by the rows, as described above. Omitted, NumPy draws fresh entropy.
-
profile(DeviceProfile | None, default:None) –Device models to evaluate for every row, as for
estimate. It needs anallocation. -
allocation(Allocation | None, default:None) –The devices granted to a run, kept with every row.
-
context(ResourceContext | None, default:None) –Counting options for the resource estimates. Omitted,
ResourceContext()applies. -
assessed_at(datetime | None, default:None) –Time-zone-aware time of the device forecasts. It needs a profile or Allocation.
-
facts(tuple[FramedFact, ...], default:()) –Accuracy evidence assessed with the forecast of every row and kept with it. It needs a profile and
accuracy, and each Plan needs an error model. -
reference(TargetReference | None, default:None) –Target reference, with the same use and requirements as
facts. -
max_assessments(int, default:4096) –Default
4096. Largest number of forecast rows, as forestimate, summed over the rows of the comparison and checked before the first model evaluation.
Returns:
-
comparison(Comparison) –One row per Method, in the order given.
Raises:
-
TypeError–If
methodsis not a nonempty list or tuple, orfactsis not a tuple. -
ValueError–If
facts,referenceorassessed_atis given without what it needs, if a profile is given without an Allocation, ifshotsorseedis invalid, or if the forecast needs more thanmax_assessmentsrows.
Examples:
For Z + I, Lanczos from the state |+> with one Krylov vector
projects onto that state, whose energy is 1. FixedGCIM with the
trial states |+> and |+i> spans the whole space, whose
eigenvalues are 0 and 2:
>>> from nwqlib import Eigenproblem, compare, solve
>>> from nwqlib.algorithms import FixedGCIM, Lanczos
>>> problem = Eigenproblem(A=[[2.0, 0.0], [0.0, 0.0]])
>>> plus, plus_i = [1.0, 1.0], [1.0, 1j]
>>> comparison = compare(problem, methods=(
... Lanczos(initial_state=plus, krylov_dimension=1),
... FixedGCIM(basis=(plus, plus_i)),
... ), seed=7)
>>> for row in comparison.rows:
... print(row.method.descriptor.method, row.reason)
chebyshev_lanczos None
fixed_gcim None
>>> for index in range(2):
... result = solve(comparison.select(index))
... print(round(result.eigenvalue, 10))
1.0
0.0
Comparison ¶
Comparison(problem: object, rows: tuple[ComparisonRow, ...])
The Plans and resource estimates of several Methods for one Problem.
compare returns it, with one row per Method
in the order the Methods were given. select(index) returns a row to pass
to solve or
prepare. A Comparison ranks nothing and
names no best Method. scan ranks rows by stated
objectives. The fields below are read-only.
Attributes:
-
problem(object) –The Problem shared by every row.
-
rows(tuple[ComparisonRow, ...]) –The
ComparisonRowrecords, in the order the Methods were given. Selecting a row returns it unchanged, with its Plan, estimate and evidence, and does not rank, plan or run anything.
select ¶
select(index)
Return the row at index, unchanged.
Any row can be selected, including one without a Plan. Running a row
without a Plan raises ApplicabilityError with the row's reason.
Parameters:
-
index(int) –Row position, from 0 to
len(rows) - 1.
Returns:
-
row(ComparisonRow) –The row at that position.
Raises:
-
IndexError–If
indexis not an integer in that range.
ComparisonRow ¶
ComparisonRow(method: Method, plan: Plan | None, reason: str | None = None, estimate: object = None, allocation: object = None, facts: tuple = (), reference: object = None, prior_work: tuple = ())
One Method of a comparison, with its Plan and resource estimate.
compare and scan
build the rows, and Comparison.select(index) returns one. Pass a row to
solve or prepare
to run its Plan, together with its device forecast and Allocation when it
has them. A Method that cannot handle the Problem gives a row with a
reason and no Plan, and running that row raises ApplicabilityError.
The fields below are read-only. Reading a row evaluates no model and
builds no circuit.
Attributes:
-
method(Method) –The configured Method. The row's Plan was made by this Method.
-
plan(Plan | None) –The Method's Plan, or
Nonewhen the Method cannot handle the Problem. -
reason(str | None) –Why the Method cannot handle the Problem, or
Nonefor a row with a Plan. -
estimate(object) –The resource estimate of this Plan: a
WorkloadEstimate, or aPlanEstimatewhen a device profile or Allocation was given, with device predictions when a profile was given.Nonefor a row without a Plan. -
allocation(object) –The Allocation given to
compareorscan, kept with the forecast, orNone. -
facts(tuple) –Accuracy evidence (
FramedFactrecords) supplied for this row. Each keeps the subject and point it was stated for and is not applied to another row. -
reference(object) –The supplied target reference (
TargetReference), orNone. No reference value is computed. -
prior_work(tuple) –Records (
Fact) of work done earlier, as supplied. They are kept apart from the work of a later run.
estimate ¶
estimate(plan, *, context=None, profile=None, allocation=None, assessed_at=None, facts=(), reference=None, max_assessments=4096)
Estimate the resources of a Plan, and optionally its run time on a device, without running it.
Without a device profile or Allocation, estimate adds up the counting
formulas of the Plan's construction (qubits, operations, shots and the
other metrics) and returns a WorkloadEstimate. A metric without a
formula is reported as unavailable, never as zero. With a profile, it
also evaluates the profile's device models at each planned execution
whose parameters are already fixed, and returns a PlanEstimate. With
an Allocation and no profile, the PlanEstimate keeps the Allocation and
makes no device prediction. Nothing is executed or compiled. The
Estimate resources and Check device fit and run
time guides explain how to read both.
Parameters:
-
plan(Plan) –The Plan to estimate.
-
context(ResourceContext | None, default:None) –Counting options, such as the gate basis (
ResourceContext(basis="cx")) and the schedule of independent executions. Omitted,ResourceContext()applies. -
profile(DeviceProfile | None, default:None) –Device models to evaluate. It needs an
allocation. -
allocation(Allocation | None, default:None) –The devices granted to the run. Given without a profile, it is kept with the estimate and no device prediction is made.
-
assessed_at(datetime | None, default:None) –Time-zone-aware time at which the device models are evaluated. Omitted, the current time is used. It needs a profile or Allocation.
-
facts(tuple[FramedFact, ...], default:()) –Accuracy evidence to assess with the forecast. It needs a profile, an error model in the Plan and an accuracy request in the Plan (
plan(..., accuracy=...)). -
reference(TargetReference | None, default:None) –Target reference to assess with the forecast, with the same requirements as
facts. -
max_assessments(int, default:4096) –Default
4096. Largest number of forecast rows, one assessment per planned execution and one prediction per device model for each, checked before the first model evaluation. Adding up the construction's counts is not limited by it.
Returns:
-
estimate(WorkloadEstimate | PlanEstimate) –WorkloadEstimatewithout a profile or Allocation,PlanEstimatewith one. Read a count of aWorkloadEstimatewithestimate.quantity(metric).
Raises:
-
TypeError–If
planis not a Plan orfactsis not a tuple. -
ValueError–If
assessed_at,factsorreferenceis given without a profile or Allocation, iffactsorreferenceis given without the profile, error model and accuracy request it needs, if a profile is given without an Allocation, ifassessed_athas no time zone, or if the forecast needs more thanmax_assessmentsrows.
Examples:
The Plan requests 64 shots of a one-qubit circuit:
>>> from nwqlib import Expectation, estimate, plan
>>> from nwqlib.algorithms import ExpectationMethod
>>> problem = Expectation(state=[1.0, 0.0],
... observable=[[1.0, 0.0], [0.0, -1.0]])
>>> selected = plan(problem, method=ExpectationMethod(), shots=64,
... seed=7)
>>> workload = estimate(selected)
>>> print(workload.quantity("shots").fact.value.numerator)
64
>>> width = workload.quantity("logical_width",
... location="logical_device")
>>> print(width.fact.value.numerator)
1
methods ¶
methods()
List the built-in Methods.
Each entry is a registration record. Its source.name and
source.version name the Method. A registration declares what the Method
is for. It does not establish that the Method or a backend has been
validated for a problem. Nothing is run. The command-line algorithms,
card and options commands print the same information and each
Method's settings (Use the command line).
Returns:
-
registrations(tuple[Registration, ...]) –One record per built-in Method.
Examples:
>>> from nwqlib import methods
>>> print([entry.source.name for entry in methods()])
['adapt_gcim', 'chebyshev_lanczos', 'finite_pauli_expectation', 'fixed_gcim', 'lchs', 'qcels', 'qhd', 'qls', 'rfe', 'rwpe', 'spe']
Rank candidate plans¶
scan ¶
scan(candidates, *, objectives, profile=None, context=None, assessed_at=None, max_candidates=256, max_assessments=4096, max_pair_comparisons=1000000, max_values=4096, max_integer_bits=4096)
Rank Plans of one Problem by resource objectives and return their Pareto front.
For each candidate, scan estimates the resources of its Plan, as
estimate does, evaluates each objective
and returns a SearchResult. Its
selection.nondominated lists the rows that no other row beats on every
objective, and select(index) returns a row to run. A ranking that rests
on conditional values, such as model predictions, is conditional too.
Passing an existing Comparison rescores
its stored estimates and forecasts, and then nothing is planned,
estimated or predicted. Every row is an existing Plan. A different shot
count or Method setting is a different Plan, supplied as another
candidate. The candidate, value and comparison limits are checked before
any estimate, model evaluation or comparison, and a profile's complete
set of forecasts is checked before its first model evaluation. The
Rank candidate plans guide describes the objectives.
Parameters:
-
candidates(tuple[Candidate, ...] | Comparison) –The
Candidaterecords of Plans of one Problem, or a Comparison to rescore. -
objectives(tuple[Objective, ...]) –Distinct objectives, all minimized.
-
profile(DeviceProfile | None, default:None) –Device models for time forecasts. Every candidate then needs an Allocation. Not accepted when rescoring.
-
context(ResourceContext | None, default:None) –Counting options for the resource estimates. Omitted,
ResourceContext()applies. Not accepted when rescoring. -
assessed_at(datetime | None, default:None) –Time-zone-aware time of new forecasts. Omitted, the current time is used. Not accepted when rescoring.
-
max_candidates(int, default:256) –Default
256. Largest number of rows. -
max_assessments(int, default:4096) –Default
4096. Largest number of forecast rows evaluated, or read from a stored Comparison. -
max_pair_comparisons(int, default:1000000) –Default
1_000_000. Largest number of coordinate comparisons of the Pareto front,N*(N-1)*kfor N rows and k objectives. -
max_values(int, default:4096) –Default
4096. Largest number of row and objective values,N*k. -
max_integer_bits(int, default:4096) –Default
4096. Largest bit length of an integer in the exact rational arithmetic.
Returns:
-
result(SearchResult) –The ranked Comparison and its
SearchSelection.
Raises:
-
TypeError–If
objectivesis not a nonempty tuple of Objective records, orcandidatesis neither a nonempty tuple of Candidate records nor a Comparison. -
ValueError–If the objectives are not distinct, a limit has an invalid value or is exceeded, the candidates plan different Problems, a profile is given without an Allocation on every candidate, or a Comparison is rescored with
profile,contextorassessed_at.
Examples:
Two Plans that differ only in their shots, ranked by requested shots:
>>> from nwqlib import Expectation, plan, scan
>>> from nwqlib.algorithms import ExpectationMethod
>>> from nwqlib.search import Candidate, Objective
>>> problem = Expectation(state=[1.0, 0.0],
... observable=[[1.0, 0.0], [0.0, -1.0]])
>>> plans = tuple(plan(problem, method=ExpectationMethod(), shots=n,
... seed=7) for n in (8, 32))
>>> search = scan(tuple(Candidate(p) for p in plans),
... objectives=(Objective(kind="requested_shots"),))
>>> print(search.selection.nondominated)
(0,)
>>> print(search.select(0).plan.shots)
8
Candidate ¶
Candidate(plan: Plan, *, allocation: Allocation | None = None, facts: tuple[FramedFact, ...] = (), reference: TargetReference | None = None, prior_work: tuple[Fact, ...] = ())
A Plan to rank with scan, with its optional device context.
Build it with the Plan and optional keyword arguments, for example
Candidate(plan, allocation=allocation), and pass a tuple of candidates
to scan. A Candidate changes nothing in its Plan. A different Method
setting or shot count is a different Plan and a separate candidate, and
scan neither creates nor tunes Method configurations.
Parameters:
-
plan(Plan) –Required, positional. A Plan from
plan. -
allocation(Allocation | None, default:None) –The devices granted to a run of this Plan (
Allocation), needed for device forecasts. -
facts(tuple[FramedFact, ...], default:()) –Accuracy evidence (
FramedFactrecords) to assess with this candidate's forecast. -
reference(TargetReference | None, default:None) –Target reference (
TargetReference) to assess with it. No reference value is computed. -
prior_work(tuple[Fact, ...], default:()) –Records (
Fact) of work done earlier for this candidate. Each supplied record is kept, repeated ones included. An empty tuple means that no earlier work is recorded, not that it cost nothing.
Raises:
-
TypeError–If
planis not a Plan, or another argument has the wrong type.
Objective ¶
Bases: Record
A quantity that scan minimizes over its candidates.
Build it with keyword arguments, for example
Objective(kind="requested_shots"), and pass a tuple of objectives to
scan. kind is the only argument required. model_id and scope are
given for predicted_seconds only, and both are then required.
requested_shotssums the shots that the Plan's readouts request.logical_widthis the largest width, in qubits, of one execution at one location. It is not a sum over executions that run at the same time.predicted_secondssums the predictions of one device timing model and scope over the Plan's executions, under a serial schedule declared withResourceContext(batch_schedule="serial"). The sum stays a prediction that holds only under its model.
Attributes:
-
kind(Literal['requested_shots', 'logical_width', 'predicted_seconds']) –Required.
"requested_shots","logical_width"or"predicted_seconds". -
model_id(ContentID | None) –Default
None. Content hash of the timing model whose predictions are summed, required forpredicted_seconds. -
scope(TimeScope | None) –Default
None. Timing scope of those predictions:"selected_acquisition","acquisition_overhead"or"native_call_wall". Required forpredicted_seconds.
Raises:
-
ValueError–If
predicted_secondslacksmodel_idorscope, or another kind has either.
SearchResult ¶
SearchResult(comparison: Comparison, selection: SearchSelection)
The rows that a scan ranked and their Pareto front.
scan returns it. Read the front in
selection.nondominated, then pass select(index) to
solve or
prepare to run one row. Construction checks
that the selection was computed for exactly this Comparison. The fields
below are read-only.
Attributes:
-
comparison(Comparison) –The
Comparisonof every candidate, including rows without a Plan or with unavailable values. -
selection(SearchSelection) –The
SearchSelectionwith every objective value, the Pareto front and the incomparable rows.
select ¶
select(index)
Return the row at index, unchanged, as Comparison.select does.
Any row can be selected, including a dominated row or a row without a
Plan. Running a row without a Plan raises ApplicabilityError.
Parameters:
-
index(int) –Row position, from 0 to the number of rows minus 1.
Returns:
-
row(ComparisonRow) –The row at that position.
Raises:
-
IndexError–If
indexis not an integer in that range.
SearchSelection ¶
Bases: Record
The objective values of every row and the rows on the Pareto front.
scan returns it in SearchResult.selection. Row
i dominates row j when every objective of i is at most that of j and at
least one is smaller. The Pareto front, nondominated, is every row
whose objectives are all available and that no other such row
dominates, so equal rows all stay. A row with any unavailable objective
is listed in incomparable instead of being ranked as zero or infinity.
The front holds only within the rows given. It is not a feasibility
filter or a global optimum. Validation recomputes both lists from the
stored values with exact rational arithmetic and rejects supplied lists
that differ, so a saved selection cannot claim a front that its values
do not support. The fields below are read-only.
Attributes:
-
comparison_id(ContentID) –Content hash of the Comparison that this selection ranks, computed from its Problem and rows.
-
objectives(tuple[Objective, ...]) –The minimized objectives, in the order given.
-
values(tuple[tuple[ObjectiveValue, ...], ...]) –One
ObjectiveValueper row and objective, in row order. -
nondominated(tuple[Count, ...] | None) –Indices of the rows on the Pareto front, recomputed on validation.
-
incomparable(tuple[Count, ...] | None) –Indices of the rows with an unavailable objective, recomputed on validation.
-
prior_work(tuple[tuple[Fact, ...], ...]) –The supplied records of earlier work of each row, each record kept as often as it was supplied.
-
work(SearchWork) –The
SearchWorkof the scan that produced this selection. -
max_pair_comparisons(Count) –Default
1_000_000. Largest number of coordinate comparisons of the front,N*(N-1)*kfor N rows and k objectives, checked before any comparison. -
max_values(Count) –Default
4096. Largest number of row and objective values,N*k, checked before any comparison. -
max_integer_bits(Count) –Default
4096. Largest bit length of an integer in the exact rational arithmetic.
validate_comparison ¶
validate_comparison(comparison)
Check that this selection was computed for exactly the rows of comparison.
Use it after loading a saved selection, for example with
SearchSelection.model_validate_json(...), to check that it belongs
to a Comparison.
Parameters:
-
comparison(Comparison) –The Comparison to check against.
Returns:
-
selection(SearchSelection) –This selection, unchanged.
Raises:
-
ValueError–If the selection belongs to another Comparison or has another number of rows.
ObjectiveValue ¶
Bases: Record
The value of one objective for one candidate, with what it rests on.
scan computes these values, one per candidate and
objective, in SearchSelection.values. A value is exact, conditional
on the assumptions it lists, or unavailable with a reason. A sum of
binary64 time predictions is computed exactly but stays a conditional
prediction. It does not bound the elapsed time or state that the
predictions hold together. The fields below are read-only.
Attributes:
-
objective_id(ContentID) –Content hash of the
Objectivethis value answers. -
value(Rational | None) –Exact nonnegative rational value (
Rational), orNonewhen unavailable. -
unit(Unit) –countfor shots and width,sfor predicted seconds. -
status(Literal['exact', 'conditional', 'unavailable']) –"exact","conditional"or"unavailable". -
sources(tuple[ContentID, ...]) –Content hashes of the stored resource quantities, experiments or predictions that the value is computed from. Nonempty for an available value.
-
assumptions(tuple[Text, ...]) –Conditions taken over from those sources.
-
reason(Text | None) –Why the value is unavailable, or
Nonefor an available value.
SearchWork ¶
Bases: Record
How many resource estimates and device forecasts one scan computed or reused.
scan records it in SearchSelection.work. It
counts estimates and forecast points, not CPU time. The fields below are
read-only.
Attributes:
-
origin(Literal['evaluated_here', 'stored_comparison']) –"evaluated_here"whenscanreceived candidates,"stored_comparison"when it rescored a Comparison. -
requested_points(Count) –Forecast points that the rows need, equal to
assessed_points + reused_points. -
assessed_points(Count) –Forecast points evaluated by this call. Zero when rescoring.
-
reused_points(Count) –Forecast points taken from an identical earlier row or from the stored Comparison.
-
base_folds(Count) –Resource estimates or forecasts computed by this call. Zero when rescoring.
-
reused_folds(Count) –Rows whose estimate or forecast came from an identical earlier row or from the stored Comparison.
Run step by step¶
prepare builds the circuits and returns them with their open Run, submit starts the Run, and Run.wait returns the Result. The Run on a backend guide describes progress, pending jobs, cancellation and limits.
prepare ¶
prepare(plan, *, backend=None, limits=None, progress=None, directory=None, settings='first')
Build the circuits of a Plan for a backend, without submitting them.
prepare creates a new Run for the
Plan and builds its first circuit, or every circuit with settings="all".
Pass the result to submit to run it, or
inspect the circuits first with Prepared.circuits and
Prepared.inspect_resources. When the Plan's experiments are fixed in
advance, rather than chosen from earlier outcomes, every circuit, shot and
preparation of the whole Plan is checked against the Run's limits before
anything is built. The returned Prepared holds the open Run, which the
caller closes, for example with with prepared.run as run:. If
preparation fails, the Run is closed and the error names its saved
folder, if any.
Parameters:
-
plan(Plan | ComparisonRow) –A Plan, or a row from
compareorscan. A row's device forecast and Allocation stay with the Run and its Result. -
backend(object | None, default:None) –Backend to run on. Omitted, local Aer runs quantum execution and the host runs classical execution.
-
limits(ExecutionLimits | None, default:None) –Limits on the Run's total preparations, circuits, shots and stored data. Omitted, the defaults of
ExecutionLimitsapply. -
progress(object | None, default:None) –Progress callback, called as
callback(stage, done, total).Falsedisables progress reports, andNonepermits the default notebook display. -
directory(str | PathLike | None, default:None) –New folder in which the Run saves its state as it runs, so that
load_runcan reopen it. -
settings(str, default:'first') –"first"(the default) prepares the setting that the Method submits first, which is the first experiment when the experiments are fixed, andsubmitprepares each later one when it reaches it."all"prepares every setting of fixed experiments now, in Plan order, so thatPrepared.circuits,Prepared.setting_names, inspection and compilation by index cover the whole Plan. Each setting is prepared and counted once, a Run with a folder saves it, andsubmituses these preparations. The limit check above already covers them, so"all"adds nothing to the limits and prepares nothing that a completed submit would not."all"needs local Aer, local NWQ-Sim or classical host execution. Another backend is refused before a Run exists, because its preparation can be a remote compilation that the provider charges for. This restriction lasts until the cost disclosure and the handling of pending remote preparations are decided (Preparing every setting on remote backends). A Method whose later settings depend on earlier outcomes (RWPE, Lanczos withSensitivitySampling, ADAPT) refuses"all"before a Run exists, and its message says what it can prepare instead.
Returns:
-
prepared(Prepared) –The prepared circuits and their open Run (
prepared.run). Nothing has been submitted.
Raises:
-
TypeError–If
planis neither a Plan nor a row of a comparison. -
ValueError–If
settingsis neither"first"nor"all", or if"all"is requested on another backend or for a Method that refuses it. -
ApplicabilityError–If
planis a row without a Plan, or the Plan lists unmet requirements.
Examples:
See submit.
Prepared ¶
Prepared(run: Run)
The prepared circuits of a Plan and their open Run, before submission.
prepare returns it. Inspect the circuits
with circuits, circuit(index), setting_names and
inspect_resources, then pass it to submit.
The Run holds the preparations, the limits, the measured data and
everything that follows. Close it when done, for example with
with prepared.run as run:. The field below is read-only.
Attributes:
circuits ¶
circuits
Copies of every prepared Qiskit circuit, in index order.
The index of a circuit is the one that circuit, setting_names and
inspect_resources use. Each access copies every circuit, and
circuit(index) copies one. Host computations have no circuit and
are skipped.
setting_names ¶
setting_names
The Plan experiment of each prepared circuit, in the index order of circuits.
Entry i is the name (Experiment.name in plan.experiments) of the
experiment that circuit i implements. After
prepare(plan, settings="all") the names of fixed experiments are
those of the Plan's circuit experiments, in Plan order. The default
settings="first" prepares only the setting that the Method submits
first, and an adaptive Method can prepare one experiment several
times with different parameter values.
circuit ¶
circuit(index=0)
Return a copy of one prepared Qiskit circuit.
Parameters:
-
index(int, default:0) –Default
0. Position of the circuit incircuitsandsetting_names.
Returns:
-
circuit(QuantumCircuit) –The copy.
Raises:
-
ValueError–If no circuit has this index. After the default
prepare(plan, settings="first")only the first setting is prepared, andsettings="all"prepares every setting of fixed experiments.
inspect_resources ¶
inspect_resources(*, index=0, transpile_options=None, max_operations=100000, max_bytes=DEFAULT_MAX_BYTES)
Count the operations of one prepared circuit, without copying or running it.
Each top-level instruction of the circuit counts once under its
operation name, measurements, barriers, simulator saves, Clifford
objects and user-defined gates included, and names are reported as
they are. Gate definitions and control-flow bodies are not expanded. With transpile_options, a transpiled copy is
counted instead, with the simulator saves removed first. The circuit
that executes is never changed or run.
Parameters:
-
index(int, default:0) –Default
0. Position of the circuit incircuits. -
transpile_options(dict | None, default:None) –Options for Qiskit's
transpile.None, the default, counts the prepared circuit as it is. -
max_operations(int, default:100000) –Default
100_000. Largest number of operations of the circuit, and of its transpiled copy. -
max_bytes(int, default:DEFAULT_MAX_BYTES) –Default 10 GB (decimal,
10_000_000_000). Largest size of the known inspection data and options. It does not bound the compiler's own memory.
Returns:
-
inventory(dict) –circuit,basis,compiler(Qiskit version and options, orNone),operations(count by name),total_operations,num_qubits,num_clbitsanddepth(Qiskit's default depth, which skips directives such as barriers and simulator saves).
Raises:
-
ValueError–If no circuit has this index or a limit is exceeded.
submit ¶
submit(prepared)
Start running prepared circuits and return their Run.
The first call starts the Run of prepared and returns it when the run
is complete or the Method has to wait for results from the backend.
run.result holds the Result once the run is complete, and
Run.wait waits for it. The Run
stays the caller's through prepared.run, also when submit raises, so
enter with prepared.run as run: before submitting to close it. A
second call on the same prepared starts a new Run with the same
backend, the current limits and the Plan's original random state,
because the work counted against a started Run cannot be reset. The new
Run draws the same seeds, so its new run_id does not establish that
its samples are independent of the first Run's.
Parameters:
-
prepared(Prepared) –The return value of
prepare.
Returns:
-
run(Run) –The started Run.
Raises:
-
TypeError–If
preparedis not the return value ofprepare. -
RunFailed–If the run fails or an attempt's outcome cannot be recovered.
Examples:
The state |0> gives <Z> = 1 in every shot:
>>> from nwqlib import Expectation, plan, prepare, submit
>>> from nwqlib.algorithms import ExpectationMethod
>>> problem = Expectation(state=[1.0, 0.0],
... observable=[[1.0, 0.0], [0.0, -1.0]])
>>> selected = plan(problem, method=ExpectationMethod(), shots=64,
... seed=7)
>>> prepared = prepare(selected)
>>> print(prepared.setting_names)
('group_0',)
>>> with prepared.run:
... result = submit(prepared).wait()
>>> print(result.value)
1.0
Run ¶
Run(plan, *, backend=None, limits=None, directory=None, progress=None, forecast=None, allocation=None)
One execution of a Plan: its circuits, attempts, measured data, limits and counted work.
prepare creates a Run (prepared.run),
submit starts it, and
load_run reopens a saved one. wait()
returns the Result, and resume() continues the Run once without
waiting. Close a Run when done, for example with
with prepared.run as run:. Closing cancels no job.
The Run is the only object that sets work aside, submits it, saves its
outcomes and counts it against the limits. The limits apply to totals
over the Run's whole life, failed and uncertain attempts included, so
raising the limits or reopening the Run never gives back work already
counted. A Run with a folder records every step in run.sqlite there
and holds an exclusive lock on the folder until it is closed. A Run
without a folder keeps the same counts in memory and can be saved later
with save. Run on a backend and Continue
an interrupted run describe both. The fields below
are read-only.
Attributes:
-
plan(Plan) –The Plan being executed. Continuing the Run never replaces it.
-
backend(object) –The backend, or
Nonefor a Run of host computations only. -
forecast(object) –The
PlanEstimategiven with the Plan, orNone. -
allocation(object) –The
Allocationgiven with the Plan, orNone. Continuing the Run does not recompute it. -
run_id(str) –Identifier of this execution, distinct from another Run of the same Plan.
directory ¶
directory
The Run's folder, as a pathlib.Path, or None for a Run without one.
A backend that runs jobs outside this process always gets a folder,
under ~/.nwqlib/runs/<run_id> when prepare was given no
directory, so that a submitted job can be reopened after the
process ends.
limit_amendments ¶
limit_amendments
Every raise of the Run's limits so far, in order.
Each is a LimitAmendment with
the old and new limits and the Run's counts just before the raise.
trace ¶
trace
The Run's attempts and counted work as they stand, as an ExecutionTrace.
It includes failed, uncertain and unused work, so a Result built from it accounts for all the work of the Run rather than only the measurements it uses. The same snapshot is returned until an attempt, submission, count or limit changes.
data ¶
data
The Run's measured data as it stands, as a RunData.
It holds the collected observations, preparation records, trace and
saved arrays, shared rather than copied. Its method_context is set
only when the Method keeps analysis data with the Result. Repeated
reads reuse the snapshots of observations and trace.
observations ¶
observations
The observations that the Method has collected so far, in the order it collected them.
An ObservationView whose chunks hold the statistics of each
measurement. A completed measurement that the Method has not yet
collected is absent. The same object is returned until the next
collection.
exposure ¶
exposure
The work submitted so far, by outcome: completed, reserved, uncertain and failed.
A dictionary with the keys "completed", "reserved", "uncertain"
and "failed", each mapping jobs, circuits, shots and
provider_managed_sampling to a count. Jobs are counted per
submission. Submissions not yet acknowledged by the backend, or
acknowledged and not finished, are reserved. Failed, cancelled and
uncertain submissions are all counted as uncertain jobs, because a
provider's final status does not state how much work it consumed.
Circuits, shots and provider-managed sampling are counted per attempt,
by the attempt's status. Only host computations can fail, so the
failed category never contains circuits or shots.
warnings ¶
warnings
Notices recorded in this process, such as a disabled progress callback or a backend's notice.
Reading them repeats no work. They are not saved with the Run.
artifacts ¶
artifacts
The store of the arrays this Run has saved, created on first use.
Read one array with hydrate(manifest), or take the handles from
run.data.artifacts.
wait ¶
wait(*, timeout=None, poll_interval=1.0)
Continue the Run until it has a Result, and return the Result.
Each pass calls resume, which reads every pending provider job once,
and then sleeps poll_interval seconds. A Method may return a valid
partial Result from the data it has before a failed job is reported,
and the Run never invents scientific output. A retrieval error
propagates and keeps the job's locator, so a later resume or wait
can read the same job, and an uncertain submission is never
resubmitted.
Parameters:
-
timeout(float | None, default:None) –Seconds to wait before raising
TimeoutError.None, the default, waits without a limit. -
poll_interval(float, default:1.0) –Default
1.0. Seconds between passes. A longer interval sends fewer status requests to a provider. The default is a polling interval chosen without tuning (Engineering constants).
Returns:
-
result(Result) –The Run's Result.
Raises:
-
RunFailed–If a preparation, host computation or submission ended in failure or cancellation, or an uncertain attempt cannot be recovered.
-
TimeoutError–If the Run is still pending after
timeout. The same Run can be continued later. -
RuntimeError–If the Run was cancelled before it completed. Its pending work is saved in its folder.
Examples:
See submit.
resume ¶
resume(*, reanalyze=False)
Continue the Run once: retrieve pending results, let the Method go on, and return.
resume reads each pending submission once, then lets the Method
continue from where the Run stands, without waiting. When the Method
finishes, run.result holds the Result. Otherwise run.result is
still None, and a later resume or wait continues. A complete
Run returns at once. Work done before an error, such as a computed
circuit or numerical intermediate, is kept for the next resume. A
Result always accounts for every attempt of the Run, failed and
uncertain ones included.
Parameters:
-
reanalyze(bool, default:False) –Default
False.Trueretries an interrupted analysis of a Method that supports it, from its saved data, before continuing. A completed Run is analyzed again withresult.analyze(...)instead.
Returns:
-
run(Run) –This Run.
Raises:
-
RunFailed–If no Result is available and an uncertain attempt cannot be retrieved by any route (stage
"recovery"). -
ValueError–If
reanalyze=Trueis given for a Run that already has its Result.
Examples:
A local Aer run completes in its first pass:
>>> from nwqlib import Expectation, plan, prepare, submit
>>> from nwqlib.algorithms import ExpectationMethod
>>> problem = Expectation(state=[1.0, 0.0],
... observable=[[1.0, 0.0], [0.0, -1.0]])
>>> selected = plan(problem, method=ExpectationMethod(), shots=64,
... seed=7)
>>> prepared = prepare(selected)
>>> with prepared.run as run:
... started = submit(prepared)
... print(started is run, run.resume().result.value)
True 1.0
cancel ¶
cancel(reason='user requested cancellation')
Stop new work in this Run, then ask the backend to cancel its pending jobs.
The request is saved first, so a Run reopened after a crash while contacting the provider still refuses new preparations and measurements. Pending remote preparations and submissions are then refreshed, which sends each job at most one cancellation request. A request does not prove that a job was cancelled, and only a status returned by the provider does. All counted work stays counted. A backend without a cancellation operation, such as local NWQ-Sim, receives no request.
Parameters:
-
reason(str, default:'user requested cancellation') –Reason recorded with the request. Default
"user requested cancellation".
Returns:
-
run(Run) –This Run.
close ¶
close()
Close the Run's folder, release its lock and free its working caches. Closing twice is harmless.
Closing cancels no job. The saved files, the Result, the preparation
records, the arrays and every count stay, so a later load_run or
inspection sees the same work. with prepared.run as run: closes the
Run at the end of the block.
save ¶
save(path)
Copy the Run's current state to a new folder. The open Run continues unchanged.
Call it while the Run is open, after a Run call has returned. The copy
holds the Plan, the limits and counts, the random state, the
preparations, the attempts and the locators of pending jobs, the
observations, the arrays and any Result. A Run without a folder gets
one this way. load_run reopens the copy. The copy and the original
name the same provider jobs, so continue only one of them. The copied
files count against max_data_bytes, and a failed copy leaves no new
folder.
Parameters:
-
path(str | PathLike) –New folder to create.
Returns:
-
path(Path) –The created folder.
Raises:
-
ValueError–If the Run is in the middle of a step, for example while an outcome is being saved.
extend_limits ¶
extend_limits(**changes)
Raise one or more limits of this Run, keeping everything it has counted.
run.extend_limits(max_total_shots=128) sets the Run's total shot
limit to 128. It does not add 128 shots, reset any count or change a
scientific setting, so raising a limit gives back no work already
counted. Limits can only be kept or raised. A call that raises a limit
records a LimitAmendment in
limit_amendments. The new limits and that record are saved
together, so a process that stops before the save reopens with the
old limits, and one that stops after it reopens with the new limits
and their record. A call that raises nothing records nothing.
Parameters:
-
**changes(int, default:{}) –New values of
ExecutionLimitsfields, by name, as integers at least the current values.
Returns:
-
run(Run) –This Run.
Raises:
-
ValueError–If no limit is named, a name is not a limit, or a value is not an integer at least the current one.
hydrate ¶
hydrate(manifest)
Return the handle of one saved array, reading its bytes from the Run's folder once.
Nothing is measured or recomputed. The array is read on first use and kept for the life of the Run. A probability observation and an array handle of this Run read through the same store.
Parameters:
-
manifest(ArtifactManifest) –The array's manifest.
Returns:
-
handle(ArtifactHandle) –The array's handle.
Raises:
-
ValueError–If the Run has no saved bytes for the array.
release_native ¶
release_native()
Release the in-memory circuits of preparations that are fully collected, idle and saved as QPY.
For a long Run with a folder, this frees the Qiskit circuits that are no longer needed. The preparation records and the order of the prepared circuits stay. Inspecting a released circuit reads its saved QPY once, and nothing is built, transpiled or submitted again. Circuits of other backends, unsaved circuits and circuits still in use are kept. Aer is the backend whose circuits are released. The counts describe released circuits, not measured memory.
Returns:
-
released(dict) –released, the content hashes of the released preparations, andkept, pairs of a content hash and the reason it was kept.
ExecutionLimits ¶
Bases: Record
Limits on what one Run may prepare, execute and store.
Build it with keyword arguments and pass it as limits= to
solve or prepare, for example
ExecutionLimits(max_total_shots=10_000_000). Every argument is
optional, and every limit is inclusive. The max_total_* limits,
max_data_bytes and max_synthesis_work count totals over the whole
Run. Planning does not use these limits. A Method checks its own
planning limits, such as Lanczos.max_bytes. Raise a limit of an
existing Run with Run.extend_limits.
Attributes:
-
max_simulation_qubits(PositiveInt) –Default
20. Largest circuit width that a local simulator (Aer or the local NWQ-Sim backend) accepts. A 20-qubit complex128 statevector needs 16 MiB. -
simulator_memory_mb(PositiveInt) –Default
1024(MiB). Memory allowance of the local simulator for the quantum state and its known working arrays. Aer receives it asmax_memory_mb. -
max_total_circuits(PositiveInt) –Default
512. Largest number of circuit preparations, and separately of circuit execution attempts. -
max_total_shots(PositiveInt) –Default
1_000_000. Largest total of shots reserved for circuit executions, including attempts whose outcome is uncertain. -
max_data_bytes(PositiveInt) –Default 10 GB (decimal,
10_000_000_000bytes). Largest size of the Run's recorded data and numerical arrays. It does not bound the memory of the Python process. -
max_completion_metadata_bytes(PositiveInt) –Default
65_536. JSON metadata allowed for each completed circuit execution or host computation, in addition to the numeric values, arrays and host-computation records that it declares. -
max_direct_amplitudes(PositiveInt) –Default
65_536(2**16, a 16-qubit state). Largest amplitude count of a direct magnitude and phase state preparation that the Run synthesizes. -
max_synthesis_work(PositiveInt) –Default
1e9work units. Largest total work of the exact syntheses of dense unitaries that the Run makes while it prepares circuits. It counts the syntheses of a backend that translates a circuit to its gate basis, and the syntheses and Qiskit's control of them when building the Qiskit circuit adds controls to a transformed block. The default allows the synthesis of one dense unitary on 8 qubits (5.2e8 units) and refuses one on 9 qubits (4.0e9 units). The work of a preparation's syntheses is checked against the remaining allowance before the first of them starts. Each distinct matrix is synthesized and counted once while the Run is open, and again after the Run is reopened. A refused preparation still counts againstmax_total_circuitsand leaves its experiment unprepared, so a later call can prepare it after the limit is raised. Syntheses that a Method counts against its own limits at planning are not counted here. The work unit and the synthesis cache are defined in Explicit workflow and reference controls.
LimitAmendment ¶
Bases: Record
One raise of a Run's limits, with the Run's counts just before it.
Run.extend_limits records one in run.limit_amendments for each call
that raises a limit. Each raises at least one limit and lowers none, and
the counts it records lie within the old limits. The fields below are
read-only.
Attributes:
-
sequence(PositiveInt) –Position in the Run's history of raises, from 1.
-
recorded_at(AwareDatetime) –Time-zone-aware wall-clock time of the raise. It is a timestamp, not a measure of elapsed time.
-
old(ExecutionLimits) –The complete
ExecutionLimitsbefore the raise. -
new(ExecutionLimits) –The complete
ExecutionLimitsafter the raise. -
circuit_preparations(Count) –Circuit preparations so far, failed and unused ones included.
-
circuit_attempts(Count) –Circuit execution attempts so far, reserved and uncertain ones included.
-
raw_shots(Count) –Shots requested explicitly so far. Unknown sampling inside an estimate that a provider manages is not included.
-
stored_data_bytes(Count) –Bytes of the Run's stored data, without
pending_output_bytes. Both byte counts describe the data the Run accounts for, never physical memory. -
pending_output_bytes(Count) –Bytes set aside for outputs not yet received.
-
synthesis_work(Count) –Work of the exact syntheses of dense unitaries counted against
max_synthesis_workso far.
ExecutionTrace ¶
Bases: Record
The attempts of a Run and the work counted against its limits.
run.trace and result.data.trace return it. It includes failed and
uncertain attempts and unused preparations, so a Result built from it
accounts for all the work of the Run, not only the measurements it uses.
local_prepared_ids names the successful preparations made in this Run.
A saved preparation that this Run uses may instead come from another
Run that is allowed to use it, and using it counts as execution work,
not as a new local preparation. limits and limit_amendments are the
limits and their history when the trace was taken, so raising the
Run's limits later does not change an earlier Result. The fields below
are read-only.
Attributes:
-
run_id(Text) –Identifier of the Run.
-
plan_id(ContentID) –Content hash of the Run's Plan.
-
preparations(Count) –Number of preparation attempts in this Run, failed and interrupted ones included. It includes the host setups counted in
host_preparations. -
construction_work_reserved(Count) –Circuit construction work counted in this Run, in work units.
-
events(tuple[ConsumptionEvent, ...]) –Every attempt (
ConsumptionEventrecords), in order, failed and uncertain ones included. -
submissions(tuple[SubmissionRecord, ...]) –The circuit submissions (
SubmissionRecordrecords), with the attempts of each. -
host_preparations(Count) –Number of host setup attempts.
-
host_preparation_work_reserved(Count) –Work of host setups counted in this Run.
-
host_invocations(Count) –Number of host computations started, interrupted ones included.
-
host_work_reserved(Count) –Work of host computations, counted before each starts.
-
data_bytes_reserved(Count) –Bytes set aside for outputs, summed over the attempts.
-
data_bytes(Count) –Bytes of the Run's stored data when the trace was taken.
-
synthesis_work_reserved(Count) –Work of the exact syntheses of dense unitaries counted against
max_synthesis_workin this Run. -
local_prepared_ids(tuple[ContentID, ...]) –Content hashes of the successful preparations made in this Run.
-
cancel_requested(Text | None) –The reason given to
Run.cancel, orNone. A request does not prove that the provider cancelled the job. -
termination_reason(Text | None) –Why the Method ended the run early, or
None. -
limits(ExecutionLimits | None) –The
ExecutionLimitswhen the trace was taken, orNonefor a trace recorded without them. -
limit_amendments(tuple[LimitAmendment, ...]) –Every raise of the limits so far (
LimitAmendmentrecords), in order.
jobs ¶
jobs: int
Number of circuit submissions, including those whose acknowledgement from the backend has not arrived.
RunFailed ¶
RunFailed(*, stage, status, locator, failure, directory, trace, exposure, attempt=None)
Bases: RuntimeError
Raised when a run fails, or when the outcome of an attempt cannot be recovered.
submit, Run.resume and Run.wait raise it. stage and status
describe the outcome. A recovery error (stage="recovery") reports an
attempt whose outcome is unavailable, with status "uncertain", even
when its submission has ended because its output cannot be retrieved.
Status "uncertain" does not claim that the execution failed. locator
and directory locate the original job and the saved Run, and failure
is the recorded failure text, not an invented local exception. trace
and exposure capture the attempts and counted work without another
backend call, and attempt names the original attempt of a recovery
error, whose record and counted work are in those snapshots. The message
names each of these. For a recovery error, it also tells you to inspect
the saved data or cancel the Run, and to start a new Run to execute the
Plan again, because nothing is resubmitted in this Run and the attempt
stays uncertain and counted.
Attributes:
-
stage–"prepare","execute"or"recovery". -
status–The observed outcome, such as
"failed","cancelled"or"uncertain". -
locator–The original provider job or remote-preparation locator, or
Nonewhen none was acknowledged. -
failure–The recorded failure text, or
None. -
directory–The Run's folder, or
Nonefor a Run without one. -
trace–The
ExecutionTraceat the time of the error. -
exposure–Read-only copy of
Run.exposureat the time of the error, the counted work by outcome. -
attempt–The attempt's identifier for a recovery error, otherwise
None.
submit and Run.resume call the two functions below for a backend that runs jobs outside this process. The backend guides name them where a direct call helps.
submit_detached ¶
submit_detached(prepared, *, run, checkpoint_sequences=None)
Submit prepared circuits as one job to a backend that runs jobs outside this process, without waiting.
submit and Run.resume call it for such a
backend, so most code never does. The IonQ guide calls it
directly to submit several circuits with equal shots as one job. The
backend checks the whole batch, the submission is saved in the Run's
folder, the backend then starts the job, and the job's locator is saved
when the backend returns it. If the process ends between the start and
the saved locator, the reopened Run has an uncertain submission without
a locator, and only the backend's own lookup by the original submission
can find the job. An error while starting the job marks the submission
and its attempts uncertain, with their work still counted, because the
provider may have accepted the request before the error reached this
process. The job is never resubmitted or replaced. Read its results with
run.resume(), run.wait() or refresh_submissions.
Parameters:
-
prepared(tuple[PreparedHandle, ...]) –The prepared circuits of this Run and backend, at least one.
-
run(Run) –The Run that holds them. It needs a folder.
-
checkpoint_sequences(tuple | None, default:None) –For an adaptive Method, the iteration checkpoint of each circuit, in order, or
None.
Returns:
-
submission(SubmissionRecord) –The saved submission with its job locator.
Raises:
-
TypeError–If
preparedis not a nonempty tuple of prepared circuits. -
ValueError–If the Run has no folder, the backend cannot start jobs, a circuit belongs to another backend, or
checkpoint_sequencesdoes not matchprepared.
refresh_submissions ¶
refresh_submissions(*, run: Run)
Read each pending job of a Run once and save the new results, without submitting anything.
Run.resume and Run.wait call it, so most code never does. Each new
result is saved with its attempt in one step and can be collected once.
A job read twice still saves each result once, because results that are
already saved are skipped. A submission whose locator was lost is read
only through the backend's own lookup by the original submission. Items
of a job keep their original positions and result keys, and a provider
may add a child job or result identifier to an item but cannot replace
one. When a provider reports failure, cancellation or
an uncertain state, the remaining attempts become uncertain and stay
counted. If reading a job fails, the failure is recorded on its
submission and the original exception propagates, with the job's
locator, counted work and earlier results kept, so a later call can read
the same job again.
Parameters:
-
run(Run) –The Run whose pending jobs are read.
Returns:
-
observations(tuple[ObservationChunk, ...]) –The newly saved observations.
Save and reopen¶
result.save(path) writes a Result with its Plan and data, and load_result reopens it. A Run with a folder saves its state as it runs, run.save(path) copies it, and load_run reopens either to continue the same work. The Continue an interrupted run guide compares the two.
load_result ¶
load_result(path, *, method=None)
Reopen a Result saved with Result.save, with its Plan and run data.
The loaded Result has the same fields as the saved one, and
Result.analyze can recompute it from the saved data with other
settings, without new measurements. Loading plans nothing, runs nothing
and computes no reference. It checks the saved records, the content hash
of the Plan and the header of every saved array, and it reads the array
values only when they are used, as read-only memory maps, so keep the
folder available while using the Result. The Save, load and reanalyze
results guide describes the saved folder.
Parameters:
-
path(str | PathLike) –Folder written by
Result.save. -
method(type | Method | None, default:None) –The Method class, or an instance of it, for a Method that is not built into NWQLib. Built-in Methods are found from the saved record.
Returns:
-
result(Result) –The saved Result, of the Method's own Result type, with its Plan and run data attached.
Raises:
-
ValueError–If the saved records fail their checks, or a Method outside NWQLib is saved and
methodis not given or differs from it.
Examples:
>>> import os, tempfile
>>> from nwqlib import Expectation, load_result, solve
>>> from nwqlib.algorithms import ExpectationMethod
>>> problem = Expectation(state=[1.0, 0.0],
... observable=[[1.0, 0.0], [0.0, -1.0]])
>>> result = solve(problem, method=ExpectationMethod(), seed=7)
>>> path = result.save(os.path.join(tempfile.mkdtemp(), "result"))
>>> print(load_result(path).value)
1.0
load_run ¶
load_run(path, *, backend, method=None, progress=None)
Reopen a saved Run to inspect it or continue it.
load_run opens the folder of a Run, either the directory given to
prepare or a copy written by Run.save, and returns the open Run with
its Plan, limits, counted work, random state and the locators of its
pending jobs. Loading plans nothing, contacts no backend and runs
nothing. run.resume() or run.wait() then continues the same work, and
a completed Run returns its saved Result. The Run takes an exclusive lock
on the folder until it is closed. The Continue an interrupted
run guide describes saving and reopening.
Parameters:
-
path(str | PathLike) –A Run folder. A folder written by
Result.saveis not a Run folder. Keep it available and writable while the Run is open, because the Run records its progress there. -
backend(object) –Backend with the configuration that the Run was saved with. Reopening never submits a replacement for an attempt whose outcome is unknown.
-
method(type | Method | None, default:None) –The Method class, or an instance of it, for a Method that is not built into NWQLib. Built-in Methods are found from the saved record.
-
progress(object | None, default:None) –Progress callback of the reopened Run,
Falseto disable it, orNonefor the notebook display, as forprepare.
Returns:
-
run(Run) –The open Run. Close it when done, for example with
with load_run(path, backend=backend) as run:.
Raises:
-
TypeError–If
progressis notNone,Falseor a callable. -
ValueError–If the saved records fail their checks, or a Method outside NWQLib is saved and
methodis not given or differs from it. -
BlockingIOError–If another open Run holds the folder. Close that Run, for example
prepared.run, first.
Examples:
>>> import os, tempfile
>>> from nwqlib import Expectation, load_run, plan, prepare, submit
>>> 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]])
>>> selected = plan(problem, method=ExpectationMethod(), shots=64,
... seed=7)
>>> folder = os.path.join(tempfile.mkdtemp(), "run")
>>> prepared = prepare(selected, directory=folder)
>>> with prepared.run:
... result = submit(prepared).wait()
>>> with load_run(folder, backend=AerBackend()) as run:
... print(run.wait().value)
1.0
A Method family that runs a sequence of Plans documents it with the family. QHD's augmented-Lagrangian layer and box refinement run one ordinary QHD Plan per round or level, each planned with its own random streams, as compare plans each Method, and run with prepare and submit. With directory=... these Runs are saved as they run, and resume_augmented_lagrangian and resume_box_refinement continue an interrupted run, reopening an unfinished Run with load_run and the progress of the resume call (QHD constrained problems and box refinement).
Entries on other pages¶
The Method base class and its hooks, PreparedHandle, and the Plan, Result and Problem hooks are documented on Extending NWQLib:
PreparedHandlePreparedHandle.inspect_circuitPreparedHandle.inspect_resourcesMethodMethod.analyzeMethod.error_modelMethod.executeMethod.planMethod.prepareMethod.prepare_all_refusalMethod.recover_analysisMethod.verifyPlan.resolveResult.validate_planProblemRecord.default_output
PhysicalScale is documented on Inputs and input types: