# Release Notes¶

## Version History¶

This table tracks the meta-package versions and the version of each Qiskit element installed:

Table 1 Version History

Qiskit Metapackage Version

qiskit-terra

qiskit-aer

qiskit-ignis

qiskit-ibmq-provider

qiskit-aqua

Release Date

0.34.1

0.19.1

0.10.2

0.7.0

0.18.3

2022-01-05

0.34.0

0.19.1

0.10.1

0.7.0

0.18.3

2021-12-20

0.33.1

0.19.1

0.9.1

0.7.0

0.18.2

2021-12-10

0.33.0

0.19.0

0.9.1

0.7.0

0.18.1

2021-12-06

0.32.1

0.18.3

0.9.1

0.6.0

0.18.1

0.9.5

2021-11-22

0.32.0

0.18.3

0.9.1

0.6.0

0.18.0

0.9.5

2021-11-10

0.31.0

0.18.3

0.9.1

0.6.0

0.17.0

0.9.5

2021-10-12

0.30.1

0.18.3

0.9.0

0.6.0

0.16.0

0.9.5

2021-09-29

0.30.0

0.18.2

0.9.0

0.6.0

0.16.0

0.9.5

2021-09-16

0.29.1

0.18.2

0.8.2

0.6.0

0.16.0

0.9.5

2021-09-10

0.29.0

0.18.1

0.8.2

0.6.0

0.16.0

0.9.4

2021-08-02

0.28.0

0.18.0

0.8.2

0.6.0

0.15.0

0.9.4

2021-07-13

0.27.0

0.17.4

0.8.2

0.6.0

0.14.0

0.9.2

2021-06-15

0.26.2

0.17.4

0.8.2

0.6.0

0.13.1

0.9.1

2021-05-19

0.26.1

0.17.4

0.8.2

0.6.0

0.13.1

0.9.1

2021-05-18

0.26.0

0.17.3

0.8.2

0.6.0

0.13.1

0.9.1

2021-05-11

0.25.4

0.17.2

0.8.2

0.6.0

0.12.3

0.9.1

2021-05-05

0.25.3

0.17.1

0.8.2

0.6.0

0.12.3

0.9.1

2021-04-29

0.25.2

0.17.1

0.8.1

0.6.0

0.12.3

0.9.1

2021-04-21

0.25.1

0.17.1

0.8.1

0.6.0

0.12.2

0.9.1

2021-04-15

0.25.0

0.17.0

0.8.0

0.6.0

0.12.2

0.9.0

2021-04-02

0.24.1

0.16.4

0.7.6

0.5.2

0.12.2

0.8.2

2021-03-24

0.24.0

0.16.4

0.7.6

0.5.2

0.12.1

0.8.2

2021-03-04

0.23.6

0.16.4

0.7.5

0.5.2

0.11.1

0.8.2

2021-02-18

0.23.5

0.16.4

0.7.4

0.5.2

0.11.1

0.8.2

2021-02-08

0.23.4

0.16.3

0.7.3

0.5.1

0.11.1

0.8.1

2021-01-28

0.23.3

0.16.2

0.7.3

0.5.1

0.11.1

0.8.1

2021-01-26

0.23.2

0.16.1

0.7.2

0.5.1

0.11.1

0.8.1

2020-12-15

0.23.1

0.16.1

0.7.1

0.5.1

0.11.1

0.8.1

2020-11-12

0.23.0

0.16.0

0.7.0

0.5.0

0.11.0

0.8.0

2020-10-16

0.22.0

0.15.2

0.6.1

0.4.0

0.10.0

0.7.5

2020-10-05

0.21.0

0.15.2

0.6.1

0.4.0

0.9.0

0.7.5

2020-09-16

0.20.1

0.15.2

0.6.1

0.4.0

0.8.0

0.7.5

2020-09-08

0.20.0

0.15.1

0.6.1

0.4.0

0.8.0

0.7.5

2020-08-10

0.19.6

0.14.2

0.5.2

0.3.3

0.7.2

0.7.3

2020-06-25

0.19.5

0.14.2

0.5.2

0.3.2

0.7.2

0.7.3

2020-06-19

0.19.4

0.14.2

0.5.2

0.3.0

0.7.2

0.7.2

2020-06-16

0.19.3

0.14.1

0.5.2

0.3.0

0.7.2

0.7.1

2020-06-02

0.19.2

0.14.1

0.5.1

0.3.0

0.7.1

0.7.1

2020-05-14

0.19.1

0.14.1

0.5.1

0.3.0

0.7.0

0.7.0

2020-05-01

0.19.0

0.14.0

0.5.1

0.3.0

0.7.0

0.7.0

2020-04-30

0.18.3

0.13.0

0.5.1

0.3.0

0.6.1

0.6.6

2020-04-24

0.18.2

0.13.0

0.5.0

0.3.0

0.6.1

0.6.6

2020-04-23

0.18.1

0.13.0

0.5.0

0.3.0

0.6.0

0.6.6

2020-04-20

0.18.0

0.13.0

0.5.0

0.3.0

0.6.0

0.6.5

2020-04-09

0.17.0

0.12.0

0.4.1

0.2.0

0.6.0

0.6.5

2020-04-01

0.16.2

0.12.0

0.4.1

0.2.0

0.5.0

0.6.5

2020-03-20

0.16.1

0.12.0

0.4.1

0.2.0

0.5.0

0.6.4

2020-03-05

0.16.0

0.12.0

0.4.0

0.2.0

0.5.0

0.6.4

2020-02-27

0.15.0

0.12.0

0.4.0

0.2.0

0.4.6

0.6.4

2020-02-06

0.14.1

0.11.1

0.3.4

0.2.0

0.4.5

0.6.2

2020-01-07

0.14.0

0.11.0

0.3.4

0.2.0

0.4.4

0.6.1

2019-12-10

0.13.0

0.10.0

0.3.2

0.2.0

0.3.3

0.6.1

2019-10-17

0.12.2

0.9.1

0.3.0

0.2.0

0.3.3

0.6.0

2019-10-11

0.12.1

0.9.0

0.3.0

0.2.0

0.3.3

0.6.0

2019-09-30

0.12.0

0.9.0

0.3.0

0.2.0

0.3.2

0.6.0

2019-08-22

0.11.2

0.8.2

0.2.3

0.1.1

0.3.2

0.5.5

2019-08-20

0.11.1

0.8.2

0.2.3

0.1.1

0.3.1

0.5.3

2019-07-24

0.11.0

0.8.2

0.2.3

0.1.1

0.3.0

0.5.2

2019-07-15

0.10.5

0.8.2

0.2.1

0.1.1

0.2.2

0.5.2

2019-06-27

0.10.4

0.8.2

0.2.1

0.1.1

0.2.2

0.5.1

2019-06-17

0.10.3

0.8.1

0.2.1

0.1.1

0.2.2

0.5.1

2019-05-29

0.10.2

0.8.0

0.2.1

0.1.1

0.2.2

0.5.1

2019-05-24

0.10.1

0.8.0

0.2.0

0.1.1

0.2.2

0.5.0

2019-05-07

0.10.0

0.8.0

0.2.0

0.1.1

0.2.1

0.5.0

2019-05-06

0.9.0

0.8.0

0.2.0

0.1.1

0.1.1

0.5.0

2019-05-02

0.8.1

0.7.2

0.1.1

0.1.0

2019-05-01

0.8.0

0.7.1

0.1.1

0.1.0

2019-03-05

0.7.3

>=0.7,<0.8

>=0.1,<0.2

2019-02-19

0.7.2

>=0.7,<0.8

>=0.1,<0.2

2019-01-22

0.7.1

>=0.7,<0.8

>=0.1,<0.2

2019-01-17

0.7.0

>=0.7,<0.8

>=0.1,<0.2

2018-12-14

নোট

For the 0.7.0, 0.7.1, and 0.7.2 meta-package releases the Qiskit সংস্করণ policy was not formalized yet.

## Notable Changes¶

### Qiskit 0.34.1¶

No change

#### Aer 0.10.2¶

##### Bug Fixes¶
• Fixed simulation of for loops where the loop parameter was not used in the body of the loop. For example, previously this code would fail, but will now succeed:

import qiskit
from qiskit.providers.aer import AerSimulator

qc = qiskit.QuantumCircuit(2)
with qc.for_loop(range(4)) as i:
qc.h(0)
qc.cx(0, 1)

AerSimulator(method="statevector").run(qc)

• Fixes a bug in QuantumError.to_dict() where N-qubit circuit instructions where the assembled instruction always applied to qubits [0, ..., N-1] rather than the instruction qubits. This bug also affected device and fake backend noise models.

See Issue 1415 for details.

No change

No change

### Qiskit 0.34.0¶

Qiskit 0.34.0 includes a point release of Qiskit Aer: version 0.10.1, which patches performance regressions in version 0.10.0 that were discovered immediately post-release. See below for the release notes for both Qiskit Aer 0.10.0 and 0.10.1.

No change

#### Aer 0.10.1¶

##### Prelude¶

The Qiskit Aer 0.10.1 patch fixes performance regressions introduced in Qiskit Aer 0.10.0.

##### Bug Fixes¶
• Fix performance regression in noisy simulations due to large increase in serialization overhead for loading noise models from Python into C++ resulting from unintended nested Python multiprocessing calls. See issue 1407 for details.

#### Aer 0.10.0¶

##### Prelude¶

The Qiskit Aer 0.10 release includes several performance and noise model improvements. Some highlights are:

• Improved performance for parallel shot GPU and HPC simulations

• Support for simulation of circuits containing QASM 3.0 control-flow instructions

• Support for relaxation noise on scheduled circuits in backend noise models

• Support of user-created transpiler passes for defining custom gate errors and noise models, and inserting them into circuits.

##### New Features¶
• Added a batched-shot simulation optimization for GPU simulations. This optional feature will use available memory on 1 or more GPUs to run multiple simulation shots in parallel for greatly improved performance on multi-shot simulations with noise models and/or intermediate measurements.

This option is enabled by default when using device="GPU" and a simulation method of either "statevector" or "density_matrix" with the AerSimulator. It can be disabled by setting batched_shots_gpu=False in the simulator options.

This optimization is most beneficial for small to medium numbers of qubits where there is sufficient GPU memory to run multiple simulations in parallel. The maximum number of active circuit qubits for enabling this optimization can be configured using the batch_shots_gpu_max_qubits simulator option. The default value of this option is 16.

• Added the new max_shot_size option to a custom executor for running multiple shots of a noisy circuit in parallel.

For example configuring max_shot_size with a custom executor:

backend = AerSimulator(
max_shot_size=1, max_job_size=1, executor=custom_executor)
job = backend.run(circuits)


will split the shots of a noisy circuit into multiple circuits. After all individual shots have finished executing, the job results are automatically combined into a single Result object that is returned by job.result().

• Added the mps_swap_direction simulator option that allows the user to determine the direction of internal swaps, when they are inserted for a 2-qubit gate. Possible values are "mps_swap_right" and "mps_swap_left". The direction of the swaps may affect performance, depending on the circuit.

• Implemented a new measurement sampling optimization for the "matrix_product_state" simulation method of the AerSimulator. Currently this algorithm is used only when all qubits are measured and when the simulator mps_sample_measure_algorithm simulator option is set to "mps_probabilities".

• Improved the performance of the measure instruction for the "matrix_product_state" simulation method of the AerSimulator.

• Added two transpiler passes for inserting instruction-dependent quantum errors into circuits:

The LocalNoisePass pass can be used to implement custom parameterized noise models by defining a noise generating function of the form

def fn(
inst: Instruction,
qubits: Optional[List[int]] = None,
) -> InstructionLike


which returns a noise instruction (eg. a QuantumError or other instruction) that can depend on any properties or parameters of the instruction and qubit arguements.

This function can be applied to all instructions in a circuit, or a specified subset (See the LocalNoisePass documentation for additional details.)

The RelaxationNoisePass is a special case of the LocalNoisePass using a predefined noise function that returns a tensor product of thermal_relaxation_error() on each qubit in an instruction, dependent on the instruction's duration and the supplied relaxation time constant parameters of the pass.

• The basic device noise model implemented by NoiseModel.from_backend() and AerSimulator.from_backend() has been upgraded to allow adding duration-dependent relaxation errors on circuit delay gates using the RelaxationNoisePass.

To enable this noise when running noisy simulations you must first schedule your circuit to insert scheduled delay instructions as follows:

backend = AerSimulator.from_backend(ibmq_backend)
scheduled_circuit = qiskit.transpile(
circuit, backend=backend, scheduling_method='asap')
result = backend.run(scheduled_circuit).result()


If the circuit is transpiled without being scheduled (and also contains no delay instructions) the noisy simulation will not include the effect of delay relaxation errors. In this case the simulation will be equivalent to the previous qiskit-aer 0.9 simulation where relaxation noise is only added to gate instructions based on their duration as obtained from the backend properties.

• The constructor of QuantumError now accepts several new types of input as noise_ops argument, for example:

import numpy as np

from qiskit import QuantumCircuit
from qiskit.circuit.library import IGate, XGate, Reset
from qiskit.quantum_info import Kraus
from qiskit.providers.aer.noise import QuantumError

# Quantum channels
kraus = Kraus([
np.array([[1, 0], [0, np.sqrt(1 - 0.9)]], dtype=complex),
np.array([[0, 0], [0, np.sqrt(0.9)]], dtype=complex)
])
print(QuantumError(kraus))

# Construction from a QuantumCircuit
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
error = QuantumError(qc)

# Construction from a tuple of (Instruction, List[int]), where the list of
# integers represents the qubits.
error = QuantumError((Reset(), [0]))

# Construction from an iterable of objects in the same form as above, but
# where each also has an associated probability.
error = QuantumError([
((IGate(), [0]), 0.9),
((XGate(), [0]), 0.1),
])

# A short-hand for the iterable form above, where the qubits are implicit,
# and each instruction is over all qubits.
error = QuantumError([(IGate(), 0.9), (XGate(), 0.1)])


Note that the original JSON-based input format is deperecated.

• Added the ability to add QuantumError objects directly to a QuantumCircuit without converting to a Kraus instruction.

Circuits containing quantum errors can now be run on the AerSimulator and QasmSimulator simulators as an alternative to, or in addition to, building a NoiseModel for defining noisy circuit instructions.

Example:

from qiskit import QuantumCircuit
from qiskit.providers.aer import AerSimulator
from qiskit.providers.aer.noise import pauli_error

error_h = pauli_error([('I', 0.95), ('X', 0.05)])
error_cx = pauli_error([('II', 0.9), ('XX', 0.1)])

qc = QuantumCircuit(3)
qc.h(0)
qc.append(error_h, [0])
qc.cx(0, 1)
qc.append(error_cx, [0, 1])
qc.cx(0, 2)
qc.append(error_cx, [0, 2])
qc.measure_all()

backend = AerSimulator(method='stabilizer')
result = backend.run(qc).result()
result.get_counts(0)


Circuits containing quantum errors can also be evaluated using the quantum_info quantum channel and DensityMatrix classes.

• Changed the default value of standard_gates to None for all functions in qiskit.providers.aer.noise.errors.standard_errors as those functions are updated so that they use standard gates by default.

##### Deprecation Notes¶
• Deprecated the number_of_qubits option of the QuantumError constructor in favor of automatic determination of the dimension.

• Deprecated the standard_gates option of all functions in qiskit.providers.aer.noise.errors.standard_errors in favor of returning errors in the form of a mixture of standard gates as much as possible by default.

• Deprecated all functions in errorutils because they are helper functions meant to be used only for implementing functions in qiskit.providers.aer.noise.errors.standard_errors and they should have been provided as private functions.

No change

#### IBM Q Provider 0.18.3¶

##### Bug Fixes¶
• Fix delivered in #1100 for an issue with JSON encoding and decoding when using ParameterExpressions in conjunction with Qiskit Terra 0.19.1 and above. Previously, the Parameter instances reconstructed from the JSON output would have different unique identifiers, causing them to seem unequal to the input. They will now have the correct backing identities.

### Qiskit 0.33.1¶

#### Terra 0.19.1¶

##### Prelude¶

Qiskit Terra 0.19.1 is a bugfix release, solving some issues in 0.19.0 concerning circuits constructed by the control-flow builder interface, conditional gates and QPY serialisation of newer Terra objects.

##### Deprecation Notes¶
• The loose functions qiskit.circuit.measure.measure() and qiskit.circuit.reset.reset() are deprecated, and will be removed in a future release. Instead, you should access these as methods on QuantumCircuit:

from qiskit import QuantumCircuit
circuit = QuantumCircuit(1, 1)

# Replace this deprecated form ...
from qiskit.circuit.measure import measure
measure(circuit, 0, 0)

# ... with either of the next two lines:
circuit.measure(0, 0)
QuantumCircuit.measure(circuit, 0, 0)

##### Bug Fixes¶
• Fixed an issue where calling QuantumCircuit.copy() on the "body" circuits of a control-flow operation created with the builder interface would raise an error. For example, this was previously an error, but will now return successfully:

from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister

qreg = QuantumRegister(4)
creg = ClassicalRegister(1)
circ = QuantumCircuit(qreg, creg)

with circ.if_test((creg, 0)):
circ.h(0)

if_else_instruction, _, _ = circ.data[0]
true_body = if_else_instruction.params[0]
true_body.copy()

• The control-flow builder interface now supports using ClassicalRegisters as conditions in nested control-flow scopes. Previously, doing this would not raise an error immediately, but the internal circuit blocks would not have the correct registers defined, and so later logic that worked with the inner blocks would fail.

For example, previously the drawers would fail when trying to draw an inner block conditioned on a classical register, whereas now it will succeed, such as in this example:

from qiskit import QuantumCircuit
from qiskit.circuit import QuantumRegister, ClassicalRegister

qreg = QuantumRegister(4)
creg = ClassicalRegister(1)
circ = QuantumCircuit(qreg, creg)

with circ.for_loop(range(10)) as a:
circ.ry(a, 0)
with circ.if_test((creg, 1)):
circ.break_loop()

print(circ.draw(cregbundle=False))
print(circ.data[0][0].blocks[0].draw(cregbundle=False))

• Two loose functions qiskit.circuit.measure.measure() and qiskit.circuit.reset.reset() were accidentally removed without a deprecation period. They have been reinstated, but are marked as deprecated in favour of the methods QuantumCircuit.measure() and QuantumCircuit.reset(), respectively, and will be removed in a future release.

##### Other Notes¶
• The new control-flow builder interface uses various context managers and helper objects to do its work. These should not be considered part of the public API, and are liable to be changed and removed without warning. The usage of the builder interface has stability guarantees, in the sense that the behaviour described by QuantumCircuit.for_loop(), while_loop() and if_test() for the builder interface are subject to the standard deprecation policies, but the actual objects used to effect this are not. You should not rely on the objects (such as IfContext or ControlFlowBuilderBlock) existing in their current locations, or having any methods or attributes attached to them.

This was not previously clear in the 0.19.0 release. All such objects now have a warning in their documentation strings making this explicit. It is likely in the future that their locations and backing implementations will become quite different.

No change

No change

### Qiskit 0.33.0¶

This release officially marks the end of support for the Qiskit Aqua project in Qiskit. It was originally deprecated in the 0.25.0 release and as was documented in that release the qiskit-aqua package has been removed from the Qiskit metapackage, which means pip install qiskit will no longer include qiskit-aqua. However, because of limitations in python packaging we cannot automatically remove a pre-existing install of qiskit-aqua when upgrading a previous version of Qiskit to this release (or a future release) with pip install -U qiskit. If you are upgrading from a previous version it's recommended that you manually uninstall Qiskit Aqua with pip uninstall qiskit-aqua or install in a fresh python environment.

The application modules that were provided by qiskit-aqua have been split into several new packages: qiskit-optimization, qiskit-nature, qiskit-machine-learning, and qiskit-finance. These packages can be installed by themselves (via the standard pip install command, e.g. pip install qiskit-nature) or with the rest of the Qiskit metapackage as optional extras (e.g. pip install 'qiskit[finance,optimization]' or pip install 'qiskit[all]'). The core algorithms and the operator flow now exist as part of Qiskit Terra at qiskit.algorithms and qiskit.opflow. Depending on your existing usage of Aqua you should either use the application packages or the new modules in Qiskit Terra. For more details on how to migrate from Qiskit Aqua you can refer to the Aqua Migration Guide.

This release also officially deprecates the Qiskit Ignis project. Accordingly, in a future release the qiskit-ignis package will be removed from the Qiskit metapackage, which means in that future release pip install qiskit will no longer include qiskit-ignis. Qiskit Ignis has been supersceded by the Qiskit Experiments project and active development has ceased. While deprecated, critical bug fixes and compatibility fixes will continue to be made to provide users a sufficient opportunity to migrate off of Ignis. After the deprecation period (which will be no shorter than 3 months from this release) the project will be retired and archived. You can refer to the migration guide for details on how to switch from Qiskit Ignis to Qiskit Experiments.

#### Terra 0.19.0¶

##### Prelude¶

The Qiskit Terra 0.19 release highlights are:

This release marks the end of support for Python 3.6 in Qiskit. This release of Qiskit Terra, and any subsequent bugfix releases in the 0.19.x series, will be the last to work with Python 3.6. Starting from the next minor release (0.20.0) of Qiskit Terra, the minimum required Python version will be 3.7.

As always, there are many more features and fixes in this release as well, which you can read about below.

##### New Features¶
• QuantumCircuit.decompose() and its corresponding transpiler pass Decompose now optionally accept a parameter containing a collection of gate names. If this parameter is given, then only gates with matching names will be decomposed. This supports Unix-shell-style wildcard matches. For example:

qc.decompose(["h", "r[xz]"])


will decompose any h, rx or rz gates, but leave (for example) x gates untouched.

• Added the termination_checker argument to the SPSA optimizer. This allows the user to implement a custom termination criterion.

import numpy as np
from qiskit.algorithms.optimizers import SPSA

def objective(x):
return np.linalg.norm(x) + .04*np.random.rand(1)

class TerminationChecker:

def __init__(self, N : int):
"""
Callback to terminate optimization when the average decrease over
the last N data points is smaller than the specified tolerance.
"""
self.N = N
self.values = []

