PennyLane
Install
Install

Related materials

  • Related contentQuantum volume
  • Related contentA brief overview of VQE
  • Related contentGetting started with the Amazon Braket Hybrid Jobs

Contents

  1. Using IBM devices
  2. Qiskit Runtime
  3. Using Qiskit Runtime
    1. Benchmarking
  4. About the author
  5. About the authors

Downloads

  • Download Python script
  • Download Notebook
  • View on GitHub
  1. Demos/
  2. Devices and Performance/
  3. Using PennyLane with IBM's quantum devices and Qiskit

Using PennyLane with IBM's quantum devices and Qiskit

Kaur Kristjuhan

Kaur Kristjuhan

Clara Ferreira Cores

Clara Ferreira Cores

Mark Nicholas Jones

Mark Nicholas Jones

Published: June 19, 2023. Last updated: January 09, 2025.

Warning

This demo includes some outdated features and may not work as intended. It can still be used as a guideline, but please consult the PennyLane-Qiskit plugin documentation to get the most up-to-date information on the features and usage of this plugin.

Bigger and better quantum computers are built every year. Instead of waiting for the perfect quantum computer to be released, we can already try out the best hardware that exists today. Experimenting on cutting-edge devices helps us understand the technology and improve the way we develop quantum software. PennyLane is a fantastic tool for prototyping quantum algorithms of all kinds, while IBM provides access to the newest and most powerful superconducting quantum devices available today. Let’s combine the two!

In this tutorial, we’ll show you how to use PennyLane to interface with IBM’s quantum computing platform. We will learn how to:

  • discover what kind of devices IBM offers;

  • connect to IBM devices through PennyLane’s device class;

  • use Qiskit Runtime to run hybrid algorithms;

  • compare different devices to improve our quantum algorithms.

Using IBM devices

IBM offers access to a variety of devices, both classical simulators and real quantum hardware. By default, these devices are not included in PennyLane, but after installing the PennyLane-Qiskit plugin with the command pip install pennylane-qiskit, they can be used just like any other device offered in PennyLane! Currently, there are three devices available — Aer, BasicSim and Remote — that can be initialized as follows:

import pennylane as qml
from qiskit_aer import AerSimulator

qubits = 4
dev_aer = qml.device("qiskit.aer", wires=qubits)
dev_basicsim = qml.device("qiskit.basicsim", wires=qubits)
try:
    dev_remote = qml.device("qiskit.remote", wires=qubits, backend=AerSimulator())
except Exception as e:
    print(e)

The last device (qiskit.remote) can cause an error if we don’t provide a valid account token through Qiskit. The Remote device is used to access quantum hardware, so it also requires an IBM Quantum account, which can be specified using an identifying token. You can find your token by creating or logging into your IBM Quantum account. Be careful not to publish code that reveals your token to other people! One way to avoid this is by saving your token in a PennyLane configuration file. To specify which machine or computational framework these devices actually connect to, we can use the backend argument.

dev_aer = qml.device("qiskit.aer", wires=qubits)

For the Aer device, different quantum computers can be used by changing the backend to the name of the specific simulator method. To see which backends exist, we can call the capabilities function:

from qiskit_aer import Aer

print(Aer.backends())
['aer_simulator', 'aer_simulator_statevector', 'aer_simulator_density_matrix',
'aer_simulator_stabilizer', 'aer_simulator_matrix_product_state',
'aer_simulator_extended_stabilizer', 'aer_simulator_unitary', 'aer_simulator_superop',
'qasm_simulator', 'statevector_simulator', 'unitary_simulator', 'pulse_simulator']

You can find even more details about these devices directly from the IBM Quantum platform. You can find information about the size, topology, quantum volume and noise profile of all the devices that they have available. Currently, the smallest device has 5 qubits and the largest has 127. On the IBM Quantum platform you can also check which devices are free to use and whether any of them are temporarily unavailable. You can even check your active jobs and estimated time in the queue for any programs you execute.

Qiskit Runtime

