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$ Jan 13 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$ Jan 13 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$ Jan 13 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$ Jan 14 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$ Jan 17 at 18:08

Your Answer

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

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