qiskit/releasenotes/notes/0.22/operation-abstract-base-cla...

94 lines
4.4 KiB
YAML

---
features:
- |
Added a new :class:`.Operation` base class which provides a lightweight abstract interface
for objects that can be put on :class:`.QuantumCircuit`. This allows to store "higher-level"
objects directly on a circuit (for instance, :class:`.Clifford` objects), to directly combine such objects
(for instance, to compose several consecutive :class:`.Clifford` objects over the same qubits), and
to synthesize such objects at run time (for instance, to synthesize :class:`.Clifford` in
a way that optimizes depth and/or exploits device connectivity).
Previously, only subclasses of :class:`qiskit.circuit.Instruction` could be put on
:class:`.QuantumCircuit`, but this interface has become unwieldy and includes too many methods
and attributes for general-purpose objects.
The new :class:`.Operation` interface includes ``name``, ``num_qubits`` and ``num_clbits``
(in the future this may be slightly adjusted), but importantly does not include ``definition``
(and thus does not tie synthesis to the object), does not include ``condition``
(this should be part of separate classical control flow), and does not include ``duration`` and
``unit`` (as these are properties of the output of the transpiler).
As of now, :class:`.Operation` includes :class:`.Gate`, :class:`.Reset`, :class:`.Barrier`,
:class:`.Measure`, and "higher-level" objects such as :class:`.Clifford`. This list of
"higher-level" objects will grow in the future.
- |
A :class:`.Clifford` is now added to a quantum circuit as an :class:`.Operation`, without first
synthesizing a subcircuit implementing this Clifford. The actual synthesis is postponed
to a later :class:`.HighLevelSynthesis` transpilation pass.
For example, the following code::
from qiskit import QuantumCircuit
from qiskit.quantum_info import random_clifford
qc = QuantumCircuit(3)
cliff = random_clifford(2)
qc.append(cliff, [0, 1])
no longer converts ``cliff`` to :class:`qiskit.circuit.Instruction`, which includes
synthesizing the clifford into a circuit, when it is appended to ``qc``.
- |
Added a new transpiler pass :class:`.OptimizeCliffords` that collects blocks of consecutive
:class:`.Clifford` objects in a circuit, and replaces each block with a single :class:`.Clifford`.
For example, the following code::
from qiskit import QuantumCircuit
from qiskit.quantum_info import random_clifford
from qiskit.transpiler.passes import OptimizeCliffords
from qiskit.transpiler import PassManager
qc = QuantumCircuit(3)
cliff1 = random_clifford(2)
cliff2 = random_clifford(2)
qc.append(cliff1, [2, 1])
qc.append(cliff2, [2, 1])
qc_optimized = PassManager(OptimizeCliffords()).run(qc)
first stores the two Cliffords ``cliff1`` and ``cliff2`` on ``qc`` as "higher-level" objects,
and then the transpiler pass :class:`.OptimizeCliffords` optimizes the circuit by composing
these two Cliffords into a single Clifford. Note that the resulting Clifford is still stored
on ``qc`` as a higher-level object. This pass is not yet included in any of preset pass
managers.
- |
Added a new transpiler pass :class:`.HighLevelSynthesis` that synthesizes higher-level objects
(for instance, :class:`.Clifford` objects).
For example, the following code::
from qiskit import QuantumCircuit
from qiskit.quantum_info import random_clifford
from qiskit.transpiler import PassManager
from qiskit.transpiler.passes import HighLevelSynthesis
qc = QuantumCircuit(3)
qc.h(0)
cliff = random_clifford(2)
qc.append(cliff, [0, 1])
qc_synthesized = PassManager(HighLevelSynthesis()).run(qc)
will synthesize the higher-level Clifford stored in ``qc`` using the default
:func:`~qiskit.quantum_info.decompose_clifford` function.
This new transpiler pass :class:`.HighLevelSynthesis` is integrated into the preset pass managers,
running right after :class:`.UnitarySynthesis` pass. Thus, :func:`.transpile` will
synthesize all higher-level Cliffords present in the circuit.
It is important to note that the work done to store :class:`.Clifford` objects as "higher-level"
objects and to transpile these objects using :class:`.HighLevelSynthesis` pass should be completely
transparent, and no code changes are required.