Qiskit Runtime is a quantum computing service provided by IBM intended to make hybrid algorithms more efficient to execute. Hybrid algorithms are algorithms where a classical computer and quantum computer work together. This often involves the classical algorithm iteratively optimizing the quantum circuit, which the quantum computer repeatedly runs.

One such example is the VQE algorithm, which can be used to calculate the ground state energy of molecules. It contains an optimization loop, which repeatedly requests the device to run a parameterized quantum circuit. Because the optimization algorithm changes the values of the parameters, the circuit requested is different each iteration. Also, the change is dependent on the results of the previous circuit, which means that there needs to be constant communication back and forth between the quantum computer and the classical computer in charge of the optimization.

The solution that Qiskit Runtime provides is placing a classical computer in close physical proximity of the quantum computer. The user uploads a job to the classical computer, which runs the entire hybrid algorithm together with the quantum hardware, with no intermediate user input. This automates the iterative process, which otherwise requires time and resources for communication between the user and the hardware provider.

Using Qiskit Runtime

The PennyLane-Qiskit plugin includes some tools to help create a Qiskit Runtime job. Since using Qiskit Runtime only makes sense when using real quantum hardware, we must again specify our IBM Quantum account details to run these jobs.

First, we set up our problem as usual, and then retrieve a program ID from IBM, which gives us a place to upload our job:

Warning

By default, this demo uses the online simulator (ibmq_qasm_simulator), which is free at the time of writing. Please note that IBM Quantum’s policies may change, and simulators could become paid services. Always verify current pricing and access policies on the IBM Quantum platform.

This demo can also run on quantum hardware by updating the backend variable accordingly. Be aware, that access to IBM Quantum hardware is not free and may result in substantial costs. Ensure you are aware of these costs and comfortable with them before proceeding.

from pennylane import numpy as pnp
from qiskit_ibm_runtime import QiskitRuntimeService

import pennylane as qml

# Obtaining the Hamiltonian for H2 from PennyLane QChem dataset
[dataset] = qml.data.load("qchem", molname="H2", bondlength=0.742, basis="STO-3G")
H = dataset.hamiltonian
qubits = 4

# Initialize QiskitRuntimeService
service = QiskitRuntimeService()

# Use the `ibmq_qasm_simulator` available on IBM Cloud
backend = service.backend("ibmq_qasm_simulator")

try:
    # Our device supports a maximum of 31 qubits
    NUM_QUBITS_SUPPORTED = 31
    dev = qml.device("qiskit.remote", wires=NUM_QUBITS_SUPPORTED, backend=backend)
except Exception as e:
    print(e)

Next, we specify our quantum circuit. Although there are many circuits to choose from, it is important to know that before a circuit is executed on hardware, it undergoes a transpilation step, which converts your circuit into a different, but equivalent, circuit. The purpose of this step is to ensure that only operations that are native to the quantum computer are used. With parameterized gates, however, this may cause some unexpected behavior, such as the emergence of more parameters when the transpiler attempts to decompose a complicated gate, such as AllSinglesDoubles. These types of issues will likely be fixed in the future, but, when in doubt, it is preferable to use simpler gates where possible. We will use a simple four-qubit circuit with one parameter that is designed specifically for the \(H_2\) molecule:

def four_qubit_ansatz(theta):
    # initial state 1100:
    qml.PauliX(wires=0)
    qml.PauliX(wires=1)

    # change of basis
    qml.RX(pnp.pi / 2, wires=0)
    qml.Hadamard(wires=1)
    qml.Hadamard(wires=2)
    qml.Hadamard(wires=3)

    qml.CNOT(wires=[3, 2])
    qml.CNOT(wires=[2, 1])
    qml.CNOT(wires=[1, 0])

    qml.RZ(theta, wires=0)

    qml.CNOT(wires=[1, 0])
    qml.CNOT(wires=[2, 1])
    qml.CNOT(wires=[3, 2])

    # invert change of basis
    qml.RX(-pnp.pi / 2, wires=0)
    qml.Hadamard(wires=1)
    qml.Hadamard(wires=2)
    qml.Hadamard(wires=3)

