Up until version 0.44, qiskit was a “metapackage” that contained several different “elements”, such as the
Aer simulator. What is called “Qiskit Terra” within this document is principally what is now just called “Qiskit”,
i.e. the SDK.
Starting with qiskit 0.45, qiskit and qiskit-terra will have the same version and will not include
any additional “elements”.
Fixed a bug in QPY serialization (qiskit.qpy) where multiple controlled custom gates in
a circuit could result in an invalid QPY file that could not be parsed. Fixed #9746.
Fixed #9363.
by labeling the non-registerless synthesis in the order that Tweedledum
returns. For example, compare this example before and after the fix:
Before After
c: ──■── a: ──■──
│ │
b: ──■── b: ──■──
│ │
a: ──o── c: ──o──
┌─┴─┐ ┌─┴─┐
return: ┤ X ├ return: ┤ X ├
└───┘ └───┘
Fixed plot_state_paulivec(), which previously damped the state coefficients by a factor of
\(2^n\), where \(n\) is the number of qubits. Now the bar graph correctly displays
the coefficients as \(\mathrm{Tr}(\sigma\rho)\), where \(\rho\) is the state to
be plotted and \(\sigma\) iterates over all possible tensor products of single-qubit Paulis.
Angles in the OpenQASM 2 exporter (QuantumCircuit.qasm()) will now always include a
decimal point, for example in the case of 1.e-5. This is required by a strict interpretation of the
floating-point-literal specification in OpenQASM 2. Qiskit’s OpenQASM 2 parser
(qasm2.load() and loads()) is more permissive by default, and will allow
1e-5 without the decimal point unless in strict mode.
The setter for SparsePauliOp.paulis will now correctly reject attempts to set the
attribute with incorrectly shaped data, rather than silently allowing an invalid object to be
created. See #10384.
This release officially marks the end of support for the Qiskit IBMQ Provider
package and the removal of Qiskit Aer from the Qiskit metapackage. After this
release the metapackage only contains Qiskit Terra, so this is the final
release we will refer to the Qiskit metapackage and Qiskit Terra as separate
things. Starting in the next release Qiskit 0.45.0 the Qiskit package will
just be what was previously Qiskit Terra and there will no longer be a
separation between them.
If you’re still using the qiskit-ibmq-provider package it has now been
retired and is no longer supported. You should follow the links to the migration
guides in the README for the package on how to switch over to the new replacement
packages qiskit-ibm-provider, qiskit-ibm-runtime, and
qiskit-ibm-experiment:
The Qiskit Aer project is still active and maintained moving forward it is
just no longer included as part of the qiskit package. To continue using
qiskit-aer you will need to explicitly install qiskit-aer and import the
package from qiskit_aer.
As this is the final release of the Qiskit metapackage the following setuptools
extras used to install optional dependencies will no longer work in the next
release Qiskit 0.45.0:
nature
machine-learning
finance
optimization
experiments
If you’re using the extras to install any packages you should migrate to using
the packages directly instead of the extra. For example if you were using
pipinstallqiskit[experiments] previously you should switch to
pipinstallqiskitqiskit-experiments to install both packages.
Similarly the all extra (what gets installed via
pipinstall"qiskit[all]") will no longer include these packages in Qiskit
0.45.0.
Control-flow operations are now supported through the transpiler at
all optimization levels, including levels 2 and 3 (e.g. calling
transpile() or generate_preset_pass_manager() with
keyword argument optimization_level specified as 2 or 3 is now
supported).
The fields IfElseOp.condition, WhileLoopOp.condition and
SwitchCaseOp.target can now be instances of the new runtime classical-expression type
expr.Expr. This is distinct from ParameterExpression because it is
evaluated at runtime for backends that support such operations.
These new expressions have significantly more power than the old two-tuple form of supplying
classical conditions. For example, one can now represent equality constraints between two
different classical registers, or the logic “or” of two classical bits. These two examples
would look like:
fromqiskit.circuitimportQuantumCircuit,ClassicalRegister,QuantumRegisterfromqiskit.circuit.classicalimportexprqr=QuantumRegister(4)cr1=ClassicalRegister(2)cr2=ClassicalRegister(2)qc=QuantumCircuit(qr,cr1,cr2)qc.h(0)qc.cx(0,1)qc.h(2)qc.cx(2,3)qc.measure([0,1,2,3],[0,1,2,3])# If the two registers are equal to each other.withqc.if_test(expr.equal(cr1,cr2)):qc.x(0)# While either of two bits are set.withqc.while_loop(expr.logic_or(cr1[0],cr1[1])):qc.reset(0)qc.reset(1)qc.measure([0,1],cr1)
This feature is new for both Qiskit and the available quantum hardware that
Qiskit works with. As the features are still being developed there are likely
to be places where there are unexpected edge cases that will need some time to
be worked out. If you encounter any issue around classical expression support
or usage please open an issue with Qiskit or your hardware vendor.
In this initial release, Qiskit has added the operations:
These can act on Python integer and Boolean literals, or on ClassicalRegister
and Clbit instances.
All these classical expressions are fully supported through the Qiskit transpiler stack, through
QPY serialisation (qiskit.qpy) and for export to OpenQASM 3 (qiskit.qasm3). Import
from OpenQASM 3 is currently managed by a separate package
(which is re-exposed via qiskit.qasm3), which we hope will be extended to match the new
features in Qiskit.
The qiskit.algorithms module has been deprecated and will be removed
in a future release. It has been superseded by a new standalone library
qiskit-algorithms which can be found on PyPi or on Github here:
The qiskit.algorithms module will continue to work as before and bug fixes
will be made to it until its future removal, but active development
of new features has moved to the new package.
If you’re relying on qiskit.algorithms you should update your
Python requirements to also include qiskit-algorithms and update the imports
from qiskit.algorithms to qiskit_algorithms. Please note that this
new package does not include already deprecated algorithms code, including
opflow and QuantumInstance-based algorithms. If you have not yet
migrated from QuantumInstance-based to primitives-based algorithms,
you should follow the migration guidelines in https://qisk.it/algo_migration.
The decision to migrate the algorithms module to a
separate package was made to clarify the purpose Qiskit and
make a distinction between the tools and libraries built on top of it.
Qiskit Terra 0.25 has dropped support for Python 3.7 following
deprecation warnings started in Qiskit Terra 0.23. This is consistent
with Python 3.7’s end-of-life on the 27th of June, 2023. To continue
using Qiskit, you must upgrade to a more recent version of Python.
The first new option split_layers allows collected blocks to be split into sub-blocks
over disjoint qubit subsets, i.e. into depth-1 sub-blocks.
The second new option collect_from_back allows blocks to be greedily collected starting
from the outputs of the circuit. This is important in combination with ALAP-scheduling passes
where we may prefer to put gates in the later rather than earlier blocks.
When split_layers is True, the collected blocks are split into
into sub-blocks over disjoint qubit subsets, i.e. into depth-1 sub-blocks.
Consider the following example:
fromqiskit.circuitimportQuantumCircuitfromqiskit.transpiler.passesimportCollectLinearFunctionscircuit=QuantumCircuit(5)circuit.cx(0,2)circuit.cx(1,4)circuit.cx(2,0)circuit.cx(0,3)circuit.swap(3,2)circuit.swap(4,1)# Collect all linear gates, without splitting into layersqct=CollectLinearFunctions(split_blocks=False,min_block_size=1,split_layers=False)(circuit)assertqct.count_ops()["linear_function"]==1# Collect all linear gates, with splitting into layersqct=CollectLinearFunctions(split_blocks=False,min_block_size=1,split_layers=True)(circuit)assertqct.count_ops()["linear_function"]==4
The original circuit is linear. When collecting linear gates without splitting into layers,
we should end up with a single linear function. However, when collecting linear gates and
splitting into layers, we should end up with 4 linear functions.
When collect_from_back is True, the blocks are greedily collected from the outputs towards
the inputs of the circuit. Consider the following example:
fromqiskit.circuitimportQuantumCircuitfromqiskit.transpiler.passesimportCollectLinearFunctionscircuit=QuantumCircuit(3)circuit.cx(1,2)circuit.cx(1,0)circuit.h(2)circuit.swap(1,2)# This combines the CX(1, 2) and CX(1, 0) gates into a single linear functionqct=CollectLinearFunctions(collect_from_back=False)(circuit)# This combines the CX(1, 0) and SWAP(1, 2) gates into a single linear functionqct=CollectLinearFunctions(collect_from_back=True)(circuit)
The original circuit contains a Hadamard gate, so that the CX(1, 0) gate can be
combined either with CX(1, 2) or with SWAP(1, 2), but not with both. When
collect_from_back is False, the linear blocks are greedily collected from the start
of the circuit, and thus CX(1, 0) is combined with CX(1, 2). When
collect_from_back is True, the linear blocks are greedily collected from the end
of the circuit, and thus CX(1, 0) is combined with SWAP(1, 2).
fromqiskitimportQuantumCircuit,QuantumRegister,ClassicalRegisterfromqiskit.convertersimportcircuit_to_dagfromqiskit.circuit.libraryimportRZGateq=QuantumRegister(3,'q')c=ClassicalRegister(3,'c')circ=QuantumCircuit(q,c)circ.h(q[0])circ.cx(q[0],q[1])circ.measure(q[0],c[0])circ.rz(0.5,q[1]).c_if(c,2)circ.measure(q[1],c[0])dag=circuit_to_dag(circ)rz_node=dag.op_nodes(RZGate)[0]# Contains the "measure" on clbit 0, and the "wire start" nodes for clbits 1 and 2.classical_predecessors=list(dag.classical_predecessors(rz_node))# Contains the "measure" on clbit 0, and the "wire end" nodes for clbits 1 and 2.classical_successors=list(dag.classical_successors(rz_node))
Enabled support for ControlFlowOp operations in the
CommutativeCancellation pass.
Previously, the blocks in control flow operations were skipped by this pass.
fromqiskitimportQuantumCircuit,QuantumRegister,ClassicalRegisterfromqiskit.circuit.libraryimportCXGate,CZGatefromqiskit.dagcircuitimportDAGCircuit# Build a DAGCircuitdag=DAGCircuit()qreg=QuantumRegister(5)creg=ClassicalRegister(5)dag.add_qreg(qreg)dag.add_creg(creg)dag.apply_operation_back(CXGate(),qreg[[1,2]],[])dag.apply_operation_back(CXGate(),qreg[[0,3]],[])dag.apply_operation_back(CZGate(),qreg[[1,4]],[])dag.apply_operation_back(CZGate(),qreg[[2,4]],[])dag.apply_operation_back(CXGate(),qreg[[3,4]],[])# Get the causal cone of qubit at index 0result=dag.quantum_causal_cone(qreg[0])
A new method find_bit() has
been added to the DAGCircuit class,
which returns the bit locations of the given Qubit or
Clbit as a tuple of the positional index of the bit within
the circuit and a list of tuples which locate the bit in the circuit’s
registers.
The transpiler’s built-in EquivalenceLibrary
(qiskit.circuit.equivalence_library.SessionEquivalenceLibrary)
has been taught the circular Pauli
relations \(X = iYZ\), \(Y = iZX\) and \(Z = iXY\). This should make transpiling
to constrained, and potentially incomplete, basis sets more reliable.
See #10293 for more detail.
Control-flow operations are now supported through the transpiler at
all optimization levels, including levels 2 and 3 (e.g. calling
transpile() or generate_preset_pass_manager() with
keyword argument optimization_level=3).
DAGCircuit.substitute_node() gained a propagate_condition keyword argument that is
analogous to the same argument in substitute_node_with_dag(). Setting this
to False opts out of the legacy behaviour of copying a condition on the node onto the
new op that is replacing it.
This option is ignored for general control-flow operations, which will never propagate their
condition, nor accept a condition from another node.
Introduced a new method, DAGCircuit.separable_circuits(), which returns a
list of DAGCircuit objects, one for each set of connected qubits
which have no gates connecting them to another set.
Each DAGCircuit instance returned by this method will contain the same
number of clbits as self. This method will not return DAGCircuit
instances consisting solely of clbits.
Added the attribute Target.concurrent_measurements which represents a hardware
constraint of qubits measured concurrently. This constraint is provided in a nested list form,
in which each element represents a qubit group to be measured together.
In an example below:
[[0,1],[2,3,4]]
qubits 0 and 1, and 2, 3 and 4 are measured together on the device.
This constraint doesn’t block measuring an individual qubit, but you may
need to consider the alignment of measure operations for these qubits when
working with the
Qiskit Pulse scheduler
and when authoring new transpiler passes that are timing-aware (i.e. passes
that perform scheduling).
The transpiler pass SetLayout can now
be constructed with a list of integers that represent the physical qubits
on which the quantum circuit will be mapped on. That is, the first qubit
in the circuit will be allocated to the physical qubit in position zero
of the list, and so on.
The transpiler’s built-in EquivalenceLibrary has been taught more Pauli-rotation
equivalences between the one-qubit \(R_X\), \(R_Y\) and \(R_Z\) gates, and between
the two-qubit \(R_{XX}\), \(R_{YY}\) and \(R_{ZZ}\) gates. This should make
simple basis translations more reliable, especially circuits that use \(Y\) rotations.
See #7332.
Control-flow operations are now supported by the Sabre family
of transpiler passes, namely layout pass SabreLayout
and routing pass SabreSwap. Function transpile()
keyword arguments layout_method and routing_method now
accept the option "sabre" for circuits with control flow,
which was previously unsupported.
The fields IfElseOp.condition, WhileLoopOp.condition and
SwitchCaseOp.target can now be instances of the new runtime classical-expression type
expr.Expr. This is distinct from ParameterExpression because it is
evaluated at runtime for backends that support such operations.
These new expressions have significantly more power than the old two-tuple form of supplying
classical conditions. For example, one can now represent equality constraints between two
different classical registers, or the logic “or” of two classical bits. These two examples
would look like:
fromqiskit.circuitimportQuantumCircuit,ClassicalRegister,QuantumRegisterfromqiskit.circuit.classicalimportexprqr=QuantumRegister(4)cr1=ClassicalRegister(2)cr2=ClassicalRegister(2)qc=QuantumCircuit(qr,cr1,cr2)qc.h(0)qc.cx(0,1)qc.h(2)qc.cx(2,3)qc.measure([0,1,2,3],[0,1,2,3])# If the two registers are equal to each other.withqc.if_test(expr.equal(cr1,cr2)):qc.x(0)# While either of two bits are set.withqc.while_loop(expr.logic_or(cr1[0],cr1[1])):qc.reset(0)qc.reset(1)qc.measure([0,1],cr1)
This feature is new for both Qiskit and the available quantum hardware that
Qiskit works with. As the features are still being developed there are likely
to be places where there are unexpected edge cases that will need some time to
be worked out. If you encounter any issue around classical expression support
or usage please open an issue with Qiskit or your hardware vendor.
In this initial release, Qiskit has added the operations:
These can act on Python integer and Boolean literals, or on ClassicalRegister
and Clbit instances.
All these classical expressions are fully supported through the Qiskit transpiler stack, through
QPY serialisation (qiskit.qpy) and for export to OpenQASM 3 (qiskit.qasm3). Import
from OpenQASM 3 is currently managed by a separate package
(which is re-exposed via qiskit.qasm3), which we hope will be extended to match the new
features in Qiskit.
Tooling for working with the new representations of classical runtime expressions
has been added.
A general ExprVisitor is provided for
consumers of these expressions to subclass. Two utilities based on this structure,
iter_vars() and structurally_equivalent(), are also provided, which
respectively produce an iterator through the Var nodes and check whether two
Expr instances are structurally the same, up to some mapping of the
Var nodes contained.
Added function lift_legacy_condition() which can be used to convert old-style
conditions into new-style Expr nodes.
Note that these expression nodes are not permitted in old-style Instruction.condition
fields, which are due to be replaced by more advanced classical handling such as IfElseOp.
Added support for taking absolute values of ParameterExpressions. For example,
the following is now possible:
The method QuantumCircuit.assign_parameters() has gained two new keywords arguments: flat_input
and strict. These are advanced options that can be used to speed up the method when passing the
parameter bindings as a dictionary; flat_input=True is a guarantee that the dictionary keys contain
only Parameter instances (not ParameterVectors), and strict=False allows the
dictionary to contain parameters that are not present in the circuit. Using these two options can
reduce the overhead of input normalisation in this function.
Added a new keyword argument flatten to the constructor for the
following classes:
If this argument is set to True the QuantumCircuit subclass
generated will not wrap the implementation into Gate or
Instruction objects. While this isn’t optimal for visualization
it typically results in much better runtime performance, especially with
QuantumCircuit.bind_parameters() and
QuantumCircuit.assign_parameters() which can see a substatial
runtime improvement with a flattened output compared to the nested
wrapped default output.
Added support for constructing LinearFunctions from more general quantum circuits,
that may contain:
Barriers (of type Barrier) and delays (Delay),
which are simply ignored
Cliffords (of type Clifford), when the Clifford represents a linear function
(and a CircuitError exception is raised if not)
Nested quantum circuits of this form
Added LinearFunction.__eq__() method. Two objects of type LinearFunction
are considered equal when their representations as binary invertible matrices are equal.
Added LinearFunction.extend_with_identity() method, which allows to extend
a linear function over k qubits to a linear function over n>=k qubits,
specifying the new positions of the original qubits and padding with identities on the
remaining qubits.
Added two methods for pretty-printing LinearFunction objects:
LinearFunction.mat_str(), which returns the string representation of the linear
function viewed as a matrix with 0/1 entries, and
LinearFunction.function_str(), which returns the string representation of the
linear function viewed as a linear transformation.
The instructions StatePreparation and Initialize,
and their associated circuit methods QuantumCircuit.prepare_state() and initialize(),
gained a keyword argument normalize, which can be set to True to automatically normalize
an array target. By default this is False, which retains the current behaviour of
raising an exception when given non-normalized input.
Added the option to pass a callback to the UMDA optimizer, which allows
keeping track of the number of function evaluations, the current parameters, and the
best achieved function value.
The OpenQASM 3 exporters (qasm3.dump(), dumps() and Exporter)
have a new allow_aliasing argument, which will eventually replace the alias_classical_registers
argument. This controls whether aliasing is permitted for either classical bits or qubits, rather
than the option only being available for classical bits.
Added a new function negativity() that calculates
the entanglement measure of negativity of a quantum state.
Example usage of the above function is given below:
fromqiskit.quantum_info.states.densitymatriximportDensityMatrixfromqiskit.quantum_info.states.statevectorimportStatevectorfromqiskit.quantum_infoimportnegativityimportnumpyasnp# Constructing a two-qubit bell state vectorstate=np.array([0,1/np.sqrt(2),-1/np.sqrt(2),0])# Calculating negativity of statevectornegv=negativity(Statevector(state),[1])# Creating the Density Matrix (DM)rho=DensityMatrix.from_label("10+")# Calculating negativity of DMnegv2=negativity(rho,[0,1])
The new functions return a ScalableSymbolicPulse instance, and match the functionality
of the corresponding functions in the discrete pulse library, with the exception of
Square() for which a phase of \(2\pi\) shifts by a full cycle (contrary to the
discrete square() where such a shift was induced by a \(\pi\) phase).
The method filter() is activated
in the ScheduleBlock class.
This method enables users to retain only Instruction
objects which pass through all the provided filters.
As builtin filter conditions, pulse Channel
subclass instance and Instruction
subclass type can be specified.
User-defined callbacks taking Instruction instance
can be added to the filters, too.
The method exclude() is activated
in the ScheduleBlock class.
This method enables users to retain only Instruction
objects which do not pass at least one of all the provided filters.
As builtin filter conditions, pulse Channel
subclass instance and Instruction
subclass type can be specified.
User-defined callbacks taking Instruction instance
can be added to the filters, too.
This method is the complement of filter(), so
the following condition is always satisfied:
block.filter(*filters)+block.exclude(*filters)==block in terms of
instructions included, where block is a ScheduleBlock
instance.
Added a new function gaussian_square_echo() to the
pulse library. The returned pulse
is composed of three GaussianSquare pulses. The
first two are echo pulses with duration half of the total duration and
implement rotary tones. The third pulse is a cancellation tone that lasts
the full duration of the pulse and implements correcting single qubit
rotations.
QPY supports the Discriminator and
Kernel objects.
This feature enables users to serialize and deserialize the
Acquire instructions with these objects
using QPY.
Added a new synthesis function synth_cx_cz_depth_line_my()
which produces the circuit form of a CX circuit followed by a CZ circuit for linear
nearest neighbor (LNN) connectivity in 2-qubit depth of at most 5n, using CX and
phase gates (S, Sdg or Z). The synthesis algorithm is based on the paper of Maslov
and Yang, arXiv:2210.16195.
The algorithm accepts a binary invertible matrix mat_x representing the CX-circuit,
a binary symmetric matrix mat_z representing the CZ-circuit, and returns a quantum circuit
with 2-qubit depth of at most 5n computing the composition of the CX and CZ circuits.
The following example illustrates the new functionality:
This function is now used by default in the Clifford synthesis algorithm
synth_clifford_depth_lnn() that optimizes 2-qubit depth
for LNN connectivity, improving the 2-qubit depth from 9n+4 to 7n+2.
The clifford synthesis algorithm can be used as follows:
The above synthesis can be further improved as described in the paper by Maslov and Yang,
using local optimization between 2-qubit layers. This improvement is left for follow-up
work.
QuantumCircuit.draw() and function circuit_drawer()
when using option output='mpl' now support drawing the nested circuit blocks of
ControlFlowOp operations, including
if, else, while, for, and switch/case. Circuit blocks are
wrapped with boxes to delineate the circuits.
Some restrictions when using wire_order in the circuit drawers have been relaxed.
Now, wire_order can list just qubits and, in that case, it can be used
with cregbundle=True, since it will not affect the classical bits.
Qiskit Terra 0.25 has dropped support for Python 3.7 following deprecation warnings started in
Qiskit Terra 0.23. This is consistent with Python 3.7’s end-of-life on the 27th of June, 2023.
To continue using Qiskit, you must upgrade to a more recent version of Python.
Qiskit Terra 0.25 now requires versison 0.13.0 of rustworkx.
By default Qiskit builds its compiled extensions using the
Python Stable ABI
with support back to the oldest version of Python supported by Qiskit
(currently 3.8). This means that moving forward there
will be a single precompiled wheel that is shipped on release that
works with all of Qiskit’s supported Python versions. There isn’t any
expected runtime performance difference using the limited API so it is
enabled by default for all builds now.
Previously, the compiled extensions were built using the version specific API and
would only work with a single Python version. This change was made
to reduce the number of package files we need to build and publish in each
release. When building Qiskit from source, there should be no changes
necessary to the build process except that the default tags in the output
filenames will be different to reflect the use of the limited API.
Support for passing in lists of argument values to the transpile()
function is removed. This functionality was deprecated as part of the
0.23.0 release. You are still able to pass in a
list of QuantumCircuit objects for the first positional argument.
What has been removed is list broadcasting of the other arguments to
each circuit in that input list. Removing this functionality was necessary
to greatly reduce the overhead for parallel execution for transpiling
multiple circuits at once. If you’re using this functionality
currently you can call transpile() multiple times instead. For
example if you were previously doing something like:
You can also leverage parallel_map() or multiprocessing from
the Python standard library if you want to run this in parallel.
The Sabre family of transpiler passes (namely SabreLayout
and SabreSwap) are now used by default for all circuits
when invoking the transpiler at optimization level 1 (e.g. calling
transpile() or generate_preset_pass_manager() with
keyword argument optimization_level=1). Previously, circuits
with control flow operations used DenseLayout and
StochasticSwap with this profile.
The OpenQASM 2 constructor methods on QuantumCircuit
(from_qasm_str() and from_qasm_file()) have been
switched to use the Rust-based parser added in Qiskit Terra 0.24. This should result in
significantly faster parsing times (10 times or more is not uncommon) and massively reduced
intermediate memory usage.
The QuantumCircuit methods are kept with the same interface for continuity; the
preferred way to access the OpenQASM 2 importer is to use qasm2.load() and
qasm2.loads(), which offer an expanded interface to control the parsing and construction.
The deprecated circuit_cregs argument to the constructor for the
InstructionSet class has been removed. It was deprecated in the
0.19.0 release. If you were using this argument and manually constructing
an InstructionSet object (which should be quite uncommon as it’s
mostly used internally) you should pass a callable to the
resource_requester keyword argument instead. For example:
The OpenQASM 2 constructor methods on QuantumCircuit
(from_qasm_str() and from_qasm_file()) have been
switched to use the Rust-based parser added in Qiskit Terra 0.24. This should result in
significantly faster parsing times (10 times or more is not uncommon) and massively reduced
intermediate memory usage.
The QuantumCircuit methods are kept with the same interface for continuity; the
preferred way to access the OpenQASM 2 importer is to use qasm2.load() and
qasm2.loads(), which offer an expanded interface to control the parsing and construction.
The OpenQASM 3 exporters (qasm3.dump(), dumps() and Exporter)
will now use fewer “register alias” definitions in its output. The circuit described will not
change, but it will now preferentially export in terms of direct bit, qubit and
qubit[n] types rather than producing a _loose_bits register and aliasing more registers
off this. This is done to minimise the number of advanced OpenQASM 3 features in use, and to
avoid introducing unnecessary array structure into programmes that do not require it.
Clifford.from_circuit() will no longer attempt to resolve instructions whose
definition fields are mutually recursive with some other object.
Such recursive definitions are already a violation of the strictly hierarchical ordering that
the definition field requires, and code should not rely on this
being possible at all. If you want to define equivalences that are permitted to have (mutual)
cycles, use an EquivalenceLibrary.
In the internal ~qiskit.visualization.circuit.matplotlib.MatplotlibDrawer object, the arguments
layout, global_phase, qregs and cregs have been removed. They were originally
deprecated in Qiskit Terra 0.20. These objects are simply inferred from the given circuit
now.
This is an internal worker class of the visualization routines. It is unlikely you will
need to change any of your code.
The qiskit.util import location has been removed, as it had
been deprecated since Qiskit Terra 0.17. Users should use the new
import location, qiskit.utils.
Extensions of the qiskit and qiskit.providers namespaces by external
packages are now deprecated and the hook points enabling this will be
removed in a future release. In the past, the Qiskit project was composed
of elements that extended a shared namespace and these hook points enabled
doing that. However, it was not intended for these interfaces to ever be
used by other packages. Now that the overall Qiskit package is no longer
using that packaging model, leaving the possibility for these extensions
carry more risk than benefits and is therefore being deprecated for
future removal. If you’re maintaining a package that extends the Qiskit
namespace (i.e. your users import from qiskit.x or
qiskit.providers.y) you should transition to using a standalone
Python namespace for your package. No warning will be raised as part of this
because there is no method to inject a warning at the packaging level that
would be required to warn external packages of this change.
The dictionary qiskit.__qiskit_version__ is deprecated, as Qiskit is defined with a single package (qiskit-terra).
In the future, qiskit.__version__ will be the single point to query the Qiskit version, as a standard string.
The function get_vf2_call_limit available via the module
qiskit.transpiler.preset_passmanagers.common has been
deprecated. This will likely affect very few users since this function was
neither explicitly exported nor documented. Its functionality has been
replaced and extended by a function in the same module.
The method qasm() and all overriding methods of subclasses
of :class:~qiskit.circuit.Instruction are deprecated. There is no replacement for generating
an OpenQASM2 string for an isolated instruction as typically
a single instruction object has insufficient context to completely
generate a valid OpenQASM2 string. If you’re relying on this
method currently you’ll have to instead rely on the OpenQASM2
exporter: QuantumCircuit.qasm() to generate the OpenQASM2
for an entire circuit object.
The qiskit.algorithms module has been deprecated and will be removed
in a future release. It has been superseded by a new standalone library
qiskit-algorithms which can be found on PyPi or on Github here:
The qiskit.algorithms module will continue to work as before and bug fixes
will be made to it until its future removal, but active development
of new features has moved to the new package.
If you’re relying on qiskit.algorithms you should update your
Python requirements to also include qiskit-algorithms and update the imports
from qiskit.algorithms to qiskit_algorithms. Please note that this
new package does not include already deprecated algorithms code, including
opflow and QuantumInstance-based algorithms. If you have not yet
migrated from QuantumInstance-based to primitives-based algorithms,
you should follow the migration guidelines in https://qisk.it/algo_migration.
The decision to migrate the algorithms module to a
separate package was made to clarify the purpose Qiskit and
make a distinction between the tools and libraries built on top of it.
Initializing amp for these with a complex value is now deprecated as well.
Instead, use two floats when specifying the amp and angle parameters, where amp represents the
magnitude of the complex amplitude, and angle represents the angle of the complex amplitude. i.e. the
complex amplitude is given by \(\texttt{amp} \times \exp(i \times \texttt{angle})\).
The Call instruction has been deprecated and will
be removed in a future release.
Instead, use function call() from module
qiskit.pulse.builder within an active building context.
The Jupyter magic %circuit_library_info and the objects in qiskit.tools.jupyter.library
it calls in turn:
circuit_data_table
properties_widget
qasm_widget
circuit_digram_widget
circuit_library_widget
are deprecated and will be removed in a future release. These objects were only intended for use in
the documentation build. They are no longer used there, so are no longer supported or maintained.
Fixed a bug in Channel where index validation was done incorrectly and only
raised an error when the index was both non-integer and negative, instead of either.
Fixed an issue with the transpile() function and all the preset
pass managers generated via generate_preset_pass_manager() where
the output QuantumCircuit object’s layout
attribute would have an invalid TranspileLayout.final_layout
attribute. This would occur in scenarios when the VF2PostLayout
pass would run and find an alternative initial layout that has lower
reported error rates. When altering the initial layout the
final_layout attribute was never updated to
reflect this change. This has been corrected so that the final_layout
is always correctly reflecting the output permutation caused by the routing
stage.
Fixed #10457
The OpenQASM 2 parser (qasm2.load() and loads()) running in strict mode
will now correctly emit an error if a barrier statement has no arguments. When running in
the (default) more permissive mode, an argument-less barrier statement will continue to
cause a barrier on all qubits currently in scope (the qubits a gate definition affects, or all
the qubits defined by a program, if the statement is in a gate body or in the global scope,
respectively).
The OpenQASM 2 exporter (QuantumCircuit.qasm()) will now no longer attempt
to output barrier statements that act on no qubits. Such a barrier statement has no effect
in Qiskit either, but is invalid OpenQASM 2.
Qiskit can represent custom instructions that act on zero qubits, or on a non-zero number of
classical bits. These cannot be exported to OpenQASM 2, but previously QuantumCircuit.qasm()
would try, and output invalid OpenQASM 2. Instead, a QASM2ExportError will now correctly
be raised. See #7351 and
#10435.
Fixed an issue with using Targets without coupling maps with the FullAncillaAllocation transpiler pass.
In this case, FullAncillaAllocation will now add
ancilla qubits so that the number of qubits in the DAGCircuit matches
that of Target.num_qubits.
DAGCircuit.substitute_node() will no longer silently overwrite an existing condition on
the given replacement op. If propagate_condition is set to True (the default), a
DAGCircuitError will be raised instead.
A parametrised circuit that contains a custom gate whose definition has a parametrised global phase
can now successfully bind the parameter in the inner global phase.
See #10283 for more detail.
Construction of a Statevector from a QuantumCircuit containing
zero-qubit operations will no longer raise an error. These operations impart a global phase on
the resulting statevector.
The control-flow builder interface will now correctly include ClassicalRegister
resources from nested switch statements in their containing circuit scopes. See #10398.
Fixed an issue in QuantumCircuit.decompose()
where passing a circuit name to the function that matched a
composite gate name would not decompose the gate if it had a label
assigned to it as well.
Fixed #9136
Fixed an issue with qiskit.visualization.plot_histogram() where the relative legend
did not show up when the given dataset had a zero value in the first position.
See #10158 for more details.
When the parameter conditional=True is specified in
random_circuit(), conditional operations
in the resulting circuit will
now be preceded by a full mid-circuit measurment.
Fixes #9016
Improved the type annotations on the
QuantumCircuit.assign_parameters()
method to reflect the change in return type depending on the inplace
argument.
Reduced overhead of the ConsolidateBlocks pass by performing matrix operations
on all two-qubit blocks instead of creating an instance of QuantumCircuit and
passing it to an Operator.
The speedup will only be applicable when consolidating two-qubit blocks. Anything higher
than that will still be handled by the Operator class.
Check #8779 for details.
The OpenQASM 3 exporter (qiskit.qasm3) will no longer output invalid OpenQASM 3 for
non-unitary Instruction instances, but will instead raise a
QASM3ExporterError explaining that these are not yet supported. This feature is
slated for a later release of Qiskit, when there are more classical-processing facilities
throughout the library.
Fixed an issue with function state_to_latex().
Previously, it produced invalid LaTeX with unintended coefficient rounding, which resulted in
errors when calling state_drawer().
Fixed #9297.
Fixed the deserialization of DiagonalGate instances through QPY.
Fixed #10364
Fixed an issue with the qs_decomposition() function, which does
quantum Shannon decomposition, when it was called on trivial numeric
unitaries that do not benefit from this decomposition, an unexpected error
was raised. This error has been fixed so that such unitaries are detected
and the equivalent circuit is returned.
Fixed #10036
Fixed an issue in the the BasicSwap class that
prevented the BasicSwap.run() method from functioning if the
fake_run keyword argument was set to True when the class was
instantiated.
Fixed #10147
Fixed an issue with copying circuits with new-style Clbits and
Qubits (bits without registers) where references to these bits
from the containing circuit could be broken, causing issues with
serialization and circuit visualization.
Fixed #10409
The CheckMap transpiler pass will no longer spuriously error when dealing with nested
conditional structures created by the control-flow builder interface. See #10394.
Fixed the dimensions of the output density matrix from DensityMatrix.partial_transpose()
so they match the dimensions of the corresponding input density matrix.
Importing qiskit.primitives will no longer cause deprecation warnings stemming from the
deprecated qiskit.opflow module. These warnings would have been hidden to users by the
default Python filters, but triggered the eager import of opflow, which meant that a
subsequent import by a user would not trigger the warnings.
Fixed #10245
Fixed the OpenQASM 2 output of QuantumCircuit.qasm() when a custom gate object contained
a gate with the same name. Ideally this shouldn’t happen for most gates, but complex algorithmic
operations like the GroverOperator class could produce such structures accidentally.
See #10162.
Fixed a regression in the LaTeX drawer of QuantumCircuit.draw()
when temporary files are placed on a separate filesystem to the working
directory. See
#10211.
Fixed an issue with UnitarySynthesis when using the target
parameter where circuits with control flow were not properly mapped
to the target.
Fixed bug in VQD where result.optimal_values was a
copy of result.optimal_points. It now returns the corresponding values.
Fixed #10263
Improved the error messages returned when an attempt to convert a fully bound
ParameterExpression into a concrete float or int failed, for example because
the expression was naturally a complex number.
Fixed #9187
Fixed float conversions for ParameterExpression values which had, at some point in
their construction history, an imaginary component that had subsequently been cancelled. When
using Sympy as a backend, these conversions would usually already have worked. When using
Symengine as the backend, these conversions would often fail with type errors, despite the
result having been symbolically evaluated to be real, and ParameterExpression.is_real()
being true.
Fixed #10191
Fixed the qpy serialization of QuantumCircuit.layout
attribue. Previously, the layout attribute would
have been dropped when serializing a circuit to QPY.
Fixed #10112
Qiskit Aer now requires CUDA version for GPU simulator to 11.2 or
higher. Previously, CUDA 10.1 was the minimum supported version.
This change was necessary because of changes in the upstream CUDA
ecosystem, including cuQuantum support. To support users running
with different versions of CUDA there is now a separate package available
for running with CUDA 11: qiskit-aer-gpu-cu11 and using the
qiskit-aer-gpu package now requires CUDA 12. If you’re an existing
user of the qiskit-aer-gpu package and want to use CUDA 11
you will need to run:
to go from the previously CUDA 10.x compatible qiskit-aer-gpu
package’s releases to upgrade to the new CUDA 11 compatible
package. If you’re running CUDA 12 locally already you can upgrade
the qiskit-aer-gpu package as normal.
If a circuit has conditional and parameters, the circuit was not be
correctly simulated because parameter bindings of Aer used wrong positions
to apply parameters. This is from a lack of consideration of bfunc operations
injected by conditional. With this commit, parameters are set to correct
positions with consideration of injected bfun operations.
Parameters for global phases were not correctly set in #1814.
https://github.com/Qiskit/qiskit-aer/pull/1814
Parameter values for global phases were copied to a template circuit and not to
actual circuits to be simulated. This commit correctly copies parameter values
to circuits to be simulated.
Results of backend.run() were not serializable because they include AerCircuits.
This commit makes the results serializable by removing AerCircuits from metadata.
:meth:QuantumCircuit.save_statevector() does not work if the circuit
is generated from OpenQASM3 text because its quantum registers have duplicated
qubit instances. With this commit, :meth:QuantumCircuit.save_statevector()
uses :data:QuantumCircuit.qubits to get qubits to be saved.
As a reminder, Qiskit Aer’s inclusion in the qiskit
package is deprecated. The next minor version of Qiskit Aer (0.13) will not be included in any
release of the qiskit package, and you should immediately begin installing Aer separately by:
pipinstallqiskit-aer
and importing it as:
importqiskit_aer
Starting from Qiskit 0.44, the command pipinstallqiskit will no longer install Qiskit Aer, or
the obsolete IBM Q Provider that has already been replaced by the new IBM Provider
<https://qiskit.org/ecosystem/ibm-provider/>__.
Performance regression due to introduction of AER::Config is fixed.
This class has many fields but is frequently copied in AER::Transpile::CircuitOptimization.
Originally json_t (former class for configuration) was also frequently copied but
it does have entries in most cases and then this copy overhead is not a problem.
With this fix, AER::Transpile::CircuitOptimization does not copy AER::Config.
When BLAS calls are failed, because omp threads do not handle exceptions,
Aer crashes without any error messages. This fix is for omp threads to catch
exceptions correctly and then rethrow them outside of omp loops.
Previously, parameters for gates are not validate in C++. If parameters are shorter than
expected (due to custom gate), segmentaion faults are thrown. This commit adds checks
whether parameter lenght is expceted. This commit will fix issues reported in #1612.
https://github.com/Qiskit/qiskit-aer/issues/1612
Since 0.12.0, parameter values in circuits are temporarily replaced with constant values
and parameter values are assigned in C++ library. Therefore, if parameter_binds is specified,
simulator returns results with the constnat values as paramter values. With this commit,
Aer raises an error if parameter_binds is not specified though circuits have parameters.
Available devices and methods are no longer queried when importing Aer.
Previously AerSimulator modifies circuit metadata to maintain
consistency between input and output of simulation with side effect of
unexpected view of metadata from applicatiln in simiulation. This fix
avoids using circuit metadata to maintain consistency internaly and then
always provides consistent view of metadata to application.
Fixed a bug where the variance in metadata in EstimatorResult was complex and now returns float.
Fixed a build break to compile Qiskit Aer with cuQuautum support (AER_ENABLE_CUQUANTUM=true).
This change does not affect build for CPU and normal GPU binaries.
Fixed a bug in from_backend() that raised an error when
the backend has no T1 and T2 values (i.e. None) for a qubit in its qubit properties.
This commit updates NoiseModel.from_backend() and basic_device_gate_errors()
so that they add an identity QuantumError (i.e. effectively no thermal relaxation error)
to a qubit with no T1 and T2 values for all gates acting on qubits including the qubit.
Fixed #1779
and #1815.
Fix an issue even if the number of qubits is set by a coupling map
or device’s configuration, when the simulation method is configured,
the number of qubits is overwritten in accordance with the method.
Fixed #1769
This is fix for library path setting in CMakeLists.txt for cuQuantum SDK.
Because the latest cuQuantum includes libraries for CUDA 11.x and 12.x,
this fix uses CUDA version returned from FindCUDA to the path of libraries
of cuQuantum and cuTENSOR.
This is fix for static link libraries of cuQuantum when building with
CUQUANTUM_STATIC=true.
MPI parallelization was not enabled since we have not used qobj.
This fix sets the number of processes and MPI rank correctly.
AerCircuit is created from a circuit by iterating its operations
while skipping barrier instructions. However, skipping barrier instructions
make wrong positionings of parameter bindings. This fix adds
barrier() and keeps parametr bindings correct.
Aer still supports Qobj as an argument of run() though
it was deprecated. However, since 0.12.0, it always fails if no run_options
is specified. This fix enables simulation of Qobj without run_options.
Since 0.12.0, AerConfig is used for simulation configuration while
performing strict type checking for arguments of meth:~.AerSimulator.run.
This commit adds casting if argument types are not expected.
:meth:QuantumCircuit.initialize() with int value was not processed
correctly as reported in #1821 <https://github.com/Qiskit/qiskit-aer/issues/1821>.
This commit enables such initialization by decomposing initialize instructions.
Changed QuantumCircuit.assign_parameters() to bind
assigned integer and float values directly into the parameters of
Instruction instances in the circuit rather than
binding the values wrapped within a
ParameterExpression. This change should have
little user impact as float(QuantumCircuit.data[i].operation.params[j])
still produces a float (and is the only way to access the value of a
ParameterExpression). Also,
Instruction() parameters could already be float
as well as a ParameterExpression, so code dealing
with instruction parameters should already handle both cases. The most
likely chance for user impact is in code that uses isinstance to check
for ParameterExpression and behaves differently
depending on the result. Additionally, qpy serializes the numeric value in
a bound ParameterExpression at a different
precision than a float (see also the related bug fix note about
QuantumCircuit.assign_parameters()).
Changed the binding of numeric values with
QuantumCircuit.assign_parameters() to avoid a mismatch between the
values of circuit instruction parameters and corresponding parameter keys
in the circuit’s calibration dictionary. Fixed #9764 and #10166. See also the
related upgrade note regarding QuantumCircuit.assign_parameters().
Fixed a bug in BlockCollapser where classical bits were ignored when collapsing
a block of nodes.
Fixed a bug in QuantumCircuit.compose() where the SwitchCaseOp.target attribute
in the subcircuit was not correctly mapped to a register in the base circuit.
Fix a bug in RZXCalibrationBuilder where calling calibration with wrong parameters would crash instead of raising an exception.
Fixed an issue with the BooleanExpression.from_dimacs_file()
constructor method where the exception type raised when tweedledum wasn’t
installed was not the expected MissingOptionalLibrary.
Fixed #10079
Using initial_layout in calls to transpile() will no longer error if the
circuit contains qubits not in any registers, or qubits that exist in more than one
register. See #10125.
Fixed the gate decomposition of multi-controlled Z rotation gates added via
QuantumCircuit.mcrz(). Previously, this method implemented a multi-controlled
phase gate, which has a relative phase difference to the Z rotation. To obtain the
previous QuantumCircuit.mcrz() behaviour, use QuantumCircuit.mcp().
Fixed an issue with the PassManagerConfig.from_backend() constructor
when building a PassManagerConfig object from a BackendV1
instance that didn’t have a coupling map attribute defined. Previously, the
constructor would incorrectly create a CouplingMap object with
0 qubits instead of using None.
Fixed #10171
Fixes a bug introduced in Qiskit 0.24.0 where numeric rotation angles were no longer substituted
for symbolic ones before preparing for two-qubit synthesis. This caused an exception to be
raised because the synthesis routines require numberic matrices.
Fix a bug in which running Optimize1qGatesDecomposition in parallel would raise an error due to OneQubitGateErrorMap not being picklable.
Fix a bug in the VF2Layout and VF2PostLayout passes
where the passes were failing to account for the 1 qubit error component when
evaluating a potential layout.
This is a major feature release that includes numerous new features
and bugfixes.
This release is the final release with support for running Qiskit
with Python 3.7. Starting in the next minor version release Python >=3.8 will
be required to run Qiskit.
The highlights of this release:
QuantumInstance, OpFlow, and algorithms usage deprecation#
This release officially deprecates the QuantumInstance class (and
its associated helper methods and classes), the qiskit.opflow module,
and any usage of those in qiskit.algorithms. This deprecation comes
from a long thread of work that started in Qiskit Terra 0.21.0 to refactor
the qiskit.algorithms module to be based on the computational
primitives. There are associated migration guides for any
existing users to migrate to the new workflow:
This release includes a major refactoring for the OpenQASM 2.0 support
in Qiskit. The first change is the introduction of a new parser for OpenQASM
2.0 in the qiskit.qasm2 module. This new module replaces the
existing qiskit.qasm module. The new parser is more explicit and
correct with respect to the language specification. It is also implemented in
Rust and is significantly faster than the previous parser. Paired with the
new parser the OpenQASM 2.0 exporter underwent a large refactor that
improved the correctness of the output when using the
QuantumCircuit.qasm() method to generate QASM output from a
QuantumCircuit object.
Transpiler support for devices with disjoint connectivity#
The transpiler now supports targeting backends with disjoint connectivity.
Previously, the transpiler only supported backends which were fully connected
(where there is a path to run operations between all pairs of qubits in the
backend). Now, if a backend has disconnected connectivity the transpiler is
able to reason about how to apply layout (Layout Stage) and
routing (Routing Stage) for the backend. If the input circuit is
not able to be executed on the hardware given the lack of connectivity between
connected components, a descriptive error will be returned.
For example, the Heron device outlined in IBM Quantum’s
hardware roadmap
describes a future backend which will have shared control hardware
and real-time classical communication between separate quantum processors.
This support enables the Target to accurately model these types
of future devices or other hardware with similar constraints.
This release adds a new control flow operation, the switch statement. This is
implemented using a new operation class SwitchCaseOp and the
QuantumCircuit.switch() method. This allows switching on a numeric
input (such as a classical register or bit) and executing the circuit that
corresponds to the matching value.
add_deprecation_to_docstring() will rewrite the function’s docstring to include a
Sphinx ..deprecated:: directive so that the deprecation shows up in docs and with
help(). The deprecation decorators from qiskit.utils call
add_deprecation_to_docstring() already for you; but you can call it directly if you
are using different mechanisms for deprecations.
@deprecate_func replaces @deprecate_function and is used to deprecate an entire
function. It will auto-generate most of the deprecation message for you.
@deprecate_arg replaces @deprecate_arguments and is used to deprecate an
argument on a function. It will generate a more useful message than the previous function.
It is also more flexible, for example it allows setting a predicate so that you only
deprecate certain situations, such as using a deprecated value or data type.
Added an alternative way to specify in HLSConfig the list of
synthesis methods used for a given high-level object.
As before, a synthesis method can be specified as a tuple consisting of
the name of the method and additional arguments. Additionally, a synthesis method
can be specified as a tuple consisting of an instance of HighLevelSynthesisPlugin
and additional arguments. Moreover, when there are no additional arguments, a synthesis
method can be specified simply by name or by an instance of HighLevelSynthesisPlugin.
The following example illustrates the new functionality:
fromqiskitimportQuantumCircuitfromqiskit.circuit.library.generalized_gatesimportPermutationGatefromqiskit.transpilerimportPassManagerfromqiskit.transpiler.passes.synthesis.high_level_synthesisimportHLSConfig,HighLevelSynthesisfromqiskit.transpiler.passes.synthesis.high_level_synthesisimportACGSynthesisPermutationqc=QuantumCircuit(6)qc.append(PermutationGate([1,2,3,0]),[1,2,3,4])# All of the ways to specify hls_config are equivalenthls_config=HLSConfig(permutation=[("acg",{})])hls_config=HLSConfig(permutation=["acg"])hls_config=HLSConfig(permutation=[(ACGSynthesisPermutation(),{})])hls_config=HLSConfig(permutation=[ACGSynthesisPermutation()])# The hls_config can then be passed as an argument to HighLevelSynthesispm=PassManager(HighLevelSynthesis(hls_config=hls_config))qc_synthesized=pm.run(qc)
Added support to the CouplingMap object to have a disjoint
connectivity. Previously, a CouplingMap could only be
constructed if the graph was connected. This will enable using
CouplingMap to represent hardware with disjoint qubits, such as hardware
with qubits on multiple separate chips.
Please refer to qiskit.synthesis documentation for more information
about each individual method.
The following example illustrates some of the new plugins:
fromqiskit.circuitimportQuantumCircuitfromqiskit.circuit.libraryimportLinearFunctionfromqiskit.quantum_infoimportCliffordfromqiskit.transpiler.passes.synthesis.high_level_synthesisimportHLSConfig,HighLevelSynthesis# Create a quantum circuit with one linear function and one cliffordqc1=QuantumCircuit(3)qc1.cx(0,1)qc1.swap(0,2)lin_fun=LinearFunction(qc1)qc2=QuantumCircuit(3)qc2.h(0)qc2.cx(0,2)cliff=Clifford(qc2)qc=QuantumCircuit(4)qc.append(lin_fun,[0,1,2])qc.append(cliff,[1,2,3])# Choose synthesis methods that adhere to linear-nearest-neighbour connectivityhls_config=HLSConfig(linear_function=["kms"],clifford=["lnn"])# Synthesizeqct=HighLevelSynthesis(hls_config)(qc)print(qct.decompose())
Added a new transpiler pass, MinimumPoint which is used primarily as
a pass to check a loop condition in a PassManager. This pass will
track the state of fields in the property set over its past executions and set
a boolean field when either a fixed point is reached over the backtracking depth
or selecting the minimum value found if the backtracking depth is reached. This
is an alternative to the FixedPoint which simply checks for a fixed
value in a property set field between subsequent executions.
Added a new method, swap_nodes(), to the
DAGCircuit to allow swapping nodes which are partially
connected. Partially connected here means that the two nodes share at
least one edge (which represents a qubit or clbit). If the nodes do not
share any edges a DAGCircuitError is raised.
Add a new synthesis algorithm synth_cz_depth_line_mr() of a CZ circuit
for linear nearest neighbor (LNN) connectivity in 2-qubit depth of 2n+2
using CX and phase gates (S, Sdg or Z). The synthesized circuit reverts
the order of the qubits. The synthesis algorithm is based on the paper of Maslov and Roetteler
(https://arxiv.org/abs/1705.09176).
Add a new synthesis algorithm synth_clifford_depth_lnn() of a Clifford circuit
for LNN connectivity in 2-qubit depth of 9n+4 (which is still not optimal),
using the layered Clifford synthesis (synth_clifford_layers()),
synth_cnot_depth_line_kms() to synthesize the CX layer in depth 5n,
and synth_cz_depth_line_mr() to synthesize each of the CZ layers in depth 2n+2.
This PR will be followed by another PR based on the recent paper of Maslov and Yang
(https://arxiv.org/abs/2210.16195), that synthesizes the CX-CZ layers in depth 5n
for LNN connectivity and performs further optimization, and hence reduces the depth
of a Clifford circuit to 7n-4 for LNN connectivity.
Equivalences between the controlled Pauli rotations and translations to two-Pauli rotations
are now available in the equivalence library for Qiskit standard gates. This allows,
for example, to translate a CRZGate to a RZZGate plus RZGate
or a CRYGate to a single RZXGate plus single qubit gates:
Added a new option, copy_operations, to circuit_to_dag() to
enable optionally disabling deep copying the operations from the input
QuantumCircuit to the output QuantumCircuit. In cases
where the input :class`~.QuantumCircuit` is not used anymore after
conversion this deep copying is unnecessary overhead as any shared
references wouldn’t have any potential unwanted side effects if the input
QuantumCircuit is discarded.
Added a new option, copy_operations, to dag_to_circuit() to
enable optionally disabling deep copying the operations from the input
DAGCircuit to the output QuantumCircuit. In cases
where the input DAGCircuit is not used anymore after conversion
this deep copying is unnecessary overhead as any shared references wouldn’t
have any potential unwanted side effects if the input DAGCircuit
is discarded.
Added a new function passmanager_stage_plugins() to the
qiskit.transpiler.preset_passmanagers.plugin module. This function
is used to obtain a mapping from plugin names to their their class type.
This enables identifying and querying any defined pass manager stage plugin’s
documentation. For example:
>>> fromqiskit.transpiler.preset_passmanagers.pluginimportpassmanager_stage_plugins>>> passmanager_stage_plugins('routing')['lookahead'].__class__qiskit.transpiler.preset_passmanagers.builtin_plugins.LookaheadSwapPassManager>>> help(passmanager_stage_plugins('routing')['lookahead'])Help on BasicSwapPassManager in module qiskit.transpiler.preset_passmanagers.builtin_plugins object:class BasicSwapPassManager(qiskit.transpiler.preset_passmanagers.plugin.PassManagerStagePlugin)| Plugin class for routing stage with :class:`~.BasicSwap`...
The transpiler pass Error now also accepts callable
inputs for its msg parameter. If used these input callables will be passed
the property_set attribute of the pass and are expected to return a string
which will be used for the error message when the pass is run. For example:
fromqiskit.transpiler.passesimportErrordeferror_message(property_set):size=property_set["size']returnf"The circuit size is: {size}"error_pass=Error(error_message)
When error_pass is included in a pass manager it will error using the
message "Thecircuitsizeis:n" where n is the circuit size set
in the property set (typically from the previous execution of the
Size pass).
The build_coupling_map() method has a new keyword argument,
filter_idle_qubits which when set to True will remove any qubits
from the output CouplingMap that don’t support any operations.
The GateDirection transpiler pass can now correctly handle
SwapGate instances that may be present in the circuit when
executing on a circuit. In these cases if the swap gate’s qubit arguments
are on the non-native direction of an edge, the pass will flip the argument
order.
The RZXCalibrationBuilder and RZXCalibrationBuilderNoEcho transpiler passes now will correctly use
an ECRGate for the entangling gate if the backend’s native
entangling gate is ECRGate. Previously, the passes would only
function correctly if the entangling gate was CXGate.
This will construct a Target object that has UGate,
CXGate, and Measure globally available on 25 qubits
which are connected in a line.
Added a new function synth_cnot_phase_aam()
which is used to synthesize cnot phase circuits for all-to-all architectures
using the Amy, Azimzadeh, and Mosca method. This function is identical to
the available qiskit.transpiler.synthesis.graysynth()
function but has a more descriptive name and is more logically placed
in the package tree. This new function supersedes the legacy function
which will likely be deprecated in a future release.
Internal tweaks to the routing algorithm in SabreSwap, used in
transpilation of non-dynamic circuits at all non-zero optimization levels,
have sped up routing for very large circuits. For example, the time to
route a depth-5 QuantumVolume circuit for a 1081-qubit heavy-hex
coupling map is approximately halved.
The runtime performance of the Optimize1qGatesDecomposition
transpiler pass has been significantly improved. This was done by both
rewriting all the computation for the pass in Rust and also decreasing
the amount of intermediate objects created as part of the pass’s
execution. This should also correspond to a similar improvement
in the runtime performance of transpile() with the
optimization_level keyword argument set to 1, 2, or 3.
Add a new synthesis method synth_stabilizer_layers() of a stabilizer state into layers.
It provides a similar decomposition to the synthesis described in Lemma 8 of Bravyi and Maslov,
(arxiv:2003.09412) without the initial Hadamard-free sub-circuit which does not affect the stabilizer state.
Add a new synthesis method synth_stabilizer_lnn() of a stabilizer state
for linear nearest neighbor connectivity in 2-qubit depth of 2n+2 and two distinct CX layers,
using CX and phase gates (S, Sdg or Z).
The synthesis algorithm is based on the paper of Maslov and Roetteler (https://arxiv.org/abs/1705.09176).
The SabreLayout pass now supports running against a target
with a disjoint CouplingMap. When targeting a disjoint coupling
the input DAGCircuit is split into its connected components of
virtual qubits, each component is mapped to the connected components
of the CouplingMap, layout is run on each connected
component in isolation, and then all layouts are combined and returned.
Note when the routing_pass argument is set the pass doesn’t
support running with disjoint connectivity.
The following layout and routing transpiler passes from the
qiskit.transpiler.passes modules now will support accepting a
Target object which is used to model the constraints of a target
backend via the first positional argument (currently named either
coupling_map or backend_properties).
The list of passes with the new support for Target input are:
The pass manager construction helper function generate_embed_passmanager()
will now also accept a Target for it’s sole positional argument
(currently named coupling_map). This can be used to construct a layout
embedding PassManager from a Target object instead of
from a CouplingMap.
The following layout and routing transpiler passes from the
qiskit.transpiler.passes modules have a new keyword argument,
target which takes in a Target object which is used to model
the constraints of a target backend. If the target keyword argument is
specified it will be used as the source of truth for any hardware
constraints used in the operation of the transpiler pass. It will
supersede any other arguments for specifying hardware constraints,
typically those arguments which take a CouplingMap,
InstructionScheduleMap or a basis gate list.
The list of these passes with the new target argument are:
The pass manager construction helper function generate_scheduling()
has a new keyword argument target which is used to specify a Target
object to model the constraints of the target backend being compiled for
when generating a new PassManager. If specified this new argument will
supersede the other argument inst_map.
The default plugin used by the UnitarySynthesis transpiler
pass now chooses one and two-qubit unitary synthesis based on the error rates
reported in the Target. In particular, it runs all possible synthesis
methods supported by the plugin and chooses the option which will result in the
lowest error. For a one-qubit decomposition, it can target Pauli basis
(e.g. RZ-RX-RZ or RZ-RY-RZ), generic unitary basis (e.g. U), and a
few others. For a two-qubit decomposition, it can target any supercontrolled basis
(e.g. CNOT, iSWAP, B) or multiple controlled basis
(e.g. CZ, CH, ZZ^.5, ZX^.2, etc.).
The interface for UnitarySynthesisPlugin has two new
optional properties supports_gate_lengths_by_qubit and
supports_gate_errors_by_qubit which when set will add the
fields gate_lengths_by_qubit and gate_errors_by_qubit
respectively to the input options to the plugin’s run() method.
These new fields are an alternative view of the data provided by
gate_lengths and gate_errors but instead have the form:
{(qubits,):[Gate,length]} (where Gate is the instance
of Gate for that definition). This allows plugins to
reason about working with gates of the same type but but that
have different parameters set.
Added a new transpiler pass, UnrollForLoops, which is used
to unroll any ForLoopOp operations in a circuit. This pass
unrolls for-loops when possible, if there are no
ContinueLoopOp or BreakLoopOp inside the body
block of the loop. For example:
fromqiskit.transpiler.passesimportUnrollForLoopsfromqiskitimportQuantumCircuitunroll_pass=UnrollForLoops()qc=QuantumCircuit(1)# For loop over range 5withqc.for_loop(range(5))asi:qc.rx(i,0)# Unroll loop into 5 rx gatesunroll_pass(qc).draw("mpl")
Added a new parameter max_trials to pass VF2PostLayout
which, when specified, limits the number of layouts discovered and
compared when searching for the best layout.
This differs from existing parameters call_limit and time_limit
(which are used to limit the number of state visits performed by the VF2
algorithm and the total time spent by pass VF2PostLayout,
respectively) in that it is used to place an upper bound on the time
spent scoring potential layouts, which may be useful for larger
devices.
The CheckMap transpiler pass has a new keyword argument on its
constructor, property_set_field. This argument can be used to specify
a field in the property set to store the results of the analysis.
Previously, it was only possible to store the result in the field
"is_swap_mapped" (which is the default). This enables you to store the
result of multiple instances of the pass in a PassManager in
different fields.
Added a new argument, var_order, to the PhaseOracle class’s constructor to
enable setting the order in which the variables in the logical expression are being
considered. For example:
A new OpenQASM 2 parser is available in qiskit.qasm2. This has two entry points:
qasm2.load() and qasm2.loads(), for reading the source code from a file and from a
string, respectively:
importqiskit.qasm2program=""" OPENQASM 2.0; include "qelib1.inc"; qreg q[2]; h q[0]; cx q[0], q[1];"""bell=qiskit.qasm2.loads(program)
This new parser is approximately 10x faster than the existing ones at
QuantumCircuit.from_qasm_file() and QuantumCircuit.from_qasm_str() for large files,
and has less overhead on each call as well. The new parser is more extensible, customisable and
generally also more type-safe; it will not attempt to output custom Qiskit objects when the
definition in the OpenQASM 2 file clashes with the Qiskit object, unlike the current exporter.
See the qiskit.qasm2 module documentation for full details and more examples.
Improve the decomposition of multi-controlled Pauli-X and Pauli-Y rotations
with QuantumCircuit.mcrx() and QuantumCircuit.mcryon:math:`n() controls to \(16n - 40\) CX gates, for \(n \geq 4\). This improvement is based
on arXiv:2302.06377.
Qiskit now supports the representation of switch statements, using the new SwitchCaseOp
instruction and the QuantumCircuit.switch() method. This allows switching on a numeric
input (such as a classical register or bit) and executing the circuit that corresponds to the
matching value. Multiple values can point to the same circuit, and CASE_DEFAULT can be
used as an always-matching label.
You can also use a builder interface, similar to the other control-flow constructs to build up
these switch statements:
fromqiskitimportQuantumCircuit,QuantumRegister,ClassicalRegisterqreg=QuantumRegister(2)creg=ClassicalRegister(2)qc=QuantumCircuit(qreg,creg)qc.h([0,1])qc.measure([0,1],[0,1])withqc.switch(creg)ascase:withcase(0):# if the register is '00'qc.z(0)withcase(1,2):# if the register is '01' or '10'qc.cx(0,1)withcase(case.DEFAULT):# the default caseqc.h(0)
The switch statement has support throughout the Qiskit compiler stack; you can
transpile() circuits containing it (if the backend advertises its support for the
construct), and it will serialize to QPY.
The switch statement is not currently a feature of OpenQASM 3, but it is under active
design and consideration, which is
expected to be adopted in the near future. Qiskit Terra has experimental support for
exporting this statement to the OpenQASM 3 syntax proposed in the linked pull request, using
an experimental feature flag. To export a switch statement circuit (such as the one
created above) to OpenQASM 3 using this speculative support, do:
Added a new attribute eigenvalue_threshold
to the AdaptVQE class for
configuring a new kind of threshold to terminate the algorithm once
the eigenvalue changes less than a set value.
Added a new attribute gradient_threshold
to the AdaptVQE class
which will replace the threshold in the
future. This new attribute behaves the same as the existing threshold attribute but has a more
accurate name, given the introduction of additional threshold options
in the class.
Adds a flag local to the ComputeUncompute state fidelity class that
allows to compute the local fidelity, which is defined by averaging over
single-qubit projectors.
Gradient classes rearrange the gradient result according to the order of the input parameters now.
Example:
fromqiskit.algorithms.gradientsimportParamShiftEstimatorGradientfromqiskit.circuitimportQuantumCircuit,Parameterfromqiskit.primitivesimportEstimatorfromqiskit.quantum_infoimportSparsePauliOp# Create a circuit with a parameterp={i:Parameter(f'p{i}')foriinrange(3)}qc=QuantumCircuit(1)qc.rx(p[0],0)qc.ry(p[1],0)qc.rz(p[2],0)op=SparsePauliOp.from_list([("Z",1)])param_values=[0.1,0.2,0.3]# Create a gradient objectestimator=Estimator()grad=ParamShiftEstimatorGradient(estimator)result=grad.run(qc,op,[param_values]).result()# would produce a gradient of the form [df/dp0, df/dp1, df/dp2]result=grad.run(qc,op,[param_values],parameters=[[p[2],p[0]]]).result()# would produce a gradient of the form [df/dp2, df/dp0]
Added support for handling time-dependent Hamiltonians (i.e. singly
parametrized operators) to the
TrotterQRTE class.
To facilitate working with this, added the
num_timesteps
attribute and a matching keyword argument to the
TrotterQRTE
constructor to control the number of time steps to divide the full evolution.
Added support for observable evaluations at every time-step
during the execution of the
TrotterQRTE class. The
TimeEvolutionProblem.aux_operators is evaluated at every time
step if the ProductFormula.reps attribute of the input
product_formula argument in the constructor is set to 1.
Added extensions to the VQD algorithm, which allow
to pass a list of optimizers and initial points for the different
minimization runs. For example, the k-th initial point and
k-th optimizer will be used for the optimization of the
k-1-th exicted state.
The constructor of Clifford now can take any Clifford gate object
up to 3 qubits as long it implements a to_matrix method,
including parameterized gates such as Rz(pi/2), which were not
convertible before.
Added the method StabilizerState.equiv,
that checks if the generating sets of two stabilizer states generate the same stabilizer group.
For example, the stabilizer group of the two-qubit Bell state contains the four elements
\(\{II, XX, -YY, ZZ\}\) and hence can be generated by either \([XX, ZZ]\),
\([XX, -YY]\) or \([-YY, ZZ]\).
Added a new method, partial_transpose(), to the
qiskit.quantum_info module’s DensityMatrix class. This
method is used to compute the partial transposition of a density matrix,
which is necessary for detecting entanglement between bipartite quantum
systems.
The conjugate operator has dimensions (4, 2, 3) x (4, 2, 3), which is consistent with permutation
moving qutrit to position 0, qubit to position 1, and the 4-qudit to position 2.
Natively support the construction of SparsePauliOp objects with
ParameterExpression coefficients, without requiring the explicit construction
of an object-array. Now the following is supported:
fromqiskit.circuitimportParameterfromqiskit.quantum_infoimportSparsePauliOpx=Parameter("x")op=SparsePauliOp(["Z","X"],coeffs=[1,x])# free_params will be: ParameterView([x])free_params=op.parameters# assign the value 2 to the parameter xbound=op.assign_parameters([2])
These new classes are instances of ScalableSymbolicPulse. With the exception of
the Sawtooth phase, behavior is identical to that of the corresponding waveform generator
function (e.g. sin()). The phase for the Sawtooth class
is defined such that a phase of \(2\pi\) shifts by a full cycle.
Added support to QPY (qiskit.qpy) for working with pulse
ScheduleBlock instances with unassigned references,
and preserving the data structure for the reference to subroutines.
This feature allows users to serialize and deserialize a template pulse
program for tasks such as pulse calibration. For example:
A new method CalibrationEntry.user_provided() has been added to
calibration entries. This method can be called to check whether the entry
is defined by an end user or backend.
Added a new method Target.get_calibration() which provides
convenient access to the calibration of an instruction in a Target object
This method can be called with parameter args and kwargs, and
it returns a pulse schedule built with parameters when the calibration
is templated with parameters.
The BackendV2Converter class has a new keyword argument,
filter_faulty, on its constructor. When this argument is set to True
the converter class will filter out any qubits or operations listed
as non-operational in the BackendProperties payload for the
input BackendV1. While not extensively used a
BackendProperties object supports annotating both qubits
and gates as being non-operational. Previously, if a backend had set that
flag on any qubits or gates the output BackendV2 instance and
its Target would include all operations whether they were
listed as operational or not. By leveraging the new flag you can filter
out these non-operational qubits and gates from the Target.
When the flag is set the output backend will still be listed as the full
width (e.g. a 24 qubit backend with 4 qubits listed as not operational will
still show it has 24 qubits) but the faulty qubits will not have any
operations listed as being supported in the Target.
The Options class now implements the
the Mapping protocol and __setitem__ method. This means that
Options instances now offer the same interface as standard
dictionaries, except for the deletion methods (__delitem__, pop,
clear). Key assignments are validated by the validators,
if any are registered.
Added a new function, staged_pass_manager_drawer(), which is used
for visualizing a StagedPassManager instance. It draws the full
pass manager with each stage represented as an outer box.
The StagedPassManager.draw() method has been updated to include
visualization of the stages in addition to the overall pass manager. The
stages are represented by outer boxes in the visualization. In previous
releases the stages were not included in the visualization. For example:
Added a new keyword argument, figsize, to the
plot_bloch_multivector() function. This
argument can be used to set a size for individual Bloch sphere sub-plots.
For example, if there are \(n\) qubits and figsize is set to
(w,h), then the overall figure width is set to \(n \cdot w\), while the
overall height is set to \(h\).
Added a new keyword argument, font_size, to the
plot_bloch_multivector() function. This argument
can be used to control the font size in the output visualization.
Added two new keyword arguments, title_font_size and title_pad, to
the plot_bloch_multivector() function. These
arguments can be used to control the font size of the overall title and its
padding respectively.
The minimum supported Rust version (MSRV) has been increased from 1.56.1
to 1.61.0. If you’re are building Qiskit from source you will now need to
ensure that you have at least Rust 1.61.0 installed to be able to build
Qiskit. This change was made because several upstream dependencies have increased
their MSRVs.
Removed the usage of primitives with the context manager and the initialization with circuits,
(observables only for Estimator), and parameters
which was deprecated in the Qiskit Terra 0.22.0 release in October 2022.
The maximum number of trials evaluated when searching for the best
layout using VF2Layout and VF2PostLayout is now
limited in
level_1_pass_manager(),
level_2_pass_manager(),
and
level_3_pass_manager()
to 2500, 25000, and 250000, respectively. Previously,
all found possible layouts were evaluated. This change was made to prevent
transpilation from hanging during layout scoring for circuits with many
connected components on larger devices, which scales combinatorially
since each connected component would be evaluated in all possible
positions on the device. To perform a full search as
before, manually run VF2PostLayout over the transpiled circuit
in strict mode, specifying 0 for max_trials.
The previously deprecated condition attribute of the
DAGDepNode class has been removed. It was marked as deprecated
in the 0.18 release (07-2021). Instead you should use the
condition attribute of the op attribute to
access the condition of an operation node. For other node types there
is no condition to access.
The default value of metadata in both DAGCircuit and
DAGDependency has been changed from None to {} for compatibility
with the matching metadata attribute of QuantumCircuit.
The CouplingMap.__eq__`() method has been updated to check that the edge lists of the
underlying graphs contain the same elements. Under the assumption that the underlying graphs are
connected, this check additionally ensures that the graphs have the same number of nodes with
the same labels. Any code using CouplingMap()==CouplingMap() to check object equality
should be updated to CouplingMap()isCouplingMap().
When running the transpile() function with a BackendV1
based backend or a BackendProperties via the backend_properties
keyword argument that has any qubits or gates flagged as faulty the function
will no longer try to automatically remap the qubits based on this information.
The method by which transpile() attempted to do this remapping was
fundamentally flawed and in most cases of such a backend it would result
an internal error being raised. In practice very few backends ever set the
fields in BackendProperties to flag a qubit or gate as faulty.
If you were relying on transpile() to do this
re-mapping for you, you will now need to manually do that and pass a
mapped input to the coupling_map and backend_properties arguments
which has filtered out the faulty qubits and gates and then manually re-map
the output.
The result of transpilations for fixed seeds may have changed compared to
previous versions of Qiskit Terra. This is because of internal tweaks to
the routing algorithm used by SabreSwap and SabreLayout,
which are the default routing and layout passes respectively, to make them
significantly faster for large circuits.
The QuantumCircuitmetadata attribute now
always returns a dictionary, and can only be set to a dictionary. Previously,
its default value was None, and could be manually set to None or a
dictionary.
The deprecated modules factorizers and linear_solvers, containing
HHL and Shor have been removed from
qiskit.algorithms. These functionalities
were originally deprecated as part of the 0.22.0 release (released on
October 13, 2022). You can access the code through the Qiskit Textbook instead:
Linear Solvers (HHL) ,
Factorizers (Shor)
Target.update_from_instruction_schedule_map() no longer raises
KeyError nor ValueError when qubits are missing in the target instruction
or inst_name_map is not provided for the undefined instruction.
In the former case, it just ignores the input InstructionScheduleMap's
definition for undefined qubits. In the latter case, a gate mapping is pulled from
the standard Qiskit gates and finally, a custom opaque Gate object is defined
from the schedule name if no mapping is found.
The deprecated max_credits argument to execute(), assemble() and all
of the Qobj configurations (e.g. QasmQobjConfig and
PulseQobjConfig) has been removed. This argument dates back
to early versions of Qiskit which was tied more closely to the IBM
Quantum service offering. At that time the max_credits field was part
of the “credit system” used by IBM Quantum’s service offering. However,
that credit system has not been in use on IBM Quantum backends for
nearly three years and also Qiskit is not tied to IBM Quantum’s service
offerings anymore (and hasn’t been for a long time). If you were relying on
this option in some way for a backend you will need to ensure that your
BackendV2 implementation exposes a max_credits field in
its Options object.
The name attribute on the BackendV2 based
fake backend classes in qiskit.providers.fake_provider have changed
from earlier releases. Previously, the names had a suffix "_v2" to
differentiate the class from the BackendV1 version. This suffix
has been removed as having the suffix could lead to inconsistencies with
other snapshotted data used to construct the backend object.
The transpiler routing pass, BIPMapping has been deprecated
and will be removed in a future release. It has been replaced by an external
plugin package: qiskit-bip-mapper. Details for this new package can
be found at the package’s github repository:
The pass was made into a separate plugin package for two reasons, first
the dependency on CPLEX makes it harder to use and secondly the plugin
packge more cleanly integrates with transpile().
Misspelled aquire_alignment in the class Target has been replaced by
correct spelling acquire_alignment.
The old constructor argument aquire_alignment and Target.aquire_alignment
are deprecated and will be removed in a future release.
Use Target.acquire_alignment instead to get and set the alignment constraint value.
Setting the QuantumCircuitmetadata attribute
to None has been deprecated and will no longer be supported in a future
release. Instead, users should set it to an empty dictionary if they want
it to contain no data.
All of the following features are now deprecated, after having been made pending deprecation
since 0.22.0. More information is available at https://qisk.it/algo_migration.
The PauliTable and StabilizerTable
are deprecated and will be removed in a future release.
Instead, the PauliList should be used.
With this change, table() has been deprecated
so that you should operate directly from tableau()
without it.
Assignment of complex values to ParameterExpression in any Qiskit Pulse object
now raises a PendingDeprecationWarning. This will align the Pulse module with
other modules where such assignment wasn’t possible to begin with. The typical use
case for complex parameters in the module was the SymbolicPulse library. As of
Qiskit-Terra 0.23.0 all library pulses were converted from complex amplitude
representation to real representation using two floats (amp,angle), as used in the
ScalableSymbolicPulse class. This eliminated the need for complex parameters.
Any use of complex parameters (and particularly custom-built pulses) should be
converted in a similar fashion to avoid the use of complex parameters.
The AmplitudeEstimation class now correctly warns if an EstimationProblem
with a set is_good_state property is passed as input, as it is not supported and ignored.
Previously, the algorithm would silently ignore this option leading to unexpected results.
QuantumCircuit.append() will now correctly raise an error if given an incorrect number of
classical bits to apply to an operation. Fix #9385.
The BarrierBeforeFinalMeasurements and MergeAdjacentBarriers transpiler
passes previously had a non-deterministic order of their emitted Barrier instructions.
This did not change the semantics of circuits but could, in limited cases where there were
non-full-width barriers, cause later stochastic transpiler passes to see a different topological
ordering of the circuit and consequently have different outputs for fixed seeds. The passes
have been made deterministic to avoid this.
The return type of run() will now
always be the same as that of its first argument. Passing a single circuit
returns a single circuit, passing a list of circuits, even of length 1,
returns a list of circuits.
See #9798.
Fixed a bug where PauliOp.adjoint() did not return a correct value for Paulis
with complex coefficients, like PauliOp(Pauli("iX")).
Fixed #9433.
Fixed an issue with the circuit drawer function circuit_drawer()
and QuantumCircuit.draw() method when using the text method and
the argument vertical_compression="low" where it would use an incorrect
character for the top-right corner of boxes used to represent gates
in the circuit.
Fixed an issue with the Gate.control() method where it previously
would incorrectly handle str or None input types for the
ctrl_state argument.
Fixed an edge case in the construction of Pauli instances; a string with an optional
phase and no qubits is now a valid label, making an operator with no qubits (such as
Pauli("-i")). This was already possible when using the array forms, or empty slices.
Fixed #9720.
Fixed an issue when using the pulse macro
measure() when working with a
BackendV2 based backend. Previously, trying to use
qiskit.pulse.macros.measure() with a BackendV2
based backend would have resulted in an error.
Fixed #9488
Fixed an issue with the marginal_distribution() function where it
would incorrectly raise an error when an input counts dictionary was using
a numpy integer type instead of the Python int type. The underlying function
always would handle the different types correctly, but the input type
checking was previously incorrectly raising a TypeError in this case.
Fixed a bug where Parameter.is_real() did not return None when
the parameter is not bound.
Fixed #8619.
Fixed the transpiler routing passes StochasticSwap,
SabreSwap, LookaheadSwap, and BasicSwap
so that they consistently raise a TranspilerError when their
respective .run() method is called if the passes were initialized
with coupling_map=None. Previously, these passes would raise errors
in this case but they were all caused by side effects and the specific
exception was not predictable.
Fixed #7127
Manually setting an item in QuantumCircuit.data will now correctly allow the operation
to be any object that implements Operation, not just a circuit.Instruction.
Note that any manual mutation of QuantumCircuit.data is discouraged; it is not
usually any more efficient than building a new circuit object, as checking the invariants
surrounding parametrised objects can be surprisingly expensive.
Fixed a bug when constructing DAGDependency from
within the TemplateOptimization transpiler pass,
which could lead to incorrect optimizations.
Fixed a bug in TensoredOp.to_matrix() where the global coefficient of the operator
was multiplied to the final matrix more than once. Now, the global coefficient is correclty
applied, independent of the number of tensored operators or states.
Fixed #9398.
Fixed global-phase handling in the UnrollCustomDefinitions transpiler pass if the
instruction in question had a global phase, but no instructions in its definition field.
Fixed the the type annotations for the transpile() function.
The return type is now narrowed correctly depending on whether a
single circuit or a list of circuits was passed.
Fixed a bug where IterativePhaseEstimation was generating the wrong circuit, causing the
algorithm to fail for simple cases. Fixed #9280.
A bug has been fixed which had allowed broadcasting when a
PauliList is initialized from Paulis or labels. For
instance, the code PauliList(["XXX","Z"]) now raises a
ValueError rather than constructing the equivalent of
PauliList(["XXX","ZZZ"]).
The OpenQASM 2 exporter (QuantumCircuit.qasm()) will now output definitions for gates used
only in other gates’ definitions in a correct order. See
#7769 and
#7773.
Standard gates defined by Qiskit, such as RZXGate, will now have properly parametrised
definitions when exported using the OpenQASM 2 exporter (QuantumCircuit.qasm()). See
#7172.
The OpenQASM 2 exporter will now output gates with no known definition with opaque statements,
rather than failing. See #5036.
An issue that prevented transpile() from working when passed
a list of CouplingMap objects was fixed. Note
that passing such a list of coupling maps is deprecated and will not be
possible starting with Qiskit Terra 0.25. Fixes
#9885.
Previous to this release, the figsize argument of
plot_bloch_multivector() was not used by the
visualization, making it impossible to change its size (e.g. to shrink
it for single-qubit states). This release fixes it by introducing a use
for the figsize argument.
Fixed an issue in transpile() with optimization_level=1 (as
well as in the preset pass managers returned by
generate_preset_pass_manager() and level_1_pass_manager())
where previously if the routing_method and layout_method arguments
were not set and no control flow operations were present in the circuit
then in cases where routing was required the
VF2PostLayout transpiler pass would not be run. This was the
opposite of the expected behavior because VF2PostLayout is
intended to find a potentially better performing layout after a heuristic
layout pass and routing are run.
Fixed #9936
Construction of a Statevector from a QuantumCircuit containing
zero-qubit operations will no longer raise an error. These operations impart a global phase on
the resulting statevector.
Fixed an issue in tranpiler passes for padding delays, which did not respect target’s constraints
and inserted delays even for qubits not supporting Delay instruction.
PadDelay and PadDynamicalDecoupling are fixed
so that they do not pad any idle time of qubits such that the target does not support
Delay instructions for the qubits.
Also legacy scheduling passes ASAPSchedule and ALAPSchedule,
which pad delays internally, are fixed in the same way.
In addition, transpile() is fixed to call PadDelay with a target object
so that it works correctly when called with scheduling_method option.
Fixed #9993
Fixed the type annotations on the
QuantumCircuit.assign_parameters()
method to correctly reflect the change in return type depending on the
value of the inplace argument.
Fixed a performance scaling issue with the VF2Layout
and VF2PostLayout passes in the preset pass managers and
transpile(), which would occur when transpiling circuits with many
connected components on large devices. Now the transpiler passes set
upper bounds on the number of potential layouts that will be evaluated.
Fixed an issue in the state_to_latex() function where it would
potentially produce invalid LaTeX due to unintended coefficient rounding.
This could also result in errors when the state_drawer() was called.
Fixed #9297.
Fixes a bug in the Optimize1qGatesDecomposition transformation pass
where the score for substitutions was wrongly calculated when the gate
errors are zero.
The method ECRGate.inverse() now returns another ECRGate instance
rather than a custom gate, since it is self inverse.
Clip probabilities in the QuantumState.probabilities() and
QuantumState.probabilities_dict() methods to the interval [0,1].
This fixes roundoff errors where probabilities could e.g. be larger than 1, leading
to errors in the shot emulation of the sampler.
Fixed #9761.
Fixed a bug in the BackendSampler where the binary probability bitstrings
were truncated to the minimal number of bits required to represent the largest outcome
as integer. That means that if e.g. {"0001":1.0} was measured, the result was truncated
to {"1":1.0}.
Fixed an issue with the PassManagerConfig.from_backend()
constructor method when it was used with a BackendV1 based
simulator backend. For some simulator backends which did not populate
some optional fields the constructor would error.
Fixed #9265 and
#8546
Fixed the BackendSampler and BackendEstimator to run successfully
with a custom bound_pass_manager. Previously, the execution for single circuits with
a bound_pass_manager would raise a ValueError because a list was not returned
in one of the steps.
The GateDirection transpiler pass will no longer reject gates that have been given
explicit calibrations, but do not exist in the generic coupling map or target.
Fixed an issue with the CommutationChecker class where it would
attempt to internally allocate an array for \(2^{n}\) qubits when it
only needed an array to represent \(n\) qubits. This could cause
an excessive amount of memory for wide gates, for example a 4 qubit
gate would require 32 gigabytes instead of 2 kilobytes.
Fixed #9197
Getting empty calibration from InstructionProperties raises
AttributeError has been fixed. Now it returns None.
Fixed qasm() so that it appends ; after reset instruction.
Register and parameter names will now be escaped during the OpenQASM 3 export
(qasm3.dumps()) if they are not already valid identifiers. Fixed #9658.
QPY (using qpy.load()) will now correctly deserialize StatePreparation
instructions. Previously, QPY would error when attempting to load a file containing one.
Fixed #8297.
Fixed a bug in random_circuit() with 64 or more qubits and conditional=True, where
the resulting circuit could have an incorrectly typed value in its condition, causing a variety
of failures during transpilation or other circuit operations. Fixed #9649.
Fixed an issue with the OneQubitEulerDecomposer class’s methods
angles() and angles_and_phase()
would error if the input matrix was of a dtype other than complex/np.cdouble. In earlier
releases this worked fine but this stopped working in Qiskit Terra 0.23.0
when the internals of OneQubitEulerDecomposer were re-written
in Rust.
Fixed #9827
The Qiskit gates CCZGate, CSGate, CSdgGate are not defined in
qelib1.inc and, therefore, when dump as OpenQASM 2.0, their definition should be inserted in the file.
Fixes #9559,
#9721, and
#9722.
Greatly improving the runtime performance of the AerSimulator and the legacy
QasmSimulator, StatevectorSimulator, and UnitarySimulator
classes by directly converting the input QuantumCircuit objects to an internal
C++ representation instead of first serializing the circuit to a QasmQobj. This
improvement will be most noticeable for circuits with a small number of qubits or parameterized
circuits using the parameter_binds keyword argument.
Added a new class method from_backend_properties() to
the NoiseModel. This enables constructing a new NoiseModel
from a BackendProperties object. Similar functionality used
to be present in the NoiseModel.from_backend() constructor,
however it was removed since a BackendProperties object alone
doesn’t contain sufficient information to create a NoiseModel
object.
Added a new class, AerDensityMatrix, to the qiskit_aer.quantum_info
module. This class is used to provide the same interface to the
upstream DensityMatrix class in Qiskit but backed by
Qiskit Aer’s simulation.
Added a new keyword argument, abelian_grouping, to
the Estimator. This argument is used to control whether the
Estimator will group the input observables into qubit-wise
commutable observables which reduces the number of circuit executions
required to compute the expectation value and improves the runtime
performance of the Estimator. By default this is set to
True.
AerState has a new method initialize_density_matrix() that sets a density matrix
to AER::QV::DensityMatrix. This method will be called in q.i.states.DensityMatrix
to initialize its data with ndarray. initialize_density_matrix() has a boolean
argument that specifies copy or share of ndarray data. If the data is shared with
C++ and python, the data must not be collected in python while C++ accesses it.
The overhead for running simulations with run()
(for all simulator backend classess) has been greatly reduced. This was
accomplished by no longer internally serializing
QuantumCircuit objects into
QasmQobj and instead the
QuantumCircuit object directly to
an internal C++ circuit structure used for simulation. This improvement
is most noticeable for simulations of circuts with a small number of qubits
or parameterized circuits using the parameter_binds keyword argument
of run().
Note that pulse simualation (via the now deprecated PulseSimulator)
and DASK-based simulation still use the internal serialization and will
not see this performance improvement.
Added a new method to the AerJob, circuits(), which
returns a list of QuantumCircuit objects. This method returns
None if Qobj is used for simulation.
AerState and AerStatevector now support applying Kraus operators.
In AerStatevector, one of the Kraus operators is applied randomly to the quantum state based on the error probabilities.
Added a new simulation method based on NVIDIA’s cuTensorNet
APIs of cuQuantum SDK. This provides a GPU accelerated general tensor
network simulator that can simulate any quantum circuit, by internally
translating the circuit into a tensor network to perform the simulation.
To use this simulation method, set method="tensor_network" and
device="GPU" when initializing an AerSimulator object.
For example:
This method supports both statevector and density matrix simulations.
Noise simulation can also be done with a density matrix single shot
simulation if there are not any SaveStatevector operations
in the circuit.
This new simulation method also supports parallelization with multiple GPUs and
MPI processes by using tensor network slicing technique. However, this type of
simulation will likely take a very long time if the input circuits are
complicated.
The BLA_VENDOR environment variable can now be specified to use a
different BLAS library when building Qiskit Aer from source. By default
if this is not specified OpenBLAS will be used by default. If
the BLAS library specified in BLA_VENDOR` can not be found then the
Cmake build process will stop.
This release of Qiskit Aer is not compatible with the Conan 2.X release
series. If you are building Qiskit Aer from source manually ensure that
you are using a Conan 1.x release. Compatibility with newer versions
of Conan will be fixed in a future release. You can refer to
issue #1730 for
more details.
The default behavior of the Estimator primitive will now
group the input observable into qubit-wise commutable observables.
The grouping reduces the number of circuits to be executed and improves
the performance. If you desire the previous behavior you can initialize
your Estimator instance with the keyword argument
abelian_grouping=False.
Removed the usage of primitives with the context manager and the initialization with circuits,
(observables only for Estimator), and parameters
which has been deprecated in the Qiskit Terra 0.22.0 release in October 2022.
The behavior of run() method has changed when invalid
or otherwise unsimulatable QuantumCircuit objects are passed as
an input. Previously, in these cases the run() method
would return an AerJob whose result() method would
return a Result with the ERROR or PARTIALCOMPLETED
(depending on whether all the circuit inputs or only some were invalid or not).
Starting in this release instead of returning a result object with these statuses
an exception will be raised instead. This change was necessary because
of the performance improvements by no longer internally serializing the
QuantumCircuit objects to a Qobj before passing it to C++, instead
the direct conversion from QuantumCircuit now errors directly when
trying to simulate a circuit Qiskit Aer is unable to execute. If you desire the
previous behavior you can build Qiskit Aer in standalone mode and manually
serialize your QuantumCircuit objects to a JSON representation of
the QasmQobj which you then pass to the standalone Aer binary
which will retain the previous behavior.
A deprecated method add_nonlocal_quantum_error() in NoiseModel has been
removed. No alternative method is available. If you want to add non-local quantum errors,
you should write a transpiler pass that inserts your own quantum error into a circuit,
and run the pass just before running the circuit on Aer simulator.
The NoiseModel.from_backend() now has changed not to accept BackendProperties
object as a backend argument. Use newly added NoiseModel.from_backend_properties()
method instead.
A deprecated standard_gates argument broadly used in several methods and functions
(listed below) across noise module has been removed.
NoiseModel.from_backend() and noise.device.basic_device_gate_errors()
kraus_error(), mixed_unitary_error(), pauli_error() and
depolarizing_error() in noise.errors.standard_errors
QuantumError.__init__()
No alternative means are available because the user should be agnostic about
how the simulator represents noises (quantum errors) internally.
The constructor of QuantumError has now dropped the support of deprecated
json-like input for noise_ops argument.
Use the new styple input for noise_ops argument instead, for example,
fromqiskit.circuit.libraryimportIGate,XGatefromqiskit_aer.noiseimportQuantumErrorerror=QuantumError([((IGate(),[1]),0.9),((XGate(),[1]),0.1),])# json-like input is no longer accepted (the following code fails)# error = QuantumError([# ([{"name": "I", "qubits": [1]}], 0.9),# ([{"name": "X", "qubits": [1]}], 0.1),# ])
Also it has dropped deprecated arguments:
number_of_qubits: Use QuantumCircuit to define noise_ops instead.
atol: Use QuantumError.atol attribute instead.
standard_gates: No alternative is available (users should not too much care about
internal representation of quantum errors).
The deprecated noise.errors.errorutils module has been entirely removed
and no alternatives are available.
All functions in the module were helper functions meant to be used
only for implementing functions in standard_errors
(i.e. they should have been provided as private functions)
and no longer used in it.
The deprecated utils.noise_remapper have been entirely removed and no alternatives
are available since the C++ code now automatically truncates and remaps noise models
if it truncates circuits.
All deprecated functions (pauli_operators() and reset_operators())
and class (NoiseTransformer) in utils.noise_transformation module
have been removed, and no alternatives are available.
They were in fact private functions/class used only for implementing
approximate_quantum_error() and should not have been public.
The previously deprecated qobj argument name of the
AerSimulator and PulseSimulator classes’
run() method has now been removed. This argument
name was deprecated as part of the Qiskit Aer 0.8.0 release and has
been by the circuits and schedules argument name respectively.
Aer’s setup.py has been updated to no longer attempt to make calls to pip to
install build requirements, both manually and via the setup_requires option in
setuptools.setup. The preferred way to build Aer is to use a PEP 517-compatible
builder such as:
pip install .
This change means that a direct call to setup.py will no longer work if the
build requirements are not installed. This is inline with modern Python packaging
guidelines.
Support for running Qiskit Aer with Python 3.7 support has been deprecated
and will be removed in a future release. This means
starting in a future release you will need to upgrade the Python
version you’re using to Python 3.8 or above.
The PulseSimulator backend has been deprecated and will be
removed in a future release. If you’re using the PulseSimulator
backend to perform pulse level simulation, instead you should use the
Qiskit Dynamics library
instead to perform the simulation. Qiskit Dynamics provides a more
flexible and robust pulse level simulation framework than the
PulseSimulator backend.
The qobj() method of the AerJob class is
now deprecated and will be removed in a future release. The use of
the qobj format as input to run() has been
deprecated since qiskit-aer 0.9.0 and in most cases this method
would return None now anyway. If you’d like to get the input
to the run() method now you can use the circuits()
method instead, which will return the QuantumCircuit
objects that were simulated in the job.
A warnings argument broadly used in several methods and functions
across noise module has been deprecated in favor of
the use of filtering functions in Python’s standard warnings library.
Fixed an issue when creating a new AerStatevector instance
from a numpy.ndarray that had non-contiguous memory. Previously,
this would result in unexpected behavior (and a potential error) as
the AerStatevector assumed the input array was contiguous. This
has been fixed so that memory layout is checked and the numpy.ndarray
will be copied internally as a contiguous array before using it.
Fixed an issue with the Sampler class where it would previously
fail if the input QuantumCircuit contained multiple
multiple classical registers.
Fixed #1679
The bits count of classical register used on the GPU was not set before
calculating free available memory for chunks that causes infinite loop.
So this fix set bits count before allocating chunks if batch shots
execution is enabled.
Fix build errors and test errors when enabling GPU but disabling cuQuantum.
Fixed an issue in the matrix product state simulation method (i.e.
setting the keyword argument method="matrix_product_state" when
initializing an AerSimulator object) where the simulator
would incorrectly sort the qubits prior to performing measurment
potentially resulting in an infinite loop. This has been fixed so
the measurement of the qubits occurs in the order of the current MPS
structure and then sorting afterwards as a post-processing step. This also
will likely improve the performance of the simulation method and enable
more accurate representation of entangled states.
Fixed #1694
The AerSimulator backend with methods:
statevector
density_matrix
matrix_product_state
stabilizer
now report that they support break_loop and continue_loop instructions when used
as backends for the Terra transpile() function. The simulators
already did support these, but had just not been reporting it.
This release removes the overly restrictive version constraints set in the
requirements for the package added in 0.20.1. For the 0.20.1 the only dependency
that was intended to have a version cap was the requests-ntlm package as its
new release was the only dependency which currently has an incompatibility with
qiskit-ibmq-provider. The other version caps which were added as part of
0.20.1 were causing installation issues in several environments because it made
the qiskit-ibmq-provider package incompatible with the dependency versions
used in other packages.
Add a decomposition of an ECRGate into Clifford gates (up to a global phase)
to the standard equivalence library.
Fixed an issue with the BackendV2Converter class when wrapping
a BackendV1-based simulator. It would error if either
the online_date field in the BackendConfiguration for the
simulator was not present or if the simulator backend supported ideal
implementations of gates that involve more than 1 qubit.
Fixed #9562.
Fixed an incorrect return value of the method BackendV2Converter.meas_map()
that had returned the backend dt instead.
The deprecated Qubit and Clbit properties register and
index will now be correctly round-tripped by QPY (qiskit.qpy) in all
valid usages of QuantumRegister and ClassicalRegister. In earlier releases
in the Terra 0.23 series, this information would be lost. In versions before 0.23.0, this
information was partially reconstructed but could be incorrect or produce invalid circuits for
certain register configurations.
The correct way to retrieve the index of a bit within a circuit, and any registers in that
circuit the bit is contained within is to call QuantumCircuit.find_bit(). This method
will return the correct information in all versions of Terra since its addition in version 0.19.
Fixed a bug in the VQD algorithm where
the energy evaluation function could not process batches of parameters, making it
incompatible with optimizers with max_evals_grouped>1.
Fixed #9500.
Fixed bug in QNSPSA which raised a type error when the computed fidelities
happened to be of type int but the perturbation was of type float.
Since qiskit-ibmq-provider is now deprecated, the dependencies have been bumped and fixed to the
latest working versions. There was an issue with the latest version of the requests-ntlm package
which caused some end to end tests to fail.
An edge case of pickle InstructionScheduleMap with
non-picklable iterable arguments is now fixed.
Previously, using an unpickleable iterable as the arguments
parameter to InstructionScheduleMap.add() (such as dict_keys)
could cause parallel calls to transpile() to fail. These
arguments will now correctly be normalized internally to list.
Fixed a performance bug in ReverseEstimatorGradient where the calculation
did a large amount of unnecessary copies if the gradient was only calculated for
a subset of parameters, or in a circuit with many unparameterized gates.
Fixed a bad deprecation of Register.name_format which had made the class attribute
available only from instances and not the class. When trying to send dynamic-circuits jobs to
hardware backends, this would frequently cause the error:
This release of the qiskit-ibmq-provider package marks the package as deprecated and will be retired and archived
in the future. The functionality in qiskit-ibmq-provider has been supersceded by 3 packages qiskit-ibm-provider,
qiskit-ibm-runtime, and qiskit-ibm-experiment which offer different subsets of functionality that
qiskit-ibmq-provider contained. You can refer to the table here:
As of version 0.20.0, qiskit-ibmq-provider has been deprecated with its support
ending and eventual archival being no sooner than 3 months from that date.
The function provided by qiskit-ibmq-provider is not going away rather it has being split out
to separate repositories. Please see https://github.com/Qiskit/qiskit-ibmq-provider#migration-guides.
In the upcoming terra release there will be a release candidate tagged
prior to the final release. However changing the version string for the
package is blocked on the qiskit-ibmq-provider right now because it is trying
to parse the version and is assuming there will be no prelease suffix on
the version string (see #8200
for the details). PR #1135
fixes this version parsing to use the regex from the
pypa/packaging project which handles all the PEP440 package versioning
include pre-release suffixes. This will enable terra to release an
0.21.0rc1 tag without breaking the qiskit-ibmq-provider.
PR #1129 updates
least_busy() method to no longer support BaseBackend as a valid
input or output type since it has been long deprecated in qiskit-terra and has recently
been removed.
threading.currentThread and notifyAll were deprecated in Python 3.10 (October 2021)
and will be removed in Python 3.12 (October 2023).
PR #1133 replaces them
with threading.current_thread, notify_all added in Python 2.6 (October 2008).
Calls to run a quantum circuit with dynamic=True now raise an error
that asks the user to install the new qiskit-ibm-provider.
This release officially deprecates the Qiskit IBMQ provider project as part of the Qiskit metapackage.
This means that in a future release, pipinstallqiskit will no longer automatically include qiskit-ibmq-provider.
If you’re currently installing or listing qiskit as a dependency to get qiskit-ibmq-provider, you
should update to explicitly include qiskit-ibmq-provider as well. This is being done as the Qiskit
project moves towards a model where the qiskit package only contains the common core functionality for
building and compiling quantum circuits, programs, and applications.
Packages that build on that core or link Qiskit to hardware or simulators will be installable as separate packages.
Performance improvements to SabreLayout. The pass
is now primarily written in Rust which can lead to a runtime
improvement, however the bigger improvement is in the quality of
the output (on average, fewer SwapGate gates
introduced by SabreSwap). For example, running
SabreLayout and SabreSwap on Bernstein
Vazirani circuits targeting the FakeSherbrooke backend
yields the following results:
This release also deprecates support for running with Python 3.7. A DeprecationWarning
will now be emitted if you run Qiskit with Python 3.7. Support for Python 3.7 will be removed
as part of the 0.25.0 release (currently planned for release in July 2023), at which point
you will need Python 3.8 or newer to use Qiskit.
can be initialized with new parameter angle, such that two float parameters could be provided:
amp and angle. Initialization with complex amp is still supported.
The AdaptVQE class has a new attribute,
eigenvalue_history, which is used to track
the lowest achieved energy per iteration of the AdaptVQE. For example:
the returned value of calc.history should be roughly [-1.85727503] as
there is a single iteration.
The runtime logging when running the AdaptVQE has been improved.
When running the class now, DEBUG and INFO level log messages
will be emitted as the class runs.
Added a new transpiler pass, CollectAndCollapse, to collect and to consolidate
blocks of nodes in a circuit. This pass is designed to be a general base class for
combined block collection and consolidation. To be completely general, the work of
collecting and collapsing the blocks is done via functions provided during
instantiating the pass. For example, the CollectLinearFunctions has been
updated to inherit from CollectAndCollapse and collects blocks of
CXGate and SwapGate gates, and replaces each block with a
LinearFunction. The CollectCliffords which is also now
based on CollectAndCollapse, collects blocks of “Clifford” gates and
replaces each block with a Clifford.
The interface also supports the option do_commutative_analysis, which allows
to exploit commutativity between gates in order to collect larger blocks of nodes.
For example, collecting blocks of CX gates in the following circuit:
qc=QuantumCircuit(2)qc.cx(0,1)qc.z(0)qc.cx(1,0)
using do_commutative_analysis enables consolidating the two CX gates, as
the first CX gate and the Z gate commute.
Added a new class BlockCollector that implements various collection strategies,
and a new class BlockCollapser that implements various collapsing strategies.
Currently BlockCollector includes the strategy to greedily collect all gates
adhering to a given filter function (for example, collecting all Clifford gates), and
BlockCollapser includes the strategy to consolidate all gates in a block to a
single object (or example, a block of Clifford gates can be consolidated to a single
Clifford).
Added a new CollectCliffords transpiler pass that collects blocks of Clifford
gates and consolidates these blocks into qiskit.quantum_info.Clifford objects.
This pass inherits from CollectAndCollapse and in particular supports the option
do_commutative_analysis.
It also supports two additional options split_blocks and min_block_size.
See the release notes for CollectAndCollapse and CollectLinearFunctions
for additional details.
The CollectLinearFunctions transpiler pass has several new arguments
on its constructor:
do_commutative_analysis: enables exploiting commutativity between gates
in order to collect larger blocks of nodes.
split_blocks: enables spliting collected blocks into sub-blocks over
disjoint subsets of qubits. For example, in the following circuit:
the single block of CX gates over qubits {0,1,2,3} can be split into two disjoint
sub-blocks, one over qubits {0,2} and the other over qubits {1,3}.
min_block_size: allows to specify the minimum size of the block to be consolidated,
blocks with fewer gates will not be modified. For example, in the following circuit:
qc=QuantumCircuit(4)qc.cx(1,2)qc.cx(2,1)
the two CX gates will be consolidated when min_block_size is 1 or 2, and will remain unchanged
when min_block_size is 3 or larger.
The DAGCircuit.replace_block_with_op() method will now
return the new DAGOpNode that is created when the block
is replaced. Previously, calling this method would not return anything.
Added a new class PermutationGate for
representing permutation logic as a circuit element. Unlike the existing
Permutation circuit library element
which had a static definition this new class avoids synthesizing a permutation
circuit when it is declared. This delays the actual synthesis to the transpiler.
It also allows enables using several different algorithms for synthesizing
permutations, which are available as high-level-synthesis
permutation plugins.
Another key feature of the PermutationGate is
that implements the __array__ interface for efficiently returning a unitary
matrix for a permutation.
Added several high-level-synthesis plugins for synthesizing permutations:
BasicSynthesisPermutation: applies to fully-connected
architectures and is based on sorting. This is the previously used
algorithm for constructing quantum circuits for permutations.
ACGSynthesisPermutation: applies to fully-connected
architectures but is based on the Alon, Chung, Graham method. It synthesizes
any permutation in depth 2 (measured in terms of SWAPs).
KMSSynthesisPermutation: applies to linear nearest-neighbor
architectures and corresponds to the recently added Kutin, Moulton, Smithline
method.
For example:
fromqiskit.circuitimportQuantumCircuitfromqiskit.circuit.libraryimportPermutationGatefromqiskit.transpilerimportPassManagerfromqiskit.transpiler.passes.synthesis.high_level_synthesisimportHLSConfig,HighLevelSynthesisfromqiskit.transpiler.passes.synthesis.pluginimportHighLevelSynthesisPluginManager# Create a permutation and add it to a quantum circuitperm=PermutationGate([4,6,3,7,1,2,0,5])qc=QuantumCircuit(8)qc.append(perm,range(8))# Print available plugin names for synthesizing permutations# Returns ['acg', 'basic', 'default', 'kms']print(HighLevelSynthesisPluginManager().method_names("permutation"))# Default plugin for permutations# Returns a quantum circuit with size 6 and depth 3qct=PassManager(HighLevelSynthesis()).run(qc)print(f"Default: {qct.size()= }, {qct.depth()= }")# KMSSynthesisPermutation plugin for permutations# Returns a quantum circuit with size 18 and depth 6# but adhering to the linear nearest-neighbor architecture.qct=PassManager(HighLevelSynthesis(HLSConfig(permutation=[("kms",{})]))).run(qc)print(f"kms: {qct.size()= }, {qct.depth()= }")# BasicSynthesisPermutation plugin for permutations# Returns a quantum circuit with size 6 and depth 3qct=PassManager(HighLevelSynthesis(HLSConfig(permutation=[("basic",{})]))).run(qc)print(f"basic: {qct.size()= }, {qct.depth()= }")# ACGSynthesisPermutation plugin for permutations# Returns a quantum circuit with size 6 and depth 2qct=PassManager(HighLevelSynthesis(HLSConfig(permutation=[("acg",{})]))).run(qc)print(f"acg: {qct.size()= }, {qct.depth()= }")
Added a new keyword argument, derivative_type, to the constructor for the
LinCombEstimatorGradient. This argument
takes a DerivativeType enum that enables specifying to compute
only the real or imaginary parts of the gradient.
Added a new option circuit_reverse_bits to the user config file.
This allows users to set a boolean for their preferred default
behavior of the reverse_bits argument of the circuit drawers
QuantumCircuit.draw() and circuit_drawer(). For example,
adding a section to the user config file in the default location
~/.qiskit/settings.conf with:
[default]circuit_reverse_bits=True
will change the default to display the bits in reverse order.
Added a new pulse directive TimeBlockade.
This directive behaves almost identically to the delay instruction, but will
be removed before execution. This directive is intended to be used internally
within the pulse builder and helps ScheduleBlock represent
instructions with absolute time intervals. This allows the pulse builder to
convert Schedule into ScheduleBlock, rather than wrapping
with Call instructions.
Added primitive-enabled algorithms for Variational Quantum Time Evolution that implement the
interface for Quantum Time Evolution. The qiskit.algorithms.VarQRTE class is used
for real and the qiskit.algorithms.VarQITE class is used for imaginary
quantum time evolution according to a variational principle passed.
Each algorithm accepts a variational principle which implements the
ImaginaryVariationalPrinciple abstract interface. The
following implementations are included:
Added rules for converting XXPlusYYGate and
XXMinusYYGate to other gates to the SessionEquivalenceLibrary. This enables
running transpile() targeting a backend or Target that
uses these gates.
Added two new fake backends, FakePrague and
FakeSherbrooke to the qiskit.providers.fake_provider module.
FakePrague provides a backend with a snapshot of the properties
from the IBM Prague Egret R1 backend and FakeSherbrooke
provides a backend with a snapshot of the properties from the IBM
Sherbrooke Eagle R3 backend.
Added a new keyword argument, allow_unknown_parameters, to the
ParameterExpression.bind() and ParameterExpression.subs()
methods. When set this new argument enables passing a dictionary
containing unknown parameters to these methods without causing an error
to be raised. Previously, this would always raise an error without
any way to disable that behavior.
The BaseEstimator.run() method’s observables argument now
accepts a str or sequence of str input type in addition to the
other types already accepted. When used the input string format
should match the Pauli string representation accepted by the constructor
for Pauli objects.
The Clifford class now takes an optional copy keyword argument in its
constructor. If set to False, then a StabilizerTable provided
as input will not be copied, but will be used directly. This can have
performance benefits, if the data in the table will never be mutated by any
other means.
The performance of Clifford.compose() has been greatly improved for
all numbers of qubits. For operators of 20 qubits, the speedup is on the
order of 100 times.
Added a new synthesis function synth_clifford_layers(), for
synthesizing a Clifford into layers. The algorithm is based
on S. Bravyi, D. Maslov, Hadamard-free circuits expose the structure
of the Clifford group, arxiv:2003.09412.
This decomposes the Clifford into 8 layers of gates including two layers
of CZ gates, and one layer of CX gates. For example, a 5-qubit Clifford
circuit is decomposed into the following layers:
This method will allow to decompose a Clifford in 2-qubit depth
\(7n+2\) for linear nearest neighbor (LNN) connectivity.
The return types for the power() methods on several standard
library gate classes have been updated to return more specific
gate objects that result in a less lossy and more efficient output.
For example, running power() now returns an IGate
instance instead of UnitaryGate as was done previously.
The full list of output types that have been improved are:
The EquivalenceLibrary is now
represented internally as a PyDiGraph, this underlying graph object
can be accesed from the new graph attribute.
This attribute is intended for use internally in Qiskit and therefore
should always be copied before being modified by the user to prevent
possible corruption of the internal equivalence graph.
The Operator.from_circuit() constructor method now will reverse
the output permutation caused by the routing/swap mapping stage of the
transpiler. By default if a transpiled circuit had Swap gates inserted
the output matrix will have that permutation reversed so the returned
matrix will be equivalent to the original un-transpiled circuit. If you’d
like to disable this default behavior the ignore_set_layout keyword
argument can be set to True to do this (in addition to previous behavior
of ignoring the initial layout from transpilation). If you’d like to
manually set a final layout you can use the new final_layout keyword
argument to pass in a Layout object to use for the output
permutation.
Added support to the GateDirection transpiler pass to
handle the the symmetric RXXGate, RYYGate, and
RZZGate gates. The pass will now correctly handle these gates
and simply reverse the qargs order in place without any other
modifications.
Added support for using the Python exponentiation operator, **, with
Gate objects is now supported. It is equivalent to running the
Gate.power() method on the object.
Added new GaussianSquareDrag pulse shape to the qiskit.pulse.library
module. This pulse shape is similar to GaussianSquare but uses
the Drag shape during its rise and fall. The correction
from the DRAG pulse shape can suppress part of the frequency spectrum of
the rise and fall of the pulse which can help avoid exciting spectator
qubits when they are close in frequency to the drive frequency of the
pulse.
Added a new keyword argument, method, to the constructors for the
FiniteDiffEstimatorGradient and FiniteDiffSamplerGradient
classes. The method argument accepts a string to indicate the
computation method to use for the gradient. There are three methods,
available "central", "forward", and "backward". The
definition of the methods are:
Method
Computation
"central"
\(\frac{f(x+e)-f(x-e)}{2e}\)
"forward"
\(\frac{f(x+e) - f(x)}{e}\)
"backward"
\(\frac{f(x)-f(x-e)}{e}\)
where \(e\) is the offset epsilon.
All gradient classes in qiskit.algorithms.gradients now preserve unparameterized
operations instead of attempting to unroll them. This allows to evaluate gradients on
custom, opaque gates that individual primitives can handle and keeps a higher
level of abstraction for optimized synthesis and compilation after the gradient circuits
have been constructed.
Added a TranslateParameterizedGates pass to map only parameterized gates in a
circuit to a specified basis, but leave unparameterized gates untouched. The pass first
attempts unrolling and finally translates if a parameterized gate cannot be further unrolled.
The CollectCliffords transpiler pass has been expanded to collect
and combine blocks of “clifford gates” into Clifford objects, where
“clifford gates” may now also include objects of type LinearFunction,
Clifford, and PauliGate.
For example:
fromqiskit.circuitimportQuantumCircuitfromqiskit.circuit.libraryimportLinearFunction,PauliGatefromqiskit.quantum_info.operatorsimportCliffordfromqiskit.transpiler.passesimportCollectCliffordsfromqiskit.transpilerimportPassManager# Create a Cliffordcliff_circuit=QuantumCircuit(2)cliff_circuit.cx(0,1)cliff_circuit.h(0)cliff=Clifford(cliff_circuit)# Create a linear functionlf=LinearFunction([[0,1],[1,0]])# Create a pauli gatepauli_gate=PauliGate("XYZ")# Create a quantum circuit with the above and also simple clifford gates.qc=QuantumCircuit(4)qc.cz(0,1)qc.append(cliff,[0,1])qc.h(0)qc.append(lf,[0,2])qc.append(pauli_gate,[0,2,1])qc.x(2)# Run CollectCliffords transpiler passqct=PassManager(CollectCliffords()).run(qc)
All the gates will be collected and combined into a single Clifford. Thus the final
circuit consists of a single Clifford object.
CouplingMap is now implicitly iterable, with the iteration being
identical to iterating through the output of CouplingMap.get_edges().
In other words,
will now function as expected, as will other iterations. This is purely a
syntactic convenience.
Added a new function synth_cnot_count_full_pmh() which is used to
synthesize linear reversible circuits for all-to-all architectures
using the Patel, Markov and Hayes method. This function is identical to
the available qiskit.transpiler.synthesis.cnot_synth()
function but has a more descriptive name and is more logically placed
in the package tree. This new function supersedes the legacy function
which will likely be deprecated in a future release.
InstructionScheduleMap has been updated to store backend calibration data
in the format of PulseQobj JSON and invokes conversion when the data is accessed
for the first time, i.e. lazy conversion.
This internal logic update drastically improves the performance of loading backend
especially with many calibration entries.
New module qiskit.pulse.calibration_entries has been added. This
contains several wrapper classes for different pulse schedule representations.
ScheduleDef
CallableDef
PulseQobjDef
These classes implement the get_schedule() and
get_signature() methods that returns pulse schedule
and parameter names to assign, respectively. These classes are internally
managed by the InstructionScheduleMap or backend Target,
and thus they will not appear in a typical user programs.
Introduced a new subclass ScalableSymbolicPulse, as a
subclass of SymbolicPulse. The new subclass behaves
the same as SymbolicPulse,
except that it assumes that the envelope of the pulse includes a complex amplitude
pre-factor of the form \(\text{amp} * e^{i \times \text{angle}}\).
This envelope shape matches many common pulses, including all of the pulses in
the Qiskit Pulse library (which were also converted to amp, angle representation in
this release).
The new subclass removes the non-unique nature of the amp, angle representation,
and correctly compares pulses according to their complex amplitude.
Added a new keyword argument, dtype, to the PauliSumOp.from_list()
method. When specified this argument can be used to specify the dtype
of the numpy array allocated for the SparsePauliOp used
internally by the constructed PauliSumOp.
Support for importing OpenQASM 3 programs into Qiskit has been added. This can most easily be
accessed using the functions qasm3.loads() and qasm3.load(), to load a program
directly from a string and indirectly from a filename, respectively. For example, one can now
do:
fromqiskitimportqasm3circuit=qasm3.loads(""" OPENQASM 3.0; include "stdgates.inc"; qubit q; qubit[5] qr; bit c; bit[5] cr; h q; c = measure q; if (c) { h qr[0]; cx qr[0], qr[1]; cx qr[0], qr[2]; cx qr[0], qr[3]; cx qr[0], qr[4]; } else { h qr[4]; cx qr[4], qr[3]; cx qr[4], qr[2]; cx qr[4], qr[1]; cx qr[4], qr[0]; } cr = measure qr;""")
This will load the program into a QuantumCircuit instance in the variable circuit.
Not all OpenQASM 3 features are supported at first, because Qiskit does not yet have a way to
represent advanced classical data processing. The capabilities of the importer will increase
along with the capabilities of the rest of Qiskit. The initial feature set of the importer is
approximately the same set of features that would be output by the exporter (qasm3.dump()
and qasm3.dumps()).
Note that Qiskit’s support of OpenQASM 3 is not meant to provide a totally lossless
representation of QuantumCircuits. For that, consider using qiskit.qpy.
The primitives-based gradient classes defined by the
BaseEstimatorGradient and BaseSamplerGradient
abstract classes have been updated to simplify extending the base
interface. There are three new internal overridable methods, _preprocess(),
_postprocess(), and _run_unique(). _preprocess() enables
a subclass to customize the input gradient circuits and parameters,
_postprocess enables to customize the output result, and
_run_unique enables calculating the gradient of a circuit with
unique parameters.
The SabreLayout transpiler pass has greatly improved performance
as it has been re-written in Rust. As part of this rewrite the pass has been
transformed from an analysis pass to a transformation pass that will run both
layout and routing. This was done to not only improve the runtime performance
but also improve the quality of the results. The previous functionality of the
pass as an analysis pass can be retained by manually setting the routing_pass
argument or using the new skip_routing argument.
The SabreLayout transpiler pass has a new constructor argument
layout_trials. This argument is used to control how many random number
generator seeds will be attempted to run SabreLayout with. When
set the SABRE layout algorithm is run layout_trials number of times and
the best quality output (measured in the lowest number of swap gates added)
is selected. These seed trials are executed in parallel using multithreading
to minimize the potential performance overhead of running layout multiple
times. By default if this is not specified the SabreLayout
pass will default to using the number of physical CPUs are available on the
local system.
Added the SolovayKitaev transpiler pass to run the Solovay-Kitaev algorithm for
approximating single-qubit unitaries using a discrete gate set. In combination with the basis
translator, this allows to convert any unitary circuit to a universal discrete gate set,
which could be implemented fault-tolerantly.
This pass can e.g. be used after compiling to U and CX gates:
fromqiskitimporttranspilefromqiskit.circuit.libraryimportQFTfromqiskit.transpiler.passes.synthesisimportSolovayKitaevqft=QFT(3)# optimize to general 1-qubit unitaries and CXtranspiled=transpile(qft,basis_gates=["u","cx"],optimization_level=1)skd=SolovayKitaev()# uses T Tdg and H as default basisdiscretized=skd(transpiled)print(discretized.count_ops())
The decomposition can also be used with the unitary synthesis plugin, as
the “sk” method on the UnitarySynthesis transpiler pass:
The Optimize1qGatesDecomposition transpiler pass has a new keyword
argument, target, on its constructor. This argument can be used to
specify a Target object that represnts the compilation target.
If used it superscedes the basis argument to determine if an
instruction in the circuit is present on the target backend.
The UnrollCustomDefinitions transpiler pass has a new keyword
argument, target, on its constructor. This argument can be used to
specify a Target object that represnts the compilation target.
If used it superscedes the basis_gates argument to determine if an
instruction in the circuit is present on the target backend.
Added the ReverseEstimatorGradient class for a classical, fast evaluation of
expectation value gradients based on backpropagation or reverse-mode gradients.
This class uses statevectors and thus provides exact gradients but scales
exponentially in system size. It is designed for fast reference calculation of smaller system
sizes. It can for example be used as:
Added the ability for analysis passes to set custom heuristic weights
for the VF2Layout and VF2PostLayout transpiler
passes. If an analysis pass sets the vf2_avg_error_map key in the
property set, its value is used for the error weights instead of
the error rates from the backend’s Target (or
BackendProperties for BackendV1). The value should be
an ErrorMap instance, where each value represents the avg error rate
for all 1 or 2 qubit operation on those qubits. If a value is NaN, the
corresponding edge is treated as an ideal edge (or qubit for 1q operations).
For example, an error map created as:
describes a 2 qubit target, where the avg 1q error
rate is 0.0024 on qubit 0 and 0.0032 on qubit 1, the avg 2q
error rate for gates that operate on (0, 1) is 0.01, and (1, 0) is not
supported by the target. This will be used for scoring if it’s set for the
vf2_avg_error_map key in the property set when VF2Layout and
VF2PostLayout are run. For example:
fromqiskit.transpilerimportAnalysisPass,PassManager,Targetfromqiskit.transpiler.passesimportVF2Layoutfromqiskit.transpiler.passes.layout.vf2_utilsimportErrorMapfromqiskit.circuit.libraryimportCZGate,UGatefromqiskit.circuitimportParameterclassCustomVF2Scoring(AnalysisPass):"""Set custom score for vf2."""defrun(self,dag):error_map=ErrorMap(3)error_map.add_error((0,0),0.0024)error_map.add_error((0,1),0.01)error_map.add_error((1,1),0.0032)self.property_set["vf2_avg_error_map"]=error_maptarget=Target(num_qubits=2)target.add_instruction(UGate(Parameter('theta'),Parameter('phi'),Parameter('lam')),{(0,):None,(1,):None})target.add_instruction(CZGate(),{(0,1):None})vf2_pass=VF2Layout(target=target,seed=1234568942)pm=PassManager([CustomVF2Scoring(),vf2_pass])
That will run VF2Layout with the custom scoring from error_map for
a 2 qubit Target that doesn’t contain any error rates.
providing a complex amp argument with a finite angle will result in
PulseError now. For example, instead of calling Gaussian(duration=100,sigma=20,amp=0.5j) one
should use Gaussian(duration=100,sigma=20,amp=0.5,angle=np.pi/2) instead now. The pulse envelope
which used to be defined as amp*... is in turn defined as amp*exp(1j*angle)*....
This change was made to better support Qiskit Experiments
where the amplitude and angle of pulses are calibrated in separate experiments.
For Python 3.7 singledispatchmethod
is now a dependency. This was added to enable leveraging the method dispatch
mechanism in the standard library of newer versions of Python. If you’re on
Python >= 3.8 there is no extra dependency required.
The previously deprecated MSBasisDecomposer transpiler pass available
via the qiskit.transpiler.passes module has been removed. It was
originally deprecated as part of the Qiskit Terra 0.16.0 release
(10-16-2020). Instead the BasisTranslator transpiler pass
should be used instead to translate a circuit into an appropriate basis
with a RXXGate
EquivalenceLibrary objects that are initialized with the base
attribute will no long have a shared reference with the
EquivalenceLibrary passed in. In earlier releases if you mutated
base after it was used to create a new EquivalenceLibrary
instance both instances would reflect that change. This no longer is the case
and updates to base will no longer be reflected in the new
EquivalenceLibrary. For example, if you created an equivalence library
with:
in previous releases new_lib would also include the definition of SXGate
after it was added to original_lib, but in this release this no longer will
be the case. This change was made because of the change in internal data
structure to be a graph, which improved performance of the
EquivalenceLibrary class, especially when there are multiple runs of
the BasisTranslator transpiler pass.
The initial_state argument for the constructor of the
NLocal class along with assigning directly to
the NLocal.initial_state atrribute must be a
QuantumCircuit now. Support for using other types
for this argument and attribute is no longer supported. Support
for other types was deprecated as part of the Qiskit Terra 0.18.0
release (July 2021).
The LaTeX array drawers (e.g. array_to_latex,
Statevector.draw('latex')) now use the same sympy function as the
ket-convention drawer. This means it may render some numbers differently
to previous releases, but will provide a more consistent experience.
For example, it may identify new factors, or rationalize denominators where
it did not previously. The default precision has been changed from 5 to
10.
The QPY version format version emitted by dump() has been
increased to version 6. This new format version is incompatible with the
previous versions and will result in an error when trying to load it with
a deserializer that isn’t able to handle QPY version 6. This change was
necessary to support the introduction of ScalableSymbolicPulse
which was handled by adding a class_name_size attribute to the header
of the dumped SymbolicPulse objects.
The __hash__ method for the SymbolicPulse was removed.
This was done to reflect the mutable nature (via parameter assignment) of this class
which could result in errors when using SymbolicPulse
in situtations where a hashable object was required. This means the builtin hash()
method and using SymbolicPulse as keys in dictionaries
or set members will no longer work.
The names of Register instances (which includes instances of
QuantumRegister and ClassicalRegigster) are no longer constrained to be
valid OpenQASM 2 identifiers. This is being done as the restriction is
overly strict as Qiskit becomes more decoupled from OpenQASM 2, and even the
OpenQASM 3 specification is not so restrictive. If you were relying on
registers having valid OpenQASM 2 identifier names, you will need to begin
escaping the names. A simplistic version of this could be done, for example,
by:
The QuantumCircuit methods u1, u2, u3, and their
controlled variants cu1, cu3 and mcu1 have been removed following
their deprecation in Qiskit Terra 0.16.0. This was to remove gate names
that were usually IBM-specific, in favour of the more general methods p(),
u(), cp() and cu().
The gate classes U1Gate, U2Gate and U3Gate
are still available for use with QuantumCircuit.append(), so backends
can still support bases with these gates explicitly given.
The QuantumCircuit methods combine and extend have been
removed following their deprecation in Qiskit Terra 0.17.0. This was done
because these functions were simply less powerful versions of
QuantumCircuit.compose(), which should be used instead.
The removal of extend also means that the + and += operators are
no longer defined for QuantumCircuit. Instead, you can use the
& and &= operators respectively, which use
QuantumCircuit.compose().
The previously deprecated functions: qiskit.circuit.measure.measure()
and qiskit.circuit.reset.reset() have been removed. These functions
were deprecated in the Qiskit Terra 0.19.0 release (December, 2021).
Instead you should use the QuantumCircuit.measure() and
QuantumCircuit.reset() methods of the QuantumCircuit
object you wish to append a Measure or Reset
operation to.
The previously deprecated ParameterView methods which were
inherited from set have been removed from ParameterView,
the type returned by QuantumCircuit.parameters. The specific
methods which have been removed are:
add()
difference()
difference_update()
discard()
intersection()
intersection_update()
issubset()
issuperset()
symmetric_difference()
symmetric_difference_update()
union()
update()
along with support for the Python operators:
ixor: ^=
isub: -=
ior: |=
These were deprecated in the Qiskit Terra 0.17.0 release (April, 2021).
The ParameterView type is now a general sequence view type and doesn’t
support these set operations any longer.
The previously deprecated NetworkX converter
methods for the DAGCircuit and DAGDependency
classes: DAGCircuit.to_networkx(),
DAGCircuit.from_networkx(), and DAGDependency.to_networkx()
have been removed. These methods were originally deprecated as part of
the Qiskit Terra 0.21.0 release (June, 2022). Qiskit has been using
rustworkx as its graph
library since the qiskit-terra 0.12.0 release and since then the NetworkX
converter function have been a lossy process. They were originally added so
that users could leverage NetworkX’s algorithms library to leverage
functionality not present in DAGCircuit and/or rustworkx. However,
since that time both DAGCircuit and rustworkx has matured and
offers more functionality and the DAGCircuit is tightly
coupled to rustworkx for its operation and having these converter methods
provided limited functionality and therefore have been removed.
tweedledum has been removed as a core requirement of Qiskit Terra. The
functionality provided (qiskit.circuit.classicalfunction) is still
available, if tweedledum is installed manually, such as by:
pipinstalltweedledum
This change was made because tweedledum development has slowed to the
point of not keeping up with new Python and OS releases, and was blocking
some Qiskit users from installing Qiskit.
The previously deprecated gate argument to the constructor of the
Decompose transpiler pass, along with its matching attribute
Decompose.gate have been removed. The argument and attribute were
deprecated as part of the Qiskit Terra 0.19.0 release (December, 2021).
Instead the gates_to_decompose argument for the constructor along
with the Decompose.gates_to_decompose attribute should be used
instead. The gates_to_decompose argument and attribute should function
the same, but has a more explicit name and also enables specifying lists
of gates instead of only supporting a single gate.
The previously deprecated label argument for the constructor of the
MCMT and MCMTVChain classes has been removed.
It was deprecated as of the Qiskit Terra 0.19.0 release (Decemeber, 2021).
Using the label argument on these classes was undefined behavior
as they are subclasses of QuantumCircuit instead of
Instruction. This would result in the assigned label generally
being ignored. If you need to assign a label to an
instance of MCMT or MCMTVChain you should convert
them to an Gate instance with to_gate()
and then assign the desired label to label attribute. For
example:
The retworkx dependency for Qiskit has been removed and replaced by
rustworkx library. These are the same packages, but rustworkx is
the new name for retworkx which was renamed as part of their combined
0.12.0 release. If you were previously using retworkx 0.12.0 with Qiskit
then you already installed rustworkx (retworkx 0.12.0 was just a redirect
shim for backwards compatibility). This change was made to migrate to the
new package name which will be the only supported package in the future.
The default behavior of the SabreLayout compiler pass has
changed. The pass is no longer an AnalysisPass and by default
will compute the initital layout, apply it to the circuit, and will
also run SabreSwap internally and apply the swap mapping
and set the final_layout property set with the permutation caused
by swap insertions. This means for users running SabreLayout
as part of a custom PassManager will need to adjust the pass
manager to account for this (unless they were setting the routing_pass
argument for SabreLayout). This change was made in the interest
of improving the quality output, the layout and routing quality are highly
coupled and SabreLayout will now run multiple parallel seed
trials and to calculate which seed provides the best results it needs to
perform both the layout and routing together. There are three ways you can
adjust the usage in your custom pass manager. The first is to avoid using
embedding in your preset pass manager. If you were previously running something
like:
as SabreLayout will apply the layout and you no longer need the embedding
stage. Alternatively, you can specify the routing_pass argument which will revert
SabreLayout to its previous behavior. For example, if you want to run
SabreLayout as it was run in previous releases you can do something like:
which will have SabreLayout run as an analysis pass and just set
the layout property set. The final approach is to leverage the skip_routing
argument on SabreLayout, when this argument is set to True it will
skip applying the found layout and inserting the swap gates from routing. However,
doing this has a runtime penalty as SabreLayout will still be computing
the routing and just does not use this data. The first two approaches outlined do
not have additional overhead associated with them.
The layouts computed by the SabreLayout pass (when run without
the routing_pass argument) with a fixed seed value may change from
previous releases. This is caused by a new random number generator being
used as part of the rewrite of the SabreLayout pass in Rust which
significantly improved the performance. If you rely on having consistent
output you can run the pass in an earlier version of Qiskit and leverage
qiskit.qpy to save the circuit and then load it using the current
version. Alternatively you can explicitly set the routing_pass argument
to an instance of SabreSwap to mirror the previous behavior
of SabreLayout:
which will mirror the behavior of the pass in the previous release. Note, that if you
were using the swap_trials argument on SabreLayout in previous releases
when adjusting the usage to this form that you will need to set trials argument
on the SabreSwap constructor if you want to retain the previous output with
a fixed seed.
The exact circuit returned by qiskit.circuit.random.random_circuit for a
given seed has changed. This is due to efficiency improvements in the
internal random-number generation for the function.
The version requirement for the optional feature package qiskit-toqm,
installable via pipinstallqiskit-terra[toqm], has been upgraded from
version 0.0.4 to 0.1.0. To use the toqm routing method
with transpile() you must now use qiskit-toqm version
0.1.0 or newer. Older versions are no longer discoverable by
the transpiler.
The output QuasiDistribution from the Sampler.run
method has been updated to filter out any states with a probability of
zero. Now if a valid state is missing from the dictionary output it can
be assumed to have a 0 probability. Previously, all possible outcomes for
a given number of bits (e.g. for a 3 bit result 000, 001,
010, 011, 100, 101, 110, and 111) even if the
probability of a given state was 0. This change was made to reduce the
size of the output as for larger number of bits the output size could be
quite large. Also, filtering the zero probability results makes the output
consistent with other implementations of BaseSampler.
The behavior of the pulse builder when a Schedule is called
has been upgraded. Called schedules are internally converted into
ScheduleBlock representation and now reference mechanism is
always applied rather than appending the schedules wrapped by
the Call instruction.
Note that the converted block doesn’t necessary recover the original alignment context.
This is simply an ASAP aligned sequence of pulse instructions with absolute time intervals.
This is an upgrade of internal representation of called pulse programs and thus no API changes.
However the Call instruction and Schedule
no longer appear in the builder’s pulse program.
This change guarantees the generated schedule blocks are always QPY compatible.
If you are filtering the output schedule instructions by Call,
you can access to the ScheduleBlock.references instead to retrieve the called program.
RZXCalibrationBuilder
and RZXCalibrationBuilderNoEcho transpiler pass
have been upgraded to generate ScheduleBlock.
This change guarantees the transpiled circuits are always QPY compatible.
If you are directly using rescale_cr_inst(),
method from another program or a pass subclass to rescale cross resonance pulse of the device,
now this method is turned into a pulse builder macro, and you need to use this method
within the pulse builder context to adopts to new release.
The method call injects a play instruction to the context pulse program,
instead of returning a Play instruction with the stretched pulse.
Support for running Qiskit with Python 3.7 support has been deprecated
and will be removed in the qiskit-terra 0.25.0 release. This means
starting in the 0.25.0 release you will need to upgrade the Python
version you’re using to Python 3.8 or above.
The class LinearFunctionsSynthesis class is now deprecated
and will be removed in a future release. It has been superseded
by the more general HighLevelSynthesis class which should
be used instead. For example, you can instantiate an instance of
HighLevelSynthesis that will behave the same way as
LinearFunctionSynthesis with:
Support for passing in lists of argument values to the transpile()
function is deprecated and will be removed in the 0.25.0 release. This
is being done to facilitate greatly reducing the overhead for parallel
execution for transpiling multiple circuits at once. If you’re using
this functionality currently you can call transpile() multiple
times instead. For example if you were previously doing something like:
You can also leverage parallel_map() or multiprocessing from
the Python standard library if you want to run this in parallel.
The legacy version of the pulse drawer present in the
qiskit.visualization.pulse has been deprecated and will be
removed in a future release. This includes the ScheduleDrawer
and :class`WaveformDrawer` classes. This module has been superseded
by the qiskit.visualization.pulse_v2 drawer and the typical user
API pulse_drawer() and PulseBlock.draw() are already updated
internally to use qiskit.visualization.pulse_v2.
The pulse.Instruction.draw() method has been deprecated and will
removed in a future release. The need for this method has been superseded
by the qiskit.visualization.pulse_v2 drawer which doesn’t require
Instrucion objects to have their own draw method. If
you need to draw a pulse instruction you should leverage the
pulse_drawer() instead.
The import qiskit.circuit.qpy_serialization is deprecated, as QPY has been promoted to the
top level. You should import the same objects from qiskit.qpy instead. The old path
will be removed in a future of Qiskit Terra.
The qiskit.IBMQ object is deprecated. This alias object lazily redirects
attribute access to qiskit.providers.ibmq.IBMQ. As the
qiskit-ibmq-provider package has been supersceded by
qiskit-ibm-provider package which maintains its own namespace
maintaining this alias is no longer relevant with the new package. If you
were relying on the qiskit.IBMQ alias you should update your usage
to use qiskit.providers.ibmq.IBMQ directly instead (and also consider
migrating to qiskit-ibm-provider, see the
migration guide
for more details).
Several public methods of pulse Qobj converters have been deprecated and in a future
release they will no longer be directly callable. The list of methods is:
In InstructionToQobjConverter,
convert_acquire()
convert_bundled_acquires()
convert_set_frequency()
convert_shift_frequency()
convert_set_phase()
convert_shift_phase()
convert_delay()
convert_play()
convert_snapshot()
In QobjToInstructionConverter,
convert_acquire()
convert_set_phase()
convert_shift_phase()
convert_set_frequency()
convert_shift_frequency()
convert_delay()
bind_pulse()
convert_parametric()
convert_snapshot()
Instead of calling any of these methods directly they will be implicitly selected when a
converter instance is directly called. For example:
The qiskit.visualization.state_visualization.num_to_latex_ket()
and qiskit.visualization.state_visualization.num_to_latex_terms()
functions have been deprecated and will be removed in a future release.
These function were primarily used internally by the LaTeX output from
Statevector.draw() and DensityMatrix.draw() which no longer
are using these function and are leverging
sympy for this instead. If you were
using these functions you should cosinder using Sympy’s
nsimplify()latex() functions.
The method Register.qasm() is deprecated and will be removed in a
future release. This method is found on the subclasses QuantumRegister
and ClassicalRegister. The deprecation is because the
qasm() method promotes a false view of the responsible
party for safe conversion to OpenQASM 2; a single object alone does not
have the context to provide a safe conversion, such as whether its name
clashes after escaping it to produce a valid identifier.
The class-variable regular expression Register.name_format is
deprecated and wil be removed in a future release. The names of registers
are now permitted to be any valid Python string, so the regular expression
has no use any longer.
Fixed an issue in the PauliOp.adjoint() method where it would
return the correct value for Paulis with complex coefficients,
for example: PauliOp(Pauli("iX")).
Fixed #9433.
Fixed an issue with the amplitude estimation algorithms in the
qiskit.algorithms.amplitude_estimators module (see
amplitude_estimators) for
the usage with primitives built from the abstract BaseSampler primitive (such
as Sampler and BackendSampler). Previously, the measurement
results were expanded to more bits than actually measured which for oracles with more
than one qubit led to potential errors in the detection of the “good” quantum states
for oracles.
Fixed an issue where the QuantumCircuit.add_calibrations() and
DAGCircuit.add_calibrations() methods had a mismatch in
their behavior of parameter-formatting logic. Previously
DAGCircuit.add_calibrations() tried to cast every parameter
into float, QuantumCircuit.add_calibrations() used given
parameters as-is. This would potentially cause an error when running
transpile() on a QuantumCircuit with pulse
gates as the parameters of the calibrations could be kept as
ParameterExpresion objects.
Fixed an issue in TensoredOp.to_matrix() where the global coefficient of the operator
was multiplied to the final matrix more than once. Now, the global coefficient is correctly
applied, independent of the number of tensored operators or states.
Fixed #9398.
The output from the run() method of the the
BackendSampler class now sets the
shots and stddev_upper_bound attributes of the returned
QuasiDistribution. Previously these attributes were missing
which prevent some post-processing using the output.
Fixed #9311
The OpenQASM 2 exporter method QuantumCircuit.qasm() will now emit
higher precision floating point numbers for gate parameters by default.
In addition, a tighter bound (\(1e-12\) instead of \(1e-6\)) is used for
checking whether a given parameter is close to a fraction/power of \(\pi\).
Fixed #7166.
Fixed support in the primitives module for running
QuantumCircuit objects with control flow instructions (e.g.
IfElseOp). Previously, the BaseSampler and
BaseEstimator base classes could not correctly
normalize such circuits. However, executing these circuits is dependent
on the particular implementation of the primitive supporting control
flow instructions. This just fixed support to enable a particular
implementation of BaseSampler or BaseEstimator
to use control flow instructions.
Fixed an issue with the PauliOp.matmul() method where it would
return incorrect results with iI.
Fixed #8680.
Fixed an issue with the Approximate Quantum Compiler (AQC)
class which caused it to return an incorrect circuit when the input
unitary had a determinant of -1.
Fixed #9327
Fixed an issue with the QuantumCircuit.compose() method where it would
incorrectly reject valid qubit or clbit specifiers. This has been fixed so
that the method now accepts the same set of qubit and clbit
specifiers as other QuantumCircuit methods, such as
append().
Fixed #8691.
Fixed an issue with the QuantumCircuit.compose() method where it would
incorrectly map registers in conditions on the given circuit to complete
registers on the base. Previously, the mapping was very imprecise; the bits
used within each condition were not subject to the mapping, and instead an inaccurate attempt was
made to find a corresponding register. This could also result in a condition on a smaller register
being expanded to be on a larger register, which is not a valid transformation. Now, a
condition on a single bit or a register will be composed to be on precisely the bits as defined
by the clbits argument. A new aliasing register will be added to the base circuit to
facilitate this, if necessary. Fixed #6583.
Fixed an issue with the transpile() function when run with
optimization_level set to 1, 2, or 3 and no
backend, basis_gates, or target argument specified. If
the input circuit had runs of single qubit gates which could be simplified
the output circuit would not be as optimized as possible as those runs
of single qubit gates would not have been removed. This could have been
corrected previously by specifying either the backend, basis_gates,
or target arguments on the transpile() call, but now the output
will be as simplified as it can be without knowing the target gates allowed.
Fixed #9217
Fixed an issue with the transpile() function when run with
optimization_level=3 and no backend, basis_gates, or target
argument specified. If the input circuit contained any 2 qubit blocks which
were equivalent to an identity matrix the output circuit would not be as
optimized as possible and and would still contain that identity block.
This could have been corrected previously by specifying either the
backend, basis_gates, or target arguments on the
transpile() call, but now the output will be as simplified as it
can be without knowing the target gates allowed.
Fixed #9217
Fixed an issue with LinCombSamplerGradient where it would
potentially raise an error when run with the
Sampler class from qiskit-aer.
Fixed an issue with
NumPyEigensolver and by extension
NumPyMinimumEigensolver
where solving for
BaseOperator
subclasses other than Operator
would cause an error.
Fixed an issue in the metadata output from primitives
where the list made copies by reference and all elements were updated
with the same value at every iteration.
Fixed an issue with the QobjToInstructionConverter
when multiple backends are called and they accidentally have the
same pulse name in the pulse library. This was an edge case that could
only be caused when a converter instance was reused across multiple
backends (this was not a typical usage pattern).
Fixed an issue with the PVQD class where the loss function
was incorrecly squaring the fidelity. This has been fixed so that
the loss function matches the definition in the original algorithm
definition.
Fixed a bug in QPY (qiskit.qpy) where circuits containing registers
whose bits occurred in the circuit after loose bits would fail to deserialize.
See #9094.
The class TwoQubitWeylDecomposition is now compatible with the
pickle protocol. Previously, it would fail to deserialize and would
raise a TypeError.
See #7312.
Fixed an issue with the LocalReadoutMitigator.quasi_probabilities() method where
the shots argument was not used. It is now used to set the number of shots
in the return object.
Fixed a regression in the construction of Clifford objects
from QuantumCircuits that contain other Clifford
objects.
Fixed an issue with the TwoQubitWeylDecomposition class (and
its subclasses) to enable the Python standard library pickle
to serialize these classes. This partially fixed
#7312
QuantumCircuit.qasm() will now correctly escape gate and register
names that collide with reserved OpenQASM 2 keywords. Fixes
#5043.
Fixed a bug in BackendSampler that raised an error
if its run() method was called two times sequentially.
Fixed two bugs in the ComposedOp where the ComposedOp.to_matrix()
method did not provide the correct results for compositions with StateFn
and for compositions with a global coefficient.
Fixed #9283.
Fixed the problem in which primitives, Sampler and Estimator, did not
work when passed a circuit with numpy.ndarray as a parameter.
Fixed a bug in SamplingVQE where the aggregation argument did not have an effect.
Now the aggregation function and, with it, the CVaR expectation value can correctly be specified.
Fixed a performance bug where SamplingVQE evaluated the energies of eigenstates
in a slow manner.
Fixed the autoevaluation of the beta parameters in
VQD, added support for
SparsePauliOp inputs, and fixed
the energy evaluation function to leverage the asynchronous execution
of primitives, by only retrieving the job results after both
jobs have been submitted.
Fixed handling of some classmethods by
wrap_method() in Python 3.11. Previously, in Python
3.11, wrap_method would wrap the unbound function associated with the
classmethod and then fail when invoked because the class object usually
bound to the classmethod was not passed to the function. Starting in
Python 3.11.1, this issue affected QiskitTestCase,
preventing it from being imported by other test code. Fixed #9291.
Fix two bugs in AerStatevector. AerStatevector uses mc* instructions, which are
not enabled in matrix_product_state method. This commit changes AerStatevector
not to use MC* and use H, X, Y, Z, U and CX. AerStatevector also failed if an
instruction is decomposed to empty QuantumCircuit. This commit allows such
instruction.
Fixed support in the AerSimulator.from_backend() method for instantiating
an AerSimulator instance from an a BackendV2 object.
Previously, attempting to use AerSimulator.from_backend() with a
BackendV2 object would have raised an AerError saying this
wasn’t supported.
Fixes a bug where NoiseModel.from_backend() with a BackendV2 object may generate
a noise model with excessive QuantumError s on non-Gate instructions while,
for example, only ReadoutError s should be sufficient for measures.
This commit updates NoiseModel.from_backend() with a BackendV2 object so that
it returns the same noise model as that called with the corresponding BackendV1 object.
That is, the resulting noise model does not contain any QuantumError s on measures and
it may contain only thermal relaxation errors on other non-gate instructions such as resets.
Note that it still contains ReadoutError s on measures.
Fixed a bug in NoiseModel.from_backend() where using the temperature kwarg with
a non-default value would incorrectly compute the excited state population for
the specified temperature. Previously, there was an additional factor of 2 in
the Boltzman distribution calculation leading to an incorrect smaller value
for the excited state population.
Fixed incorrect logic in the control-flow compiler that could allow unrelated instructions to
appear “inside” control-flow bodies during execution, causing incorrect results. For example,
previously:
would print {'010':100} as the nested control-flow operations would accidentally jump over
the first X gate on qubit 2, which should have been executed.
Fixes a bug where NoiseModel.from_backend() prints verbose warnings when
supplying a backend that reports un-physical device parameters such as T2 > 2 * T1
due to statistical errors in their estimation.
This commit removes such warnings because they are not actionable for users in the sense
that there are no means other than truncating them to the theoretical bounds as
done within noise.device module.
See Issue 1631
for details of the fixed bug.
This is fix for GPU statevector simulator.
Chunk distribution tried to allocate all free memory on GPU,
but this causes memory allocation error.
So this fix allocates 80 percent of free memory.
Also this fixes size of matrix buffer when noise sampling is applied.
This is a fix of AerState running with cache blocking. AerState wrongly configured
transpiler of Aer for cache blocking, and then its algorithm to swap qubits
worked wrongly. This fix corrects AerState to use this transpiler. More specifically,
After the transpilation, a swapped qubit map is recoverd to the original map
when using AerState. This fix is necessary for AerStatevector to use multiple-GPUs.
This is fix for AerStatevector.
It was not possible to create an AerStatevector instance directly from
terra’s Statevector.
This fix allows a Statevector as AerStatevector’s input.
SamplerResult.quasi_dists contain the data about the number of qubits.
QuasiDistribution.binary_probabilities() returns bitstrings with correct length.
Previously seed is not initialized in AerStatevector and then sampled results
are always same. With this commit, a seed is initialized for each sampling
and sampled results can be vary.
AdaptVQE now correctly
indicates that it supports auxiliary operators.
The circuit drawers (QuantumCircuit.draw() and circuit_drawer()) will no
longer emit a warning about the cregbundle parameter when using the default arguments,
if the content of the circuit requires all bits to be drawn individually. This was most
likely to appear when trying to draw circuits with new-style control-flow operations.
Fixed a bug causing QNSPSA to fail when max_evals_grouped was set to a
value larger than 1.
Fixed an issue with the SabreSwap pass which would cause the
output of multiple runs of the pass without the seed argument specified
to reuse the same random number generator seed between runs instead of
using different seeds. This previously caused identical results to be
returned between runs even when no seed was specified.
Fixed an issue with the primitive classes, BackendSampler and BackendEstimator,
where instances were not able to be serialized with pickle. In general these classes are not guaranteed
to be serializable as BackendV2 and BackendV1 instances are not required to be
serializable (and often are not), but the class definitions of BackendSampler and
BackendEstimator no longer prevent the use of pickle.
The pulse.Instruction.draw() method will now succeed, as before.
This method is deprecated with no replacement planned, but it should
still work for the period of deprecation.
Fixed a bug in the VF2PostLayout pass when transpiling for backends
with a defined Target, where the interaction graph would be built
incorrectly. This could result in excessive runtimes due to the graph being
far more complex than necessary.
The Pulse expression parser should no longer periodically hang when called
from Jupyter notebooks. This is achieved by avoiding an internal deepycopy
of a recursive object that seemed to be particularly difficult for the
memoization to evaluate.
The pauli_list kwarg of pauli_basis() has been deprecated as
pauli_basis() now always returns a PauliList. This argument
was removed prematurely from Qiskit Terra 0.22.0 which broke compatibility
for users that were leveraging the pauli_list``argument.Now,theargumenthasbeenrestoredbutwillemita``DeprecationWarning when used. If used
it has no effect because since Qiskit Terra 0.22.0 a PauliList is
always returned.
Fixed the BarrierBeforeFinalMeasurements transpiler pass when there
are conditions on loose Clbits immediately before the final measurement
layer. Previously, this would fail claiming that the bit was not present
in an internal temporary circuit.
Fixed #8923
The equality checkers for QuantumCircuit and DAGCircuit
(with objects of the same type) will now correctly handle conditions on single
bits. Previously, these would produce false negatives for equality, as the
bits would use “exact” equality checks instead of the “semantic” checks the rest
of the properties of circuit instructions get.
Fixed handling of classical bits in StochasticSwap with control flow.
Previously, control-flow operations would be expanded to contain all the
classical bits in the outer circuit and not contracted again, leading to a
mismatch between the numbers of clbits the instruction reported needing and
the actual number supplied to it.
Fixed #8903
Fixed handling of globally defined instructions for the Target
class. Previously, two methods, operations_for_qargs() and
operation_names_for_qargs() would ignore/incorrectly handle
any globally defined ideal operations present in the target. For example:
will now return {"cx"} for names and [CXGate()] for ops
instead of raising a KeyError or an empty return.
Fixed an issue in the Target.add_instruction() method where it
would previously have accepted an argument with an invalid number of
qubits as part of the properties argument. For example:
This will now correctly raise a TranspilerError instead of causing
runtime issues when interacting with the target.
Fixed #8914
Fixed an issue with the plot_state_hinton() visualization function
which would result in a misplaced axis that was offset from the actual
plot.
Fixed #8446 <https://github.com/Qiskit/qiskit-terra/issues/8446>
Fixed the output of the plot_state_hinton() function so that the state labels
are ordered ordered correctly, and the image matches up with the natural matrix
ordering.
Fixed #8324
Fixed an issue with the primitive classes, BackendSampler and
BackendEstimator when running on backends that have a limited
number of circuits in each job. Not all backends support an unlimited
batch size (most hardware backends do not) and previously the backend
primitive classes would have potentially incorrectly sent more circuits
than the backend supported. This has been corrected so that
BackendSampler and BackendEstimator will chunk the
circuits into multiple jobs if the backend has a limited number of
circuits per job.
Fixed an issue with the BackendEstimator class where previously
setting a run option named monitor to a value that evaluated as
True would have incorrectly triggered a job monitor that only
worked on backends from the qiskit-ibmq-provider package. This
has been removed so that you can use a monitor run option if needed
without causing any issues.
Fixed an issue with the Target.build_coupling_map() method where
it would incorrectly return None for a Target object
with a mix of ideal globally available instructions and instructions
that have qubit constraints. Now in such cases the
Target.build_coupling_map() will return a coupling map for the
constrained instruction (unless it’s a 2 qubit operation which will
return None because globally there is no connectivity constraint).
Fixed #8971
Fixed an issue with the Target.qargs attribute where it would
incorrectly return None for a Target object that contained
any globally available ideal instruction.
Fixed the premature removal of the pauli_list keyword argument of
the pauli_basis() function which broke existing code using the
pauli_list=True future compatibility path on upgrade to Qiskit Terra
0.22.0. This keyword argument has been added back to the function and is
now deprecated and will be removed in a future release.
Fixed an issue in QPY serialization (dump()) when a custom
ControlledGate subclass that overloaded the _define()
method to provide a custom definition for the operation. Previously,
this case of operation was not serialized correctly because it wasn’t
accounting for using the potentially _define() method to provide
a definition.
Fixes #8794
QPY deserialisation will no longer add extra Clbit instances to the
circuit if there are both loose Clbits in the circuit and more
Qubits than Clbits.
QPY deserialisation will no longer add registers named q and c if the
input circuit contained only loose bits.
Fixed the SparsePauliOp.dot() method when run on two operators with
real coefficients. To fix this, the dtype that SparsePauliOp can
take is restricted to np.complex128 and object.
Fixed #8992
Fixed an issue in the circuit_drawer() function and
QuantumCircuit.draw() method where the only built-in style
for the mpl output that was usable was default. If another
built-in style, such as iqx, were used then a warning about
the style not being found would be emitted and the drawer would
fall back to use the default style.
Fixed #8991
Fixed an issue with the transpile() where it would previously
fail with a TypeError if a custom Target object was
passed in via the target argument and a list of multiple circuits
were specified for the circuits argument.
Fixed an issue with transpile() when targeting a Target
(either directly via the target argument or via a
BackendV2 instance from the backend argument) that
contained an ideal Measure instruction (one that does not have
any properties defined). Previously this would raise an exception
trying to parse the target.
Fixed #8969
Fixed an issue with the VF2Layout pass where it would error
when running with a Target that had instructions that were
missing error rates. This has been corrected so in such cases the
lack of an error rate will be treated as an ideal implementation and
if no error rates are present it will just select the first matching
layout.
Fixed #8970
Fixed an issue with the VF2PostLayout pass where it would
error when running with a Target that had instructions that
were missing. In such cases the lack of an error rate will be treated as
an ideal implementation of the operation.
Fixed an issue with the VQD class if more than
k=2 eigenvalues were computed. Previously this would fail due to an
internal type mismatch, but now runs as expected.
Fixed #8982
Fixed a performance bug where the new primitive-based variational algorithms
minimum_eigensolvers.VQE, eigensolvers.VQD and SamplingVQE
did not batch energy evaluations per default, which resulted in a significant slowdown
if a hardware backend was used.
Fixes bug in Statevector.evolve() where subsystem evolution
will return the incorrect value in certain cases where there are 2 or more
than non-evolved subsystems with different subsystem dimensions.
Fixes issue #8899
Fixed a potential build error when trying to use CMake 3.18 or newer and
building qiskit-aer with GPU support enabled. Since CMake 3.18 or later
when building with CUDA the CMAKE_CUDA_ARCHITECTURES was required to
be set with the architecture value for the target GPU. This has been
corrected so that setting AER_CUDA_ARCH will be used if this was
not set.
Fixes a bug in the handling of instructions with clbits in LocalNoisePass.
Previously, it was accidentally erasing clbits of instructions (e.g. measures)
to which the noise is applied in the case of method="append".
Fixed the performance overhead of the Sampler class when running with identical circuits on multiple executions.
This was accomplished by skipping/caching the transpilation of these identical circuits on subsequent executions.
Fixed compatibility of the Sampler and Estimator
primitive classes with qiskit-terra 0.22.0 release. In qiskit-terra 0.22.0 breaking API changes were made to the
abstract interface which broke compatibility with these classes, this has been addressed so that
Sampler and Estimator can now be used with
qiskit-terra >= 0.22.0.
This release also officially deprecates the Qiskit Aer project as part of the Qiskit metapackage.
This means that in a future release pipinstallqiskit will no longer include qiskit-aer.
If you’re currently installing or listing qiskit as a dependency to get Aer you should upgrade
this to explicitly list qiskit-aer as well.
The qiskit-aer project is still active and maintained moving forward but for the Qiskit
metapackage (i.e. what gets installed via pipinstallqiskit) the project is moving towards
a model where the Qiskit package only contains the common core functionality for building and
compiling quantum circuits, programs, and applications and packages that build on it or link
Qiskit to hardware or simulators are separate packages.
The Qiskit Terra 0.22.0 release is a major feature release that includes
a myriad of new feature and bugfixes. The highlights for this release are:
Adding initial support to the transpiler for transpiling
QuantumCircuit objects that contain control flow instructions
such as ForLoopOp and WhileLoopOp.
Greatly improved scaling and performance for the transpile() function
with large numbers of qubits, especially when optimization_level=3 is used.
External plugin interface for transpile() that enables external
packages to implement stages for the default pass managers. More details on this
can be found at qiskit.transpiler.preset_passmanagers.plugin.
Additionally, BackendV2 backends can now optionally set
custom default plugins to use for the scheduling and translation stages.
Add support for representing an operation that has a variable width
to the Target class. Previously, a Target object
needed to have an instance of Operation defined for each
operation supported in the target. This was used for both validation
of arguments and parameters of the operation. However, for operations
that have a variable width this wasn’t possible because each instance
of an Operation class can only have a fixed number of qubits.
For cases where a backend supports variable width operations the
instruction can be added with the class of the operation instead of an
instance. In such cases the operation will be treated as globally
supported on all qubits. For example, if building a target like:
Added new primitive implementations, BackendSampler and BackendEstimator,
to qiskit.primitives. Thes new primitive class implementation wrap a BackendV1
or BackendV2 instance as a BaseSampler or BaseEstimator
respectively. The intended use case for these primitive implementations is to bridge the gap
between providers that do not have native primitive implementations and use that provider’s
backend with APIs that work with primitives. For example, the SamplingVQE class
takes a BaseSampler instance to function. If you’d like to run that class with
a backend from a provider without a native primitive implementation you can construct a
BackendSampler to do this:
If you’re using a provider that has native primitive implementations (such as
qiskit-ibm-runtime or qiskit-aer) it is always a better choice to use that native
primitive implementation instead of BackendEstimator or BackendSampler
as the native implementations will be much more efficient and/or do additional pre and post
processing. BackendEstimator and BackendSampler are designed to be
generic that can work with any backend that returns Counts in their
Results which precludes additional optimization.
fromqiskit.algorithms.minimum_eigensolversimportAdaptVQE,VQEfromqiskit.algorithms.optimizersimportSLSQPfromqiskit.primitivesimportEstimatorfromqiskit.circuit.libraryimportEvolvedOperatorAnsatz# get your Hamiltonianhamiltonian=...# construct your ansatzansatz=EvolvedOperatorAnsatz(...)vqe=VQE(Estimator(),ansatz,SLSQP())adapt_vqe=AdaptVQE(vqe)result=adapt_vqe.compute_minimum_eigenvalue(hamiltonian)
The BackendV2 class now has support for two new optional hook
points enabling backends to inject custom compilation steps as part of
transpile() and generate_preset_pass_manager(). If a
BackendV2 implementation includes the methods
get_scheduling_stage_plugin() or get_translation_stage_plugin() the
transpiler will use the returned string as the default value for
the scheduling_method and translation_method arguments. This enables
backends to run additional custom transpiler passes when targetting that
backend by leveraging the transpiler stage
plugin interface.
For more details on how to use this see: Custom Transpiler Passes.
Added a new keyword argument, ignore_backend_supplied_default_methods, to the
transpile() function which can be used to disable a backend’s
custom selection of a default method if the target backend has
get_scheduling_stage_plugin() or get_translation_stage_plugin()
defined.
Added a label parameter to the Barrier class’s constructor
and the barrier() method which allows a user to
assign a label to an instance of the Barrier directive. For
visualizations generated with circuit_drawer() or
QuantumCircuit.draw() this label will be printed at the top of the
barrier.
Added qiskit.algorithms.eigensolvers package to include
interfaces for primitive-enabled algorithms. This new module
will eventually replace the previous qiskit.algorithms.eigen_solvers.
This new module contains an alternative implementation of the
VQD which instead of taking
a backend or QuantumInstance instead takes an instance of
BaseEstimator, including Estimator,
BackendEstimator, or any provider implementations such as
those as those present in qiskit-ibm-runtime and qiskit-aer.
For example, to use the new implementation with an instance of
Estimator class:
Note that the evaluated auxillary operators are now obtained via the
aux_operators_evaluated field on the results. This will consist of a list or dict of
tuples containing the expectation values for these operators, as we well as the metadata from
primitive run. aux_operator_eigenvalues is no longer a valid field.
Added new algorithms to calculate state fidelities/overlaps
for pairs of quantum circuits (that can be parametrized). Apart from
the base class (BaseStateFidelity) which defines the interface,
there is an implementation of the compute-uncompute method that leverages
instances of the BaseSampler primitive: qiskit.algorithms.state_fidelities.ComputeUncompute.
Added a new module qiskit.algorithms.gradients that contains
classes which are used to compute gradients using the primitive
interfaces defined in qiskit.primitives. There are 4 types of
gradient classes: Finite Difference, Parameter Shift, Linear
Combination of Unitary, and SPSA with implementations that either use
an instance of the BaseEstimator interface:
The estimator-based gradients compute the gradient of expectation
values, while the sampler-based gradients return gradients of the
measurement outcomes (also referred to as “probability gradients”).
The Grover class has a new keyword argument, sampler which is
used to run the algorithm using an instance of the BaseSampler
interface to calculate the results. This new argument supersedes the
the quantum_instance argument and accordingly, quantum_instance
is pending deprecation and will be deprecated and subsequently removed in
future releases.
A new option, "formatter.control.fill_waveform" has been added to
the pulse drawer (pulse_v2.draw() and Schedule.draw())
style sheets. This option can be used to remove the face color of pulses
in the output visualization which allows for drawing pulses only with
lines.
Added a new transpiler pass, ResetAfterMeasureSimplification,
which is used to replace a Reset operation after a
Measure with a conditional XGate. This pass can
be used on backends where a Reset operation is performed by
doing a measurement and then a conditional X gate so that this will
remove the duplicate implicit Measure from the Reset
operation. For example:
Added a new supported value, "reverse_linear" for the entanglement keyword argument
to the constructor for the NLocal circuit class. For TwoLocal circuits
(which are subclassess of NLocal), if entanglement_blocks="cx" then
using entanglement="reverse_linear" provides an equivalent n-qubit circuit as
entanglement="full" but with only \(n-1\)CXGate gates, instead of
\(\frac{n(n-1)}{2}\).
ScheduleBlock has been updated so that it can manage unassigned subroutine,
in other words, to allow lazy calling of other programs.
For example, this enables the following workflow:
Now a user can create prog without knowing actual implementation of
the reference ("x","q0"), and assign it at a later time for execution.
This improves modularity of pulse programs, and thus one can easily write a template
pulse program relying on other calibrations.
To realize this feature, the new pulse instruction (compiler directive)