Skip to main contentIBM Quantum Documentation

Qiskit 0.43 release notes


0.43.3

Terra 0.24.2

Prelude

Qiskit Terra 0.24.2 is a bugfix release, addressing some minor issues identified since the 0.24.1 release.

Upgrade Notes

  • The QPY format version emitted by dump has increased to 8. This new format version adds support for serializing the QuantumCircuit.layout attribute.

Bug Fixes

  • Fixed the deserialization of DiagonalGate instances through QPY. Fixed #10364(opens in a new tab)

  • Fixed an issue with the qs_decomposition() function, which does quantum Shannon decomposition, when it was called on trivial numeric unitaries that do not benefit from this decomposition, an unexpected error was raised. This error has been fixed so that such unitaries are detected and the equivalent circuit is returned. Fixed #10036(opens in a new tab)

  • Fixed an issue in the the BasicSwap class that prevented the BasicSwap.run() method from functioning if the fake_run keyword argument was set to True when the class was instantiated. Fixed #10147(opens in a new tab)

  • Fixed an issue with copying circuits with new-style Clbits and Qubits (bits without registers) where references to these bits from the containing circuit could be broken, causing issues with serialization and circuit visualization. Fixed #10409(opens in a new tab)

  • The CheckMap transpiler pass will no longer spuriously error when dealing with nested conditional structures created by the control-flow builder interface. See #10394(opens in a new tab).

  • Fixed an failure of the Pulse Builder when the context is initialized with BackendV2.

  • Fixed the output of pulse measure() and measure_all() when functions are called with the BackendV2 backend.

  • Fixed the dimensions of the output density matrix from DensityMatrix.partial_transpose() so they match the dimensions of the corresponding input density matrix.

  • Importing qiskit.primitives will no longer cause deprecation warnings stemming from the deprecated qiskit.opflow module. These warnings would have been hidden to users by the default Python filters, but triggered the eager import of opflow, which meant that a subsequent import by a user would not trigger the warnings. Fixed #10245(opens in a new tab)

  • Fixed the OpenQASM 2 output of QuantumCircuit.qasm() when a custom gate object contained a gate with the same name. Ideally this shouldn’t happen for most gates, but complex algorithmic operations like the GroverOperator class could produce such structures accidentally. See #10162(opens in a new tab).

  • Fixed a regression in the LaTeX drawer of QuantumCircuit.draw() when temporary files are placed on a separate filesystem to the working directory. See #10211(opens in a new tab).

  • Fixed an issue with UnitarySynthesis when using the target parameter where circuits with control flow were not properly mapped to the target.

  • Fixed bug in VQD where result.optimal_values was a copy of result.optimal_points. It now returns the corresponding values. Fixed #10263(opens in a new tab)

  • Improved the error messages returned when an attempt to convert a fully bound ParameterExpression into a concrete float or int failed, for example because the expression was naturally a complex number. Fixed #9187(opens in a new tab)

  • Fixed float conversions for ParameterExpression values which had, at some point in their construction history, an imaginary component that had subsequently been cancelled. When using Sympy as a backend, these conversions would usually already have worked. When using Symengine as the backend, these conversions would often fail with type errors, despite the result having been symbolically evaluated to be real, and ParameterExpression.is_real() being true. Fixed #10191(opens in a new tab)

  • Fixed the qpy serialization of QuantumCircuit.layout attribue. Previously, the layout attribute would have been dropped when serializing a circuit to QPY. Fixed #10112(opens in a new tab)

Aer 0.12.2

Prelude

Qiskit Aer 0.12.2 is the second patch release to 0.12.0. This fixes some bugs that have been discovered since the release of 0.12.1.

Upgrade Notes

  • Qiskit Aer now requires CUDA version for GPU simulator to 11.2 or higher. Previously, CUDA 10.1 was the minimum supported version. This change was necessary because of changes in the upstream CUDA ecosystem, including cuQuantum support. To support users running with different versions of CUDA there is now a separate package available for running with CUDA 11: qiskit-aer-gpu-cu11 and using the qiskit-aer-gpu package now requires CUDA 12. If you’re an existing user of the qiskit-aer-gpu package and want to use CUDA 11 you will need to run:

    pip uninstall qiskit-aer-gpu && pip install -U qiskit-aer-gpu-cu11

    to go from the previously CUDA 10.x compatible qiskit-aer-gpu package’s releases to upgrade to the new CUDA 11 compatible package. If you’re running CUDA 12 locally already you can upgrade the qiskit-aer-gpu package as normal.

Bug Fixes

  • If a circuit has conditional and parameters, the circuit was not be correctly simulated because parameter bindings of Aer used wrong positions to apply parameters. This is from a lack of consideration of bfunc operations injected by conditional. With this commit, parameters are set to correct positions with consideration of injected bfun operations.

  • Parameters for global phases were not correctly set in #1814. https://github.com/Qiskit/qiskit-aer/pull/1814(opens in a new tab) Parameter values for global phases were copied to a template circuit and not to actual circuits to be simulated. This commit correctly copies parameter values to circuits to be simulated.

  • Results of backend.run() were not serializable because they include AerCircuits. This commit makes the results serializable by removing AerCircuits from metadata.

  • :meth:QuantumCircuit.save_statevector() does not work if the circuit is generated from OpenQASM3 text because its quantum registers have duplicated qubit instances. With this commit, :meth:QuantumCircuit.save_statevector() uses :data:QuantumCircuit.qubits to get qubits to be saved.

IBM Q Provider 0.20.2

No change.


0.43.2

As a reminder, Qiskit Aer(opens in a new tab)’s inclusion in the qiskit package is deprecated. The next minor version of Qiskit Aer (0.13) will not be included in any release of the qiskit package, and you should immediately begin installing Aer separately by:

pip install qiskit-aer

and importing it as:

import qiskit_aer

Starting from Qiskit 0.44, the command pip install qiskit will no longer install Qiskit Aer, or the obsolete IBM Q Provider that has already been replaced by the new IBM Provider.

Terra 0.24.1

No change

Aer 0.12.1

Prelude

Qiskit Aer 0.12.1 is the first patch release to 0.12.0. This fixes some bugs that have been discovered since the release of 0.12.0.

Known Issues

  • Fix a bug that returns wrong expectation values in Estimator when abelian_grouping=True.

Upgrade Notes

  • Improved performance when the same circuits and multiple parameters are passed to Estimator with approximation=True.

Deprecation Notes

  • Options of meth:~.AerSimulator.run need to use correct types.