Finally, we can run our example VQE algorithm. In order to query the quantum computer iteratively we need to initialize a Qiskit Session, which allows multiple jobs from a single algorithm to be ran sequentially without interruptions. We also need to provide our VQE algorithm an optimizer. In this case, we will be using the GradientDescentOptimizer.

from pennylane_qiskit import qiskit_session


@qml.qnode(dev)
def cost_fn(theta):
    four_qubit_ansatz(theta)
    return qml.expval(H)


max_iterations = 40
theta = pnp.array(0.0, requires_grad=True)
opt = qml.GradientDescentOptimizer(stepsize=0.4)
energies = []

with qiskit_session(dev) as session:
    for n in range(max_iterations):
        theta, prev_energy = opt.step_and_cost(cost_fn, theta)
        energies.append(prev_energy)

Note

This may take a long time depending on how busy the hardware is. Depending on the tier of your IBM plan, your session may also be interrupted before the optimization can finish. Luckily, the rest of the workflow demonstrates how to run VQE with a simulator instead, which has no such restrictions at all.

Benchmarking

One of the reasons why we even want to have access to these various devices and backends is so that we can benchmark the capabilities of the algorithms that we develop. Some simulators are particularly good with certain types of circuits, whereas other simulators are more general and may provide resources for simulating noise which mimics the kind of errors that real quantum hardware produces. Switching between your devices helps you learn more about your algorithm and can potentially provide guidance on how to make it better. For example, we can compare the performance of the default PennyLane simulator to the Qiskit 'aer_simulator' by running the same VQE algorithm on both. The difference between these two devices is that the 'aer_simulator' uses a finite number of shots to estimate the energy in each iteration, rather than performing an exact calculation using the information hidden in the vector representation of the quantum state.

dev1 = qml.device("default.qubit", wires=4)
shots = 8000
dev2 = qml.device("qiskit.aer", wires=4, shots=shots)


@qml.qnode(dev1)
def cost_fn_1(theta):
    four_qubit_ansatz(theta)
    return qml.expval(H)


@qml.qnode(dev2)
def cost_fn_2(theta):
    four_qubit_ansatz(theta)
    return qml.expval(H)


# we can also use the qnode to draw the circuit
import matplotlib.pyplot as plt

qml.draw_mpl(cost_fn_1, decimals=2)(theta=1.0)
plt.show()
Circuit
stepsize = 0.4
max_iterations = 40
opt = qml.GradientDescentOptimizer(stepsize=stepsize)
theta_1 = pnp.array(0.0, requires_grad=True)
theta_2 = pnp.array(0.0, requires_grad=True)
energies_1 = []
energies_2 = []
for n in range(max_iterations):
    theta_1, prev_energy_1 = opt.step_and_cost(cost_fn_1, theta_1)
    theta_2, prev_energy_2 = opt.step_and_cost(cost_fn_2, theta_2)
    print(prev_energy_1, prev_energy_2)
    energies_1.append(prev_energy_1)
    energies_2.append(prev_energy_2)
-1.1173489211359304 -1.1190829868933736
-1.1279998277357466 -1.1288232086760344
-1.1326490062948753 -1.1301129826377698
-1.1346624646306156 -1.1359551977827906
-1.135531456349987 -1.1361153521202156
-1.1359059478903804 -1.1365135907218555
-1.1360672311675288 -1.1378046643806679
-1.1361366722397177 -1.135703178347981
-1.1361665667682972 -1.1357895389865689
-1.1361794357654167 -1.1369628601568447
-1.1361849754890518 -1.1365783784951322
-1.1361873601539711 -1.1367306582741445
-1.1361883866679017 -1.1358320382653255
-1.1361888285450743 -1.1357663570027223
-1.1361890187570935 -1.135670418637738
-1.1361891006364095 -1.1369084485357166
-1.1361891358824536 -1.139272401360956
-1.1361891510545838 -1.137130432389924
-1.136189157585629 -1.1377776180459274
-1.1361891603970047 -1.1358917536737867
-1.1361891616071986 -1.1370070425290821
-1.1361891621281424 -1.135792429417887
-1.13618916235239 -1.1350561467266231
-1.13618916244892 -1.1366759212135573
-1.1361891624904732 -1.1351253597692734
-1.13618916250836 -1.1362073324228987
 -1.13618916251606 -1.1366017151897079
