Release News: Qiskit v0.39.0 is Here!

Abby Mitchell
Published in
6 min readOct 14, 2022

By Abby Mitchell, Luciano Bello, Kevin Krsulich, Matthew Treinish, Stefan Wörner, and Elena Peña Tapia

Today, we’re excited to announce that Qiskit v0.39.0 has been released! Read on for a summary of the key highlights, and as always, you can see the full release notes here.


The biggest updates we’re going to cover in this article include the following:

  • Custom transpiler stages are now supported with a new plugin interface.
  • Foundational work has been done in the algorithms module to support Primitives (qiskit.primitives) in the future.
  • Transpiler passes (optimization level 0 and 1) now support dynamic circuits.
  • Performance improvement for the SabreSwap transpiler pass using Rust.
  • Qiskit Aer has been moved to a new namespace in preparation for removal from the Qiskit metapackage.
  • Shor() and HHL() classes are deprecated from the algorithms module.
  • There is a breaking change in the transpiler (optimization level 3) where approximation_degree=1.0 is the new default setting (instead of approximation_degree=None as before).

Top New Features and Improvements

Here we’ll cover some of the most important new features and enhancements included in this release. If you want to know more about these, or other features that didn’t make it into the article, you can see the full list of new features here.

Custom Transpiler Stages using External Plugins

Since Qiskit 0.38.0 users have been able to adapt transpiler passes using the StagedPassManager with default pre-defined stages init, layout, routing, translation, optimization and scheduling.

The latest 0.39.0 version of Qiskit now extends this feature to enable users to provide stages to the passmanager from external plugins. Whether you’ve found an open-source transpiler plugin or created your own from scratch, you can now integrate this into your workflow faster than you can say transpilation!

For example, let’s say you want to use the open-source plugin routing method qiskit-toqm.Integrating this is as simple as installing it (pip install qiskit-toqm) and updating your routing_method argument like so:

from qiskit.compiler import transpiletranspile(…, routing_method="toqm", optimization_level=2, …)