def __call__(self, nfev, parameters, value, stepsize, accepted) -> bool:
"""
Returns:
True if the optimization loop should be terminated.
"""
self.values.append(value)

if len(self.values) > self.N:
last_values = self.values[-self.N:]
pp = np.polyfit(range(self.N), last_values, 1)
slope = pp[0] / self.N

if slope > 0:
return True
return False

maxiter = 400
spsa = SPSA(maxiter=maxiter, termination_checker=TerminationChecker(10))
parameters, value, niter = spsa.optimize(2, objective, initial_point=np.array([0.5, 0.5]))

• Added a new Target class to the transpiler module. The Target class is designed to represent the constraints of backend to the compiler. The Target class is intended to be used with a BackendV2 backend and is how backends will model their constraints for the transpiler moving forward. It combines the previously distinct fields used for controlling the transpile() target device (e.g. basis_gates, coupling_map, instruction_durations, etc) into a single data structure. It also adds additional functionality on top of what was available previously such as representing heterogeneous gate sets, multi-qubit gate connectivity, and tuned variants of the same gates. Currently the transpiler doesn't factor in all these constraints, but over time it will grow to leverage the extra functionality.

• The Options class now has optional support for specifying validators. This enables Backend authors to optionally specify basic validation on the user supplied values for fields in the Options object. For example, if you had an Options object defined with:

from qiskit.providers.Options
options = Options(shots=1024)


you can set a validator on shots for it to be between 1 and 4096 with:

options.set_validator('shots', (1, 4096))


With the validator set any call to the update_options() method will check that if shots is being updated the proposed new value is within the valid range.

• Added a new transpiler analysis pass, ContainsInstruction, to the qiskit.transpiler.passes module. This pass is used to determine if a circuit contains a specific instruction. It takes in a single parameter at initialization, the name of the instruction to check for and set a boolean in the property set whether the circuit contains that instruction or not. For example:

from qiskit.transpiler.passes import ContainsInstruction
from qiskit.circuit import QuantumCircuit

circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()

property_set = {}
contains_h = ContainsInstruction("h")
contains_h(circuit, property_set)
assert property_set["contains_h"] == True
# Not contains SX
contains_sx = ContainsInstruction("sx")
contains_sx(circuit, property_set)
assert property_set["contains_sx"] == False

• Added a utility function qiskit.utils.detach_prefix() that is a counterpart of apply_prefix(). The new function returns a tuple of scaled value and prefix from a given float value. For example, a value 1.3e8 will be converted into (130, "M") that can be used to display a value in the user friendly format, such as 130 MHz.

• The values "gate_error" and "balanced" are now available for the objective option in the construction of the BIPMapping object, and "balanced" is now the default.

The "gate_error" objective requires passing a BackendProperties instance in the backend_prop kwarg, which contains the 2q-gate gate errors used in the computation of the objectives. The "balanced" objective will use the BackendProperties instance if it is given, but otherwise will assume a CX error rate as given in the new parameter default_cx_error_rate. The relative weights of the gate-error and depth components of the balanced objective can be controlled with the new depth_obj_weight parameter.

• Every attribute of the VQE class that is set at the initialization is now accessible with getters and setters. Further, the default values of the VQE attributes ansatz and optimizer can be reset by assigning None to them:

vqe = VQE(my_ansatz, my_optimizer)
vqe.ansatz = None   # reset to default: RealAmplitudes ansatz
vqe.optimizer = None  # reset to default: SLSQP optimizer

• Added a new coupling-map constructor method CouplingMap.from_hexagonal_lattice() for constructing a hexagonal lattice coupling map. For example, to construct a 2x2 hexagonal lattice coupling map:

from qiskit.transpiler import CouplingMap
cmap = CouplingMap.from_hexagonal_lattice(2, 2)
cmap.draw()

• New fake backend classes are available under qiskit.test.mock. These include mocked versions of ibmq_brooklyn, ibmq_manila, ibmq_jakarta, and ibmq_lagos. As with the other fake backends, these include snapshots of calibration data (i.e. backend.defaults()) and error data (i.e. backend.properties()) taken from the real system, and can be used for local testing, compilation and simulation.

• Added a new constructor method PassManagerConfig.from_backend(). It constructs a PassManagerConfig object with user options and the configuration of a backend. With this feature, a preset passmanager can be built easier. For example:

from qiskit.transpiler.passmanager_config import PassManagerConfig
from qiskit.transpiler.preset_passmanagers import level_1_pass_manager
from qiskit.test.mock import FakeMelbourne

pass_manager = level_1_pass_manager(
PassManagerConfig.from_backend(FakeMelbourne(), seed_transpiler=42)
)

• A new transpiler pass, PulseGates, was added, which automatically extracts user-provided calibrations from the instruction schedule map and attaches the gate schedule to the given (transpiled) quantum circuit as a pulse gate.

The PulseGates transpiler pass is applied to all optimization levels from 0 to 3. No gate implementation is updated unless the end-user explicitly overrides the backend.defaults().instruction_schedule_map. This pass saves users from individually calling QuantumCircuit.add_calibration() for every circuit run on the hardware.

To supplement this new pass, a schedule was added to InstructionScheduleMap and is implicitly updated with a metadata field "publisher". Backend-calibrated gate schedules have a special publisher kind to avoid overriding circuits with calibrations of already known schedules. Usually, end-users don't need to take care of this metadata as it is applied automatically. You can call InstructionScheduleMap.has_custom_gate() to check if the map has custom gate calibration.

See the below code example to learn how to apply custom gate implementation for all circuits under execution.

from qiskit.test.mock import FakeGuadalupe
from qiskit import pulse, circuit, transpile

with pulse.build(backend, name="x") as x_q0:
pulse.play(pulse.Constant(160, 0.1), pulse.drive_channel(0))

circs = []
for _ in range(100):
circ = circuit.QuantumCircuit(1)
circ.sx(0)
circ.rz(1.57, 0)
circ.x(0)
circ.measure_active()
circs.append(circ)

circs = transpile(circs, backend)
circs[0].calibrations  # This returns calibration only for x gate


Note that the instruction schedule map is a mutable object. If you override one of the entries and use that backend for other experiments, you may accidentally update the gate definition.

backend = FakeGuadalupe()

instmap = backend.defaults().instruction_schedule_map

qc = QuantumCircuit(1, 1)
qc.x(0)
qc.measure(0, 0)

qc = transpile(qc, backend)  # This backend uses custom X gate


If you want to update the gate definitions of a specific experiment, you need to first deepcopy the instruction schedule map and directly pass it to the transpiler.

• Introduced a new option qubit_subset to the constructor of BIPMapping. The option enables us to specify physical qubits to be used (in coupling_map of the device) during the mapping in one line:

mapped_circ = BIPMapping(
coupling_map=CouplingMap([[0, 1], [1, 2], [1, 3], [3, 4]]),
qubit_subset=[1, 3, 4]
)(circ)


Previously, to do the same thing, we had to supply a reduced coupling_map which contains only the qubits to be used, embed the resulting circuit onto the original coupling_map and update the QuantumCircuit._layout accordingly:

reduced_coupling = coupling_map.reduce(qubit_to_use)
mapped = BIPMapping(reduced_coupling)(circ)
# skip the definition of fill_with_ancilla()
# recover circuit on original coupling map
layout = Layout({q: qubit_to_use[i] for i, q in enumerate(mapped.qubits)})
for reg in mapped.qregs:
property_set = {"layout": fill_with_ancilla(layout)}
recovered = ApplyLayout()(mapped, property_set)
# recover layout
overall_layout = Layout({v: qubit_to_use[q] for v, q in mapped._layout.get_virtual_bits().items()})
for reg in mapped.qregs:
recovered._layout = fill_with_ancilla(overall_layout)

• Added the ignore_pauli_phase and copy arguments to the constructor of SparsePauliOp. ignore_pauli_phase prevents the phase attribute of an input PauliList from being read, which is more performant if the PauliList is already known to have all phases as zero in the internal ZX convention. copy allows users to avoid the copy of the input data when they explicitly set copy=False.

• Added the SparsePauliOp.sum() method to add together many SparsePauliOps. This method has significantly better performance than adding the instances together in a loop. For example, the previous way to add several SparsePauliOps together would be to do:

from qiskit.quantum_info import SparsePauliOp, random_pauli_list
sparse_ops = [SparsePauliOp(random_pauli_list(10, 10)) for _ in [None]*1000]

total = sparse_ops[0]
for op in sparse_ops[1:]:
total += op


This can now be done far more efficiently (in both speed and typing!) as:

SparsePauliOp.sum(sparse_ops)

• Using QuantumCircuit.draw() or circuit_drawer() with the latex drawer will now generate a file in an image format inferred from the filename extension, for example:

import qiskit

circuit = qiskit.QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.draw('latex', filename='./file.jpg')


This will save the circuit drawing in the JPEG format. Previously, the image always be in PNG format. Refer to #6448 for more details.

Now, if it encounters a filename extension which is not supported, for example:

circuit.draw('latex', filename='./file.spooky')


it will raise a ValueError to change the filename extension to a supported image format.

• Introduced an approximate quantum compiler and a corresponding unitary synthesis plugin implementation. The main AQC class is AQC for a standalone version that compiles a unitary matrix into an approximate circuit. The plugin may be invoked by transpile() when the unitary_synthesis_method argument is set to 'aqc'. See qiskit.transpiler.synthesis.aqc for full details.

• Added a filter_function argument to QuantumCircuit.depth() and QuantumCircuit.size() in order to analyze circuit operations according to some criteria.

For example, to get the number of two-qubit gates, you can do:

circuit.size(lambda x: x[0].num_qubits == 2)


Or to get the depth of T gates acting on the zeroth qubit:

circuit.depth(lambda x: x[0].name == 't' and circuit.qubits[0] in x[1])

• Introduced a new transpiler pass InverseCancellation that generalizes the CXCancellation pass to cancel any self-inverse gates or gate-inverse pairs. It can be used by initializing InverseCancellation and passing a gate to cancel, for example:

from qiskit.transpiler.passes import InverseCancellation
from qiskit import QuantumCircuit
from qiskit.circuit.library import HGate
from qiskit.transpiler import PassManager

qc = QuantumCircuit(2, 2)
qc.h(0)
qc.h(0)
pass_ = InverseCancellation([HGate()])
pm = PassManager(pass_)
new_circ = pm.run(qc)

• The Statevectors of states comprised only of qubits can now be drawn in LaTeX in ket notation. In ket notation the entries of the statevector are processed such that exact factors like fractions or square roots of two are drawn as such. The particular convention can be chosen by passing the convention keyword argument as either "ket" or "vector" as appropriate:

import math
from qiskit.quantum_info import Statevector

sv = Statevector([math.sqrt(0.5), 0, 0, -math.sqrt(0.5)])
sv.draw("latex", convention="ket")
sv.draw("latex", convention="vector")

• Added a new transpiler pass EchoRZXWeylDecomposition that allows users to decompose an arbitrary two-qubit gate in terms of echoed RZX-gates by leveraging Cartan's decomposition. In combination with other transpiler passes, this can be used to transpile arbitrary circuits to RZX-gate-based and pulse-efficient circuits that implement the same unitary.

• The SPSA and QNSPSA optimizer classes are now capable of batching as many circuit evaluations as possible for both the iterations and the initial calibrations. This can be leveraged by setting the max_evals_grouped kwarg on the constructor for VQE when using either SPSA or QNSPSA as the optimizer parameter. For example:

from qiskit.circuit.library import TwoLocal
from qiskit.algorithms import VQE
from qiskit.algorithms.optimizers import QNSPSA
from qiskit.test.mock import FakeMontreal

backend = FakeMontreal()
ansatz = TwoLocal(2, rotation_blocks=["ry", "rz"], entanglement_blocks="cz")
qnspsa = QNSPSA(fidelity, maxiter=5)
vqe = VQE(
ansatz=ansatz,
optimizer=qnspsa,
max_evals_grouped=100,
quantum_instance=backend,
)

• This release introduces a decomposition method for two-qubit gates which targets user-defined sets of RZX gates. Transpiler users can enable decomposition for {RZX(pi/2), RZX(pi/4), and RZX(pi/6)} specifically by including 'rzx' in their basis_gates list when calling transpile(). Quantum information package users can find the method itself under the XXDecomposer class.

• Added a max_job_tries parameter to QuantumInstance, to limit the number of times a job will attempt to be executed on a backend. Previously the submission and fetching of results would be attempted infinitely, even if the job was cancelled or errored on the backend. The default is now 50, and the previous behaviour can be achieved by setting max_job_tries=-1. Fixes #6872 and #6821.

• The latex output method for the circuit_drawer() function and the QuantumCircuit.draw() method can now draw circuits that contain gates with single bit condition. This was added for compatibility of latex drawer with the new feature of supporting classical conditioning of gates on single classical bits.

• The "mpl" output method for the circuit_drawer() function and the QuantumCircuit.draw() method can now draw circuits that contain gates with single bit condition. This was added for compatibility of the "mpl" drawer with the new feature of supporting classical conditioning of gates on single classical bits.

• The text output method for the circuit_drawer() function and the QuantumCircuit.draw() method can now draw circuits that contain gates with single bit condition. This was added for compatibility of text drawer with the new feature of supporting classical conditioning of gates on single classical bits.

• A new analysis transpiler pass, GatesInBasis, was added to qiskit.transpiler.passes. This pass is used to check if the DAGCircuit being transpiled has all the gates in the configured basis set or not. It will set the attribute "all_gates_in_basis" in the property set to True if all the gates in the DAGCircuit are in the configured basis set or False if they are not. For example:

from qiskit.circuit import QuantumCircuit
from qiskit.transpiler.passes import GatesInBasis

# Instatiate Pass
basis_gates = ["cx", "h"]
basis_check_pass = GatesInBasis(basis_gates)
# Build circuit
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()
# Run pass on circuit
property_set = {}
basis_check_pass(circuit, property_set=property_set)
assert property_set["all_gates_in_basis"]

• The HHL algorithm can now find solutions when its matrix has negative eigenvalues. To enable this, the algorithm now adds an extra qubit to represent the sign of the value, and the helper algorithm ExactReciprocal was updated to process this new information. See #6971 for more details.

• Added a new parameter, add_bits, to QuantumCircuit.measure_all(). By default it is set to True to maintain the previous behaviour of adding a new ClassicalRegister of the same size as the number of qubits to store the measurements. If set to False, the measurements will be stored in the already existing classical bits. For example, if you created a circuit with existing classical bits like:

from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister

qr = QuantumRegister(2)
cr = ClassicalRegister(2, "meas")
circuit = QuantumCircuit(qr, cr)


calling circuit.measure_all(add_bits=False) will use the existing classical register cr as the output target of the Measurement objects added to the circuit.

• ParameterExpression now delegates its numeric conversions to the underlying symbolic library, even if there are potentially unbound parameters. This allows conversions of expressions such as:

>>> from qiskit.circuit import Parameter
>>> x = Parameter('x')
>>> float(x - x + 2.3)
2.3


where the underlying expression has a fixed value, but the parameter x is not yet bound.

• Added an Optimizer.minimize() method to all optimizers: Optimizer and derived classes. This method mimics the signature of SciPy's minimize() function and returns an OptimizerResult.

For example

import numpy as np
from qiskit.algorithms.optimizers import COBYLA

def loss(x):
return -(x[0] - 1) ** 2 - (x[1] + 1) ** 3

initial_point = np.array([0, 0])
optimizer = COBYLA()
result = optimizer.minimize(loss, initial_point)

optimal_parameters = result.x
minimum_value = result.fun
num_function_evals = result.nfev

• Added a PauliEvolutionGate to the circuit library (qiskit.circuit.library) which defines a gate performing time evolution of (sums or sums-of-sums of) Paulis. The synthesis of this gate is performed by EvolutionSynthesis and is decoupled from the gate itself. Currently available synthesis methods are:

For example:

from qiskit.circuit import QuantumCircuit
from qiskit.circuit.library import PauliEvolutionGate
from qiskit.quantum_info import SparsePauliOp
from qiskit.synthesis import SuzukiTrotter

operator = SparsePauliOp.from_list([
("XIZ", 0.5), ("ZZX", 0.5), ("IYY", -1)
])
time = 0.12  # evolution time
synth = SuzukiTrotter(order=4, reps=2)

evo = PauliEvolutionGate(operator, time=time, synthesis=synth)

circuit = QuantumCircuit(3)
circuit.append(evo, range(3))

• A new function plot_coupling_map() has been introduced, which extends the functionality of the existing function plot_gate_map(), by accepting three parameters: num_qubit, qubit_coordinates, and coupling_map (instead of backend), to allow an arbitrary qubit coupling map to be plotted.

• Qiskit Terra now has initial support for serializing QuantumCircuits to OpenQASM 3:

from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit import qasm3

qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)

print(qasm3.dumps(qc))

OPENQASM 3;
include "stdgates.inc";
qubit[2] _all_qubits;
let q = _all_qubits[0:1];
h q[0];
cx q[0], q[1];



This initial release has limited support for named registers, basic built-in instructions (such as measure, barrier and reset), user-defined gates, user-defined instructions (as subroutines), and the new control-flow constructs also introduced in this release:

from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit import qasm3
import math

composite_circ_qreg = QuantumRegister(2)
composite_circ = QuantumCircuit(composite_circ_qreg, name="composite_circ")
composite_circ.h(0)
composite_circ.x(1)
composite_circ.cx(0, 1)
composite_circ_gate = composite_circ.to_gate()

qr = QuantumRegister(2, "qr")
cr = ClassicalRegister(2, "cr")
qc = QuantumCircuit(qr, cr)
with qc.for_loop(range(4)) as i:
qc.rx(i * math.pi / 4, 0)
qc.cx(0, 1)
qc.barrier()
qc.append(composite_circ_gate, [0, 1])
qc.measure([0, 1], [0, 1])

print(qasm3.dumps(qc))

OPENQASM 3;
include "stdgates.inc";
gate composite_circ _gate_q_0, _gate_q_1 {
h _gate_q_0;
x _gate_q_1;
cx _gate_q_0, _gate_q_1;
}
bit[2] cr;
qubit[2] _all_qubits;
let qr = _all_qubits[0:1];
for _loop_i_0 in [0:3] {
rx(pi/4*_loop_i_0) qr[0];
cx qr[0], qr[1];
}
barrier qr[0], qr[1];
composite_circ qr[0], qr[1];
cr[0] = measure qr[0];
cr[1] = measure qr[1];


• The QDrift class was reformulated as a synthesis method for PauliEvolutionGate, deriving from TrotterizationBase.

from qiskit.circuit import QuantumCircuit
from qiskit.circuit.library import PauliEvolutionGate
from qiskit.synthesis import QDrift
from qiskit.opflow import X, Y, Z

qdrift = QDrift(reps=2)
operator = (X ^ 3) + (Y ^ 3) + (Z ^ 3)
time = 2.345  # evolution time

evolution_gate = PauliEvolutionGate(operator, time, synthesis=qdrift)

circuit = QuantumCircuit(3)
circuit.append(evolution_gate, range(3))

• A new find_bit() method has been added to the QuantumCircuit class, which allows lookups of the index and registers of a provided Bit on the given circuit. The method returns a two-element namedtuple containing 0) the index of the Bit in either qubits (for a Qubit) or clbits (for a Clbit) and 1) a list of length-2 tuples containing each circuit Register which contains the Bit, and the index in that Register at which the Bit can be found.

For example:

from qiskit.circuit import QuantumCircuit, QuantumRegister, Qubit

reg1 = QuantumRegister(3, 'foo')
qubit = Qubit()
reg2 = QuantumRegister(2, 'bar')

qc = QuantumCircuit(reg1, [qubit], reg2)

print(qc.find_bit(reg1[2]))
print(qc.find_bit(qubit))


would generate:

BitLocations(index=2, registers=[(QuantumRegister(3, 'foo'), 2)])
BitLocations(index=3, registers=[])

• Added the LocalReadoutMitigator class for performing measurement readout error mitigation of local measurement errors. Local measuerment errors are those that are described by a tensor-product of single-qubit measurement errors.

This class can be initialized with a list of $$N$$ single-qubit of measurement error assignment matrices or from a backend using the readout error information in the backend properties.

Mitigation is implemented using local assignment-matrix inversion which has complexity of $$O(2^N)$$ for $$N$$-qubit mitigation of QuasiDistribution and expectation values.

• Added the CorrelatedReadoutMitigator class for performing measurement readout error mitigation of correlated measurement errors. This class can be initialized with a single $$2^N \times 2^N$$ measurement error assignment matrix that descirbes the error probabilities. Mitigation is implemented via inversion of assigment matrix which has mitigation complexity of $$O(4^N)$$ of QuasiDistribution and expectation values.

• When running the Grover algorithm class if the optimal power is known and only a single circuit is run, the AmplificationProblem.is_good_state callback function is no longer required to be set and the Grover search will return the most likely bitstring. Generally, if the optimal power of the Grover operator is not known, the Grover algorithm checks different powers (i.e. iterations) and applies the is_good_state function to check whether a good bitstring has been measured. For example, you are now able to run something like:

from qiskit.algorithms import Grover, AmplificationProblem
from qiskit.providers.aer import AerSimulator
from qiskit.quantum_info import Statevector

# Fixed Grover power: 2.
grover = Grover(iterations=2, quantum_instance=AerSimulator())

# The is_good_state argument not required here since Grover search
# will be run only once, with a power of 2.
problem = AmplificationProblem(Statevector.from_label("111"))

# Run Grover search and print the best measurement
result = grover.amplify(problem)
print(result.top_measurement)  # should print 111

• Various transpilation internals now use new features in retworkx 0.10 when operating on the internal circuit representation. This can often result in speedups in calls to transpile of around 10-40%, with greater effects at higher optimization levels. See #6302 for more details.

• Allow two transpiler stages in the QuantumInstance, one for parameterized circuits and a second one for bound circuits (i.e. no free parameters) only. If a quantum instance with passes for unbound and bound circuits is passed into a CircuitSampler, the sampler will attempt to apply the unbound pass once on the parameterized circuit, cache it, and only apply the bound pass for all future evaluations.

This enables variational algorithms like the VQE to run a custom pass manager for parameterized circuits once and, additionally, another the transpiler again with a different custom pass manager on the bound circuits in each iteration. Being able to run different pass managers is important because not all passes support parameterized circuits (for example Optimize1qGatesDecomposition only works with bound circuit parameters).

