-
Notifications
You must be signed in to change notification settings - Fork 188
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
How to import noise models from Qiskit (#1235)
**Title:** How to import noise models from Qiskit **Summary:** Importing and creating noise models in PennyLane using the noise models in Qiskit **Issue:** [sc-75668] ---- If you are writing a demonstration, please answer these questions to facilitate the marketing process. * GOALS — Why are we working on this now? - This is meant to promote the noise model PennyLane feature. - In particular, how to use `from_qiskit_noise` method to import noise models from Qiskit. * AUDIENCE — Who is this for? - This is meant for both users and researchers who utilize PennyLane and also users. - This is also meant for users who use Qiskit noise models in their workflows. * KEYWORDS — What words should be included in the marketing post? - Noise models, - Noisy simulation. * Which of the following types of documentation is most similar to your file? (more details [here](https://www.notion.so/xanaduai/Different-kinds-of-documentation-69200645fe59442991c71f9e7d8a77f8)) - [X] How-to --------- Co-authored-by: GitHub Nightly Merge Action <[email protected]> Co-authored-by: Mudit Pandey <[email protected]> Co-authored-by: Mikhail Andrenkov <[email protected]> Co-authored-by: David Wierichs <[email protected]> Co-authored-by: Korbinian Kottmann <[email protected]> Co-authored-by: Ivana Kurečić <[email protected]> Co-authored-by: Paul Finlay <[email protected]> Co-authored-by: Jack Brown <[email protected]> Co-authored-by: bellekaplan <[email protected]>
- Loading branch information
1 parent
cf00c6f
commit 9b70c40
Showing
6 changed files
with
268 additions
and
1 deletion.
There are no files selected for viewing
Binary file added
BIN
+118 KB
...ils/large_demo_thumbnails/thumbnail_large_how_to_import_qiskit_noise_models.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+116 KB
...ils/opengraph_demo_thumbnails/OGthumbnail_how_to_import_qiskit_noise_models.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+27.5 KB
...mbnails/regular_demo_thumbnails/thumbnail_how_to_import_qiskit_noise_models.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 43 additions & 0 deletions
43
demonstrations/tutorial_how_to_import_qiskit_noise_models.metadata.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
{ | ||
"title": "How to import noise models from Qiskit", | ||
"authors": [ | ||
{ | ||
"username": "whatsis" | ||
} | ||
], | ||
"dateOfPublication": "2024-11-25T00:00:00+00:00", | ||
"dateOfLastModification": "2024-11-25T00:00:00+00:00", | ||
"categories": [ | ||
"Quantum Computing", | ||
"How-to" | ||
], | ||
"tags": [], | ||
"previewImages": [ | ||
{ | ||
"type": "thumbnail", | ||
"uri": "/_static/demo_thumbnails/regular_demo_thumbnails/thumbnail_how_to_import_qiskit_noise_models.png" | ||
}, | ||
{ | ||
"type": "large_thumbnail", | ||
"uri": "/_static/demo_thumbnails/large_demo_thumbnails/thumbnail_large_how_to_import_qiskit_noise_models.png" | ||
} | ||
], | ||
"seoDescription": "Learn how noise models can be imported into PennyLane from Qiskit.", | ||
"doi": "", | ||
"references": [ | ||
], | ||
"basedOnPapers": [], | ||
"referencedByPapers": [], | ||
"relatedContent": [ | ||
{ | ||
"type": "demonstration", | ||
"id": "tutorial_how_to_use_noise_models", | ||
"weight": 1.0 | ||
}, | ||
{ | ||
"type": "demonstration", | ||
"id": "tutorial_noisy_circuits", | ||
"weight": 1.0 | ||
} | ||
] | ||
} |
219 changes: 219 additions & 0 deletions
219
demonstrations/tutorial_how_to_import_qiskit_noise_models.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
r"""How to import noise models from Qiskit | ||
========================================== | ||
Noise models describe how a quantum system interacts with its environment. | ||
These models are typically represented by a set of | ||
`Kraus operators <https://pennylane.ai/qml/demos/tutorial_noisy_circuits/#noisy-operations>`_ | ||
that encapsulates the probabilistic nature of quantum errors. ⚡ | ||
Interestingly, different sets of Kraus operators can represent the same quantum noise process. | ||
The non-unique nature of these representations allows quantum computing libraries to use | ||
different approaches for storing and building Kraus operators to construct noise models. | ||
In this how-to guide, we will first compare the construction of noise models in | ||
`Qiskit <https://docs.quantum.ibm.com/>`_ and | ||
`PennyLane <https://docs.pennylane.ai/en/stable/code/qml.html>`_. Then, we will learn how to | ||
convert a Qiskit noise model into an equivalent PennyLane one, allowing users to import any | ||
custom user-defined or fake backend-based noise models. | ||
""" | ||
|
||
###################################################################### | ||
# Noise models in Qiskit and PennyLane | ||
# ------------------------------------ | ||
# | ||
# The noise models in Qiskit are built using the tools available in the | ||
# `noise module <https://qiskit.github.io/qiskit-aer/apidocs/aer_noise.html>`_ | ||
# of the ``Qiskit-Aer`` package. Each model is represented by a `NoiseModel | ||
# <https://qiskit.github.io/qiskit-aer/stubs/qiskit_aer.noise.NoiseModel.html>`_ | ||
# object that contains `QuantumError | ||
# <https://qiskit.github.io/qiskit-aer/stubs/qiskit_aer.noise.QuantumError.html>`_ | ||
# to describe the errors encountered in gate operations. Optionally, it may also have a | ||
# `ReadoutError <https://qiskit.github.io/qiskit-aer/stubs/qiskit_aer.noise.ReadoutError.html>`_ | ||
# that describes the classical readout errors. | ||
# | ||
# Let's build a Qiskit noise model that inserts *depolarization* errors for single-qubit gates, | ||
# *bit-flip* errors for the target qubit of the two-qubit gates, | ||
# and *amplitude damping* errors for each measurement: | ||
# | ||
|
||
import numpy as np | ||
from qiskit_aer.noise import ( | ||
amplitude_damping_error, depolarizing_error, pauli_error, NoiseModel | ||
) | ||
|
||
# Building the Qiskit noise model | ||
model_qk = NoiseModel() | ||
|
||
# Depolarization error for single-qubit gates | ||
prob_depol = 0.2 | ||
error_gate1 = depolarizing_error(prob_depol, 1) | ||
model_qk.add_all_qubit_quantum_error(error_gate1, ["u1", "u2", "u3"]) | ||
|
||
# Bit flip errors for two-qubit gate | ||
prob_bit_flip = 0.1 | ||
error_gate2 = pauli_error([('X', prob_bit_flip), ('I', 1 - prob_bit_flip)]).tensor( | ||
pauli_error([('I', 1)]) | ||
) | ||
model_qk.add_all_qubit_quantum_error(error_gate2, ["cx"]) | ||
|
||
# Amplitude damping error for measurements | ||
n_qubits = 3 | ||
exc_population = 0.2 | ||
prob_ampl_damp = np.random.default_rng(42).uniform(0, 0.2, n_qubits) | ||
for qubit in range(n_qubits): | ||
error_meas = amplitude_damping_error(prob_ampl_damp[qubit], exc_population) | ||
model_qk.add_quantum_error(error_meas, "measure", [qubit]) | ||
|
||
print(model_qk) | ||
|
||
###################################################################### | ||
# In contrast, the noise models in PennyLane are :class:`~.pennylane.NoiseModel` | ||
# objects with Boolean conditions that select the operation for which | ||
# we want to apply noise. These conditions are mapped to noise functions | ||
# that apply (or queue) the corresponding noise for the selected operation | ||
# or measurement process based on user-provided metadata. This allows | ||
# for a more functional construction, as we can see by recreating the | ||
# above noise model as shown below. For more information on this, check out our | ||
# :doc:`how-to for noise models in PennyLane <tutorial_how_to_use_noise_models>`. 🧑🏫 | ||
# | ||
|
||
import pennylane as qml | ||
|
||
# Depolarization error for single-qubit gates | ||
gate1_fcond = qml.noise.op_in(["U1", "U2", "U3"]) & qml.noise.wires_in(range(n_qubits)) | ||
gate1_noise = qml.noise.partial_wires(qml.DepolarizingChannel, prob_depol) | ||
|
||
# Bit flip errors for two-qubit gate | ||
gate2_fcond = qml.noise.op_eq("CNOT") | ||
def gate2_noise(op, **metadata): | ||
qml.BitFlip(prob_bit_flip, op.wires[1]) | ||
|
||
# Readout errors for measurements | ||
rmeas_fcond = qml.noise.meas_eq(qml.counts) | ||
def rmeas_noise(op, **metadata): | ||
for wire in op.wires: | ||
qml.GeneralizedAmplitudeDamping(prob_ampl_damp[wire], 1 - exc_population, wire) | ||
|
||
# Building the PennyLane noise model | ||
model_pl = qml.NoiseModel( | ||
{gate1_fcond: gate1_noise, gate2_fcond: gate2_noise}, {rmeas_fcond: rmeas_noise}, | ||
) | ||
|
||
print(model_pl) | ||
|
||
###################################################################### | ||
# It is important to verify whether these noise models work the intended way. | ||
# For this purpose, we will use them while simulating a | ||
# `GHZ state <https://en.wikipedia.org/wiki/Greenberger–Horne–Zeilinger_state>`_ using the | ||
# `default.mixed <https://docs.pennylane.ai/en/stable/code/api/pennylane.devices.default_mixed.html>`_ | ||
# and `qiskit.aer <https://docs.pennylane.ai/projects/qiskit/en/latest/devices/aer.html>`_ | ||
# devices. Note that we require :func:`~.pennylane.add_noise` transform for | ||
# adding the PennyLane noise model but the Qiskit noise model is provided in | ||
# the device definition itself: | ||
# | ||
|
||
# Preparing the devices | ||
n_shots = int(2e6) | ||
dev_pl_ideal = qml.device("default.mixed", wires=n_qubits, shots=n_shots) | ||
dev_qk_noisy = qml.device("qiskit.aer", wires=n_qubits, shots=n_shots, noise_model=model_qk) | ||
|
||
def GHZcircuit(): | ||
qml.U2(0, np.pi, wires=[0]) | ||
for wire in range(n_qubits-1): | ||
qml.CNOT([wire, wire + 1]) | ||
return qml.counts(wires=range(n_qubits), all_outcomes=True) | ||
|
||
# Preparing the circuits | ||
pl_ideal_circ = qml.QNode(GHZcircuit, dev_pl_ideal) | ||
pl_noisy_circ = qml.add_noise(pl_ideal_circ, noise_model=model_pl) | ||
qk_noisy_circ = qml.QNode(GHZcircuit, dev_qk_noisy) | ||
|
||
# Preparing the results | ||
pl_noisy_res, qk_noisy_res = pl_noisy_circ(), qk_noisy_circ() | ||
|
||
###################################################################### | ||
# Now let's look at the results to compare the two noise models: | ||
# | ||
|
||
pl_probs = np.array(list(pl_noisy_res.values())) / n_shots | ||
qk_probs = np.array(list(qk_noisy_res.values())) / n_shots | ||
|
||
print("PennyLane Results: ", np.round(pl_probs, 3)) | ||
print("Qiskit Results: ", np.round(qk_probs, 3)) | ||
print("Are results equal? ", np.allclose(pl_probs, qk_probs, atol=1e-2)) | ||
|
||
###################################################################### | ||
# As the results are equal within a targeted tolerance, | ||
# we can confirm that the two noise models are equivalent. | ||
# Note that this tolerance can be further suppressed by | ||
# increasing the number of shots (``n_shots``) in the simulation. | ||
# | ||
|
||
###################################################################### | ||
# Importing Qiskit noise models | ||
# ----------------------------- | ||
# | ||
# PennyLane provides the :func:`~.pennylane.from_qiskit_noise` function to | ||
# easily convert a Qiskit noise model into an equivalent PennyLane noise model. | ||
# Let's look at an example of a noise model based on the `GenericBackendV2 | ||
# <https://docs.quantum.ibm.com/api/qiskit/qiskit.providers.fake_provider.GenericBackendV2>`_ | ||
# backend that gets instantiated with the error data generated and sampled randomly from | ||
# historical IBM backend data. | ||
# | ||
|
||
from qiskit.providers.fake_provider import GenericBackendV2 | ||
|
||
backend = GenericBackendV2(num_qubits=2, seed=42) | ||
qk_noise_model = NoiseModel.from_backend(backend) | ||
print(qk_noise_model) | ||
|
||
###################################################################### | ||
# To import this noise model as a PennyLane one, we simply do: | ||
# | ||
|
||
pl_noise_model = qml.from_qiskit_noise(qk_noise_model) | ||
print(pl_noise_model) | ||
|
||
###################################################################### | ||
# This conversion leverages the standard Kraus representation of the errors | ||
# stored in the ``qk_noise_model``. Internally, this is done in a smart three-step process: | ||
# | ||
# 1. First, all the basis gates from the noise model are mapped to the corresponding PennyLane | ||
# gate `operations <https://docs.pennylane.ai/en/stable/introduction/operations.html>`_. | ||
# 2. Next, the operations with noise are mapped to the corresponding error channels | ||
# defined via :class:`~.pennylane.QubitChannel`. | ||
# 3. Finally, the `Boolean conditionals <https://docs.pennylane.ai/en/stable/code/qml_noise.html#boolean-functions>`_ | ||
# are constructed and combined based on their associated errors. | ||
# | ||
# This can be done for any noise model defined in Qiskit with a minor catch that | ||
# the classical readout errors are not supported yet in PennyLane. | ||
# However, we can easily re-insert quantum readout errors into our converted noise model. | ||
# Here's an example that adds ``rmeas_fcond`` and ``rmeas_noise`` (defined earlier) to | ||
# ``pl_noise_model``: | ||
# | ||
|
||
pl_noise_model += {"meas_map": {rmeas_fcond: rmeas_noise}} | ||
print(pl_noise_model.meas_map) | ||
|
||
###################################################################### | ||
# Conclusion | ||
# ---------- | ||
# | ||
|
||
###################################################################### | ||
# Qiskit provides noise models and tools that could be used to mirror the behaviour of quantum | ||
# devices. Integrating them into PennyLane is a powerful way to enable users to perform | ||
# differentiable noisy simulations that help them study the effects of noise on quantum circuits | ||
# and develop noise-robust quantum algorithms. In this how-to guide, we learned how to construct | ||
# PennyLane noise models from Qiskit ones by manually building one-to-one mappings | ||
# for each kind of error and also by using the :func:`~.pennylane.from_qiskit_noise` function | ||
# to convert the Qiskit noise model automatically. 💪 | ||
# | ||
# Should you have any questions about using noise models in PennyLane, you can consult the | ||
# `noise module documentation <https://docs.pennylane.ai/en/stable/code/qml_noise.html>`_, | ||
# the `PennyLane Codebook module on Noisy Quantum Theory | ||
# <https://pennylane.ai/codebook/#06-noisy-quantum-theory>`_, | ||
# or create a post on the `PennyLane Discussion Forum <https://discuss.pennylane.ai>`_. | ||
# | ||
|
||
###################################################################### | ||
# About the author | ||
# ---------------- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters