Release Notes



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

Upgrade Notes

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

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

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

Bug Fixes

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

  • Parameters for global phases were not correctly set in #1814. Parameter values for global phases were copied to a template circuit and not to actual circuits to be simulated. This commit correctly copies parameter values to circuits to be simulated.

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

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



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

Known Issues

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

Upgrade Notes

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

Deprecation Notes

  • Options of need to use correct types.

Bug Fixes

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

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

  • Previously, parameters for gates are not validate in C++. If parameters are shorter than expected (due to custom gate), segmentaion faults are thrown. This commit adds checks whether parameter lenght is expceted. This commit will fix issues reported in #1612.

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

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

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

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

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

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

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

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

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

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

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

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

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

  • :meth:QuantumCircuit.initialize() with int value was not processed correctly as reported in #1821 <>. This commit enables such initialization by decomposing initialize instructions.

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



The Qiskit Aer 0.12.0 release highlights are:

  • Added a new GPU tensor network simulator based on cuTensorNet

  • Added a new AerDensityMatrix class to the qiskit_aer.quantum_info module

  • Greatly improving the runtime performance of the AerSimulator and the legacy QasmSimulator, StatevectorSimulator, and UnitarySimulator classes by directly converting the input QuantumCircuit objects to an internal C++ representation instead of first serializing the circuit to a QasmQobj. This improvement will be most noticeable for circuits with a small number of qubits or parameterized circuits using the parameter_binds keyword argument.

New Features

  • Added a new class method from_backend_properties() to the NoiseModel. This enables constructing a new NoiseModel from a BackendProperties object. Similar functionality used to be present in the NoiseModel.from_backend() constructor, however it was removed since a BackendProperties object alone doesn’t contain sufficient information to create a NoiseModel object.

  • Added a new keyword argument, abelian_grouping, to the Estimator. This argument is used to control whether the Estimator will group the input observables into qubit-wise commutable observables which reduces the number of circuit executions required to compute the expectation value and improves the runtime performance of the Estimator. By default this is set to True.

  • AerState has a new method initialize_density_matrix() that sets a density matrix to AER::QV::DensityMatrix. This method will be called in q.i.states.DensityMatrix to initialize its data with ndarray. initialize_density_matrix() has a boolean argument that specifies copy or share of ndarray data. If the data is shared with C++ and python, the data must not be collected in python while C++ accesses it.

  • The overhead for running simulations with run() (for all simulator backend classess) has been greatly reduced. This was accomplished by no longer internally serializing QuantumCircuit objects into QasmQobj and instead the QuantumCircuit object directly to an internal C++ circuit structure used for simulation. This improvement is most noticeable for simulations of circuts with a small number of qubits or parameterized circuits using the parameter_binds keyword argument of run(). Note that pulse simualation (via the now deprecated PulseSimulator) and DASK-based simulation still use the internal serialization and will not see this performance improvement.

  • Added a new method to the AerJob, circuits(), which returns a list of QuantumCircuit objects. This method returns None if Qobj is used for simulation.

  • AerState and AerStatevector now support applying Kraus operators. In AerStatevector, one of the Kraus operators is applied randomly to the quantum state based on the error probabilities.

  • Added a new simulation method based on NVIDIA’s cuTensorNet APIs of cuQuantum SDK. This provides a GPU accelerated general tensor network simulator that can simulate any quantum circuit, by internally translating the circuit into a tensor network to perform the simulation. To use this simulation method, set method="tensor_network" and device="GPU" when initializing an AerSimulator object. For example:

    from qiskit_aer import AerSimulator
    tensor_net_sim = AerSimulator(method="tensor_network", device="GPU")

    This method supports both statevector and density matrix simulations. Noise simulation can also be done with a density matrix single shot simulation if there are not any SaveStatevector operations in the circuit.

    This new simulation method also supports parallelization with multiple GPUs and MPI processes by using tensor network slicing technique. However, this type of simulation will likely take a very long time if the input circuits are complicated.

  • The BLA_VENDOR environment variable can now be specified to use a different BLAS library when building Qiskit Aer from source. By default if this is not specified OpenBLAS will be used by default. If the BLAS library specified in BLA_VENDOR` can not be found then the Cmake build process will stop.

Known Issues

  • This release of Qiskit Aer is not compatible with the Conan 2.X release series. If you are building Qiskit Aer from source manually ensure that you are using a Conan 1.x release. Compatibility with newer versions of Conan will be fixed in a future release. You can refer to issue #1730 for more details.

Upgrade Notes

  • The default behavior of the Estimator primitive will now group the input observable into qubit-wise commutable observables. The grouping reduces the number of circuits to be executed and improves the performance. If you desire the previous behavior you can initialize your Estimator instance with the keyword argument abelian_grouping=False.

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

  • The behavior of run() method has changed when invalid or otherwise unsimulatable QuantumCircuit objects are passed as an input. Previously, in these cases the run() method would return an AerJob whose result() method would return a Result with the ERROR or PARTIAL COMPLETED (depending on whether all the circuit inputs or only some were invalid or not). Starting in this release instead of returning a result object with these statuses an exception will be raised instead. This change was necessary because of the performance improvements by no longer internally serializing the QuantumCircuit objects to a Qobj before passing it to C++, instead the direct conversion from QuantumCircuit now errors directly when trying to simulate a circuit Qiskit Aer is unable to execute. If you desire the previous behavior you can build Qiskit Aer in standalone mode and manually serialize your QuantumCircuit objects to a JSON representation of the QasmQobj which you then pass to the standalone Aer binary which will retain the previous behavior.

  • A deprecated method add_nonlocal_quantum_error() in NoiseModel has been removed. No alternative method is available. If you want to add non-local quantum errors, you should write a transpiler pass that inserts your own quantum error into a circuit, and run the pass just before running the circuit on Aer simulator.

  • A deprecated standard_gates argument broadly used in several methods and functions (listed below) across noise module has been removed.

    • NoiseModel.from_backend() and noise.device.basic_device_gate_errors()

    • kraus_error(), mixed_unitary_error(), pauli_error() and depolarizing_error() in noise.errors.standard_errors

    • QuantumError.__init__()

    No alternative means are available because the user should be agnostic about how the simulator represents noises (quantum errors) internally.

  • The constructor of QuantumError has now dropped the support of deprecated json-like input for noise_ops argument. Use the new styple input for noise_ops argument instead, for example,

    from qiskit.circuit.library import IGate, XGate
    from qiskit_aer.noise import QuantumError
    error = QuantumError([
        ((IGate(), [1]), 0.9),
        ((XGate(), [1]), 0.1),
    # json-like input is no longer accepted (the following code fails)
    #  error = QuantumError([
    #      ([{"name": "I", "qubits": [1]}], 0.9),
    #      ([{"name": "X", "qubits": [1]}], 0.1),
    #  ])

    Also it has dropped deprecated arguments:

    • number_of_qubits: Use QuantumCircuit to define noise_ops instead.

    • atol: Use QuantumError.atol attribute instead.

    • standard_gates: No alternative is available (users should not too much care about internal representation of quantum errors).

  • The deprecated noise.errors.errorutils module has been entirely removed and no alternatives are available. All functions in the module were helper functions meant to be used only for implementing functions in standard_errors (i.e. they should have been provided as private functions) and no longer used in it.

  • The deprecated utils.noise_remapper have been entirely removed and no alternatives are available since the C++ code now automatically truncates and remaps noise models if it truncates circuits.

  • All deprecated functions (pauli_operators() and reset_operators()) and class (NoiseTransformer) in utils.noise_transformation module have been removed, and no alternatives are available. They were in fact private functions/class used only for implementing approximate_quantum_error() and should not have been public.

  • The previously deprecated qobj argument name of the AerSimulator and PulseSimulator classes’ run() method has now been removed. This argument name was deprecated as part of the Qiskit Aer 0.8.0 release and has been by the circuits and schedules argument name respectively.

  • Aer’s has been updated to no longer attempt to make calls to pip to install build requirements, both manually and via the setup_requires option in setuptools.setup. The preferred way to build Aer is to use a PEP 517-compatible builder such as:

    pip install .

    This change means that a direct call to will no longer work if the build requirements are not installed. This is inline with modern Python packaging guidelines.

Deprecation Notes

  • Support for running Qiskit Aer with Python 3.7 support has been deprecated and will be removed in a future release. This means starting in a future release you will need to upgrade the Python version you’re using to Python 3.8 or above.

  • The PulseSimulator backend has been deprecated and will be removed in a future release. If you’re using the PulseSimulator backend to perform pulse level simulation, instead you should use the Qiskit Dynamics library instead to perform the simulation. Qiskit Dynamics provides a more flexible and robust pulse level simulation framework than the PulseSimulator backend.

  • The qobj() method of the AerJob class is now deprecated and will be removed in a future release. The use of the qobj format as input to run() has been deprecated since qiskit-aer 0.9.0 and in most cases this method would return None now anyway. If you’d like to get the input to the run() method now you can use the circuits() method instead, which will return the QuantumCircuit objects that were simulated in the job.

  • A warnings argument broadly used in several methods and functions across noise module has been deprecated in favor of the use of filtering functions in Python’s standard warnings library.

Bug Fixes

  • Fixed an issue when creating a new AerStatevector instance from a numpy.ndarray that had non-contiguous memory. Previously, this would result in unexpected behavior (and a potential error) as the AerStatevector assumed the input array was contiguous. This has been fixed so that memory layout is checked and the numpy.ndarray will be copied internally as a contiguous array before using it.

  • Fixed an issue with the Sampler class where it would previously fail if the input QuantumCircuit contained multiple multiple classical registers. Fixed #1679

  • The bits count of classical register used on the GPU was not set before calculating free available memory for chunks that causes infinite loop. So this fix set bits count before allocating chunks if batch shots execution is enabled.

  • Fix build errors and test errors when enabling GPU but disabling cuQuantum.

  • Fixed an issue in the matrix product state simulation method (i.e. setting the keyword argument method="matrix_product_state" when initializing an AerSimulator object) where the simulator would incorrectly sort the qubits prior to performing measurment potentially resulting in an infinite loop. This has been fixed so the measurement of the qubits occurs in the order of the current MPS structure and then sorting afterwards as a post-processing step. This also will likely improve the performance of the simulation method and enable more accurate representation of entangled states. Fixed #1694

  • The AerSimulator backend with methods:

    • statevector

    • density_matrix

    • matrix_product_state

    • stabilizer

    now report that they support break_loop and continue_loop instructions when used as backends for the Terra transpile() function. The simulators already did support these, but had just not been reporting it.



The Qiskit Aer 0.11.0 release highlights are:

New Features

  • Added support for BackendV2 to from_backend(). Now it can generate a NoiseModel object from an input BackendV2 instance. When a BackendV2 input is used on from_backend() the two deprecated options, standard_gates and warnings, are gracefully ignored.

  • Added Aer implementation of primitives, Sampler and BaseSampler and BaseEstimator interfaces leverage qiskit aer to efficiently perform the computation of the primitive operations. You can refer to the qiskit.primitives docs for a more detailed description of the primitives API.

  • Added a shared library to Qiskit Aer that allows external programs to use Aer’s simulation methods. This is an experimental feature and its API may be changed without the deprecation period.

  • 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.

  • Added support for cuQuantum, NVIDIA’s APIs for quantum computing, to accelerate statevector, density matrix and unitary simulators by using GPUs. This is experiemental implementation for cuQuantum Beta 2. (0.1.0) cuStateVec APIs are enabled to accelerate instead of Aer’s implementations by building Aer by setting path of cuQuantum to CUSTATEVEC_ROOT. (binary distribution is not available currently.) cuStateVector is enabled by setting device='GPU' and cuStateVec_threshold options. cuStateVec is enabled when number of qubits of input circuit is equal or greater than cuStateVec_threshold.

  • Added partial support for running on ppc64le and s390x Linux platforms. This release will start publishing pre-compiled binaries for ppc64le and s390x Linux platforms on all Python versions. However, unlike other supported platforms not all of Qiskit’s upstream dependencies support these platforms yet. So a C/C++ compiler may be required to build and install these dependencies and a simple pip install qiskit-aer with just a working Python environment will not be sufficient to install Qiskit Aer. Additionally, these same constraints prevent us from testing the pre-compiled wheels before publishing them, so the same guarantees around platform support that exist for the other platforms don’t apply to these platforms.

  • Allow initialization with a label, that consists of +-rl. Now the following code works:

    import qiskit
    from qiskit_aer import AerSimulator
    qc = qiskit.QuantumCircuit(4)

Known Issues

  • When running on Linux s390x platforms (or other big endian platforms) running circuits that contain UnitaryGate operations will not work because of an endianess bug. See #1506 for more details.

Upgrade Notes

  • MPI parallelization for large number of qubits is optimized to apply multiple chunk-swaps as all-to-all communication that can decrease data size exchanged over MPI processes. This upgrade improve scalability of parallelization.

  • Set default fusion_max_qubit and fusion_threshold depending on the configured method for AerSimulator. Previously, the default values of fusion_max_qubit and fusion_threshold were 5 and 14 respectively for all simulation methods. However, their optimal values depend on running methods. If you depended on the previous defaults you can explicitly set fusion_max_qubit=5 or fusion_threshold=14 to retain the previous default behavior. For example:

    from qiskit_aer import AerSimulator
    sim = AerSimulator(method='mps', fusion_max_qubit=5, fusion_threshold=14)
  • This is update to support cuQuantum including bug fix of thread safety in some cuStateVec APIs. Now Qiskit Aer turns on multi-threading for multi-shots and multi-chunk parallelization when enabling cuStateVec.

  • Running qiskit-aer with Python 3.6 is no longer supported. Python >= 3.7 is now required to install and run qiskit-aer.

  • The qiskit-aer Python package has moved to be a self-contained namespace, qiskit_aer. Previously, it shared a namespace with qiskit-terra by being qiskit.providers.aer. This was problematic for several reasons, and this release moves away from it. For the time being import qiskit.providers.aer will continue to work and redirect to qiskit_aer automatically. Imports from the legacy qiskit.provider.aer namespace will emit a DeprecationWarning in the future. To avoid any potential issues starting with this release, updating all imports from qiskit.providers.aer to qiskit_aer and from qiskit.Aer to qiskit_aer.Aer is recommended.

  • Removed snapshot instructions (such as SnapshotStatevector) which were deprecated since 0.9.0. Applications that use these instructions need to be modified to use corresponding save instructions (such as SaveStatevector).

  • Removed the qiskit_aer.extensions module completely. With the removal of the snapshot instructions, this module has become empty and no longer serves a purpose.

  • The required version of Qiskit Terra has been bumped to 0.20.0.

Bug Fixes

  • Fixes for MPI chunk distribution. Including fix for global indexing for Thrust implementations, fix for cache blocking of non-gate operations. Also savestatevector returns same statevector to all processes (only 1st process received statevector previously.)

  • Handles a multiplexer gate as a unitary gate if it has no control qubits. Previously, if a multiplexer gate does not have control qubits, quantum state was not updated.

  • Fixes a bug in RelaxationNoisePass where 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.

  • Fixed simulation of for loops 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_aer import AerSimulator
    qc = qiskit.QuantumCircuit(2)
    with qc.for_loop(range(4)) as i:
        qc.h(0), 1)
  • Fixes a bug in NoiseModel.from_backend() that raised an error when T2 value greater than 2 * T1 was supplied by the backend. After this fix, it becomes to truncate T2 value up to 2 * T1 and issue a user warning if truncates. The bug was introduced at #1391 and, before that, NoiseModel.from_backend() had truncated the T2 value up to 2 * T1 silently.

    See Issue 1464 for details.

  • 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.

  • This is the fix for Issue #1557. Different seed numbers are generated for each process if seed_simulator option is not set. This fix average seed set in Circuit for all processes to use the same seed number.

  • This is a fix of MPI parallelization for multi-chunk parallelization and multi-shot distribution over parallel processes. There were missing distribution configuration that prevents MPI distribution, is now fixed.

  • This is fix for cache blocking transpiler and chunk parallelization for GPUs or MPI. This fix fixes issue with qubits which has many control or target qubits (> blocking_qubits). From this fix, only target qubits of the multi-controlled gate is cache blocked in blocking_qubits. But it does not support case if number of target qubits is still larger than blocking_qubits (i.e. large unitary matrix multiplication)

  • 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.

  • Because a seed was randomly assigned to each circuit if seed_simulator is not set, multi-circuit simulation was not reproducible with another multi-circuit simulation. Users needed to run multiple single-circuit simulation with the seed_simulator which is randomly assigned in the multi-circuit simulation. This fix allows users to reproduce multi-circuit simulation with another multi-circuit simulation by setting seed_simulator of the first circuit in the first multi-circuit simulation. This fix also resolve an issue reported in, where simulation with parameter-binds returns identical results for each circuit instance.

  • Fix performance issue in multi-shots batched optimization for GPU when using Pauli noise. This fix allows multi-threading to runtime noise sampling, and uses nested OpenMP parallelization when using multiple GPUs. This is fix for issue 1473 <>

  • This is the fix for cuStateVec support, fix for build error because of specification change of some APIs of cuStateVec from cuQuantum version 0.40.



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 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 simulation method of either "statevector" or "density_matrix" with the AerSimulator. It can be disabled by setting batched_shots_gpu=False in 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_qubits simulator option. The default value of this option is 16.

  • Added the new max_shot_size option to a custom executor for running multiple shots of a noisy circuit in parallel.

    For example configuring max_shot_size with a custom executor:

    backend = AerSimulator(
       max_shot_size=1, max_job_size=1, executor=custom_executor)
    job =

    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 Result object that is returned by job.result().

  • Added the mps_swap_direction simulator 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 the AerSimulator. Currently this algorithm is used only when all qubits are measured and when the simulator mps_sample_measure_algorithm simulator option is set to "mps_probabilities".

  • Improved the performance of the measure instruction for the "matrix_product_state" simulation method of the AerSimulator.

  • Added a SaveClifford instruction for saving the state of the stabilizer simulation method as a Clifford object.

    Note that this instruction is essentially equivalent to the SaveStabilizer instruction, however that instruction will return the saved state as a StabilizerState object instead of a Clifford object.

  • Added two transpiler passes for inserting instruction-dependent quantum errors into circuits:

    • qiskit.providers.aer.noise.LocalNoisePass

    • qiskit.providers.aer.noise.RelaxationNoisePass

    The LocalNoisePass pass can be used to implement custom parameterized noise models by defining a noise generating function of the form

    def fn(
        inst: Instruction,
        qubits: Optional[List[int]] = None,
    ) -> InstructionLike

    which returns a noise instruction (eg. a QuantumError or 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 LocalNoisePass documentation for additional details.)

    The RelaxationNoisePass is a special case of the LocalNoisePass using a predefined noise function that returns a tensor product of thermal_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() and AerSimulator.from_backend() has been upgraded to allow adding duration-dependent relaxation errors on circuit delay gates using the RelaxationNoisePass.

    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 =

    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 QuantumError now accepts several new types of input as noise_ops argument, 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)
    # Construction from a QuantumCircuit
    qc = QuantumCircuit(2)
    qc.h(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 all QuantumErrors in the noise model.

  • Added two utility functions qiskit.providers.aer.utils.transpile_quantum_error() and qiskit.providers.aer.utils.transpile_noise_model() for transpiling the circuits contained in QuantumError, and all errors in a NoiseModel.

  • Added the ability to add QuantumError objects directly to a QuantumCircuit without converting to a Kraus instruction.

    Circuits containing quantum errors can now be run on the AerSimulator and QasmSimulator simulators as an alternative to, or in addition to, building a NoiseModel for defining noisy circuit instructions.


    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.append(error_h, [0]), 1)
    qc.append(error_cx, [0, 1]), 2)
    qc.append(error_cx, [0, 2])
    backend = AerSimulator(method='stabilizer')
    result =

    Circuits containing quantum errors can also be evaluated using the quantum_info quantum channel and DensityMatrix classes.

Upgrade Notes

  • Changed the default value of standard_gates to None for all functions in qiskit.providers.aer.noise.errors.standard_errors as those functions are updated so that they use standard gates by default.

Deprecation Notes

  • Using NumPy ndarray methods and attributes on the return type of save_statevector(), save_density_matrix(), save_unitary(), and save_superop() has been deprecated, and will stop working in a future release. These instructions now return qiskit.quantum_info classes 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 BackendProperties object for the backend argument of NoiseModel.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 Terra BackendV1 object instead.

  • Deprecated the number_of_qubits option of the QuantumError constructor in favor of automatic determination of the dimension.

  • Deprecated the standard_gates option of the QuantumError constructor in favor of externalizing such basis-change functionality. In many cases, you can transform any error into an error defined only with specific gates using approximate_quantum_error().

  • Deprecated the standard_gates option of all functions in qiskit.providers.aer.noise.errors.standard_errors in favor of returning errors in the form of a mixture of standard gates as much as possible by default.

  • Deprecated all functions in errorutils because they are helper functions meant to be used only for implementing functions in qiskit.providers.aer.noise.errors.standard_errors and they should have been provided as private functions.

  • Deprecated the standard_gates option of NoiseModel.from_backend() in favor of externalizing such basis-change functionality.

  • Deprecated all public variables, functions and classes in qiskit.providers.aer.noise.utils.noise_transformation except for approximate_quantum_error() and approximate_noise_model(), because they are helper functions meant to be used only for implementing the approximate_* 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.



The 0.9 release includes new backend options for parallel exeuction of large numbers of circuits on a HPC cluster using a Dask distributed, along with other general performance improvements and bug fixes.

New Features

  • Add qiskit library SXdgGate and CUGate to the supported basis gates for the Aer simulator backends. Note that the CUGate gate is only natively supported for the statevector and unitary methods. For other simulation methods it must be transpiled to the supported basis gates for that method.

  • Adds support for N-qubit Pauli gate ( qiskit.circuit.library.generalized_gates.PauliGate) to all simulation methods of the AerSimulator and QasmSimulator.

  • Adds the ability to set a custom executor and configure job splitting for executing multiple circuits in parallel on a HPC clustor. A custom executor can be set using the executor option, and job splitting is configured by using the max_job_size option.

    For example configuring a backend and executing using

    backend = AerSimulator(max_job_size=1, executor=custom_executor)
    job =

    will split the exection into multiple jobs each containing a single circuit. If job splitting is enabled the run method will return a AerJobSet object containing all the individual AerJob classes. After all individual jobs finish running the job results are automatically combined into a single Result object that is returned by job.result().

    Supported executors include those in the Python concurrent.futures module (eg. ThreadPoolExecutor, ProcessPoolExecutor), and Dask distributed Client executors if the optional dask library is installed. Using a Dask executor allows configuring parallel execution of multiple circuits on HPC clusters. See the Dask executor API Documentation for additional details on using Dask executors for HPC simulation.

Upgrade Notes

  • The default basis for the NoiseModel class has been changed from ["id", "u3", "cx"] to ["id", "rz", "sx", "cx"] due to the deprecation of the u3 circuit method in qiskit-terra and change of qiskit-ibmq-provider backend basis gates. To use the old basis gates you can initialize a noise model with custom basis gates as NoiseModel(basis_gates=["id", "u3", "cx"]).

  • Removed the backend_options kwarg from the run methnod of Aer backends that was deprecated in qiskit-aer 0.7. All run options must now be passed as separate kwargs.

  • Removed passing system_model as a positional arg for the run method of the PulseSimulator.

Deprecation Notes

  • Passing an assembled qobj directly to the run() method of the Aer simulator backends has been deprecated in favor of passing transpiled circuits directly as, **run_options).

  • All snapshot instructions in qiskit.providers.aer.extensions have been deprecated. For replacement use the save instructions from the qiskit.providers.aer.library module.

  • Adding non-local quantum errors to a NoiseModel has been deprecated due to inconsistencies in how this noise is applied to the optimized circuit. Non-local noise should be manually added to a scheduled circuit in Qiskit using a custom transpiler pass before being run on the simulator.

  • Use of the method option of the StatevectorSimulator, and UnitarySimulator to run a GPU simulation has been deprecated. To run a GPU simulation on a compatible system use the option device='GPU' instead.

Bug Fixes

  • Fixes bug where the if the required memory is smaller than the system memory the multi-chunk simulation method was enabled and simulation was still started. This case will now throw an insufficient memory exception.

  • Fixes issue where setting the shots option for a backend with set_options(shots=k) was always running the default number of shots (1024) rather than the specified value.

  • Fixes a bug in how the AerSimulator handled the option value for max_parallel_experiments=1. Previously this was treated the same as max_parallel_experiments=0.

  • Fixes bug in the extended_stabilizer simulation method where it incorrectly treated qelay gate and multi-qubit Pauli instructions as unsupported.

  • Fixes typo in the AerSimulator and QasmSimulator options for the extended_stabilizer_norm_estimation_repetitions option.