Configure error suppression
Error suppression refers to techniques where you use knowledge about the undesirable effects to introduce customization that can anticipate and avoid the potential impacts of those effects. These techniques often consist of altering or adding control signals to ensure that the quantum processor returns the desired results. This typically results in quantum pre-processing overhead; therefore, it is important to achieve a balance between perfecting your results and ensuring that your job completes in a reasonable amount of time.
V2 primitives support a number of error suppression techniques, including dynamical decoupling and Pauli twirling. See Error mitigation and suppression techniques for an explanation of each. In V2 primitives, you can turn on or off individual methods. See the Advanced error suppression options section for details.
Estimator V2 employs error suppression and mitigation by default. If you don't want any processing done to your input circuits, follow the instructions in the Turn off all error mitigation and error suppression section.
To ensure faster and more efficient results, as of 1 March 2024, circuits and observables need to be transformed to only use instructions supported by the QPU (referred to as instruction set architecture (ISA) circuits and observables) before being submitted to the Qiskit Runtime primitives. See the transpilation documentation for instructions to transform circuits. Due to this change, the primitives will no longer perform layout or routing operations. Consequently, transpilation options referring to those tasks will no longer have any effect. By default, all V1 primitives optimize the input circuits. To bypass all optimization when using a V1 primitive, set optimization_level=0
.
Exception: When you initialize the Qiskit Runtime Service with the Q-CTRL channel strategy (example below), abstract circuits are still supported.
service = QiskitRuntimeService(channel="ibm_cloud", channel_strategy="q-ctrl")
Set the optimization level (V1 primitives only)
The optimization_level
setting specifies how much optimization to perform on the circuits. Higher levels generate more optimized circuits, at the expense of longer compile times.
Optimization levels 2 and 3 behave identically to level 1.
Optimization Level | Estimator & Sampler |
---|---|
0 | No optimization: typically used for hardware characterization or debugging |
1, 2, 3 | Light optimization:
|
If using an IBM Cloud® Qiskit Runtime service instance with Q-CTRL performance management enabled, there is no need to specify runtime optimization or resilience levels, as the strategy includes an automatic preset.
Q-CTRL defaults to optimization_level=3
and resilience_level=1
.
Setting optimization_level
or resilience_level
equal to 0 will result in an
execution error. Levels 1, 2, and 3 are permitted but will not impact performance.
Setting other options will likewise not impact performance, and it may result in a
runtime warning. For more information visit the Q-CTRL documentation(opens in a new tab).
Example: configure Estimator with optimization levels
from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.circuit.library import RealAmplitudes
from qiskit.quantum_info import SparsePauliOp
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
psi = RealAmplitudes(num_qubits=2, reps=2)
H = SparsePauliOp.from_list([("II", 1), ("IZ", 2), ("XI", 3)])
theta = [0, 1, 1, 2, 3, 5]
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
psi = pm.run(psi)
H = H.apply_layout(psi.layout)
estimator = Estimator(mode=backend)
job = estimator.run([(psi, H, theta)])
psi1_H1 = job.result()[0]
from qiskit_ibm_runtime import QiskitRuntimeService, Estimator, Options
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.circuit.library import RealAmplitudes
from qiskit.quantum_info import SparsePauliOp
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
options = Options(optimization_level=1)
psi = RealAmplitudes(num_qubits=2, reps=2)
H = SparsePauliOp.from_list([("II", 1), ("IZ", 2), ("XI", 3)])
theta = [0, 1, 1, 2, 3, 5]
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
psi = pm.run(psi)
H = H.apply_layout(psi.layout)
estimator = Estimator(options=options, backend=backend)
job = estimator.run(circuits=[psi], observables=[H], parameter_values=[theta])
psi1_H1 = job.result()
If the optimization level is not specified, the service uses optimization_level = 1
.
Advanced error suppression options
In the V2 primitives, you can explicitly enable and disable individual error mitigation and suppression methods, such as dynamical decoupling.
- Not all options are available for both primitives. See the available options table for the list of available options.
- Not all methods work together on all types of circuits. See the options compatibility table for details.
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import SamplerV2 as Sampler
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
sampler = Sampler(backend)
# Turn on dynamical decoupling with sequence XpXm.
sampler.options.dynamical_decoupling.enable = True
sampler.options.dynamical_decoupling.sequence_type = "XpXm"
print(f">>> dynamical decoupling sequence to use: {sampler.options.dynamical_decoupling.sequence_type}")
Because all input must be ISA, options.transpilation.xxx
is ignored. See Advanced runtime options for information.
Turn off all error suppression
For instructions to turn off all error suppression, see the Turn off all error suppression and mitigation section.
Next steps
- Learn more about error mitigation and error suppression techniques.
- Configure error mitigation.
- Explore other options.
- Decide what execution mode to run your job in.