Qiskit 0.34 release notes
0.34.2
Terra 0.19.2
Prelude
Qiskit Terra 0.19.2 is predominantly a bugfix release, but also now comes with wheels built for Python 3.10 on all major platforms.
New Features
- Added support for running with Python 3.10. This includes publishing precompiled binaries to PyPI for Python 3.10 on supported platforms.
Upgrade Notes
- Starting from Python 3.10, Qiskit Terra will have reduced support for 32-bit platforms. These are Linux i686 and 32-bit Windows. These platforms with Python 3.10 are now at Tier 3 instead of Tier 2 support (per the tiers defined in: https://qiskit.org/documentation/getting_started.html#platform-support) This is because the upstream dependencies Numpy and Scipy have dropped support for them. Qiskit will still publish precompiled binaries for these platforms, but we’re unable to test the packages prior to publishing, and you will need a C/C++ compiler so that
pipcan build their dependencies from source. If you’re using one of these platforms, we recommended that you use Python 3.7, 3.8, or 3.9.
Bug Fixes
-
Fixed a bug where the
CVaRMeasurementattempted to convert aPauliSumOpto a dense matrix to check whether it were diagonal. For large operators (> 16 qubits) this computation was extremely expensive and raised an error if not explicitly enabled usingqiskit.utils.algorithm_globals.massive = True. The check is now efficient even for large numbers of qubits. -
DAGCircuit.draw()and the associated functiondag_drawer()will now show a more useful error message when the provided filename is not valid. -
QuantumCircuit.add_register()will no longer cause duplicateAncillaQubitreferences in a circuit when given anAncillaRegisterwhose bits are already present. -
Fixed conversion of
QuantumCircuits with classical conditions on single, registerlessClbits toInstructions when using thecircuit_to_instruction()function or theQuantumCircuit.to_instruction()method. For example, the following will now work:from qiskit.circuit import QuantumCircuit, Qubit, Clbit qc = QuantumCircuit([Qubit(), Clbit()]) qc.h(0).c_if(qc.clbits[0], 0) qc.to_instruction() -
Registers will now correctly reject duplicate bits. Fixed #7446.
-
The
FakeOpenPulse2Qmock backend now has T2 times and readout errors stored for its qubits. These are arbitrary values, approximately consistent with real backends at the time of its creation. -
Fix the qubit order of 2-qubit evolutions in the
PauliEvolutionGate, if used with a product formula synthesis. For instance, before, the evolution ofIIZ + IZI + IZZfrom qiskit.circuit.library import PauliEvolutionGate from qiskit.opflow import I, Z operator = (I ^ I ^ Z) + (I ^ Z ^ I) + (I ^ Z ^ Z) print(PauliEvolutionGate(operator).definition.decompose())produced
┌───────┐ q_0: ┤ Rz(2) ├──────── ├───────┤ q_1: ┤ Rz(2) ├─■────── └───────┘ │ZZ(2) q_2: ──────────■──────whereas now it correctly yields
┌───────┐ q_0: ┤ Rz(2) ├─■────── ├───────┤ │ZZ(2) q_1: ┤ Rz(2) ├─■────── └───────┘ q_2: ───────────────── -
Fixed a problem in the
latexandmplcircuit drawers when register names with multiple underscores in the name did not display correctly. -
Negative numbers in array outputs from the drawers will now appear as decimal numbers instead of fractions with huge numerators and denominators. Like positive numbers, they will still be fractions if the ratio is between small numbers.
-
Fixed an issue with the
Target.get_non_global_operation_names()method when running on a target incorrectly raising an exception on targets with ideal global operations. Previously, if this method was called on a target that contained any ideal globally defined operations, where the instruction properties are set toNone, this method would raise an exception instead of treating that instruction as global. -
Fixed an issue with the
transpile()function where it could fail when being passed aTargetobject directly with thetargetkwarg. -
Fixed an issue with the
transpile()function where it could fail when thebackendargument was aBackendV2or aTargetvia thetargetkwarg that contained ideal globally defined operations. -
Fixed an issue where plotting Bloch spheres could cause an
AttributeErrorto be raised in Jupyter or when trying to crop figures down to size with Matplotlib 3.3 or 3.4 (but not 3.5). For example, the following code would previously crash with a message:AttributeError: 'Arrow3D' object has no attribute '_path2d'but will now succeed with all current supported versions of Matplotlib:
from qiskit.visualization import plot_bloch_vector plot_bloch_vector([0, 1, 0]).savefig("tmp.png", bbox_inches='tight') -
Fixed a bug in
PauliSumOp.permute()where the object on which the method is called was permuted in-place, instead of returning a permuted copy. This bug only occured for permutations that left the number of qubits in the operator unchanged. -
Fixed the
PauliEvolutionGate.inverse()method, which previously computed the inverse by inverting the evolution time. This was only the correct inverse if the operator was evolved exactly. In particular, this led to the inverse of Trotterization-based time evolutions being incorrect. -
The
QuantumInstance.execute()method will no longer mutate its input if it is given a list of circuits. -
Fixed QPY serialisation of custom instructions which had an explicit no-op definition. Previously these would be written and subsequently read the same way as if they were opaque gates (with no given definition). They will now correctly round-trip an empty definition. For example, the following will now be correct:
import io from qiskit.circuit import Instruction, QuantumCircuit, qpy_serialization # This instruction is explicitly defined as a one-qubit gate with no # operations. empty = QuantumCircuit(1, name="empty").to_instruction() # This instruction will perform some operations that are only known # by the hardware backend. opaque = Instruction("opaque", 1, 0, []) circuit = QuantumCircuit(2) circuit.append(empty, [0], []) circuit.append(opaque, [1], []) qpy_file = io.BytesIO() qpy_serialization.dump(circuit, qpy_file) qpy_file.seek(0) new_circuit = qpy_serialization.load(qpy_file)[0] # Previously both instructions in `new_circuit` would now be opaque, but # there is now a correct distinction. circuit == new_circuit -
Added a missing
BackendV2.providerattribute to implementations of theBackendV2abstract class. Previously,BackendV2backends could be initialized with a provider but that was not accessible to users. -
Fixed support for the
QuantumInstanceclass when running with aBackendV2backend. Previously, attempting to use aQuantumInstancewith aBackendV2would have resulted in an error. -
Fixed a bug in
VQEwhere the parameters of the ansatz were still explicitly ASCII-sorted by their name if the ansatz was resized. This led to a mismatched order of the optimized values in theoptimal_pointattribute of the result object.In particular, this bug occurred if no ansatz was set by the user and the VQE chose a default with 11 or more free parameters.
-
Stopped the parser in
QuantumCircuit.from_qasm_str()andfrom_qasm_file()from accepting OpenQASM programs that identified themselves as being from a language version other than 2.0. This parser is only for OpenQASM 2.0; support for imported circuits from OpenQASM 3.0 will be added in an upcoming release. -
Fixed QPY serialization of
QuantumCircuitobjects that contained control flow instructions. Previously if you attempted to serialize a circuit containingIfElseOp,WhileLoopOp, orForLoopOpthe serialization would fail. Fixed #7583. -
Fixed QPY serialization of
QuantumCircuitcontaining subsets of bits from aQuantumRegisterorClassicalRegister. Previously if you tried to serialize a circuit like this it would incorrectly treat these bits as standaloneQubitorClbitwithout having a register set. For example, if you try to serialize a circuit like:import io from qiskit import QuantumCircuit, QuantumRegister from qiskit.circuit.qpy_serialization import load, dump qr = QuantumRegister(2) qc = QuantumCircuit([qr[0]]) qc.x(0) with open('file.qpy', 'wb') as fd: dump(qc, fd)when that circuit is loaded now the registers will be correctly populated fully even though the circuit only contains a subset of the bits from the register.
-
QFTwill now warn if it is instantiated or built with settings that will cause it to lose precision, rather than raising anOverflowError. This can happen if the number of qubits is very large (slightly over 1000) without the approximation degree being similarly large. The circuit will now build successfully, but some angles might be indistinguishable from zero, due to limitations in double-precision floating-point numbers.
Aer 0.10.3
Prelude
Qiskit Aer 0.10.3 is mainly a bugfix release, fixing several bugs that have been discovered since the 0.10.2 release. Howver, this release also introduces support for running with Python 3.10 including precompiled binary wheels on all major platforms. This release also includes precompiled binary wheels for arm64 on macOS.
New Features
-
Added support for running with Python 3.10. This includes publishing precompiled binaries to PyPI for Python 3.10 on supported platforms.
-
Added support for M1 macOS systems. Precompiled binaries for supported Python versions >=3.8 on arm64 macOS will now be published on PyPI for this and future releases.
Upgrade Notes
- Qiskit Aer no longer fully supports 32 bit platforms on Python >= 3.10. These are Linux i686 and 32-bit Windows. These platforms with Python 3.10 are now at Tier 3 instead of Tier 2 support (per the tiers defined in: https://qiskit.org/documentation/getting_started.html#platform-support) This is because the upstream dependencies Numpy and Scipy have dropped support for them. Qiskit will still publish precompiled binaries for these platforms, but we’re unable to test the packages prior to publishing, and you will need a C/C++ compiler so that
pipcan build their dependencies from source. If you’re using one of these platforms, we recommended that you use Python 3.7, 3.8, or 3.9.
Bug Fixes
-
Fixes a bug in
RelaxationNoisePasswhere instruction durations were always assumed to be in dt time units, regardless of the actual unit of the isntruction. Now unit conversion is correctly handled for all instruction duration units.See #1453 for details.
-
Fixes an issue with
LocalNoisePassfor noise functions that return aQuantumCircuitfor the noise op. These were appended to the DAG as an opaque circuit instruction that must be unrolled to be simulated. This fix composes them so that the cirucit instructions are added to the new DAG and can be simulated without additional unrolling if all circuit instructions are supported by the simulator.See #1447 for details.
-
Multi-threaded transpilations to generate diagonal gates will now work correctly if the number of gates of a circuit exceeds
fusion_parallelization_threshold. Previously, different threads would occasionally fuse the same element into multiple blocks, causing incorrect results. -
Fixes a bug with truncation of circuits in parameterized Qobjs. Previously parameters of parameterized QObj could be wrongly resolved if unused qubits of their circuits were truncated, because indices of the parameters were not updated after the instructions on unmeasured qubits were removed.
See #1427 for details.
Ignis 0.7.0
No change
IBM Q Provider 0.18.3
No change
0.34.1
Terra 0.19.1
No change
Aer 0.10.2
Bug Fixes
-
Fixed simulation of
forloops where the loop parameter was not used in the body of the loop. For example, previously this code would fail, but will now succeed:import qiskit from qiskit.providers.aer import AerSimulator qc = qiskit.QuantumCircuit(2) with qc.for_loop(range(4)) as i: qc.h(0) qc.cx(0, 1) AerSimulator(method="statevector").run(qc) -
Fixes a bug in
QuantumError.to_dict()where N-qubit circuit instructions where the assembled instruction always applied to qubits[0, ..., N-1]rather than the instruction qubits. This bug also affected device and fake backend noise models.See Issue 1415 for details.
Ignis 0.7.0
No change
IBM Q Provider 0.18.3
No change
0.34.0
Qiskit 0.34.0 includes a point release of Qiskit Aer: version 0.10.1, which patches performance regressions in version 0.10.0 that were discovered immediately post-release. See below for the release notes for both Qiskit Aer 0.10.0 and 0.10.1.
Terra 0.19.1
No change
Aer 0.10.1
Prelude
The Qiskit Aer 0.10.1 patch fixes performance regressions introduced in Qiskit Aer 0.10.0.
Bug Fixes
- Fix performance regression in noisy simulations due to large increase in serialization overhead for loading noise models from Python into C++ resulting from unintended nested Python multiprocessing calls. See issue 1407 for details.
Aer 0.10.0
Prelude
The Qiskit Aer 0.10 release includes several performance and noise model improvements. Some highlights are:
- Improved performance for parallel shot GPU and HPC simulations
- Support for simulation of circuits containing QASM 3.0 control-flow instructions
- Support for relaxation noise on scheduled circuits in backend noise models
- Support of user-created transpiler passes for defining custom gate errors and noise models, and inserting them into circuits.
New Features
-
Added support of QASM 3.0 control-flow instructions introduced in Qiskit-Terra 0.19.0. Supported instructions are
ForLoopOp,WhileLoopOp,ContinueLoopOp,BreakLoopOp,IfElseOp. -
Added a batched-shot simulation optimization for GPU simulations. This optional feature will use available memory on 1 or more GPUs to run multiple simulation shots in parallel for greatly improved performance on multi-shot simulations with noise models and/or intermediate measurements.
This option is enabled by default when using
device="GPU"and a simulationmethodof either"statevector"or"density_matrix"with theAerSimulator. It can be disabled by settingbatched_shots_gpu=Falsein the simulator options.This optimization is most beneficial for small to medium numbers of qubits where there is sufficient GPU memory to run multiple simulations in parallel. The maximum number of active circuit qubits for enabling this optimization can be configured using the
batch_shots_gpu_max_qubitssimulator option. The default value of this option is 16. -
Added the new
max_shot_sizeoption to a custom executor for running multiple shots of a noisy circuit in parallel.For example configuring
max_shot_sizewith a custom executor:backend = AerSimulator( max_shot_size=1, max_job_size=1, executor=custom_executor) job = backend.run(circuits)will split the shots of a noisy circuit into multiple circuits. After all individual shots have finished executing, the job results are automatically combined into a single
Resultobject that is returned byjob.result(). -
Added the
mps_swap_directionsimulator option that allows the user to determine the direction of internal swaps, when they are inserted for a 2-qubit gate. Possible values are"mps_swap_right"and"mps_swap_left". The direction of the swaps may affect performance, depending on the circuit. -
Implemented a new measurement sampling optimization for the
"matrix_product_state"simulation method of theAerSimulator. Currently this algorithm is used only when all qubits are measured and when the simulatormps_sample_measure_algorithmsimulator option is set to"mps_probabilities". -
Improved the performance of the measure instruction for the
"matrix_product_state"simulation method of theAerSimulator. -
Added a
SaveCliffordinstruction for saving the state of the stabilizer simulation method as aCliffordobject.Note that this instruction is essentially equivalent to the
SaveStabilizerinstruction, however that instruction will return the saved state as aStabilizerStateobject instead of aCliffordobject. -
Added two transpiler passes for inserting instruction-dependent quantum errors into circuits:
qiskit.providers.aer.noise.LocalNoisePassqiskit.providers.aer.noise.RelaxationNoisePass
The
LocalNoisePasspass can be used to implement custom parameterized noise models by defining a noise generating function of the formdef fn( inst: Instruction, qubits: Optional[List[int]] = None, ) -> InstructionLikewhich returns a noise instruction (eg. a
QuantumErroror other instruction) that can depend on any properties or parameters of the instruction and qubit arguements.This function can be applied to all instructions in a circuit, or a specified subset (See the
LocalNoisePassdocumentation for additional details.)The
RelaxationNoisePassis a special case of theLocalNoisePassusing a predefined noise function that returns a tensor product ofthermal_relaxation_error()on each qubit in an instruction, dependent on the instruction’s duration and the supplied relaxation time constant parameters of the pass. -
The basic device noise model implemented by
NoiseModel.from_backend()andAerSimulator.from_backend()has been upgraded to allow adding duration-dependent relaxation errors on circuit delay gates using theRelaxationNoisePass.To enable this noise when running noisy simulations you must first schedule your circuit to insert scheduled delay instructions as follows:
backend = AerSimulator.from_backend(ibmq_backend) scheduled_circuit = qiskit.transpile( circuit, backend=backend, scheduling_method='asap') result = backend.run(scheduled_circuit).result()If the circuit is transpiled without being scheduled (and also contains no delay instructions) the noisy simulation will not include the effect of delay relaxation errors. In this case the simulation will be equivalent to the previous qiskit-aer 0.9 simulation where relaxation noise is only added to gate instructions based on their duration as obtained from the backend properties.
-
The constructor of
QuantumErrornow accepts several new types of input asnoise_opsargument, for example:import numpy as np from qiskit import QuantumCircuit from qiskit.circuit.library import IGate, XGate, Reset from qiskit.quantum_info import Kraus from qiskit.providers.aer.noise import QuantumError # Quantum channels kraus = Kraus([ np.array([[1, 0], [0, np.sqrt(1 - 0.9)]], dtype=complex), np.array([[0, 0], [0, np.sqrt(0.9)]], dtype=complex) ]) print(QuantumError(kraus)) # Construction from a QuantumCircuit qc = QuantumCircuit(2) qc.h(0) qc.cx(0, 1) error = QuantumError(qc) # Construction from a tuple of (Instruction, List[int]), where the list of # integers represents the qubits. error = QuantumError((Reset(), [0])) # Construction from an iterable of objects in the same form as above, but # where each also has an associated probability. error = QuantumError([ ((IGate(), [0]), 0.9), ((XGate(), [0]), 0.1), ]) # A short-hand for the iterable form above, where the qubits are implicit, # and each instruction is over all qubits. error = QuantumError([(IGate(), 0.9), (XGate(), 0.1)])Note that the original JSON-based input format is deperecated.
-
Added a utility function
qiskit.providers.aer.utils.transform_noise_model()for constructing a noise model by applying a supplied function to allQuantumErrors in the noise model. -
Added two utility functions
qiskit.providers.aer.utils.transpile_quantum_error()andqiskit.providers.aer.utils.transpile_noise_model()for transpiling the circuits contained inQuantumError, and all errors in aNoiseModel. -
Added the ability to add
QuantumErrorobjects directly to aQuantumCircuitwithout converting to aKrausinstruction.Circuits containing quantum errors can now be run on the
AerSimulatorandQasmSimulatorsimulators as an alternative to, or in addition to, building aNoiseModelfor defining noisy circuit instructions.Example:
from qiskit import QuantumCircuit from qiskit.providers.aer import AerSimulator from qiskit.providers.aer.noise import pauli_error error_h = pauli_error([('I', 0.95), ('X', 0.05)]) error_cx = pauli_error([('II', 0.9), ('XX', 0.1)]) qc = QuantumCircuit(3) qc.h(0) qc.append(error_h, [0]) qc.cx(0, 1) qc.append(error_cx, [0, 1]) qc.cx(0, 2) qc.append(error_cx, [0, 2]) qc.measure_all() backend = AerSimulator(method='stabilizer') result = backend.run(qc).result() result.get_counts(0)Circuits containing quantum errors can also be evaluated using the
quantum_infoquantum channel andDensityMatrixclasses.
Upgrade Notes
-
The return type of several save instructions have been changed to be the corresponding Qiskit Terra classes rather than raw NumPy arrays or dictionaries. The types that have changed are
save_statevector()now returns as aStatevectorsave_density_matrix()now returns as aDensityMatrixsave_stabilizer()now returns asStabilizerStatesave_unitary()now returns asOperatorsave_superop()now returns asSuperOpsave_probabilities_dict()now returns as aProbDistribution
-
Changed the default value of
standard_gatestoNonefor all functions inqiskit.providers.aer.noise.errors.standard_errorsas those functions are updated so that they use standard gates by default. -
When an unsupported argument is supplied to
approximate_quantum_error(), it will now raise aNoiseErrorinstead of aRuntimeError.
Deprecation Notes
-
Using NumPy
ndarraymethods and attributes on the return type ofsave_statevector(),save_density_matrix(),save_unitary(), andsave_superop()has been deprecated, and will stop working in a future release. These instructions now returnqiskit.quantum_infoclasses for their return types. Partial backwards compatability with treating these objects as NumPy arrays is implemented by forwarding methods to the internal array during the deprecation period. -
Passing in a
BackendPropertiesobject for thebackendargument ofNoiseModel.from_backend()has been deprecated, as it is incompatible with duration dependent delay noises, and will be removed in a future release. Pass in a Qiskit TerraBackendV1object instead. -
Deprecated the
number_of_qubitsoption of theQuantumErrorconstructor in favor of automatic determination of the dimension. -
Deprecated the
standard_gatesoption of theQuantumErrorconstructor in favor of externalizing such basis-change functionality. In many cases, you can transform any error into an error defined only with specific gates usingapproximate_quantum_error(). -
Deprecated the
standard_gatesoption of all functions inqiskit.providers.aer.noise.errors.standard_errorsin favor of returning errors in the form of a mixture of standard gates as much as possible by default. -
Deprecated all functions in
errorutilsbecause they are helper functions meant to be used only for implementing functions inqiskit.providers.aer.noise.errors.standard_errorsand they should have been provided as private functions. -
Deprecated the
standard_gatesoption ofNoiseModel.from_backend()in favor of externalizing such basis-change functionality. -
Deprecated
NoiseModel.from_dict()to make the noise model independent of Qobj (JSON) format. -
Deprecated all public variables, functions and classes in
qiskit.providers.aer.noise.utils.noise_transformationexcept forapproximate_quantum_error()andapproximate_noise_model(), because they are helper functions meant to be used only for implementing theapproximate_*functions and they should have been provided as private functions. -
Deprecated
remap_noise_model()since the C++ code now automatically truncates and remaps noise models if it truncates circuits.
Other Notes
- Changes in the implementation of the function
approximate_quantum_error()may change the resulting approximate error compared to Qiskit Aer 0.9.
Ignis 0.7.0
No change
IBM Q Provider 0.18.3
Bug Fixes
- Fix delivered in #1100 for an issue with JSON encoding and decoding when using
ParameterExpressions in conjunction with Qiskit Terra 0.19.1 and above. Previously, theParameterinstances reconstructed from the JSON output would have different unique identifiers, causing them to seem unequal to the input. They will now have the correct backing identities.