For example, this feature allows using the pulse-efficient CX decomposition in the VQE, as

from qiskit.algorithms import VQE
from qiskit.opflow import Z
from qiskit.circuit.library.standard_gates.equivalence_library import StandardEquivalenceLibrary as std_eqlib
from qiskit.transpiler import PassManager, PassManagerConfig, CouplingMap
from qiskit.transpiler.preset_passmanagers import level_1_pass_manager
from qiskit.transpiler.passes import (
Collect2qBlocks, ConsolidateBlocks, Optimize1qGatesDecomposition,
RZXCalibrationBuilderNoEcho, UnrollCustomDefinitions, BasisTranslator
)
from qiskit.transpiler.passes.optimization.echo_rzx_weyl_decomposition import EchoRZXWeylDecomposition
from qiskit.test.mock import FakeBelem
from qiskit.utils import QuantumInstance

# Replace by a real backend! If not ensure qiskit-aer is installed to simulate the backend
backend = FakeBelem()

# Build the pass manager for the parameterized circuit
rzx_basis = ['rzx', 'rz', 'x', 'sx']
coupling_map = CouplingMap(backend.configuration().coupling_map)
config = PassManagerConfig(basis_gates=rzx_basis, coupling_map=coupling_map)
pre = level_1_pass_manager(config)

# Build a pass manager for the CX decomposition (works only on bound circuits)
post = PassManager([
# Consolidate consecutive two-qubit operations.
Collect2qBlocks(),
ConsolidateBlocks(basis_gates=['rz', 'sx', 'x', 'rxx']),

# Rewrite circuit in terms of Weyl-decomposed echoed RZX gates.
EchoRZXWeylDecomposition(backend),

# Attach scaled CR pulse schedules to the RZX gates.
RZXCalibrationBuilderNoEcho(backend),

# Simplify single-qubit gates.
UnrollCustomDefinitions(std_eqlib, rzx_basis),
BasisTranslator(std_eqlib, rzx_basis),
Optimize1qGatesDecomposition(rzx_basis),
])

quantum_instance = QuantumInstance(backend, pass_manager=pre, bound_pass_manager=post)

vqe = VQE(quantum_instance=quantum_instance)
result = vqe.compute_minimum_eigenvalue(Z ^ Z)

• Introduced a new unitary synthesis plugin interface which is used to enable using alternative synthesis techniques included in external packages seamlessly with the UnitarySynthesis transpiler pass. Users can select a plugin to use when calling transpile() by setting the unitary_synthesis_method kwarg to the plugin's name. A full list of installed plugins can be found using the qiskit.transpiler.passes.synthesis.plugin.unitary_synthesis_plugin_names() function. For example, if you installed a package that includes a synthesis plugin named special_synth you could use it with:

from qiskit import transpile

transpile(qc, unitary_synthesis_method='special_synth', optimization_level=3)


This will replace all uses of the UnitarySynthesis with the method included in the external package that exports the special_synth plugin.

The plugin interface is built around setuptools entry points which enable packages external to Qiskit to advertise they include a synthesis plugin. For details on writing a new plugin refer to the qiskit.transpiler.passes.synthesis.plugin module documentation.

##### Known Issues¶
• The "ket" convention in the "latex" drawer of Statevector.draw() is only valid for states comprising purely of qubits. If you are using states with some spaces of dimension greater than two, you should either pass convention="vector", or use a different drawer.

• The OpenQASM 3 export capabilities are in a beta state, and some features of Qiskit Terra's QuantumCircuit are not yet supported. In particular, you may see errors if you try to export custom subroutines with classical parameters, and there is no provision yet for exporting pulse-calibrated operations into OpenPulse.

• When running the BasisTranslator in isolation with the target argument set to a Target object, where some single-qubit gates can only apply to non-overlapping sets of qubits, the output circuit might incorrectly include operations on a qubit that are not allowed by the Target. For example, if you ran:

from qiskit.circuit import QuantumCircuit, Parameter
from qiskit.circuit.library import UGate, RZGate, XGate, SXGate, CXGate
from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary as sel

from qiskit.transpiler import PassManager, Target, InstructionProperties
from qiskit.transpiler.passes import BasisTranslator

gmap = Target()

# U gate in qubit 0.
theta = Parameter('theta')
phi = Parameter('phi')
lam = Parameter('lambda')
u_props = {
(0,): InstructionProperties(duration=5.23e-8, error=0.00038115),
}

# Rz gate in qubit 1.
phi = Parameter("phi")
rz_props = {
(1,): InstructionProperties(duration=0.0, error=0),
}

# X gate in qubit 1.
x_props = {
(1,): InstructionProperties(
duration=3.5555555555555554e-08, error=0.00020056469709026198
),
}

# SX gate in qubit 1.
sx_props = {
(1,): InstructionProperties(
duration=3.5555555555555554e-08, error=0.00020056469709026198
),
}

cx_props = {
(0, 1): InstructionProperties(duration=5.23e-7, error=0.00098115),
(1, 0): InstructionProperties(duration=4.52e-7, error=0.00132115),
}

bt_pass = BasisTranslator(sel, target_basis=None, target=gmap)

qc = QuantumCircuit(2)
qc.iswap(0, 1)
output = bt_pass(qc)


output will have RZGate and SXGate on qubit 0, even though this is forbidden. To correct this you can normally run the basis translator a second time (i.e. output = bt_pass(output) in the above example) to correct this. This should not affect the output of running the transpile() function and is only an issue if you run the pass by itself.

• Starting with this version, from qiskit import * will not import submodules, but only a selected list of objects. This might break existing code using from qiskit import * and referring to objects that are not part of the current namespace. As a reminder, import * is considered bad practice and it should not be used in production code. Qiskit sets __all__ in qiskit/__init__.py as a way to mitigate the effects of said bad practice. If your code raises name '<something>' is not defined, add from qiskit import <something> and try again.

• The default method for BIPMapping is now balanced rather than depth. This new objective generally achieves a better result, as it factors in both the circuit depth and the gate error.

• The sort_parameters_by_name of the VQE class has been removed, following its deprecation in Qiskit Terra 0.18. There is no alternative provided, as the new ordering of parameters is the more natural sort order.

• The circuit drawers QuantumCircuit.draw() and circuit_drawer() with the latex option will now save their images in a format determined the file extension (if a file name is provided). Previously, they would always save in PNG format. They now raise ValueError if the image format is not known. This was done to make it easier to save the image in different formats.

• The core dependency retworkx had its version requirement bumped to 0.10.1, up from 0.9. This enables several performance improvements across different transpilation passes.

• The DAGCircuit.extend_back() method has been removed. It was originally deprecated in the 0.13.0 release. Instead you can use the DAGCircuit.compose() method which is more general and provides the same functionality.

• The DAGCircuit.compose_back() method has been removed. It was originally deprecated in the 0.13.0 release. Instead you can use the DAGCircuit.compose() method which is more general and provides the same functionality.

• The edge_map kwarg of the DAGCircuit method compose() has been removed. It was originally deprecated in the 0.14.0 release. The method takes a qubits and clbits kwargs to specify the positional order of bits to compose onto instead of using a dictionary mapping that edge_map previously provided.

• Named access for the first positional argument for the constructor of the SingleQubitUnitary class with u has been removed. It was originally deprecated in the 0.14.0 release. Instead, the first positional argument can be set using the name unitary_matrix (or just set it positionally instead of by name).

• Named access for the first positional argument for the QuantumCircuit method squ with u has been removed. It was originally deprecated in the 0.14.0 release. Instead the first positional argument can be set using the name unitary_matrix (or just set it positionally instead of by name).

• The unused proc and nested_scope kwargs for the qasm() method of the QASM node classes in the qiskit.qasm.node module have been removed. They were originally deprecated in the 0.15.0 release.

• The unused proc and nested_scope kwargs for the latex() method of the QASM node classes in the qiskit.qasm.node module have been removed. They were originally deprecated in the 0.15.0 release.

• The unused proc and nested_scope kwargs for the real() method of the QASM node classes in the qiskit.qasm.node module have been removed. They were originally deprecated in the 0.15.0 release.

• The output of Statevector.draw() when using "latex" output is now the new "ket" convention if plotting a state comprised purely of qubits. This was changed to make reading the output clearer, especially in educational contexts, because it shows the ket labels, and only displays the nonzero elements.

• When running execute() with a BackendV1 backend the default values for the kwargs shots, max_credits, meas_level, meas_return and memory_slot_size will now be whatever the set default is on the target backend's options attribute. Previously these defaults were set to match the default values when calling execute() with a legacy BaseBackend backend. For example:

from qiskit.test.mock import FakeMumbai
from qiskit import QuantumCircuit, execute

circuit = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
qc.measure_all()

backend = FakeMumbai()
backend.set_options(shots=4096)
execute(qc, backend)


will now run with 4096 shots. While in previous releases it would run with 1024.

• The minimum supported version of Matplotlib has been raised from 2.1.0 to 3.3.0. You will now need to have Matplotlib 3.3.0 installed if you're using Matplotlib-based visualization functions such as the 'mpl' backend for the circuit_drawer() function or the plot_bloch_vector() function. This was done for two reasons, the first is because recent versions of Matplotlib have deprecated the use of APIs around 3D visualizations that were compatible with older releases and second installing older versions of Matplotlib was becoming increasingly difficult as matplotlib's upstream dependencies have caused incompatiblities that made testing moving forward more difficult.

• The internal use of the random number generator in random_circuit() was adjusted, which will change the output from previous versions, even with a fixed seed. This was done to greatly improve the runtime scaling with the number of qubits being used. If you were depending on an identical output from a previous version it is recommended that you use qpy_serialization.dump() to save the random circuit generated with a previous version and instead of re-generating it with the new release, and instead just use qpy_serialization.load() to load that saved circuit.

• The use of * (__mul__) for the dot() method and @ (__matmul__) for the compose() method of BaseOperator (which is the parent of all the operator classes in qiskit.quantum_info including classes like Operator and Pauli) is no longer supported. The use of these operators were previously deprecated in 0.17.0 release. Instead you should use the dot() and compose() methods directly, or the & operator (__and__) can be used for compose(). For example, if you were previously using the operator like:

from qiskit.quantum_info import random_hermitian

op_a = random_hermitian(4)
op_b = random_hermitian(4)

new_op = op_a @ op_b


this should be changed to be:

from qiskit.quantum_info import random_hermitian

op_a = random_hermitian(4)
op_b = random_hermitian(4)
new_op = op_a.compose(op_b)


or:

new_op = op_a & op_b

• Various methods of assigning parameters to operands of pulse program instructions have been removed, having been deprecated in Qiskit Terra 0.17. These include:

These parameters should be assigned from the pulse program (pulse.Schedule and pulse.ScheduleBlock) rather than operands of the pulse program instruction.

• The flatten() method of pulse.Instruction and qiskit.pulse.Schedule has been removed and no longer exists as per the deprecation notice from Qiskit Terra 0.17. This transformation is defined as a standalone function in qiskit.pulse.transforms.canonicalization.flatten().

• qiskit.pulse.interfaces.ScheduleComponent has been removed and no longer exists as per the deprecation notice from Qiskit Terra 0.15. No alternative class will be provided.

• Legacy pulse drawer arguments have been removed from pulse.Waveform.draw(), Schedule.draw() and ScheduleBlock.draw() and no longer exist as per the deprecation notice from Qiskit Terra 0.16. Now these draw methods support only V2 pulse drawer arguments. See method documentations for details.

• The qiskit.pulse.reschedule module has been removed and this import path no longer exist as per the deprecation notice from Qiskit Terra 0.14. Use qiskit.pulse.transforms instead.

• A protected method Schedule._children() has been removed and replaced by a protected instance variable as per the deprecation notice from Qiskit Terra 0.17. This is now provided as a public attribute Schedule.children.

• Timeslot relevant methods and properties have been removed and no longer exist in ScheduleBlock as per the deprecation notice from Qiskit Terra 0.17. Since this representation doesn't have notion of instruction time t0, the timeslot information will be available after it is transformed to a Schedule. Corresponding attributes have been provided after this conversion, but they are no longer supported. The following attributes are removed:

• timeslots

• start_time

• stop_time

• ch_start_time

• ch_stop_time

• shift

• insert

• Alignment pulse schedule transforms have been removed and no longer exist as per the deprecation notice from Qiskit Terra 0.17. These transforms are integrated and implemented in the AlignmentKind context of the schedule block. The following explicit transform functions are removed:

• qiskit.pulse.transforms.align_equispaced

• qiskit.pulse.transforms.align_func

• qiskit.pulse.transforms.align_left

• qiskit.pulse.transforms.align_right

• qiskit.pulse.transforms.align_sequential

• Redundant pulse builder commands have been removed and no longer exist as per the deprecation notice from Qiskit Terra 0.17. pulse.builder.call_schedule and pulse.builder.call_circuit have been integrated into pulse.builder.call().

• An internal filter override that caused all Qiskit deprecation warnings to be displayed has been removed. This means that the behaviour will now revert to the standard Python behaviour for deprecations; you should only see a DeprecationWarning if it was triggered by code in the main script file, interpreter session or Jupyter notebook. The user will no longer be blamed with a warning if internal Qiskit functions call deprecated behaviour. If you write libraries, you should occasionally run with the default warning filters disabled, or have tests which always run with them disabled. See the Python documentation on warnings, and in particular the section on testing for deprecations for more information on how to do this.

• Certain warnings used to be only issued once, even if triggered from multiple places. This behaviour has been removed, so it is possible that if you call deprecated functions, you may see more warnings than you did before. You should change any deprecated function calls to the suggested versions, because the deprecated forms will be removed in future Qiskit releases.

• The deprecated qiskit.schemas module and the qiskit.validation module which build jsonschema validator from the schemas have been removed. This was deprecated in the 0.17.0 release and has been replaced with a dedicated repository for the IBM Quantum API payload schemas.

If you were relying on the schema files previously packaged in qiskit.schemas or the validators built on them you should use that repository and create validators from the schema files it contains.

• The fastjsonschema and jsonschema packages are no longer in the requirements list for qiskit-terra. The internal use of jsonschema has been removed and they are no longer required to use qiskit-terra.

• The exception raised by the assemble() function when invalid parameters are passed in for constructing a PulseQobj have changed from a SchemaValidationError to a QiskitError. This was necessary because the SchemaValidationError class was removed along with the rest of the deprecated qiskit.schemas and qiskit.validation. This also makes it more consistent with other error conditions from assemble() which were already raising a QiskitError.

• The default routing pass and layout pass for transpiler optimization level 3 has changed to use SabreSwap and SabreLayout respectively. This was done to improve the quality of the output result, as using the sabre passes produces better results than using StochasticSwap and DenseLayout, which were used as the defaults in prior releases. This change will improve the quality of the results when running transpile() or execute() functions with the optimization_level kwarg set to 3. While this is generally an improvement, if you need to retain the previous behavior for any reason you can do this by explicitly setting the routing_method="stochastic" and layout_method="dense" when calling transpile() with optimization_level=3.

