436 lines
50 KiB
Plaintext
436 lines
50 KiB
Plaintext
---
|
||
title: Qiskit SDK 1.2 release notes
|
||
description: Changes made in Qiskit SDK 1.2
|
||
in_page_toc_max_heading_level: 3
|
||
---
|
||
|
||
<span id="qiskit-version-release-notes" />
|
||
|
||
<span id="release-notes" />
|
||
|
||
# Qiskit SDK 1.2 release notes
|
||
|
||
<span id="relnotes-1-2-0" />
|
||
|
||
<span id="id1" />
|
||
|
||
## 1.2.0
|
||
|
||
<span id="relnotes-1-2-0-prelude" />
|
||
|
||
### 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`).
|
||
|
||
<span id="relnotes-1-2-0-new-features" />
|
||
|
||
### New Features
|
||
|
||
* Added a new class [`QFTGate`](/api/qiskit/qiskit.circuit.library.QFTGate "qiskit.circuit.library.QFTGate") for natively representing Quantum Fourier Transforms (QFTs). The older way of representing QFTs via quantum circuits, see [`QFT`](/api/qiskit/qiskit.circuit.library.QFT "qiskit.circuit.library.QFT"), 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()`](/api/qiskit/synthesis#qiskit.synthesis.synth_qft_full "qiskit.synthesis.synth_qft_full") for constructing a QFT circuit assuming a fully-connected architecture.
|
||
|
||
* Added two high-level-synthesis plugins for synthesizing a [`QFTGate`](/api/qiskit/qiskit.circuit.library.QFTGate "qiskit.circuit.library.QFTGate"). The class [`QFTSynthesisFull`](/api/qiskit/qiskit.transpiler.passes.synthesis.high_level_synthesis.QFTSynthesisFull "qiskit.transpiler.passes.synthesis.high_level_synthesis.QFTSynthesisFull") is based on [`synth_qft_full()`](/api/qiskit/synthesis#qiskit.synthesis.synth_qft_full "qiskit.synthesis.synth_qft_full") and synthesizes a QFT gate assuming an all-to-all connectivity. The class [`QFTSynthesisLine`](/api/qiskit/qiskit.transpiler.passes.synthesis.high_level_synthesis.QFTSynthesisLine "qiskit.transpiler.passes.synthesis.high_level_synthesis.QFTSynthesisLine") is based on [`synth_qft_line()`](/api/qiskit/synthesis#qiskit.synthesis.synth_qft_line "qiskit.synthesis.synth_qft_line") and synthesizes a QFT gate assuming a linear-nearest-neighbor connectivity.
|
||
|
||
* Added two parameters to [`GenericBackendV2`](/api/qiskit/qiskit.providers.fake_provider.GenericBackendV2 "qiskit.providers.fake_provider.GenericBackendV2") to exclude error (`noise_info`) and pulse channel information (`pulse_channels`) from the construction of the backend. These parameters are `True` by default, replicating the initial default behavior of the constructor. A memory-sensitive user may set these options to `False` to reduce the memory overhead by 40x when transpiling on large- scale [`GenericBackendV2`](/api/qiskit/qiskit.providers.fake_provider.GenericBackendV2 "qiskit.providers.fake_provider.GenericBackendV2").
|
||
|
||
* The [`StabilizerState`](/api/qiskit/qiskit.quantum_info.StabilizerState "qiskit.quantum_info.StabilizerState") class now has a new method [`StabilizerState.probabilities_dict_from_bitstring()`](/api/qiskit/qiskit.quantum_info.StabilizerState#probabilities_dict_from_bitstring "qiskit.quantum_info.StabilizerState.probabilities_dict_from_bitstring") allowing the user to pass single bitstring to measure an outcome for. Previouslly the [`StabilizerState.probabilities_dict()`](/api/qiskit/qiskit.quantum_info.StabilizerState#probabilities_dict "qiskit.quantum_info.StabilizerState.probabilities_dict") would be utilized and would at worst case calculate ($2^n$) 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 `UniformSuperpositionGate` class, 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 $\frac{1}{\sqrt{M}} \sum_{j=0}^{M-1} |j\rangle$, where $M$ is a positive integer representing the number of computational basis states with an amplitude of $\frac{1}{\sqrt{M}}$. This implementation supports the efficient creation of uniform superposition states, requiring only $O(\log_2 (M))$ qubits and $O(\log_2 (M))$ gates. Usage example:
|
||
|
||
```python
|
||
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()
|
||
```
|
||
|
||
<span id="relnotes-1-2-0-circuits-features" />
|
||
|
||
### Circuits Features
|
||
|
||
* Added a new function [`random_clifford_circuit()`](/api/qiskit/circuit#qiskit.circuit.random.random_clifford_circuit "qiskit.circuit.random.random_clifford_circuit") to [`qiskit.circuit`](/api/qiskit/circuit#module-qiskit.circuit "qiskit.circuit"), that allows to generate a pseudo-random Clifford circuit with gates from the standard library. Example usage:
|
||
|
||
```python
|
||
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.params`](/api/qiskit/qiskit.circuit.AnnotatedOperation#params "qiskit.circuit.AnnotatedOperation.params") and [`AnnotatedOperation.validate_parameter()`](/api/qiskit/qiskit.circuit.AnnotatedOperation#validate_parameter "qiskit.circuit.AnnotatedOperation.validate_parameter"), which enable circuit-level parameter handling (such as binding parameters) for annotated operations.
|
||
|
||
* [`CircuitInstruction`](/api/qiskit/qiskit.circuit.CircuitInstruction "qiskit.circuit.CircuitInstruction") and [`DAGOpNode`](/api/qiskit/qiskit.dagcircuit.DAGOpNode "qiskit.dagcircuit.DAGOpNode") each have new methods to query various properties of their internal [`Operation`](/api/qiskit/qiskit.circuit.Operation "qiskit.circuit.Operation"), without necessarily needing to access it. These methods are:
|
||
|
||
* [`CircuitInstruction.is_standard_gate()`](/api/qiskit/qiskit.circuit.CircuitInstruction#is_standard_gate "qiskit.circuit.CircuitInstruction.is_standard_gate") and [`DAGOpNode.is_standard_gate()`](/api/qiskit/qiskit.dagcircuit.DAGOpNode#is_standard_gate "qiskit.dagcircuit.DAGOpNode.is_standard_gate"),
|
||
* [`CircuitInstruction.is_controlled_gate()`](/api/qiskit/qiskit.circuit.CircuitInstruction#is_controlled_gate "qiskit.circuit.CircuitInstruction.is_controlled_gate") and [`DAGOpNode.is_controlled_gate()`](/api/qiskit/qiskit.dagcircuit.DAGOpNode#is_controlled_gate "qiskit.dagcircuit.DAGOpNode.is_controlled_gate"),
|
||
* [`CircuitInstruction.is_directive()`](/api/qiskit/qiskit.circuit.CircuitInstruction#is_directive "qiskit.circuit.CircuitInstruction.is_directive") and [`DAGOpNode.is_directive()`](/api/qiskit/qiskit.dagcircuit.DAGOpNode#is_directive "qiskit.dagcircuit.DAGOpNode.is_directive"),
|
||
* [`CircuitInstruction.is_control_flow()`](/api/qiskit/qiskit.circuit.CircuitInstruction#is_control_flow "qiskit.circuit.CircuitInstruction.is_control_flow") and [`DAGOpNode.is_control_flow()`](/api/qiskit/qiskit.dagcircuit.DAGOpNode#is_control_flow "qiskit.dagcircuit.DAGOpNode.is_control_flow"), and
|
||
* [`CircuitInstruction.is_parameterized()`](/api/qiskit/qiskit.circuit.CircuitInstruction#is_parameterized "qiskit.circuit.CircuitInstruction.is_parameterized") and [`DAGOpNode.is_parameterized()`](/api/qiskit/qiskit.dagcircuit.DAGOpNode#is_parameterized "qiskit.dagcircuit.DAGOpNode.is_parameterized").
|
||
|
||
If applicable, using any of these methods is significantly faster than querying [`CircuitInstruction.operation`](/api/qiskit/qiskit.circuit.CircuitInstruction#operation "qiskit.circuit.CircuitInstruction.operation") or [`DAGOpNode.op`](/api/qiskit/qiskit.dagcircuit.DAGOpNode#op "qiskit.dagcircuit.DAGOpNode.op") directly, 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 [`QuantumCircuit`](/api/qiskit/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") or [`DAGCircuit`](/api/qiskit/qiskit.dagcircuit.DAGCircuit "qiskit.dagcircuit.DAGCircuit") it 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()`](/api/qiskit/circuit#qiskit.circuit.random.random_circuit "qiskit.circuit.random.random_circuit") function has a new feature where users can specify a distribution `num_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, if `num_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 if `num_operand_distribution` is not specified then `max_operands` will default to 4 and a random circuit with a random gate distribution will be generated. If both `num_operand_distribution` and `max_operands` are specified at the same time then `num_operand_distribution` will be used to generate the random circuit.
|
||
|
||
Example usage:
|
||
|
||
```python
|
||
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()`](/api/qiskit/qiskit.dagcircuit.DAGCircuit#quantum_causal_cone "qiskit.dagcircuit.DAGCircuit.quantum_causal_cone") by not examining the same non-directive node multiple times when reached from different paths.
|
||
|
||
* Added the `insert_barriers` keyword argument to the [`QuantumCircuit.repeat()`](/api/qiskit/qiskit.circuit.QuantumCircuit#repeat "qiskit.circuit.QuantumCircuit.repeat") method. Setting it to `True` will insert barriers between circuit repetitions.
|
||
|
||
* Replacing the internal synthesis algorithm of [`StatePreparation`](/api/qiskit/qiskit.circuit.library.StatePreparation "qiskit.circuit.library.StatePreparation") and [`Initialize`](/api/qiskit/qiskit.circuit.library.Initialize "qiskit.circuit.library.Initialize") of Shende et al. by the algorithm given in [`Isometry`](/api/qiskit/qiskit.circuit.library.Isometry "qiskit.circuit.library.Isometry") of Iten et al. The new algorithm reduces the number of CX gates and the circuit depth by a factor of 2.
|
||
|
||
* [`ParameterExpression`](/api/qiskit/qiskit.circuit.ParameterExpression "qiskit.circuit.ParameterExpression") now supports the unary `+` operator.
|
||
|
||
<span id="relnotes-1-2-0-primitives-features" />
|
||
|
||
### Primitives Features
|
||
|
||
* Added a new method [`BitArray.postselect()`](/api/qiskit/qiskit.primitives.BitArray#postselect "qiskit.primitives.BitArray.postselect") that returns all shots containing specified bit values. Example usage:
|
||
|
||
```python
|
||
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`](/api/qiskit/qiskit.primitives.StatevectorSampler "qiskit.primitives.StatevectorSampler"), [`StatevectorEstimator`](/api/qiskit/qiskit.primitives.StatevectorEstimator "qiskit.primitives.StatevectorEstimator"), [`BackendSamplerV2`](/api/qiskit/qiskit.primitives.BackendSamplerV2 "qiskit.primitives.BackendSamplerV2") and [`BackendEstimatorV2`](/api/qiskit/qiskit.primitives.BackendEstimatorV2 "qiskit.primitives.BackendEstimatorV2"), has been updated to match that of IBM quantum devices.
|
||
|
||
* `version` and `circuit_metadata` are added for all V2 implementations
|
||
* `shots` is added for [`BackendSamplerV2`](/api/qiskit/qiskit.primitives.BackendSamplerV2 "qiskit.primitives.BackendSamplerV2") and [`BackendEstimatorV2`](/api/qiskit/qiskit.primitives.BackendEstimatorV2 "qiskit.primitives.BackendEstimatorV2")
|
||
* `precision` is renamed with `target_precision` for [`StatevectorEstimator`](/api/qiskit/qiskit.primitives.StatevectorEstimator "qiskit.primitives.StatevectorEstimator")
|
||
|
||
Note that the metadata of [`StatevectorEstimator`](/api/qiskit/qiskit.primitives.StatevectorEstimator "qiskit.primitives.StatevectorEstimator") does not have `shots` because the class computes expectation values with [`Statevector`](/api/qiskit/qiskit.quantum_info.Statevector "qiskit.quantum_info.Statevector") and shots are not used.
|
||
|
||
<span id="relnotes-1-2-0-openqasm-features" />
|
||
|
||
### OpenQASM Features
|
||
|
||
* The internal symbol table of the OpenQASM 3 exporter ([`qiskit.qasm3`](/api/qiskit/qasm3#module-qiskit.qasm3 "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 several [`RZXGate`](/api/qiskit/qiskit.circuit.library.RZXGate "qiskit.circuit.library.RZXGate")s 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](https://github.com/openqasm/openqasm/blob/4ca1d793833b24a195dcb8a5db99f1bd21b0d32f/examples/stdgates.inc). This should generally have no effect on your use of Qiskit, unless you were retrieving our vendored file for your own use.
|
||
|
||
<span id="relnotes-1-2-0-synthesis-features" />
|
||
|
||
### Synthesis Features
|
||
|
||
* [`MCXRecursive`](/api/qiskit/qiskit.circuit.library.MCXRecursive "qiskit.circuit.library.MCXRecursive") with $k$ control qubits and a single clean auxiliary qubit now requires at most $16k-8$ CX gates.
|
||
|
||
* [`MCXVChain`](/api/qiskit/qiskit.circuit.library.MCXVChain "qiskit.circuit.library.MCXVChain") has two new Boolean parameters relative\_phase and action\_only. If `action_only` is `True` the circuit does not clean the dirty qubits. If `relative_phase` is `True` the gate is implemented up to a global phase. Both parameters are used to optimize the decomposition of [`MCXVChain`](/api/qiskit/qiskit.circuit.library.MCXVChain "qiskit.circuit.library.MCXVChain").
|
||
|
||
* [`MCXVChain`](/api/qiskit/qiskit.circuit.library.MCXVChain "qiskit.circuit.library.MCXVChain") with $k$ controls and $k-2$ dirty auxiliary qubits now requires $8k-6$ CX gates.
|
||
|
||
* Port [`synth_permutation_acg()`](/api/qiskit/synthesis#qiskit.synthesis.synth_permutation_acg "qiskit.synthesis.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()`](/api/qiskit/synthesis#qiskit.synthesis.synth_permutation_basic "qiskit.synthesis.synth_permutation_basic"), used to synthesize qubit permutations, to Rust.
|
||
|
||
* Port [`synth_cnot_count_full_pmh()`](/api/qiskit/synthesis#qiskit.synthesis.synth_cnot_count_full_pmh "qiskit.synthesis.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()`](/api/qiskit/synthesis#qiskit.synthesis.synth_cnot_count_full_pmh "qiskit.synthesis.synth_cnot_count_full_pmh") now allows choosing the (heuristically) optimal `section_size` by setting it to `None`. Then, a value is chosen which attempts to minimize the upper bound on the number of CX gates, that is $\alpha \log_2(n)$ where $n$ is the number of qubits and $\alpha \approx 0.56$.
|
||
|
||
* The function [`synth_clifford_bm()`](/api/qiskit/synthesis#qiskit.synthesis.synth_clifford_bm "qiskit.synthesis.synth_clifford_bm") was ported to Rust. Recall that this function optimally synthesizes [`Clifford`](/api/qiskit/qiskit.quantum_info.Clifford "qiskit.quantum_info.Clifford") operators 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()`](/api/qiskit/synthesis#qiskit.synthesis.synth_clifford_greedy "qiskit.synthesis.synth_clifford_greedy") that synthesizes [`Clifford`](/api/qiskit/qiskit.quantum_info.Clifford "qiskit.quantum_info.Clifford") operators 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 `wrap` keyword argument to the [`ProductFormula`](/api/qiskit/qiskit.synthesis.ProductFormula "qiskit.synthesis.ProductFormula") classes which (when enabled) wraps individual Pauli evolution terms. This can be useful when visualizing circuits.
|
||
|
||
* The `atomic_evolution` argument to [`ProductFormula`](/api/qiskit/qiskit.synthesis.ProductFormula "qiskit.synthesis.ProductFormula") (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()`](/api/qiskit/synthesis#qiskit.synthesis.synth_permutation_depth_lnn_kms "qiskit.synthesis.synth_permutation_depth_lnn_kms"), used to synthesize permutations for linear connectivity, by porting it to Rust.
|
||
|
||
<span id="relnotes-1-2-0-transpiler-features" />
|
||
|
||
### Transpiler Features
|
||
|
||
* Added a new import path option for [`generate_preset_pass_manager()`](/api/qiskit/transpiler_preset#qiskit.transpiler.preset_passmanagers.generate_preset_pass_manager "qiskit.transpiler.preset_passmanagers.generate_preset_pass_manager"), so that it can now be imported as:
|
||
|
||
```python
|
||
from qiskit import generate_preset_pass_manager
|
||
```
|
||
|
||
instead of having to type the full path:
|
||
|
||
```python
|
||
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
|
||
```
|
||
|
||
The function is also importable from the [`qiskit.transpiler`](/api/qiskit/transpiler#module-qiskit.transpiler "qiskit.transpiler") module as:
|
||
|
||
```python
|
||
from qiskit.transpiler import generate_preset_pass_manager
|
||
```
|
||
|
||
* Added a new user config file option `sabre_all_threads` and a corresponding environment variable `QISKIT_SABRE_ALL_THREADS`. When this flag is set the preset pass managers will run the [`SabreLayout`](/api/qiskit/qiskit.transpiler.passes.SabreLayout "qiskit.transpiler.passes.SabreLayout") and [`SabreSwap`](/api/qiskit/qiskit.transpiler.passes.SabreSwap "qiskit.transpiler.passes.SabreSwap") transpiler 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 fewer [`SwapGate`](/api/qiskit/qiskit.circuit.library.SwapGate "qiskit.circuit.library.SwapGate")s.
|
||
|
||
These transpiler passes run multiple random trials in parallel and pick the output which results in the fewest [`SwapGate`](/api/qiskit/qiskit.circuit.library.SwapGate "qiskit.circuit.library.SwapGate")s. 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 [`Split2QUnitaries`](/api/qiskit/qiskit.transpiler.passes.Split2QUnitaries "qiskit.transpiler.passes.Split2QUnitaries") that 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`](/api/qiskit/qiskit.transpiler.passes.Collect2qBlocks "qiskit.transpiler.passes.Collect2qBlocks"), [`ConsolidateBlocks`](/api/qiskit/qiskit.transpiler.passes.ConsolidateBlocks "qiskit.transpiler.passes.ConsolidateBlocks") and [`Split2QUnitaries`](/api/qiskit/qiskit.transpiler.passes.Split2QUnitaries "qiskit.transpiler.passes.Split2QUnitaries") have been added to the `init` stage of the preset pass managers with optimization level 2 and optimization level 3. The modification of the `init` stage 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 [`Target`](/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target") that has a discrete basis gate set, i.e., all basis gates have are not parameterized.
|
||
|
||
* The performance of [`StarPreRouting`](/api/qiskit/qiskit.transpiler.passes.StarPreRouting "qiskit.transpiler.passes.StarPreRouting"), used to find a star graph connectivity subcircuit, is improved by performing the heavy lifting in Rust space.
|
||
|
||
* The [`SabreLayout`](/api/qiskit/qiskit.transpiler.passes.SabreLayout "qiskit.transpiler.passes.SabreLayout") transpiler pass has been updated to always run an additional trial using the same algorithm as [`DenseLayout`](/api/qiskit/qiskit.transpiler.passes.DenseLayout "qiskit.transpiler.passes.DenseLayout") to 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 default [`SabreLayout`](/api/qiskit/qiskit.transpiler.passes.SabreLayout "qiskit.transpiler.passes.SabreLayout") still start with `layout_trials` random 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 `dt` argument has been added to [`generate_preset_pass_manager()`](/api/qiskit/transpiler_preset#qiskit.transpiler.preset_passmanagers.generate_preset_pass_manager "qiskit.transpiler.preset_passmanagers.generate_preset_pass_manager") to match the set of arguments of [`transpile()`](/api/qiskit/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile"). This will allow for the internal conversion of transpilation constraints to a [`Target`](/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target") representation.
|
||
|
||
<span id="relnotes-1-2-0-visualization-features" />
|
||
|
||
### 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 the `idle_wires` option of the circuit drawers [`QuantumCircuit.draw()`](/api/qiskit/qiskit.circuit.QuantumCircuit#draw "qiskit.circuit.QuantumCircuit.draw") and [`circuit_drawer()`](/api/qiskit/qiskit.visualization.circuit_drawer "qiskit.visualization.circuit_drawer"). For example, adding a section to `~/.qiskit/settings.conf` with:
|
||
|
||
```python
|
||
[default]
|
||
circuit_idle_wires = false
|
||
```
|
||
|
||
will change the default to not display idle wires.
|
||
|
||
<span id="relnotes-1-2-0-misc-features" />
|
||
|
||
### Misc. Features
|
||
|
||
* Added a new build-time environment variable `QISKIT_NO_CACHE_GATES` which when set to a value of `1` (i.e. `QISKIT_NO_CACHE_GATES=1`) decreases the memory overhead of a [`CircuitInstruction`](/api/qiskit/qiskit.circuit.CircuitInstruction "qiskit.circuit.CircuitInstruction") and [`DAGOpNode`](/api/qiskit/qiskit.dagcircuit.DAGOpNode "qiskit.dagcircuit.DAGOpNode") object at the cost of increased runtime on multiple accesses to [`CircuitInstruction.operation`](/api/qiskit/qiskit.circuit.CircuitInstruction#operation "qiskit.circuit.CircuitInstruction.operation") and [`DAGOpNode.op`](/api/qiskit/qiskit.dagcircuit.DAGOpNode#op "qiskit.dagcircuit.DAGOpNode.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.
|
||
|
||
<span id="relnotes-1-2-0-circuits-upgrade-notes" />
|
||
|
||
### Circuits Upgrade Notes
|
||
|
||
* The `annotated` argument of the [`Gate.control()`](/api/qiskit/qiskit.circuit.Gate#control "qiskit.circuit.Gate.control") method is now `None` by 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 [`Operation`](/api/qiskit/qiskit.circuit.Operation "qiskit.circuit.Operation") instances of [`DAGOpNode.op`](/api/qiskit/qiskit.dagcircuit.DAGOpNode#op "qiskit.dagcircuit.DAGOpNode.op") being returned will not necessarily share a common reference to the underlying object anymore. This was never guaranteed to be the case and mutating the [`DAGOpNode.op`](/api/qiskit/qiskit.dagcircuit.DAGOpNode#op "qiskit.dagcircuit.DAGOpNode.op") directly by reference was unsound and always likely to corrupt the DAG’s internal state tracking Due to the internal refactor of the [`QuantumCircuit`](/api/qiskit/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") and [`DAGCircuit`](/api/qiskit/qiskit.dagcircuit.DAGCircuit "qiskit.dagcircuit.DAGCircuit") to store standard gates in Rust, the output object from [`DAGOpNode.op`](/api/qiskit/qiskit.dagcircuit.DAGOpNode#op "qiskit.dagcircuit.DAGOpNode.op") will now likely be a copy instead of a shared instance. If you need to mutate an element should ensure that you do:
|
||
|
||
```python
|
||
op = dag_node.op
|
||
op.params[0] = 3.14159
|
||
dag.substitute_node(dag_node, op)
|
||
```
|
||
|
||
instead of doing something like:
|
||
|
||
```python
|
||
dag_node.op.params[0] = 3.14159
|
||
```
|
||
|
||
which 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 [`Operation`](/api/qiskit/qiskit.circuit.Operation "qiskit.circuit.Operation") instances of [`CircuitInstruction.operation`](/api/qiskit/qiskit.circuit.CircuitInstruction#operation "qiskit.circuit.CircuitInstruction.operation") being returned will not necessarily share a common reference to the underlying object anymore. This was never guaranteed to be the case and mutating the [`CircuitInstruction.operation`](/api/qiskit/qiskit.circuit.CircuitInstruction#operation "qiskit.circuit.CircuitInstruction.operation") directly by reference was unsound and always likely to corrupt the circuit, especially when parameters were in use. Due to the internal refactor of the [`QuantumCircuit`](/api/qiskit/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") to store standard gates in Rust, the output object from [`CircuitInstruction.operation`](/api/qiskit/qiskit.circuit.CircuitInstruction#operation "qiskit.circuit.CircuitInstruction.operation") will 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:
|
||
|
||
```python
|
||
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:
|
||
|
||
```python
|
||
from qiskit.circuit import QuantumCircuit
|
||
|
||
qc = QuantumCircuit(1)
|
||
qc.p(0)
|
||
|
||
qc.data[0].operation.params[0] = 3.14
|
||
```
|
||
|
||
which 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.
|
||
|
||
<span id="relnotes-1-2-0-primitives-upgrade-notes" />
|
||
|
||
### Primitives Upgrade Notes
|
||
|
||
* [`BitArray.slice_bits()`](/api/qiskit/qiskit.primitives.BitArray#slice_bits "qiskit.primitives.BitArray.slice_bits") and [`BitArray.slice_shots()`](/api/qiskit/qiskit.primitives.BitArray#slice_shots "qiskit.primitives.BitArray.slice_shots") will now raise `IndexError` when indices are out of bounds. They used to raise `ValueError` in the case.
|
||
|
||
* `BitArray.__getitem__()` will now raise `IndexError` when indices are out of bounds or the number of dimensions of indices does not match that of [`BitArray`](/api/qiskit/qiskit.primitives.BitArray "qiskit.primitives.BitArray"). They used to raise `ValueError` in the case.
|
||
|
||
<span id="relnotes-1-2-0-synthesis-upgrade-notes" />
|
||
|
||
### Synthesis Upgrade Notes
|
||
|
||
* [`LieTrotter`](/api/qiskit/qiskit.synthesis.LieTrotter "qiskit.synthesis.LieTrotter") and [`SuzukiTrotter`](/api/qiskit/qiskit.synthesis.SuzukiTrotter "qiskit.synthesis.SuzukiTrotter") no 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 of [`QuantumCircuit.decompose()`](/api/qiskit/qiskit.circuit.QuantumCircuit#decompose "qiskit.circuit.QuantumCircuit.decompose") or add the `wrap=True` keyword argument to your synthesis object.
|
||
|
||
<span id="relnotes-1-2-0-transpiler-upgrade-notes" />
|
||
|
||
### 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 $2\pi \otimes 2^{-25}$.
|
||
|
||
* The default routing pass used by optimization level 0 for [`generate_preset_pass_manager()`](/api/qiskit/transpiler_preset#qiskit.transpiler.preset_passmanagers.generate_preset_pass_manager "qiskit.transpiler.preset_passmanagers.generate_preset_pass_manager") and [`transpile()`](/api/qiskit/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile") has been changed from [`StochasticSwap`](/api/qiskit/qiskit.transpiler.passes.StochasticSwap "qiskit.transpiler.passes.StochasticSwap") to [`SabreSwap`](/api/qiskit/qiskit.transpiler.passes.SabreSwap "qiskit.transpiler.passes.SabreSwap"). The [`SabreSwap`](/api/qiskit/qiskit.transpiler.passes.SabreSwap "qiskit.transpiler.passes.SabreSwap") pass performs exactly the same function but performs better in both runtime and output quality (in number of swap gates and depth) compared to [`StochasticSwap`](/api/qiskit/qiskit.transpiler.passes.StochasticSwap "qiskit.transpiler.passes.StochasticSwap"). For `optimization_level=0` this 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_method` argument for [`transpile()`](/api/qiskit/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile") and [`generate_preset_pass_manager()`](/api/qiskit/transpiler_preset#qiskit.transpiler.preset_passmanagers.generate_preset_pass_manager "qiskit.transpiler.preset_passmanagers.generate_preset_pass_manager") to `"stochastic"` to use the [`StochasticSwap`](/api/qiskit/qiskit.transpiler.passes.StochasticSwap "qiskit.transpiler.passes.StochasticSwap") pass.
|
||
|
||
* The [`generate_preset_pass_manager()`](/api/qiskit/transpiler_preset#qiskit.transpiler.preset_passmanagers.generate_preset_pass_manager "qiskit.transpiler.preset_passmanagers.generate_preset_pass_manager") function has been upgraded to, when possible, internally convert transpiler constraints into a [`Target`](/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target") instance. If a backend input of type [`BackendV1`](/api/qiskit/qiskit.providers.BackendV1 "qiskit.providers.BackendV1") is provided, it will be converted to [`BackendV2`](/api/qiskit/qiskit.providers.BackendV2 "qiskit.providers.BackendV2") to expose its [`Target`](/api/qiskit/qiskit.transpiler.Target "qiskit.transpiler.Target"). This change does not require any user action.
|
||
|
||
<span id="relnotes-1-2-0-misc-upgrade-notes" />
|
||
|
||
### 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.
|
||
|
||
<span id="relnotes-1-2-0-circuits-deprecations" />
|
||
|
||
### 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:
|
||
|
||
> * [`QuantumCircuit.cast()`](/api/qiskit/qiskit.circuit.QuantumCircuit#cast "qiskit.circuit.QuantumCircuit.cast")
|
||
> * [`QuantumCircuit.cls_instances()`](/api/qiskit/qiskit.circuit.QuantumCircuit#cls_instances "qiskit.circuit.QuantumCircuit.cls_instances")
|
||
> * [`QuantumCircuit.cls_prefix()`](/api/qiskit/qiskit.circuit.QuantumCircuit#cls_prefix "qiskit.circuit.QuantumCircuit.cls_prefix")
|
||
> * [`QuantumCircuit.cbit_argument_conversion()`](/api/qiskit/qiskit.circuit.QuantumCircuit#cbit_argument_conversion "qiskit.circuit.QuantumCircuit.cbit_argument_conversion")
|
||
> * [`QuantumCircuit.qbit_argument_conversion()`](/api/qiskit/qiskit.circuit.QuantumCircuit#qbit_argument_conversion "qiskit.circuit.QuantumCircuit.qbit_argument_conversion")
|
||
|
||
* Treating [`CircuitInstruction`](/api/qiskit/qiskit.circuit.CircuitInstruction "qiskit.circuit.CircuitInstruction") as a tuple-like iterable is deprecated, and this legacy path way will be removed in Qiskit 2.0. You should use the attribute-access fields [`CircuitInstruction.operation`](/api/qiskit/qiskit.circuit.CircuitInstruction#operation "qiskit.circuit.CircuitInstruction.operation"), [`CircuitInstruction.qubits`](/api/qiskit/qiskit.circuit.CircuitInstruction#qubits "qiskit.circuit.CircuitInstruction.qubits"), and [`CircuitInstruction.clbits`](/api/qiskit/qiskit.circuit.CircuitInstruction#clbits "qiskit.circuit.CircuitInstruction.clbits") instead. For example:
|
||
|
||
```python
|
||
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
|
||
```
|
||
|
||
<span id="relnotes-1-2-0-primitives-deprecations" />
|
||
|
||
### 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`](/api/qiskit/qiskit.primitives.Estimator "qiskit.primitives.Estimator"), in favor of the V2 equivalent, [`StatevectorEstimator`](/api/qiskit/qiskit.primitives.StatevectorEstimator "qiskit.primitives.StatevectorEstimator")
|
||
* [`Sampler`](/api/qiskit/qiskit.primitives.Sampler "qiskit.primitives.Sampler"), in favor of the V2 equivalent, [`StatevectorSampler`](/api/qiskit/qiskit.primitives.StatevectorSampler "qiskit.primitives.StatevectorSampler")
|
||
* [`BackendEstimator`](/api/qiskit/qiskit.primitives.BackendEstimator "qiskit.primitives.BackendEstimator"), in favor of the V2 equivalent, [`BackendEstimatorV2`](/api/qiskit/qiskit.primitives.BackendEstimatorV2 "qiskit.primitives.BackendEstimatorV2")
|
||
* [`BackendSampler`](/api/qiskit/qiskit.primitives.BackendSampler "qiskit.primitives.BackendSampler"), in favor of the V2 equivalent, [`BackendSamplerV2`](/api/qiskit/qiskit.primitives.BackendSamplerV2 "qiskit.primitives.BackendSamplerV2")
|
||
|
||
As well as the following non-versioned type aliases:
|
||
|
||
* [`BaseEstimator`](/api/qiskit/qiskit.primitives.BaseEstimator "qiskit.primitives.BaseEstimator"), alias for [`BaseEstimatorV1`](/api/qiskit/qiskit.primitives.BaseEstimatorV1 "qiskit.primitives.BaseEstimatorV1")
|
||
* [`BaseSampler`](/api/qiskit/qiskit.primitives.BaseSampler "qiskit.primitives.BaseSampler"), alias for [`BaseSamplerV1`](/api/qiskit/qiskit.primitives.BaseSamplerV1 "qiskit.primitives.BaseSamplerV1")
|
||
|
||
This deprecation does **not** affect the explicitly-versioned [`BaseEstimatorV1`](/api/qiskit/qiskit.primitives.BaseEstimatorV1 "qiskit.primitives.BaseEstimatorV1") and [`BaseSamplerV1`](/api/qiskit/qiskit.primitives.BaseSamplerV1 "qiskit.primitives.BaseSamplerV1") abstract interface definitions or related result and job classes.
|
||
|
||
<span id="relnotes-1-2-0-providers-deprecations" />
|
||
|
||
### Providers Deprecations
|
||
|
||
* The [`BackendV1`](/api/qiskit/qiskit.providers.BackendV1 "qiskit.providers.BackendV1") class is deprecated and it will be removed no earlier than the next major release, 2.0.0. See [the migration guide](https://qisk.it/backendV1-to-V2) for details on how to update to [`BackendV2`](/api/qiskit/qiskit.providers.BackendV2 "qiskit.providers.BackendV2").
|
||
|
||
* The Qobj structure and related classes (see [`qiskit.qobj`](/api/qiskit/qobj#module-qiskit.qobj "qiskit.qobj")) are now deprecated. They were introduced as part of the [`BackendV1`](/api/qiskit/qiskit.providers.BackendV1 "qiskit.providers.BackendV1") workflow and are no longer necessary for interacting with [`BackendV2`](/api/qiskit/qiskit.providers.BackendV2 "qiskit.providers.BackendV2") backends. [`QuantumCircuit`](/api/qiskit/qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") serialiaztion should be done via QPY (see [`qiskit.qpy`](/api/qiskit/qpy#module-qiskit.qpy "qiskit.qpy")) or OpenQASM (see [`qiskit.qasm2`](/api/qiskit/qasm2#module-qiskit.qasm2 "qiskit.qasm2") and [`qiskit.qasm3`](/api/qiskit/qasm3#module-qiskit.qasm3 "qiskit.qasm3")) instead.
|
||
|
||
<span id="relnotes-1-2-0-transpiler-deprecations" />
|
||
|
||
### Transpiler Deprecations
|
||
|
||
* The [`assemble()`](/api/qiskit/compiler#qiskit.compiler.assemble "qiskit.compiler.assemble") function is now deprecated and will be removed in the 2.0 release. The function was primarily used to create a `Qobj`, which is no longer necessary in [`BackendV2`](/api/qiskit/qiskit.providers.BackendV2 "qiskit.providers.BackendV2")-based workflows. It was also used for binding parameters, a functionality fully covered by [`QuantumCircuit.assign_parameters()`](/api/qiskit/qiskit.circuit.QuantumCircuit#assign_parameters "qiskit.circuit.QuantumCircuit.assign_parameters").
|
||
|
||
<span id="relnotes-1-2-0-visualization-deprecations" />
|
||
|
||
### Visualization Deprecations
|
||
|
||
* The `justify` argument of [`circuit_drawer()`](/api/qiskit/qiskit.visualization.circuit_drawer "qiskit.visualization.circuit_drawer") or [`QuantumCircuit.draw()`](/api/qiskit/qiskit.circuit.QuantumCircuit#draw "qiskit.circuit.QuantumCircuit.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()`](/api/qiskit/qiskit.visualization.visualize_transition "qiskit.visualization.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.
|
||
|
||
<span id="relnotes-1-2-0-bug-fixes" />
|
||
|
||
### Bug Fixes
|
||
|
||
* Fixed a series of issues when controlling parameterized standard gates. The controlled version of some gates (e.g. [`RXXGate`](/api/qiskit/qiskit.circuit.library.RXXGate "qiskit.circuit.library.RXXGate") or [`RYGate`](/api/qiskit/qiskit.circuit.library.RYGate "qiskit.circuit.library.RYGate") for more than 1 control) cannot be synthesized if they contain unbound parameters. Previously, calling `.control()` in such a case failed, but now we create an [`AnnotatedOperation`](/api/qiskit/qiskit.circuit.AnnotatedOperation "qiskit.circuit.AnnotatedOperation") as 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](https://github.com/Qiskit/qiskit/issues/10311), [#10697](https://github.com/Qiskit/qiskit/issues/10697), and [#12135](https://github.com/Qiskit/qiskit/issues/12135).
|
||
|
||
* The [`SGate`](/api/qiskit/qiskit.circuit.library.SGate "qiskit.circuit.library.SGate") and [`SdgGate`](/api/qiskit/qiskit.circuit.library.SdgGate "qiskit.circuit.library.SdgGate") now correctly return a [`CSGate`](/api/qiskit/qiskit.circuit.library.CSGate "qiskit.circuit.library.CSGate"), resp. [`CSdgGate`](/api/qiskit/qiskit.circuit.library.CSdgGate "qiskit.circuit.library.CSdgGate"), if they are controlled on a single control qubit.
|
||
|
||
* Fix the calculation of the standard deviation in [`BackendEstimatorV2`](/api/qiskit/qiskit.primitives.BackendEstimatorV2 "qiskit.primitives.BackendEstimatorV2"), by taking into account co-variance of non-commuting Paulis. Fixed [Qiskit/qiskit-ibm-runtime#1751](https://github.com/Qiskit/qiskit-ibm-runtime/issues/1751).
|
||
|
||
* Fixed an issue where [`circuit_drawer()`](/api/qiskit/qiskit.visualization.circuit_drawer "qiskit.visualization.circuit_drawer") or the [`QuantumCircuit.draw()`](/api/qiskit/qiskit.circuit.QuantumCircuit#draw "qiskit.circuit.QuantumCircuit.draw") method would not raise a warning when an invalid value was passed to the `justify` argument, 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](https://github.com/Qiskit/qiskit/issues/12089) for more details.
|
||
|
||
* Fixed [`SparsePauliOp.apply_layout()`](/api/qiskit/qiskit.quantum_info.SparsePauliOp#apply_layout "qiskit.quantum_info.SparsePauliOp.apply_layout") and [`Pauli.apply_layout()`](/api/qiskit/qiskit.quantum_info.Pauli#apply_layout "qiskit.quantum_info.Pauli.apply_layout") to raise [`QiskitError`](/api/qiskit/exceptions#qiskit.exceptions.QiskitError "qiskit.exceptions.QiskitError") if duplicate indices or negative indices are provided as part of a layout.
|
||
|
||
* Fixed a bug in the [`ConsolidateBlocks`](/api/qiskit/qiskit.transpiler.passes.ConsolidateBlocks "qiskit.transpiler.passes.ConsolidateBlocks") transpiler pass, when the input circuit contains a custom opaque gate and neither the `basis_gates` or `target` options are set the pass would raise a [`QiskitError`](/api/qiskit/exceptions#qiskit.exceptions.QiskitError "qiskit.exceptions.QiskitError") and 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`](/api/qiskit/qiskit.transpiler.passes.PadDynamicalDecoupling "qiskit.transpiler.passes.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 `order` of the function [`BitArray.from_bool_array()`](/api/qiskit/qiskit.primitives.BitArray#from_bool_array "qiskit.primitives.BitArray.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()`](/api/qiskit/qiskit.circuit.QuantumCircuit#mcx "qiskit.circuit.QuantumCircuit.mcx") without using ancilla qubits, so that the number of [`CXGate`](/api/qiskit/qiskit.circuit.library.CXGate "qiskit.circuit.library.CXGate")s will grow quadratically in the number of qubits, as expected, and not exponentially.
|
||
|
||
* Fixed [`SparsePauliOp.apply_layout()`](/api/qiskit/qiskit.quantum_info.SparsePauliOp#apply_layout "qiskit.quantum_info.SparsePauliOp.apply_layout") to work correctly with zero-qubit operators. For example, if you previously created a 0 qubit and applied a layout like:
|
||
|
||
```python
|
||
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 [`StatevectorSampler`](/api/qiskit/qiskit.primitives.StatevectorSampler "qiskit.primitives.StatevectorSampler") that ignored gates with `c_if`. It will raise an error because [`Statevector`](/api/qiskit/qiskit.quantum_info.Statevector "qiskit.quantum_info.Statevector") cannot handle `c_if`.
|
||
|
||
* Fixed an oversight in the [`Commuting2qGateRouter`](/api/qiskit/qiskit.transpiler.passes.Commuting2qGateRouter "qiskit.transpiler.passes.Commuting2qGateRouter") transpiler 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’s `layout` property 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](https://github.com/Qiskit/qiskit/issues/12359).
|
||
|
||
* Fixed a bug in [`synth_cnot_count_full_pmh()`](/api/qiskit/synthesis#qiskit.synthesis.synth_cnot_count_full_pmh "qiskit.synthesis.synth_cnot_count_full_pmh") where providing a `section_size` that did not divide the number of qubits without remainder could lead to wrong results. Now any `section_size` (at most equal to the number of qubits) synthesizes the correct circuit. For a (heuristically) optimal value, set `section_size=None`.
|
||
|
||
* [`PassManager.run()`](/api/qiskit/qiskit.transpiler.PassManager#run "qiskit.transpiler.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()`](/api/qiskit/qiskit.visualization.plot_coupling_map "qiskit.visualization.plot_coupling_map") that caused the edges of the coupling map to be colored incorrectly. Fixed [#12354](https://github.com/Qiskit/qiskit/issues/12354).
|
||
|
||
* The OpenQASM 2.0 parser ([`qasm2.load()`](/api/qiskit/qasm2#qiskit.qasm2.load "qiskit.qasm2.load") and [`qasm2.loads()`](/api/qiskit/qasm2#qiskit.qasm2.loads "qiskit.qasm2.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 $2\pi$.
|
||
|
||
* The OpenQASM 3 exporter (see [`qiskit.qasm3`](/api/qiskit/qasm3#module-qiskit.qasm3 "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`](/api/qiskit/qasm3#module-qiskit.qasm3 "qiskit.qasm3")) will now correctly export multiple instances of [`PauliEvolutionGate`](/api/qiskit/qiskit.circuit.library.PauliEvolutionGate "qiskit.circuit.library.PauliEvolutionGate") from 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`](/api/qiskit/qasm3#module-qiskit.qasm3 "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()`](/api/qiskit/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile") and [`generate_preset_pass_manager()`](/api/qiskit/transpiler_preset#qiskit.transpiler.preset_passmanagers.generate_preset_pass_manager "qiskit.transpiler.preset_passmanagers.generate_preset_pass_manager") have been fixed. These inconsistencies would lead to different transpilation outputs for the same inputs, or [`generate_preset_pass_manager()`](/api/qiskit/transpiler_preset#qiskit.transpiler.preset_passmanagers.generate_preset_pass_manager "qiskit.transpiler.preset_passmanagers.generate_preset_pass_manager") failing for certain input combinations accepted by [`transpile()`](/api/qiskit/compiler#qiskit.compiler.transpile "qiskit.compiler.transpile").
|
||
|