Skip to content

Extending NWQLib

This page lists the classes and functions for adding a method: the Method base class and its hooks, the checker and registry for a new method, the Program (NWQLib's description of a circuit as named steps), the blocks a Program calls, the readouts it requests and the hooks that save its data. Add a Method states every requirement of a Method, and Run your own circuit builds the smallest Method step by step.

from nwqlib.algorithms import AlgorithmDescriptor, ApplicabilityError, Method
from nwqlib.algorithms.authoring import MethodCase, check_method
from nwqlib.blocks import SelectedConstruction, lower_qiskit, select_preparation
from nwqlib.ir import (
    Allocate, BlockCall, Definition, Measure, Program, Register, Sequence,
)

A new Method ships a case() function that returns a MethodCase, and check_method runs it. With the reference Hadamard Method of tests/_hadamard_method.py on the import path:

from nwqlib.algorithms.authoring import check_method
from _hadamard_method import case

report = check_method(case())
print(report["status"], report["method"])
# CONFORMANT example.hadamard_pauli_expectation

From a shell, python -m nwqlib check-method my_methods:case runs the same check on the case() of your module my_methods.

Task Entries
Write the Method class Method, AlgorithmDescriptor, ApplicabilityError
Tie a Plan and a Result to their inputs and data Plan._bind, Result._attach, Result.validate_plan
Inspect a prepared circuit and its resources PreparedHandle
Check a Method against its case MethodCase, check_method
Register a Method and resolve it by name Registration, AlgorithmRegistry, direct_method
Describe the circuit as a Program Program, registers and block signatures, nodes
Give a Program named parameters and expressions Parameter, Expression
Make the blocks a Program calls and build the Qiskit circuit select_preparation, transform_block, SelectedConstruction, lower_qiskit
Request readouts and read the observations Experiment, ObservationSpec, ObservationChunk, Histogram
Save and reload a Method's data ArchiveFiles, write_blocks, read_blocks

Implement a method

Subclass Method, give it a descriptor, and implement plan and analyze. The other hooks have defaults. Plan and Result have four protected hooks that a Method's code calls or overrides: Plan._bind, Result._attach, Result._validate_common_plan and Result._summary_lines. They keep each input and its data tied to the Plan and run no extra computation, and Supported protected extension hooks states what each must do. A Method's Result type overrides validate_plan, and a new Problem type defines default_output.

Method

Bases: Record

Base class of every method: an immutable configuration that plans, runs and analyzes one kind of problem.

Subclass it to add a method. Declare the class attribute descriptor: ClassVar[AlgorithmDescriptor] and the method's configuration fields, and implement plan and analyze. Users pass an instance as method= to solve, plan or compare. A Method is kept separate from the Problem it solves, so one problem can be approached with different initial states, trial spaces, degrees or estimators and compared on equal terms. A Method is an immutable Record, so its content hash enters every Plan it makes, and changing a field gives a different Plan. Running, preparation, submission, saving and reports call the hooks below and never branch on the method's family, so a new Method needs no change elsewhere in NWQLib. Add a Method states every requirement, including the protected hooks of Plan and Result below, and Run your own circuit shows the smallest Method.

Hooks a Method implements or may override:

  • plan: choose and bind the Plan. Required.
  • analyze: turn existing run data into the Result. Required.
  • prepare and execute: defaults for a fixed set of circuits. A Method that chooses later circuits from earlier results overrides them.
  • prepare_all_refusal: why settings="all" cannot be served, asked before a Run exists.
  • error_model: the known and unavailable error sources of a Plan.
  • verify and recover_analysis: explicit extra operations, unavailable by default.
  • reduction_allowance, for a Plan that reduces data while it is collected: check the reduction's workspace and return the Method's remaining work allowance.
  • before_submit: check data collection before its submission is recorded.
  • validate_point, specialize_experiment and selected_kernels: check and derive one resolved point without planning again.

Attributes:

plan

plan(problem, *, output, execution, shots, rng, accuracy=None)

Choose the circuits and readout for a problem and return the bound Plan.

nwqlib.plan calls it. The Plan must keep the original problem, this Method, the output, the execution mode, the requested accuracy and the state of each named random stream after the planning draws. nwqlib.plan rejects a Plan that replaced the problem, Method or output object, or whose random state or accuracy differs. accuracy is a requested criterion, and the Plan must not record it as an achieved error bound. Raise ApplicabilityError when this Method cannot solve the problem or output.

Parameters:

  • problem (Record) –

    The problem.

  • output (Record) –

    The requested output.

  • execution (str) –

    The requested execution, such as "quantum" or "classical".

  • shots (int | None) –

    Requested shots, or None for exact readout or the Method's default.

  • rng (RandomStreams) –

    The Plan's named random streams. Draw from them, so that one seed reproduces the same choice.

  • accuracy (Accuracy | None, default: None ) –

    Requested accuracy criterion. It is passed only when the caller gives one.

Returns:

  • plan ( Plan ) –

    The bound Plan.

analyze

analyze(plan, data, *, settings)

Turn the collected data of a Plan into its Result, with explicit settings and without collecting new data.

Result.analyze and the end of a Run call it. Return an instance of the Method's Result class attached to this Plan and the exact data used. Result._attach runs the supported Plan and data checks.

Parameters:

  • plan (Plan) –

    The Plan.

  • data (RunData) –

    The collected data.

  • settings (dict) –

    Analysis settings.

Returns:

  • result ( Result ) –

    The Result attached to plan and data.

prepare

prepare(plan, *, run, settings='first')

Prepare circuits of the Plan in the Run without submitting them.

The default prepares the first setting, or every setting for settings="all". A Method that chooses its next circuit from earlier results overrides it to prepare that circuit. The hook receives "all" only after prepare_all_refusal returned None.

Parameters:

  • plan (Plan) –

    The Plan.

  • run (Run) –

    The Run that holds the prepared circuits.

  • settings (str, default: 'first' ) –

    "first" or "all".

prepare_all_refusal

prepare_all_refusal()

Return why prepare(plan, settings="all") cannot serve this Method, or None when it can.

nwqlib.prepare asks before it creates a Run, so a refusal leaves no Run folder. A Method whose later settings depend on earlier outcomes overrides it to return its reason and what can be prepared instead. Otherwise the inherited preparation would prepare, and count against the Run's limits, every setting of the Plan, including ones the Method never submits. The default returns None when prepare accepts the settings keyword, and otherwise a refusal, because a prepare override without that keyword never receives "all".

Returns:

  • reason ( str | None ) –

    The reason, or None.

execute

execute(plan, *, run)

Advance the Run's work and return the Result when it is complete, or None while it is pending.

The default runs the Plan's experiments in order, one attempt each, never submits an existing attempt again, and analyzes once every experiment has its data. A Method that chooses later circuits from earlier results overrides it.

Parameters:

  • plan (Plan) –

    The Plan.

  • run (Run) –

    The Run.

Returns:

  • result ( Result | None ) –

    The Result, or None while work is pending.

error_model

error_model(plan)

Return the known and unavailable error sources of a Plan, each with the quantity and unit it refers to.

The default returns the error model stored in the Plan (plan.error_model).

Parameters:

  • plan (Plan) –

    The Plan.

Returns:

  • model ( ErrorModel | None ) –

    The error model, or None.

verify

verify(plan, result, *, checks)

Run checks the caller selected explicitly on a Result, at their own cost.

Result.verify(checks=...) calls it. Override it only for checks the Method supports. The default refuses.

Parameters:

  • plan (Plan) –

    The Plan.

  • result (Result) –

    The Result to check.

  • checks (object) –

    The selected checks, as Result.verify received them.

Raises:

  • ValueError –

    Always, in the default.

recover_analysis

recover_analysis(plan, *, run)

Finish an analysis that a saved Run interrupted, without submitting earlier work again.

Only a Method that saves an interrupted analysis overrides it. The default raises.

Parameters:

  • plan (Plan) –

    The Plan.

  • run (Run) –

    The reopened Run.

Raises:

  • ValueError –

    Always, in the default.

AlgorithmDescriptor

Bases: Record

What a Method declares about itself: name, version, the problems and outputs it handles, its coverage, limitations and references.

Build it with keyword arguments, for example AlgorithmDescriptor(method="hadamard_expectation", version="1", problem_families=("expectation",)), and set it as the class attribute descriptor of a Method subclass. method and version are required. The descriptor states scope and references. Whether a Method applies to a given problem is decided by its plan, and a descriptor neither proves that nor qualifies a backend.

Attributes:

  • method (Text) –

    Required. Registered method name, such as "lchs".

  • version (Text) –

    Required. Method version. The pair (method, version) identifies the implementation.

  • problem_families (tuple[Text, ...]) –

    Default (). Problem kinds the Method declares, such as "linear_dynamics".

  • output_families (tuple[Text, ...]) –

    Default (). Output kinds it declares, such as "solution".

  • access_families (tuple[Text, ...]) –

    Default (). Input representations it declares, such as "dense".

  • resource_coverage (tuple[Text, ...]) –

    Default (). What its resource estimates cover.

  • evidence_coverage (tuple[Text, ...]) –

    Default (). What its error evidence covers.

  • limitations (tuple[Text, ...]) –

    Default (). Known limitations stated to users.

  • references (tuple[Source, ...]) –

    Default (). Sources of the implemented method, such as its paper.

  • maintenance (Text) –

    Default "experimental research method". Maintainer or status label.

source

source

The Source that names this method and version.

Registrations and saved results use it to identify the implementation.

ApplicabilityError

Bases: ValueError

Raised when a configured Method cannot solve the given problem or output.

A Method's plan raises it, for example for an unsupported problem type, input representation or output. It is a ValueError.

default_output

default_output()

Return the output that plan and compare use when no output is given.

Each built-in Problem returns its default output, such as Eigenvalue() for an Eigenproblem. A Problem type of a Method author defines its own, as Run your own circuit shows. This base raises, so a Problem without its own default needs an explicit output.

Returns:

Raises:

  • TypeError –

    Always, on this base.

_bind

_bind(*, blocks=(), **native)

Bind the planned circuit blocks and named live inputs to this Plan once, and return the Plan.

A supported hook for Method authors (Add a Method). It compiles nothing, measures nothing and does not rebuild the inputs. An archive reader restores the same blocks with it instead of planning again.

Parameters:

  • blocks (tuple, default: () ) –

    The live circuit blocks of the construction.

  • **native (object, default: {} ) –

    Named live inputs that the Method keeps with the Plan.

Returns:

  • plan ( Plan ) –

    This Plan.

Raises:

  • ValueError –

    If live data is already bound to this Plan.

resolve

resolve(experiment: str, *, bindings: tuple[Binding, ...] = ()) -> Realization

Bind the open Program parameters of one experiment, without changing the Plan.

Only values that pass the Program's checks are bound. The result depends on the Plan and the bindings alone, and nothing is prepared.

Parameters:

  • experiment (str) –

    Name of one of this Plan's experiments.

  • bindings (tuple[Binding, ...], default: () ) –

    Values for Program parameters that the Plan and the experiment's setting leave unbound, such as a point of a range axis. A value that differs from an existing binding is rejected.

Returns:

  • realization ( Realization ) –

    The Plan's content hash, the experiment name and every parameter value, in parameter-name order.

_attach

_attach(plan, data)

Attach the Plan and run data to a Result once, and return the Result.

A supported hook for Method authors (Add a Method). It checks that the Result names this Plan and these observations, that every part of the observations it uses is in the data, and calls validate_plan before attaching. It measures nothing and creates no missing observation.

Parameters:

  • plan (Plan) –

    The Plan the Result was computed from.

  • data (RunData) –

    The run data the Result was computed from.

Returns:

  • result ( Result ) –

    This Result, with plan and data attached.

Raises:

  • ValueError –

    If the Result names another Plan or other observations, uses an observation absent from the data, or is already attached to another Plan or data.

validate_plan

validate_plan(plan)

Check that this Result belongs to plan, before the Plan is attached.

The base check compares plan_id with the Plan's content hash. A Method's Result type overrides it to call _validate_common_plan and then check its own relation between the Plan and its fields (Add a Method).

Parameters:

  • plan (Plan) –

    The Plan to check against.

Raises:

  • ValueError –

    If the Result names another Plan.

_validate_common_plan

_validate_common_plan(plan, plan_type)

Check the Plan type, the Plan's content hash and the Method that analyzed the Result.

A supported hook for Method authors. Call it from validate_plan before checking the Method's own relation between the Plan and the Result (Add a Method).

Parameters:

  • plan (Plan) –

    The Plan to check against.

  • plan_type (type) –

    The exact Plan class that the Method produces.

Raises:

  • TypeError –

    If plan is not exactly of type plan_type.

  • ValueError –

    If the Result names another Plan, or its origin names another Method than the Plan's.

_summary_lines

_summary_lines()

Return the first lines of print(result), built from the Result's stored values.

A supported hook for Method authors (Add a Method). An override must not measure, reanalyze, load arrays or recompute error evidence.

Returns:

  • lines ( tuple[str, ...] ) –

    The lines.

PreparedHandle

PreparedHandle()

The prepared circuit of one experiment for one backend, with its preparation record.

Submission uses exactly this circuit, so the circuit that executes is the one the preparation record describes. After Run.release_native the circuit is dropped from memory and read back from the Run's saved QPY when needed, without building or transpiling it again. Method authors receive handles from the Run's preparation calls. The fields below are read-only.

Attributes:

  • record (PreparedArtifact) –

    The preparation record (PreparedArtifact), with the readout and the backend.

  • realization (Realization) –

    The experiment's concrete parameter values and construction (Realization).

inspect_circuit

inspect_circuit()

Return a copy of the prepared Qiskit circuit.

QuantumCircuit.copy gives the copy its own instruction list and its own operation objects (checked against the installed Qiskit), so changing the copy leaves the circuit that executes unchanged.

Returns:

  • circuit ( QuantumCircuit ) –

    The copy.

Raises:

  • ValueError –

    If this preparation is a host computation without a circuit.

inspect_resources

inspect_resources(*, transpile_options=None, max_operations=100000, max_bytes=DEFAULT_MAX_BYTES)

Count the operations of the 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:

  • 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, or None), operations (count by name), total_operations, num_qubits, num_clbits and depth (Qiskit's default depth, which skips directives such as barriers and simulator saves).

Raises:

  • ValueError –

    If this preparation has no circuit or a limit is exceeded.

Check and register a method

MethodCase

MethodCase(method: Method, problem: Record, evaluate: Callable[[Plan], Result], accepts: Callable[[Result], bool], invalid_result: Callable[[Result], Result], output: Record | None = None, execution: str = 'quantum', shots: int | None = None, seed: int | None = None)

One small test case for a new Method: a problem, how to run it, an independent check of the answer and a deliberately wrong answer.

Build it with keyword arguments, usually in a case() function next to the Method, and pass it to check_method or run python -m nwqlib check-method my_methods:case. method, problem, evaluate, accepts and invalid_result are required. The checker computes no reference answer of its own. accepts holds the independent expected relation, and evaluate decides whether the case prepares and submits circuits or analyzes data supplied with it. The Method's archive hooks are trusted code and run under the ordinary archive byte limits. The reference Hadamard Method, tests/_hadamard_method.py, defines such a case().

Parameters:

  • method (Method) –

    The configured Method under test.

  • problem (Record) –

    The problem of this case.

  • evaluate (Callable[[Plan], Result]) –

    Called with the Plan, returns that Plan's attached Result, for example by prepare, submit and run.wait().

  • accepts (Callable[[Result], bool]) –

    Called with the Result, returns True when the independent expected relation holds, for example abs(result.value - 1.0) < 1e-12.

  • invalid_result (Callable[[Result], Result]) –

    Called with the Result, returns a Result of the same class and Plan with a scientific field changed so that it is valid as a record but wrong for this Plan, for example result.revise(value=-1.0).

  • output (Record | None, default: None ) –

    Requested output, or None for the problem's default.

  • execution (str, default: 'quantum' ) –

    "quantum" or "classical".

  • shots (int | None, default: None ) –

    Requested shots, or None for exact readout or the Method's default.

  • seed (int | None, default: None ) –

    Seed of the Plan's random streams, or None for fresh entropy.

check_method

check_method(case: MethodCase) -> dict

Check a new Method against its test case: the expected answer, the Plan checks and a saved-result round trip.

The check plans the case through the public plan, evaluates the Plan with the case's callback, and requires the case's independent relation to accept the Result. The Method's error_model must equal the Plan's, and its result_type must name the Result class. The wrong Result from invalid_result must be a valid record that the Method's validate_plan rejects, both in memory and after it replaces the legal Result in a saved archive. The legal Result must then reload unchanged and still pass the relation. These wrong-answer steps show that the Method's own Plan and Result check catches a scientifically wrong answer under the same Plan, which a record's own field checks cannot do. Nothing beyond the case's callback is computed, neither a reference solve nor extra circuits. "CONFORMANT" means this one case passed. It does not certify other inputs, physical accuracy, backend support or cost. The example at the top of Extending NWQLib runs it on the reference Hadamard Method.

Parameters:

Returns:

  • report ( dict ) –

    A dict with status ("CONFORMANT"), method (the descriptor's method name), plan_id, result_id, scope and qualification.

Raises:

  • TypeError –

    If the case, the Method or its Result class does not meet the Method protocol.

  • ValueError –

    If the expected relation, the wrong-answer check or the saved round trip fails.

Registration

Registration(source: Source, factory: str, descriptor: AlgorithmDescriptor | None = None, method_type: type[Method] | None = None)

An entry that makes a Method findable by name and version: its Source and a trusted factory path.

Build it with keyword arguments, for example Registration(source=MyMethod.descriptor.source, factory="my_methods:MyMethod"), in a module that does not import the Method itself, and pass it to AlgorithmRegistry. source and factory are required. Building it imports nothing. A saved Source string never loads code. Only a registration in the running process does. Explicit trusted registration shows the metadata module of the reference Method.

Parameters:

  • source (Source) –

    Source naming the method and version, as descriptor.source gives it.

  • factory (str) –

    "module:attribute" path of a callable that returns the Method, called only by AlgorithmRegistry.resolve.

  • descriptor (AlgorithmDescriptor | None, default: None ) –

    The Method's AlgorithmDescriptor when already known, with the same method and version as source. None avoids importing the Method to read it.

  • method_type (type[Method] | None, default: None ) –

    The Method class when already known. Its descriptor must equal descriptor.

Raises:

  • ValueError –

    If factory is not a module:attribute path, or the descriptor's method and version differ from source or from method_type.descriptor.

  • TypeError –

    If method_type is not a Method subclass.

AlgorithmRegistry

AlgorithmRegistry(registrations: Iterable[Registration] = ())

A list of trusted Method registrations that finds a Method by name and version and builds it on request.

Build it as AlgorithmRegistry((registration, ...)). Without registrations it is empty. discover lists the registrations without running any factory, and resolve runs only the factory of the requested Source. A registry is not a security sandbox, and a registration does not qualify a backend.

Parameters:

  • registrations (Iterable[Registration], default: () ) –

    The registrations, at most one per method and version.

Raises:

  • ValueError –

    If two registrations share a method and version.

discover

discover() -> tuple[Registration, ...]

Return the registrations in method and version order, without importing any factory.

Returns:

  • registrations ( tuple[Registration, ...] ) –

    The registrations.

resolve

resolve(source: Source, *, expected_type: type[T] = Method, **configuration) -> T

Build the registered Method for a Source by calling its factory with the given configuration.

Only the factory of that Source runs, with exactly the configuration supplied, and no earlier configuration is reused. The built Method must match the registered method, version, descriptor and class.

Parameters:

  • source (Source) –

    Source of the method and version, equal to the registered one.

  • expected_type (type, default: Method ) –

    Class the result must be an instance of, which keeps a caller's concrete type.

  • **configuration (object, default: {} ) –

    Keyword arguments for the factory, such as Method settings.

Returns:

  • method ( Method ) –

    The configured Method.

Raises:

  • LookupError –

    If no registration has this method and version.

  • ValueError –

    If source differs from the registered Source, or the built Method differs from the registration.

  • TypeError –

    If the built object is not a complete Method of expected_type.

builtin_registrations

builtin_registrations() -> tuple[Registration, ...]

Return a registration for each built-in Method, without constructing or planning one.

It imports the built-in configuration modules, which can load NumPy, SciPy and their dependencies, but no quantum SDK. Installed extensions are not included. Their configuration fields, defaults and required fields come from each Method class's schema.

Returns:

  • registrations ( tuple[Registration, ...] ) –

    The registrations, in method and version order.

third_party_registrations

third_party_registrations(entries: Iterable[EntryPoint] | None = None) -> tuple[Registration, ...]

Return a registration for each installed nwqlib.algorithms entry point, without loading its code.

Each entry point must be named method@version, and its value is the factory path. The descriptor and Method class of these registrations stay None until code is loaded explicitly. Builtin inventory does not call this function, so installed extensions are found only when it is called.

Parameters:

  • entries (Iterable[EntryPoint] | None, default: None ) –

    Entry points to read. None reads the installed entry points of the group nwqlib.algorithms. Entries of other groups are ignored.

Returns:

  • registrations ( tuple[Registration, ...] ) –

    The registrations, sorted by method, version and factory.

Raises:

  • ValueError –

    If an entry-point name is not method@version.

direct_method

direct_method(method: object, *, expected_type: type[T] = Method) -> T

Check that an object is a complete Method and return it, without running a factory.

A complete Method has a descriptor and implements plan and analyze.

Parameters:

  • method (object) –

    The object to check.

  • expected_type (type, default: Method ) –

    Class the object must be an instance of.

Returns:

  • method ( Method ) –

    The same object.

Raises:

  • TypeError –

    If it is not an instance of expected_type, has no descriptor, or does not implement plan and analyze.

options_schema

options_schema(registration: Registration) -> dict

Return the JSON schema of a registered Method's configuration, with its required fields and defaults.

nwqlib options METHOD prints it. The schema comes from the Method class (model_json_schema()), so no required input is guessed.

Parameters:

  • registration (Registration) –

    A registration whose method_type is known.

Returns:

  • schema ( dict ) –

    The JSON schema.

Raises:

  • ValueError –

    If the registration's Method class is not loaded, as for an installed extension found by third_party_registrations. Select the extension's code explicitly in Python first.

Describe a circuit as a Program

A Program lists named nodes: register allocation, block calls, measurements, repeats and their order. It is checked when it is built. Describe a circuit as a Program explains the nodes and Program checks the lifecycle rules.

Program

Bases: Record

A circuit described as named steps: registers, block calls, measurements and their order, checked when it is built.

Build it with keyword arguments and use it in a SelectedConstruction. root and definitions are required. Every node is a Definition with an ID, and nodes refer to each other by ID, so a shared body is stored once however often it runs, and the checking work grows with its distinct contexts rather than its run count. The root starts with no allocated registers or classical values. Registers still allocated at the end of the root stay available to code that uses the quantum output, while the body of a measurement batch must release its registers. Construction runs the full structural check of the declared effects, so an illegal lifecycle or a graph over its limits is rejected before anything uses the Program. Unresolved requirements, such as an unbound width, do not reject it but make it not ready.

One Program is the single description of a construction that the structural check, resource estimate, circuit building and readout all read, so a cost, a circuit and a readout cannot describe different constructions. Its content hash covers every table, binding and limit. Run your own circuit builds a Program around a supplied circuit, and Describe a circuit as a Program explains the nodes.

Attributes:

  • root (Text) –

    Required. Definition ID of the root node.

  • definitions (tuple[Definition, ...]) –

    Required. The Definition records.

  • expressions (tuple[Expression, ...]) –

    Default (). Expression records that widths, counts and arguments refer to.

  • parameters (tuple[Parameter, ...]) –

    Default (). Declared Parameter records.

  • constraints (tuple[ExprRef, ...]) –

    Default (). Bool expressions that every bound point must satisfy.

  • registers (tuple[Register, ...]) –

    Default (). Quantum Register records.

  • classical (tuple[ClassicalValue, ...]) –

    Default (). ClassicalValue records.

  • signatures (tuple[BlockSignature, ...]) –

    Default (). BlockSignature records of the blocks called.

  • bindings (tuple[Binding, ...]) –

    Default (). Parameter values bound so far.

  • limits (AdmissionLimits) –

    Default AdmissionLimits(), the default AdmissionLimits.

  • premises (tuple[Text, ...]) –

    Default (). Stated assumptions of the construction.

Raises:

  • ValueError –

    If the structure breaks a lifecycle rule, refers to an unknown ID, or exceeds limits.

Examples:

Allocate a two-qubit register and measure it.

>>> from nwqlib.ir import (Allocate, ClassicalValue, Definition, Measure,
...                        Program, Register, Sequence)
>>> program = Program(
...     root="main",
...     definitions=(
...         Definition(id="allocate", node=Allocate(wire="q")),
...         Definition(id="measure", node=Measure(wire="q", result="bits")),
...         Definition(id="main",
...                    node=Sequence(children=("allocate", "measure"))),
...     ),
...     registers=(Register(name="q", width=2),),
...     classical=(ClassicalValue(name="bits", dtype="bits", width=2),),
... )
>>> program.check_readiness().ready
True

check_readiness

check_readiness() -> Readiness

Return the result of this Program's structural check.

The check runs once per Program object, when it is built, and its result is kept for later calls. Copies and unpickled Programs check again on first use. It covers every concrete rule and lists unresolved requirements as blockers. expression_evaluations + lifecycle_steps of the result is the checking work it measured.

Returns:

  • readiness ( Readiness ) –

    The result of the check.

bind

bind(**values)

Return a copy of the Program with parameter values bound, keeping shared bodies.

The copy runs the structural check again.

Parameters:

  • **values (int | Float64, default: {} ) –

    Parameter values by name, an exact integer or a Float64.

Returns:

  • program ( Program ) –

    The bound Program.

Raises:

  • ValueError –

    If the bound Program fails the structural check.

select_experiment

select_experiment(batch_id: str, setting_index: int, **axis_values)

Return a Program for one experiment of a measurement batch, without expanding any range or product.

The returned Program's root is the batch with the one selected setting and no axes. It keeps the dependency closure of that batch, every global constraint and the register layout, and the selected values also bind the global constraints. It creates no observation or execution ID, because the original Program identifies the whole source graph. Use it before lower_qiskit, which builds the circuit of one static experiment.

Parameters:

  • batch_id (str) –

    Definition ID of the measurement batch.

  • setting_index (int) –

    Index of the setting.

  • **axis_values (int, default: {} ) –

    One value for each range axis of the batch.

Returns:

  • program ( Program ) –

    The Program of the selected experiment.

Raises:

  • ValueError –

    If the batch, setting or axis values are invalid.

iter_definitions

iter_definitions()

Return an iterator over the stored definitions, each once in declaration order, without expanding anything.

Returns:

  • definitions ( Iterator[Definition] ) –

    The definitions.

Definition

Bases: Record

One node of a Program with its ID. Nodes refer to each other by ID, so a shared body is stored once.

Build it as Definition(id="main", node=Sequence(children=(...))) and pass it in definitions= of a Program. Both arguments are required.

Attributes:

  • id (Text) –

    Required. Unique ID within the Program.

  • node (Node) –

    Required. One node: Sequence, Repeat, BlockCall, CoherentRegion, Allocate, Release, Measure, Reset, Branch, ClassicalStage, AdaptiveLoop, MeasurementBatch or Parallel.

Readiness

Bases: Record

The result of a Program's structural check: what is still unresolved, and the checking work it took.

Program.check_readiness returns it. The fields below are read-only. A ready Program is structurally valid. It is not a check of the blocks' promised actions or an approval to run.

Attributes:

  • blockers (tuple[Text, ...]) –

    Sorted unresolved requirements, such as an unbound width or an unknown block effect. Empty when the Program is ready.

  • expression_evaluations (NonnegativeInt) –

    Expression evaluations of this check.

  • lifecycle_steps (NonnegativeInt) –

    Other checking work units of this check, not quantum events or algorithm costs.

ready

ready: bool

Whether no requirement is unresolved, that is, blockers is empty.

require_ready

require_ready()

Return this result, or raise when a requirement is still unresolved.

Returns:

Raises:

  • ValueError –

    If blockers is not empty. The message lists them.

AdmissionLimits

Bases: Record

Limits on the size of a Program's stored structure and on the work of checking it.

Pass it as limits= to Program. Every argument is optional. A caller can make a Program's metadata arbitrarily large or deep, and these limits make the structural check and the resource estimate reject it before their work or memory passes a fixed size. They limit the stored structure and the checking work, never the size of the workload the Program describes, and repeat counts and range lengths are not expanded. A Method with a max_admission_steps setting uses it as max_steps of its Programs, and Program checks explains how planning work is counted.

Attributes:

  • max_definitions (PositiveInt) –

    Default 16384. Positive limit on the stored definitions, expressions, parameters, registers, classical values and signatures together. 16,384 is the smallest power of two with at least a twofold margin over the 5,951 of a sampled FixedGCIM Plan with a 12-qubit, 200-term observable and four basis states (the Program inventory row of Engineering constants).

  • max_depth (PositiveInt) –

    Default 128, also the largest accepted value. Limit on the longest chain of references, which is also the recursion limit of the lifecycle check.

  • max_steps (PositiveInt) –

    Default 100000. Positive limit on the checking work units of one check, and separately on the number of stored fields.

  • max_integer_bits (PositiveInt) –

    Default 4096. Positive limit on the bit length of any integer the check accepts or computes.

Registers, values and block signatures

Register

Bases: Record

A quantum register of a Program, allocated explicitly by an Allocate node.

Build it as Register(name="q", width=2) and pass it in registers= of a Program. name and width are required.

Attributes:

  • name (Text) –

    Required. Register name, used by ports, allocation and measurement.

  • width (Integer) –

    Required. Number of qubits, an integer or an ExprRef.

  • location (Text) –

    Default "logical_device". Device location on which the resource estimate places the register.

  • role (Literal['system', 'clean_ancilla', 'dirty_ancilla']) –

    Default "system". "system", "clean_ancilla" or "dirty_ancilla", reported separately in memory and qubit counts.

ClassicalValue

Bases: Record

A named classical value of a Program, such as measured bits or a computed scalar.

Build it as ClassicalValue(name="bits", dtype="bits", width=2) and pass it in classical= of a Program. name and dtype are required. Bits have a positive width, and the other types have none.

Attributes:

  • name (Text) –

    Required. Value name.

  • dtype (Literal['bits', 'bool', 'integer', 'real']) –

    Required. "bits", "bool", "integer" or "real".

  • width (Integer | None) –

    Default None. Number of bits, positive and required for "bits", None otherwise.

Raises:

  • ValueError –

    If width is missing or not positive for bits, or given for another type.

BlockSignature

Bases: Record

The declared interface of a block that a Program calls: its target action, ports and parameters.

Build it with keyword arguments, for example BlockSignature(name="h", target=source, quantum=(QuantumPort(name="system", width=1),)), and pass it in signatures= of a Program. name and target are required. A BlockCall names the signature, and the selected definition bound to it supplies the action, its cost rules and the circuit constructor. The signature declares an interface. It does not prove that an implementation performs the action.

Attributes:

  • name (Text) –

    Required. Signature name, used by block calls and by the selected definition.

  • target (Source) –

    Required. Versioned Source of the action a selection must implement.

  • quantum (tuple[QuantumPort, ...]) –

    Default (). Ordered QuantumPort records.

  • parameters (tuple[Parameter, ...]) –

    Default (). Scalar Parameter records with their domains.

  • interface (Literal['declared', 'unknown']) –

    Default "declared". "unknown" keeps an undeclared block in the Program, which is then not ready.

  • coupling (Literal['joint', 'independent']) –

    Default "joint", when the call may correlate its ports, or "independent" when it promises not to.

  • obligations (tuple[Text, ...]) –

    Default (). Promises that the selected implementation must meet.

QuantumPort

Bases: Record

A port of a block signature: a whole register the block acts on, with the state it needs and the effect it promises.

Build it as QuantumPort(name="system", width=2) and pass it in quantum= of a BlockSignature. name and width are required. A call maps each port, in signature order, to a register that no other port of the call uses. The zero state counts as coherent. A "unitary" effect keeps the register's coherence epoch but clears a known zero state, and "preserve" promises that the state is restored exactly. A "zero" or "coherent" output asserts a newly prepared state, which the block's implementation must guarantee. An "unknown" effect makes the Program not ready and cannot satisfy a later state requirement.

Attributes:

  • name (Text) –

    Required. Port name.

  • width (Integer) –

    Required. Number of qubits, an integer or an ExprRef.

  • requires (Literal['live', 'zero', 'coherent']) –

    Default "live". Input state the port needs: any allocated ("live") state, "zero" or "coherent".

  • ensures (Literal['unitary', 'preserve', 'zero', 'coherent', 'unknown']) –

    Default "unitary". Effect on the register: "unitary", "preserve", "zero", "coherent" or "unknown".

Nodes

Sequence

Bases: Record

Runs its child nodes in order, even when they act on disjoint registers.

Build it as Sequence(children=("allocate", "measure")), with the IDs of other definitions.

Attributes:

  • children (tuple[Text, ...]) –

    Default (). Definition IDs, in order.

Parallel

Bases: Record

Runs block calls concurrently on disjoint registers and joins them.

Build it as Parallel(children=("call_a", "call_b")). Every child must be a direct block call whose ports declare "unitary" or "preserve". Children that share registers, and classical work or lifetime changes, are rejected. Use Sequence for serial order.

Attributes:

  • children (tuple[Text, ...]) –

    Default (). Definition IDs of the block calls.

Repeat

Bases: Record

Repeats a body a fixed number of times, without unrolling it.

Build it as Repeat(body="step", count=4). Both arguments are required. The check verifies that the body can be repeated and never expands it, so a large count costs no more checking work than a small one.

Attributes:

  • body (Text) –

    Required. Definition ID of the body.

  • count (Integer) –

    Required. Nonnegative repetition count, an integer or an ExprRef.

BlockCall

Bases: Record

Calls a declared block signature on whole registers, with ports in signature order.

Build it as BlockCall(signature="h", ports=(PortMap(port="system", wire="q"),)). signature is required. Each register is used by one port only. The call names the signature, not an implementation. The selected definition bound to that signature supplies the action, cost rules and circuit constructor.

Attributes:

  • signature (Text) –

    Required. Signature name.

  • ports (tuple[PortMap, ...]) –

    Default (). One PortMap per port, in signature order.

  • arguments (tuple[Argument, ...]) –

    Default (). Argument values of the signature's parameters.

PortMap

Bases: Record

Maps one port of a block signature to a whole register in a block call.

Build it as PortMap(port="system", wire="q"). Both arguments are required.

Attributes:

  • port (Text) –

    Required. Port name of the signature.

  • wire (Text) –

    Required. Register name.

Argument

Bases: Record

Gives a scalar parameter of a block signature the value of an expression in a block call.

Build it as Argument(parameter="angle", value=ExprRef(expression="theta")). Both arguments are required.

Attributes:

  • parameter (Text) –

    Required. Parameter name of the signature.

  • value (ExprRef) –

    Required. The ExprRef of the value.

Allocate

Bases: Record

Allocates a register in the zero state, starting its lifetime in the current experiment.

Build it as Allocate(wire="q").

Attributes:

  • wire (Text) –

    Required. Register name.

Release

Bases: Record

Discards a register. Its quantum state cannot be used after this point.

Build it as Release(wire="q").

Attributes:

  • wire (Text) –

    Required. Register name.

Measure

Bases: Record

Measures a whole register into a classical bits value. The register stays allocated in a new epoch.

Build it as Measure(wire="q", result="bits"). wire and result are required.

Attributes:

  • wire (Text) –

    Required. Register name.

  • result (Text) –

    Required. Name of a classical bits value of the same width.

  • basis (Text) –

    Default "computational", the only basis that lower_qiskit and OpenQASM export support.

Reset

Bases: Record

Resets an allocated register to zero, starting a new coherent epoch.

Build it as Reset(wire="q").

Attributes:

  • wire (Text) –

    Required. Register name.

CoherentRegion

Bases: Record

Requires the claimed registers to stay in their coherent epochs throughout the body.

Build it as CoherentRegion(body="kernel", claims=(StateClaim(wire="q", epoch=0),)). Both arguments are required. A measurement, reset or other new preparation of a claimed register inside the body is rejected.

Attributes:

  • body (Text) –

    Required. Definition ID of the body.

  • claims (tuple[StateClaim, ...]) –

    Required. The StateClaim records.

StateClaim

Bases: Record

Claims that a register is still in a given coherent epoch. Measurement and reset start a new epoch.

Use it in claims= of a CoherentRegion. An epoch numbers the coherence generations of one register. The first allocation starts it at 0. Every measurement, reset, release, reallocation and block port that promises a newly prepared zero or coherent output adds one, to the register it acts on and to every register correlated with it. A claim therefore names one specific coherent state, and a claim written before a measurement no longer matches after it. Program checks gives the full rules.

Attributes:

  • wire (Text) –

    Required. Register whose coherence is claimed.

  • epoch (NonnegativeInt) –

    Required. Epoch the register must currently have.

Branch

Bases: Record

Chooses between two bodies on a classical value. Both paths are checked.

Build it as Branch(condition="flag", when_true="a", when_false="b"). Every argument is required. After the branch, a register state or classical value is available only as far as both paths make it available.

Attributes:

  • condition (Text) –

    Required. Name of an available classical value.

  • when_true (Text) –

    Required. Definition ID of the body for true.

  • when_false (Text) –

    Required. Definition ID of the body for false.

ClassicalStage

Bases: Record

A classical computation inside the quantum job or on the host. The check runs no code.

Build it with keyword arguments, for example ClassicalStage(implementation=source, inputs=("bits",), outputs=("value",)). implementation is required. A host stage requires every register to be released first and can name the selected kernel that runs it.

Attributes:

  • implementation (Source) –

    Required. Versioned Source of the computation.

  • inputs (tuple[Text, ...]) –

    Default (). Classical values read, which must be available on every path.

  • outputs (tuple[Text, ...]) –

    Default (). Classical values defined.

  • arguments (tuple[Argument, ...]) –

    Default (). Scalar Argument values.

  • boundary (Literal['in_job', 'host']) –

    Default "in_job", processing inside the quantum job, or "host".

  • kernel (Text | None) –

    Default None. Name of the selected kernel that runs a host stage.

AdaptiveLoop

Bases: Record

Repeats a body zero to max_rounds times, with a classical policy after each round and a declared stopping rule.

Build it with keyword arguments. body, max_rounds, policy and termination are required. The stopping rule is kept as text and never executed.

Attributes:

  • body (Text) –

    Required. Definition ID of one round.

  • max_rounds (Integer) –

    Required. Upper bound on the rounds, an integer or an ExprRef.

  • policy (ClassicalStage) –

    Required. Versioned ClassicalStage run after each round, which may read that round's results.

  • termination (Text) –

    Required. Declared stopping rule.

  • resource_envelope (Text | None) –

    Default None. Stated bound on the cost of every round. With None, the resource estimate leaves the loop's cost unknown.

MeasurementBatch

Bases: Record

Independent experiments that share one body. No quantum or classical state passes between them.

Build it with keyword arguments, for example MeasurementBatch(body="experiment", settings=(setting,), repetitions=1, observation_kind="counts"). body and settings are required. The settings are combined with the range axes. A requirement that depends on an axis value keeps the Program not ready until one experiment is selected and bound (Program.select_experiment). lower_qiskit builds one circuit of the body, not its repetitions. Every register the body allocates must be released at its end.

Attributes:

  • body (Text) –

    Required. Definition ID of the shared body.

  • settings (tuple[Setting, ...]) –

    Required. At least one Setting.

  • axes (tuple[RangeAxis, ...]) –

    Default (). RangeAxis ranges.

  • scope (Literal['independent_experiments']) –

    Default "independent_experiments", the only accepted value.

  • repetitions (Integer | None) –

    Default None. Independent runs of the body, an integer or an ExprRef. None leaves the planning requirement unknown. Preparing an exact readout kind requires 1.

  • observation_kind (ObservationKind | None) –

    Default None. For the innermost batch, "counts" for sampled counts, "pauli_expectation" or "probabilities" for exact statistics, "estimated_observable" for a provider estimate, or "trajectory". A "trajectory" is one exact evaluation of the body whose observation points belong to the selected experiment's readout, not to the settings. An outer batch has None.

Setting

Bases: Record

One experiment of a measurement batch: a label, parameter values and method metadata.

Build it as Setting(label="z_basis", bindings=(...), metadata=MetadataRef(...)). label and metadata are required. The label, bindings and metadata together determine the experiment's content hash.

Attributes:

RangeAxis

Bases: Record

An integer parameter range [start, stop) with a positive step, kept compact and never expanded.

Build it as RangeAxis(parameter="k", start=0, stop=8) and pass it in axes= of a MeasurementBatch, which combines every setting with every value. parameter, start and stop are required.

Attributes:

  • parameter (Text) –

    Required. Parameter name.

  • start (NonnegativeInt) –

    Required. Nonnegative first value.

  • stop (NonnegativeInt) –

    Required. Nonnegative end, excluded and greater than start.

  • step (NonnegativeInt) –

    Default 1. Positive step.

Raises:

  • ValueError –

    If the range is empty.

MetadataRef

Bases: Record

A reference to method metadata attached to a setting, in a format the method defines. It is never decoded by the check.

Build it as MetadataRef(format=source, data=input_ref). Both arguments are required.

Attributes:

  • format (Source) –

    Required. Source of the metadata format.

  • data (InputRef) –

    Required. InputRef of the stored metadata.

Parameters and expressions

Parameter

Bases: Record

A named integer or real parameter of a Program, with optional inclusive bounds.

Build it with keyword arguments, for example Parameter(name="steps", domain="integer", lower=1), and pass it in parameters= of a Program or a BlockSignature. name and domain are required. A real value is a finite binary64 number given as Float64.

Attributes:

  • name (Text) –

    Required. Parameter name.

  • domain (Literal['integer', 'real']) –

    Required. "integer" or "real".

  • lower (Value | None) –

    Default None. Inclusive lower bound, an exact integer for an integer domain.

  • upper (Value | None) –

    Default None. Inclusive upper bound, not below lower.

Raises:

  • ValueError –

    If an integer domain has a non-integer bound, or lower exceeds upper.

admit
admit(value)

Check a value against the parameter's domain and bounds, without rounding, and return it as a number.

Parameters:

  • value (int | Float64) –

    An exact integer for an integer domain, or a Float64 for a real domain.

Returns:

  • value ( int | float ) –

    The value as a number.

Raises:

  • ValueError –

    If the value has the wrong type or lies outside the bounds.

Binding

Bases: Record

A concrete value for one parameter, part of the content hash of the record that holds it.

Build it as Binding(parameter="steps", value=4) and pass it in bindings= of a Program, a Setting or a selected definition. Both arguments are required.

Attributes:

  • parameter (Text) –

    Required. Parameter name.

  • value (Value) –

    Required. An exact integer or a Float64.

Expression

Bases: Record

A named expression of a Program: a constant, a parameter value or an operation on two expressions.

Build it as Expression(id="width", value=Constant(value=3)) and pass it in expressions= of a Program. Both arguments are required, and the ID is unique within the Program.

Attributes:

Constant

Bases: Record

An exact integer or finite Float64 literal, the value of an expression.

Build it as Constant(value=3) and wrap it in an Expression.

Attributes:

  • value (Value) –

    Required. An exact integer or a Float64.

ParameterRef

Bases: Record

The value of a declared parameter, as an expression.

Build it as ParameterRef(parameter="steps") and wrap it in an Expression. While the parameter is unbound, the structural check treats the value as unknown and the resource estimate keeps it symbolic. It is never read as zero.

Attributes:

  • parameter (Text) –

    Required. Name of a declared parameter.

Binary

Bases: Record

An operation on two expressions of the Program, such as a sum or an exact ceiling division.

Build it as Binary(op="multiply", left="n", right="two") and wrap it in an Expression. Both operands must have the same numeric domain. "eq", "lt" and "le" return a bool, and "ceildiv" is exact, requires integers and a positive denominator.

Attributes:

  • op (Literal['add', 'multiply', 'ceildiv', 'min', 'max', 'eq', 'lt', 'le']) –

    Required. "add", "multiply", "ceildiv", "min", "max", "eq", "lt" or "le".

  • left (Text) –

    Required. ID of the left operand's expression.

  • right (Text) –

    Required. ID of the right operand's expression.

ExprRef

Bases: Record

A reference to an expression of the Program by its ID, used wherever a width, count or argument may be computed.

Build it as ExprRef(expression="width"). The ID names an entry of Program.expressions. It is never source code.

Attributes:

  • expression (Text) –

    Required. ID of the expression.

Select and lower blocks

A Program calls blocks by signature name. Each select_* function returns a SelectedBlock whose record states the block's promised action, recipe and cost rules, and lower_qiskit builds the Qiskit circuit from the Program and its blocks. Compose blocks composes a Pauli block encoding from these functions.

select_preparation

select_preparation(name: str, state: StateInput, *, choice: str = 'native', per_bit: bool = False) -> SelectedBlock

Build the state preparation block of a state input, U|0> = state, with the cheapest exact recipe its form allows.

Pass a StateInput from state_input or the ingest_* functions. Selection reads only the stored representation. It never normalizes, hashes the data again, synthesizes or simulates. An occupation, basis or uniform state gets an exact gate recipe, with the physical global phase as a phase gate. A prefix-uniform, general or product state uses the direct preparation and its CX upper bound, and a product state is counted as q one-qubit preparations, not one q-qubit vector. A supplied Qiskit circuit becomes its own block with unknown synthesis cost and error, because its content cannot be recognized. The block promises only U|0>, the normalized state, with the physical global phase kept, including under control. choice="hzh" prepares each occupied site of an occupation input with H, Z, H instead of X. The two recipes are equal as full operators and are different choices, with different content hashes and gate counts.

Parameters:

  • name (str) –

    Signature name of the block.

  • state (StateInput) –

    The state input.

  • choice (str, default: 'native' ) –

    "native", or "hzh" for an occupation input.

  • per_bit (bool, default: False ) –

    With True, the block has one one-qubit port system_<j> per qubit, in the same order, for a caller that measures or connects single sites.

Returns:

  • block ( SelectedBlock ) –

    The preparation block, with port system of q qubits, or the per-qubit ports.

Raises:

  • ValueError –

    If the state's preparation has no circuit constructor, choice is unknown, or "hzh" is used for an input that is not an occupation.

  • TypeError –

    If per_bit is not a bool.

select_block_encoding

select_block_encoding(name, encoding, *, operator, max_bytes=DEFAULT_INPUT_BYTES)

Wrap a block-encoding circuit you built as a block that a Program can call.

Pass a BlockEncoding, for example from build_block_encoding, and the operator input A it encodes. The block promises the (alpha, a, epsilon) block encoding of Gilyén, Su, Low and Wiebe, arXiv:1806.01838v1, Sec. 4.1, Definition 43 (p. 41), ||A - alpha (<0_a| tensor I) U (|0_a> tensor I)|| <= epsilon, with alpha and epsilon in the units of A. The formula writes the ancillas first, as the paper does. NWQLib's encodings place them on the low-order qubits, so in a Qiskit dense matrix the block is (I tensor <0_a|) U (I tensor |0_a>). The relation and error are the caller's assertion. Selection checks the widths, alpha and the error's domain, and does not extract or verify the dense block. The circuit is copied once, so an encoding with equal shapes or metadata cannot attach another circuit later. When the encoding's family and gate counts are known (dense dilation, banded, Pauli LCU or multiplexed Pauli), the block carries a CX-per-query estimate from them, recorded as the caller's assertion rather than a verified inventory. Qiskit is imported only by this call.

Parameters:

  • name (str) –

    Signature name of the block.

  • encoding (BlockEncoding) –

    The encoding circuit and its metadata.

  • operator (OperatorInput) –

    The operator input A.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Default 10 GB (decimal, 10_000_000_000 bytes). Limit on the stored data of the copied circuit.

Returns:

  • block ( SelectedBlock ) –

    The block, with ports ancillas (a qubits, omitted when a = 0) and system.

Raises:

  • TypeError –

    If encoding is not a BlockEncoding.

  • ValueError –

    If the circuit width is not ancillas plus system qubits, the system width is not log2 of A's power-of-two dimension, alpha is not finite and positive, or a given error bound is not finite and nonnegative.

select_signed_pauli

select_signed_pauli(name: str, operator: OperatorInput, *, max_bytes=DEFAULT_INPUT_BYTES) -> SelectedBlock

Build the signed Pauli SELECT block of a Hermitian Pauli operator, the core of its LCU block encoding.

For A = sum_j c_j P_j with real c_j, alpha = sum_j |c_j| and |G> = PREP|0> = sum_j sqrt(|c_j| / alpha) |j>, SELECT applies sign(c_j) P_j on label j. Then (<G| tensor I) SELECT (|G> tensor I) = A / alpha, written with the label register first as the papers do. The block places the label register on the low-order qubits, so a Qiskit dense matrix of it, whose qubit 0 is the least significant index, reads (I tensor <G|) SELECT (I tensor |G>). The recorded relation string keeps the paper order. This is the LCU relation of An, Childs and Lin, arXiv:2312.03916v2, Appendix A.3, Lemma 24, Eq. (178), with each coefficient's sign moved from the two preparation oracles into SELECT. Both oracles then coincide, so the unpreparation is the exact adjoint of PREP and a single real preparation serves both sides. Kirby, Motta and Mezzacapo, arXiv:2208.00567v4, Eqs. (2)-(4), p. 3, use the same form, with nonnegative weights and each Pauli carrying its sign. Their weights have unit L1 norm, so their alpha_i, P_i and H are |c_j|/alpha, sign(c_j) P_j and A/alpha here. Every branch sign(c_j) P_j is Hermitian and unitary, so SELECT squares to the identity. That is their Eq. (5), p. 4, the assumption of the Chebyshev walk in their Lemma 1.

Identity terms are included, and no centering or coefficient threshold is applied. Padding labels apply the identity and get PREP amplitude zero. One term gives a = 0 and P = 1. The zero operator, and an empty or zero-alpha input, has no positive-alpha encoding and is rejected. The coefficients are the real parts of the stored complex128 coefficients, copied bit for bit, alpha is fsum(abs(c)) over them and each amplitude keeps the operand order sqrt(abs(c_j)) / sqrt(alpha). A saved block derives them again from the restored operator in the same way, so alpha, the coefficients and the PREP amplitudes are equal before saving and after loading. Selection does O(M*q + 2**a) work.

max_bytes limits the m*(q+16) + 32P bytes, with m = M terms and P = 2**a >= m, of the label strings with their 16-byte coefficients and of the selection arrays. The selection arrays stay within 32P because the coefficients are frozen before the amplitudes are built: coefficients use 8m, amplitudes 8P, and at most two float64 temporaries 16m, giving 24m + 8P <= 32P. Coefficient freezing peaks at 16m before amplitudes exist, amplitude freezing at 8m + 16P <= 24P, and these phases are sequential.

Parameters:

  • name (str) –

    Signature name of the SELECT block in the Program.

  • operator (OperatorInput) –

    Hermitian Pauli operator A with M terms on q qubits, from ingest_pauli.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Default 10 GB (decimal, 10_000_000_000 bytes). Nonnegative limit on the bytes above.

Returns:

  • block ( SelectedBlock ) –

    The SELECT, with ports index (a = ceil(log2 M) qubits, omitted for M = 1) and system (q qubits). Its record.semantics.alpha is sum_j |c_j| in the units of A.

Raises:

  • ValueError –

    If the operator has no Hermitian Pauli terms, max_bytes is negative or too small, or alpha is zero or not finite.

select_pauli_preparation

select_pauli_preparation(name: str, select: SelectedBlock, *, max_bytes=DEFAULT_INPUT_BYTES) -> SelectedBlock

Build the coefficient preparation PREP of a signed Pauli SELECT, PREP|0> = sum_j sqrt(|c_j| / alpha) |j>.

The amplitudes come from the SELECT block, so the PREP is tied to that SELECT and the pair encodes A/alpha as select_signed_pauli states. The PREP's input is the coefficient vector, while the SELECT keeps the physical operator A. Use the PREP, the SELECT and the adjoint of the PREP (from transform_block) in that order on the label register. A single-term SELECT has no label register and needs no PREP.

Parameters:

  • name (str) –

    Signature name of the PREP block.

  • select (SelectedBlock) –

    The untransformed signed Pauli SELECT.

  • max_bytes (int, default: DEFAULT_INPUT_BYTES ) –

    Default 10 GB (decimal, 10_000_000_000 bytes). Limit on the bytes of the amplitude vector input.

Returns:

  • block ( SelectedBlock ) –

    The PREP block on the label register.

Raises:

  • ValueError –

    If select is not an untransformed signed Pauli SELECT, or it has a single term.

select_pauli_readout

select_pauli_readout(name: str, select: SelectedBlock) -> SelectedBlock

Build the readout block of a signed Pauli SELECT, a label-controlled change to the basis of each Pauli term.

Controlled on the label register, the block V applies H for X, H S^dagger for Y, and the identity for Z, I and padding labels on each system qubit. A computational measurement after V is read with the diagonal value D: the coefficient sign times the parity of the non-identity system qubits for a used label, and zero for a padding label. Then V^dagger D V = Pi_used SELECT Pi_used, the SELECT restricted to the used labels, not the full identity-padded SELECT. No postselection is needed. The label register is kept and may remain entangled. The block reuses the SELECT's data and reads no input again. Its gate tables are built when the circuit is built, and its CX count is bounded by pauli_readout_cx_bound.

Parameters:

  • name (str) –

    Signature name of the readout block.

  • select (SelectedBlock) –

    The untransformed signed Pauli SELECT.

Returns:

  • block ( SelectedBlock ) –

    The readout block, with the same ports as select.

Raises:

  • ValueError –

    If select is not an untransformed signed Pauli SELECT.

select_zero_reflection

select_zero_reflection(name: str, num_qubits: int) -> SelectedBlock

Build the reflection 2|0><0| - I on q qubits, the sign step of the Lanczos Chebyshev walk.

Conjugated by the coefficient PREP G, this block is the reflection R = (2|G><G| - I) (x) I of Kirby, Motta and Mezzacapo, arXiv:2208.00567v4, Lemma 1, Eq. (6), p. 4, with the label register written first as in select_signed_pauli. With the self-inverse signed SELECT U of an operator A, their Eq. (7) gives (<G| (x) I)(R U)**k (|G> (x) I) = T_k(A/alpha). Their H has coefficients of unit L1 norm, which is A/alpha here. The Lanczos method reads expectations of these Chebyshev polynomials. The sign convention matters under control, because control makes the global phase relative. The recipe applies X on every qubit, a multi-controlled Z, X again and a global phase pi, so |0> gets +1 and every other basis state -1. It uses no extra qubits, and zero width gives the identity.

Parameters:

  • name (str) –

    Signature name of the block.

  • num_qubits (int) –

    Nonnegative width q.

Returns:

  • block ( SelectedBlock ) –

    The block, with port system of q qubits.

Raises:

  • ValueError –

    If num_qubits is negative or not an integer.

transform_block

transform_block(name: str, block: SelectedBlock, *, control=False, adjoint=False) -> SelectedBlock

Build the controlled version, the adjoint, or both, of a selected block, keeping its global phase.

A block's promise usually fixes only part of the operator, for a preparation only U|0>. Control and inversion act on the whole selected circuit, including its global phase, which control makes observable. The new block therefore keeps the base block's promise as its base_semantics and declares its own error unknown, because a state or projected-block error of the base does not bound the transformed operator. A transformed block cannot be transformed again, so every transform refers to one concrete base. Adding a control increases the construction work by the controlled cost rule of the base, and a direct preparation's CX count switches to its controlled form. The Pauli SELECT and readout counts read the controlled flag instead. A dense-dilation encoding adds the work of the exact synthesis of its unitary and of Qiskit's control of the synthesized gates, and a supplied preparation or encoding adds the same for each dense unitary in its circuit. lower_qiskit counts these syntheses before they start, against its max_synthesis_work, or in a Run against ExecutionLimits.max_synthesis_work.

Parameters:

  • name (str) –

    Signature name of the new block.

  • block (SelectedBlock) –

    The untransformed base block.

  • control (bool, default: False ) –

    Add one coherent control, as a first port control of one qubit.

  • adjoint (bool, default: False ) –

    Take the adjoint.

Returns:

Raises:

  • ValueError –

    If neither control nor adjoint is set, block is already transformed or has parameters, or its promise does not allow the transformation.

signed_pauli_cx_bound

signed_pauli_cx_bound(index_qubits: int, system_qubits: int, *, controlled=False) -> int

Return an upper bound on the CX gates of a signed Pauli SELECT, optionally with one control.

With a = index_qubits, L = 2**a labels and q = system_qubits, the bound counts the CX positions of the signed Pauli SELECT construction of select_signed_pauli:

  • Each system qubit receives one uniformly controlled one-qubit gate (UCG) with a controls. Qiskit's exact UCGate construction (up_to_diagonal=False) uses L one-qubit core gates and L-1 CX, followed by an exact completion diagonal on a+1 qubits. This core is the decomposition of Bergholm, Vartiainen, Mottonen and Salomaa, arXiv:quant-ph/0410066v2, Sec. III, pp. 3-4, drawn in Fig. 6(a), p. 5, which implements a UCG with k controls by 2**k one-qubit gates and 2**k - 1 CNOTs up to one diagonal (k+1)-qubit gate. In Qiskit 2.5.2, the lower bound of the declared dependency, a random UCGate with a = 1, ..., 4 transpiles to exactly 3(L-1) CX at optimization level 0, matching the per-UCG total below.
  • A diagonal on m qubits costs 2**m - 2 CX and 2**m - 1 Rz rotations. Shende, Bullock and Markov, arXiv:quant-ph/0406176v5, Theorem 7 (p. 10) splits a diagonal into a multiplexed Rz with m-1 select bits and a diagonal on the remaining m-1 qubits. Their Theorem 8 (p. 11) gives 2**k CX for a multiplexed rotation with k select bits. Summing over k = 1, ..., m-1 gives the count. The completion diagonal (m = a+1) therefore adds 2L-2 CX, so each UCG costs 3(L-1) CX.
  • The coefficient sign diagonal on the index register (m = a) adds at most L-2 CX and L-1 rotations.

The uncontrolled total is 3q(L-1) + max(0, L-2). With one control, each CX becomes a Toffoli of 6 CX and one-qubit gates, and each of the q(3L-1) + L-1 one-qubit operations becomes a controlled one-qubit gate of at most 2 CX (the two-CX circuit of Shende, Bullock and Markov, arXiv:quant-ph/0406176v5, Sec. 3.1, p. 9). The six-CX Toffoli is the textbook circuit reproduced by Shende and Markov, arXiv:0803.2316v1, Fig. 1, p. 3. Their Theorem 1 shows that no Toffoli circuit of CX and one-qubit gates uses fewer CX. A global phase becomes a one-qubit phase under control, which costs zero CX but is not zero work. Removing exact dependencies can lower these counts, and hardware cost is unknown.

Parameters:

  • index_qubits (int) –

    Nonnegative width a of the label register.

  • system_qubits (int) –

    Nonnegative system width q.

  • controlled (bool, default: False ) –

    Count one added coherent control.

Returns:

  • bound ( int ) –

    The bound 3q(L-1) + max(0, L-2), or with controlled=True 6 (3q(L-1) + max(0, L-2)) + 2 (q(3L-1) + L-1).

Raises:

  • ValueError –

    If a width is negative or not an integer, or controlled is not a bool.

pauli_readout_cx_bound

pauli_readout_cx_bound(index_qubits: int, system_qubits: int, *, controlled=False) -> int

Return an upper bound on the CX gates of a Pauli label readout block, optionally with one control.

The readout uses the same UCG core and completion diagonal per system qubit as signed_pauli_cx_bound, without the coefficient sign diagonal. With L = 2**a, the bound is that function's value minus max(0, L-2) uncontrolled, or minus 6 max(0, L-2) + 2 (L-1) with one control.

Parameters:

  • index_qubits (int) –

    Nonnegative width a of the label register.

  • system_qubits (int) –

    Nonnegative system width q.

  • controlled (bool, default: False ) –

    Count one added coherent control.

Returns:

  • bound ( int ) –

    The CX bound.

Raises:

  • ValueError –

    If a width is negative or not an integer, or controlled is not a bool.

SelectedBlock

SelectedBlock(*args, **kwargs)

A selected block: its portable record and the trusted code that builds its circuit.

The select_* functions and transform_block return it, and SelectedBlock.bind builds one for a new kind of block. A Plan binds the blocks its Program calls, and lower_qiskit accepts a block only when its record is exactly the selected definition the Program names, so a record loaded from JSON or an equal-looking input cannot attach a different circuit. A controlled or adjoint block keeps its live base block instead of its own constructor, so the base's gates and global phase remain the single source of the transformed action. Direct construction raises TypeError.

Attributes:

bind

bind(record, *, payload=None, base=None, constructor=None)

Bind trusted code to a selected definition and its inputs, for a new kind of block.

A leaf block gets a constructor that receives (block, arguments, method_context) and returns a Qiskit circuit, after the common checks of lower_qiskit. The constructor must implement the record's promised action and work rule, and must not keep the context getter or the Run. A controlled or adjoint block gets its base instead of a constructor. Loading a SelectedDefinition from a file never recreates this binding.

Parameters:

  • record (SelectedDefinition) –

    The selected definition.

  • payload (object | None, default: None ) –

    The checked input or construction data the constructor reads.

  • base (SelectedBlock | None, default: None ) –

    The base block of a control or adjoint, whose content hash equals record.base_selection_id.

  • constructor (Callable | None, default: None ) –

    The leaf constructor, required unless record names a blocker or a base.

Returns:

Raises:

  • TypeError –

    If record is not a SelectedDefinition or constructor is not callable.

  • ValueError –

    If the base and constructor do not match the record.

SelectedConstruction

Bases: Record

A Program with the selected definition of every block it calls: what estimates, circuit building and OpenQASM export read.

Build it with keyword arguments, for example SelectedConstruction(program=program, selections=tuple(b.record for b in blocks)), or read it as plan.construction. program and selections are required. It is not a Plan, and holds no problem, method or data. Saved JSON keeps the sharing of Program.definitions, and executable code is bound again by exact record when the circuit is built, never from saved code. The checks require exactly one selected definition per Program signature, with an identical signature, so every block call resolves to one selection, and every host stage names its exact selected kernel. A Pauli encoding with a label register must be the ordered PREP, SELECT, PREP-adjoint Sequence on that register, where the PREP was selected from this SELECT's coefficients and the adjoint is of that same PREP. A single-term encoding has no label register and is the SELECT alone. That structure is what makes <0|U|0> = A/alpha hold for the subgraph.

Attributes:

  • program (Program) –

    Required. The Program that estimates, circuit building and export read.

  • selections (tuple[SelectedDefinition, ...]) –

    Required. One SelectedDefinition per Program signature.

  • encodings (tuple[PauliEncoding, ...]) –

    Default (). PauliEncoding subgraphs, checked as PREP, SELECT and PREP-adjoint.

  • kernels (tuple[SelectedKernel, ...]) –

    Default (). Host kernel declarations, each named by one host ClassicalStage.

Raises:

  • ValueError –

    If a signature lacks exactly one matching selection, a host stage and kernel do not match, or an encoding breaks the PREP, SELECT, PREP-adjoint structure.

encoding_semantics

encoding_semantics(root: str) -> BlockSemantics

Return the block-encoding promise of one checked Pauli encoding: A, alpha, label convention and error.

The relation is the LCU block encoding of An, Childs and Lin, arXiv:2312.03916v2, Appendix A.3, Lemma 24, Eq. (178), in the real-coefficient form where both preparation oracles equal PREP and sign(c_j) sits in SELECT. With alpha = sum_j |c_j| the label-zero block is A/alpha. This is an exact block encoding in the sense of their Definition 23 (Appendix A.2). Measuring the label register in |0> succeeds with probability ||A psi||^2 / alpha^2, and the label register is not restored in general.

Parameters:

  • root (str) –

    Definition ID of the encoding's Sequence.

Returns:

  • semantics ( BlockSemantics ) –

    The SELECT's promise, restated as a block encoding.

Raises:

  • ValueError –

    If no checked encoding has this root.

PauliEncoding

Bases: Record

Names the PREP, SELECT and PREP-adjoint calls that form one Pauli LCU block encoding in a Program.

Build it with keyword arguments, for example PauliEncoding(root="encoding", select="select", prepare="prep", unprepare="unprep"), and pass it in encodings= of SelectedConstruction, which checks the structure. root and select are required. The normalization, the physical operator A and the error come from the checked SELECT, so this record holds no second copy of them. With the label register in |0> the subgraph acts as A/alpha.

Attributes:

  • root (Text) –

    Required. Definition ID of the Sequence that forms the encoding.

  • select (Text) –

    Required. Signature name of the signed Pauli SELECT.

  • prepare (Text | None) –

    Default None. Signature name of the coefficient PREP, None for a single-term encoding.

  • unprepare (Text | None) –

    Default None. Signature name of the adjoint of that PREP, None for a single-term encoding.

SelectedDefinition

Bases: Record

The portable half of a selected block: its interface, promised action, chosen recipe and cost rules.

Read it as block.record of a SelectedBlock, or from SelectedConstruction.selections. The select_* functions build it. It holds everything resource estimates, saved archives and reports need, and its content hash covers every field. The executable half is the SelectedBlock that binds trusted code to this exact record. Two recipes for the same full operator, such as X and HZH, are different selections with different content hashes and gate counts. decomposition gives the ordered exact gate recipe when one exists. Otherwise cost_law names the cost rule of the circuit construction. An unknown cost stays unresolved and never becomes zero. construction_work counts the documented size rule, not CPU time or memory. The fields below are read-only.

Attributes:

  • signature (BlockSignature) –

    Declared interface, equal to the Program's signature of the same name.

  • semantics (BlockSemantics) –

    The promised action and its approximation: kind, input, relation, normalization alpha, projectors, error epsilon and its norm, whether control and adjoint are allowed, and the phase convention.

  • implementation (Source) –

    Versioned Source of the implementation.

  • choice (Text) –

    Recipe label within the implementation. A supplied circuit gets a fresh unique label.

  • decomposition (tuple[Primitive, ...] | None) –

    Exact ordered Primitive recipe, or None when a cost rule describes the cost.

  • cost_law (Source | None) –

    Source of the size or CX rule, or None when there is none.

  • cost_parameters (tuple[Binding, ...]) –

    Exact arguments of that rule for this selection.

  • cost_context (Text) –

    Scope and limits of the rule, carried into resource quantities.

  • construction_work (Count | None) –

    Work units of building the block's circuit definition by its size rule, or None when unknown.

  • controlled (StrictBool) –

    Whether this selection adds one coherent control to its base.

  • adjoint (StrictBool) –

    Whether this selection is the adjoint of its base.

  • base_selection_id (Text | None) –

    Content hash of the base selection of a control or adjoint.

  • coefficient_selection_id (ContentID | None) –

    Content hash of the SELECT whose coefficients this PREP prepares.

  • blocker (Text | None) –

    Why the selection cannot run, for a block with a cost rule only or an unsupported block.

  • resource_laws (tuple[ResourceLaw, ...]) –

    Per-call resource rules.

  • workspace (tuple[Workspace, ...]) –

    Workspace bytes per call, by location. An empty tuple means unknown, not zero.

Primitive

Bases: Record

One exact gate in a block's recipe. A global phase has no target qubits and becomes observable under control.

SelectedDefinition.decomposition lists these in order. Build it with keyword arguments, for example Primitive(gate="cx", qubits=(0, 1)). gate is required.

Attributes:

  • gate (Literal['x', 'h', 'z', 'sdg', 'cx', 'mc_z', 'phase']) –

    Required. "x", "h", "z" or "sdg" on one qubit, "cx" on (control, target), "mc_z" on two or more qubits, or a global "phase" with no qubits.

  • qubits (tuple[Count, ...]) –

    Default (). Distinct local qubit indices in the block's ports concatenated in signature order, index 0 being the least significant.

  • angle (Real) –

    Default 0.0. Phase angle in radians, nonzero only for "phase", which multiplies the block by exp(i*angle).

Raises:

  • ValueError –

    If the qubits repeat, their number does not match the gate, or a gate other than "phase" has an angle.

lower_qiskit

lower_qiskit(construction: SelectedConstruction, *, blocks: tuple[SelectedBlock, ...], max_operations=100000, max_qubits=4096, max_clbits=4096, max_direct_amplitudes=DEFAULT_MAX_DIRECT_AMPLITUDES, max_synthesis_work=1000000000) -> LogicalCircuit

Build the Qiskit circuit of one experiment of a selected construction, after checking its size.

The construction's root must be one static experiment, for example from Program.select_experiment. It supports sequences, bound repeats, block calls, coherent regions, allocation, release, computational measurement and reset. Reallocation and a register lifetime split across jobs are not supported, and there is no OpenQASM fallback. A counting pass first checks every reachable binding, width, direct-preparation size and supported node and counts the repeats arithmetically, so an oversized or unbound construction is rejected before Qiskit is imported. It reads the same Program and selected definitions as the resource estimate, so the circuit and the estimate describe one construction. Each block call is built by the SelectedBlock whose record is the selection the Program names. A final measurement batch gives one circuit, whatever its repetitions or observation kind, and running it is the Run's task.

Parameters:

  • construction (SelectedConstruction) –

    The Program and its selected definitions.

  • blocks (tuple[SelectedBlock, ...]) –

    The bound blocks of the reachable selections, matched to them by their exact records.

  • max_operations (int, default: 100000 ) –

    Positive, inclusive limit on the Program node visits, repeat counts included.

  • max_qubits (int, default: 4096 ) –

    Limit on the total declared qubits.

  • max_clbits (int, default: 4096 ) –

    Limit on the total declared classical bits.

  • max_direct_amplitudes (int, default: DEFAULT_MAX_DIRECT_AMPLITUDES ) –

    Default 65536. Positive limit on the amplitudes of each reachable direct state preparation, whose synthesis work grows as q * 2**q.

  • max_synthesis_work (int, default: 1000000000 ) –

    Positive limit on the total work of the exact dense-unitary syntheses, and Qiskit's control of them, that the controlled blocks of this circuit make, in the work units of the dense synthesis size rule (Circuit-free synthesis laws). Each synthesis is counted before it starts.

Returns:

  • circuit ( LogicalCircuit ) –

    The circuit with its register and measurement layouts.

Raises:

  • ValueError –

    If a limit is invalid or exceeded, the root is not one static experiment, a block is missing or does not match its selection, or a node is outside the supported subset.

LogicalCircuit

LogicalCircuit(construction_id: str, circuit: object, quantum_layout: tuple, measurement_layout: tuple, dynamic_visits: int, construction_work: int, defined_selections: tuple[str, ...])

A Qiskit circuit built from a selected construction, with its register and measurement layouts, before compilation.

lower_qiskit returns it. The fields below are read-only. Bit and qubit indices are little-endian, index 0 being the least significant.

Attributes:

  • construction_id (str) –

    Content hash of the construction the circuit was built from.

  • circuit (object) –

    The Qiskit circuit. It is not compiled or run.

  • quantum_layout (tuple) –

    (register, qubit indices) pairs in declaration order.

  • measurement_layout (tuple) –

    (classical value, bit indices) pairs.

  • dynamic_visits (int) –

    Program node visits counted while building the circuit, not a gate count.

  • construction_work (int) –

    Sum of the size rules of the selected definitions, not measured work or a limit.

  • defined_selections (tuple[str, ...]) –

    Content hashes of the gate definitions used, base definitions included. Several calls with different arguments can share one definition.

Request readouts and reduce observations

A Plan's experiments name the readout each circuit returns. Reducers that turn a saved state into statistics during data collection are registered by name in nwqlib.core.planning.READOUT_REDUCERS, and the modules of the built-in reducers are listed in nwqlib.core.planning.BUILTIN_REDUCER_MODULES. The reduction-allowance row of Add a Method describes the registration.

Experiment

Bases: Record

One measurement of a Plan: a direct readout, or one setting of a measurement batch of the Program.

A Method's planning step builds the experiments of its Plan with keyword arguments, as Run your own circuit shows. Experiment(name="ghz", setting="computational", observation=ObservationSpec(kind="counts", shots=shots)) declares a direct readout. An experiment of a measurement batch gives batch, setting_index and readout instead, and the batch fixes the readout kind, the setting and the number of repetitions. name is required.

Attributes:

  • name (Text) –

    Required. Name of the experiment, unique in the Plan.

  • setting (Text | None) –

    Default None. Readout setting label of a direct experiment. A batch experiment takes it from the batch.

  • observation (ObservationSpec | None) –

    Default None. The readout (ObservationSpec) of a direct experiment.

  • readout (ReadoutDetails | None) –

    Default None. The Method's readout details of a batch experiment (ReadoutDetails).

  • batch (Text | None) –

    Default None. Definition id of the Program's MeasurementBatch, or None for a direct experiment.

  • setting_index (Count | None) –

    Default None. Index of the setting in that batch.

Raises:

  • ValueError –

    If a direct experiment lacks setting or observation or has readout, if a batch experiment has setting or observation or lacks readout, or if only one of batch and setting_index is given.

ObservationSpec

Bases: ReadoutDetails

The readout of one experiment: what is measured and with how many shots.

A Method's planning step builds it with keyword arguments, for example ObservationSpec(kind="counts", shots=1000), as Run your own circuit shows. kind is required, and the other fields below have defaults. Bit and qubit positions count from the least significant. Each kind accepts only the fields it uses:

  • counts: 1 <= shots <= 2**63 - 1 (the int64 count range), no labels, qubits or position, and the unconditional population. The Program's classical bits fix the measured bits.
  • probabilities: distinct qubits for the marginal, with no labels, shots or position.
  • pauli_expectation: distinct Pauli labels over I, X, Y and Z and an optional position, with no qubits or shots.
  • host_scalars: distinct labels naming the statistics, with no qubits, shots or position, and the unconditional population.
  • amplitudes: an amplitudes declaration, with no labels, qubits, shots or position, on the unconditional final state.
  • estimated_observable: an estimate, with no amplitudes, labels, qubits, shots or position, on the unconditional final state.
  • trajectory: at least one point in positions, zero shots and the unconditional population, with the single-readout fields empty. An empty request is algebraic work without a measurement, so it declares no experiment.

Only a trajectory has positions. Pauli expectations are read before the logical instruction at position, and None means the end. Counts use the Program's measurements in the computational basis, and probability marginals are read after the final measurements are removed. No full state is saved.

An exact trajectory declares readouts that do not disturb one coherent evolution, at several points of it. Its shot count is zero. Each result is kept with its point ID and its label or outcome, and the saved values are reductions of the simulator state at those points. Sampled readouts describe the Program's measurements and use their declared positive shot counts. The readouts of a trajectory are deterministic, and its zero shots do not allow measurement-conditioned, reset, postselected, noisy or outcome-dependent evolution. Host, amplitude, sampled and provider-estimate readouts keep their own meanings.

Readout requests are combined only when they have the same body, position, readout view (a basis change applied for the readout and then undone), readout kind and population. Two requests share one saved value only when they also name the same label, outcome or amplitude declaration, or the same reducer with the same parameters. A union of distinct requested labels still holds one item per distinct label, and every association of a point with its result is kept when a value is shared. The limit check counts the items of every declared point, N_items = sum_k L_k with L_k the number of items of point k.

Attributes:

  • kind (Literal['pauli_expectation', 'counts', 'probabilities', 'host_scalars', 'amplitudes', 'estimated_observable', 'trajectory']) –

    Required. "pauli_expectation", "counts", "probabilities", "host_scalars", "amplitudes", "estimated_observable" or "trajectory".

  • shots (Count) –

    Default 0. Positive number of shots for counts, and zero for the readouts without a prescribed number of shots, a trajectory included.

  • amplitudes (AmplitudeReadout | None) –

    Default None. The amplitude output of the amplitudes kind (AmplitudeReadout).

  • estimate (ObservableEstimateSpec | None) –

    Default None. The weighted Pauli sum whose expectation a provider estimates, for the estimated_observable kind (ObservableEstimateSpec).

  • position (Count | None) –

    Default None, which means the end of the body. Number of bound logical operations before the readout point. Zero reads the initial state, and the body length reads the final state. The end is resolved before the circuit is prepared. Building the circuit keeps this boundary when it expands operations and, on a backend that runs readout views, inserts them there.

  • labels (tuple[Text, ...]) –

    Default (). Pauli or host-scalar labels, in the order of the returned values.

  • qubits (tuple[Count, ...]) –

    Default (). Measured or marginal qubit positions, least significant first.

  • population (Literal['unconditional', 'native_conditioned']) –

    Default "unconditional". "unconditional" or "native_conditioned", the measured shots that the readout covers.

  • padding (Text) –

    Default "no padding; all returned bit patterns belong to the declared registers". Meaning of any padding, and which returned coordinates belong to the system.

  • positions (tuple[ObservationPoint, ...]) –

    Default (). The points of a trajectory, in order. Each point names a boundary in the planned coherent body, its readout kind and its ordered labels or marginal qubits, and may name a readout view. The points share one preparation and measurement, and their order and payload sizes are part of the Plan.

Raises:

  • ValueError –

    If a field is given that the kind does not use, a field the kind needs is missing, trajectory point IDs repeat, or the point boundaries decrease.

point_observation

point_observation(point_id)

Return the single-point readout of the trajectory point point_id.

Pauli, probability and amplitude points map to the readout kinds of the same name, so their saved values keep those kinds' records and checks. A reduction point's readout is the single-point trajectory of that point, and its saved values are ReducedValues records.

Parameters:

  • point_id (str) –

    ID of a point in positions.

Returns:

Raises:

  • ValueError –

    If the trajectory has no such point.

point_observations

point_observations()

Return the single-point readout of every point, by point ID, in one pass over the points.

Returns:

  • readouts ( dict[str, ObservationSpec] ) –

    Each point's readout, as point_observation gives it.

point_readout_fields

point_readout_fields(point)

Return the fields of one point's single-point readout, without building an ObservationSpec.

point_observation builds its readout from these fields, so a byte bound of the stored readout can be computed from the same fields without building it. It takes the point object itself, so no ID lookup is needed. Pauli, probability and amplitude points take their kind, labels, qubits, amplitude declaration and the unconditional population, and a Pauli point also its position. Their point ID, readout view and non-Pauli position stay associated only through the preparation record, the point ID, the boundary and the content hash of the trajectory. A reduction point's readout is the single-point trajectory of that entire point, so it copies the point's ID, declared position, reducer, parameters and readout view. Every other field keeps its default.

Parameters:

  • point (ObservationPoint) –

    A point of a trajectory.

Returns:

  • fields ( dict ) –

    Keyword arguments of ObservationSpec.

reject_unsupported_schedule

reject_unsupported_schedule(backend)

Raise if backend cannot run this multi-point schedule, before any circuit is built or submitted.

A backend calls it to keep its supported single-point readouts and reject the multi-point schedules, readout views and reductions that it does not run, before building or submitting a circuit. The error names the backend and the feature.

Parameters:

  • backend (str) –

    Name of the backend, used in the error message.

Raises:

  • ValueError –

    If this readout is a trajectory.

unsupported_schedule

unsupported_schedule()

Describe this readout's multi-point schedule, readout views and reductions, or return None.

Backends name this description when they reject a schedule they do not run. A single-point readout returns None.

Returns:

  • description ( str | None ) –

    The description.

ReductionContext

ReductionContext(prepared_id: str, probability_window: float | None, probability_window_exclusions: tuple[str, ...] | None, state_error: float | None = None, state_error_reason: str | None = None, modulo_phase_state_error: float | None = None)

What a reduction of a saved state knows about the preparation that produced the state.

A reducer registered with receives_context=True receives it as the keyword context when it runs. Its fields are read-only values of the preparation record (PreparedArtifact) that produced the saved state.

A saved-state reduction receives a native error estimate modulo the global phase, with its conditions, when its declared outputs do not change under that phase. A state uncertainty defined with the phase is unavailable unless a separate phase-error model supplies it, and the context reports that reason. A host correction of the phase adds its finite multiplication and modulus error to every user of the corrected array. Projected mass checks can use the modulo-phase estimate even when other diagnostics of the same reducer depend on the phase. If an assumption of the native estimate remains unavailable, they use the probability window, propagated through the phase correction, and report the original exclusions.

The preparation record's state error (PreparedArtifact.state_error) bounds the computed state only up to one common global phase. It does not bound the exact prefix phase, the summation that accumulates the prefix phase, the subtraction that forms the correction angle, or an amplitude defined with its phase, and adding a host term to it gives no finite estimate for such a quantity. A saved state used by a phase-sensitive and a phase-invariant reducer is corrected once, and both see the same array and the same host error bound of the preparation record (PreparedArtifact.statevector_roundoff). The phase-invariant reducer therefore includes the error of the phase product, even though its own registration did not request the phase correction.

Attributes:

  • prepared_id (str) –

    Content hash of the preparation record that produced the saved state.

  • probability_window (float | None) –

    The preparation record's saved_state_probability_window, its probability window propagated through the host correction of the saved state, or None when that correction was not assessed, which gives no finite budget for a mass check. It does not bound a host contraction of the saved state, which has its own accumulated error.

  • probability_window_exclusions (tuple[str, ...] | None) –

    The preparation record's probability_window_exclusions, the operations, readout path, simulator version or non-default compiler optimization level whose effect the window does not bound. Empty when the whole execution lies inside the window, None when not assessed.

  • state_error (float | None) –

    The state error bound that matches the reducer's declared phase behavior. For a reducer registered phase_invariant it is modulo_phase_state_error. For any other reducer it is None, since a bound defined with the phase is unavailable. It is also None when an assumption of the native estimate remains unavailable. A reducer uses its probability window when this value is unavailable, and the original exclusions stay available in probability_window_exclusions.

  • state_error_reason (str | None) –

    Why state_error is None. For a reducer that is not registered phase invariant it is the reason a bound defined with the phase is unavailable, and otherwise the preparation record's native or host reason. None when state_error is available.

  • modulo_phase_state_error (float | None) –

    The preparation record's saved_state_error after resolving the labels that the reducer declares, a distance modulo one common global phase that includes the error of the host phase product, or None when an assumption of the native estimate or the host assessment is unavailable. A phase-sensitive reducer may use it only for outputs shown separately to be phase invariant, as the projected mass checks do.

registered_reducer

registered_reducer(name)

Return the reducer registered under name, or None when there is none.

On a miss, each module of BUILTIN_REDUCER_MODULES is imported (an already imported module is not imported again, and a module registers its reducers once, at import), and READOUT_REDUCERS is read again.

Parameters:

  • name (str) –

    The reducer's registered name.

Returns:

  • reducer ( Reducer | None ) –

    The registered reducer, with its shape, work and execution functions.

ObservationChunk

Bases: Record

The statistics of one measurement, or of one point of a trajectory, as stored with a Run or Result.

data.observations.chunks holds them, and a Method's analyze reads them, as Run your own circuit shows. A chunk keeps the sufficient statistics of its measurement, never one record per shot. Chunks of different attempts stay distinct even when their values are equal. Their identifiers record where the data came from and are not evidence that random measurements are independent.

Read probabilities and counts with histogram(), whose layout Histogram states, and build such a chunk with from_histogram. Counts are stored as JSON CountBin records. Every count, the exact total and the requested shots are at most 2**63 - 1, the int64 maximum of the count weights that the reader returns, and a chunk outside that range is rejected. A probability marginal stores its values in binary arrays. The chunk holds one ProbabilityArrays record with the array manifests and the summary values computed when the arrays were saved. The arrays live in the array store of the Run or Result that holds the chunk. A chunk keeps a private reference to that store, which is not a field. Saving the arrays, reopening a Run (load_run), loading a Result (load_result) and the chunk's own revise and copies set or carry it, and histogram() reads the arrays through it on first use, once per payload for the store's lifetime. A chunk rebuilt from JSON in any other way has no such reference, and its histogram() raises an error that names the loader to use.

A trajectory measurement stores one chunk per observation point. The chunk names its point and resolved boundary, so a saved value maps to its body, point and preparation record after reloading. A trajectory stores one full declaration in its preparation record and one row per point, with only that point's readout declaration and the content hash of the shared declaration on the row. Validating the preparation record and indexing the points visit the schedule once, each chunk validates its own declaration and values, and readout() returns the stored single-point readout. Storage and validation are linear in the total accepted declarations and payloads, with no per-point copy or rescan of the full schedule. The single-point readout is ObservationSpec.point_observation of the point, and trajectory_id is the content hash of the full declaration. Joining the chunk to its preparation record, in validate_unit_bound and when the Run records the chunk, checks both. Point chunks share their measurement's completion, preparation, shots and native work. The chunks of one measurement share its run, attempt and job, and differ in chunk. A missing point makes the quantity that depends on it incomplete. It never causes the shared prefix to be run again in analysis or loading.

Attributes:

  • run_id (Text) –

    Identifier of the Run that made the measurement.

  • execution (Literal['quantum_circuit', 'host_kernel']) –

    "quantum_circuit" or "host_kernel", the kind of computation that produced the data.

  • plan_id (ContentID) –

    Content hash of the Plan.

  • realization_id (ContentID) –

    Content hash of the experiment's concrete parameter values.

  • prepared_id (ContentID) –

    Content hash of the preparation record of the circuit or host computation that was run.

  • experiment (Text) –

    Name of the experiment in the Plan.

  • setting (Text) –

    The readout or batch setting.

  • bindings (tuple[Binding, ...]) –

    The experiment's parameter values, in order.

  • quantum_layout (tuple[RegisterMap, ...]) –

    Order of the quantum registers, which fixes how outcome coordinates are read.

  • classical_layout (tuple[RegisterMap, ...]) –

    Order of the classical registers, which fixes how count labels are read.

  • attempt (Text) –

    Identifier of the attempt that was set aside for this measurement.

  • job (Text) –

    Identifier of the job that produced the data, not of a later reduction.

  • chunk (Text) –

    Position of this part within that job.

  • observation (ObservationSpec) –

    The readout against which the returned statistics are checked. For a trajectory point, it is that point's single-point readout.

  • population (Literal['unconditional', 'native_conditioned', 'unknown']) –

    "unconditional", "native_conditioned" or "unknown", which shots the statistics cover.

  • returned_shots (Count | None) –

    Total of the returned counts, or None when no shot total is available.

  • trajectories (Count | None) –

    Number of trajectories, or None when unavailable or not applicable.

  • values (tuple[Statistic, ...]) –

    Sufficient statistics, each kept with its original label and its physical normalization. Probabilities have one ProbabilityArrays record, and counts one CountBin per stored outcome. Read both with histogram().

  • source (Source) –

    The backend or host code that produced the data (Source).

  • selected_kernel_id (ContentID | None) –

    Content hash of the host computation's declaration, or None for a circuit.

  • physical_scale (PhysicalScale | None) –

    Positive factor that restores physical magnitude to this chunk's unit-normalized data, or None. Its meaning belongs to the Method. For LCHS and the QLS qsvt_inverse solver it is the norm of the output vector, and analysis multiplies the unit solution direction by it. For Expectation, Lanczos and QPE it is the norm of the supplied input state. Expectation's physical quadratic form uses it, and the eigenvalue Methods record it with the input, since an energy does not depend on the state's norm. QHD, FixedGCIM and ADAPT host chunks carry None, because their scalars need no recovery, a QLS shortcut chunk carries None because the shortcut recovers no physical norm, and quantum circuit chunks other than amplitude readout carry None.

  • physical_scale_unavailable (Text | None) –

    Why physical_scale is None, because the scale is unavailable or no recovery applies. Host and amplitude chunks set exactly one of the two fields.

  • artifacts (tuple[ArtifactManifest, ...]) –

    Manifests of the arrays saved from this measurement.

  • applications (tuple[KernelApplication, ...]) –

    Records of the host operator applications.

  • unavailable (tuple[UnavailableOutput, ...]) –

    Named outputs that could not be produced.

  • point (Text | None) –

    ID of the trajectory point whose values this chunk holds, or None for a readout without a point schedule.

  • boundary (Count | None) –

    Resolved boundary of that point in the planned body, or None.

  • trajectory_id (ContentID | None) –

    Content hash of the trajectory declaration that the point belongs to, held by the preparation record, or None.

acquisition_key

acquisition_key

(run_id, attempt, job, chunk), which identifies the data of one measurement.

A Run stores, deduplicates and joins observations under this key. Two chunks with equal values but different keys are different measurements, except that the point chunks of one trajectory measurement share its run, attempt and job and differ only in chunk.

declares_readout_of

declares_readout_of(receipt)

Return whether this chunk holds the readout that its preparation record declares.

A point chunk holds the single-point readout of its point in the preparation record's trajectory, whose content hash is its trajectory_id. Any other chunk holds the record's readout itself. The record's point lookup is indexed, so K point chunks join in O(K) lookups.

Parameters:

Returns:

  • declared ( bool ) –

    Whether the readouts match.

from_histogram

from_histogram(outcomes, /, **fields)

Build a probabilities or counts chunk from its outcomes.

Validation is that of every other construction path, including the count range 0 to 2**63 - 1. A probability chunk keeps its arrays in memory, with manifests that carry the digest of their bytes. Its stored encoding, dense or sparse, and its sorted order are those of every saved probability readout.

Parameters:

  • outcomes (Mapping | tuple) –

    Either a mapping from bit-string key to weight, with keys spelled as the chunk stores them (rightmost character bit 0, no register separators), or a pair (indices, weights) in the layout of Histogram: 1-D indices for a width of at most 64 or (entries, words) packed indices for every width, integer counts or float64 probabilities. Empty arrays of shape (0,) or (0, words) describe an empty chunk whatever their dtype.

  • **fields (object, default: {} ) –

    The other ObservationChunk fields except values. observation selects counts or probabilities. The width is the number of its qubits (probabilities) or of the bits of classical_layout (counts).

Raises:

  • TypeError –

    When values is also supplied.

  • ValueError –

    For another readout kind, indices outside the width or in another layout, weights of another type or length, or any check of the chunk itself.

histogram

histogram()

Return the outcomes of this probabilities or counts chunk in the Histogram layout.

The chunk builds its Histogram on the first call and returns the same read-only object afterwards. The slot that holds it is not a field, so equality, identity and serialization never see it. A probability chunk rebuilt from stored JSON returns a Histogram whose width and entries come from its summaries; its arrays are read through the artifact store of its Run or Result on the first access to the weights or indices, once per payload for the store's lifetime, with no recheck of the values or summaries.

Raises:

  • ValueError –

    For any other readout kind, or for a probability chunk that has neither its arrays nor a store to read them from.

readout

readout()

The readout whose statistics this chunk holds, its observation.

For a trajectory point chunk that is the point's one-point readout, which the chunk stores, so nothing is rebuilt.

validate_unit_bound

validate_unit_bound(receipt)

Check that exact probabilities, Pauli expectations and branch masses exceed one only within the roundoff window of the executed circuit.

The window follows the native operation count of the preparation record, so this check joins the chunk to its own preparation record. Alone, the chunk accepts nonnegative probabilities and masses and finite expectations. Counts and host scalars have no roundoff endpoint here.

The window is derived from the preparation record rather than stored on the chunk. A stored copy would change the record format and add derived data that every reader would have to check against its record. The cost is that each place where a new chunk meets its record must call this method. The shared places are the decoding of backend output and the validation of a standalone Result before it is saved. Reopening a Run or loading a Result reads chunks that passed one of them, and it does not call this method again. A Method's Result validation may add its own calls, as QLS does for its masses. A new producer of chunks that bypasses both places must add the call. Engineering constants defines the window in its exact_probability_window paragraph.

A trajectory point chunk also joins its record's trajectory declaration: the same trajectory_id, the declared point's single-point readout and its resolved boundary. A reduction point has no endpoint here, because host contractions of saved states have their own accumulated error, which the record's probability and Pauli readout term does not bound. Amplitude-derived masses use the record's saved_state_probability_window, which includes the host correction of the saved state, and are checked for nonnegativity only when that correction was not assessed.

Parameters:

Raises:

  • ValueError –

    If the record is not this chunk's, a point chunk does not match its declared point or boundary, or a value exceeds its endpoint by more than the window.

Histogram

Histogram(width, integers, weights)

Outcome indices and weights of one probabilities or counts chunk.

ObservationChunk.histogram() returns it. Code that reads observations can rely on the layout below. All arrays are read-only.

  • width: the readout width w, the number of observed qubits (probabilities) or of classical bits over the whole classical layout (counts).
  • entries: the number of stored entries, counting any stored zero weight, so it is not the number of nonzero weights.
  • weights: a 1-D array with one weight per entry, float64 for probabilities and int64 for counts.
  • indices(): for w <= 64, a 1-D uint64 array with one outcome index per entry. Bit 0 of an index is the first observed qubit (probabilities) or classical bit 0 (counts), which is the rightmost character of the chunk's bit-string key. For w > 64 it raises ValueError naming the width.
  • packed_indices(): for every w, a 2-D uint64 array of shape (entries, words) with words = max(1, ceil(w/64)). Word 0 holds the least significant 64 bits and the padding bits above w are zero.
  • index_list(): the outcome indices as Python integers, for every w.

Entries keep the order in which the chunk stores them; nothing is sorted. A probability chunk stores a dense marginal by outcome position, every outcome including exact zeros, or a sparse marginal with strictly increasing indices of its nonzero values (ProbabilityArrays), so its entries are in increasing index order; a dense marginal's indices are formed when they are first requested. For a histogram obtained from a validated count chunk, every weight and the exact total are in [0, 2**63 - 1], and the total equals returned_shots and does not exceed the requested shots. Because the weights are nonnegative, an int64 sum of this single chunk's weights cannot overflow. Totals combined across acquisitions require an overflow-safe accumulation. An empty chunk gives indices() of shape (0,) and packed_indices() of shape (0, words).

Attributes:

  • width –

    Readout width w.

  • entries –

    Number of stored entries.

  • weights –

    Read-only 1-D float64 probabilities or int64 counts.

index_list

index_list()

Return the outcome indices as Python integers, for every width.

indices

indices()

Return the 1-D uint64 outcome indices; the width must be at most 64.

packed_indices

packed_indices()

Return the (entries, words) uint64 outcome indices, word 0 least significant.

PreparedArtifact

Bases: Record

The preparation record of one circuit or host computation: what was built, for which target, and its roundoff bounds.

run.data.receipts and result.data.receipts hold one per preparation. It describes the prepared circuit and holds no executable bytes. snapshot names a circuit built in this process and is not a verified file digest. target and compiler are recorded when the circuit is prepared. The concrete parameter values (realization) survive failed attempts and the reopening of a saved Run, so recovering them needs no completed observation and no guess of a default point. Reading this record loads no circuit data. The fields below are read-only.

Attributes:

  • execution (Literal['quantum_circuit', 'host_kernel']) –

    "quantum_circuit" or "host_kernel", the kind of preparation.

  • plan_id (ContentID) –

    Content hash of the Plan.

  • realization_id (ContentID) –

    Content hash of realization.

  • realization (Realization) –

    The experiment and its concrete parameter values, kept even before any result exists.

  • construction_id (ContentID) –

    Content hash of the construction used for this preparation.

  • snapshot (Text) –

    Name of the circuit built in this process, not a digest of its bytes.

  • target (Source) –

    The backend target (Source) when the circuit was prepared.

  • compiler (Source) –

    The compiler or preparation code (Source).

  • runtime (RuntimeOptions) –

    The runtime seed and backend preparation options in effect.

  • observation (ObservationSpec) –

    The readout (ObservationSpec).

  • quantum_layout (tuple[RegisterMap, ...]) –

    Layout of the logical quantum registers.

  • classical_layout (tuple[RegisterMap, ...]) –

    Layout of the logical classical registers.

  • native_basis (tuple[Text, ...]) –

    The backend's gate names after preparation.

  • environment (tuple[Source, ...]) –

    Versions of the packages used by the preparation (Source records).

  • preparation_time (Text) –

    Time of the preparation.

  • construction_work_reserved (Count) –

    Circuit construction work counted before execution, in work units.

  • logical (LogicalPreparationReceipt | None) –

    Record of how the logical circuit was built, or None for a host-only preparation.

  • native_operations (Count | None) –

    Prepared operation count, or None when unavailable. For a coherent statevector readout on Aer, a trajectory included, it counts the native evolution operations that execute, including every executed forward and inverse view operation, and no save instruction: a save evaluates or copies the current state and inserts no state error into the continuing state. It is not multiplied by the number of saved labels or points, and one whole-trajectory count gives a conservative window for every point. On Aer, a body with control flow and sampled counts count every instruction of the prepared native circuit. Other adapters state their own count.

  • host_preparation_work_reserved (Count) –

    Host setup work counted for this preparation.

  • selected_kernel_id (ContentID | None) –

    Content hash of the host computation's declaration, or None for a circuit.

  • transformation (Text) –

    Description of how the planned circuit was turned into the backend's circuit.

  • population (Literal['unconditional', 'native_conditioned', 'unknown']) –

    "unconditional", "native_conditioned" or "unknown", which shots the measured counts cover.

  • payload (PayloadRef | None) –

    Where the backend's circuit bytes are saved, or None. It holds no bytes itself.

  • native_quantum_layout (tuple[RegisterMap, ...]) –

    Layout of the compiled quantum registers.

  • native_classical_layout (tuple[RegisterMap, ...]) –

    Layout of the compiled classical registers.

  • logical_to_native (tuple[Count, ...]) –

    The compiled wire of each logical wire, in order.

  • backend_configuration_id (ContentID | None) –

    Content hash of the backend configuration, or None for host execution.

  • counts_sampling (CountsSampling | None) –

    How the counts are sampled (CountsSampling), or None for other readouts.

  • provider_options_json (Text | None) –

    The provider settings in effect, saved without credentials.

  • probability_window_exclusions (tuple[Text, ...] | None) –

    Labels of the native operations, readout path, simulator version or non-default compiler optimization level whose effect the derivation of probability_window does not bound. An empty tuple means the whole execution lies inside it. None means the preparing backend did not assess it.

  • body_length (Count | None) –

    Number of bound logical operations of the planned body, the largest trajectory boundary, recorded for a trajectory, and None otherwise.

  • boundaries (tuple[Count, ...]) –

    Resolved boundary of each trajectory point in declaration order, with the end-position shorthand resolved before native preparation; empty for other readouts.

  • template_seed (Count | None) –

    Seed of the per-construction native template that the backend prepared this circuit from, or None when the backend used no template.

  • statevector_roundoff (tuple[Nonnegative, Nonnegative] | None) –

    The bound (t, e) on the error of the host phase correction of this execution's saved statevectors, the componentwise maxima over the record's saved states. It is included in the error of every user of those statevectors (saved_state_error and saved_state_probability_window). The pair (t, e) bounds the output phase product on saved statevectors. (0.0, 0.0) denotes an assessed zero-error operation, including no product or multiplication by the represented factor (1.0, ±0.0) under the host arithmetic model. None means the host correction was not assessed.

probability_window

probability_window: float

The accepted binary64 roundoff between one and the total of an exact probability population of this execution.

It is max(1e-12, (c*G + 2**(n+1) + 10)*u) for G native operations, the circuit width n, the executing simulator's per-instruction constant c and u = 2**-53, as Engineering constants derives. A target without a derived constant of its own uses Aer's, the larger one. Host and unknown counts keep the fixed floor 1e-12.

saved_state_probability_window

saved_state_probability_window

probability_window propagated through the host correction of a saved state, or None.

omega_saved = omega + (2t + t**2)(1 + omega) + 2(1 + t)(1 + omega) e + e**2 with (t, e) the record's statevector_roundoff. An unassessed correction gives None, not the uncorrected window, so it yields no finite mass-check budget.

saved_state_error

saved_state_error(resolved=())

Return (delta_saved, reason): state_error(resolved) after the host correction of a saved state.

delta_saved = delta + t (1 + delta) + e with (t, e) the record's statevector_roundoff. Like state_error it is a distance modulo one common global phase, conditional on the native first-order model. It returns the native unavailable reason unchanged when delta is unavailable, and an unavailable reason for the missing premise when the host correction was not assessed. Every consumer of a saved statevector uses it; direct native probability and Pauli saves keep state_error, since their buffers undergo no host correction.

state_error

state_error(resolved=())

Return (delta, None) for this execution's final-state budget, or (None, reason).

delta is native_state_error of the native operation count with the target's derived per-instruction constant, a first-order bound on ||psi_hat - exp(i phi) psi||_2 against the unitary native circuit. It describes distance modulo one common global phase. It does not bound the exact prefix phase, the summation that accumulates the prefix phase of a saved state, the subtraction forming its correction angle, or a phase-defined amplitude. The users of a saved statevector use saved_state_error. It exists only when the derivation covers the whole execution, that is, for a circuit on a target with a derived constant, a known operation count and assessed probability_window_exclusions that are all in resolved, the labels whose effect the caller's own readout bounds. Unlike probability_window, an unknown count or target gets no default constant and no floor. The budget enters the bound on differences of point probabilities, which QHD uses for the tie window of its most probable point. The Aer constant that probability_window takes for an unknown target has no derivation for that target, and the 1e-12 floor that it keeps for an unknown count is an input convention for a population total, not a derived bound, so neither can stand in for delta.

Save and restore a method's data

A Method whose Runs or Results are saved implements save_archive(plan, files) and load_archive(saved, files) and names its Result class in result_type. Both hooks receive an ArchiveFiles object, save_archive reads the bound blocks from plan.blocks, and When the archive hooks are required shows them for a small Method.

ArchiveFiles

ArchiveFiles(path, max_bytes)

The folder of a saved Result or Run, as passed to a Method's save_archive and load_archive hooks.

A Method author writes and reads the Method's data through the files argument of those hooks, as Add a Method and Run your own circuit show, rather than through a serializer of its own. Its operations keep each input in its own representation and count the written bytes against the folder's limit. Files have readable names, are created new and are never overwritten. An array or circuit used by several parts is written once per save and read once per load. Arrays load as read-only NumPy memory maps and are neither normalized nor content-hashed. The headers of input arrays are checked against their representation, dimensions and declared encoding. These checks do not validate every value or restore the digest that the input had when it was first accepted. Keep the folder available while using the restored Plan. Circuits use Qiskit's public QPY format. The memory and CPU use of the SDKs is unknown.

Open the folder path, with a limit of max_bytes on the bytes written.

NWQLib opens the folder and passes it to the hooks, so Method code does not build one.

Parameters:

  • path (str | PathLike) –

    The folder.

  • max_bytes (int | None) –

    Positive limit on the bytes written, or None for a folder without a limit of its own.

Raises:

  • ValueError –

    If max_bytes is neither a positive integer nor None.

write_plan

write_plan(plan)

Return the Plan's JSON description.

Its Problem, Method and output entries are descriptions only. read_plan replaces them with the objects that their own readers restored.

Parameters:

  • plan (Plan) –

    The Plan.

Returns:

  • description ( dict ) –

    The Plan's JSON description.

read_plan

read_plan(data, *, problem, method, output, reconstruction=None)

Rebuild a Plan from its JSON description and the Problem, Method and output already restored.

Parameters:

  • data (dict) –

    The description that write_plan returned.

  • problem (ProblemRecord) –

    The restored Problem.

  • method (Method) –

    The restored Method.

  • output (OutputRecord) –

    The restored output.

  • reconstruction (object | None, default: None ) –

    The Method's restored interpretation data, which replaces the saved one when given.

Returns:

  • plan ( Plan ) –

    The Plan. A Method that binds circuit blocks binds them with plan._bind(...) before returning the Plan from load_archive.

read_problem

read_problem(data)

Rebuild a built-in Problem from its saved description, with its inputs restored.

The Problem class is chosen from a fixed table of the built-in kinds, so saved text never selects an arbitrary class.

Parameters:

  • data (dict) –

    The description that write_problem returned.

Returns:

  • problem ( ProblemRecord ) –

    The Problem.

read_output

read_output(data)

Rebuild a built-in output from its saved description.

The output class is chosen from a fixed table of the built-in kinds, as in read_problem.

Parameters:

  • data (dict) –

    The description that write_output returned.

Returns:

  • output ( OutputRecord ) –

    The output.

write_state

write_state(name, state)

Save a state input, its preparation and its circuit, and return its description.

The vector and its normalized direction are stored as given, without normalizing them again, so scale and phase survive exactly. When the two arrays have the same dtype, shape and bytes (a unit-norm vector is its own direction), one array is written and the direction names its file. The comparison is one pass over the entries.

Parameters:

  • name (str) –

    Prefix of the file names.

  • state (StateInput) –

    The state input.

Returns:

  • description ( dict ) –

    JSON description that read_state reads.

write_operator

write_operator(name, operator)

Save an operator in its own representation, never a converted one, and return its description.

Dense, CSR, CSC, Pauli and periodic-stencil inputs keep their arrays or parameters, so saving never turns a sparse or Pauli operator into a dense matrix. A declaration without data is saved as a declaration.

Parameters:

  • name (str) –

    Prefix of the file names.

  • operator (OperatorInput) –

    The operator.

Returns:

  • description ( dict ) –

    JSON description that read_operator reads.

read_path

read_path(name)

Register a file that the Method's saved data depends on, and return its path.

A load_archive hook that restores cached data must call it for every file it refers to, including files whose contents it reads only later. Registration reads the file's metadata only, so a missing file raises FileNotFoundError here, and it keeps the file from being removed as unused when the Run is reopened. A folder opened with a limit counts the file's size against it, and a folder opened without one (max_bytes=None) counts nothing.

Parameters:

  • name (str) –

    The file name, without a directory part.

Returns:

  • path ( Path ) –

    The file's path.

blocks

blocks

The live circuit blocks that the Method bound to this Plan with _bind.

A Method's archive hook saves them, as Run your own circuit shows.

write_blocks

write_blocks(blocks, files)

Return the saved form of a Method's selected blocks, for its save_archive hook.

Call it in save_archive(plan, files) with the archive object files that the hook receives, and store the returned dict with the saved Plan. Each block is written once, base blocks before the blocks that transform them. Only the built-in preparation, Pauli SELECT and readout, reflection and transformed blocks can be saved. A signed Pauli SELECT or readout saves its operator and amplitude array only, because loading derives the coefficients from the operator, and blocks that share an operator or amplitude array write it once.

The selection limit of select_signed_pauli does not bound the whole archive or the live packed operator. For m terms on q qubits, P = 2**a >= m padded amplitudes and w = ceil(q/64), the packed operator holds B_op = 16mw + 16m bytes of numerical data and the one shared amplitude file adds 8P, so

B_archive,data = 16mw + 16m + 8P,

plus four NPY headers, at most 256 bytes each for these fixed-dtype rank-one and rank-two arrays, and the graph and manifest JSON. The NumPy NPY writer (v2.5.2) writes a contiguous array with at most one data chunk of min(array.nbytes, 2**24) bytes, and an array that must be copied because it is not contiguous needs a second such buffer. With contiguous packed and amplitude arrays, the numerical peak while writing is

B_held,other + B_op + 8m + 8P + min(max(8mw, 16m, 8P), 2**24) + H_archive,

where H_archive, the graph serialization and writer bookkeeping, is not fixed for an arbitrary block graph. The peak of a save is the larger of this and the selection peak, counting shared operator bytes once. A transport that buffers a whole archive needs its own allowance. This function takes no byte limit, and the archive's byte limits apply to each file it writes.

Parameters:

  • blocks (Iterable[SelectedBlock]) –

    The blocks to save, usually the Plan's bound blocks.

  • files (ArchiveFiles) –

    The archive object of the hook.

Returns:

  • saved ( dict ) –

    The saved block graph, with its format, nodes and roots, for read_blocks.

read_blocks

read_blocks(data, records, files)

Restore the blocks saved by write_blocks, for a Method's load_archive hook.

A saved kind selects one constructor from a fixed table of built-in block kinds, so loading never imports or calls code named in the archive. A preparation is checked against its reloaded state input before it is bound, and a transformed block is bound again to its restored base. A signed Pauli SELECT or readout derives its coefficients from the restored operator with the expression selection uses, so alpha, the coefficients and the PREP amplitudes equal those before saving, and a SELECT and its readout share one restored operator.

Parameters:

  • data (dict) –

    The saved block graph that write_blocks returned.

  • records (Sequence[SelectedDefinition]) –

    The selected definitions that the saved root blocks refer to by position. The reference Method passes plan.construction.selections.

  • files (ArchiveFiles) –

    The archive object of the hook.

Returns:

  • blocks ( tuple[SelectedBlock, ...] ) –

    The restored blocks, in the saved order.

Raises:

  • ValueError –

    If the saved format is not the current block format, or a saved preparation does not match its input.

InputRef

Bases: Record

A declaration of an input and of how it is accessed, without its data.

It names the input and its representation. It does not build an oracle or a circuit for the input. Eigenproblem.subspace takes one to name an explicitly defined subspace.

Attributes:

  • identity (Text) –

    Required. Name of the input.

  • representation (Text) –

    Required. How the input is represented, for example "circuit".

  • source (Source) –

    Required. The Source of the input.