If you want to create your own custom plugin, Qiskit includes some built-in plugins that you can use as a guide to write your own (see qiskit/transpiler/preset_passmanagers/, as well as extensive documentation on how to write plugins.

By creating your own custom plugin, this means that if you develop a new routing method or a new optimization, you can plug it into Qiskit without needing to integrate it into the Qiskit codebase itself. Creating an open-source custom plugin is now the recommended way to integrate your own research into Qiskit.

In addition, if you decide to open-source your custom plugin (which we highly recommend you do!) we invite you to submit an application to add it to the Qiskit Ecosystem!

Algorithms now support Primitives

If you are not already familiar with them, Primitives (qiskit.primitives) are predefined programs that provide a simplified interface for executing workloads efficiently on quantum systems. They allow backends to provide higher levels of abstractions than a count object and can be provided by a provider (such as qiskit-aer or qiskit-ibm-runtime). Alternatively, if a given backend does not support them, Qiskit Terra provides wrappers for traditional count objects (seeBackendSampler and BackendEstimator).

In this release, a significant proportion of the algorithms module has been enhanced to support the Estimator and Sampler primitives.

The most prominent enhancements include:

  • A standard VQE implementation using the Estimator primitive
  • A gradients submodule with 8 different gradient classes using either the Estimator or Sampler primitives.
  • A QAOA implementation using the Sampler primitive
  • A State Fidelity interface including a range of state fidelity classes using the Sampler primitive

The following example illustrates how you can start using VQE with the Estimator() primitive:

from qiskit.algorithms.minimum_eigensolvers import VQE
from qiskit.algorithms.optimizers import SPSA
from qiskit.circuit.library import RealAmplitudes
from qiskit.primitives import Estimator
from qiskit.quantum_info import SparsePauliOp

op = SparsePauliOp(["ZZ", "XX"])

vqe = VQE(Estimator(), RealAmplitudes(), SPSA())
result = vqe.compute_minimum_eigenvalue(op)

Dynamic Circuit Support in the Transpiler

The transpilation optimization levels 0 and 1 have been enhanced to support dynamic circuits. So if a backend supports control flow instructions (such as Qiskit Aer, that supports for_loop, if_else and while_loop) then the transpiler passes will now recursively run in any control flow blocks.

So, given a circuit with a conditional, where one of the branches can be optimized with transpilation, then the transpiler is able to support that conditional instruction and optimize the block. For example, let’s say we have a circuit with some control flow instructions like this:

from qiskit import QuantumCircuitqc = QuantumCircuit(2, 1)
qc.measure(0, 0)
# if classical bit is True, add an X and Y gate on q1, if False add # a Y gate on q0with qc.if_test((0, True)) as else_:
with else_:
print(qc)> output:
q_0: ┤ H ├┤M├┤0 ├
└───┘└╥┘│ │
q_1: ──────╫─┤1 If_else ├
║ │ │
c: ══════╩═╡0 ╞

Before this release you would not have been able to transpile the if_else block, but now you can! 🎉

from qiskit import transpile
from qiskit_aer import AerSimulator
transpiled = transpile(qc, AerSimulator())print(transpiled)> output:
global phase: 3π/2
0: ──────────
1: ┤ U1(-π) ├
0: ══════════

SabreSwap Performance Improvements

The SabreSwap transpiler pass has been refactored using Rust, resulting in a reduction in transpilation time. In addition, this pass now trials multiple seeds in parallel and uses the best performing output, providing better quality results (such as fewer swaps being inserted).

Users can continue to use the pass exactly the same way as before, but should notice a significant performance improvement. In fact, due to this improvement, the SabreSwap pass is now set as the default pass for optimization level 1 and 2, instead of StochasticSwap.

The following graph provides a comparison of overall performance in terms of transpilation speed, before and after switching the default to SabreSwap:

comparison of transpiler performance in Qiskit Terra v0.21.2 (pre SabreSwap refactor) compared to v0.22.0 (incl. SabreSwap refactor)

New Deprecations

Here we’ll cover some of the most important new deprecations in this release. This section aims to highlight things that will now start throwing deprecation warnings and will be removed in a later release. For guidance on how to deal with deprecation warnings, check out the deprecations section in our previous article here. You can see more detail about these deprecations here.

Qiskit Aer

Don’t panic! Qiskit Aer itself is NOT being deprecated, it is just being removed from the Qiskit metapackage.

Previously, if users ran pip install qiskit you would get Qiskit Terra, IBMQ Provider and Qiskit Aer installed by default. But some time in 2023 Qiskit Aer will be removed from the metapackage, at which point pip install qiskit will not install Qiskit Aer anymore.

Instead, users can continue to install Qiskit Aer by running pip install qiskit_aer , which is the recommended method for installation going forward. And consequently, the recommended way of using Qiskit Aer in your development work is by importing it straight from its namespace: from qiskit_aer import Aer

Shor and HHL Algorithm Classes

The Shor() and HHL() classes are deprecated and will be removed in a future release. Going forward it is recommended to construct these algorithms from scratch. Detailed explanations for implementing these algorithms can be found in the Qiskit Textbook in the following sections on Shor’s Algorithm and the HHL Algorithm.

Breaking Changes

In this section we’ll highlight any changes that could cause user’s existing code to break when updating to this latest version, such as deprecated classes/functions that have now been removed.

approximation_degree default set to 1.0 in transpiler

Previously the approximation_degree argument in the transpiler (optimization level 3) had a default setting of None , but this has now been changed to default 1.0 to prevent users unintentionally breaking unitary equivalence when using the transpiler. Going forward, transformations that intentionally break unitary equivalence need to be explicitly activated by the user by setting approximation_degree to signal the internals pass a circuit approximation tolerance (where 1.0=no approximation and 0.0 or None=max approximation up to the backend’s error rate).

And there you have it! The most important details of the latest release. Remember if you want to put ideas forward for future versions of Qiskit you can always open a GitHub issue to request a feature or report a bug! And if you want to follow what’s coming up in the next release (as well as releases for other Qiskit packages) you can take a look at the Qiskit Release Planning Wiki.



Abby Mitchell
Editor for

I’m a Quantum Developer Advocate at IBM. I’m particularly passionate about Quantum Computing and encouraging women to pursue careers in technology.