Build and run your first quantum program
Introduction
In the following video, Olivia Lanes steps you through the content in this lesson. Alternatively, you can open the YouTube video for this lesson in a separate window.
Welcome to Use a quantum computer today! The goal of this course is for you to run code on a real quantum computer in the shortest time possible, with no prior background required. Let's get started.
This first lesson is a gentle, hands-on introduction to quantum computing that works for curious beginners and busy leaders alike. You'll learn about quantum circuits and write a small quantum program that creates entanglement, and run it on a real IBM® quantum computer. You also have the option to run the same program on a simulator, should you choose to skip running on a real quantum computer.
You can run this notebook from top to bottom in a fresh Google Colab runtime, or run locally.
Set up
To run this notebook in Google Colab, you'll need a Google account so you can open notebooks and execute cells in the browser.
To run on a real IBM quantum computer, you'll also need an IBM Quantum® Platform account. This is completely free, and with an Open account, you get 10 minutes of quantum processor unit (QPU) time per month, which actually is quite a lot!
You can also run this notebook locally after installing Qiskit by following the instructions on IBM Quantum Platform.
Installation and imports
In Colab, we install dependencies inside the notebook so everyone runs the same tools. The next cell installs Qiskit with the visualization module plus two add-ons: Aer (fast simulators) and the IBM Runtime client (for quantum computer runs).
Next, we have a number of imports. The QuantumCircuit class is where we define our quantum bits, or qubits, and define operations on those qubits. This is our first quantum term: a qubit is the basic building block of quantum computation, just as a bit is the building block of classical computation. We'll learn more about the special properties of qubits as we create our circuit. Next, plot_histogram will be used to visualize the results of our quantum circuit. AerSimulator, allows us to simulate the quantum circuit on a classical computer. But simulators cannot run quantum circuits at the same scale as real quantum computers; that's why we need real quantum computers. This can be helpful for testing, debugging, or educational purposes; or if you've exhausted your 10 free minutes of QPU time. The preset_passmanagers help optimize the circuits to run efficiently on hardware, which becomes really important as our circuits become more complex. Sampler and QiskitRuntimeService are necessary to actually run the circuit on the quantum computer. More on this later.
!pip install 'qiskit[visualization]' qiskit-ibm-runtime qiskit-aer
# Core Qiskit imports
from qiskit import QuantumCircuit
from qiskit.visualization import plot_histogram
from qiskit_aer import AerSimulator
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
# IBM Runtime specific imports
from qiskit_ibm_runtime import SamplerV2 as Sampler, QiskitRuntimeServiceNext we'll do a quick environment check. We confirm versions and confirm imports.
If anything fails here, it's usually a dependency install issue; fixing it now prevents confusing errors later.
import sys
import qiskit
import qiskit_aer
import qiskit_ibm_runtime
print("Python:", sys.version.split()[0])
print("qiskit:", qiskit.__version__)
print("qiskit-aer:", qiskit_aer.__version__)
print("qiskit-ibm-runtime:", qiskit_ibm_runtime.__version__)Output:
Python: 3.12.2
qiskit: 2.2.3
qiskit-aer: 0.17.2
qiskit-ibm-runtime: 0.41.1
A brief side quest: use the Composer
Before we write code, it's helpful to see circuits visually. IBM Quantum Composer lets you build circuits by dragging gates onto wires. It's a great way to learn what a circuit is doing without getting distracted by syntax.
Open the Composer here.
Once it loads, launch the guided tutorial from the menu: Help | Build your first circuit. Work through it at your own pace. As you go, pay attention to how each gate changes what you expect to measure.
The tutorial steps through building the "Hello World" circuit. It's visualized in what is called a circuit diagram, where the qubits are represented by horizontal lines and the gates acting on those qubits are represented by boxes or other symbols on the lines. This circuit introduces us to a few key features of qubits and quantum computers:
First, the red box labeled "H" is a Hadamard gate, which creates a superposition state of qubit 0. Unlike a bit, which can only be in the state 1 or 0, a qubit state can include both possibilities at once, with certain weights (called amplitudes) attached to each. Superposition doesn't mean you'll ever see both results in one measurement; it means the state is set up so that either outcome can happen when you measure.
Second, the circles and vertical line connecting the two qubits is a CNOT gate, which generates entanglement between the two qubits. Entanglement is a special kind of link between qubits. When qubits are entangled, the outcomes of measurements can be strongly correlated in a way that doesn't match what we'd expect from ordinary independent coin flips, or from any classical correlation. When two qubits are entangled, measuring one will instantaneously tell you the outcome of measuring the other.
Another key idea you'll see in the tutorial is shots. Because measurement is the moment a qubit stops behaving like a quantum state and gives you a classical readout, a superposition state will probabilistically collapse to either a 0 or a 1 when it's measured. So, to learn about that superposition, you need to measure it many times by running the same circuit to accumulate statistics. These are called shots.
Check your understanding
Think about each question below, then click to reveal the answer.
No. A single measurement always returns a classical value: either 0 or 1. The "mixture" idea shows up only in the statistics you see after many runs, also called shots.
It gives you linked outcomes. Measuring one qubit tells you something about the other. This link is stronger than independent randomness and stronger than any purely classical correlation or shared randomness can explain.
In a single measurement you see only one classical result: either 0 or 1. You need many shots because the "superposition" shows up as a probability distribution, which you can only estimate by collecting statistics over repeated runs.
It shows you a 50% chance of being in the state and a 50% chance of being in the state . This means that if you measure one to be 0, the other will be 0 and if you measure one to be 1, the other will also be 1. This is a correlation between the two qubits that can be explained by entanglement.
Create and run a quantum program using Qiskit
Okay, back to coding. We're going to generate the same entangled state as we did in Composer (called the (phi-plus) Bell state) but this time, we'll write the code by hand. We need to build this skill because as we scale to more qubits and more complicated circuits, the Composer won't be able to help us.
To build the Bell state circuit, we use an (Hadamard) gate to put the first qubit into an equal superposition. Then we apply a (controlled-NOT) gate, which entangles the two states together. The two qubits are now correlated in a way that has no classical equivalent.
# --- Build the Bell circuit (phi-plus) ---
bell = QuantumCircuit(2)
bell.h(0)
bell.cx(0, 1)
bell.measure_all() # creates a classical register named "meas"
bell.draw("mpl")Output:
Helper function for running circuits
Now let's define a helper function that handles the process of running a quantum circuit and retrieving measurement results. This function takes care of transpiling the circuit to match the backend's instruction set, running it through a Sampler primitive, and extracting the counts from the results.
def run_circuit_and_get_counts(circuit, backend, shots=1000):
"""
Runs a quantum circuit on a specified backend and returns the measurement counts.
Args:
circuit (QuantumCircuit): The quantum circuit to run.
backend: The Qiskit backend (real device or simulator).
shots (int): The number of shots to run the circuit.
Returns:
dict: A dictionary of measurement counts.
"""
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(circuit)
sampler = Sampler(mode=backend)
job = sampler.run([isa_circuit], shots=shots)
result = job.result()
return result[0].data.meas.get_counts()Run on a QPU and visualize results
Finally, we run the circuit on an IBM quantum processing unit (QPU) in the cloud for 1000 shots and plot the results. IBM QPUs are physical systems that can pick up noise, so gates are slightly imperfect, measurements can be wrong sometimes, and device calibration drifts over time.
Running on real quantum computers also introduces practical considerations. Jobs can sit in a queue, because many people may be using the same device. You also have to choose a shot count that balances statistical considerations (more shots equals a higher signal-to-noise ratio) with time/cost constraints.
Follow the instructions in the code comments of the next cell. After running the cell, you should see a histogram with approximately equal counts for the and bitstrings, with some occurrences of or due to noise. The following cell in this notebook runs the same circuit on a simulator, should you choose to skip running on a QPU.
# Syntax for first saving your token. Delete these lines after saving your credentials.
QiskitRuntimeService.save_account(
channel="ibm_quantum_platform",
token="YOUR_TOKEN_HERE",
overwrite=True,
set_as_default=True,
)
service = QiskitRuntimeService(channel="ibm_quantum_platform")
# Load saved credentials
service = QiskitRuntimeService()
# Use the least busy backend, or uncomment the loading of a specific backend like "ibm_fez".
backend = service.least_busy(operational=True, simulator=False, min_num_qubits=127)
# backend = service.backend("ibm_fez")
print(backend.name)Output:
ibm_pittsburgh
counts = run_circuit_and_get_counts(bell, backend, shots=1000)
plot_histogram(counts)Output:
Run on a simulator and visualize results
A simulator is a "perfect world" version of quantum computing. Here we run the circuit on a simulator for 1000 shots and plot the results. You should see approximately equal counts for the and states, with no occurrences of or , which is the signature of the Bell state's perfect correlation.
backend = AerSimulator()
counts = run_circuit_and_get_counts(bell, backend, shots=1000)
plot_histogram(counts)Output:
Check your understanding
Think about each question below, then click to reveal the answer.
An H gate on qubit 0, followed by a CX gate with qubit 0 as control and qubit 1 as target.
00 and 11 should dominate.
Even though a simulator is "perfect" and leads to a perfect Bell state, it is still simulating an inherently random process, so statistical fluctuations will still occur. It's like flipping a coin 1000 times: even if there is an exact 50-50 chance of the coin landing on heads or tails, that doesn't mean you'll always get exactly 500 instances of heads and 500 of tails.
Because real devices have noise. Gates and measurements are not perfect, and that can introduce occasional errors.
Quantum computers can involve queue time, limited availability, and device-specific constraints that affect how circuits run.
Conclusion
We started by setting up Qiskit in a fresh Colab environment, which is exactly how many real-world notebook workflows begin. We followed that with a journey into quantum computing using the Composer. We then built a simple two-qubit circuit that produces the Bell state and used repeated sampling and visualized the entanglement as a correlation in the qubit measurement histogram. We also saw how real quantum computers introduce noise and errors.
Learning objective
Now that we've walked through how to create the Bell state, see if you can edit the code to create one of the other three Bell states. In particular, the state will be used in an upcoming lesson, so if you figure out how to create it, you'll be ahead of the game.