[Abstract] IBM Qiskit is used as a typical development environment for quantum computing. Its version is frequently updated, and some parts are soon deprecated, which can be confusing. The description of quantum gates and quantum circuits remains almost the same, but there are frequent changes in simulations and execution methods on actual machines. Here, I would like to note three typical execution methods at the present time (2024-11-10).
🔴Example: Quantum computation part of Shor's prime factorization algorithm
Here, we will focus only on running the order finding quantum circuit, which is the main part of Shor's algorithm. Fig.1 shows the prime factorization of the very small integer 15 (15 = 3 × 5) for demonstration purposes. We will not explain the relationship between the entire Shor algorithm and the quantum circuit in Fig.1 this time, so if necessary, please refer to the following past articles.
🔴[1] Simulation with Qiskit Sampler (run on local PC)
Qiskit Sampler is the most common simulator for running a quantum circuit (name: qc) like the one in Fig.1 (including measuring the lower three qubits). The main points of its use are as follows. The results of this simulation (measurement results of 1,000 shots) are shown in Fig.2.
# Running the Simulation
from qiskit_aer.primitives import Sampler
sampler = Sampler()
result = sampler.run(qc, shots=1000).result()
# Extraction and visualization of measurement results
quasi_dists = result.quasi_dists
binary_quasi_dist = quasi_dists[0].binary_probabilities()
counts_dict = quasi_dists[0].binary_probabilities()
counts = Counts(counts_dict)
plot_histogram(counts)
🔴[2] Simulation incorporating a noise model of the actual machine (run on a local PC)
In the above, the simulation results (Fig.2) show that the counts corresponding to the four bases are approximately 25% each, and the counts of the other bases are zero as expected because there is no noise. In addition to using a normal sampler like this, it is also possible to perform simulations that reflect the noise generated by the actual quantum computer.
Fig. 3 shows the result of incorporating a noise model generated by a real machine (127-qubits) named ibm_sherbrooke into AerSimulator and running it. Indeed, the effects of noise that did not occur in Fig. 2 are apparent. This may be useful for preliminary examination before running on a real machine.
# important imports
from qiskit_aer import AerSimulator
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler
# Set the noise model of the real machine
real_backend = service.backend("ibm_sherbrooke")
aer = AerSimulator.from_backend(real_backend)
pm = generate_preset_pass_manager(backend=aer, optimization_level=1)
isa_qc = pm.run(qc) # transpile for the real machine
sampler = Sampler(mode=aer)
result = sampler.run([isa_qc],shots=1000).result() # execution
# Extraction and visualization of measurement results
pub_result = result[0]
counts = pub_result.data.c.get_counts() # Note the 'c' !
plot_histogram(counts)
🔴[3] Execution on an actual IBM Quantum machine (submitting a job via the web)
Next, the job was submitted to an actual IBM Quantum machine via the web and executed. The machine was ibm_sherbrooke, the same as that given in the noise model above. The job was executed in batch mode, so the execution results were retrieved via the web after it was completed. This is shown in Fig. 4, and it was found to be almost identical to the simulation results shown in Fig. 3, which reflect the above noise model.
# Automatically select machines with low load
from qiskit_ibm_runtime import SamplerV2 as Sampler
service = QiskitRuntimeService(channel="ibm_quantum", token= "***")
be = service.least_busy(simulator=False, operational=True)
print(f"QPU backend:{be}")
# Transpile for real machine and submit the job
pm = generate_preset_pass_manager(optimization_level=1, backend=be)
ic = pm.run(qc) # Transpiled circuit
job = Sampler(be).run([ic], shots= 1000)
print(f"job ID: {job.job_id()}")
print(f"job statusI: {job.status()}")
# After execution, the results are retrieved and displayed
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService(
channel='ibm_quantum',
instance='ibm-q/open/main',
token='token for the job'
)
job = service.job('jab ID')
job_result = job.result()
counts = job.result()[0].data.c.get_counts()
plot_histogram(counts)
The execution status is shown in Fig. 5. Usage = 2 sec. Free users are limited to 10 minutes of usage per month. This is sufficient for testing simple quantum circuits, but caution is required when testing slightly more complex quantum circuits, as this can result in unexpectedly high usage. At present, there are three models of actual machines available for free use, as shown in Fig. 6. For paid users, eight more models of actual machines can be used in addition to these.
🔴 Differences between the results of a real machine and a simulator
Currently, quantum computers generate various noises, which causes errors. For example, the difference between the results of a pure simulator (Fig. 2) and the results of a real machine (Fig. 4) shows this. Although it cannot be said in general, errors that occur on a real machine can have a large impact on the necessary calculations. However, in the case of this example problem, due to the nature of probabilistically searching for an order, it can be said that the difference between Fig. 2 and Fig. 4 is almost no problem.