Qiskit 0.37 release notes
0.37.2
Terra 0.21.2
Prelude
Qiskit Terra 0.21.2 is a primarily a bugfix release, and also comes with several improved documentation pages.
Bug Fixes
-
aer_simulator_statevector_gpu
will now be recognized correctly as statevector method in some function when using Qiskit Aer’s GPU simulators inQuantumInstance
and other algorithm runners. -
Fixed the
UCGate.inverse()
method which previously did not invert the global phase. -
QuantumCircuit.compose()
will now function correctly when used with theinplace=True
argument within control-flow builder contexts. Previously the instructions would be added outside the control-flow scope. Fixed #8433. -
Fixed a bug where a bound
ParameterExpression
was not identified as real ifsymengine
was installed and the bound expression was not a plain1j
. For example:from qiskit.circuit import Parameter x = Parameter("x") expr = 1j * x bound = expr.bind({x: 2}) print(bound.is_real()) # used to be True, but is now False
-
Fixed QPY serialisation and deserialisation of
ControlledGate
with open controls (i.e. those whosectrl_state
is not all ones). Fixed #8549. -
All fake backends in
qiskit.providers.fake_provider.backends
have been updated to return the corresponding pulse channel objects with the method call ofdrive_channel()
,measure_channel()
,acquire_channel()
,control_channel()
. -
Fixed support for running
Z2Symmetries.taper()
on larger problems. Previously, the method would require a large amount of memory which would typically cause failures for larger problem. As a side effect of this fix the performance has significantly improved.
Aer 0.10.4
No change
IBM Q Provider 0.19.2
No change
0.37.1
Terra 0.21.1
Bug Fixes
-
Fixed an issue in
QuantumCircuit.decompose()
method when passing in a list ofGate
classes for thegates_to_decompose
argument. If any gates in the circuit had a label set this argument wouldn’t be handled correctly and caused the output decomposition to incorrectly skip gates explicitly in thegates_to_decompose
list. -
Fix
to_instruction()
which previously tried to create aUnitaryGate
without exponentiating the operator to evolve. Since this operator is generally not unitary, this raised an error (and if the operator would have been unitary by chance, it would not have been the expected result).Now calling
to_instruction()
correctly produces a gate that implements the time evolution of the operator it holds:>>> from qiskit.opflow import EvolvedOp, X >>> op = EvolvedOp(0.5 * X) >>> op.to_instruction() Instruction( name='unitary', num_qubits=1, num_clbits=0, params=[array([[0.87758256+0.j, 0.-0.47942554j], [0.-0.47942554j, 0.87758256+0.j]])] )
-
Fixed an issue with the
marginal_distribution()
function: when a numpy array was passed in for theindices
argument the function would raise an error. Fixed #8283 -
Previously it was not possible to adjoint a
CircuitStateFn
that has been constructed from aVectorStateFn
. That’s because the statevector has been converted to a circuit with theInitialize
instruction, which is not unitary. This problem is now fixed by instead using theStatePreparation
instruction, which can be used since the state is assumed to start out in the all 0 state.For example we can now do:
from qiskit import QuantumCircuit from qiskit.opflow import StateFn left = StateFn([0, 1]) left_circuit = left.to_circuit_op().primitive right_circuit = QuantumCircuit(1) right_circuit.x(0) overlap = left_circuit.inverse().compose(right_circuit) # this line raised an error before!
-
Fix a bug in the
Optimizer
classes where re-constructing a new optimizer instance from a previously exisitingsettings
reset both the new and previous optimizer settings to the defaults. This notably led to a bug ifOptimizer
objects were send as input to Qiskit Runtime programs.Now optimizer objects are correctly reconstructed:
>>> from qiskit.algorithms.optimizers import COBYLA >>> original = COBYLA(maxiter=1) >>> reconstructed = COBYLA(**original.settings) >>> reconstructed._options["maxiter"] 1 # used to be 1000!
-
Fixed an issue where the
limit_amplitude
argument on an individualSymbolicPulse
orWaveform
instance was not properly reflected by parameter validation. In addition, QPY scheduledump()
has been fixed to correctly store thelimit_amplitude
value tied to the instance, rather than saving the global class variable. -
Fix the pairwise entanglement structure for
NLocal
circuits. This led to a bug in theZZFeatureMap
, where usingentanglement="pairwise"
raised an error. Now it correctly produces the desired feature map:from qiskit.circuit.library import ZZFeatureMap encoding = ZZFeatureMap(4, entanglement="pairwise", reps=1) print(encoding.decompose().draw())
The above prints:
┌───┐┌─────────────┐ q_0: ┤ H ├┤ P(2.0*x[0]) ├──■────────────────────────────────────■──────────────────────────────────────────── ├───┤├─────────────┤┌─┴─┐┌──────────────────────────────┐┌─┴─┐ q_1: ┤ H ├┤ P(2.0*x[1]) ├┤ X ├┤ P(2.0*(π - x[0])*(π - x[1])) ├┤ X ├──■────────────────────────────────────■── ├───┤├─────────────┤└───┘└──────────────────────────────┘└───┘┌─┴─┐┌──────────────────────────────┐┌─┴─┐ q_2: ┤ H ├┤ P(2.0*x[2]) ├──■────────────────────────────────────■──┤ X ├┤ P(2.0*(π - x[1])*(π - x[2])) ├┤ X ├ ├───┤├─────────────┤┌─┴─┐┌──────────────────────────────┐┌─┴─┐└───┘└──────────────────────────────┘└───┘ q_3: ┤ H ├┤ P(2.0*x[3]) ├┤ X ├┤ P(2.0*(π - x[2])*(π - x[3])) ├┤ X ├────────────────────────────────────────── └───┘└─────────────┘└───┘└──────────────────────────────┘└───┘
-
Fixed an issue in handling the global phase of the
UCGate
class.
Aer 0.10.4
No change
IBM Q Provider 0.19.2
No change
0.37.0
This release officially marks the end of support for the Qiskit Ignis project from Qiskit. It was originally deprecated in the 0.33.0 release and as was documented in that release the qiskit-ignis
package has been removed from the Qiskit metapackage, which means in that future release pip install qiskit
will no longer include qiskit-ignis
. However, note because of limitations in python packaging we cannot automatically remove a pre-existing install of qiskit-ignis
. If you are upgrading from a previous version it’s recommended that you manually uninstall Qiskit Ignis with pip uninstall qiskit-ignis
or install the metapackage in a fresh python environment.
Qiskit Ignis has been supersceded by the Qiskit Experiments project. You can refer to the migration guide for details on how to switch from Qiskit Ignis to Qiskit Experiments.
Terra 0.21.0
Prelude
The Qiskit 0.21.0 release highlights are:
- Support for serialization of a pulse
ScheduleBlock
viaqiskit.qpy
. The QPY Format has been updated to version 5 which includes a definition for including the pulse schedules. To support this, a newSymbolicPulse
class was introduced to enable defining parametric pulse waveforms via symbolic expressions.- Improvements to working with preset pass managers. A new function
generate_preset_pass_manager()
enables easily generating a pass manager equivalent to whattranspile()
will use internally. Additionally, preset pass managers are now instances ofStagedPassManager
which makes it easier to modify sections.- A refactor of the internal data structure of the
QuantumCircuit.data
attribute. It previously was a list of tuples in the form(instruction, qubits, clbits)
and now is a list ofCircuitInstruction
objects. TheCircuitInstruction
objects is backwards compatible with the previous tuple based access, however with runtime overhead cost.
Additionally, the transpiler has been improved to enable better quality outputs. This includes the introduction of new passes such as VF2PostLayout
and ToqmSwap
.
New Features
-
Added a new class,
qiskit.transpiler.StagedPassManager
, which is aPassManager
subclass that has a pipeline with defined phases to perform circuit compilation. Each phase is aPassManager
object that will get executed in a fixed order. For example:from qiskit.transpiler.passes import * from qiskit.transpiler import PassManager, StagedPassManager basis_gates = ['rx', 'ry', 'rxx'] init = PassManager([UnitarySynthesis(basis_gates, min_qubits=3), Unroll3qOrMore()]) translate = PassManager([Collect2qBlocks(), ConsolidateBlocks(basis_gates=basis_gates), UnitarySynthesis(basis_gates)]) staged_pm = StagedPassManager(stages=['init', 'translation'], init=init, translation=translate)
-
Added the methods
PauliList.group_commuting()
andSparsePauliOp.group_commuting()
, which partition these operators into sublists where each element commutes with all the others. For example:from qiskit.quantum_info import PauliList, SparsePauliOp groups = PauliList(["XX", "YY", "IZ", "ZZ"]).group_commuting() # 'groups' is [PauliList(['IZ', 'ZZ']), PauliList(['XX', 'YY'])] op = SparsePauliOp.from_list([("XX", 2), ("YY", 1), ("IZ", 2j), ("ZZ", 1j)]) groups = op.group_commuting() # 'groups' is [ # SparsePauliOp(['IZ', 'ZZ'], coeffs=[0.+2.j, 0.+1.j]), # SparsePauliOp(['XX', 'YY'], coeffs=[2.+0.j, 1.+0.j]), # ]
-
Added a new function,
marginal_distribution()
, which is used to marginalize an input dictionary of bitstrings to an integer (such asCounts
). This is similar in functionality to the existingmarginal_counts()
function with three key differences. The first is thatmarginal_counts()
works with either a counts dictionary or aResults
object whilemarginal_distribution()
only works with a dictionary. The second is thatmarginal_counts()
does not respect the order of indices in itsindices
argument whilemarginal_distribution()
does and will permute the output bits based on theindices
order. The third difference is thatmarginal_distribution()
should be faster as its implementation is written in Rust and streamlined for just marginalizing a dictionary input. -
Added the
@
(__matmul__
) binary operator toBaseOperator
subclasses in theqiskit.quantum_info
module. This is shorthand to call the classes’dot
method (A @ B == A.dot(B)
). -
Added a new optional argument,
reps
, toQuantumCircuit.decompose()
, which allows repeated decomposition of the circuit. For example:from qiskit import QuantumCircuit circuit = QuantumCircuit(1) circuit.ry(0.5, 0) # Equivalent to circuit.decompose().decompose() circuit.decompose(reps=2) # decompose 2 times, but only RY gate 2 times and R gate 1 times circuit.decompose(gates_to_decompose=['ry','r'], reps=2)
-
Added a new pulse base class
SymbolicPulse
. This is a replacement of the conventionalParametricPulse
, which will be deprecated. In the new base class, pulse-envelope and parameter-validation functions are represented by symbolic-expression objects. The new class provides self-contained and portable pulse data since these symbolic equations can be easily serialized through symbolic computation libraries. -
Added support for non-Hermitian operators in
AerPauliExpectation
. This allows the use of Aer’s fast snapshot expectation computations in algorithms such asQEOM
. -
Added a new circuit drawing style,
textbook
, which uses the color scheme of the Qiskit Textbook. -
A new attribute
QuantumCircuit.op_start_times
is populated when one of scheduling analysis passes is run on the circuit. It can be used to obtain circuit instruction with instruction time, for example:from qiskit import QuantumCircuit, transpile from qiskit.providers.fake_provider import FakeMontreal backend = FakeMontreal() qc = QuantumCircuit(2) qc.h(0) qc.cx(0, 1) qct = transpile( qc, backend, initial_layout=[0, 1], coupling_map=[[0, 1]], scheduling_method="alap" ) scheduled_insts = list(zip(qct.op_start_times, qct.data))
-
Added a new method
QuantumCircuit.clear()
which is used to remove all instructions from aQuantumCircuit
. -
Added a new method
QuantumCircuit.copy_empty_like()
which is used to get a cleared copy of aQuantumCircuit
instance. This is logically equivalent toqc.copy().clear()
, but significantly faster and more memory-efficient. This is useful when one needs a new empty circuit with all the same resources (qubits, classical bits, metadata, and so on) already added. -
The
Target.instruction_supported()
method now supports two new keyword arguments,operation_class
andparameters
. Using these arguments theinstruction_supported()
method can now be used for checking that a specific operation with parameter values are supported by aTarget
object. For example, if you want to check if aTarget
namedtarget
supports running aRXGate
with you would do something like:from math import pi from qiskit.circuit.library import RXGate target.instruction_supported(operation_class=RXGate, parameters=[pi/2])
which will return
True
iftarget
supports runningRXGate
with andFalse
if it does not. -
Added a Trotterization-based quantum real-time evolution algorithm
qiskit.algorithms.TrotterQRTE
. It is compliant with the new quantum time evolution framework and makes use of theProductFormula
andPauliEvolutionGate
implementations.from qiskit.algorithms import EvolutionProblem from qiskit.algorithms.evolvers.trotterization import TrotterQRTE from qiskit.opflow import X, Z, StateFn, SummedOp operator = SummedOp([X, Z]) initial_state = StateFn([1, 0]) time = 1 evolution_problem = EvolutionProblem(operator, time, initial_state) trotter_qrte = TrotterQRTE() evolution_result = trotter_qrte.evolve(evolution_problem) evolved_state_circuit = evolution_result.evolved_state
-
Added a new function
generate_preset_pass_manager()
which can be used to quickly generate a presetPassManager
object that mirrors thePassManager
used internally by thetranspile()
function. For example:from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager from qiskit.providers.fake_provider import FakeWashingtonV2 # Generate an optimization level 3 pass manager targeting FakeWashingtonV2 pass_manager = generate_preset_pass_manager(3, FakeWashingtonV2())
-
Added a new function
marginal_memory()
which is used to marginalize shot memory arrays. Provided with the shot memory array and the indices of interest, the function will return a maginized shot memory array. This function differs from the memory support in themarginal_counts()
method which only works on thememory
field in aResults
object. -
The primitives interface has been extended to accept objects in addition to indices as arguments to the
__call__
method. Theparameter_values
argument can now be optional. -
The OpenQASM 3 exporter (
qiskit.qasm3
) now supports exporting circuits with explicit delays, such as fromQuantumCircuit.delay()
. -
Added a new layout and routing method to
transpile()
based on the paper “Time-optimal qubit mapping”. To use it, the optional package Qiskit TOQM must be installed. Therouting_method
kwarg oftranspile()
supports an additional value,'toqm'
which is used to enable layout and routing via TOQM.To install
qiskit-toqm
along with Terra, run:pip install qiskit-terra[toqm]
-
Added a new module
qiskit.quantum_info.synthesis.qsd
to apply Quantum Shannon Decomposition of arbitrary unitaries. This functionality replaces the previous isometry-based approach in the default unitary synthesis transpiler pass as well as when adding unitaries to a circuit using aUnitaryGate
.The Quantum Shannon Decomposition uses about half the cnot gates as the isometry implementation when decomposing unitary matrices of greater than two qubits.
-
Classes in the
quantum_info
module that support scalar multiplication can now be multiplied by a scalar from either the left or the right. Previously, they would only accept scalar multipliers from the left. -
The transpiler pass
LookaheadSwap
(used bytranspile()
whenrouting_method="lookahead"
) has seen some performance improvements and will now be approximately three times as fast. This is purely being more efficient in its calculations, and does not change the complexity of the algorithm. In most cases, a more modern routing algorithm likeSabreSwap
(routing_method="sabre"
) will be vastly more performant. -
New transpiler passes have been added. The transpiler pass
Commuting2qGateRouter
uses swap strategies to route a block of commuting gates to the coupling map. Indeed, routing is a hard problem but is significantly easier when the gates commute as in CZ networks. Blocks of commuting gates are also typically found in QAOA. Such cases can be dealt with using swap strategies that apply a predefined set of layers of SWAP gates. Furthermore, the new transpiler passFindCommutingPauliEvolutions
identifies blocks of Pauli evolutions made of commuting two-qubit terms. Here, a swap strategy is specified by the classSwapStrategy
. Swap strategies need to be tailored to the coupling map and, ideally, the circuit for the best results. -
Introduced a new optimizer to Qiskit library, which adds support to the optimization of parameters of variational quantum algorithms. This is the Univariate Marginal Distribution Algorithm (UMDA), which is a specific type of the Estimation of Distribution Algorithms. For example:
from qiskit.opflow import X, Z, I from qiskit import Aer from qiskit.algorithms.optimizers import UMDA from qiskit.algorithms import QAOA from qiskit.utils import QuantumInstance H2_op = (-1.052373245772859 * I ^ I) + \ (0.39793742484318045 * I ^ Z) + \ (-0.39793742484318045 * Z ^ I) + \ (-0.01128010425623538 * Z ^ Z) + \ (0.18093119978423156 * X ^ X) p = 2 # Toy example: 2 layers with 2 parameters in each layer: 4 variables opt = UMDA(maxiter=100, size_gen=20) backend = Aer.get_backend('statevector_simulator') vqe = QAOA(opt, quantum_instance=QuantumInstance(backend=backend), reps=p) result = vqe.compute_minimum_eigenvalue(operator=H2_op)
-
The constructor for the
Unroll3qOrMore
transpiler pass has two new optional keyword arguments,target
andbasis_gates
. These options enable you to specify theTarget
or supported basis gates respectively to describe the target backend. If any of the operations in the circuit are in thetarget
orbasis_gates
those will not be unrolled by the pass as the target device has native support for the operation. -
QPY serialization has been upgraded to support
ScheduleBlock
. Now you can save pulse program in binary and load it at later time:from qiskit import pulse, qpy with pulse.build() as schedule: pulse.play(pulse.Gaussian(160, 0.1, 40), pulse.DriveChannel(0)) with open('schedule.qpy', 'wb') as fd: qpy.dump(schedule, fd) with open('schedule.qpy', 'rb') as fd: new_schedule = qpy.load(fd)[0]
This uses the QPY interface common to
QuantumCircuit
. See SCHEDULE_BLOCK for details of data structure. -
Added a new transpiler pass,
VF2PostLayout
. This pass is of a new type to perform a new phase/function in the compilation pipeline, post-layout or post optimization qubit selection. The idea behind this pass is after we finish the optimization loop in transpiler we know what the final gate counts will be on each qubit in the circuit so we can potentially find a better-performing subset of qubits on a backend to execute the circuit. The pass will search for an isomorphic subgraph in the connectivity graph of the target backend and look at the full error rate of the complete circuit on any subgraph found and return the layout found with the lowest error rate for the circuit.This pass is similar to the
VF2Layout
pass and both internally use the same VF2 implementation from retworkx. However,VF2PostLayout
is deisgned to run after initial layout, routing, basis translation, and any optimization passes run and will only work if a layout has already been applied, the circuit has been routed, and all gates are in the target basis. This is required so that when a new layout is applied the circuit can still be run on the target device.VF2Layout
on the other hand is designed to find a perfect initial layout and can work with any circuit. -
The
ApplyLayout
transpiler pass now has support for updating a layout on a circuit after a layout has been applied once before. If thepost_layout
field is present (in addition to the requiredlayout
field) theproperty_set
when theApplyLayout
pass is run the pass will update the layout to apply the new layout. This will return aDAGCircuit
with the qubits in the new physical order and thelayout
property set will be updated so that it maps the virtual qubits from the original layout to the physical qubits in the newpost_layout
field. -
The preset pass managers generated by
level_1_pass_manager()
,level_2_pass_manager()
, andlevel_3_pass_manager()
which correspond tooptimization_level
1, 2, and 3 respectively on thetranspile()
function now run theVF2PostLayout
pass after running the routing pass. This enables the transpiler to potentially find a different set of physical qubits on the target backend to run the circuit on which have lower error rates. TheVF2PostLayout
pass will not be run if you manually specify alayout_method
,routing_method
, orinitial_layout
arguments totranspile()
. If the pass can find a better performing subset of qubits on backend to run the physical circuit it will adjust the layout of the circuit to use the alternative qubits instead. -
The algorithm iteratively computes each eigenstate by starting from the ground state (which is computed as in VQE) and then optimising a modified cost function that tries to compute eigen states that are orthogonal to the states computed in the previous iterations and have the lowest energy when computed over the ansatz. The interface implemented is very similar to that of VQE and is of the form:
from qiskit.algorithms import VQD from qiskit.utils import QuantumInstance from qiskit.circuit.library import TwoLocal from qiskit.algorithms.optimizers import COBYLA from qiskit import BasicAer from qiskit.opflow import I,Z,X h2_op = ( -1.052373245772859 * (I ^ I) + 0.39793742484318045 * (I ^ Z) - 0.39793742484318045 * (Z ^ I) - 0.01128010425623538 * (Z ^ Z) + 0.18093119978423156 * (X ^ X) ) vqd = VQD(k =2, ansatz = TwoLocal(rotation_blocks="ry", entanglement_blocks="cz"),optimizer = COBYLA(maxiter = 0), quantum_instance = QuantumInstance( BasicAer.get_backend("qasm_simulator"), shots = 2048) ) vqd_res = vqd.compute_eigenvalues(op)
This particular code snippet generates 2 eigenvalues (ground and 1st excited state) Tests have also been implemented.
Upgrade Notes
-
The pulse classes in
qiskit.pulse.library
are now subclasses ofSymbolicPulse
rather thanParametricPulse
. The available classes remain unchanged asGaussian
,GaussianSquare
,Drag
, andConstant
.SymbolicPulse
has full backward compatibility, and there should be no loss of functionality. -
The data type of each element in
QuantumCircuit.data
has changed. It used to be a simple 3-tuple of anInstruction
, a list ofQubit
s, and a list ofClbit
s, whereas it is now an instance ofCircuitInstruction
.The attributes of this new class are
operation
,qubits
andclbits
, corresponding to the elements of the previous tuple. However,qubits
andclbits
are nowtuple
instances, notlist
s.This new class will behave exactly like the old 3-tuple if one attempts to access its index its elements, or iterate through it. This includes casting the
qubits
andclbits
elements to lists. This is to assist backwards compatibility. Starting from Qiskit Terra 0.21, this is no longer the preferred way to access these elements. Instead, you should use the attribute-access form described above.This has been done to allow further developments of the
QuantumCircuit
data structure in Terra, without constantly breaking backwards compatibility. Planned developments include dynamic parameterized circuits, and an overall reduction in memory usage of deep circuits. -
The
python-constraint
dependency, which is used solely by theCSPLayout
transpiler pass, is no longer in the requirements list for the Qiskit Terra package. This is because theCSPLayout
pass is no longer used by default in any of the preset pass managers fortranspile()
. While the pass is still available, if you’re using it you will need to manually installpython-contraint
or when you installqiskit-terra
you can use thecsp-layout
extra, for example:pip install "qiskit-terra[csp-layout]"
-
The QPY version format version emitted by
qpy.dump()
has been increased to version 5. 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 5. This change was necessary to fix support for representing controlled gates properly and representing non-default control states. -
Qiskit Terra’s compiled Rust extensions now have a minimum supported Rust version (MSRV) of 1.56.1. This means when building Qiskit Terra from source the oldest version of the Rust compiler supported is 1.56.1. If you are using an older version of the Rust compiler you will need to update to a newer version to continue to build Qiskit from source. This change was necessary as a number of upstream dependencies have updated their minimum supported versions too.
-
Circuit scheduling now executes in parallel when more than one circuit is provided to
schedule()
. Refer to #2695 for more details. -
The previously deprecated
BaseBackend
,BaseJob
, andBaseProvider
classes have all been removed. They were originally deprecated in the 0.18.0 release. Instead of these classes you should be using the versioned providers interface classes, the latest beingBackendV2
,JobV1
, andProviderV1
. -
The previously deprecated
backend
argument for the constructor of theRZXCalibrationBuilder
transpiler pass has been removed. It was originally deprecated in the 0.19.0 release. Instead you should query theBackend
object for theinstruction_schedule_map
andqubit_channel_mapping
and pass that directly to the constructor. For example, with aBackendV1
backend:from qiskit.transpiler.passes import RZXCalibrationBuilder from qiskit.providers.fake_provider import FakeMumbai backend = FakeMumbai() inst_map = backend.defaults().instruction_schedule_map channel_map = backend.configuration().qubit_channel_mapping cal_pass = RZXCalibrationBuilder( instruction_schedule_map=inst_map, qubit_channel_mapping=channel_map, )
or with a
BackendV2
backend:from qiskit.transpiler.passes import RZXCalibrationBuilder from qiskit.providers.fake_provider import FakeMumbaiV2 backend = FakeMumbaiV2() inst_map = backend.instruction_schedule_map channel_map = {bit: backend.drive_channel(bit) for bit in range(backend.num_qubits)} cal_pass = RZXCalibrationBuilder( instruction_schedule_map=inst_map, qubit_channel_mapping=channel_map, )
-
The measurement shot limit for the
BasicAer
backend has been removed. -
For the
DAGNode
, the previously deprecatedtype
,op
,qargs
,cargs
, andwire
kwargs and attributes have been removed. These were originally deprecated in the 0.19.0 release. Theop
,qargs
, andcargs
kwargs and attributes can be accessed only on instances ofDAGOpNode
, and thewire
kwarg and attribute are only on instances ofDAGInNode
orDAGOutNode
. -
The deprecated function
pauli_group()
has been removed. It was originally deprecated in Qiskit Terra 0.17. -
Several deprecated methods on
Pauli
have been removed, which were originally deprecated in Qiskit Terra 0.17. These were:sgn_prod
Use
Pauli.compose()
orPauli.dot()
instead.to_spmatrix
Use
Pauli.to_matrix()
with argumentsparse=True
instead.kron
Use
Pauli.expand()
, but beware that this returns a new object, rather than mutating the existing one.update_z
andupdate_x
Set the
z
andx
attributes of the object directly.insert_paulis
Use
Pauli.insert()
.append_paulis
Use
Pauli.expand()
.delete_qubits
Use
Pauli.delete()
.pauli_single
Construct the label manually and pass directly to the initializer, such as:
Pauli("I" * index + pauli_label + "I" * (num_qubits - index - len(pauli_label)))
random
Use
quantum_info.random_pauli()
instead. -
Removed the
optimize
method from theOptimizer
classes, which is superseded by theminimize()
method as direct replacement. The one exception isSPSA
, where the deprecation warning was not triggered so the method there is still kept. -
Result
was modified so that it always containsdate
,status
, andheader
attributes (set toNone
if not specified). -
For Python 3.7 shared-memory38 is now a dependency. This was added as a dependency for Python 3.7 to enable leveraging the shared memory constructs in the standard library of newer versions of Python. If you’re running on Python >= 3.8 there is no extra dependency required.
-
Instruction
labels are now type-checked on instruction creation. -
QPY serialization has been upgraded to serialize
QuantumCircuit
withQuantumCircuit.calibrations
. As of QPY Version 5, only calibration entries ofScheduleBlock
type can be serialized. -
The definition of
XXPlusYYGate
has been changed. See #7969 for details. -
The preset pass managers generated by
level_1_pass_manager()
,level_2_pass_manager()
, andlevel_3_pass_manager()
and used by thetranspile()
function’soptimization_level
argument at 1, 2, and 3 respectively no longer set a hard time limit on theVF2Layout
transpiler pass. This means that the pass will no longer stop trying to find a better alternative perfect layout up until a fixed time limit (100ms for level 1, 10 sec for level 2, and 60 sec for level 3) as doing this limited the reproducibility of compilation when a perfect layout was available. This means that the output when using the pass might be different than before, although in all cases it would only change if a lower noise set of qubits can be found over the previous output. If you wish to retain the previous behavior you can create a customPassManager
that sets thetime_limit
argument on the constructor for theVF2Layout
pass.
Deprecation Notes
-
Calling
timeline_drawer()
with an unscheduled circuit has been deprecated. All circuits, even one consisting only of delay instructions, must be transpiled with thescheduling_method
keyword argument oftranspile()
set, to generate schedule information being stored inQuantumCircuit.op_start_times
. -
The NetworkX converter functions for the
DAGCircuit.to_networkx()
andfrom_networkx()
, along with theDAGDependency.to_networkx()
method have been deprecated and will be removed in a future release. Qiskit has been using retworkx as its graph library since the qiskit-terra 0.12.0 release, and since then the networkx converter functions have been lossy. They were originally added so that users could leverage functionality in NetworkX’s algorithms library not present in retworkx. Since that time, retworkx has matured and offers more functionality, and theDAGCircuit
is tightly coupled to retworkx for its operation. Having these converter methods provides limited value moving forward and are therefore going to be removed in a future release. -
Accessing several old toggles (
HAS_MATPLOTLIB
,HAS_PDFTOCAIRO
,HAS_PYLATEX
andHAS_PIL
) from theqiskit.visualization
module is now deprecated, and these import paths will be removed in a future version of Qiskit Terra. The same objects should instead be accessed throughqiskit.utils.optionals
, which contains testers for almost all of Terra’s optional dependencies. -
The
qiskit.test.mock
module is now deprecated. The fake backend and fake provider classes which were previously available inqiskit.test.mock
have been accessible inqiskit.providers.fake_provider
since Terra 0.20.0. This change represents a proper commitment to support the fake backend classes as part of Qiskit, whereas previously they were just part of the internal testing suite, and were exposed to users as a side effect. -
The arguments’ names when calling an
Estimator
orSampler
object as a function are renamed fromcircuit_indices
andobservable_indices
tocircuits
andobservables
. -
The
qobj_id
andqobj_header
keyword arguments for theexecute()
function have been deprecated and will be removed in a future release. Since the removal of theBaseBackend
class these arguments don’t have any effect as no backend supports execution with aQobj
object directly and instead only work withQuantumCircuit
objects directly. -
The arguments
x
,z
andlabel
to the initializer ofPauli
were documented as deprecated in Qiskit Terra 0.17, but a bug prevented the expected warning from being shown at runtime. The warning will now correctly show, and the arguments will be removed in Qiskit Terra 0.23 or later. A pair ofx
andz
should be passed positionally as a single tuple (Pauli((z, x))
). A stringlabel
should be passed positionally in the first argument (Pauli("XYZ")
). -
The
SPSA.optimize()
method is deprecated in favor ofSPSA.minimize()
, which can be used as direct replacement. Note that this method returns a complete result object with more information than before available. -
The
circuits
argument ofqpy.dump()
has been deprecated and replaced withprograms
since now QPY supports multiple data types other than circuits. -
AlignmentKind.to_dict()
method has been deprecated and will be removed.
Bug Fixes
-
Extra validation was added to
DiagonalGate
to check the argument has modulus one. -
Duplicate qubit indices given to
SparsePauliOp.from_sparse_list()
will now correctly raise an error, instead of silently overwriting previous values. The old behavior can be accessed by passing the new keyword argumentdo_checks=False
. -
The
timeline_drawer()
visualization will no longer misalign classical register slots. -
Parameter validation for
GaussianSquare
is now consistent before and after construction. Refer to #7882 for more details. -
The
BackendV2
-based fake backends in theqiskit.providers.fake_provider
module, such asFakeMontrealV2
, now support theDelay
operation in theirtarget
attributes. Previously,QuantumCircuit
objects that contained delays could not be compiled to these backends. -
Fixed a bug in
TridiagonalToeplitz.eigs_bounds()
, which caused incorrect eigenvalue bounds to be returned in some cases with negative eigenvalues. Refer to #7939 for more details. -
Fixed a bug in which the LaTeX statevector drawer ignored the
max_size
parameter. -
Fixed support in the
PassManagerConfig.from_backend()
constructor method for building aPassManagerConfig
object from aBackendV2
instance. Previously this wasn’t handled correctly and would fail when running with aBackendV2
object. -
Fixed support for QPY serialization (
qpy.dump()
) and deserialization (qpy.load()
) of aQuantumCircuit
object containing customControlledGate
objects. Previously, an exception would be raised byqpy.load()
when trying to reconstruct the customControlledGate
. Fixed #7999. -
Fixed support for QPY serialization (
qpy.dump()
) and deserialization (qpy.load()
) of aQuantumCircuit
object containing customMCPhaseGate
objects. Previously, an exception would be raised byqpy.load()
when trying to reconstruct theMCPhaseGate
. -
Fixed support for QPY serialization (
qpy.dump()
) and deserialization (qpy.load()
) of aQuantumCircuit
object containing controlled gates with an open control state. Previously, the open control state would be lost by the serialization process and the reconstructed circuit. -
Fixed
QuantumCircuit.reverse_bits()
with circuits containing registerlessQubit
andClbit
. For example, the following will now work:from qiskit.circuit import QuantumCircuit, Qubit, Clbit qc = QuantumCircuit([Qubit(), Clbit()]) qc.h(0).c_if(qc.clbits[0], 0) qc.reverse_bits()
-
Fixed the
ConfigurableFakeBackend.t2
attribute, which was previously incorrectly set based on the providedt1
value. -
Fixed an issue with
BackendV2
-based fake backend classes from theqiskit.providers.fake_provider
module such asFakeMontrealV2
where the value for thedt
attribute (and theTarget.dt
attribute) were not properly being converted to seconds. This would cause issues when using these fake backends with scheduling. -
Fixed a bug in
plot_histogram()
when thenumber_to_keep
argument was smaller that the number of keys. The following code will no longer throw errors and will be properly aligned:from qiskit.visualization import plot_histogram data = {'00': 3, '01': 5, '11': 8, '10': 11} plot_histogram(data, number_to_keep=2)
-
Improved the performance of building and working with parameterized
QuantumCircuit
instances with many gates that share a relatively small number of parameters. -
The OpenQASM 3 exporter (
qiskit.qasm3
) will no longer attempt to produce definitions for non-standard gates in thebasis_gates
option. -
Fixed the getter of
OptimizerResult.nit
, which previously returned the number of Jacobian evaluations instead of the number of iterations. -
Fixed a bug in the string representation of
Result
objects that caused the attributes to be specified incorrectly. -
Fixed an issue with
transpile()
where in some cases providing a list of basis gate strings with thebasis_gates
keyword argument or implicitly via aTarget
input via thetarget
keyword argument would not be interpreted correctly and result in a subset of the listed gates being used for each circuit. -
Fixed an issue in the
UnitarySynthesis
transpiler pass which would result in an error when aTarget
that didn’t have any qubit restrictions on the operations (e.g. in the case of an ideal simulator target) was specified with thetarget
keyword argument for the constructor. -
The method
qiskit.result.marginal_counts()
, when passed aResult
from a pulse backend, would fail, because it contains an array ofExperimentResult
objects, each of which have anQobjExperimentHeader
, and thoseExperimentHeaders
lack creg_sizes instance-variables. If theResult
came from a simulator backend (e.g. Aer), that instance-variable would be there. We fixmarginal_counts
so that it skips logic that needs creg_sizes if the field is not present, or non-None. -
The OpenQASM 2 exporter (
QuantumCircuit.qasm()
) will now correctly define the qubit parameters forUnitaryGate
operations that do not affect all the qubits they are defined over. Fixed #8224. -
Fixed an issue with reproducibility of the
transpile()
function when running withoptimization_level
1, 2, and 3. Previously, under some conditions when there were multiple perfect layouts (a layout that doesn’t require any SWAP gates) available the selected layout and output circuit could vary regardless of whether theseed_transpiler
argument was set.
Aer 0.10.4
No change
IBM Q Provider 0.19.2
Bug Fixes
- 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.
threading.currentThread
andnotifyAll
were deprecated in Python 3.10 (October 2021) and will be removed in Python 3.12 (October 2023). PR #1133 replaces them withthreading.current_thread
,notify_all
added in Python 2.6 (October 2008).