• The name attribute of the SingleQubitUnitary gate class has been changed from unitary to squ. This was necessary to avoid a conflict with the UnitaryGate class's name which was also unitary since the 2 gates are not the same and don't have the same implementation (and can't be used interchangeably).

• A new dependency stevedore has been added to the requirements list. This is required by qiskit-terra as it is used to build the unitary synthesis plugin interface.

##### Deprecation Notes¶
• The gate attribute and initialization parameter of qiskit.transpiler.passes.Decompose is deprecated, and will be removed in a future release. Instead of this single gate, you should pass a list of gate names to the new parameter gates_to_decompose. This was done as the new form allows you to select more than one gate as a decomposition target, which is more flexible, and does not need to re-run the pass several times to decompose a set of gates.

• There has been a significant transpiler pass reorganization regarding calibrations. The import paths:

from qiskit.transpiler.passes.scheduling.calibration_creators import RZXCalibrationBuilder
from qiskit.transpiler.passes.scheduling.calibration_creators import RZXCalibrationBuilderNoEcho


are deprecated, and will be removed in a future release. The import path:

from qiskit.transpiler.passes.scheduling.rzx_templates import rzx_templates


is also deprecated, and will be removed in a future release. You should use the new import paths:

from qiskit.transpiler.passes import RZXCalibrationBuilder
from qiskit.transpiler.passes import RZXCalibrationBuilderNoEcho
from qiskit.transpiler.passes.calibration.rzx_templates import rzx_templates

• For the constructor of the RZXCalibrationBuilder passing a backend either as the first positional argument or with the named backend kwarg is deprecated and will no longer work in a future release. Instead a InstructionScheduleMap should be passed directly to the instruction_schedule_map kwarg and a list of channel name lists for each qubit should be passed directly to qubit_channel_mapping. For example, if you were calling the pass like:

from qiskit.transpiler.passes import RZXCalibrationBuilder
from qiskit.test.mock import FakeMumbai

backend = FakeMumbai()
cal_pass = RZXCalibrationBuilder(backend)


instead you should call it like:

from qiskit.transpiler.passes import RZXCalibrationBuilder
from qiskit.test.mock import FakeMumbai

backend = FakeMumbai()
inst_map = backend.defaults().instruction_schedule_map
channel_map = self.backend.configuration().qubit_channel_mapping
cal_pass = RZXCalibrationBuilder(
instruction_schedule_map=inst_map,
qubit_channel_mapping=channel_map,
)


This change is necessary because as a general rule backend objects are not pickle serializable and it would break when it was used with multiple processes inside of transpile() when compiling multiple circuits at once.

• The label property of class MCMT and subclass MCMTVChain has been deprecated and will be removed in a future release. Consequently, the label kwarg on the constructor for both classes is also deprecated, along with the label kwarg of method MCMT.control(). Currently, the label property is used to name the controlled target when it is comprised of more than one target qubit, however, this was never intended to be user-specifiable, and can result in an incorrect MCMT gate if the name of a well-known operation is used. After deprecation, the label property will no longer be user-specifiable. However, you can get the generated name of the controlled target via

MCMT.data[0][0].base_gate.name

• Creating an instance of InstructionSet with the circuit_cregs keyword argument is deprecated. In general, these classes never need to be constructed by users (but are used internally), but should you need to, you should pass a callable as the resource_requester keyword argument. For example:

from qiskit.circuit import Clbit, ClassicalRegister, InstructionSet
from qiskit.circuit.exceptions import CircuitError

def my_requester(bits, registers):
bits_set = set(bits)
bits_flat = tuple(bits)
registers_set = set(registers)

def requester(specifier):
if isinstance(specifer, Clbit) and specifier in bits_set:
return specifier
if isinstance(specifer, ClassicalRegster) and specifier in register_set:
return specifier
if isinstance(specifier, int) and 0 <= specifier < len(bits_flat):
return bits_flat[specifier]
raise CircuitError(f"Unknown resource: {specifier}")

return requester

my_bits = [Clbit() for _ in [None]*5]
my_registers = [ClassicalRegister(n) for n in range(3)]

InstructionSet(resource_requester=my_requester(my_bits, my_registers))

• The Optimizer.optimize() method for all the optimizers (Optimizer and derived classes) is now deprecated and will be removed in a future release. Instead, the Optimizer.minimize() method should be used which mimics the signature of SciPy's minimize() function.

To replace the current optimize call with minimize you can replace

xopt, fopt, nfev = optimizer.optimize(
num_vars,
objective_function,
variable_bounds,
initial_point,
)


with

result = optimizer.minimize(
fun=objective_function,
x0=initial_point,
bounds=variable_bounds,
)
xopt, fopt, nfev = result.x, result.fun, result.nfev

• Importing the qiskit.util module will now issue a DeprecationWarning. Users should instead import all the same functionality from qiskit.utils. The util module has been deprecated since Terra 0.17, but previously did not issue a warning. It will be removed in Terra 0.20.

##### Bug Fixes¶
• Fixed a bug where many layout methods would ignore 3-or-more qubit gates, resulting in unexpected layout-allocation decisions. The transpiler pass Unroll3qOrMore is now being executed before the layout pass in all the preset pass managers when transpile() is called. Fixed #7156.

• Fixed setting the ansatz or optimizer attributes of a VQE instance to None resulting in a buggy behavior. See #7093 for details.

• Fixed addition of PauliLists with qargs. The method used to raise a runtime error if the operands had different numbers of qubits.

• Fixed an issue causing an error when trying to compute a gradient with the CircuitGradient class for a gate that was not a supported gate. This bugfix transpiles a given gate to the set of supported gates for a requested gradient method. Fixes #6918.

• Fixed an issue where the ax kwarg and the figwidth option in the style kwarg for the mpl circuit drawer did not scale properly. Users can now pass an ax from a Matplotlib subplot to the mpl circuit drawer and the circuit will be drawn within the boundaries of that subplot. Alternatively, users can set the figwidth in inches in the style dict kwarg and the drawing will scale to the width in inches that was set. Fixed #6367.

• Fixed an issue with the circuit_drawer() function and draw() method of QuantumCircuit. With any of the 3 drawer options, mpl, latex, or text, if a gate with a classical condition was conditioned on the same classical bit as a measure and the bit that the measure targeted did not have a register, the drawer would fail.

• C3SXGate now has a correct decomposition and matrix representation. Previously it was equivalent to SdgXGate().control(3), rather than the intended SXGate().control(3).

• The member name of qiskit.test.mock.utils.ConfigurableFakeBackend has been changed to backend_name. This was done to avoid a conflict with the name() method inherited from the parent abstract BackendV1 class. This makes ConfigurableFakeBackend compatible with anything expecting a BackendV1 object. However, if you were using the name attribute directly before you will now need to either call it as a method or access the backend_name attribute instead.

• Fixed an issue where calling QuantumCircuit.decompose() on a circuit containing an Instruction whose definition attribute was empty would leave the instruction in place, instead of decomposing it into zero operations. For example, with a circuit:

from qiskit.circuit import QuantumCircuit
empty = QuantumCircuit(1, name="decompose me!")
circuit = QuantumCircuit(1)
circuit.append(empty.to_gate(), [0])


Previously, calling circuit.decompose() would not change the circuit. Now, the decomposition will correct decompose empty into zero instructions. See #6997 for more.

• Fixed an issue with the circuit_drawer() function and draw() method of QuantumCircuit. When displaying a measure instruction containing a classical condition using the mpl or latex options, the condition information would sometimes overwrite the measure display.

• Fixed a bug in the Hoare optimizer transpilation pass where it could attempt to remove a gate twice if it could be separately combined with both its predecessor and its successor to form the identity. Refer to #7271 for more details.

• Trying to make an instruction conditional with the standard InstructionSet.c_if() method will now correctly raise an error if the classical resource is not present in the circuit. See #7255 for more detail.

• Fixed a compatibility issue with Matplotlib 3.5, where the Bloch sphere would fail to render if it had any vectors attached, such as by using plot_bloch_vector. See #7272 for more detail.

• Complex valued pulse parameter assignment with symengine has been fixed. For example,

from qiskit import circuit, pulse
import numpy as np

amp = circuit.Parameter("amp")
phase = circuit.Parameter("phase")

with pulse.build() as sched:
pulse.play(pulse.Gaussian(160, amp * np.exp(1j * phase), 40), pulse.DriveChannel(0))
sched.assign_parameters({amp: 0.1, phase: 1.57}, inplace=True)


The assigned amplitude has been shown as ParameterExpression(0.1*exp(1.57*I)) after the use of symengine was introduced in the 0.18.0 release. This is now correctly evaluated and shown as 7.96327e-05 + 0.0999999683j.

• Fixed an issue where QAOAAnsatz had an incorrect number of parameters if identities of PauliSumOp were given, e.g., PauliSumOp.from_list([("III", 1)]). See #7225 for more detail.

• Fixed an issue where trying to display registerless bits would cause a failure of the mpl and the latex circuit drawers. A leading _ has been removed from the display of registerless bits' numbers in the text drawer. Fixed #6732.

• For one-bit registers, all of the circuit drawers now display only the register name and no longer show the 0 subscript. Fixed #5784.

• Fixed naming collisions of implicit registers in QuantumCircuit.qasm when dealing with registerless qubits and clbits. Previously, registerless qubits and clbits were put into corresponding qreg and creg both called regless, despite the collision. They will now have separate, deterministically generated names, which will not clash with any user-defined register names in the circuit.

• Fixed an issue in scheduling of circuits with clbits operations, e.g. measurements, conditional gates, updating ASAPSchedule, ALAPSchedule, and AlignMeasures. The updated schedulers assume all clbits I/O operations take no time, measure writes the measured value to a clbit at the end, and c_if reads the conditional value in clbit(s) at the beginning. Fixed #7006.

• Fixed an issue in PiecewiseChebyshev when the function to be approximated was constant. In these cases, you should now pass the constant directly as the f_x argument, rather than using a function, such as:

from qiskit.circuit.library.arithmetic import PiecewiseChebyshev

PiecewiseChebyshev(1.0, degree=3)


See #6707 for more details.

• If an HHL algorithm instance was constructed without a QuantumInstance (the default), attempts to use the getter and setter properties to read or set an instance later would fail. The getters and setters now work as expected.

• The QuantumCircuit.qasm() method now edits the names of copies of the instructions present in the circuit, not the original instructions that live in circuit.data. Refer to #6952 for more details.

• Fixed a bug in PauliSumOp.permute() causing the error:

QiskitError: 'Pauli string label "" is not valid.'


if the permutation had the same number of Pauli terms. Calling permute([2, 1, 0]) on X ^ Y ^ Z no longer raises an error, and now returns Z ^ Y ^ X.

• Fixed multi-bit classical register removal in pass RemoveFinalMeasurements and in method remove_final_measurements() of class QuantumCircuit where classical registers were not removed even if other bits were idle, unless a final measure was done into each and every bit. Now, classical registers that become idle as a result of removing final measurements and barriers are always removed. Classical bits are removed if they are referenced only by removed registers or are not referenced at all and became idle due to the removal. This fix also adds proper handling of registers with shared underlying bits.

• When tapering an empty zero operator in qiskit.opflow, the code, on detecting it was zero, logged a warning and returned the original operator. Such operators are commonly found in the auxiliary operators, when using Qiskit Nature, and the above behavior caused VQE to throw an exception as tapered non-zero operators were a different number of qubits from the tapered zero operators (since taper has returned the input operator unchanged). The code will now correctly taper a zero operator such that the number of qubits is reduced as expected and matches to tapered non-zero operators e.g 0*"IIII" when we are tapering by 3 qubits will become 0*"I".

• Fixed an issue with the draw() method and circuit_drawer() function, where a custom style set via the user config file (i.e. settings.conf) would ignore the set value of the circuit_mpl_style field if the style kwarg on the function/method was not set.

##### Other Notes¶
• The string cast for qiskit.circuit.ParameterExpression does not have full precision anymore. This removes the trailing 0s when printing parameters that are bound to floats. This has consequences for QASM serialization and the circuit text drawer:

>>> from qiskit.circuit import Parameter
>>> x = Parameter('x')
>>> str(x.bind({x:0.5}))

• The QAOAAnsatz has been updated to use the parameter symbol γ for the cost operator and β for the mixer operator, as is the standard notation in QAOA literature.

No change

#### Ignis 0.7.0¶

##### Prelude¶

This release deprecates the Qiskit Ignis project, it has been supersceded by the Qiskit Experiments project and active development has ceased. While deprecated, critical bug fixes and compatibility fixes will continue to be made to provide users a sufficient opportunity to migrate off of Ignis. After the deprecation period (which will be no shorter than 3 months from this release) the project will be retired and archived.

##### New Features¶
• Added the option for the fast analytical generation of syndrome graphs. The RepetitionCode now has a new bool argument brute, which allows to still use the brute force method. Helper class RepetitionCodeSyndromeGenerator added to facilitate this.

• The RepetitionCode now has keyword arguments resets and delay. The former determines whether reset gates are inserted after measurement. The latter allows a time (in dt) to be specificed for a delay after each measurement (and reset, if applicable).

The syndrome_measurement() method of RepetitionCode now has keyword arguments final and delay. The former determines whether to add reset gates according to the global resets, or to overwrite it with appropriate behavior for the final round of syndrome measurements. The latter allows a time (in dt) to be specificed for a delay after each measurement (and reset, if applicable).

• The keyword argument reset has been removed from the the syndrome_measurement() method of RepetitionCode. This is replaced by the global resets keyword argument for the class as well as the keyword argument final for syndrome_measurement. In cases where one would previously add the final measurement round using reset=False to avoid the final reset gates, one should now use final=True.

• Remove ParametrizedSchedule from update_u_gates().

ParametrizedSchedule was deprecated as a part of Qiskit-terra 0.17.0 and will be removed in next release. The function now updates u gates with Schedule programs involving unassigned Parameter objects.

##### Deprecation Notes¶
• Deprecating methods in AccreditationFitter namely bound_variation_distance and single_protocol_run

• The Qiskit Ignis project as a whole has been deprecated and the project will be retired and archived in the future. While deprecated only compatibility fixes and fixes for critical bugs will be made to the proejct. Instead of using Qiskit Ignis you should migrate to use Qiskit Experiments instead. You can refer to the migration guide:

https://github.com/Qiskit/qiskit-ignis#migration-guide

### Qiskit 0.32.1¶

No change

No change

No change

No change

#### IBM Q Provider 0.18.1¶

##### Bug Fixes¶
• Fixes #209 where the websocket connection kept timing out when streaming results for a runtime job, due to inactivity, when the job is in a pending state for a long time.

### Qiskit 0.32.0¶

No change

No change

No change

No change

#### IBM Q Provider 0.18.0¶

##### Bug Fixes¶
• Fixes the issue wherein a runtime job result cannot be retrieved multiple times if the result contains a numpy array.

### Qiskit 0.31.0¶

No change

#### Aer 0.9.1¶

• optimize_ideal_threshold and optimize_noisy_threshold have been removed from the lists of simulator defaults and the documentation. These have had no effect since Aer 0.5.1, but these references to them had remained accidentally.

##### Bug Fixes¶
• Fixes #1351 where running an empty QuantumCircuit with a noise model set would cause the simulator to crash.

• Fixes #1347 where the behaviour of using the set_options() and set_option() methods of simulator backends could lead to different behavior for some options.

• Fixes an bug where using a Dask Client executor would cause an error at job submission due to the executor Client not being pickleable.

• Fixed an issue with the matrix_product_state simulation method where the accumulation of small rounding errors during measurement of many quits could sometimes cause a segmentation fault.

• Fixes an unintended change between qiskit-aer 0.8.0 and 0.9.0 where when running a list of circuits with an invalid circuit using the automatic simulation method of the AerSimulator or QasmSimulator would raise an exception for an invalid input qobj rather than return partial results for the circuits that were valid.

• Fixes an issue with the standalone simulator where it would return a IBM Quantum API schema invalid response in the case of an error that prevented the simulation from running.

• Fixes #1346 which was a bug in the handling of the parameter_binds kwarg of the backend run() method that would result in an error if the parameterized circuit was transpiled to a different set of basis gates than the original parameterizations.

No change

No change

### Qiskit 0.30.1¶

#### Terra 0.18.3¶

##### Prelude¶

This bugfix release fixes a few minor issues in 0.18, including a performance regression in assemble when dealing with executing QuantumCircuit objects on pulse-enabled backends.

##### Bug Fixes¶
• Fixed #7004 where AttributeError was raised when executing ScheduleBlock on a pulse backend. These blocks are now correctly treated as pulse jobs, like Schedule.

• Fixed an issue causing an error when binding a complex parameter value to an operator's coefficient. Casts to float in PrimitiveOp were generalized to casts to complex if necessary, but will remain float if there is no imaginary component. Fixes #6976.

• Update the 1-qubit gate errors in plot_error_map to use the sx gate instead of the u2 gate, consistent with IBMQ backends.

No change

No change

No change

No change

### Qiskit 0.30.0¶

No change

#### Aer 0.9.0¶

##### Prelude¶

The 0.9 release includes new backend options for parallel exeuction of large numbers of circuits on a HPC cluster using a Dask distributed, along with other general performance improvements and bug fixes.

##### New Features¶

• Add qiskit library SXdgGate and CUGate to the supported basis gates for the Aer simulator backends. Note that the CUGate gate is only natively supported for the statevector and unitary methods. For other simulation methods it must be transpiled to the supported basis gates for that method.

• Adds support for N-qubit Pauli gate ( qiskit.circuit.library.generalized_gates.PauliGate) to all simulation methods of the AerSimulator and QasmSimulator.

• Adds the ability to set a custom executor and configure job splitting for executing multiple circuits in parallel on a HPC clustor. A custom executor can be set using the executor option, and job splitting is configured by using the max_job_size option.

For example configuring a backend and executing using

backend = AerSimulator(max_job_size=1, executor=custom_executor)
job = backend.run(circuits)


will split the exection into multiple jobs each containing a single circuit. If job splitting is enabled the run method will return a AerJobSet object containing all the individual AerJob classes. After all individual jobs finish running the job results are automatically combined into a single Result object that is returned by job.result().

Supported executors include those in the Python concurrent.futures module (eg. ThreadPoolExecutor, ProcessPoolExecutor), and Dask distributed Client executors if the optional dask library is installed. Using a Dask executor allows configuring parallel execution of multiple circuits on HPC clusters. See the Dask executor API Documentation for additional details on using Dask executors for HPC simulation.

• Adds ability to record logging data for the matrix_product_state simulation method to the experiment result metadata by setting the backend option mps_log_data=True. The saved data includes the bond dimensions and the discarded value (the sum of the squares of the Schmidt coeffients that were discarded by approximation) after every relevant circuit instruction.

• The run() method for the AerSimulator, QasmSimulator, StatevectorSimulator, and UnitarySimulator has a new kwarg, parameter_binds which is used to provide a list of values to use for any unbound parameters in the inbound circuit. For example:

from qiskit.circuit import QuantumCircuit, Parameter
from qiskit.providers.aer import AerSimulator

shots = 1000
backend = AerSimulator()
circuit = QuantumCircuit(2)
theta = Parameter('theta')
circuit.rx(theta, 0)
circuit.cx(0, 1)
circuit.measure_all()
parameter_binds = [{theta: [0, 3.14, 6.28]}]
backend.run(circuit, shots=shots, parameter_binds=parameter_binds).result()


will run the input circuit 3 times with the values 0, 3.14, and 6.28 for theta. When running with multiple parameters the length of the value lists must all be the same. When running with multiple circuits, the length of parameter_binds must match the number of input circuits (you can use an empty dict, {}, if there are no binds for a circuit).

• The PulseSimulator can now take QuantumCircuit objects on the run(). Previously, it only would except Schedule objects as input to run(). When a circuit or list of circuits is passed to the simulator it will call schedule() to convert the circuits to a schedule before executing the circuit. For example:

from qiskit.circuit import QuantumCircuit
from qiskit.compiler import transpile
from qiskit.test.mock import FakeVigo
from qiskit.providers.aer.backends import PulseSimulator

backend = PulseSimulator.from_backend(FakeVigo())

circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()

transpiled_circuit = transpile(circuit, backend)
backend.run(circuit)

##### Known Issues¶
• The default basis for the NoiseModel class has been changed from ["id", "u3", "cx"] to ["id", "rz", "sx", "cx"] due to the deprecation of the u3 circuit method in qiskit-terra and change of qiskit-ibmq-provider backend basis gates. To use the old basis gates you can initialize a noise model with custom basis gates as NoiseModel(basis_gates=["id", "u3", "cx"]).

• Removed the backend_options kwarg from the run methnod of Aer backends that was deprecated in qiskit-aer 0.7. All run options must now be passed as separate kwargs.

• Removed passing system_model as a positional arg for the run method of the PulseSimulator.

##### Deprecation Notes¶
• Passing an assembled qobj directly to the run() method of the Aer simulator backends has been deprecated in favor of passing transpiled circuits directly as backend.run(circuits, **run_options).

• All snapshot instructions in qiskit.providers.aer.extensions have been deprecated. For replacement use the save instructions from the qiskit.providers.aer.library module.

• Adding non-local quantum errors to a NoiseModel has been deprecated due to inconsistencies in how this noise is applied to the optimized circuit. Non-local noise should be manually added to a scheduled circuit in Qiskit using a custom transpiler pass before being run on the simulator.

• Use of the method option of the StatevectorSimulator, and UnitarySimulator to run a GPU simulation has been deprecated. To run a GPU simulation on a compatible system use the option device='GPU' instead.

##### Bug Fixes¶
• Fixes performance issue with how the basis_gates configuration attribute was set. Previously there were unintended side-effects to the backend class which could cause repeated simulation runtime to incrementally increase. Refer to #1229 <https://github.com/Qiskit/qiskit-aer/issues/1229> for more information and examples.

• Fixed bug in MPS::apply_kraus. After applying the kraus matrix to the relevant qubits, we should propagate the changes to the neighboring qubits.

• Fixes a bug where qiskit-terra assumes that qubits in a multiplexer gate are first the targets and then the controls of the gate while qiskit-aer assumes the opposite order.

• Fixes a bug introduced in 0.8.0 where GPU simulations would allocate unneeded host memory in addition to the GPU memory.

• Fixes bug where the initialize instruction would disable measurement sampling optimization for the statevector and matrix product state simulation methods even when it was the first circuit instruction or applied to all qubits and hence deterministic.

• Fix issue #1196 by using the inner products with the computational basis states to calculate the norm rather than the norm estimation algorithm.

• Fixes a bug in the stabilizer simulator method of the QasmSimulator and AerSimulator where the expectation value for the save_expectation_value and snapshot_expectation_value could have the wrong sign for certain Y Pauli's.

• Fixes bug where the if the required memory is smaller than the system memory the multi-chunk simulation method was enabled and simulation was still started. This case will now throw an insufficient memory exception.

• Fixes issue where setting the shots option for a backend with set_options(shots=k) was always running the default number of shots (1024) rather than the specified value.

• Fixes a bug in how the AerSimulator handled the option value for max_parallel_experiments=1. Previously this was treated the same as max_parallel_experiments=0.

• Fixes bug in the extended_stabilizer simulation method where it incorrectly treated qelay gate and multi-qubit Pauli instructions as unsupported.

• Fixes typo in the AerSimulator and QasmSimulator options for the extended_stabilizer_norm_estimation_repetitions option.

• Fixes bug with applying the unitary gate in using the matrix_product_state simulation method which did not correctly support permutations in the ordering of the qubits on which the gate is applied.

• Fixes an issue where gate fusion could still be enabled for the matrix_product_state simulation method even though it is not supported. Now fusion is always disabled for this method.

• Fixed bug in the matrix_product_state simulation method in computing the normalization following truncation of the Schmidt coefficients after performing the SVD.

##### Other Notes¶
• Improves the performance of the measurement sampling algorithm for the matrix_product_state simulation method. The new default behaviour is to always sample using the improved mps_apply_measure method. The mps_probabilities sampling method be still used by setting the custom option value mps_sample_measure_algorithm="mps_probabilities".

No change

No change

No change

### Qiskit 0.29.1¶

#### Terra 0.18.2¶

##### Bug Fixes¶
• Fixed an issue with the assemble() function when called with the backend kwarg set and the parametric_pulses kwarg was set to an empty list the output qobj would contain the parametric_pulses setting from the given backend's BackendConfiguration instead of the expected empty list. Fixed #6898

• The Matplotlib circuit drawer will no longer duplicate drawings when using ipykernel>=6.0.0. Fixes #6889.

No change

No change

#### Aqua 0.9.5¶

##### Bug Fixes¶
• Fixed a handling error in the Yahoo provider when only one ticker is entered. Added exception error if no ticker is entered. Limit yfinance to >=0.1.62 as previous versions have a JSON decoder error.

No change

### Qiskit 0.29.0¶

#### Terra 0.18.1¶

##### Prelude¶

This bugfix release fixes a few minor issues and regressions in the 0.18.0 release. There is also a minor change to how pip handles the [all] extra when installing qiskit-terra directly, compared to 0.18.0.

• pip install qiskit-terra[all] will no longer attempt to install the bip-mapper extra. This is because the dependency cplex is not well supported on the range of Python versions and OSes that Terra supports, and a failed extra dependency would fail the entire package resolution. If you are using Python 3.7 or 3.8 and are on Linux-x64 or -ppc64le, macOS-x64 or Windows-x64 you should be able to install qiskit-terra[bip-mapper] explicitly, if desired, while other combinations of OS, platform architectures and Python versions will likely fail.

No change

No change

No change

### Qiskit 0.28.0¶

#### Terra 0.18.0¶

##### Prelude¶

This release includes many new features and bug fixes. The highlights of this release are the introduction of two new transpiler passes, BIPMapping and DynamicalDecoupling, which when combined with the new pulse_optimize kwarg on the UnitarySynthesis pass enables recreating the Quantum Volume 64 results using the techniques described in: https://arxiv.org/abs/2008.08571. These new transpiler passes and options and are also generally applicable to optimizing any circuit.

##### New Features¶
• The measurement_error_mitgation kwarg for the QuantumInstance constructor can now be set to the TensoredMeasFitter class from qiskit-ignis in addition to CompleteMeasFitter that was already supported. If you use TensoredMeasFitter you will also be able to set the new mit_pattern kwarg to specify the qubits on which to use TensoredMeasFitter You can refer to the documentation for mit_pattern in the TensoredMeasFitter documentation for the expected format.

• The decomposition methods for single-qubit gates, specified via the basis kwarg, in OneQubitEulerDecomposer has been expanded to now also include the 'ZSXX' basis, for making use of direct $$X$$ gate as well as $$\sqrt{X}$$ gate.

• Added two new passes AlignMeasures and ValidatePulseGates to the qiskit.transpiler.passes module. These passes are a hardware-aware optimization, and a validation routine that are used to manage alignment restrictions on time allocation of instructions for a backend.

If a backend has a restriction on the alignment of Measure instructions (in terms of quantization in time), the AlignMeasures pass is used to adjust delays in a scheduled circuit to ensure that any Measure instructions in the circuit are aligned given the constraints of the backend. The ValidatePulseGates pass is used to check if any custom pulse gates (gates that have a custom pulse definition in the calibrations attribute of a QuantumCircuit object) are valid given an alignment constraint for the target backend.

In the built-in preset_passmangers used by the transpile() function, these passes get automatically triggered if the alignment constraint, either via the dedicated timing_constraints kwarg on transpile() or has an timing_constraints attribute in the BackendConfiguration object of the backend being targetted.

The backends from IBM Quantum Services (accessible via the qiskit-ibmq-provider package) will provide the alignment information in the near future.

For example:

from qiskit import circuit, transpile
from qiskit.test.mock import FakeArmonk

backend = FakeArmonk()

qc = circuit.QuantumCircuit(1, 1)
qc.x(0)
qc.delay(110, 0, unit="dt")
qc.measure(0, 0)
qc.draw('mpl')

qct = transpile(qc, backend, scheduling_method='alap',
timing_constraints={'acquire_alignment': 16})
qct.draw('mpl')

• A new transpiler pass class qiskit.transpiler.passes.BIPMapping that tries to find the best layout and routing at once by solving a BIP (binary integer programming) problem as described in arXiv:2106.06446 has been added.

The BIPMapping pass (named "mapping" to refer to "layout and routing") represents the mapping problem as a BIP (binary integer programming) problem and relies on CPLEX (cplex) to solve the BIP problem. The dependent libraries including CPLEX can be installed along with qiskit-terra:

pip install qiskit-terra[bip-mapper]


Since the free version of CPLEX can solve only small BIP problems, i.e. mapping of circuits with less than about 5 qubits, the paid version of CPLEX may be needed to map larger circuits.

The BIP mapper scales badly with respect to the number of qubits or gates. For example, it would not work with coupling_map beyond 10 qubits because the BIP solver (CPLEX) could not find any solution within the default time limit.

Note that, if you want to fix physical qubits to be used in the mapping (e.g. running Quantum Volume (QV) circuits), you need to specify coupling_map which contains only the qubits to be used.

Here is a minimal example code to build pass manager to transpile a QV circuit:

num_qubits = 4  # QV16
circ = QuantumVolume(num_qubits=num_qubits)

backend = ...
basis_gates = backend.configuration().basis_gates
coupling_map = CouplingMap.from_line(num_qubits)  # supply your own coupling map

def _not_mapped(property_set):
return not property_set["is_swap_mapped"]

def _opt_control(property_set):
return not property_set["depth_fixed_point"]

from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary as sel
pm = PassManager()
# preparation
pm.append([
Unroll3qOrMore(),
TrivialLayout(coupling_map),
FullAncillaAllocation(coupling_map),
EnlargeWithAncilla(),
BarrierBeforeFinalMeasurements()
])
# mapping
pm.append(BIPMapping(coupling_map))
pm.append(CheckMap(coupling_map))
pm.append(Error(msg="BIP mapper failed to map", action="raise"),
condition=_not_mapped)
# post optimization
pm.append([
Depth(),
FixedPoint("depth"),
Collect2qBlocks(),
ConsolidateBlocks(basis_gates=basis_gates),
UnitarySynthesis(basis_gates),
Optimize1qGatesDecomposition(basis_gates),
CommutativeCancellation(),
UnrollCustomDefinitions(sel, basis_gates),
BasisTranslator(sel, basis_gates)
], do_while=_opt_control)

transpile_circ = pm.run(circ)

• A new constructor method initialize_from() was added to the Schedule and ScheduleBlock classes. This method initializes a new empty schedule which takes the attributes from other schedule. For example:

sched = Schedule(name='my_sched')
new_sched = Schedule.initialize_from(sched)

assert sched.name == new_sched.name

• A new kwarg, line_discipline, has been added to the job_monitor() function. This kwarg enables changing the carriage return characters used in the job_monitor output. The line_discipline kwarg defaults to '\r', which is what was in use before.

• The abstract Pulse class (which is the parent class for classes such as Waveform, Constant, and Gaussian now has a new kwarg on the constructor, limit_amplitude, which can be set to False to disable the previously hard coded amplitude limit of 1. This can also be set as a class attribute directly to change the global default for a Pulse class. For example:

from qiskit.pulse.library import Waveform

# Change the default value of limit_amplitude to False
Waveform.limit_amplitude = False
wave = Waveform(2.0 * np.exp(1j * 2 * np.pi * np.linspace(0, 1, 1000)))

• A new class, PauliList, has been added to the qiskit.quantum_info module. This class is used to efficiently represent a list of Pauli operators. This new class inherets from the same parent class as the existing PauliTable (and therefore can be mostly used interchangeably), however it differs from the PauliTable because the qiskit.quantum_info.PauliList class can handle Z4 phases.

• Added a new transpiler pass, RemoveBarriers, to qiskit.transpiler.passes. This pass is used to remove all barriers in a circuit.

• Add a new optimizer class, SciPyOptimizer, to the qiskit.algorithms.optimizers module. This class is a simple wrapper class of the scipy.optimize.minimize function (documentation) which enables the use of all optimization solvers and all parameters (e.g. callback) which are supported by scipy.optimize.minimize. For example:

from qiskit.algorithms.optimizers import SciPyOptimizer

values = []

def callback(x):
values.append(x)

optimizer = SciPyOptimizer("BFGS", options={"maxiter": 1000}, callback=callback)

• The HoareOptimizer pass has been improved so that it can now replace a ControlledGate in a circuit with with the base gate if all the control qubits are in the $$|1\rangle$$ state.

• Added two new methods, is_successor() and is_predecessor(), to the DAGCircuit class. These functions are used to check if a node is either a successor or predecessor of another node on the DAGCircuit.

• A new transpiler pass, RZXCalibrationBuilderNoEcho, was added to the qiskit.transpiler.passes module. This pass is similar to the existing RZXCalibrationBuilder in that it creates calibrations for an RZXGate(theta), however RZXCalibrationBuilderNoEcho does this without inserting the echo pulses in the pulse schedule. This enables exposing the echo in the cross-resonance sequence as gates so that the transpiler can simplify them. The RZXCalibrationBuilderNoEcho pass only supports the hardware-native direction of the CXGate.

• A new kwarg, wrap, has been added to the compose() method of QuantumCircuit. This enables choosing whether composed circuits should be wrapped into an instruction or not. By default this is False, i.e. no wrapping. For example:

from qiskit import QuantumCircuit
circuit = QuantumCircuit(2)
circuit.h([0, 1])
other = QuantumCircuit(2)
other.x([0, 1])
print(circuit.compose(other, wrap=True))  # wrapped
print(circuit.compose(other, wrap=False))  # not wrapped

     ┌───┐┌──────────────┐
q_0: ┤ H ├┤0             ├
├───┤│  circuit-114 │
q_1: ┤ H ├┤1             ├
└───┘└──────────────┘
┌───┐┌───┐
q_0: ┤ H ├┤ X ├
├───┤├───┤
q_1: ┤ H ├┤ X ├
└───┘└───┘

• A new attribute, control_channels, has been added to the PulseBackendConfiguration class. This attribute represents the control channels on a backend as a mapping of qubits to a list of ControlChannel objects.

• A new kwarg, epsilon, has been added to the constructor for the Isometry class and the corresponding QuantumCircuit method isometry(). This kwarg enables optionally setting the epsilon tolerance used by an Isometry gate. For example:

import numpy as np
from qiskit import QuantumRegister, QuantumCircuit

tolerance = 1e-8
iso = np.eye(2,2)
num_q_output = int(np.log2(iso.shape[0]))
num_q_input = int(np.log2(iso.shape[1]))
q = QuantumRegister(num_q_output)
qc = QuantumCircuit(q)

qc.isometry(iso, q[:num_q_input], q[num_q_input:], epsilon=tolerance)

• Added a transpiler pass, DynamicalDecoupling, to qiskit.transpiler.passes for inserting dynamical decoupling sequences in idle periods of a circuit (after mapping to physical qubits and scheduling). The pass allows control over the sequence of DD gates, the spacing between them, and the qubits to apply on. For example:

from qiskit.circuit import QuantumCircuit
from qiskit.circuit.library import XGate
from qiskit.transpiler import PassManager, InstructionDurations
from qiskit.transpiler.passes import ALAPSchedule, DynamicalDecoupling
from qiskit.visualization import timeline_drawer

circ = QuantumCircuit(4)
circ.h(0)
circ.cx(0, 1)
circ.cx(1, 2)
circ.cx(2, 3)
circ.measure_all()

durations = InstructionDurations(
[("h", 0, 50), ("cx", [0, 1], 700), ("reset", None, 10),
("cx", [1, 2], 200), ("cx", [2, 3], 300),
("x", None, 50), ("measure", None, 1000)]
)

dd_sequence = [XGate(), XGate()]

pm = PassManager([ALAPSchedule(durations),
DynamicalDecoupling(durations, dd_sequence)])
circ_dd = pm.run(circ)
timeline_drawer(circ_dd)

• The QuantumCircuit method qasm() has a new kwarg, encoding, which can be used to optionally set the character encoding of an output QASM file generated by the function. This can be set to any valid codec or alias string from the Python standard library's codec module.

• Added a new class, EvolvedOperatorAnsatz, to the qiskit.circuit.library module. This library circuit, which had previously been located in Qiskit Nature , can be used to construct ansatz circuits that consist of time-evolved operators, where the evolution time is a variational parameter. Examples of such ansatz circuits include UCCSD class in the chemistry module of Qiskit Nature or the QAOAAnsatz class.

• A new fake backend class is available under qiskit.test.mock for the ibmq_guadalupe backend. As with the other fake backends, this includes a snapshot of calibration data (i.e. backend.defaults()) and error data (i.e. backend.properties()) taken from the real system, and can be used for local testing, compilation and simulation.

• A new method children() for the Schedule class has been added. This method is used to return the child schedule components of the Schedule object as a tuple. It returns nested schedules without flattening. This method is equivalent to the private _children() method but has a public and stable interface.

• A new optimizer class, GradientDescent, has been added to the qiskit.algorithms.optimizers module. This optimizer class implements a standard gradient descent optimization algorithm for use with quantum variational algorithms, such as VQE. For a detailed description and examples on how to use this class, please refer to the GradientDescent class documentation.

• A new optimizer class, QNSPSA, has been added to the qiskit.algorithms.optimizers module. This class implements the Quantum Natural SPSA (QN-SPSA) algorithm, a generalization of the 2-SPSA algorithm, and estimates the Quantum Fisher Information Matrix instead of the Hessian to obtain a stochastic estimate of the Quantum Natural Gradient. For examples on how to use this new optimizer refer to the QNSPSA class documentation.

• A new kwarg, second_order, has been added to the constructor of the SPSA class in the qiskit.algorithms.optimizers module. When set to True this enables using second-order SPSA. Second order SPSA, or 2-SPSA, is an extension of the ordinary SPSA algorithm that enables estimating the Hessian alongside the gradient, which is used to precondition the gradient before the parameter update step. As a second-order method, this tries to improve convergence of SPSA. For examples on how to use this option refer to the SPSA class documentation.

• When using the latex or latex_source output mode of circuit_drawer() or the draw() of QuantumCircuit the style kwarg can now be used just as with the mpl output formatting. However, unlike the mpl output mode only the displaytext field will be used when using the latex or latex_source output modes (because neither supports color).

• When using the mpl or latex output methods for the circuit_drawer() function or the draw() of QuantumCircuit, you can now use math mode formatting for text and set color formatting (mpl only) by setting the style kwarg as a dict with a user-generated name or label. For example, to add subscripts and to change a gate color:

from qiskit import QuantumCircuit
from qiskit.circuit.library import HGate
qc = QuantumCircuit(3)
qc.append(HGate(label='h1'), [0])
qc.append(HGate(label='h2'), [1])
qc.append(HGate(label='h3'), [2])
qc.draw('mpl', style={'displaytext': {'h1': 'H_1', 'h2': 'H_2', 'h3': 'H_3'},
'displaycolor': {'h2': ('#EEDD00', '#FF0000')}})

• Added three new classes, CDKMRippleCarryAdder, ClassicalAdder and DraperQFTAdder, to the qiskit.circuit.library module. These new circuit classes are used to perform classical addition of two equally-sized qubit registers. For two registers $$|a\rangle_n$$ and $$|b\rangle_n$$ on $$n$$ qubits, the three new classes perform the operation:

$|a\rangle_n |b\rangle_n \mapsto |a\rangle_n |a + b\rangle_{n + 1}.$

For example:

from qiskit.circuit import QuantumCircuit
from qiskit.quantum_info import Statevector

# a encodes |01> = 1
a = QuantumCircuit(2)
a.x(0)

# b encodes |10> = 2
b = QuantumCircuit(2)
b.x(1)

# add the state preparations to the front of the circuit

# simulate and get the state of all qubits
counts = sv.probabilities_dict()
state = list(counts.keys())[0]  # we only have a single state

# skip the input carry (first bit) and the register |a> (last two bits)
result = state[1:-2]
print(result)  # '011' = 3 = 1 + 2

• Added two new classes, RGQFTMultiplier and HRSCumulativeMultiplier, to the qiskit.circuit.library module. These classes are used to perform classical multiplication of two equally-sized qubit registers. For two registers $$|a\rangle_n$$ and $$|b\rangle_n$$ on $$n$$ qubits, the two new classes perform the operation

$|a\rangle_n |b\rangle_n |0\rangle_{2n} \mapsto |a\rangle_n |b\rangle_n |a \cdot b\rangle_{2n}.$

For example:

from qiskit.circuit import QuantumCircuit
from qiskit.circuit.library import RGQFTMultiplier
from qiskit.quantum_info import Statevector

num_state_qubits = 2

# a encodes |11> = 3
a = QuantumCircuit(num_state_qubits)
a.x(range(num_state_qubits))

# b encodes |11> = 3
b = QuantumCircuit(num_state_qubits)
b.x(range(num_state_qubits))

# multiplier on 2-bit numbers
multiplier = RGQFTMultiplier(num_state_qubits)

# add the state preparations to the front of the circuit
multiplier.compose(a, [0, 1], inplace=True, front=True)
multiplier.compose(b, [2, 3], inplace=True, front=True)

# simulate and get the state of all qubits
sv = Statevector(multiplier)
counts = sv.probabilities_dict(decimals=10)
state = list(counts.keys())[0]  # we only have a single state

# skip both input registers
result = state[:-2*num_state_qubits]
print(result)  # '1001' = 9 = 3 * 3

• The Delay class now can accept a ParameterExpression or Parameter value for the duration kwarg on its constructor and for its duration attribute.

For example:

idle_dur = Parameter('t')
qc = QuantumCircuit(1, 1)
qc.x(0)
qc.delay(idle_dur, 0, 'us')
qc.measure(0, 0)
print(qc)  # parameterized delay in us (micro seconds)

# assign before transpilation
assigned = qc.assign_parameters({idle_dur: 0.1})
print(assigned)  # delay in us
transpiled = transpile(assigned, some_backend_with_dt)
print(transpiled)  # delay in dt

# assign after transpilation
transpiled = transpile(qc, some_backend_with_dt)
print(transpiled)  # parameterized delay in dt
assigned = transpiled.assign_parameters({idle_dur: 0.1})
print(assigned)  # delay in dt

• A new binary serialization format, QPY, has been introduced. It is designed to be a fast binary serialization format that is backwards compatible (QPY files generated with older versions of Qiskit can be loaded by newer versions of Qiskit) that is native to Qiskit. The QPY serialization tooling is available via the qiskit.circuit.qpy_serialization module. For example, to generate a QPY file:

from datetime import datetime

from qiskit.circuit import QuantumCircuit
from qiskit.circuit import qpy_serialization

qc = QuantumCircuit(
)
qc.h(0)
qc.cx(0, 1)
qc.measure_all()

circuits = [qc] * 5

with open('five_bells.qpy', 'wb') as qpy_file:
qpy_serialization.dump(circuits, qpy_file)


Then the five circuits saved in the QPY file can be loaded with:

from qiskit.circuit.qpy_serialization

with open('five_bells.qpy', 'rb') as qpy_file:


The QPY file format specification is available in the module documentation.

• The TwoQubitBasisDecomposer class has been updated to perform pulse optimal decompositions for a basis with CX, √X, and virtual Rz gates as described in https://arxiv.org/pdf/2008.08571. Pulse optimal here means that the duration of gates between the CX gates of the decomposition is reduced in exchange for possibly more local gates before or after all the CX gates such that, when composed into a circuit, there is the possibility of single qubit compression with neighboring gates reducing the overall sequence duration.

A new keyword argument, pulse_optimize, has been added to the constructor for TwoQubitBasisDecomposer to control this:

• None: Attempt pulse optimal decomposition. If a pulse optimal decomposition is unknown for the basis of the decomposer, drop back to the standard decomposition without warning. This is the default setting.

• True: Attempt pulse optimal decomposition. If a pulse optimal decomposition is unknown for the basis of the decomposer, raise QiskitError.

• False: Do not attempt pulse optimal decomposition.

For example:

from qiskit.quantum_info import TwoQubitBasisDecomposer
from qiskit.circuit.library import CXGate
from qiskit.quantum_info import random_unitary

unitary_matrix = random_unitary(4)

decomposer = TwoQubitBasisDecomposer(CXGate(), euler_basis="ZSX", pulse_optimize=True)
circuit = decomposer(unitary_matrix)

• The transpiler pass UnitarySynthesis located in qiskit.transpiler.passes has been updated to support performing pulse optimal decomposition. This is done primarily with the the pulse_optimize keyword argument which was added to the constructor and used to control whether pulse optimal synthesis is performed. The behavior of this kwarg mirrors the pulse_optimize kwarg in the TwoQubitBasisDecomposer class's constructor. Additionally, the constructor has another new keyword argument, synth_gates, which is used to specify the list of gate names over which synthesis should be attempted. If None and pulse_optimize is False or None, use "unitary". If None and pulse_optimize is True, use "unitary" and "swap". Since the direction of the CX gate in the synthesis is arbitrary, another keyword argument, natural_direction, is added to consider first a coupling map and then CXGate durations in choosing for which direction of CX to generate the synthesis.

from qiskit.circuit import QuantumCircuit
from qiskit.transpiler import PassManager, CouplingMap
from qiskit.transpiler.passes import TrivialLayout, UnitarySynthesis
from qiskit.test.mock import FakeVigo
from qiskit.quantum_info.random import random_unitary

backend = FakeVigo()
conf = backend.configuration()
coupling_map = CouplingMap(conf.coupling_map)
triv_layout_pass = TrivialLayout(coupling_map)
circ = QuantumCircuit(2)
circ.unitary(random_unitary(4), [0, 1])
unisynth_pass = UnitarySynthesis(
basis_gates=conf.basis_gates,
coupling_map=None,
backend_props=backend.properties(),
pulse_optimize=True,
natural_direction=True,
synth_gates=['unitary'])
pm = PassManager([triv_layout_pass, unisynth_pass])
optimal_circ = pm.run(circ)

• A new basis option, 'XZX', was added for the basis argument OneQubitEulerDecomposer class.

• Added a new method, get_instructions(), was added to the QuantumCircuit class. This method is used to return all Instruction objects in the circuit which have a name that matches the provided name argument along with its associated qargs and cargs lists of Qubit and Clbit objects.

• A new optional extra all has been added to the qiskit-terra package. This enables installing all the optional requirements with a single extra, for example: pip install 'qiskit-terra[all]', Previously, it was necessary to list all the extras individually to install all the optional dependencies simultaneously.

• Added two new classes ProbDistribution and QuasiDistribution for dealing with probability distributions and quasiprobability distributions respectively. These objects both are dictionary subclasses that add additional methods for working with probability and quasiprobability distributions.

• Added a new settings property to the Optimizer abstract base class that all the optimizer classes in the qiskit.algorithms.optimizers module are based on. This property will return a Python dictionary of the settings for the optimizer that can be used to instantiate another instance of the same optimizer class. For example:

from qiskit.algorithms.optimizers import GradientDescent

settings = optimizer.settings


The settings dictionary is also potentially useful for serializing optimizer objects using JSON or another serialization format.

• A new function, set_config(), has been added to the qiskit.user_config module. This function enables setting values in a user config from the Qiskit API. For example:

from qiskit.user_config import set_config
set_config("circuit_drawer", "mpl", section="default", file="settings.conf")


which will result in adding a value of circuit_drawer = mpl to the default section in the settings.conf file.

If no file_path argument is specified, the currently used path to the user config file (either the value of the QISKIT_SETTINGS environment variable if set or the default location ~/.qiskit/settings.conf) will be updated. However, changes to the existing config file will not be reflected in the current session since the config file is parsed at import time.

• Added a new state class, StabilizerState, to the qiskit.quantum_info module. This class represents a stabilizer simulator state using the convention from Aaronson and Gottesman (2004).

• Two new options, 'value' and 'value_desc' were added to the sort kwarg of the qiskit.visualization.plot_histogram() function. When sort is set to either of these options the output visualization will sort the x axis based on the maximum probability for each bitstring. For example:

from qiskit.visualization import plot_histogram

counts = {
'000': 5,
'001': 25,
'010': 125,
'011': 625,
'100': 3125,
'101': 15625,
'110': 78125,
'111': 390625,
}
plot_histogram(counts, sort='value')

##### Known Issues¶
• The minimum version of the retworkx dependency was increased to version 0.9.0. This was done to use new APIs introduced in that release which improved the performance of some transpiler passes.

• The default value for QISKIT_PARALLEL on Python 3.9 environments has changed to False, this means that when running on Python 3.9 by default multiprocessing will not be used. This was done to avoid a potential deadlock/hanging issue that can occur when running multiprocessing on Python 3.9 (see the known issues section for more detail). It is still possible to manual enable it by explicitly setting the QISKIT_PARALLEL environment variable to TRUE.

• The existing fake backend classes in qiskit.test.mock now strictly implement the BackendV1 interface. This means that if you were manually constructing QasmQobj or PulseQobj object for use with the run() method this will no longer work. The run() method only accepts QuantumCircuit or Schedule objects now. This was necessary to enable testing of new backends implemented without qobj which previously did not have any testing inside qiskit terra. If you need to leverage the fake backends with QasmQobj or PulseQobj new fake legacy backend objects were added to explicitly test the legacy providers interface. This will be removed after the legacy interface is deprecated and removed. Moving forward new fake backends will only implement the BackendV1 interface and will not add new legacy backend classes for new fake backends.

• When creating a Pauli object with an invalid string label, a QiskitError is now raised. This is a change from previous releases which would raise an AttributeError on an invalid string label. This change was made to ensure the error message is more informative and distinct from a generic AttributeError.

• The output program representation from the pulse builder (qiskit.pulse.builder.build()) has changed from a Schedule to a ScheduleBlock. This new representation disables some timing related operations such as shift and insert. However, this enables parameterized instruction durations within the builder context. For example:

from qiskit import pulse
from qiskit.circuit import Parameter

dur = Parameter('duration')

with pulse.build() as sched:
with pulse.align_sequential():
pulse.delay(dur, pulse.DriveChannel(1))
pulse.play(pulse.Gaussian(dur, 0.1, dur/4), pulse.DriveChannel(0))

assigned0 = sched.assign_parameters({dur: 100})
assigned1 = sched.assign_parameters({dur: 200})


You can directly pass the duration-assigned schedules to the assembler (or backend), or you can attach them to your quantum circuit as pulse gates.

• The tweedledum library which was previously an optional dependency has been made a requirement. This was done because of the wide use of the PhaseOracle (which depends on having tweedledum installed) with several algorithms from qiskit.algorithms.

• The optional extra full-featured-simulators which could previously used to install qiskit-aer with something like pip install qiskit-terra[full-featured-simulators] has been removed from the qiskit-terra package. If this was being used to install qiskit-aer with qiskit-terra instead you should rely on the qiskit metapackage or just install qiskit-terra and qiskit-aer together with pip install qiskit-terra qiskit-aer.

• A new requirement symengine has been added for Linux (on x86_64, aarch64, and ppc64le) and macOS users (x86_64 and arm64). It is an optional dependency on Windows (and available on PyPi as a precompiled package for 64bit Windows) and other architectures. If it is installed it provides significantly improved performance for the evaluation of Parameter and ParameterExpression objects.

• All library circuit classes, i.e. all QuantumCircuit derived classes in qiskit.circuit.library, are now wrapped in a Instruction (or Gate, if they are unitary). For example, importing and drawing the QFT circuit:

before looked like

                                          ┌───┐
q_0: ────────────────────■────────■───────┤ H ├─X─
┌───┐ │        │P(π/2) └───┘ │
q_1: ──────■───────┤ H ├─┼────────■─────────────┼─
┌───┐ │P(π/2) └───┘ │P(π/4)                │
q_2: ┤ H ├─■─────────────■──────────────────────X─
└───┘


and now looks like

     ┌──────┐
q_0: ┤0     ├
│      │
q_1: ┤1 QFT ├
│      │
q_2: ┤2     ├
└──────┘


To obtain the old circuit, you can call the decompose() method on the circuit

This change was primarily made for consistency as before this release some circuit classes in qiskit.circuit.library were previously wrapped in an Instruction or Gate but not all.

##### Other Notes¶
• The deprecation of the parameters() method for the Instruction class has been reversed. This method was originally deprecated in the 0.17.0, but it is still necessary for several applications, including when running calibration experiments. This method will continue to be supported and will not be removed.

No change

No change

No change

#### IBM Q Provider 0.15.0¶

##### Deprecation Notes¶
• The id instruction has been deprecated on IBM hardware backends. Instead, please use the delay instruction which implements variable-length delays, specified in units of dt. When running a circuit containing an id instruction, a warning will be raised on job submission and any id instructions in the job will be automatically replaced with their equivalent delay instruction.

### Qiskit 0.27.0¶

No change

No change

No change

#### Aqua 0.9.2¶

##### Bug Fixes¶
• Removed version caps from the requirements list to enable installing with newer versions of dependencies.

#### IBM Q Provider 0.14.0¶

##### New Features¶
• You can now use the qiskit.providers.ibmq.runtime.RuntimeJob.logs() method to retrieve job logs. Note that logs are only available after the job finishes.

• A new backend configuration attribute input_allowed now tells you the types of input supported by the backend. Valid input types are job, which means circuit jobs, and runtime, which means Qiskit Runtime.

You can also use input_allowed in backend filtering. For example:

from qiskit import IBMQ

# Get a list of all backends that support runtime.
runtime_backends = provider.backends(input_allowed='runtime')

• qiskit-ibmq-provider now uses a new package websocket-client as its websocket client, and packages websockets and nest-asyncio are no longer required. setup.py and requirements.txt have been updated accordingly.

##### Bug Fixes¶
• Fixes the issue that uses shots=1 instead of the documented default when no shots is specified for run_circuits().

• Fixes the issue wherein a QiskitBackendNotFoundError exception is raised when retrieving a runtime job that was submitted using a different provider than the one used for retrieval.

• Streaming runtime program interim results with proxies is now supported. You can specify the proxies to use when enabling the account as usual, for example:

from qiskit import IBMQ

proxies = {'urls': {'https://127.0.0.1:8085'}}
provider = IBMQ.enable_account(API_TOKEN, proxies=proxies)


No change

No change

No change

No change

### Qiskit 0.26.0¶

#### Terra 0.17.3¶

##### Prelude¶

This release includes 2 new classes, ProbDistribution and QuasiDistribution, which were needed for compatibility with the recent qiskit-ibmq-provider release's beta support for the qiskit-runtime. These were only added for compatibility with that new feature in the qiskit-ibmq-provider release and the API for these classes is considered experimental and not considered stable for the 0.17.x release series. The interface may change when 0.18.0 is released in the future.

##### Bug Fixes¶
• Fixed an issue in plot_histogram() function where a ValueError would be raised when the function run on distributions with unequal lengths.

No change

No change

No change

#### IBM Q Provider 0.13.1¶

##### Prelude¶

This release introduces a new feature Qiskit Runtime Service. Qiskit Runtime is a new architecture offered by IBM Quantum that significantly reduces waiting time during computational iterations. You can execute your experiments near the quantum hardware, without the interactions of multiple layers of classical and quantum hardware slowing it down.

Qiskit Runtime allows authorized users to upload their Qiskit quantum programs, which are Python code that takes certain inputs, performs quantum and maybe classical computation, and returns the processing results. The same or other authorized users can then invoke these quantum programs by simply passing in the required input parameters.

Note that Qiskit Runtime is currently in private beta for select account but will be released to the public in the near future.

##### New Features¶
• qiskit.providers.ibmq.experiment.analysis_result.AnalysisResult now has an additional verified attribute which identifies if the quality has been verified by a human.

• qiskit.providers.ibmq.experiment.Experiment now has an additional notes attribute which can be used to set notes on an experiment.

• This release introduces a new feature Qiskit Runtime Service. Qiskit Runtime is a new architecture that significantly reduces waiting time during computational iterations. This new service allows authorized users to upload their Qiskit quantum programs, which are Python code that takes certain inputs, performs quantum and maybe classical computation, and returns the processing results. The same or other authorized users can then invoke these quantum programs by simply passing in the required input parameters.

An example of using this new service:

from qiskit import IBMQ

# Print all avaiable programs.
provider.runtime.pprint_programs()

# Prepare the inputs. See program documentation on input parameters.
inputs = {...}
options = {"backend_name": provider.backend.ibmq_montreal.name()}

job = provider.runtime.run(program_id="runtime-simple",
options=options,
inputs=inputs)
# Check job status.
print(f"job status is {job.status()}")

# Get job result.
result = job.result()

• The deprecated Human Bad, Computer Bad, Computer Good and Human Good enum values have been removed from qiskit.providers.ibmq.experiment.constants.ResultQuality. They are replaced with Bad and Good values which should be used with the verified attribute on qiskit.providers.ibmq.experiment.analysis_result.AnalysisResult:

Old Quality

New Quality

Verified

True

False

Computer Good

Good

False

Human Good

Good

True

Furthermore, the NO_INFORMATION enum has been renamed to UNKNOWN.

• The qiskit.providers.ibmq.IBMQBackend.defaults() method now always returns pulse defaults if they are available, regardless whether open pulse is enabled for the provider.

##### Bug Fixes¶
• Fixes the issue wherein passing in a noise model when sending a job to an IBMQ simulator would raise a TypeError. Fixes #894

##### Other Notes¶
• The qiskit.providers.ibmq.experiment.analysis_result.AnalysisResult fit attribute is now optional.

### Qiskit 0.25.4¶

#### Terra 0.17.2¶

##### Prelude¶

This is a bugfix release that fixes several issues from the 0.17.1 release. Most importantly this release fixes compatibility for the QuantumInstance class when running on backends that are based on the BackendV1 abstract class. This fixes all the algorithms and applications built on qiskit.algorithms or qiskit.opflow when running on newer backends.

No change

No change

No change

No change

### Qiskit 0.25.3¶

No change

#### Aer 0.8.2¶

##### Bug Fixes¶
• Fixes performance issue with how the basis_gates configuration attribute was set. Previously there were unintended side-effects to the backend class which could cause repeated simulation runtime to incrementally increase. Refer to #1229 <https://github.com/Qiskit/qiskit-aer/issues/1229> for more information and examples.

• Fixes a bug with the "multiplexer" simulator instruction where the order of target and control qubits was reversed to the order in the Qiskit instruction.

• Fixes a bug introduced in 0.8.0 where GPU simulations would allocate unneeded host memory in addition to the GPU memory.

• Fixes a bug in the stabilizer simulator method of the QasmSimulator and AerSimulator where the expectation value for the save_expectation_value and snapshot_expectation_value could have the wrong sign for certain Y Pauli's.

No change

No change

No change

### Qiskit 0.25.2¶

No change

No change

No change

No change

#### IBM Q Provider 0.12.3¶

##### Other Notes¶
• The qiskit.providers.ibmq.experiment.analysis_result.AnalysisResult fit attribute is now optional.

### Qiskit 0.25.1¶

#### Terra 0.17.1¶

##### Prelude¶

This is a bugfix release that fixes several issues from the 0.17.0 release. Most importantly this release fixes the incorrectly constructed sdist package for the 0.17.0 release which was not actually buildable and was blocking installation on platforms without precompiled binaries available.

No change

No change

### Qiskit 0.25.0¶

This release officially deprecates the Qiskit Aqua project. Accordingly, in a future release the qiskit-aqua package will be removed from the Qiskit metapackage, which means in that future release pip install qiskit will no longer include qiskit-aqua. The application modules that are provided by qiskit-aqua have been split into several new packages: qiskit-optimization, qiskit-nature, qiskit-machine-learning, and qiskit-finance. These packages can be installed by themselves (via the standard pip install command, e.g. pip install qiskit-nature) or with the rest of the Qiskit metapackage as optional extras (e.g. pip install 'qiskit[finance,optimization]' or pip install 'qiskit[all]' The core algorithms and the operator flow now exist as part of qiskit-terra at qiskit.algorithms and qiskit.opflow. Depending on your existing usage of Aqua you should either use the application packages or the new modules in Qiskit Terra. For more details on how to migrate from Qiskit Aqua you can refer to the aqua-migration.

#### Terra 0.17.0¶

##### Prelude¶

The Qiskit Terra 0.17.0 includes many new features and bug fixes. The major new feature for this release is the introduction of the qiskit.algorithms and qiskit.opflow modules which were migrated and adapted from the qiskit.aqua project.

##### New Features¶
• The qiskit.pulse.call() function can now take a Parameter object along with a parameterized subroutine. This enables assigning different values to the Parameter objects for each subroutine call.

For example,

from qiskit.circuit import Parameter
from qiskit import pulse

amp = Parameter('amp')

with pulse.build() as subroutine:
pulse.play(pulse.Gaussian(160, amp, 40), DriveChannel(0))

with pulse.build() as main_prog:
pulse.call(subroutine, amp=0.1)
pulse.call(subroutine, amp=0.3)

• The qiskit.providers.models.QasmBackendConfiguration has a new field processor_type which can optionally be used to provide information about a backend's processor in the form: {"family": <str>, "revision": <str>, segment: <str>}. For example: {"family": "Canary", "revision": "1.0", segment: "A"}.

• The qiskit.pulse.Schedule, qiskit.pulse.Instruction, and qiskit.pulse.Channel classes now have a parameter property which will return any Parameter objects used in the object and a is_parameterized() method which will return True if any parameters are used in the object.

For example:

from qiskit.circuit import Parameter
from qiskit import pulse

shift = Parameter('alpha')

schedule = pulse.Schedule()
schedule += pulse.SetFrequency(shift, pulse.DriveChannel(0))

assert schedule.is_parameterized() == True
print(schedule.parameters)

{Parameter(alpha)}

• Added a PiecewiseChebyshev to the qiskit.circuit.library for implementing a piecewise Chebyshev approximation of an input function. For a given function $$f(x)$$ and degree $$d$$, this class class implements a piecewise polynomial Chebyshev approximation on $$n$$ qubits to $$f(x)$$ on the given intervals. All the polynomials in the approximation are of degree $$d$$.

For example:

import numpy as np
from qiskit import QuantumCircuit
from qiskit.circuit.library.arithmetic.piecewise_chebyshev import PiecewiseChebyshev
f_x, degree, breakpoints, num_state_qubits = lambda x: np.arcsin(1 / x), 2, [2, 4], 2
pw_approximation = PiecewiseChebyshev(f_x, degree, breakpoints, num_state_qubits)
pw_approximation._build()
qc = QuantumCircuit(pw_approximation.num_qubits)
qc.h(list(range(num_state_qubits)))
qc.append(pw_approximation.to_instruction(), qc.qubits)
qc.draw(output='mpl')

• The BackendProperties class now has a readout_length() method, which returns the readout length [sec] of the given qubit.

• A new class, ScheduleBlock, has been added to the qiskit.pulse module. This class provides a new representation of a pulse program. This representation is best suited for the pulse builder syntax and is based on relative instruction ordering.

This representation takes alignment_context instead of specifying starting time t0 for each instruction. The start time of instruction is implicitly allocated with the specified transformation and relative position of instructions.

The ScheduleBlock allows for lazy instruction scheduling, meaning we can assign arbitrary parameters to the duration of instructions.

For example:

from qiskit.pulse import ScheduleBlock, DriveChannel, Gaussian
from qiskit.pulse.instructions import Play, Call
from qiskit.pulse.transforms import AlignRight
from qiskit.circuit import Parameter

dur = Parameter('rabi_duration')

block = ScheduleBlock(alignment_context=AlignRight())
block += Play(Gaussian(dur, 0.1, dur/4), DriveChannel(0))
block += Call(measure_sched)  # subroutine defined elsewhere


this code defines an experiment scanning a Gaussian pulse's duration followed by a measurement measure_sched, i.e. a Rabi experiment. You can reuse the block object for every scanned duration by assigning a target duration value.

• Added a new function array_to_latex() to the qiskit.visualization module that can be used to represent and visualize vectors and matrices with LaTeX.

from qiskit.visualization import array_to_latex
from numpy import sqrt, exp, pi
mat = [[0, exp(pi*.75j)],
[1/sqrt(8), 0.875]]
array_to_latex(mat)

$\begin{split}\begin{bmatrix} 0 & \tfrac{1}{\sqrt{2}}(-1 + i) \\ \tfrac{1}{\sqrt{8}} & \tfrac{7}{8} \\ \end{bmatrix} \end{split}$
• The Statevector and DensityMatrix classes now have draw() methods which allow objects to be drawn as either text matrices, IPython Latex objects, Latex source, Q-spheres, Bloch spheres and Hinton plots. By default the output type is the equivalent output from __repr__ but this default can be changed in a user config file by setting the state_drawer option. For example:

from qiskit.quantum_info import DensityMatrix
dm = DensityMatrix.from_label('r0')
dm.draw('latex')

$\begin{split}\begin{bmatrix} \tfrac{1}{2} & 0 & -\tfrac{1}{2}i & 0 \\ 0 & 0 & 0 & 0 \\ \tfrac{1}{2}i & 0 & \tfrac{1}{2} & 0 \\ 0 & 0 & 0 & 0 \\ \end{bmatrix} \end{split}$
from qiskit.quantum_info import Statevector
sv = Statevector.from_label('+r')
sv.draw('qsphere')


Additionally, the draw() method is now used for the ipython display of these classes, so if you change the default output type in a user config file then when a Statevector or a DensityMatrix object are displayed in a jupyter notebook that output type will be used for the object.

• Pulse qiskit.pulse.Instruction objects and parametric pulse objects (eg Gaussian now support using Parameter and ParameterExpression objects for the duration parameter. For example:

from qiskit.circuit import Parameter
from qiskit.pulse import Gaussian

dur = Parameter('x_pulse_duration')
double_dur = dur * 2
rx_pulse = Gaussian(dur, 0.1, dur/4)
double_rx_pulse = Gaussian(double_dir, 0.1, dur/4)


Note that while we can create an instruction with a parameterized duration adding an instruction with unbound parameter duration to a schedule is supported only by the newly introduced representation ScheduleBlock. See the known issues release notes section for more details.

• The run() method for the QasmSimulatorPy, StatevectorSimulatorPy, and UnitarySimulatorPy backends now takes a QuantumCircuit (or a list of QuantumCircuit objects) as its input. The previous QasmQobj object is still supported for now, but will be deprecated in a future release.

For an example of how to use this see:

from qiskit import transpile, QuantumCircuit

from qiskit.providers.basicaer import BasicAer

backend = BasicAer.get_backend('qasm_simulator')

circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()

tqc = transpile(circuit, backend)
result = backend.run(tqc, shots=4096).result()

• The CommutativeCancellation transpiler pass has a new optional kwarg on the constructor basis_gates, which takes the a list of the names of basis gates for the target backend. When specified the pass will only use gates in the basis_gates kwarg. Previously, the pass would automatically replace consecutive gates which commute with ZGate with the U1Gate unconditionally. The basis_gates kwarg enables you to specify which z-rotation gates are present in the target basis to avoid this.

• The constructors of the Bit class and subclasses, Qubit, Clbit, and AncillaQubit, have been updated such that their two parameters, register and index are now optional. This enables the creation of bit objects that are independent of a register.

• A new class, BooleanExpression, has been added to the qiskit.circuit.classicalfunction module. This class allows for creating an oracle from a Python boolean expression. For example:

from qiskit.circuit import BooleanExpression, QuantumCircuit

expression = BooleanExpression('~x & (y | z)')
circuit = QuantumCircuit(4)
circuit.append(expression, [0, 1, 2, 3])
circuit.draw('mpl')

circuit.decompose().draw('mpl')


The BooleanExpression also includes a method, from_dimacs_file(), which allows loading formulas described in the DIMACS-CNF format. For example:

from qiskit.circuit import BooleanExpression, QuantumCircuit

boolean_exp = BooleanExpression.from_dimacs_file("simple_v3_c2.cnf")
circuit = QuantumCircuit(boolean_exp.num_qubits)
circuit.append(boolean_exp, range(boolean_exp.num_qubits))
circuit.draw('text')

     ┌───────────────────┐
q_0: ┤0                  ├
│                   │
q_1: ┤1                  ├
│  SIMPLE_V3_C2.CNF │
q_2: ┤2                  ├
│                   │
q_3: ┤3                  ├
└───────────────────┘

circuit.decompose().draw('text')

q_0: ──o────o────────────
│    │
q_1: ──■────o────■───────
│    │    │
q_2: ──■────┼────o────■──
┌─┴─┐┌─┴─┐┌─┴─┐┌─┴─┐
q_3: ┤ X ├┤ X ├┤ X ├┤ X ├
└───┘└───┘└───┘└───┘

• Added a new class, PhaseOracle, has been added to the qiskit.circuit.library module. This class enables the construction of phase oracle circuits from Python boolean expressions.

from qiskit.circuit.library.phase_oracle import PhaseOracle

oracle = PhaseOracle('x1 & x2 & (not x3)')
oracle.draw('mpl')


These phase oracles can be used as part of a larger algorithm, for example with qiskit.algorithms.AmplificationProblem:

from qiskit.algorithms import AmplificationProblem, Grover
from qiskit import BasicAer

backend = BasicAer.get_backend('qasm_simulator')

problem = AmplificationProblem(oracle, is_good_state=oracle.evaluate_bitstring)
grover = Grover(quantum_instance=backend)
result = grover.amplify(problem)
result.top_measurement

'011'


The PhaseOracle class also includes a from_dimacs_file() method which enables constructing a phase oracle from a file describing a formula in the DIMACS-CNF format.

from qiskit.circuit.library.phase_oracle import PhaseOracle

oracle = PhaseOracle.from_dimacs_file("simple_v3_c2.cnf")
oracle.draw('text')

state_0: ─o───────o──────────────
│ ┌───┐ │ ┌───┐
state_1: ─■─┤ X ├─■─┤ X ├─■──────
│ └───┘   └───┘ │ ┌───┐
state_2: ─■───────────────o─┤ Z ├
└───┘

• All transpiler passes (ie any instances of BasePass) are now directly callable. Calling a pass provides a convenient interface for running the pass on a QuantumCircuit object.

For example, running a single transformation pass, such as BasisTranslator, can be done with:

from qiskit import QuantumCircuit
from qiskit.transpiler.passes import BasisTranslator
from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary as sel

circuit = QuantumCircuit(1)
circuit.h(0)

pass_instance = BasisTranslator(sel, ['rx', 'rz', 'cx'])
result = pass_instance(circuit)
result.draw(output='mpl')


When running an analysis pass, a property set (as dict or as PropertySet) needs to be added as a parameter and it might be modified "in-place". For example:

from qiskit import QuantumCircuit
from qiskit.transpiler.passes import Depth

circuit = QuantumCircuit(1)
circuit.h(0)

property_set = {}
pass_instance = Depth()
pass_instance(circuit, property_set)
print(property_set)

{'depth': 1}

• The QasmQobjConfig class now has an optional kwarg for meas_level and meas_return. These fields can be used to enable generating QasmQobj job payloads that support meas_level=1 (kerneled data) for circuit jobs (previously this was only exposed for PulseQobj objects). The assemble() function has been updated to set this field for QasmQobj objects it generates.

• A new tensor() method has been added to the QuantumCircuit class. This method enables tensoring another circuit with an existing circuit. This method works analogously to qiskit.quantum_info.Operator.tensor() and is consistent with the little-endian convention of Qiskit.

For example:

from qiskit import QuantumCircuit
top = QuantumCircuit(1)
top.x(0);
bottom = QuantumCircuit(2)
bottom.cry(0.2, 0, 1);
bottom.tensor(top).draw(output='mpl')

• The qiskit.circuit.QuantumCircuit class now supports arbitrary free form metadata with the metadata attribute. A user (or program built on top of QuantumCircuit) can attach metadata to a circuit for use in tracking the circuit. For example:

from qiskit.circuit import QuantumCircuit



or:

from qiskit.circuit import QuantumCircuit

qc = QuantumCircuit(2)


This metadata will not be used for influencing the execution of the circuit but is just used for tracking the circuit for the lifetime of the object. The metadata attribute will persist between any circuit transforms including transpile() and assemble(). The expectation is for providers to associate the metadata in the result it returns, so that users can filter results based on circuit metadata the same way they can currently do with QuantumCircuit.name.

• Add a new operator class CNOTDihedral has been added to the qiskit.quantum_info module. This class is used to represent the CNOT-Dihedral group, which is generated by the quantum gates CXGate, TGate, and XGate.

• Adds a & (__and__) binary operator to BaseOperator subclasses (eg qiskit.quantum_info.Operator) in the qiskit.quantum_info module. This is shorthand to call the classes compose() method (ie A & B == A.compose(B)).

For example:

import qiskit.quantum_info as qi

qi.Pauli('X') & qi.Pauli('Y')

• Adds a & (__and__) binary operator to qiskit.quantum_info.Statevector and qiskit.quantum_info.DensityMatrix classes. This is shorthand to call the classes evolve() method (ie psi & U == psi.evolve(U)).

For example:

import qiskit.quantum_info as qi

qi.Statevector.from_label('0') & qi.Pauli('X')

• A new a new 2-qubit gate, ECRGate, the echo cross-resonance (ECR), has been added to the qiskit.circuit.library module along with a corresponding method, ecr() for the QuantumCircuit class. The ECR gate is two $$CR(\frac{π}{4})$$ pulses with an XGate between them for the echo. This gate is locally equivalent to a CXGate (can convert to a CNOT with local pre- or post-rotation). It is the native gate on current IBM hardware and compiling to it allows the pre-/post-rotations to be merged into the rest of the circuit.

• A new kwarg approximation_degree has been added to the transpile() function for enabling approximate compilation. Valid values range from 0 to 1, and higher means less approximation. This is a heuristic dial to experiment with circuit approximations. The concrete interpretation of this number is left to each pass, which may use it to perform some approximate version of the pass. Specific examples include the UnitarySynthesis pass or the or translators to discrete gate sets. If a pass does not support this option, it implies exact transformation.

• Two new transpiler passess, GateDirection and qiskit.transpiler.passes.CheckGateDirection, were added to the qiskit.transpiler.passes module. These new passes are inteded to be more general replacements for CXDirection and CheckCXDirection (which are both now deprecated, see the deprecation notes for more details) that perform the same function but work with other gates beside just CXGate.

• When running on Windows, parallel execution with the parallel_map() function can now be enabled (it is still disabled by default). To do this you can either set parallel = True in a user config file, or set the QISKIT_PARALLEL environment variable to TRUE (this will also effect transpile() and assemble() which both use parallel_map() internally). It is important to note that when enabling parallelism on Windows there are limitations around how Python launches processes for Windows, see the Known Issues section below for more details on the limitations with parallel execution on Windows.

• A new function, hellinger_distance(), for computing the Hellinger distance between two counts distributions has been added to the qiskit.quantum_info module.

• The decompose_clifford() function in the qiskit.quantum_info module (which gets used internally by the qiskit.quantum_info.Clifford.to_circuit() method) has a new kwarg method which enables selecting the synthesis method used by either setting it to 'AG' or 'greedy'. By default for more than three qubits it is set to 'greedy' which uses a non-optimal greedy compilation routine for Clifford elements synthesis, by Bravyi et. al., which typically yields better CX cost compared to the previously used Aaronson-Gottesman method (for more than two qubits). You can use the method kwarg to revert to the previous default Aaronson-Gottesman method by setting method='AG'.

• The Initialize class in the qiskit.extensions module can now be constructed using an integer. The '1' bits of the integer will insert a Reset and an XGate into the circuit for the corresponding qubit. This will be done using the standard little-endian convention is qiskit, ie the rightmost bit of the integer will set qubit 0. For example, setting the parameter in Initialize equal to 5 will set qubits 0 and 2 to value 1.

from qiskit.extensions import Initialize

initialize = Initialize(13)
initialize.definition.draw('mpl')

• The Initialize class in the qiskit.extensions module now supports constructing directly from a Pauli label (analogous to the qiskit.quantum_info.Statevector.from_label() method). The Pauli label refer to basis states of the Pauli eigenstates Z, X, Y. These labels use Qiskit's standard little-endian notation, for example a label of '01' would initialize qubit 0 to $$|1\rangle$$ and qubit 1 to $$|0\rangle$$.

from qiskit.extensions import Initialize

initialize = Initialize("10+-lr")
initialize.definition.draw('mpl')

• The kwarg, template_list, for the constructor of the qiskit.transpiler.passes.TemplateOptimization transpiler pass now supports taking in a list of both QuantumCircuit and DAGDependency objects. Previously, only QuantumCircuit were accepted (which were internally converted to DAGDependency objects) in the input list.

• A new transpiler pass, qiskit.transpiler.passes.RZXCalibrationBuilder, capable of generating calibrations and adding them to a quantum circuit has been introduced. This pass takes calibrated CXGate objects and creates the calibrations for qiskit.circuit.library.RZXGate objects with an arbitrary rotation angle. The schedules are created by stretching and compressing the GaussianSquare pulses of the echoed-cross resonance gates.

• New template circuits for using qiskit.circuit.library.RZXGate are added to the qiskit.circuit.library module (eg rzx_yz). This enables pairing the TemplateOptimization pass with the qiskit.transpiler.passes.RZXCalibrationBuilder pass to automatically find and replace gate sequences, such as CNOT - P(theta) - CNOT, with more efficent circuits based on qiskit.circuit.library.RZXGate with a calibration.

• The matplotlib output type for the circuit_drawer() and the draw() method for the QuantumCircuit class now supports configuration files for setting the visualization style. In previous releases, there was basic functionality that allowed users to pass in a style kwarg that took in a dict to customize the colors and other display features of the mpl drawer. This has now been expanded so that these dictionaries can be loaded from JSON files directly without needing to pass a dictionary. This enables users to create new style files and use that style for visualizations by passing the style filename as a string to the style kwarg.

To leverage this feature you must set the circuit_mpl_style_path option in a user config file. This option should be set to the path you want qiskit to search for style JSON files. If specifying multiple path entries they should be separated by :. For example, setting circuit_mpl_style_path = ~/.qiskit:~/user_styles in a user config file will look for JSON files in both ~/.qiskit and ~/user_styles.

• A new kwarg, format_marginal has been added to the function marginal_counts() which when set to True formats the counts output according to the cregs in the circuit and missing indices are represented with a _. For example:

from qiskit import QuantumCircuit, execute, BasicAer, result
from qiskit.result.utils import marginal_counts
qc = QuantumCircuit(5, 5)
qc.x(0)
qc.measure(0, 0)

result = execute(qc, BasicAer.get_backend('qasm_simulator')).result()
print(marginal_counts(result.get_counts(), [0, 2, 4], format_marginal=True))

{'0_0_1': 1024}

• Improved the performance of qiskit.quantum_info.Statevector.expectation_value() and qiskit.quantum_info.DensityMatrix.expectation_value() when the argument operator is a Pauli or SparsePauliOp operator.

• The user config file has 2 new configuration options, num_processes and parallel, which are used to control the default behavior of parallel_map(). The parallel option is a boolean that is used to dictate whether parallel_map() will run in multiple processes or not. If it set to False calls to parallel_map() will be executed serially, while setting it to True will enable parallel execution. The num_processes option takes an integer which sets how many CPUs to use when executing in parallel. By default it will use the number of CPU cores on a system.

• There are 2 new environment variables, QISKIT_PARALLEL and QISKIT_NUM_PROCS, that can be used to control the default behavior of parallel_map(). The QISKIT_PARALLEL option can be set to the TRUE (any capitalization) to set the default to run in multiple processes when parallel_map() is called. If it is set to any other value parallel_map() will be executed serially. QISKIT_NUM_PROCS takes an integer (for example QISKIT_NUM_PROCS=5) which will be used as the default number of processes to run with. Both of these will take precedence over the equivalent option set in the user config file.

• A new method, gradient(), has been added to the ParameterExpression class. This method is used to evaluate the gradient of a ParameterExpression object.

• The __eq__ method (ie what is called when the == operator is used) for the ParameterExpression now allows for the comparison with a numeric value. Previously, it was only possible to compare two instances of ParameterExpression with ==. For example:

from qiskit.circuit import Parameter

x = Parameter("x")
y = x + 2
y = y.assign(x, -1)

assert y == 1

• The PauliFeatureMap class in the qiskit.circuit.library module now supports adjusting the rotational factor, $$\alpha$$, by either setting using the kwarg alpha on the constructor or setting the alpha attribute after creation. Previously this value was fixed at 2.0. Adjusting this attribute allows for better control of decision boundaries and provides additional flexibility handling the input features without needing to explicitly scale them in the data set.

• A new Gate class, PauliGate, has been added the qiskit.circuit.library module and corresponding method, pauli(), was added to the QuantumCircuit class. This new gate class enables applying several individual pauli gates to different qubits at the simultaneously. This is primarily useful for simulators which can use this new gate to more efficiently implement multiple simultaneous Pauli gates.

• Improve the qiskit.quantum_info.Pauli operator. This class now represents and element from the full N-qubit Pauli group including complex coefficients. It now supports the Operator API methods including compose(), dot(), tensor() etc, where compose and dot are defined with respect to the full Pauli group.

This class also allows conversion to and from the string representation of Pauli's for convenience.

For example

from qiskit.quantum_info import Pauli

P1 = Pauli('XYZ')
P2 = Pauli('YZX')
P1.dot(P2)

Pauli('-iZXY')


Pauli's can also be directly appended to QuantumCircuit objects

from qiskit import QuantumCircuit
from qiskit.quantum_info import Pauli

circ = QuantumCircuit(3)
circ.append(Pauli('XYZ'), [0, 1, 2])
circ.draw(output='mpl')


Additional methods allow computing when two Pauli's commute (using the commutes() method) or anticommute (using the anticommutes() method), and computing the Pauli resulting from Clifford conjugation $$P^\prime = C.P.C^\dagger$$ using the evolve() method.

See the API documentation of the Pauli class for additional information.

• A new function, random_pauli(), for generating a random element of the N-qubit Pauli group has been added to the qiskit.quantum_info module.

• A new class, PiecewisePolynomialPauliRotations, has been added to the qiskit.circuit.library module. This circuit library element is used for mapping a piecewise polynomial function, $$f(x)$$, which is defined through breakpoints and coefficients, on qubit amplitudes. The breakpoints $$(x_0, ..., x_J)$$ are a subset of $$[0, 2^n-1]$$, where $$n$$ is the number of state qubits. The corresponding coefficients $$[a_{j,1},...,a_{j,d}]$$, where $$d$$ is the highest degree among all polynomials. Then $$f(x)$$ is defined as:

$\begin{split}f(x) = \begin{cases} 0, x < x_0 \\ \sum_{i=0}^{i=d}a_{j,i} x^i, x_j \leq x < x_{j+1} \end{cases}\end{split}$

where we implicitly assume $$x_{J+1} = 2^n$$. And the mapping applied to the amplitudes is given by

$F|x\rangle |0\rangle = \cos(p_j(x))|x\rangle |0\rangle + \sin(p_j(x))|x\rangle |1\rangle$

This mapping is based on controlled Pauli Y-rotations and constructed using the PolynomialPauliRotations.

• A new module qiskit.algorithms has been introduced. This module contains functionality equivalent to what has previously been provided by the qiskit.aqua.algorithms module (which is now deprecated) and provides the building blocks for constructing quantum algorithms. For details on migrating from qiskit-aqua to this new module please refer to the migration guide aqua-migration

• A new module qiskit.opflow has been introduced. This module contains functionality equivalent to what has previously been provided by the qiskit.aqua.operators module (which is now deprecated) and provides the operators and state functions which are used to build quantum algorithms. For details on migrating from qiskit-aqua to this new module please refer to the migration guide aqua-migration

• This is the first release that includes precompiled binary wheels for the for Linux aarch64 systems. If you are running a manylinux2014 compatible aarch64 Linux system there are now precompiled wheels available on PyPI, you are no longer required to build from source to install qiskit-terra.

• The qiskit.quantum_info.process_fidelity() function is now able to be used with a non-unitary target channel. In this case the returned value is equivalent to the qiskit.quantum_info.state_fidelity() of the normalized qiskit.quantum_info.Choi matrices for the channels.

Note that the qiskit.quantum_info.average_gate_fidelity() and qiskit.quantum_info.gate_error() functions still require the target channel to be unitary and will raise an exception if it is not.

• Added a new pulse builder function, qiskit.pulse.macro(). This enables normal Python functions to be decorated as macros. This enables pulse builder functions to be used within the decorated function. The builder macro can then be called from within a pulse building context, enabling code reuse.

For Example:

from qiskit import pulse

@pulse.macro
def measure(qubit: int):
pulse.play(pulse.GaussianSquare(16384, 256, 15872),
pulse.MeasureChannel(qubit))
mem_slot = pulse.MemorySlot(0)
pulse.acquire(16384, pulse.AcquireChannel(0), mem_slot)
return mem_slot

with pulse.build(backend=backend) as sched:
mem_slot = measure(0)
print(f"Qubit measured into {mem_slot}")

sched.draw()

• A new class, PauliTwoDesign, was added to the qiskit.circuit.library which implements a particular form of a 2-design circuit from https://arxiv.org/pdf/1803.11173.pdf For instance, this circuit can look like:

from qiskit.circuit.library import PauliTwoDesign
circuit = PauliTwoDesign(4, reps=2, seed=5, insert_barriers=True)
circuit.decompose().draw(output='mpl')

• A new pulse drawer qiskit.visualization.pulse_v2.draw() (which is aliased as qiskit.visualization.pulse_drawer_v2) is now available. This new pulse drawer supports multiple new features not present in the original pulse drawer (pulse_drawer()).

• Truncation of long pulse instructions.

• Visualization of parametric pulses.

• New stylesheets IQXStandard, IQXSimple, IQXDebugging.

• Visualization of system info (channel frequency, etc...) by specifying qiskit.providers.Backend objects for visualization.

• Specifying axis objects for plotting to allow further extension of generated plots, i.e., for publication manipulations.

New stylesheets can take callback functions that dynamically modify the apperance of the output image, for example, reassembling a collection of channels, showing details of instructions, updating appearance of pulse envelopes, etc... You can create custom callback functions and feed them into a stylesheet instance to modify the figure appearance without modifying the drawer code. See pulse drawer module docstrings for details.

Note that file saving is now delegated to Matplotlib. To save image files, you need to call savefig method with returned Figure object.

• Adds a reverse_qargs() method to the qiskit.quantum_info.Statevector and qiskit.quantum_info.DensityMatrix classes. This method reverses the order of subsystems in the states and is equivalent to the qiskit.circuit.QuantumCircuit.reverse_bits() method for N-qubit states. For example:

from qiskit.circuit.library import QFT
from qiskit.quantum_info import Statevector

circ = QFT(3)

state1 = Statevector.from_instruction(circ)
state2 = Statevector.from_instruction(circ.reverse_bits())

state1.reverse_qargs() == state2

True

• Adds a reverse_qargs() method to the qiskit.quantum_info.Operator class. This method reverses the order of subsystems in the operator and is equivalent to the qiskit.circuit.QuantumCircuit.reverse_bits() method for N-qubit operators. For example:

from qiskit.circuit.library import QFT
from qiskit.quantum_info import Operator

circ = QFT(3)

op1 = Operator(circ)
op2 = Operator(circ.reverse_bits())

op1.reverse_qargs() == op2

True

• The latex output method for the qiskit.visualization.circuit_drawer() function and the draw() method now will use a user defined label on gates in the output visualization. For example:

import math

from qiskit.circuit import QuantumCircuit

qc = QuantumCircuit(2)
qc.h(0)
qc.rx(math.pi/2, 0, label='My Special Rotation')

qc.draw(output='latex')

• The routing_method kwarg for the transpile() function now accepts a new option, 'none'. When routing_method='none' no routing pass will be run as part of the transpilation. If the circuit does not fit coupling map a TranspilerError exception will be raised.

• A new gate class, RVGate, was added to the qiskit.circuit.library module along with the corresponding QuantumCircuit method rv(). The RVGate is a general rotation gate, similar to the UGate, but instead of specifying Euler angles the three components of a rotation vector are specified where the direction of the vector specifies the rotation axis and the magnitude specifies the rotation angle about the axis in radians. For example:

import math

import np

from qiskit.circuit import QuantumCircuit

qc = QuantumCircuit(1)
theta = math.pi / 5
phi = math.pi / 3
# RGate axis:
axis = np.array([math.cos(phi), math.sin(phi)])
rotation_vector = theta * axis
qc.rv(*rotation_vector, 0)

• Unbound Parameter objects used in a QuantumCircuit object will now be sorted by name. This will take effect for the parameters returned by the parameters attribute. Additionally, the qiskit.circuit.QuantumCircuit.bind_parameters() and qiskit.circuit.QuantumCircuit.assign_parameters() methods can now take in a list of a values which will bind/assign them to the parameters in name-sorted order. Previously these methods would only take a dictionary of parameters and values. For example:

from qiskit.circuit import QuantumCircuit, Parameter

circuit = QuantumCircuit(1)
circuit.rx(Parameter('x'), 0)
circuit.ry(Parameter('y'), 0)

print(circuit.parameters)

bound = circuit.bind_parameters([1, 2])
bound.draw(output='mpl')

ParameterView([Parameter(x), Parameter(y)])

• The constructors for the qiskit.quantum_info.Statevector and qiskit.quantum_info.DensityMatrix classes can now take a QuantumCircuit object in to build a Statevector and DensityMatrix object from that circuit, assuming that the qubits are initialized in $$|0\rangle$$. For example:

from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector

qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)

statevector = Statevector(qc)
statevector.draw(output='latex')

$\frac{\sqrt{2}}{2} |00\rangle+\frac{\sqrt{2}}{2} |11\rangle$
• New fake backend classes are available under qiskit.test.mock. These included mocked versions of ibmq_casablanca, ibmq_sydney, ibmq_mumbai, ibmq_lima, ibmq_belem, ibmq_quito. As with the other fake backends, these include snapshots of calibration data (i.e. backend.defaults()) and error data (i.e. backend.properties()) taken from the real system, and can be used for local testing, compilation and simulation.

##### Known Issues¶
• Attempting to add an qiskit.pulse.Instruction object with a parameterized duration (ie the value of duration is an unbound Parameter or ParameterExpression object) to a qiskit.pulse.Schedule is not supported. Attempting to do so will result in UnassignedDurationError PulseError being raised. This is a limitation of how the Instruction overlap constraints are evaluated currently. This is supported by ScheduleBlock, in which the overlap constraints are evaluated just before the execution.

• On Windows systems when parallel execution is enabled for parallel_map() parallelism may not work when called from a script running outside of a if __name__ == '__main__': block. This is due to how Python launches parallel processes on Windows. If a RuntimeError or AttributeError are raised by scripts that call parallel_map() (including using functions that use parallel_map() internally like transpile()) with Windows and parallelism enabled you can try embedding the script calls inside if __name__ == '__main__': to workaround the issue. For example:

from qiskit import QuantumCircuit, QiskitError
from qiskit import execute, Aer

qc1 = QuantumCircuit(2, 2)
qc1.h(0)
qc1.cx(0, 1)
qc1.measure([0,1], [0,1])
# making another circuit: superpositions
qc2 = QuantumCircuit(2, 2)
qc2.h([0,1])
qc2.measure([0,1], [0,1])
execute([qc1, qc2], Aer.get_backend('qasm_simulator'))


should be changed to:

from qiskit import QuantumCircuit, QiskitError
from qiskit import execute, Aer

def main():
qc1 = QuantumCircuit(2, 2)
qc1.h(0)
qc1.cx(0, 1)
qc1.measure([0,1], [0,1])
# making another circuit: superpositions
qc2 = QuantumCircuit(2, 2)
qc2.h([0,1])
qc2.measure([0,1], [0,1])
execute([qc1, qc2], Aer.get_backend('qasm_simulator'))

if __name__ == '__main__':
main()


if any errors are encountered with parallelism on Windows.

• The preset pass managers level_1_pass_manager, level_2_pass_manager, and level_3_pass_manager (which are used for optimization_level 1, 2, and 3 in the transpile() and execute() functions) now unconditionally use the Optimize1qGatesDecomposition pass for 1 qubit gate optimization. Previously, these pass managers would use the Optimize1qGates pass if the basis gates contained u1, u2, or u3. If you want to still use the old Optimize1qGates you will need to construct a custom PassManager with the pass.

• Following transpilation of a parameterized QuantumCircuit, the global_phase attribute of output circuit may no longer be returned in a simplified form, if the global phase is a ParameterExpression.

For example:

qc = QuantumCircuit(1)
theta = Parameter('theta')

qc.rz(theta, 0)
qc.rz(-theta, 0)

print(transpile(qc, basis_gates=['p']).global_phase)


previously returned 0, but will now return -0.5*theta + 0.5*theta. This change was necessary was to avoid a large runtime performance penalty as simplifying symbolic expressions can be quite slow, especially if there are many ParameterExpression objects in a circuit.

• The BasicAerJob job objects returned from BasicAer backends are now synchronous instances of JobV1. This means that calls to the run() will block until the simulation finishes executing. If you want to restore the previous async behavior you'll need to wrap the run() with something that will run in a seperate thread or process like futures.ThreadPoolExecutor or futures.ProcessPoolExecutor.

• The allow_sample_measuring option for the BasicAer simulator QasmSimulatorPy has changed from a default of False to True. This was done to better reflect the actual default behavior of the simulator, which would use sample measuring if the input circuit supported it (even if it was not enabled). If you are running a circuit that doesn't support sample measurement (ie it has Reset operations or if there are operations after a measurement on a qubit) you should make sure to explicitly set this option to False when you call run().

• The CommutativeCancellation transpiler pass is now aware of the target basis gates, which means it will only use gates in the specified basis. Previously, the pass would unconditionally replace consecutive gates which commute with ZGate with the U1Gate. However, now that the pass is basis aware and has a kwarg, basis_gates, for specifying the target basis there is a potential change in behavior if the kwarg is not set. When the basis_gates kwarg is not used and there are no variable z-rotation gates in the circuit then no commutative cancellation will occur.

• Register (which is the parent class for QuantumRegister and ClassicalRegister and Bit (which is the parent class for Qubit and Clbit) objects are now immutable. In previous releases it was possible to adjust the value of a size or name attributes of a Register object and the index or register attributes of a Bit object after it was initially created. However this would lead to unsound behavior that would corrupt container structure that rely on a hash (such as a dict) since these attributes are treated as immutable properties of a register or bit (see #4705 for more details). To avoid this unsound behavior this attributes of a Register and Bit are no longer settable after initial creation. If you were previously adjusting the objects at runtime you will now need to create a new Register or Bit object with the new values.

• The DAGCircuit.__eq__ method (which is used by the == operator), which is used to check structural equality of DAGCircuit and QuantumCircuit instances, will now include the global_phase and calibrations attributes in the fields checked for equality. This means that circuits which would have evaluated as equal in prior releases may not anymore if the global_phase or calibrations differ between the circuits. For example, in previous releases this would return True:

import math

from qiskit import QuantumCircuit

qc1 = QuantumCircuit(1)
qc1.x(0)

qc2 = QuantumCircuit(1, global_phase=math.pi)
qc2.x(0)

print(qc2 == qc1)


However, now because the global_phase attribute of the circuits differ this will now return False.

• The previously deprecated qubits() and clbits() methods on the DAGCircuit class, which were deprecated in the 0.15.0 Terra release, have been removed. Instead you should use the qubits and clbits attributes of the DAGCircuit class. For example, if you were running:

from qiskit.dagcircuit import DAGCircuit

dag = DAGCircuit()
qubits = dag.qubits()


That would be replaced by:

from qiskit.dagcircuit import DAGCircuit

dag = DAGCircuit()
qubits = dag.qubits

• The PulseDefaults returned by the fake pulse backends qiskit.test.mock.FakeOpenPulse2Q and qiskit.test.mock.FakeOpenPulse3Q have been updated to have more realistic pulse sequence definitions. If you are using these fake backend classes you may need to update your usage because of these changes.

• The default synthesis method used by decompose_clifford() function in the quantum_info module (which gets used internally by the qiskit.quantum_info.Clifford.to_circuit() method) for more than 3 qubits now uses a non-optimal greedy compilation routine for Clifford elements synthesis, by Bravyi et. al., which typically yields better CX cost compared to the old default. If you need to revert to the previous Aaronson-Gottesman method this can be done by setting method='AG'.

• The previously deprecated module qiskit.visualization.interactive, which was deprecated in the 0.15.0 release, has now been removed. Instead you should use the matplotlib based visualizations:

Removed Interactive function

Equivalent matplotlib function

iplot_bloch_multivector

qiskit.visualization.plot_bloch_multivector()

iplot_state_city

qiskit.visualization.plot_state_city()

iplot_state_qsphere

qiskit.visualization.plot_state_qsphere()

iplot_state_hinton

qiskit.visualization.plot_state_hinton()

iplot_histogram

qiskit.visualization.plot_histogram()

iplot_state_paulivec

qiskit.visualization.plot_state_paulivec()

• The qiskit.Aer and qiskit.IBMQ top level attributes are now lazy loaded. This means that the objects will now always exist and warnings will no longer be raised on import if qiskit-aer or qiskit-ibmq-provider are not installed (or can't be found by Python). If you were checking for the presence of qiskit-aer or qiskit-ibmq-provider using these module attributes and explicitly comparing to None or looking for the absence of the attribute this no longer will work because they are always defined as an object now. In other words running something like:

try:
from qiskit import Aer
except ImportError:
print("Aer not available")

or::

try:
from qiskit import IBMQ
except ImportError:
print("IBMQ not available")


will no longer work. Instead to determine if those providers are present you can either explicitly use qiskit.providers.aer.Aer and qiskit.providers.ibmq.IBMQ:

try:
from qiskit.providers.aer import Aer
except ImportError:
print("Aer not available")

try:
from qiskit.providers.ibmq import IBMQ
except ImportError:
print("IBMQ not available")


or check bool(qiskit.Aer) and bool(qiskit.IBMQ) instead, for example:

import qiskit

if not qiskit.Aer:
print("Aer not available")
if not qiskit.IBMQ:
print("IBMQ not available")


This change was necessary to avoid potential import cycle issues between the qiskit packages and also to improve the import time when Aer or IBMQ are not being used.

• The user config file option suppress_packaging_warnings option in the user config file and the QISKIT_SUPPRESS_PACKAGING_WARNINGS environment variable no longer has any effect and will be silently ignored. The warnings this option controlled have been removed and will no longer be emitted at import time from the qiskit module.

• The previously deprecated condition kwarg for qiskit.dagcircuit.DAGNode constructor has been removed. It was deprecated in the 0.15.0 release. Instead you should now be setting the classical condition on the Instruction object passed into the DAGNode constructor when creating a new op node.

• When creating a new Register (which is the parent class for QuantumRegister and ClassicalRegister) or QuantumCircuit object with a number of bits (eg QuantumCircuit(2)), it is now required that number of bits are specified as an integer or another type which is castable to unambiguous integers(e.g. 2.0). Non-integer values will now raise an error as the intent in those cases was unclear (you can't have fractional bits). For more information on why this was changed refer to: #4855

• networkx is no longer a requirement for qiskit-terra. All the networkx usage inside qiskit-terra has been removed with the exception of 3 methods:

If you are using any of these methods you will need to manually install networkx in your environment to continue using them.

• By default on macOS with Python >=3.8 parallel_map() will no longer run in multiple processes. This is a change from previous releases where the default behavior was that parallel_map() would launch multiple processes. This change was made because with newer versions of macOS with Python 3.8 and 3.9 multiprocessing is either unreliable or adds significant overhead because of the change in Python 3.8 to launch new processes with spawn instead of fork. To re-enable parallel execution on macOS with Python >= 3.8 you can use the user config file parallel option or set the environment variable QISKIT_PARALLEL to True.

• The previously deprecated kwarg callback on the constructor for the PassManager class has been removed. This kwarg has been deprecated since the 0.13.0 release (April, 9th 2020). Instead you can pass the callback kwarg to the qiskit.transpiler.PassManager.run() method directly. For example, if you were using:

from qiskit.circuit.random import random_circuit
from qiskit.transpiler import PassManager

qc = random_circuit(2, 2)

def callback(**kwargs)
print(kwargs['pass_'])

pm = PassManager(callback=callback)
pm.run(qc)


this can be replaced with:

from qiskit.circuit.random import random_circuit
from qiskit.transpiler import PassManager

qc = random_circuit(2, 2)

def callback(**kwargs)
print(kwargs['pass_'])

pm = PassManager()
pm.run(qc, callback=callback)

• It is now no longer possible to instantiate a base channel without a prefix, such as qiskit.pulse.Channel or qiskit.pulse.PulseChannel. These classes are designed to classify types of different user facing channel classes, such as qiskit.pulse.DriveChannel, but do not have a definition as a target resource. If you were previously directly instantiating either qiskit.pulse.Channel or qiskit.pulse.PulseChannel, this is no longer allowed. Please use the appropriate subclass.

• When the require_cp and/or require_tp kwargs of qiskit.quantum_info.process_fidelity(), qiskit.quantum_info.average_gate_fidelity(), qiskit.quantum_info.gate_error() are True, they will now only log a warning rather than the previous behavior of raising a QiskitError exception if the input channel is non-CP or non-TP respectively.

• The QFT class in the qiskit.circuit.library module now computes the Fourier transform using a little-endian representation of tensors, i.e. the state $$|1\rangle$$ maps to $$|0\rangle - |1\rangle + |2\rangle - ..$$ assuming the computational basis correspond to little-endian bit ordering of the integers. $$|0\rangle = |000\rangle, |1\rangle = |001\rangle$$, etc. This was done to make it more consistent with the rest of Qiskit, which uses a little-endian convention for bit order. If you were depending on the previous bit order you can use the reverse_bits() method to revert to the previous behavior. For example:

from qiskit.circuit.library import QFT

qft = QFT(5).reverse_bits()

• The qiskit.__qiskit_version__ module attribute was previously a dict will now return a custom read-only Mapping object that checks the version of qiskit elements at runtime instead of at import time. This was done to speed up the import path of qiskit and eliminate a possible import cycle by only importing the element packages at runtime if the version is needed from the package. This should be fully compatible with the dict previously return and for most normal use cases there will be no difference. However, if some applications were relying on either mutating the contents or explicitly type checking it may require updates to adapt to this change.

• The qiskit.execute module has been renamed to qiskit.execute_function. This was necessary to avoid a potentical name conflict between the execute() function which is re-exported as qiskit.execute. qiskit.execute the function in some situations could conflict with qiskit.execute the module which would lead to a cryptic error because Python was treating qiskit.execute as the module when the intent was to the function or vice versa. The module rename was necessary to avoid this conflict. If you're importing qiskit.execute to get the module (typical usage was from qiskit.execute import execute) you will need to update this to use qiskit.execute_function instead. qiskit.execute will now always resolve to the function.

• The qiskit.compiler.transpile, qiskit.compiler.assemble, qiskit.compiler.schedule, and qiskit.compiler.sequence modules have been renamed to qiskit.compiler.transpiler, qiskit.compiler.assembler, qiskit.compiler.scheduler, and qiskit.compiler.sequence respectively. This was necessary to avoid a potentical name conflict between the modules and the re-exported function paths qiskit.compiler.transpile(), qiskit.compiler.assemble(), qiskit.compiler.schedule(), and qiskit.compiler.sequence(). In some situations this name conflict between the module path and re-exported function path would lead to a cryptic error because Python was treating an import as the module when the intent was to use the function or vice versa. The module rename was necessary to avoid this conflict. If you were using the imports to get the modules before (typical usage would be likefrom qiskit.compiler.transpile import transpile) you will need to update this to use the new module paths. qiskit.compiler.transpile(), qiskit.compiler.assemble(), qiskit.compiler.schedule(), and qiskit.compiler.sequence() will now always resolve to the functions.

• The qiskit.quantum_info.Quaternion class was moved from the qiskit.quantum_info.operator submodule to the qiskit.quantum_info.synthesis submodule to better reflect it's purpose. No change is required if you were importing it from the root qiskit.quantum_info module, but if you were importing from qiskit.quantum_info.operator you will need to update your import path.

• Removed the QuantumCircuit.mcmt method, which has been deprecated since the Qiskit Terra 0.14.0 release in April 2020. Instead of using the method, please use the MCMT class instead to construct a multi-control multi-target gate and use the qiskit.circuit.QuantumCircuit.append() or qiskit.circuit.QuantumCircuit.compose() to add it to a circuit.

For example, you can replace:

circuit.mcmt(ZGate(), [0, 1, 2], [3, 4])


with:

from qiskit.circuit.library import MCMT
mcmt = MCMT(ZGate(), 3, 2)
circuit.compose(mcmt, range(5))

• Removed the QuantumCircuit.diag_gate method which has been deprecated since the Qiskit Terra 0.14.0 release in April 2020. Instead, use the diagonal() method of QuantumCircuit.

• Removed the QuantumCircuit.ucy method which has been deprecated since the Qiskit Terra 0.14.0 release in April 2020. Instead, use the ucry() method of QuantumCircuit.

• The previously deprecated mirror() method for qiskit.circuit.QuantumCircuit has been removed. It was deprecated in the 0.15.0 release. The qiskit.circuit.QuantumCircuit.reverse_ops() method should be used instead since mirroring could be confused with swapping the output qubits of the circuit. The reverse_ops() method only reverses the order of gates that are applied instead of mirroring.

• The previously deprecated support passing a float (for the scale kwarg as the first positional argument to the qiskit.circuit.QuantumCircuit.draw() has been removed. It was deprecated in the 0.12.0 release. The first positional argument to the qiskit.circuit.QuantumCircuit.draw() method is now the output kwarg which does not accept a float. Instead you should be using scale as a named kwarg instead of using it positionally.

For example, if you were previously calling draw with:

from qiskit import QuantumCircuit

qc = QuantumCircuit(2)
qc.draw(0.75, output='mpl')


this would now need to be:

from qiskit import QuantumCircuit

qc = QuantumCircuit(2)
qc.draw(output='mpl', scale=0.75)


or:

qc.draw('mpl', scale=0.75)

• Features of Qiskit Pulse (qiskit.pulse) which were deprecated in the 0.15.0 release (August, 2020) have been removed. The full set of changes are:

Module

Old

New

qiskit.pulse.library

SamplePulse

Waveform

qiskit.pulse.library

ConstantPulse

Constant

(module rename)

pulse.pulse_lib Module

qiskit.pulse.library

Class

Old method

New method

ParametricPulse

get_sample_pulse

get_waveform

Instruction

command

N/A. Commands and Instructions have been unified. Use operands() to get information about the instruction data.

Acquire

acquires, mem_slots, reg_slots

acquire(), mem_slot(), reg_slot(). (The Acquire instruction no longer broadcasts across multiple qubits.)

• The dictionary previously held on DAGCircuit edges has been removed. Instead, edges now hold the Bit instance which had previously been included in the dictionary as its 'wire' field. Note that the NetworkX graph returned by to_networkx() will still have a dictionary for its edge attributes, but the 'name' field will no longer be populated.

• The parameters attribute of the QuantumCircuit class no longer is returning a set. Instead it returns a ParameterView object which implements all the methods that set offers (albeit deprecated). This was done to support a model that preserves name-sorted parameters. It should be fully compatible with any previous usage of the set returned by the parameters attribute, except for where explicit type checking of a set was done.

• When running transpile() on a QuantumCircuit with delay() instructions, the units will be converted to dt if the value of dt (sample time) is known to transpile(), either explicitly via the dt kwarg or via the BackendConfiguration for a Backend object passed in via the backend kwarg.

• The interpretation of meas_map (which is an attribute of a PulseBackendConfiguration object or as the corresponding meas_map kwarg on the schedule(), assemble(), sequence(), or execute() functions) has been updated to better match the true constraints of the hardware. The format of this data is a list of lists, where the items in the inner list are integers specifying qubit labels. For instance:

[[A, B, C], [D, E, F, G]]


Previously, the meas_map constraint was interpreted such that if one qubit was acquired (e.g. A), then all other qubits sharing a subgroup with that qubit (B and C) would have to be acquired at the same time and for the same duration. This constraint has been relaxed. One acquisition does not require more acquisitions. (If A is acquired, B and C do not need to be acquired.) Instead, qubits in the same measurement group cannot be acquired in a partially overlapping way -- think of the meas_map as specifying a shared acquisition resource (If we acquire A from t=1000 to t=2000, we cannot acquire B starting from 1000<t<2000). For example:

# Good
meas_map = [[0, 1]]
# Acquire a subset of [0, 1]
sched = pulse.Schedule()
sched = sched.append(pulse.Acquire(10, acq_q0))

# Acquire 0 and 1 together (same start time, same duration)
sched = pulse.Schedule()
sched = sched.append(pulse.Acquire(10, acq_q0))
sched = sched.append(pulse.Acquire(10, acq_q1))

# Acquire 0 and 1 disjointly
sched = pulse.Schedule()
sched = sched.append(pulse.Acquire(10, acq_q0))
sched = sched.append(pulse.Acquire(10, acq_q1)) << 10

# Acquisitions overlap, but 0 and 1 aren't in the same measurement
# grouping
meas_map = [[0], [1]]
sched = pulse.Schedule()
sched = sched.append(pulse.Acquire(10, acq_q0))
sched = sched.append(pulse.Acquire(10, acq_q1)) << 1

# Bad: 0 and 1 are in the same grouping, but acquisitions
# partially overlap
meas_map = [[0, 1]]
sched = pulse.Schedule()
sched = sched.append(pulse.Acquire(10, acq_q0))
sched = sched.append(pulse.Acquire(10, acq_q1)) << 1

##### Deprecation Notes¶
• Two new arguments have been added to qiskit.dagcircuit.DAGNode.semantic_eq(), bit_indices1 and bit_indices2, which are expected to map the Bit instances in each DAGNode to their index in qubits or clbits list of their respective DAGCircuit. During the deprecation period, these arguments are optional and when not specified the mappings will be automatically constructed based on the register and index properties of each Bit instance. However, in a future release, they will be required arguments and the mapping will need to be supplied by the user.

• The pulse builder functions:

• qiskit.pulse.call_circuit()

• qiskit.pulse.call_schedule()

are deprecated and will be removed in a future release. These functions are unified into qiskit.pulse.call() which should be used instead.

• The qiskit.pulse.Schedule method qiskit.pulse.Schedule.flatten() method is deprecated and will be removed in a future release. Instead you can use the qiskit.pulse.transforms.flatten() function which will perform the same operation.

• The assign_parameters() for the following classes:

• qiskit.pulse.library.Pulse,

and all their subclasses is now deprecated and will be removed in a future release. This functionality has been subsumed ScheduleBlock which is the future direction for constructing parameterized pulse programs.

• The parameters attribute for the following clasess:

is deprecated and will be removed in a future release. This functionality has been subsumed ScheduleBlock which is the future direction for constructing parameterized pulse programs.

• Python 3.6 support has been deprecated and will be removed in a future release. When support is removed you will need to upgrade the Python version you're using to Python 3.7 or above.

• Two QuantumCircuit methods combine() and extend() along with their corresponding Python operators + and += are deprecated and will be removed in a future release. Instead the QuantumCircuit method compose() should be used. The compose() method allows more flexibility in composing two circuits that do not have matching registers. It does not, however, automatically add qubits/clbits unlike the deprecated methods. To add a circuit on new qubits/clbits, the qiskit.circuit.QuantumCircuit.tensor() method can be used. For example:

from qiskit.circuit import QuantumRegister, QuantumCircuit

a = QuantumRegister(2, 'a')
circuit_a = QuantumCircuit(a)
circuit_a.cx(0, 1)

b = QuantumRegister(2, 'b')
circuit_b = QuantumCircuit(b)
circuit_b.cz(0, 1)

# same as circuit_a + circuit_b (or combine)

# same as circuit_a + circuit_a (or combine)

# same as circuit_a += circuit_b (or extend)
circuit_a = circuit_b.tensor(circuit_a)

# same as circuit_a += circuit_a (or extend)
circuit_a.compose(circuit_a, inplace=True)

• Support for passing Qubit instances to the qubits kwarg of the qiskit.transpiler.InstructionDurations.get() method has been deprecated and will be removed in a future release. Instead, you should call the get() method with the integer indices of the desired qubits.

• Using @ (__matmul__) for invoking the compose method of BaseOperator subclasses (eg Operator) is deprecated and will be removed in a future release. The qiskit.quantum_info.Operator.compose() method can be used directly or also invoked using the & (__and__) operator.

• Using * (__mul__) for calling the dot() method of BaseOperator subclasses (eg qiskit.quantum_info.Operator) is deprecated and will be removed in a future release. Instead you can just call the dot() directly.

• Using @ (__matmul__) for invoking the evolve() method of the qiskit.quantum_info.Statevector and qiskit.quantum_info.DensityMatrix classes is deprecated and will be removed in a future release.. The evolve method can be used directly or also invoked using the & (__and__) operator.

• The qiskit.pulse.schedule.ParameterizedSchedule class has been deprecated and will be removed in a future release. Instead you can directly parameterize pulse Schedule objects with a Parameter object, for example:

from qiskit.circuit import Parameter
from qiskit.pulse import Schedule
from qiskit.pulse import ShiftPhase, DriveChannel

theta = Parameter('theta')
target_schedule = Schedule()
target_schedule.insert(0, ShiftPhase(theta, DriveChannel(0)), inplace=True)

• The qiskit.pulse.ScheduleComponent class in the qiskit.pulse module has been deprecated and will be removed in a future release. Its usage should be replaced either using a qiskit.pulse.Schedule or qiskit.pulse.Instruction directly. Additionally, the primary purpose of the ScheduleComponent class was as a common base class for both Schedule and Instruction for any place that was explicitly type checking or documenting accepting a ScheduleComponent input should be updated to accept Instruction or Schedule.

• The JSON Schema files and usage for the IBMQ API payloads are deprecated and will be removed in a future release. This includes everything under the qiskit.schemas module and the qiskit.validation module. This also includes the validate kwargs for qiskit.qobj.QasmQobj.to_dict() and qiskit.qobj.QasmQobj.to_dict() along with the module level fastjsonschema validators in qiskit.qobj (which do not raise a deprecation warning). The schema files have been moved to the Qiskit/ibmq-schemas repository and those should be treated as the canonical versions of the API schemas. Moving forward only those schemas will recieve updates and will be used as the source of truth for the schemas. If you were relying on the schemas bundled in qiskit-terra you should update to use that repository instead.

• The qiskit.util module has been deprecated and will be removed in a future release. It has been replaced by qiskit.utils which provides the same functionality and will be expanded in the future. Note that no DeprecationWarning will be emitted regarding this deprecation since it was not feasible on Python 3.6.

• The CXDirection transpiler pass in the qiskit.transpiler.passes module has been deprecated and will be removed in a future release. Instead the GateDirection should be used. It behaves identically to the CXDirection except that it now also supports transforming a circuit with ECRGate gates in addition to CXGate gates.

• The CheckCXDirection transpiler pass in the qiskit.transpiler.passes module has been deprecated and will be removed in a future release. Instead the CheckGateDirection pass should be used. It behaves identically to the CheckCXDirection except that it now also supports checking the direction of all 2-qubit gates, not just CXGate gates.

• The WeightedAdder method num_ancilla_qubits() is deprecated and will be removed in a future release. It has been replaced with the qiskit.circuit.library.WeightedAdder.num_ancillas attribute which is consistent with other circuit libraries' APIs.

• The following legacy methods of the qiskit.quantum_info.Pauli class have been deprecated. See the method documentation for replacement use in the updated Pauli class.

• Using a list or numpy.ndarray as the channel or target argument for the qiskit.quantum_info.process_fidelity(), qiskit.quantum_info.average_gate_fidelity(), qiskit.quantum_info.gate_error(), and qiskit.quantum_info.diamond_norm() functions has been deprecated and will not be supported in a future release. The inputs should instead be a Gate or a BaseOperator subclass object (eg. Operator, Choi, etc.)

• Accessing references from Qubit and Clbit instances to their containing registers via the register or index properties has been deprecated and will be removed in a future release. Instead, Register objects can be queried to find the Bit objects they contain.

• The current functionality of the qiskit.visualization.pulse_drawer() function is deprecated and will be replaced by qiskit.visualization.pulse_drawer_v2() (which is not backwards compatible) in a future release.

• The use of methods inherited from the set type on the output of the parameters attribute (which used to be a set) of the QuantumCircuit class are deprecated and will be removed in a future release. This includes the methods from the add(), difference(), difference_update(), discard(), intersection(), intersection_update(), issubset(), issuperset(), symmetric_difference(), symmetric_difference_update(), union(), update(), __isub__() (which is the -= operator), and __ixor__() (which is the ^= operator).

• The name of the first (and only) positional argument for the qiskit.circuit.QuantumCircuit.bind_parameters() method has changed from value_dict to values. The passing an argument in with the name values_dict is deprecated and will be removed in future release. For example, if you were previously calling bind_parameters() with a call like: bind_parameters(values_dict={}) this is deprecated and should be replaced by bind_parameters(values={}) or even better just pass the argument positionally bind_parameters({}).

• The name of the first (and only) positional argument for the qiskit.circuit.QuantumCircuit.assign_parameters() method has changed from param_dict to parameters. Passing an argument in with the name param_dict is deprecated and will be removed in future release. For example, if you were previously calling assign_parameters() with a call like: assign_parameters(param_dict={}) this is deprecated and should be replaced by assign_parameters(values={}) or even better just pass the argument positionally assign_parameters({})`.