iTranslated by AI
Playing with Qiskit (24) — Using Qiskit Runtime local testing mode
Purpose
According to Qiskit Runtime local testing mode:
Local testing mode (available with
qiskit-ibm-runtime0.22.0 or later) can be used to help develop and test programs before fine-tuning them and sending them to real quantum hardware.
I want to try this out. Broadly speaking, it seems that the way we used to write code to submit jobs to actual devices on the cloud can now be done locally. By simply switching the backend specification from fake backends or simulators to actual devices, we can experiment on simulators or actual hardware without rewriting the code.
Implementation
Installing Qiskit
Anything works as long as qiskit-ibm-runtime 0.22.0 or later is available, but for now, I'll try installing it by specifying the version.
%%bash
pip install -U "qiskit==1.0.2" "qiskit[visualization]==1.0.2" "qiskit-aer==0.13.3"
pip install -U qiskit-ibm-runtime=="0.22.0"
Importing necessary modules
Implementation following the Example. For comparison, I've also imported several fake backends. As mentioned in Migrate to the Qiskit Runtime V2 primitives, Qiskit Runtime V2 primitives have also been released, so I will use those as well. From a brief look, the way to specify error mitigation has changed. In SamplerV2, dynamic decoupling seems available when the real hardware supports it, but since I am doing this locally, it won't be used.
from qiskit_aer import AerSimulator
from qiskit.circuit import QuantumCircuit
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.visualization import plot_histogram
from qiskit_ibm_runtime import (
Session,
SamplerV2 as Sampler,
QiskitRuntimeService,
)
from qiskit_ibm_runtime.fake_provider import (
FakeManilaV2,
FakeSherbrooke,
FakeTorino,
)
Experiment
Sampling the Bell state exactly as in the Example.
# Bell Circuit
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
qc.measure_all()
# Assuming account information has been saved beforehand
service = QiskitRuntimeService()
use_real = True
if use_real:
real_backend = service.backend("ibm_brisbane") # Actual device
backend = AerSimulator.from_backend(real_backend) # Load device info into the simulator
else:
# backend = FakeManilaV2() # Fake backend with 5 qubits
backend = FakeTorino() # Fake backend with 133 qubits
# backend = AerSimulator() # Noise-free simulator
# Run the sampler job locally using AerSimulator.
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_qc = pm.run(qc)
with Session(backend=backend) as session:
sampler = Sampler(session=session)
result = sampler.run([isa_qc]).result()
Checking the results
pub_result = result[0]
plot_histogram(pub_result.data.meas.get_counts())
You can view the results with the code above.
In the case of a noise-free simulator
Naturally,

In the case of ibm_brisbane (loaded from the simulator)
The result includes some noise. By setting backend = real_backend, the job will be sent to the actual device.

Circuit Visualization
Circuit without Pass Manager
Just as it is.
qc.draw("mpl", style="clifford")

Circuit with Pass Manager
To be honest, I don't really understand what the pass manager is even after reading Qiskit v0.45 is here!, but I suppose it is fine to use generate_preset_pass_manager from Preset Passmanagers just like in the example.
As a result, we obtain the transpiled circuit.
isa_qc.draw("mpl", style="clifford")

ibm_brisbane Layout
Finally, let's wrap up by looking at the layout of ibm_brisbane. In this case, it looks like only the two qubits in the upper right were used.
real_backend.coupling_map.draw()

Summary
Qiskit updates are frequent, so new ways of writing code appear before you know it. If I don't update occasionally, it becomes confusing.
This time, I tried it out because the same coding style used on the cloud can now be used locally.
Discussion