Bug Fixes

  • Performance regression due to introduction of AER::Config is fixed. This class has many fields but is frequently copied in AER::Transpile::CircuitOptimization. Originally json_t (former class for configuration) was also frequently copied but it does have entries in most cases and then this copy overhead is not a problem. With this fix, AER::Transpile::CircuitOptimization does not copy AER::Config.

  • When BLAS calls are failed, because omp threads do not handle exceptions, Aer crashes without any error messages. This fix is for omp threads to catch exceptions correctly and then rethrow them outside of omp loops.

  • Previously, parameters for gates are not validate in C++. If parameters are shorter than expected (due to custom gate), segmentaion faults are thrown. This commit adds checks whether parameter lenght is expceted. This commit will fix issues reported in #1612. https://github.com/Qiskit/qiskit-aer/issues/1612(opens in a new tab)

  • Since 0.12.0, parameter values in circuits are temporarily replaced with constant values and parameter values are assigned in C++ library. Therefore, if parameter_binds is specified, simulator returns results with the constnat values as paramter values. With this commit, Aer raises an error if parameter_binds is not specified though circuits have parameters.

  • Available devices and methods are no longer queried when importing Aer.

  • Previously AerSimulator modifies circuit metadata to maintain consistency between input and output of simulation with side effect of unexpected view of metadata from applicatiln in simiulation. This fix avoids using circuit metadata to maintain consistency internaly and then always provides consistent view of metadata to application.

  • Fixed a bug where the variance in metadata in EstimatorResult was complex and now returns float.

  • Fixed a build break to compile Qiskit Aer with cuQuautum support (AER_ENABLE_CUQUANTUM=true). This change does not affect build for CPU and normal GPU binaries.

  • Fixed a bug in from_backend() that raised an error when the backend has no T1 and T2 values (i.e. None) for a qubit in its qubit properties. This commit updates NoiseModel.from_backend() and basic_device_gate_errors() so that they add an identity QuantumError (i.e. effectively no thermal relaxation error) to a qubit with no T1 and T2 values for all gates acting on qubits including the qubit. Fixed #1779(opens in a new tab) and #1815(opens in a new tab).

  • Fix an issue even if the number of qubits is set by a coupling map or device’s configuration, when the simulation method is configured, the number of qubits is overwritten in accordance with the method. Fixed #1769(opens in a new tab)

  • This is fix for library path setting in CMakeLists.txt for cuQuantum SDK. Because the latest cuQuantum includes libraries for CUDA 11.x and 12.x, this fix uses CUDA version returned from FindCUDA to the path of libraries of cuQuantum and cuTENSOR.

  • This is fix for static link libraries of cuQuantum when building with CUQUANTUM_STATIC=true.

  • MPI parallelization was not enabled since we have not used qobj. This fix sets the number of processes and MPI rank correctly.

  • AerCircuit is created from a circuit by iterating its operations while skipping barrier instructions. However, skipping barrier instructions make wrong positionings of parameter bindings. This fix adds barrier() and keeps parametr bindings correct.

  • Aer still supports Qobj as an argument of run() though it was deprecated. However, since 0.12.0, it always fails if no run_options is specified. This fix enables simulation of Qobj without run_options.

  • Since 0.12.0, AerConfig is used for simulation configuration while performing strict type checking for arguments of meth:~.AerSimulator.run. This commit adds casting if argument types are not expected.

  • :meth:QuantumCircuit.initialize() with int value was not processed correctly as reported in #1821 <https://github.com/Qiskit/qiskit-aer/issues/1821(opens in a new tab)>. This commit enables such initialization by decomposing initialize instructions.

  • QuantumCircuit supports parameterization for its global_phase. However, Aer has not allowed such parameterization and failed when transpiler generates parameterized global phases. This commit supports parameterization of global_phase and resolve issues related to https://github.com/Qiskit/qiskit-aer/issues/1795(opens in a new tab), https://github.com/Qiskit/qiskit-aer/issues/1781(opens in a new tab), and https://github.com/Qiskit/qiskit-aer/issues/1798(opens in a new tab).

  • Aer will now use omp_set_max_active_levels() instead of the deprecated omp_set_nested() when compiled against recent versions of OpenMP.

IBM Q Provider 0.20.2

No change.


0.43.1

Terra 0.24.1

Prelude

Qiskit Terra 0.24.1 is the first patch release to 0.24.0. This fixes some bugs that have been discovered since the release of 0.24.0.

Upgrade Notes

Bug Fixes

Aer 0.12.0

No change

IBM Q Provider 0.20.2

No change


0.43.0

Terra 0.24.0

Prelude

This is a major feature release that includes numerous new features and bugfixes.

This release is the final release with support for running Qiskit with Python 3.7. Starting in the next minor version release Python >=3.8 will be required to run Qiskit.

The highlights of this release:

QuantumInstance, OpFlow, and algorithms usage deprecation

This release officially deprecates the QuantumInstance class (and its associated helper methods and classes), the qiskit.opflow module, and any usage of those in qiskit.algorithms. This deprecation comes from a long thread of work that started in Qiskit Terra 0.21.0 to refactor the qiskit.algorithms module to be based on the computational primitives. There are associated migration guides for any existing users to migrate to the new workflow:

OpenQASM2 improvements

This release includes a major refactoring for the OpenQASM 2.0 support in Qiskit. The first change is the introduction of a new parser for OpenQASM 2.0 in the qiskit.qasm2 module. This new module replaces the existing qiskit.qasm module. The new parser is more explicit and correct with respect to the language specification. It is also implemented in Rust and is significantly faster than the previous parser. Paired with the new parser the OpenQASM 2.0 exporter underwent a large refactor that improved the correctness of the output when using the QuantumCircuit.qasm() method to generate QASM output from a QuantumCircuit object.

Transpiler support for devices with disjoint connectivity

The transpiler now supports targeting backends with disjoint connectivity. Previously, the transpiler only supported backends which were fully connected (where there is a path to run operations between all pairs of qubits in the backend). Now, if a backend has disconnected connectivity the transpiler is able to reason about how to apply layout (Layout Stage) and routing (Routing Stage) for the backend. If the input circuit is not able to be executed on the hardware given the lack of connectivity between connected components, a descriptive error will be returned.

For example, the Heron device outlined in IBM Quantum’s hardware roadmap(opens in a new tab) describes a future backend which will have shared control hardware and real-time classical communication between separate quantum processors. This support enables the Target to accurately model these types of future devices or other hardware with similar constraints.

Switch Operation

This release adds a new control flow operation, the switch statement. This is implemented using a new operation class SwitchCaseOp and the QuantumCircuit.switch() method. This allows switching on a numeric input (such as a classical register or bit) and executing the circuit that corresponds to the matching value.

New Features

  • Added the functions add_deprecation_to_docstring(), deprecate_arg(), and deprecate_func() to the qiskit.utils module.

    add_deprecation_to_docstring() will rewrite the function’s docstring to include a Sphinx .. deprecated:: directive so that the deprecation shows up in docs and with help(). The deprecation decorators from qiskit.utils call add_deprecation_to_docstring() already for you; but you can call it directly if you are using different mechanisms for deprecations.

    @deprecate_func replaces @deprecate_function and is used to deprecate an entire function. It will auto-generate most of the deprecation message for you.

    @deprecate_arg replaces @deprecate_arguments and is used to deprecate an argument on a function. It will generate a more useful message than the previous function. It is also more flexible, for example it allows setting a predicate so that you only deprecate certain situations, such as using a deprecated value or data type.

