Qiskit SDK 1.2 release notes
1.2.4
Prelude
Qiskit 1.2.4 is a patch release that fixes a QPY problem introduced in the yanked 1.2.3 bugfix release. In 1.2.3, an error would be raised when loading a QPY file that was generated with a different symengine version from the version installed when loading.
Bug Fixes
- Fixed an issue introduced in the now yanked 1.2.3 bugfix release that would cause an exception with the error message “Qiskit doesn’t support loading a symengine payload generated with symengine >= 1.0” to be raised whenever loading a QPY file that was generated with a different symengine version from the version installed when loading. This issue could only occur in 1.2.3.
1.2.3
Prelude
Qiskit 1.2.3 is a patch release fixing a problem in QPY that could cause files generated by one Python environment to fail to load in a different Python environment, despite the format supposedly being transferable. This is related to differences in the version of the library symengine, which QPY should have protected against.
Known Issues
-
Versions of Qiskit before 1.2.4 will not be able to load QPY files dumped using
qpy.dump(), even withversionset appropriately, if:- there are unbound
ParameterExpressionobjects in the QPY file, - the
use_symengine=Trueflag was set (which is the default in Qiskit >= 1.0.0) inqpy.dump(), and - the version of
symengineinstalled in the generating and loading environments are not within the same minor version.
This applies regardless of the version of Qiskit used in the generation (at least up to Qiskit 1.2.4 inclusive).
If you want to maximize compatibility with versions of Qiskit < 1.2.3, you should set
use_symengine=False. Versions of Qiskit >= 1.2.3 should not require this. - there are unbound
-
QPY files from the Qiskit 0.45 series can, under a very specific and unlikely set of circumstances, fail to load with any newer version of Qiskit, including Qiskit 1.2.4. The criteria are:
- the
QuantumCircuitorScheduleBlockto be dumped contained unboundParameterExpressionobjects, - the installed version of
symenginewas in the 0.9 series (which was the most recent release during the support window of Qiskit 0.45), and - the
use_symengine=Trueflag was set (which was not the default).
Later versions of Qiskit used during generation are not affected, because they required newer versions than
symengine0.9.In this case, you can recover the QPY file by reloading it with an environment with Qiskit 0.45.3 and
symengine0.9.2 installed. Then, useqpy.dump()withuse_symengine=Falseto re-export the file. This will then be readable by any newer version of Qiskit. - the
Upgrade Notes
- The supported versions of symengine have been pre-emptively capped at < 0.14.0 (which is expected to be the next minor version, as of this release of Qiskit). This has been done to protect against a potential incompatibility in
qpywhen serializingParameterExpressionobjects. The serialization used in QPY Format versions 10, 11, and 12 forParameterExpressionobjects is tied to the symengine version used to generate it, and there is the potential for a future symengine release to not be compatible. This upper version cap is to prevent a future release of symengine causing incompatibilities when trying to load QPY files usingqpy.load().
Bug Fixes
-
Fixed an issue with
qpy.load()when loading a QPY file containing aParameterExpression, if the versions ofsymengineinstalled in the generating and loading environments were not the same. For example, if a QPY file containingParameterExpressionobjects was generated using Qiskit 1.2.2 withsymengine==0.11.0installed, Qiskit 1.2.2 withsymengine==0.13.0installed would be unable to load it.Previously, an error would have been raised by
symenginearound this version mismatch. This has been worked around forsymengine0.11 and 0.13 (there was no 0.12). However, if you’re trying to use different versions ofsymengineand there is a mismatch, this version of Qiskit still might not work.
1.2.2
Prelude
Qiskit 1.2.2 is a minor bugfix release for the 1.2 series.
Bug Fixes
-
Fixed a bug in the transpiler pass
ElidePermutationswhere the qubit mapping was not updated correctly in the presence ofPermutationGates. -
Fixed a potential source of non-determinism in
DenseLayout(and by extensionSabreLayout) when targeting aCouplingMaporTargetthat has more than one subgraph with the same degree of connectivity. In these case the exact output layout from the pass could previously fluctuate based on the number of local CPUs and thread execution speed. -
The
HighLevelSynthesistranspiler pass no longer raises an exception when encountering a custom gate that is called “qft” but is not an instance ofQFTGate. Instead, the synthesis plugins for QFT gates ignore such a gate, and the gate’s definition is used (if provided). -
Fixed a bug in the circuit drawers, which could fail or omit wires if
idle_wires=False. Fixed #13128 and #13146. -
Fixed an issue when calling
transpile()or the methodStagedPassManager.run()of a pass manager generated bygenerate_preset_pass_manager(), usingoptimization_level2 or 3 when therouting_methodargument is set to"none"to explicitly disable routing. Previously under these conditions the transpiler would run theElidePermutationspass as part of the init stage, as under normal conditions this is a useful optimization to removeSwapGateandPermutationGateinstances from the circuit. But whenrouting_method="none"this optimization wasn’t expected as it permutes the circuit in a similar manner to routing, which shouldn’t be performed whenrouting_method="none". This has been fixed by no longer runningElidePermutationsifrouting_method="none"is set. Fixed #13144. -
The OpenQASM 3 exporter has restored its behavior of accepting non-standard-library include files in the
includesargument toqasm3.dump(),dumps(), andExporter. These will insert a suitableincludestatement into the output as before, and the exporter remains unaware of the intended gates in that include file; you should pass the gates you expect it to define in thebasis_gatesargument to the same functions.We expect to improve the export mechanism against non-standard include files in a future release of Qiskit.
1.2.1
Prelude
Qiskit 1.2.1 is a minor bugfix release for the 1.2 series.
Bug Fixes
-
Fixed an issue with the visualizations of some backends/coupling maps that showed as folded on their own. The default ``neato` setting <https://graphviz.org/docs/layouts/neato/>`_ works well in most cases. However,
prismoverlap returns a more regular layout for other scenarios. -
Parametric controlled standard-library gates (such as
CRXGate) will now get correctly extracted to a Rust-space standard gate when usingQuantumCircuit.append()and the gate object. Previously there was a discrepancy where using theQuantumCircuit.crx()method would cause a correct extraction in Rust space, but theappend()form would not. The bug should generally not have caused any unsoundness from Python. -
Fixed a bug in
TwoQubitBasisDecomposerwhere the Rust-based code would panic if the given KAK gate was not a default version of the standard gates (for example, usingCXGate(ctrl_state=0)). Fixed #12998. -
Fixed a bug where
InstructionDurations.from_backend()did not work forBackendV2backends. Fixed #12760. -
Fixed the definition of the
CUGatematrix in Rust-space. While this was not noticable when handling theCUGatepurely on the Python side, this had knock-on effects when transpiler passes were using the Rust representation, such as could happen inConsolidate2qBlocks. Fixed #13118. -
Fixed a bug in
HoareOptimizerwhere a controlled gate was simplified by removing its controls but the new gate was not handled correctly. Fixed #13079. -
generate_preset_pass_manager()now correctly raises an exception, ifseed_transpileris set to an invalid value (i.e., it is not a non-negative integer). Fixed #12938. -
Fixed an edge case in
SabreLayout, where, in rare cases on large devices and challenging circuits, the routing would fail. This was due to the release valve making more than one two-qubit gate routable, where only one was expected. Fixed #13081. -
Fixed a bug in
Split2QUnitarieswhere it would fail to run on circuits with customGateobjects that did not implement__array__. See #12970. -
Fixed a bug in
StatePreparationwhere thenormalizeargument was ignored for input arrays. Fixed #12984. -
Fixed a bug where various synthesis methods created circuits without quantum or classical registers. This also affected functions that internally used the synthesis methods, such as
Clifford.to_circuit(). While the circuits were valid, this could cause issues when comparing circuits with registers. Fixed #13041. -
Fixed a bug that caused the method
Initialize.gates_to_uncompute()fail. Fixed #12969. -
Fixed an edge case when transpiling a circuit with
optimization_level2 or 3 with an incomplete 1-qubit basis gate set on a circuit containing 2-qubit gates, that can be implemented as a product of single qubit gates. This bug is resolved by restrictingSplit2QUnitariesto consider onlyUnitaryGateobjects. Fixed #12970.
1.2.0
Prelude
The Qiskit 1.2.0 release focuses mainly on improving performance and quality of the compiler. Also, it is the last release supporting Python 3.8. In Qiskit 1.3.0 the minimal required Python version will be 3.9. Among a wide range of new features, improvements, and fixes, the release highlights are:
- The circuit infrastructure, including gates and operations, is moved to Rust. This enables a series of speedups in circuit construction and circuit manipulation.
- Leveraging the above point, parts of the synthesis library are now constructing circuits in Rust. This produces a significant speedup when synthesizing operations such as Cliffords, permutations, or linear functions. As example, decomposing 50+ qubit Cliffords benefit from an approximate 1000-fold speedup in runtime.
- The quality of compiled circuits is improved by optimizing with a unitary peephole optimization at the initial stage of the transpilation workflow (at optimization level
>1), and by using a dense layout as a Sabre layouting trial (at optimization level>0).
New Features
-
Added a new class
QFTGatefor natively representing Quantum Fourier Transforms (QFTs). The older way of representing QFTs via quantum circuits, seeQFT, remains for backward compatibility. The new way of representing a QFT via a gate avoids synthesizing its definition circuit when the gate is declared, delaying the actual synthesis to the transpiler. It also allows to easily choose between several different algorithms for synthesizing QFTs, which are available as high-level-synthesis plugins. -
Added a synthesis method
synth_qft_full()for constructing a QFT circuit assuming a fully-connected architecture. -
Added two high-level-synthesis plugins for synthesizing a
QFTGate. The classQFTSynthesisFullis based onsynth_qft_full()and synthesizes a QFT gate assuming an all-to-all connectivity. The classQFTSynthesisLineis based onsynth_qft_line()and synthesizes a QFT gate assuming a linear-nearest-neighbor connectivity. -
Added two parameters to
GenericBackendV2to exclude error (noise_info) and pulse channel information (pulse_channels) from the construction of the backend. These parameters areTrueby default, replicating the initial default behavior of the constructor. A memory-sensitive user may set these options toFalseto reduce the memory overhead by 40x when transpiling on large- scaleGenericBackendV2. -
The
StabilizerStateclass now has a new methodStabilizerState.probabilities_dict_from_bitstring()allowing the user to pass single bitstring to measure an outcome for. Previouslly theStabilizerState.probabilities_dict()would be utilized and would at worst case calculate () number of probability calculations (depending on the state), even if a user wanted a single result. With this new method the user can calculate just the single outcome bitstring value a user passes to measure the probability for. As the number of qubits increases, the more prevelant the performance enhancement may be (depending on the state) as only 1 bitstring result is measured. -
Implemented
UniformSuperpositionGateclass, which allows the creation of a uniform superposition state using the Shukla-Vedula algorithm. This feature facilitates the creation of quantum circuits that produce a uniform superposition state , where is a positive integer representing the number of computational basis states with an amplitude of . This implementation supports the efficient creation of uniform superposition states, requiring only qubits and gates. Usage example:from qiskit import QuantumCircuit from qiskit.circuit.library.data_preparation import UniformSuperpositionGate M = 5 num_qubits = 3 usp_gate = UniformSuperpositionGate(M, num_qubits) qc = QuantumCircuit(num_qubits) qc.append(usp_gate, list(range(num_qubits))) qc.draw()
Circuits Features
-
Added a new function
random_clifford_circuit()toqiskit.circuit, that allows to generate a pseudo-random Clifford circuit with gates from the standard library. Example usage:from qiskit.circuit.random import random_clifford_circuit circ = random_clifford_circuit(num_qubits=2, num_gates=6) circ.draw(output='mpl')
-
Added support for
AnnotatedOperation.paramsandAnnotatedOperation.validate_parameter(), which enable circuit-level parameter handling (such as binding parameters) for annotated operations. -
CircuitInstructionandDAGOpNodeeach have new methods to query various properties of their internalOperation, without necessarily needing to access it. These methods are:CircuitInstruction.is_standard_gate()andDAGOpNode.is_standard_gate(),CircuitInstruction.is_controlled_gate()andDAGOpNode.is_controlled_gate(),CircuitInstruction.is_directive()andDAGOpNode.is_directive(),CircuitInstruction.is_control_flow()andDAGOpNode.is_control_flow(), andCircuitInstruction.is_parameterized()andDAGOpNode.is_parameterized().
If applicable, using any of these methods is significantly faster than querying
CircuitInstruction.operationorDAGOpNode.opdirectly, especially if the instruction or node represents a Qiskit standard gate. This is because the standard gates are stored natively in Rust, and their Python representation is only created when requested. -
A native rust representation of Qiskit’s standard gate library has been added. When a standard gate is added to a
QuantumCircuitorDAGCircuitit is now represented in a more efficient manner directly in Rust. Accessing that gate object from a circuit or DAG will return a new Python object representing the standard gate. This leads to faster and more efficient transpilation and manipulation of circuits for functionality written in Rust. -
The
random_circuit()function has a new feature where users can specify a distributionnum_operand_distribution(a dict) that specifies the ratio of 1-qubit, 2-qubit, 3-qubit, and 4-qubit gates in the random circuit. For example, ifnum_operand_distribution = {1: 0.25, 2: 0.25, 3: 0.25, 4: 0.25}is passed to the function then the generated circuit will have approximately 25% of 1-qubit, 2-qubit, 3-qubit, and 4-qubit gates. Also it should be noted that the ifnum_operand_distributionis not specified thenmax_operandswill default to 4 and a random circuit with a random gate distribution will be generated. If bothnum_operand_distributionandmax_operandsare specified at the same time thennum_operand_distributionwill be used to generate the random circuit.Example usage:
from qiskit.circuit.random import random_circuit circ = random_circuit( num_qubits=6, depth=5, num_operand_distribution={1: 0.25, 2: 0.25, 3: 0.25, 4: 0.25} ) circ.draw(output="mpl")
-
Improved performance of the method
DAGCircuit.quantum_causal_cone()by not examining the same non-directive node multiple times when reached from different paths. -
Added the
insert_barrierskeyword argument to theQuantumCircuit.repeat()method. Setting it toTruewill insert barriers between circuit repetitions. -
Replacing the internal synthesis algorithm of
StatePreparationandInitializeof Shende et al. by the algorithm given inIsometryof Iten et al. The new algorithm reduces the number of CX gates and the circuit depth by a factor of 2. -
ParameterExpressionnow supports the unary+operator.
Primitives Features
-
Added a new method
BitArray.postselect()that returns all shots containing specified bit values. Example usage:from qiskit.primitives.containers import BitArray ba = BitArray.from_counts({'110': 2, '100': 4, '000': 3}) print(ba.postselect([0,2], [0,1]).get_counts()) # {'110': 2, '100': 4} -
The metadata of Primitives V2 implementations, i.e.,
StatevectorSampler,StatevectorEstimator,BackendSamplerV2andBackendEstimatorV2, has been updated to match that of IBM quantum devices.versionandcircuit_metadataare added for all V2 implementationsshotsis added forBackendSamplerV2andBackendEstimatorV2precisionis renamed withtarget_precisionforStatevectorEstimator
Note that the metadata of
StatevectorEstimatordoes not haveshotsbecause the class computes expectation values withStatevectorand shots are not used.
OpenQASM Features
-
The internal symbol table of the OpenQASM 3 exporter (
qiskit.qasm3) has been rewritten, which should result in cleaner outputs when using Qiskit standard-library gates that are not in the OpenQASM 3 standard-library headers, and more deterministic outputs. For example, using severalRZXGates will now result in only a single parametric definition, and when naming collisions occur, the symbol table will assign a deterministic counter to make names unique, rather than a non-deterministic integer (previously, the object identity was used). -
The vendored version of the OpenQASM 3.0 standard library has been updated to match the state as of commit 4ca1d79383. This should generally have no effect on your use of Qiskit, unless you were retrieving our vendored file for your own use.
Synthesis Features
-
MCXRecursivewith control qubits and a single clean auxiliary qubit now requires at most CX gates. -
MCXVChainhas two new Boolean parameters relative_phase and action_only. Ifaction_onlyisTruethe circuit does not clean the dirty qubits. Ifrelative_phaseisTruethe gate is implemented up to a global phase. Both parameters are used to optimize the decomposition ofMCXVChain. -
MCXVChainwith controls and dirty auxiliary qubits now requires CX gates. -
Port
synth_permutation_acg(), used to synthesize qubit permutations, to Rust. This produces an approximate 3x performance improvement on 1000 qubit circuits. -
Port
synth_permutation_basic(), used to synthesize qubit permutations, to Rust. -
Port
synth_cnot_count_full_pmh(), used to synthesize a linear function into a CX network, to Rust. This produces approximately 44x speedup, as measured on 100 qubit circuits. -
The function
synth_cnot_count_full_pmh()now allows choosing the (heuristically) optimalsection_sizeby setting it toNone. Then, a value is chosen which attempts to minimize the upper bound on the number of CX gates, that is where is the number of qubits and . -
The function
synth_clifford_bm()was ported to Rust. Recall that this function optimally synthesizesCliffordoperators on 1, 2 or 3 qubits with respect to the number of CX-gates. This leads to a significant increase in performance. For Cliffords over 3 qubits, the speedup in on the order of 80 times. -
The function
synth_clifford_greedy()that synthesizesCliffordoperators was ported to Rust, leading to a significant increase in performance for all numbers of qubits. For Cliffords over 50 qubits, the speedup is on the order of 1000 times. -
Added the
wrapkeyword argument to theProductFormulaclasses which (when enabled) wraps individual Pauli evolution terms. This can be useful when visualizing circuits. -
The
atomic_evolutionargument toProductFormula(and its subclasses) has a new function signature. Rather than taking some Pauli operator and time coefficient and returning the evolution circuit, the new function takes in an existing circuit and should append the evolution of the provided Pauli and given time to this circuit. This new implementation benefits from significantly better performance. -
Improved the performance of
synth_permutation_depth_lnn_kms(), used to synthesize permutations for linear connectivity, by porting it to Rust.
Transpiler Features
-
Added a new import path option for
generate_preset_pass_manager(), so that it can now be imported as:from qiskit import generate_preset_pass_managerinstead of having to type the full path:
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_managerThe function is also importable from the
qiskit.transpilermodule as:from qiskit.transpiler import generate_preset_pass_manager -
Added a new user config file option
sabre_all_threadsand a corresponding environment variableQISKIT_SABRE_ALL_THREADS. When this flag is set the preset pass managers will run theSabreLayoutandSabreSwaptranspiler passes using all the available CPUs on the local system. Using this option is a tradeoff between determinism of output between different computers and potentially better output with fewerSwapGates.These transpiler passes run multiple random trials in parallel and pick the output which results in the fewest
SwapGates. As a rule of thumb, if you run more trials, this provides the algorithm more opportunities to find a better result. By default, the preset pass managers use a fixed number of trials, in this release 5 trials for levels 0 and 1, and 20 trials for levels 2 and 3, but these numbers may change in future releases (and were different in historical releases). Using a fixed number of trials results in deterministic results regardless of the local system, because even with a fixed seed if you were to default to the number of local CPUs available the results would different when running between different computers.If the default number of trials for a given optimization level is higher than the number of local CPUs it will use the optimization level default which is higher.
-
Added a new pass
Split2QUnitariesthat iterates over all two-qubit gates or unitaries in a circuit and replaces them with two single-qubit unitaries, if possible without introducing errors, i.e., the two-qubit gate/unitary is actually a tensor product of single-qubit unitaries. -
The passes
Collect2qBlocks,ConsolidateBlocksandSplit2QUnitarieshave been added to theinitstage of the preset pass managers with optimization level 2 and optimization level 3. The modification of theinitstage should allow for a more efficient routing for quantum circuits that either:- contain two-qubit unitaries/gates that are actually a product of single-qubit gates, or
- contain multiple two-qubit gates in a continuous block of two-qubit gates.
In the former case, the routing of the two-qubit gate can simply be skipped as no real interaction between a pair of qubits occurs. In the latter case, the lookahead space of routing algorithms is not ‘polluted’ by superfluous two-qubit gates, i.e., for routing it is sufficient to only consider one single two-qubit gate per continuous block of two-qubit gates. These passes are not run if the pass managers target a
Targetthat has a discrete basis gate set, i.e., all basis gates have are not parameterized. -
The performance of
StarPreRouting, used to find a star graph connectivity subcircuit, is improved by performing the heavy lifting in Rust space. -
The
SabreLayouttranspiler pass has been updated to always run an additional trial using the same algorithm asDenseLayoutto choose a starting point for Sabre’s layout algorithm. The starting point used by the layout algorithm can have a large influence on the quality of the results. By defaultSabreLayoutstill start withlayout_trialsrandom trials but in addition there will be a single trial that uses the densest subgraph of the connectivity graph as the starting point. This may yield better results in some cases especially on cases with smaller circuits for larger coupling maps. -
A new
dtargument has been added togenerate_preset_pass_manager()to match the set of arguments oftranspile(). This will allow for the internal conversion of transpilation constraints to aTargetrepresentation.
Visualization Features
-
The user configuration file has a new option
circuit_idle_wires, which takes a Boolean value. This allows users to set their preferred default behavior of theidle_wiresoption of the circuit drawersQuantumCircuit.draw()andcircuit_drawer(). For example, adding a section to~/.qiskit/settings.confwith:[default] circuit_idle_wires = falsewill change the default to not display idle wires.
Misc. Features
- Added a new build-time environment variable
QISKIT_NO_CACHE_GATESwhich when set to a value of1(i.e.QISKIT_NO_CACHE_GATES=1) decreases the memory overhead of aCircuitInstructionandDAGOpNodeobject at the cost of increased runtime on multiple accesses toCircuitInstruction.operationandDAGOpNode.op. If this environment variable is set when building the Qiskit Python package from source the caching of the return of these attributes will be disabled.
Circuits Upgrade Notes
-
The
annotatedargument of theGate.control()method is nowNoneby default, which allows Qiskit to choose whether to annotate a controlled operation. If the concrete implementation (annotated=False) is available, it will be returned by default. Otherwise, the annotated implementation will be returned (annotated=True). This allows, for example, to defer the synthesis of controlled, parameterized gates. -
The
Operationinstances ofDAGOpNode.opbeing returned will not necessarily share a common reference to the underlying object anymore. This was never guaranteed to be the case and mutating theDAGOpNode.opdirectly by reference was unsound and always likely to corrupt the DAG’s internal state tracking Due to the internal refactor of theQuantumCircuitandDAGCircuitto store standard gates in Rust, the output object fromDAGOpNode.opwill now likely be a copy instead of a shared instance. If you need to mutate an element should ensure that you do:op = dag_node.op op.params[0] = 3.14159 dag.substitute_node(dag_node, op)instead of doing something like:
dag_node.op.params[0] = 3.14159which will not work for any standard gate in this release. It would have likely worked by chance in a previous release but was never an API guarantee.
-
The
Operationinstances ofCircuitInstruction.operationbeing returned will not necessarily share a common reference to the underlying object anymore. This was never guaranteed to be the case and mutating theCircuitInstruction.operationdirectly by reference was unsound and always likely to corrupt the circuit, especially when parameters were in use. Due to the internal refactor of theQuantumCircuitto store standard gates in Rust, the output object fromCircuitInstruction.operationwill now likely be a copy instead of a shared instance. If you need to mutate an element in the circuit (which is strongly not recommended as it’s inefficient and error prone) you should ensure that you do:from qiskit.circuit import QuantumCircuit qc = QuantumCircuit(1) qc.p(0) op = qc.data[0].operation op.params[0] = 3.14 qc.data[0] = qc.data[0].replace(operation=op)instead of doing something like:
from qiskit.circuit import QuantumCircuit qc = QuantumCircuit(1) qc.p(0) qc.data[0].operation.params[0] = 3.14which will not work for any standard gates in this release. It would have likely worked by chance in a previous release but was never an API guarantee.
Primitives Upgrade Notes
-
BitArray.slice_bits()andBitArray.slice_shots()will now raiseIndexErrorwhen indices are out of bounds. They used to raiseValueErrorin the case. -
BitArray.__getitem__()will now raiseIndexErrorwhen indices are out of bounds or the number of dimensions of indices does not match that ofBitArray. They used to raiseValueErrorin the case.
Synthesis Upgrade Notes
LieTrotterandSuzukiTrotterno longer wrap the individually evolved Pauli terms into gate definitions. If you rely on a certain decomposition level of your circuit, you have to remove one level ofQuantumCircuit.decompose()or add thewrap=Truekeyword argument to your synthesis object.
Transpiler Upgrade Notes
-
Optimization levels 2 and 3 now additionally employ peephole optimization is now employed before the translation/synthesis stage (previously this was only done in the optimization stage). The effects of peephole optimization include the removal of gates that are very close to the identity, for example, controlled-phase gates with a rotational angle smaller than .
-
The default routing pass used by optimization level 0 for
generate_preset_pass_manager()andtranspile()has been changed fromStochasticSwaptoSabreSwap. TheSabreSwappass performs exactly the same function but performs better in both runtime and output quality (in number of swap gates and depth) compared toStochasticSwap. Foroptimization_level=0this shouldn’t matter because it’s not expected to run routing for the typical use case of level 0.If you were relying on the previous default routing algorithm for any reason you can use the
routing_methodargument fortranspile()andgenerate_preset_pass_manager()to"stochastic"to use theStochasticSwappass. -
The
generate_preset_pass_manager()function has been upgraded to, when possible, internally convert transpiler constraints into aTargetinstance. If a backend input of typeBackendV1is provided, it will be converted toBackendV2to expose itsTarget. This change does not require any user action.
Misc. Upgrade Notes
- The minimum version of rustworkx required to run this release has been increased from 0.14.0 to 0.15.0. This is required because Qiskit is now using new functionality added in the rustworkx 0.15.0 release which improves performance.
Circuits Deprecations
-
The following circuit methods were not intended for public use, but were accidentally left documented in the public API during the 1.0 release. They are now deprecated from Qiskit 1.2 and will be removed in Qiskit 2.0:
-
Treating
CircuitInstructionas a tuple-like iterable is deprecated, and this legacy path way will be removed in Qiskit 2.0. You should use the attribute-access fieldsCircuitInstruction.operation,CircuitInstruction.qubits, andCircuitInstruction.clbitsinstead. For example:from qiskit.circuit import QuantumCircuit qc = QuantumCircuit(2, 2) qc.h(0) qc.cx(0, 1) qc.measure([0, 1], [0, 1]) # Deprecated. for op, qubits, clbits in qc.data: pass # New style. for instruction in qc.data: op = instruction.operation qubits = instruction.qubits clbits = instruction.clbits
Primitives Deprecations
-
Primitive V1 implementations and V1-exclusive non-versioned type aliases are now deprecated in favor of their V2 counterparts. The deprecation is extended to the following classes implementing V1 interfaces:
Estimator, in favor of the V2 equivalent,StatevectorEstimatorSampler, in favor of the V2 equivalent,StatevectorSamplerBackendEstimator, in favor of the V2 equivalent,BackendEstimatorV2BackendSampler, in favor of the V2 equivalent,BackendSamplerV2
As well as the following non-versioned type aliases:
BaseEstimator, alias forBaseEstimatorV1BaseSampler, alias forBaseSamplerV1
This deprecation does not affect the explicitly-versioned
BaseEstimatorV1andBaseSamplerV1abstract interface definitions or related result and job classes.
Providers Deprecations
-
The
BackendV1class is deprecated and it will be removed no earlier than the next major release, 2.0.0. See the migration guide for details on how to update toBackendV2. -
The Qobj structure and related classes (see
qiskit.qobj) are now deprecated. They were introduced as part of theBackendV1workflow and are no longer necessary for interacting withBackendV2backends.QuantumCircuitserialiaztion should be done via QPY (seeqiskit.qpy) or OpenQASM (seeqiskit.qasm2andqiskit.qasm3) instead.
Transpiler Deprecations
- The
assemble()function is now deprecated and will be removed in the 2.0 release. The function was primarily used to create aQobj, which is no longer necessary inBackendV2-based workflows. It was also used for binding parameters, a functionality fully covered byQuantumCircuit.assign_parameters().
Visualization Deprecations
-
The
justifyargument ofcircuit_drawer()orQuantumCircuit.draw(), will no longer support invalid values (previously changing them to the default), and in a future release they will error. Valid justify values are"left","right"or"none". -
The
visualize_transition()function has been deprecated and will be removed in the 2.0.0 release. This function had a number of limitations which limited its utility to only very specific use cases and did not fit in with the rest of the Qiskit visualization module.
Bug Fixes
-
Fixed a series of issues when controlling parameterized standard gates. The controlled version of some gates (e.g.
RXXGateorRYGatefor more than 1 control) cannot be synthesized if they contain unbound parameters. Previously, calling.control()in such a case failed, but now we create anAnnotatedOperationas placeholder. This allows to insert the controlled gate into a circuit, bind the parameters at a later stage, and then synthesize the operation. Fixes #10311, #10697, and #12135. -
The
SGateandSdgGatenow correctly return aCSGate, resp.CSdgGate, if they are controlled on a single control qubit. -
Fix the calculation of the standard deviation in
BackendEstimatorV2, by taking into account co-variance of non-commuting Paulis. Fixed Qiskit/qiskit-ibm-runtime#1751. -
Fixed an issue where
circuit_drawer()or theQuantumCircuit.draw()method would not raise a warning when an invalid value was passed to thejustifyargument, before changing it to the default. Now, it will raise a warning if an invalid value is passed. Valid justify values are"left","right"or"none". Refer to #12089 for more details. -
Fixed
SparsePauliOp.apply_layout()andPauli.apply_layout()to raiseQiskitErrorif duplicate indices or negative indices are provided as part of a layout. -
Fixed a bug in the
ConsolidateBlockstranspiler pass, when the input circuit contains a custom opaque gate and neither thebasis_gatesortargetoptions are set the pass would raise aQiskitErrorand fail. This has been corrected so that the in these situations the transpiler pass will not consolidate the block identified containing a custom gate instead of failing. -
Fixed a bug in
PadDynamicalDecoupling, which previously did not correctly display the error message that a delay is not pulse-aligned, if the previous or following node was an input/output node. Now, the error message is correctly displayed. -
The keyword argument
orderof the functionBitArray.from_bool_array()should be"little"or"big". Added checks to raise error if an invalid value is entered. -
Improve the decomposition of the gate generated by
QuantumCircuit.mcx()without using ancilla qubits, so that the number ofCXGates will grow quadratically in the number of qubits, as expected, and not exponentially. -
Fixed
SparsePauliOp.apply_layout()to work correctly with zero-qubit operators. For example, if you previously created a 0 qubit and applied a layout like:op = SparsePauliOp("") op.apply_layout(None, 3)this would have previously raised an error. Now this will correctly return an operator of the form:
SparsePauliOp(['III'], coeffs=[1.+0.j]) -
Fixed a bug of
StatevectorSamplerthat ignored gates withc_if. It will raise an error becauseStatevectorcannot handlec_if. -
Fixed an oversight in the
Commuting2qGateRoutertranspiler pass where the quantum register permutations were not added to the pass property set, so they would have to be tracked manually by the user. Now it is possible to access the permutation through the output circuit’slayoutproperty and plug the pass into any transpilation pipeline without loss of information. -
Fixed a floating-point imprecision when scaling certain pulse units between seconds and nanoseconds. If the pulse was symbolically defined, an unnecessary floating-point error could be introduced by the scaling for certain builds of
symengine, which could manifest in unexpected results once the symbols were fully bound. Fixed #12392. -
Fixed a bug in
synth_cnot_count_full_pmh()where providing asection_sizethat did not divide the number of qubits without remainder could lead to wrong results. Now anysection_size(at most equal to the number of qubits) synthesizes the correct circuit. For a (heuristically) optimal value, setsection_size=None. -
PassManager.run()will no longer waste time serializing itself when given multiple inputs if it is only going to work in serial. -
Fixed a bug in
plot_coupling_map()that caused the edges of the coupling map to be colored incorrectly. Fixed #12354. -
The OpenQASM 2.0 parser (
qasm2.load()andqasm2.loads()) can now evaluate gate-angle expressions including integer operands that would overflow the system-size integer. These will be evaluated in a double-precision floating-point context, just like the rest of the expression always has been. Beware: an arbitrarily large integer will not necessarily be exactly representable in double-precision floating-point, so there is a chance that however the circuit was generated, it had already lost all numerical precision modulo . -
The OpenQASM 3 exporter (see
qiskit.qasm3) will now correctly error when asked to use a keyword or other invalid identifier as a “basis gate”, as it has no way of generating correct output in these cases. -
The OpenQASM 3 exporter (
qiskit.qasm3) will now correctly export multiple instances ofPauliEvolutionGatefrom a circuit. Previously, only a single instance would be exported, and all other instances would silently use the same (incorrect) version. -
The OpenQASM 3 exporter (
qiskit.qasm3) will now correctly escape gate names. Previously, a gate whose name was an invalid OpenQASM 3 identifier would cause invalid OpenQASM 3 to be generated. -
A series of input-handling inconsistencies between
transpile()andgenerate_preset_pass_manager()have been fixed. These inconsistencies would lead to different transpilation outputs for the same inputs, orgenerate_preset_pass_manager()failing for certain input combinations accepted bytranspile().