Skip to content

Commit 554e661

Browse files
Add release notes for manual Var and Store (#12421)
* Add release notes for manual `Var` and `Store` This adds the release notes and updates some small portions of documentation that were previously missed surrounding the new manual `Var` storage locations. This includes documenting all new keyword arguments to methods, upgrade instructions for providers, and adding the `Var.new` method to the documentation, which was previously erroneously omitted. * Fix Sphinx typo * Fix another Sphinx typo * Move QPY version bump to upgrade * Unify base release note * Reword providers upgrade note Co-authored-by: Matthew Treinish <mtreinish@kortar.org> --------- Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
1 parent 72ad545 commit 554e661

File tree

4 files changed

+174
-2
lines changed

4 files changed

+174
-2
lines changed

qiskit/circuit/classical/expr/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
real-time variable, or a wrapper around a :class:`.Clbit` or :class:`.ClassicalRegister`.
4444
4545
.. autoclass:: Var
46-
:members: var, name
46+
:members: var, name, new
4747
4848
Similarly, literals used in expressions (such as integers) should be lifted to :class:`Value` nodes
4949
with associated types.

qiskit/providers/__init__.py

+38-1
Original file line numberDiff line numberDiff line change
@@ -452,8 +452,45 @@ def get_translation_stage_plugin(self):
452452
efficient output on ``Mybackend`` the transpiler will be able to perform these
453453
custom steps without any manual user input.
454454
455+
.. _providers-guide-real-time-variables:
456+
457+
Real-time variables
458+
^^^^^^^^^^^^^^^^^^^
459+
460+
The transpiler will automatically handle real-time typed classical variables (see
461+
:mod:`qiskit.circuit.classical`) and treat the :class:`.Store` instruction as a built-in
462+
"directive", similar to :class:`.Barrier`. No special handling from backends is necessary to permit
463+
this.
464+
465+
If your backend is *unable* to handle classical variables and storage, we recommend that you comment
466+
on this in your documentation, and insert a check into your :meth:`~.BackendV2.run` method (see
467+
:ref:`providers-guide-backend-run`) to eagerly reject circuits containing them. You can examine
468+
:attr:`.QuantumCircuit.num_vars` for the presence of variables at the top level. If you accept
469+
:ref:`control-flow operations <circuit-control-flow-repr>`, you might need to recursively search the
470+
internal :attr:`~.ControlFlowOp.blocks` of each for scope-local variables with
471+
:attr:`.QuantumCircuit.num_declared_vars`.
472+
473+
For example, a function to check for the presence of any manual storage locations, or manual stores
474+
to memory::
475+
476+
from qiskit.circuit import Store, ControlFlowOp, QuantumCircuit
477+
478+
def has_realtime_logic(circuit: QuantumCircuit) -> bool:
479+
if circuit.num_vars:
480+
return True
481+
for instruction in circuit.data:
482+
if isinstance(instruction.operation, Store):
483+
return True
484+
elif isinstance(instruction.operation, ControlFlowOp):
485+
for block in instruction.operation.blocks:
486+
if has_realtime_logic(block):
487+
return True
488+
return False
489+
490+
.. _providers-guide-backend-run:
491+
455492
Backend.run Method
456-
--------------------
493+
------------------
457494
458495
Of key importance is the :meth:`~qiskit.providers.BackendV2.run` method, which
459496
is used to actually submit circuits to a device or simulator. The run method

releasenotes/notes/1.1/classical-store-e64ee1286219a862.yaml

+13
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,16 @@ features_circuits:
5454
Variables can be used wherever classical expressions (see :mod:`qiskit.circuit.classical.expr`)
5555
are valid. Currently this is the target expressions of control-flow operations, though we plan
5656
to expand this to gate parameters in the future, as the type and expression system are expanded.
57+
58+
See :ref:`circuit-repr-real-time-classical` for more discussion of these variables, and the
59+
associated data model.
60+
61+
These are supported throughout the transpiler, through QPY serialization (:mod:`qiskit.qpy`),
62+
OpenQASM 3 export (:mod:`qiskit.qasm3`), and have initial support through the circuit visualizers
63+
(see :meth:`.QuantumCircuit.draw`).
64+
65+
.. note::
66+
67+
The new classical variables and storage will take some time to become supported on hardware
68+
and simulator backends. They are not supported in the primitives interfaces
69+
(:mod:`qiskit.primitives`), but will likely inform those interfaces as they evolve.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
---
2+
features_circuits:
3+
- |
4+
:class:`.QuantumCircuit` has several new methods to work with and inspect manual :class:`.Var`
5+
variables.
6+
7+
See :ref:`circuit-real-time-methods` for more in-depth discussion on all of these.
8+
9+
The new methods are:
10+
11+
* :meth:`~.QuantumCircuit.add_var`
12+
* :meth:`~.QuantumCircuit.add_input`
13+
* :meth:`~.QuantumCircuit.add_capture`
14+
* :meth:`~.QuantumCircuit.add_uninitialized_var`
15+
* :meth:`~.QuantumCircuit.get_var`
16+
* :meth:`~.QuantumCircuit.has_var`
17+
* :meth:`~.QuantumCircuit.iter_vars`
18+
* :meth:`~.QuantumCircuit.iter_declared_vars`
19+
* :meth:`~.QuantumCircuit.iter_captured_vars`
20+
* :meth:`~.QuantumCircuit.iter_input_vars`
21+
* :meth:`~.QuantumCircuit.store`
22+
23+
In addition, there are several new dynamic attributes on :class:`.QuantumCircuit` surrounding
24+
these variables:
25+
26+
* :attr:`~.QuantumCircuit.num_vars`
27+
* :attr:`~.QuantumCircuit.num_input_vars`
28+
* :attr:`~.QuantumCircuit.num_captured_vars`
29+
* :attr:`~.QuantumCircuit.num_declared_vars`
30+
- |
31+
:class:`.ControlFlowOp` and its subclasses now have a :meth:`~.ControlFlowOp.iter_captured_vars`
32+
method, which will return an iterator over the unique variables captured in any of its immediate
33+
blocks.
34+
- |
35+
:class:`.DAGCircuit` has several new methods to work with and inspect manual :class:`.Var`
36+
variables. These are largely equivalent to their :class:`.QuantumCircuit` counterparts, except
37+
that the :class:`.DAGCircuit` ones are optimized for programmatic access with already defined
38+
objects, while the :class:`.QuantumCircuit` methods are more focussed on interactive human use.
39+
40+
The new methods are:
41+
42+
* :meth:`~.DAGCircuit.add_input_var`
43+
* :meth:`~.DAGCircuit.add_captured_var`
44+
* :meth:`~.DAGCircuit.add_declared_var`
45+
* :meth:`~.DAGCircuit.has_var`
46+
* :meth:`~.DAGCircuit.iter_vars`
47+
* :meth:`~.DAGCircuit.iter_declared_vars`
48+
* :meth:`~.DAGCircuit.iter_captured_vars`
49+
* :meth:`~.DAGCircuit.iter_input_vars`
50+
51+
There are also new public attributes:
52+
53+
* :attr:`~.DAGCircuit.num_vars`
54+
* :attr:`~.DAGCircuit.num_input_vars`
55+
* :attr:`~.DAGCircuit.num_captured_vars`
56+
* :attr:`~.DAGCircuit.num_declared_vars`
57+
- |
58+
:attr:`.DAGCircuit.wires` will now also contain any :class:`.Var` manual variables in the
59+
circuit as well, as these are also classical data flow.
60+
- |
61+
A new method, :meth:`.Var.new`, is added to manually construct a real-time classical variable
62+
that owns its memory.
63+
- |
64+
:meth:`.QuantumCircuit.compose` has two need keyword arguments, ``var_remap`` and ``inline_captures``
65+
to better support real-time classical variables.
66+
67+
``var_remap`` can be used to rewrite :class:`.Var` nodes in the circuit argument as its
68+
instructions are inlined onto the base circuit. This can be used to avoid naming conflicts.
69+
70+
``inline_captures`` can be set to ``True`` (defaults to ``False``) to link all :class:`.Var`
71+
nodes tracked as "captures" in the argument circuit with the same :class:`.Var` nodes in the
72+
base circuit, without attempting to redeclare the variables. This can be used, in combination
73+
with :meth:`.QuantumCircuit.copy_empty_like`'s ``vars_mode="captures"`` handling, to build up
74+
a circuit layer by layer, containing variables.
75+
- |
76+
:meth:`.DAGCircuit.compose` has a new keyword argument, ``inline_captures``, which can be set to
77+
``True`` to inline "captured" :class:`.Var` nodes on the argument circuit onto the base circuit
78+
without redeclaring them. In conjunction with the ``vars_mode="captures"`` option to several
79+
:class:`.DAGCircuit` methods, this can be used to combine DAGs that operate on the same variables.
80+
- |
81+
:meth:`.QuantumCircuit.copy_empty_like` and :meth:`.DAGCircuit.copy_empty_like` have a new
82+
keyword argument, ``vars_mode`` which controls how any memory-owning :class:`.Var` nodes are
83+
tracked in the output. By default (``"alike"``), the variables are declared in the same
84+
input/captured/local mode as the source. This can be set to ``"captures"`` to convert all
85+
variables to captures (useful with :meth:`~.QuantumCircuit.compose`) or ``"drop"`` to remove
86+
them.
87+
- |
88+
A new ``vars_mode`` keyword argument has been added to the :class:`.DAGCircuit` methods:
89+
90+
* :meth:`~.DAGCircuit.separable_circuits`
91+
* :meth:`~.DAGCircuit.layers`
92+
* :meth:`~.DAGCircuit.serial_layers`
93+
94+
which has the same meaning as it does for :meth:`~.DAGCircuit.copy_empty_like`.
95+
features_qasm:
96+
- |
97+
The OpenQASM 3 exporter supports manual-storage :class:`.Var` nodes on circuits.
98+
features_qpy:
99+
- |
100+
QPY (:mod:`qiskit.qpy`) format version 12 has been added, which includes support for memory-owning
101+
:class:`.Var` variables. See :ref:`qpy_version_12` for more detail on the format changes.
102+
features_visualization:
103+
- |
104+
The text and `Matplotlib <https://matplotlib.org>`__ circuit drawers (:meth:`.QuantumCircuit.draw`)
105+
have minimal support for displaying expressions involving manual real-time variables. The
106+
:class:`.Store` operation and the variable initializations are not yet supported; for large-scale
107+
dynamic circuits, we recommend using the OpenQASM 3 export capabilities (:func:`.qasm3.dumps`) to
108+
get a textual representation of a circuit.
109+
upgrade_qpy:
110+
- |
111+
The value of :attr:`qiskit.qpy.QPY_VERSION` is now 12. :attr:`.QPY_COMPATIBILITY_VERSION` is
112+
unchanged at 10.
113+
upgrade_providers:
114+
- |
115+
Implementations of :class:`.BackendV2` (and :class:`.BackendV1`) may desire to update their
116+
:meth:`~.BackendV2.run` methods to eagerly reject inputs containing typed
117+
classical variables (see :mod:`qiskit.circuit.classical`) and the :class:`.Store` instruction,
118+
if they do not have support for them. The new :class:`.Store` instruction is treated by the
119+
transpiler as an always-available "directive" (like :class:`.Barrier`); if your backends do not
120+
support this won't be caught by the :mod:`~qiskit.transpiler`.
121+
122+
See :ref:`providers-guide-real-time-variables` for more information.

0 commit comments

Comments
 (0)