Transpiler Features
  • Added an alternative way to specify in HLSConfig the list of synthesis methods used for a given high-level object. As before, a synthesis method can be specified as a tuple consisting of the name of the method and additional arguments. Additionally, a synthesis method can be specified as a tuple consisting of an instance of HighLevelSynthesisPlugin and additional arguments. Moreover, when there are no additional arguments, a synthesis method can be specified simply by name or by an instance of HighLevelSynthesisPlugin. The following example illustrates the new functionality:

    from qiskit import QuantumCircuit
    from qiskit.circuit.library.generalized_gates import PermutationGate
    from qiskit.transpiler import PassManager
    from qiskit.transpiler.passes.synthesis.high_level_synthesis import HLSConfig, HighLevelSynthesis
    from qiskit.transpiler.passes.synthesis.high_level_synthesis import ACGSynthesisPermutation
     
    qc = QuantumCircuit(6)
    qc.append(PermutationGate([1, 2, 3, 0]), [1, 2, 3, 4])
     
    # All of the ways to specify hls_config are equivalent
    hls_config = HLSConfig(permutation=[("acg", {})])
    hls_config = HLSConfig(permutation=["acg"])
    hls_config = HLSConfig(permutation=[(ACGSynthesisPermutation(), {})])
    hls_config = HLSConfig(permutation=[ACGSynthesisPermutation()])
     
    # The hls_config can then be passed as an argument to HighLevelSynthesis
    pm = PassManager(HighLevelSynthesis(hls_config=hls_config))
    qc_synthesized = pm.run(qc)
  • Added support to the CouplingMap object to have a disjoint connectivity. Previously, a CouplingMap could only be constructed if the graph was connected. This will enable using CouplingMap to represent hardware with disjoint qubits, such as hardware with qubits on multiple separate chips.

  • Added a new method CouplingMap.connected_components() which is used to get a list of CouplingMap component subgraphs for a disjoint CouplingMap. If the CouplingMap object is connected this will just return a single CouplingMap equivalent to the original.

  • Added new rules to the built-in EquivalenceLibrary instance: qiskit.circuit.equivalence_library.SessionEquivalenceLibrary. The new rules added are:

  • Added high-level-synthesis plugins for LinearFunction and for qiskit.quantum_info.Clifford, extending the set of synthesis methods that can be called from HighLevelSynthesis transpiler pass.

    For LinearFunction the available plugins are listed below:

    Plugin nameHigh-level synthesis plugin
    defaultDefaultSynthesisLinearFunction
    kmsKMSSynthesisLinearFunction
    pmhPMHSynthesisLinearFunction

    For qiskit.quantum_info.Clifford the available plugins are listed below:

    Plugin nameHigh-level synthesis plugin
    defaultDefaultSynthesisClifford
    agAGSynthesisClifford
    bmBMSynthesisClifford
    greedyGreedySynthesisClifford
    layersLayerSynthesisClifford
    lnnLayerLnnSynthesisClifford

    Please refer to qiskit.synthesis documentation for more information about each individual method.

    The following example illustrates some of the new plugins:

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.library import LinearFunction
    from qiskit.quantum_info import Clifford
    from qiskit.transpiler.passes.synthesis.high_level_synthesis import HLSConfig, HighLevelSynthesis
     
    # Create a quantum circuit with one linear function and one clifford
    qc1 = QuantumCircuit(3)
    qc1.cx(0, 1)
    qc1.swap(0, 2)
    lin_fun = LinearFunction(qc1)
     
    qc2 = QuantumCircuit(3)
    qc2.h(0)
    qc2.cx(0, 2)
    cliff = Clifford(qc2)
     
    qc = QuantumCircuit(4)
    qc.append(lin_fun, [0, 1, 2])
    qc.append(cliff, [1, 2, 3])
     
    # Choose synthesis methods that adhere to linear-nearest-neighbour connectivity
    hls_config = HLSConfig(linear_function=["kms"], clifford=["lnn"])
     
    # Synthesize
    qct = HighLevelSynthesis(hls_config)(qc)
    print(qct.decompose())
  • Added a new transpiler pass, MinimumPoint which is used primarily as a pass to check a loop condition in a PassManager. This pass will track the state of fields in the property set over its past executions and set a boolean field when either a fixed point is reached over the backtracking depth or selecting the minimum value found if the backtracking depth is reached. This is an alternative to the FixedPoint which simply checks for a fixed value in a property set field between subsequent executions.

  • Added a new method, swap_nodes(), to the DAGCircuit to allow swapping nodes which are partially connected. Partially connected here means that the two nodes share at least one edge (which represents a qubit or clbit). If the nodes do not share any edges a DAGCircuitError is raised.

  • Add a new synthesis algorithm synth_cz_depth_line_mr() of a CZ circuit for linear nearest neighbor (LNN) connectivity in 2-qubit depth of 2n+2 using CX and phase gates (S, Sdg or Z). The synthesized circuit reverts the order of the qubits. The synthesis algorithm is based on the paper of Maslov and Roetteler (https://arxiv.org/abs/1705.09176(opens in a new tab)).

  • Add a new synthesis algorithm synth_clifford_depth_lnn() of a Clifford circuit for LNN connectivity in 2-qubit depth of 9n+4 (which is still not optimal), using the layered Clifford synthesis (synth_clifford_layers()), synth_cnot_depth_line_kms() to synthesize the CX layer in depth 5n, and synth_cz_depth_line_mr() to synthesize each of the CZ layers in depth 2n+2. This PR will be followed by another PR based on the recent paper of Maslov and Yang (https://arxiv.org/abs/2210.16195(opens in a new tab)), that synthesizes the CX-CZ layers in depth 5n for LNN connectivity and performs further optimization, and hence reduces the depth of a Clifford circuit to 7n-4 for LNN connectivity.

  • Equivalences between the controlled Pauli rotations and translations to two-Pauli rotations are now available in the equivalence library for Qiskit standard gates. This allows, for example, to translate a CRZGate to a RZZGate plus RZGate or a CRYGate to a single RZXGate plus single qubit gates:

    from qiskit.circuit import QuantumCircuit
    from qiskit.compiler import transpile
     
    angle = 0.123
    circuit = QuantumCircuit(2)
    circuit.cry(angle, 0, 1)
     
    basis = ["id", "sx", "x", "rz", "rzx"]
    transpiled = transpile(circuit, basis_gates=basis)
    print(transpiled.draw())
  • Added a new option, copy_operations, to circuit_to_dag() to enable optionally disabling deep copying the operations from the input QuantumCircuit to the output QuantumCircuit. In cases where the input :class`~.QuantumCircuit` is not used anymore after conversion this deep copying is unnecessary overhead as any shared references wouldn’t have any potential unwanted side effects if the input QuantumCircuit is discarded.

  • Added a new option, copy_operations, to dag_to_circuit() to enable optionally disabling deep copying the operations from the input DAGCircuit to the output QuantumCircuit. In cases where the input DAGCircuit is not used anymore after conversion this deep copying is unnecessary overhead as any shared references wouldn’t have any potential unwanted side effects if the input DAGCircuit is discarded.

  • Added a new function passmanager_stage_plugins() to the qiskit.transpiler.preset_passmanagers.plugin module. This function is used to obtain a mapping from plugin names to their their class type. This enables identifying and querying any defined pass manager stage plugin’s documentation. For example:

    >>> from qiskit.transpiler.preset_passmanagers.plugin import passmanager_stage_plugins
    >>> passmanager_stage_plugins('routing')['lookahead'].__class__
     
    qiskit.transpiler.preset_passmanagers.builtin_plugins.LookaheadSwapPassManager
     
    >>> help(passmanager_stage_plugins('routing')['lookahead'])
    Help on BasicSwapPassManager in module qiskit.transpiler.preset_passmanagers.builtin_plugins object:
     
    class BasicSwapPassManager(qiskit.transpiler.preset_passmanagers.plugin.PassManagerStagePlugin)
    |  Plugin class for routing stage with :class:`~.BasicSwap`
    ...
  • The transpiler pass Error now also accepts callable inputs for its msg parameter. If used these input callables will be passed the property_set attribute of the pass and are expected to return a string which will be used for the error message when the pass is run. For example:

    from qiskit.transpiler.passes import Error
     
    def error_message(property_set):
     
        size = property_set["size']
        return f"The circuit size is: {size}"
     
    error_pass = Error(error_message)

    When error_pass is included in a pass manager it will error using the message "The circuit size is: n" where n is the circuit size set in the property set (typically from the previous execution of the Size pass).

  • The build_coupling_map() method has a new keyword argument, filter_idle_qubits which when set to True will remove any qubits from the output CouplingMap that don’t support any operations.

  • The GateDirection transpiler pass can now correctly handle SwapGate instances that may be present in the circuit when executing on a circuit. In these cases if the swap gate’s qubit arguments are on the non-native direction of an edge, the pass will flip the argument order.

  • The RZXCalibrationBuilder and RZXCalibrationBuilderNoEcho transpiler passes now will correctly use an ECRGate for the entangling gate if the backend’s native entangling gate is ECRGate. Previously, the passes would only function correctly if the entangling gate was CXGate.

  • Added a new constructor for the Target class, Target.from_configuration(), which lets you construct a Target object from the separate object types for describing the constraints of a backend (e.g. basis gates, CouplingMap, BackendProperties, etc). For example:

    target = Target.from_configuration(
        basis_gates=["u", "cx", "measure"],
        coupling_map=CouplingMap.from_line(25),
    )

    This will construct a Target object that has UGate, CXGate, and Measure globally available on 25 qubits which are connected in a line.

  • Added a new function synth_cnot_phase_aam() which is used to synthesize cnot phase circuits for all-to-all architectures using the Amy, Azimzadeh, and Mosca method. This function is identical to the available qiskit.transpiler.synthesis.graysynth() function but has a more descriptive name and is more logically placed in the package tree. This new function supersedes the legacy function which will likely be deprecated in a future release.

  • Internal tweaks to the routing algorithm in SabreSwap, used in transpilation of non-dynamic circuits at all non-zero optimization levels, have sped up routing for very large circuits. For example, the time to route a depth-5 QuantumVolume circuit for a 1081-qubit heavy-hex coupling map is approximately halved.

  • The runtime performance of the Optimize1qGatesDecomposition transpiler pass has been significantly improved. This was done by both rewriting all the computation for the pass in Rust and also decreasing the amount of intermediate objects created as part of the pass’s execution. This should also correspond to a similar improvement in the runtime performance of transpile() with the optimization_level keyword argument set to 1, 2, or 3.

  • Add a new synthesis method synth_stabilizer_layers() of a stabilizer state into layers. It provides a similar decomposition to the synthesis described in Lemma 8 of Bravyi and Maslov, (arxiv:2003.09412) without the initial Hadamard-free sub-circuit which does not affect the stabilizer state.

  • Add a new synthesis method synth_stabilizer_lnn() of a stabilizer state for linear nearest neighbor connectivity in 2-qubit depth of 2n+2 and two distinct CX layers, using CX and phase gates (S, Sdg or Z). The synthesis algorithm is based on the paper of Maslov and Roetteler (https://arxiv.org/abs/1705.09176(opens in a new tab)).

  • The SabreLayout pass now supports running against a target with a disjoint CouplingMap. When targeting a disjoint coupling the input DAGCircuit is split into its connected components of virtual qubits, each component is mapped to the connected components of the CouplingMap, layout is run on each connected component in isolation, and then all layouts are combined and returned. Note when the routing_pass argument is set the pass doesn’t support running with disjoint connectivity.

  • The following layout and routing transpiler passes from the qiskit.transpiler.passes modules now will support accepting a Target object which is used to model the constraints of a target backend via the first positional argument (currently named either coupling_map or backend_properties).

    The list of passes with the new support for Target input are:

  • The pass manager construction helper function generate_embed_passmanager() will now also accept a Target for it’s sole positional argument (currently named coupling_map). This can be used to construct a layout embedding PassManager from a Target object instead of from a CouplingMap.

  • The following layout and routing transpiler passes from the qiskit.transpiler.passes modules have a new keyword argument, target which takes in a Target object which is used to model the constraints of a target backend. If the target keyword argument is specified it will be used as the source of truth for any hardware constraints used in the operation of the transpiler pass. It will supersede any other arguments for specifying hardware constraints, typically those arguments which take a CouplingMap, InstructionScheduleMap or a basis gate list. The list of these passes with the new target argument are:

  • The pass manager construction helper function generate_scheduling() has a new keyword argument target which is used to specify a Target object to model the constraints of the target backend being compiled for when generating a new PassManager. If specified this new argument will supersede the other argument inst_map.

  • The default plugin used by the UnitarySynthesis transpiler pass now chooses one and two-qubit unitary synthesis based on the error rates reported in the Target. In particular, it runs all possible synthesis methods supported by the plugin and chooses the option which will result in the lowest error. For a one-qubit decomposition, it can target Pauli basis (e.g. RZ-RX-RZ or RZ-RY-RZ), generic unitary basis (e.g. U), and a few others. For a two-qubit decomposition, it can target any supercontrolled basis (e.g. CNOT, iSWAP, B) or multiple controlled basis (e.g. CZ, CH, ZZ^.5, ZX^.2, etc.).

  • The interface for UnitarySynthesisPlugin has two new optional properties supports_gate_lengths_by_qubit and supports_gate_errors_by_qubit which when set will add the fields gate_lengths_by_qubit and gate_errors_by_qubit respectively to the input options to the plugin’s run() method. These new fields are an alternative view of the data provided by gate_lengths and gate_errors but instead have the form: {(qubits,): [Gate, length]} (where Gate is the instance of Gate for that definition). This allows plugins to reason about working with gates of the same type but but that have different parameters set.

  • Added a new transpiler pass, UnrollForLoops, which is used to unroll any ForLoopOp operations in a circuit. This pass unrolls for-loops when possible, if there are no ContinueLoopOp or BreakLoopOp inside the body block of the loop. For example:

    from qiskit.transpiler.passes import UnrollForLoops
    from qiskit import QuantumCircuit
     
    unroll_pass = UnrollForLoops()
     
    qc = QuantumCircuit(1)
    # For loop over range 5
    with qc.for_loop(range(5)) as i:
        qc.rx(i, 0)
    # Unroll loop into 5 rx gates
    unroll_pass(qc).draw("mpl")
    _images/legacy_release_notes-1.png
  • Added a new parameter max_trials to pass VF2PostLayout which, when specified, limits the number of layouts discovered and compared when searching for the best layout. This differs from existing parameters call_limit and time_limit (which are used to limit the number of state visits performed by the VF2 algorithm and the total time spent by pass VF2PostLayout, respectively) in that it is used to place an upper bound on the time spent scoring potential layouts, which may be useful for larger devices.

  • The CheckMap transpiler pass has a new keyword argument on its constructor, property_set_field. This argument can be used to specify a field in the property set to store the results of the analysis. Previously, it was only possible to store the result in the field "is_swap_mapped" (which is the default). This enables you to store the result of multiple instances of the pass in a PassManager in different fields.

Circuits Features
  • Added a new gate class, GlobalPhaseGate, which can be used to add a global phase on the QuantumCircuit instance.

  • Added a new attribute, layout, to the QuantumCircuit class. This attribute is typically populated by transpile() or PassManager.run() (when the Layout Stage and Routing Stage are run in the PassManager) and contains a TranspileLayout which contains the information about the permutation of the input circuit during transpile().

  • Added a new argument, var_order, to the PhaseOracle class’s constructor to enable setting the order in which the variables in the logical expression are being considered. For example:

    from qiskit.tools.visualization import plot_histogram
    from qiskit.primitives import Sampler
    from qiskit.circuit.library import PhaseOracle
    from qiskit.algorithms import Grover, AmplificationProblem
     
    oracle = PhaseOracle('((A & C) | (B & D)) & ~(C & D)', var_order=['A', 'B', 'C', 'D'])
    problem = AmplificationProblem(oracle=oracle, is_good_state=oracle.evaluate_bitstring)
    grover = Grover(sampler=Sampler())
    result = grover.amplify(problem)
    print(result.circuit_results[0])
  • A new OpenQASM 2 parser is available in qiskit.qasm2. This has two entry points: qasm2.load() and qasm2.loads(), for reading the source code from a file and from a string, respectively:

    import qiskit.qasm2
    program = """
      OPENQASM 2.0;
      include "qelib1.inc";
      qreg q[2];
      h q[0];
      cx q[0], q[1];
    """
    bell = qiskit.qasm2.loads(program)

    This new parser is approximately 10x faster than the existing ones at QuantumCircuit.from_qasm_file() and QuantumCircuit.from_qasm_str() for large files, and has less overhead on each call as well. The new parser is more extensible, customisable and generally also more type-safe; it will not attempt to output custom Qiskit objects when the definition in the OpenQASM 2 file clashes with the Qiskit object, unlike the current exporter. See the qiskit.qasm2 module documentation for full details and more examples.

  • Improve the decomposition of multi-controlled Pauli-X and Pauli-Y rotations with QuantumCircuit.mcrx() and QuantumCircuit.mcry on :math:`n() controls to 16n4016n - 40 CX gates, for n4n \geq 4. This improvement is based on arXiv:2302.06377(opens in a new tab).

  • Qiskit now supports the representation of switch statements, using the new SwitchCaseOp instruction and the QuantumCircuit.switch() method. This allows switching on a numeric input (such as a classical register or bit) and executing the circuit that corresponds to the matching value. Multiple values can point to the same circuit, and CASE_DEFAULT can be used as an always-matching label.

    You can also use a builder interface, similar to the other control-flow constructs to build up these switch statements:

    from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
     
    qreg = QuantumRegister(2)
    creg = ClassicalRegister(2)
    qc = QuantumCircuit(qreg, creg)
     
    qc.h([0, 1])
    qc.measure([0, 1], [0, 1])
    with qc.switch(creg) as case:
      with case(0):  # if the register is '00'
        qc.z(0)
      with case(1, 2):  # if the register is '01' or '10'
        qc.cx(0, 1)
      with case(case.DEFAULT):  # the default case
        qc.h(0)

    The switch statement has support throughout the Qiskit compiler stack; you can transpile() circuits containing it (if the backend advertises its support for the construct), and it will serialize to QPY.

    The switch statement is not currently a feature of OpenQASM 3, but it is under active design and consideration(opens in a new tab), which is expected to be adopted in the near future. Qiskit Terra has experimental support for exporting this statement to the OpenQASM 3 syntax proposed in the linked pull request, using an experimental feature flag. To export a switch statement circuit (such as the one created above) to OpenQASM 3 using this speculative support, do:

    from qiskit import qasm3
     
    qasm3.dumps(qc, experimental=qasm3.ExperimentalFeatures.SWITCH_CASE_V1)
Algorithms Features
  • Added a new attribute eigenvalue_threshold to the AdaptVQE class for configuring a new kind of threshold to terminate the algorithm once the eigenvalue changes less than a set value.

  • Added a new attribute gradient_threshold to the AdaptVQE class which will replace the threshold in the future. This new attribute behaves the same as the existing threshold attribute but has a more accurate name, given the introduction of additional threshold options in the class.

  • Added the EstimationProblem.has_good_state attribute, which allows to check whether an EstimationProblem has a custom EstimationProblem.is_good_state or if it is the default. This is useful for checks in amplitude estimators, such as AmplitudeEstimation, which only support the default implementation.

  • Adds a flag local to the ComputeUncompute state fidelity class that allows to compute the local fidelity, which is defined by averaging over single-qubit projectors.

  • Gradient classes rearrange the gradient result according to the order of the input parameters now.

    Example:

    from qiskit.algorithms.gradients import ParamShiftEstimatorGradient
    from qiskit.circuit import QuantumCircuit, Parameter
    from qiskit.primitives import Estimator
    from qiskit.quantum_info import SparsePauliOp
     
    # Create a circuit with a parameter
    p = {i: Parameter(f'p{i}') for i in range(3)}
    qc = QuantumCircuit(1)
    qc.rx(p[0], 0)
    qc.ry(p[1], 0)
    qc.rz(p[2], 0)
    op = SparsePauliOp.from_list([("Z", 1)])
    param_values = [0.1, 0.2, 0.3]
     
    # Create a gradient object
    estimator = Estimator()
    grad = ParamShiftEstimatorGradient(estimator)
    result = grad.run(qc, op, [param_values]).result()
    # would produce a gradient of the form [df/dp0, df/dp1, df/dp2]
    result = grad.run(qc, op, [param_values], parameters=[[p[2], p[0]]]).result()
    # would produce a gradient of the form [df/dp2, df/dp0]
  • Added support for handling time-dependent Hamiltonians (i.e. singly parametrized operators) to the TrotterQRTE class. To facilitate working with this, added the num_timesteps attribute and a matching keyword argument to the TrotterQRTE constructor to control the number of time steps to divide the full evolution.

  • Added support for observable evaluations at every time-step during the execution of the TrotterQRTE class. The TimeEvolutionProblem.aux_operators is evaluated at every time step if the ProductFormula.reps attribute of the input product_formula argument in the constructor is set to 1.

  • Added extensions to the VQD algorithm, which allow to pass a list of optimizers and initial points for the different minimization runs. For example, the k-th initial point and k-th optimizer will be used for the optimization of the k-1-th exicted state.

Quantum Information Features
  • Added two new constructor methods, Clifford.from_matrix() and Clifford.from_operator(), that create a Clifford object from its unitary matrix and operator representation respectively.

  • The constructor of Clifford now can take any Clifford gate object up to 3 qubits as long it implements a to_matrix method, including parameterized gates such as Rz(pi/2), which were not convertible before.

  • Added new utility functions: commutator(), anti_commutator(), and double_commutator() which are used to compute commutators for any object implementing the LinearOp abstract base class such as QuantumChannel, SparsePauliOp, or ScalarOp.

  • Added the method StabilizerState.equiv, that checks if the generating sets of two stabilizer states generate the same stabilizer group. For example, the stabilizer group of the two-qubit Bell state contains the four elements {II,XX,YY,ZZ}\{II, XX, -YY, ZZ\} and hence can be generated by either [XX,ZZ][XX, ZZ], [XX,YY][XX, -YY] or [YY,ZZ][-YY, ZZ].

  • Added a new method, partial_transpose(), to the qiskit.quantum_info module’s DensityMatrix class. This method is used to compute the partial transposition of a density matrix, which is necessary for detecting entanglement between bipartite quantum systems.

  • Added a method qiskit.quantum_info.Operator.apply_permutation() that pre-composes or post-composes an Operator with a Permutation. This method works for general qudits.

    Here is an example to calculate P.O.PP^\dagger.O.P which reorders Operator’s bits:

    import numpy as np
    from qiskit.quantum_info.operators import Operator
     
    op = Operator(np.array(range(576)).reshape((24, 24)), input_dims=(2, 3, 4), output_dims=(2, 3, 4))
    perm = [1, 2, 0]
    inv_perm = [2, 0, 1]
    conjugate_op = op.apply_permutation(inv_perm, front=True).apply_permutation(perm, front=False)

    The conjugate operator has dimensions (4, 2, 3) x (4, 2, 3), which is consistent with permutation moving qutrit to position 0, qubit to position 1, and the 4-qudit to position 2.

  • Natively support the construction of SparsePauliOp objects with ParameterExpression coefficients, without requiring the explicit construction of an object-array. Now the following is supported:

    from qiskit.circuit import Parameter
    from qiskit.quantum_info import SparsePauliOp
     
    x = Parameter("x")
    op = SparsePauliOp(["Z", "X"], coeffs=[1, x])
  • Added the SparsePauliOp.assign_parameters() method and SparsePauliOp.parameters attribute to assign and query unbound parameters inside a SparsePauliOp. This function can for example be used as:

    from qiskit.circuit import Parameter
    from qiskit.quantum_info import SparsePauliOp
     
    x = Parameter("x")
    op = SparsePauliOp(["Z", "X"], coeffs=[1, x])
     
    # free_params will be: ParameterView([x])
    free_params = op.parameters
     
    # assign the value 2 to the parameter x
    bound = op.assign_parameters([2])
Pulse Features
  • Added new SymbolicPulse classes to the pulse library (qiskit.pulse.library) The new pulses in the library are:

    These new classes are instances of ScalableSymbolicPulse. With the exception of the Sawtooth phase, behavior is identical to that of the corresponding waveform generator function (e.g. sin()). The phase for the Sawtooth class is defined such that a phase of 2π2\pi shifts by a full cycle.

  • Added support to QPY (qiskit.qpy) for working with pulse ScheduleBlock instances with unassigned references, and preserving the data structure for the reference to subroutines. This feature allows users to serialize and deserialize a template pulse program for tasks such as pulse calibration. For example:

    from qiskit import pulse
    from qiskit import qpy
     
    with pulse.build() as schedule:
        pulse.reference("cr45p", "q0", "q1")
        pulse.reference("x", "q0")
        pulse.reference("cr45p", "q0", "q1")
     
    with open('template_ecr.qpy', 'wb') as fd:
        qpy.dump(schedule, fd)
  • A new method CalibrationEntry.user_provided() has been added to calibration entries. This method can be called to check whether the entry is defined by an end user or backend.

  • Added a new method Target.get_calibration() which provides convenient access to the calibration of an instruction in a Target object This method can be called with parameter args and kwargs, and it returns a pulse schedule built with parameters when the calibration is templated with parameters.

Providers Features
  • The BackendV2Converter class has a new keyword argument, filter_faulty, on its constructor. When this argument is set to True the converter class will filter out any qubits or operations listed as non-operational in the BackendProperties payload for the input BackendV1. While not extensively used a BackendProperties object supports annotating both qubits and gates as being non-operational. Previously, if a backend had set that flag on any qubits or gates the output BackendV2 instance and its Target would include all operations whether they were listed as operational or not. By leveraging the new flag you can filter out these non-operational qubits and gates from the Target. When the flag is set the output backend will still be listed as the full width (e.g. a 24 qubit backend with 4 qubits listed as not operational will still show it has 24 qubits) but the faulty qubits will not have any operations listed as being supported in the Target.

  • The Options class now implements the the Mapping protocol and __setitem__ method. This means that Options instances now offer the same interface as standard dictionaries, except for the deletion methods (__delitem__, pop, clear). Key assignments are validated by the validators, if any are registered.

Visualization Features
  • Added a new function, staged_pass_manager_drawer(), which is used for visualizing a StagedPassManager instance. It draws the full pass manager with each stage represented as an outer box.

    For example:

    from qiskit.visualization import staged_pass_manager_drawer
    from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
    from qiskit.providers.fake_provider import FakeSherbrooke
     
    backend = FakeSherbrooke()
    pm = generate_preset_pass_manager(3, backend)
    staged_pass_manager_drawer(pm)
  • The StagedPassManager.draw() method has been updated to include visualization of the stages in addition to the overall pass manager. The stages are represented by outer boxes in the visualization. In previous releases the stages were not included in the visualization. For example:

    from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
    from qiskit.providers.fake_provider import FakeSherbrooke
     
    backend = FakeSherbrooke()
    pm = generate_preset_pass_manager(3, backend)
    pm.draw(pm)
  • Added a new keyword argument, figsize, to the plot_bloch_multivector() function. This argument can be used to set a size for individual Bloch sphere sub-plots. For example, if there are nn qubits and figsize is set to (w, h), then the overall figure width is set to nwn \cdot w, while the overall height is set to hh.

  • Added a new keyword argument, font_size, to the plot_bloch_multivector() function. This argument can be used to control the font size in the output visualization.

  • Added two new keyword arguments, title_font_size and title_pad, to the plot_bloch_multivector() function. These arguments can be used to control the font size of the overall title and its padding respectively.

Upgrade Notes

  • The minimum supported Rust version (MSRV) has been increased from 1.56.1 to 1.61.0. If you’re are building Qiskit from source you will now need to ensure that you have at least Rust 1.61.0 installed to be able to build Qiskit. This change was made because several upstream dependencies have increased their MSRVs.

  • Removed the usage of primitives with the context manager and the initialization with circuits, (observables only for Estimator), and parameters which was deprecated in the Qiskit Terra 0.22.0 release in October 2022.

  • PrimitiveJob.submit() no longer blocks on execution finishing. As a result, Sampler.run(), BackendSampler.run(), Estimator.run() and BaseEstimator.run() do not block until PrimitiveJob.result() method is called.

Transpiler Upgrade Notes
  • The maximum number of trials evaluated when searching for the best layout using VF2Layout and VF2PostLayout is now limited in level_1_pass_manager(), level_2_pass_manager(), and level_3_pass_manager() to 2 500, 25 000, and 250 000, respectively. Previously, all found possible layouts were evaluated. This change was made to prevent transpilation from hanging during layout scoring for circuits with many connected components on larger devices, which scales combinatorially since each connected component would be evaluated in all possible positions on the device. To perform a full search as before, manually run VF2PostLayout over the transpiled circuit in strict mode, specifying 0 for max_trials.

  • The previously deprecated condition attribute of the DAGDepNode class has been removed. It was marked as deprecated in the 0.18 release (07-2021). Instead you should use the condition attribute of the op attribute to access the condition of an operation node. For other node types there is no condition to access.

  • The default value of metadata in both DAGCircuit and DAGDependency has been changed from None to {} for compatibility with the matching metadata attribute of QuantumCircuit.

  • The CouplingMap.__eq__`() method has been updated to check that the edge lists of the underlying graphs contain the same elements. Under the assumption that the underlying graphs are connected, this check additionally ensures that the graphs have the same number of nodes with the same labels. Any code using CouplingMap() == CouplingMap() to check object equality should be updated to CouplingMap() is CouplingMap().

  • When running the transpile() function with a BackendV1 based backend or a BackendProperties via the backend_properties keyword argument that has any qubits or gates flagged as faulty the function will no longer try to automatically remap the qubits based on this information. The method by which transpile() attempted to do this remapping was fundamentally flawed and in most cases of such a backend it would result an internal error being raised. In practice very few backends ever set the fields in BackendProperties to flag a qubit or gate as faulty. If you were relying on transpile() to do this re-mapping for you, you will now need to manually do that and pass a mapped input to the coupling_map and backend_properties arguments which has filtered out the faulty qubits and gates and then manually re-map the output.

  • The result of transpilations for fixed seeds may have changed compared to previous versions of Qiskit Terra. This is because of internal tweaks to the routing algorithm used by SabreSwap and SabreLayout, which are the default routing and layout passes respectively, to make them significantly faster for large circuits.

Circuits Upgrade Notes
  • The QuantumCircuit metadata attribute now always returns a dictionary, and can only be set to a dictionary. Previously, its default value was None, and could be manually set to None or a dictionary.
Algorithms Upgrade Notes
Pulse Upgrade Notes
  • Target.update_from_instruction_schedule_map() no longer raises KeyError nor ValueError when qubits are missing in the target instruction or inst_name_map is not provided for the undefined instruction. In the former case, it just ignores the input InstructionScheduleMap's definition for undefined qubits. In the latter case, a gate mapping is pulled from the standard Qiskit gates and finally, a custom opaque Gate object is defined from the schedule name if no mapping is found.
Providers Upgrade Notes
  • The deprecated max_credits argument to execute(), assemble() and all of the Qobj configurations (e.g. QasmQobjConfig and PulseQobjConfig) has been removed. This argument dates back to early versions of Qiskit which was tied more closely to the IBM Quantum service offering. At that time the max_credits field was part of the “credit system” used by IBM Quantum’s service offering. However, that credit system has not been in use on IBM Quantum backends for nearly three years and also Qiskit is not tied to IBM Quantum’s service offerings anymore (and hasn’t been for a long time). If you were relying on this option in some way for a backend you will need to ensure that your BackendV2 implementation exposes a max_credits field in its Options object.

  • The name attribute on the BackendV2 based fake backend classes in qiskit.providers.fake_provider have changed from earlier releases. Previously, the names had a suffix "_v2" to differentiate the class from the BackendV1 version. This suffix has been removed as having the suffix could lead to inconsistencies with other snapshotted data used to construct the backend object.

Deprecation Notes

Transpiler Deprecations
  • The transpiler routing pass, BIPMapping has been deprecated and will be removed in a future release. It has been replaced by an external plugin package: qiskit-bip-mapper. Details for this new package can be found at the package’s github repository:

    https://github.com/qiskit-community/qiskit-bip-mapper(opens in a new tab)

    The pass was made into a separate plugin package for two reasons, first the dependency on CPLEX makes it harder to use and secondly the plugin packge more cleanly integrates with transpile().

  • Misspelled aquire_alignment in the class Target has been replaced by correct spelling acquire_alignment. The old constructor argument aquire_alignment and Target.aquire_alignment are deprecated and will be removed in a future release. Use Target.acquire_alignment instead to get and set the alignment constraint value.

Circuits Deprecations
  • Setting the QuantumCircuit metadata attribute to None has been deprecated and will no longer be supported in a future release. Instead, users should set it to an empty dictionary if they want it to contain no data.
Algorithms Deprecations
Quantum Information Deprecations
  • The PauliTable and StabilizerTable are deprecated and will be removed in a future release. Instead, the PauliList should be used. With this change, table() has been deprecated so that you should operate directly from tableau() without it.
Pulse Deprecations
  • Assignment of complex values to ParameterExpression in any Qiskit Pulse object now raises a PendingDeprecationWarning. This will align the Pulse module with other modules where such assignment wasn’t possible to begin with. The typical use case for complex parameters in the module was the SymbolicPulse library. As of Qiskit-Terra 0.23.0 all library pulses were converted from complex amplitude representation to real representation using two floats (amp,angle), as used in the ScalableSymbolicPulse class. This eliminated the need for complex parameters. Any use of complex parameters (and particularly custom-built pulses) should be converted in a similar fashion to avoid the use of complex parameters.

Bug Fixes

  • The AmplitudeEstimation class now correctly warns if an EstimationProblem with a set is_good_state property is passed as input, as it is not supported and ignored. Previously, the algorithm would silently ignore this option leading to unexpected results.

  • QuantumCircuit.append() will now correctly raise an error if given an incorrect number of classical bits to apply to an operation. Fix #9385(opens in a new tab).

  • The BarrierBeforeFinalMeasurements and MergeAdjacentBarriers transpiler passes previously had a non-deterministic order of their emitted Barrier instructions. This did not change the semantics of circuits but could, in limited cases where there were non-full-width barriers, cause later stochastic transpiler passes to see a different topological ordering of the circuit and consequently have different outputs for fixed seeds. The passes have been made deterministic to avoid this.

  • The return type of run() will now always be the same as that of its first argument. Passing a single circuit returns a single circuit, passing a list of circuits, even of length 1, returns a list of circuits. See #9798(opens in a new tab).

  • Fixed a bug where PauliOp.adjoint() did not return a correct value for Paulis with complex coefficients, like PauliOp(Pauli("iX")). Fixed #9433(opens in a new tab).

  • Fixed an issue with the circuit drawer function circuit_drawer() and QuantumCircuit.draw() method when displaying instruction parameters that type QuantumCircuit which would result in an illegible drawing. Fixed #9908(opens in a new tab)

  • Fixed an issue with the circuit drawer function circuit_drawer() and QuantumCircuit.draw() method when using the text method and the argument vertical_compression="low" where it would use an incorrect character for the top-right corner of boxes used to represent gates in the circuit.

  • Fixed an issue with the Gate.control() method where it previously would incorrectly handle str or None input types for the ctrl_state argument.

  • Fixed an edge case in the construction of Pauli instances; a string with an optional phase and no qubits is now a valid label, making an operator with no qubits (such as Pauli("-i")). This was already possible when using the array forms, or empty slices. Fixed #9720(opens in a new tab).

  • Fixed an issue when using the pulse macro measure() when working with a BackendV2 based backend. Previously, trying to use qiskit.pulse.macros.measure() with a BackendV2 based backend would have resulted in an error. Fixed #9488(opens in a new tab)

  • Fixed an issue with the marginal_distribution() function where it would incorrectly raise an error when an input counts dictionary was using a numpy integer type instead of the Python int type. The underlying function always would handle the different types correctly, but the input type checking was previously incorrectly raising a TypeError in this case.

  • Fixed a bug where Parameter.is_real() did not return None when the parameter is not bound. Fixed #8619(opens in a new tab).

  • Circuits containing C3SXGate can now be output and read in again safely from the OpenQASM 2.0 exporter (QuantumCircuit.qasm()) and parser (QuantumCircuit.from_qasm_str()).

  • Fixed a bug in QPY (qiskit.qpy) where circuits containing gates of class MCXGate, MCXGrayCode, and MCXRecursive, and MCXVChain would fail to serialize. See #9390(opens in a new tab).

  • Fixed the transpiler routing passes StochasticSwap, SabreSwap, LookaheadSwap, and BasicSwap so that they consistently raise a TranspilerError when their respective .run() method is called if the passes were initialized with coupling_map=None. Previously, these passes would raise errors in this case but they were all caused by side effects and the specific exception was not predictable. Fixed #7127(opens in a new tab)

  • Manually setting an item in QuantumCircuit.data will now correctly allow the operation to be any object that implements Operation, not just a circuit.Instruction. Note that any manual mutation of QuantumCircuit.data is discouraged; it is not usually any more efficient than building a new circuit object, as checking the invariants surrounding parametrised objects can be surprisingly expensive.

  • Fixed a bug when constructing DAGDependency from within the TemplateOptimization transpiler pass, which could lead to incorrect optimizations.

  • Fixed a bug in TensoredOp.to_matrix() where the global coefficient of the operator was multiplied to the final matrix more than once. Now, the global coefficient is correclty applied, independent of the number of tensored operators or states. Fixed #9398(opens in a new tab).

  • Fixed global-phase handling in the UnrollCustomDefinitions transpiler pass if the instruction in question had a global phase, but no instructions in its definition field.

  • Fixed the the type annotations for the transpile() function. The return type is now narrowed correctly depending on whether a single circuit or a list of circuits was passed.

  • Fixed a bug where IterativePhaseEstimation was generating the wrong circuit, causing the algorithm to fail for simple cases. Fixed #9280(opens in a new tab).

  • A bug has been fixed which had allowed broadcasting when a PauliList is initialized from Paulis or labels. For instance, the code PauliList(["XXX", "Z"]) now raises a ValueError rather than constructing the equivalent of PauliList(["XXX", "ZZZ"]).

  • The OpenQASM 2 exporter (QuantumCircuit.qasm()) will no longer emit duplicate definitions for gates that appear in other gates’ definitions. See #7771(opens in a new tab), #8086(opens in a new tab), #8402(opens in a new tab), #8558(opens in a new tab), and #9805(opens in a new tab).

  • The OpenQASM 2 exporter (QuantumCircuit.qasm()) will now handle multiple and nested definitions of UnitaryGate. See #4623(opens in a new tab), #6712(opens in a new tab), #7772(opens in a new tab), and #8222(opens in a new tab).

  • The OpenQASM 2 exporter (QuantumCircuit.qasm()) will now output definitions for gates used only in other gates’ definitions in a correct order. See #7769(opens in a new tab) and #7773(opens in a new tab).

  • Standard gates defined by Qiskit, such as RZXGate, will now have properly parametrised definitions when exported using the OpenQASM 2 exporter (QuantumCircuit.qasm()). See #7172(opens in a new tab).

  • Quantum volume circuits (QuantumVolume) are now supported by the OpenQASM 2 exporter (QuantumCircuit.qasm()). See #6466(opens in a new tab) and #7051(opens in a new tab).

  • The OpenQASM 2 exporter will now output gates with no known definition with opaque statements, rather than failing. See #5036(opens in a new tab).

  • An issue that prevented transpile() from working when passed a list of CouplingMap objects was fixed. Note that passing such a list of coupling maps is deprecated and will not be possible starting with Qiskit Terra 0.25. Fixes #9885(opens in a new tab).

  • Previous to this release, the figsize argument of plot_bloch_multivector() was not used by the visualization, making it impossible to change its size (e.g. to shrink it for single-qubit states). This release fixes it by introducing a use for the figsize argument.

  • Fixed an issue in transpile() with optimization_level=1 (as well as in the preset pass managers returned by generate_preset_pass_manager() and level_1_pass_manager()) where previously if the routing_method and layout_method arguments were not set and no control flow operations were present in the circuit then in cases where routing was required the VF2PostLayout transpiler pass would not be run. This was the opposite of the expected behavior because VF2PostLayout is intended to find a potentially better performing layout after a heuristic layout pass and routing are run. Fixed #9936(opens in a new tab)

  • Construction of a Statevector from a QuantumCircuit containing zero-qubit operations will no longer raise an error. These operations impart a global phase on the resulting statevector.

  • Fixed an issue in tranpiler passes for padding delays, which did not respect target’s constraints and inserted delays even for qubits not supporting Delay instruction. PadDelay and PadDynamicalDecoupling are fixed so that they do not pad any idle time of qubits such that the target does not support Delay instructions for the qubits. Also legacy scheduling passes ASAPSchedule and ALAPSchedule, which pad delays internally, are fixed in the same way. In addition, transpile() is fixed to call PadDelay with a target object so that it works correctly when called with scheduling_method option. Fixed #9993(opens in a new tab)

  • Fixed the type annotations on the QuantumCircuit.assign_parameters() method to correctly reflect the change in return type depending on the value of the inplace argument.

  • Fixed a performance scaling issue with the VF2Layout and VF2PostLayout passes in the preset pass managers and transpile(), which would occur when transpiling circuits with many connected components on large devices. Now the transpiler passes set upper bounds on the number of potential layouts that will be evaluated.

  • Fixed an issue in the state_to_latex() function where it would potentially produce invalid LaTeX due to unintended coefficient rounding. This could also result in errors when the state_drawer() was called. Fixed #9297(opens in a new tab).

Aer 0.12.0

No change

IBM Q Provider 0.20.2

No change

Was this page helpful?