-1.136189162519374 -1.1362493563165617
-1.136189162520801 -1.1378309783921152
-1.1361891625214149 -1.1350975937163135
-1.1361891625216796 -1.1372437534918245
-1.136189162521793 -1.1361363466968788
-1.1361891625218425 -1.136401712436813
-1.1361891625218634 -1.1346185510801001
-1.136189162521872 -1.1351658522378076
-1.1361891625218763 -1.1350958264741222
-1.1361891625218783 -1.135516284054897
-1.136189162521879 -1.137538330500378
 -1.1361891625218792 -1.1359072863719688
-1.1361891625218794 -1.1369053955536899

We can clearly see the difference between the two devices when we plot the energies over each iteration:

plt.plot(energies_1, color="r", label="default.qubit")
plt.plot(energies_2, color="b", label="qiskit.aer")

# min energy = min eigenvalue
min_energy = min(qml.eigvals(H))
z = [min_energy] * max_iterations

plt.plot(z, "--", color="k", label="Exact answer")
plt.xlabel("VQE iterations")
plt.ylabel("Energy (Ha)")
plt.legend()
plt.show()
Iterations

The device with the finite number of shots is unable to converge to the right answer because it is limited by the precision of the result in each iteration. This is an effect that will certainly appear in real quantum devices too, and it can be instructive to study this effect independently of all the other limitations on real devices, such as decoherence, limited topology and readout errors.

This tutorial has demonstrated how and why to use quantum computing hardware provided by IBM using PennyLane. To read more about the details and possibilities of the PennyLane-Qiskit plugin, read the documentation.

About the authors

Kaur Kristjuhan
Kaur Kristjuhan

Kaur Kristjuhan

Kaur Kristjuhan is the head of quantum computing at Molecular Quantum Solutions. His focus is on developing algorithms on NISQ devices for chemistry applications.

Clara Ferreira Cores
Clara Ferreira Cores

Clara Ferreira Cores

Clara Ferreira Cores is a quantum physicist working at Molecular Quantum Solutions. Her focus is on using tensor networks to enhance the performance of hybrid quantum-classical algorithms.

Mark Nicholas Jones
Mark Nicholas Jones

Mark Nicholas Jones

Mark Nicholas Jones is the CEO and co-founder of Molecular Quantum Solutions. Molecular Quantum Solutions provides a software platform for calculating thermodynamic properties of molecules, with applications in the pharmaceutical and agrochemical ind...

Share demo

Ask a question on the forum

Related Demos

Quantum volume

A brief overview of VQE

Getting started with the Amazon Braket Hybrid Jobs

Your guide to PennyLane if you know Qiskit

How to use Qiskit 1.0 with PennyLane

Modelling chemical reactions on a quantum computer

Compilation of quantum circuits

Estimating observables with classical shadows in the Pauli basis

Computing gradients in parallel with Amazon Braket

Accelerating VQEs with quantum natural gradient

PennyLane

PennyLane is a cross-platform Python library for quantum computing, quantum machine learning, and quantum chemistry. Built by researchers, for research. Created with ❤️ by Xanadu.

Research

  • Research
  • Performance
  • Hardware & Simulators
  • Demos
  • Quantum Compilation
  • Quantum Datasets

Education

  • Teach
  • Learn
  • Codebook
  • Coding Challenges
  • Videos
  • Glossary

Software

  • Install PennyLane
  • Features
  • Documentation
  • Catalyst Compilation Docs
  • Development Guide
  • API
  • GitHub
Stay updated with our newsletter

© Copyright 2025 | Xanadu | All rights reserved

TensorFlow, the TensorFlow logo and any related marks are trademarks of Google Inc.

Privacy Policy|Terms of Service|Cookie Policy|Code of Conduct