I have the following code to run an Estimator primitive by using Qiskit Runtime. It computes the expectation value $\langle O \rangle = \langle \psi | O | \psi \rangle$ (in this example $\langle 0 | Z | 0 \rangle = 1$ with zero variance):

from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit_ibm_runtime import QiskitRuntimeService, Options, Session, Estimator

# prepare the state |Ψ>
qc = QuantumCircuit(1)

# define the operator/observable O
O = SparsePauliOp(['Z'])

service = QiskitRuntimeService()
backend = 'ibmq_qasm_simulator'
options = Options(resilience_level=0)

with Session(service=service, backend=backend) as session:
    estimator = Estimator(session=session, options=options)
    job = estimator.run(circuits=[qc], observables=[O])


I know that Qiskit Runtime primitives can run on real IBM quantum devices but what I'm wondering whether is possible run them by using fake backends (or, more in general, custom noise models). For example, how can I run the code above on the FakeManila backend or passing a NoiseModel instance? Is there any other way to do that?


1 Answer 1


Using primitives with fake backends

You can use BackendEstimator to work with fake backends. As primitives implementation, BackendEstimator and BackendSampler are designed to be generic that can work with almost any backend.

from qiskit.primitives import BackendEstimator

estimator = BackendEstimator(backend = FakeNairobi())

job = estimator.run(qc, O)
result = job.result()

Note that, if you are dealing with a provider that has native primitive implementations, like Qiskit Runtime or Qiskit Aer, you should use that native implementation. Most probably, it will be much more efficient.

Using primitives with Qiskit runtime noisy simulators

If what you want is to use primitives with Qiskit runtime noisy simulators, you can easily do that by creating the NoiseModel and passing it to the estimator options as follows:

from qiskit_aer.noise import NoiseModel

noisy_backend = service.get_backend('ibm_nairobi')
backend_noise_model = NoiseModel.from_backend(noisy_backend)

simulator = service.get_backend('ibmq_qasm_simulator')

options = Options()
options.resilience_level = 0
options.optimization_level = 0
options.simulator = {
    "noise_model": backend_noise_model

with Session(service=service, backend=simulator) as session:
    estimator = Estimator(session=session, options=options)
    job = estimator.run(circuits=qc, observables=O)
  • $\begingroup$ Ok thank you! It seems that the Qiskit Runtime provider does not include fake backends right? $\endgroup$ Commented Jan 13, 2023 at 13:09
  • 1
    $\begingroup$ That's correct. However, that does not mean you can't load a custom NoiseModel into runtime simulators. I updated my answer to cover this point. $\endgroup$ Commented Jan 13, 2023 at 15:32
  • $\begingroup$ That looks fine, thank you. However, I tried to run the simulation loading the custom noise model but I still get perfect result with variance 0. I think this is an already encountered issue, previously mentioned here. $\endgroup$ Commented Jan 13, 2023 at 17:39
  • $\begingroup$ Code works with me without issue. Try to increase the depth of your circuit such that the noise affects the result. e.g., qc = random_circuit(1, 10, 1, seed=1) $\endgroup$ Commented Jan 14, 2023 at 6:27
  • 1
    $\begingroup$ Noise model should be passed to estimator options instead of passing it to the simulator. I updated my answer to correct the code snippet. $\endgroup$ Commented Jan 17, 2023 at 18:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.