Skip to content

Commit

Permalink
Qiskit addons aqc pages (#2291)
Browse files Browse the repository at this point in the history
Closes #2289 and #2290
  • Loading branch information
kaelynj authored Nov 13, 2024
1 parent 8e335ea commit 3b53138
Show file tree
Hide file tree
Showing 12 changed files with 534 additions and 33 deletions.
13 changes: 13 additions & 0 deletions docs/guides/_toc.json
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,19 @@
}
]
},
{
"title": "Approximate quantum compilation (AQC-Tensor)",
"children": [
{
"title": "AQC-Tensor addon overview",
"url": "/guides/qiskit-addons-aqc"
},
{
"title": "Getting started with AQC-Tensor",
"url": "/guides/qiskit-addons-aqc-get-started"
}
]
},
{
"title": "Operator backpropagation (OBP)",
"children": [
Expand Down
6 changes: 4 additions & 2 deletions docs/guides/optimize-for-hardware.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ can be run on IBM® hardware using IBM Qiskit Runtime.
- [Q-CTRL Performance Management](/guides/q-ctrl-performance-management)
- [QEDMA QESEM](/guides/qedma-qesem)

### Qiskit Addons
### Qiskit addons
* [Approximate Quantum Compilation with Tensor Networks (AQC-Tensor)](./qiskit-addons-aqc)
* [Getting started with AQC-Tensor](./qiskit-addons-aqc-get-started)
* [Operator Backpropagation (OBP)](./qiskit-addons-obp)
* [Getting started with OBP](./qiskit-addons-obp-get-started)
* [Getting started with OBP](./qiskit-addons-obp-get-started)
375 changes: 375 additions & 0 deletions docs/guides/qiskit-addons-aqc-get-started.ipynb

Large diffs are not rendered by default.

86 changes: 86 additions & 0 deletions docs/guides/qiskit-addons-aqc.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
title: Approximate quantum compiler with tensor networks
description: Overview of the addon for approximate quantum compilation using tensor networks
---

# Approximate quantum compiler with tensor networks (AQC-Tensor)

The Approximate quantum compilation with tensor networks (AQC-Tensor) Qiskit addon enables users to compile the *initial portion* of a circuit into a nearly equivalent approximation of that circuit, but with much fewer layers. This is accomplished using tensor networks using the method described in [[1]](#references). Its primary utility is in circuits which simulate time evolution, but may be applicable to any class of circuits which has access to:

1. A great intermediate state, known as the “target state,” that can be achieved by tensor-network simulation; and,
2. A good circuit that prepares an approximation to the target state, but with fewer layers when compiled to the target hardware device.


The technique generates an ansatz circuit based on a larger target circuit which a user ultimately wants to execute on a QPU. This is accomplished by first simulating some portion of the target circuit by tensor network methods and obtaining an accurate description of an intermediate state which the ansatz circuit will approximate. Once this intermediate state is found, it is used as a cost function in order to optimize the ansatz circuit's parameters. After the optimization is complete, the remaining portion of the target circuit is appended to the ansatz and then executed on quantum hardware.


## Install the AQC-Tensor package

There are two ways to install the AQC-Tensor package: PyPI and building from source. It is recommended to install these packages in a [virtual environment](https://docs.python.org/3.10/tutorial/venv.html) to ensure separation between package dependencies.

### Install from PyPI

The most straightforward way to install the AQC-Tensor package is via PyPI. In order to use the package, you must also install at least one tensor network backend. The following code snippet will install the addon, along with `quimb` (for tensor network support) and `jax` (for automatic differentiation). If you are interested, check out the package on [GitHub](https://github.com/Qiskit/qiskit-addon-aqc-tensor)

```bash
pip install 'qiskit-addon-aqc-tensor[quimb-jax]'
```

### Install from source

<details>
<summary>
Click here to read how to install this package manually.
</summary>

If you wish to contribute to this package or want to install it manually, first clone the repository:

```bash
git clone git clone [email protected]:Qiskit/qiskit-addon-aqc-tensor.git
```
and install the package via `pip`. If you plan on running the tutorials found in the package repository, install the notebook dependencies as well. If you plan on developing in the repository, you may also want to install the `dev` dependencies.
```bash
pip install tox jupyterlab -e '.[notebook-dependencies,dev]'
```
</details>

## Theoretical Background

The AQC-Tensor procedure is explained in detail in [[1]](#references). This section provides an overview of the technique.

![Diagram depicting the approximate quantum compilation procedure](/images/guides/qiskit-addons/aqc_diagram.png)

In general, AQC-Tensor requires three things as input:
1. A description of the **target state** in the form of a tensor network. This can be generated by simulating a circuit on a tensor network simulator, or it could be generated in some other way (for example, by performing time evolution on a matrix-product state using the time-dependent variational principle).
2. A parametrized **ansatz circuit**. Ideally one which contains hardware-efficient connectivity, such that it will have a reasonable depth on the target hardware.
3. **Initial parameters** to plug into the ansatz circuit, such that the resulting state is already a *good* approximation of the target state. (This is not, in principle, required for AQC, but it helps to give the optimizer a sensible starting point.)

The technique is to then iteratively optimize the parameters of the ansatz circuit, such that the state it generates is as close to the target state as possible.

### Ansatz generation

To generate (2) and (3) from the above list, the `qiskit-addon-aqc` package possesses a function, `generated_ansatz_from_circuit()` which will take an input circuit and outputs a parameterized ansatz and initial set of parameters. The parameters returned by the function are such that, when plugged into the ansatz, will generate a state that is exactly equivalent to the input circuit, up to a global phase.

The ansatz which is generated by this function uses 9 parameters per two-qubit block and is based on the KAK decomposition, which parametrizes any two-qubit gate in terms of three parameters, up to single-qubit rotations. The single-qubit rotations are then decomposed as $ZXZ$, each of which has three parameters. This results in the ansatz circuit containing 3 parameters for each two-qubit block of the original circuit, plus 3 parameters for an outgoing single-qubit rotation on each of the two qubits (for a total of 9 parameters). After adding these blocks, the ansatz is completed by adding a layer of single-qubit rotations to each active qubit at the start of the circuit.

### Tensor-network simulation

To obtain a description of the target state which is desired, this addon uses a matrix product state (the simplest form of a tensor network) and supports the following tensor-network simulators:
- MPS simulator found in Qiskit Aer
- Quimb's [eager](https://quimb.readthedocs.io/en/latest/tensor-circuit-mps.html) [`CircuitMPS`](https://quimb.readthedocs.io/en/latest/autoapi/quimb/tensor/index.html#quimb.tensor.CircuitMPS) simulator
- Quimb's [lazy](https://quimb.readthedocs.io/en/latest/tensor-circuit.html) [`Circuit`](https://quimb.readthedocs.io/en/latest/autoapi/quimb/tensor/index.html#quimb.tensor.Circuit) simulator

The most important parameter of a tensor network is its maximum bond dimension, $\chi$. This parameter limits how much entanglement can be represented with a tensor network, and thus to what depth a given circuit can be faithfully simulated.

Given a circuit with $L$ qubits, a matrix-product state needs at most a bond dimension of $\chi_{exact} = 2^{L/2}$ in order to exactly simulate the circuit to *any* depth. This is out of reach for general utility-scale circuits acting on 100+ qubits. For this reason, if you are attempting to experiment with this addon for a toy-problem with few qubits, it is important to ensure that $\chi < 2^{L/2}$. This way, when you scale the problem to a larger circuit, the target state remains classically simulable.

## Next steps

<Admonition type="tip" title="Recommendations">
- Read through the page on [getting started with AQC-Tensor](/guides/qiskit-addons-aqc-get-started)
</Admonition>


## References

[1] Robertson, Niall F., et al. ["Approximate Quantum Compiling for Quantum Simulation: A Tensor Network based approach"](https://arxiv.org/abs/2301.08609) arXiv preprint arXiv:2301.08609 (2023).
72 changes: 42 additions & 30 deletions docs/guides/qiskit-addons-obp-get-started.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "markdown",
"id": "f9dcb976-96bf-4016-976a-cb19ace0f526",
"id": "2d697463-4d74-4761-b1d7-da8cea7cc308",
"metadata": {},
"source": [
"# Get started with OBP\n",
Expand All @@ -27,8 +27,8 @@
},
{
"cell_type": "code",
"execution_count": 1,
"id": "00f39aa3-60ee-47f1-8e3a-a110ca87c994",
"execution_count": 9,
"id": "5b4fd077-2d8f-46e8-9631-40cadbe07879",
"metadata": {},
"outputs": [
{
Expand All @@ -38,7 +38,7 @@
"<Figure size 1959.72x869.556 with 1 Axes>"
]
},
"execution_count": 1,
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
Expand Down Expand Up @@ -87,7 +87,7 @@
},
{
"cell_type": "markdown",
"id": "21b9eba7-3e24-4a14-8cd0-0fe05678104e",
"id": "f6bcccef-263d-4cf2-81b3-141b99ffc860",
"metadata": {},
"source": [
"### Prepare inputs to backpropagate\n",
Expand All @@ -97,8 +97,8 @@
},
{
"cell_type": "code",
"execution_count": 2,
"id": "67446f03-4ca7-480e-9b85-7bba97f05b57",
"execution_count": 10,
"id": "af6efa03-22bd-4aa4-b17e-3e3f87cd0584",
"metadata": {},
"outputs": [
{
Expand All @@ -116,7 +116,7 @@
},
{
"cell_type": "markdown",
"id": "521c51fb-0fb9-41fb-850f-dd4f0d241c97",
"id": "10279a97-597d-44a0-b350-7a85cc58bf48",
"metadata": {},
"source": [
"Once the slices have been generated, specify an `OperatorBudget` to provide the `backpropagate()` function with a condition to stop backpropagating the operator and prevent the classical overhead from growing further. You can also specify a truncation error budget for each slice wherein Pauli terms with small coefficients will be truncated from each slice until the error budget is filled. Any leftover budget will then be added to the following slice's budget.\n",
Expand All @@ -126,8 +126,8 @@
},
{
"cell_type": "code",
"execution_count": 3,
"id": "71ee4776-4d89-43d1-b73e-95932ae8c892",
"execution_count": 11,
"id": "5b853133-40e4-4549-9751-76cc03e87595",
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -137,7 +137,7 @@
},
{
"cell_type": "markdown",
"id": "c7cf0465-e079-4c95-b245-c72c64201ded",
"id": "5488b302-2df5-4715-9af1-19c615d215c6",
"metadata": {},
"source": [
"### Backpropagate slices\n",
Expand All @@ -153,8 +153,8 @@
},
{
"cell_type": "code",
"execution_count": 4,
"id": "3bd64d98-8650-4ad9-af19-539c19651dbf",
"execution_count": 12,
"id": "edb18b6e-8cca-4081-9909-baca7e82bf37",
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -196,8 +196,8 @@
},
{
"cell_type": "code",
"execution_count": 5,
"id": "6dddb0ce-0cf2-4e13-abe0-0180e37ea091",
"execution_count": 13,
"id": "243681df-1234-4b83-9139-16b2b8c88308",
"metadata": {},
"outputs": [
{
Expand All @@ -214,7 +214,7 @@
"<Figure size 1226x521.733 with 1 Axes>"
]
},
"execution_count": 5,
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -228,16 +228,16 @@
},
{
"cell_type": "markdown",
"id": "4443fbef-9d2f-40ac-b465-6822d2a71bcc",
"id": "bf66b2c0-ecd5-4657-9962-2d6dae8c63c0",
"metadata": {},
"source": [
"The below code snippets backpropagates the circuit *with* a truncation error budget."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "bc98019c-3985-4118-8a1e-06018fb0a522",
"execution_count": 14,
"id": "b1ea2012-21e2-4cb4-bc7f-f528bbb8a9cb",
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -281,8 +281,8 @@
},
{
"cell_type": "code",
"execution_count": 7,
"id": "6a3d796b-3b4e-48c4-b416-98a4d72ce39d",
"execution_count": 15,
"id": "ab852775-229d-4652-9456-56c4dc8e628c",
"metadata": {},
"outputs": [
{
Expand All @@ -299,7 +299,7 @@
"<Figure size 924.998x521.733 with 1 Axes>"
]
},
"execution_count": 7,
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -313,7 +313,7 @@
},
{
"cell_type": "markdown",
"id": "1fd7563b-a7c1-42f7-be00-c3f338197aa0",
"id": "aeb9995a-5530-4dbb-82f7-dca6abd798f0",
"metadata": {},
"source": [
"### Transpile and execute quantum workload\n",
Expand All @@ -325,18 +325,18 @@
},
{
"cell_type": "code",
"execution_count": 8,
"id": "59f7344c-e6aa-4a44-9551-34be0e9bbcec",
"execution_count": 16,
"id": "a04ff4e3-4a8c-4844-bcac-c4557c7e24fe",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Exact expectation value: 0.8854160687717517\n",
"Backpropagated expectation value without truncation: 0.8854160687717538\n",
"Backpropagated expectation value without truncation: 0.8854160687717509\n",
"Backpropagated expectation value with truncation: 0.8850236647156042\n",
" - Expected Error for truncated observable: 0.000e+00\n",
" - Expected Error for truncated observable: 4.933e-02\n",
" - Observed Error for truncated observable: 3.924e-04\n"
]
}
Expand Down Expand Up @@ -384,7 +384,7 @@
"print(f\"Backpropagated expectation value without truncation: {result_bp}\")\n",
"print(f\"Backpropagated expectation value with truncation: {result_bp_trunc}\")\n",
"print(\n",
" f\" - Expected Error for truncated observable: {metadata.accumulated_error(0):.3e}\"\n",
" f\" - Expected Error for truncated observable: {metadata_trunc.accumulated_error(0):.3e}\"\n",
")\n",
"print(\n",
" f\" - Observed Error for truncated observable: {abs(result_exact - result_bp_trunc):.3e}\"\n",
Expand All @@ -393,7 +393,7 @@
},
{
"cell_type": "markdown",
"id": "31eb5da9-26cf-4b7d-b337-64ceeba6ca65",
"id": "bdccc683-0fc3-4ce2-975b-3ff495247c66",
"metadata": {},
"source": [
"Lastly the following code snippet will transpile and execute the backpropagated circuit on a QPU (both with and without truncation)."
Expand All @@ -402,7 +402,7 @@
{
"cell_type": "code",
"execution_count": 9,
"id": "189b129b-17fd-44f7-9a39-2c52bf79c21b",
"id": "fb918a29-acb5-491a-8d7e-58fccd159a6a",
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -458,6 +458,18 @@
" f\" - Observed Error for truncated observable: {abs(result_exact - result_bp_trunc_qpu):.3e}\"\n",
")"
]
},
{
"cell_type": "markdown",
"id": "a56ecccf-d412-42bc-8bee-3a0e2f51ce2c",
"metadata": {},
"source": [
"## Next steps\n",
"\n",
"<Admonition type=\"tip\" title=\"Recommendations\">\n",
" - Read through the [OBP tutorial](https://learning.quantum.ibm.com/tutorial/improving-estimation-of-expectation-values-with-operator-backpropagation) on the IBM Quantum Learning Platform.\n",
"</Admonition>"
]
}
],
"metadata": {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions qiskit_bot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -388,3 +388,7 @@ notifications:
- "@kaelynj"
"docs/guides/qiskit-addons-sqd-get-started":
- "@kaelynj"
"docs/guides/qiskit-addons-aqc":
- "@kaelynj"
"docs/guides/qiskit-addons-aqc-get-started":
- "@kaelynj"
1 change: 1 addition & 0 deletions scripts/config/cspell/dictionaries/people.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ Murali
Nannicini
Nesterov’s
Neumann
Niall
Ourense
Paik
Paulis
Expand Down
1 change: 1 addition & 0 deletions scripts/config/cspell/dictionaries/qiskit.txt
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ qubit
qubits
qudit
qutrit
quimb
randomizations
rcccx
regs
Expand Down
3 changes: 2 additions & 1 deletion scripts/config/notebook-testing.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ notebooks_normal_test = [
"docs/guides/serverless-first-program.ipynb",
"docs/guides/serverless-run-first-workload.ipynb",
"docs/guides/specify-observables-pauli.ipynb",
"docs/guides/qiskit-addons-obp-get-started.ipynb",
"docs/guides/qiskit-addons-aqc-get-started.ipynb",
]

# Don't test the following notebooks (this section can include glob patterns)
Expand All @@ -54,6 +54,7 @@ notebooks_exclude = [
notebooks_that_submit_jobs = [
"docs/guides/primitive-input-output.ipynb",
"docs/guides/debug-qiskit-runtime-jobs.ipynb",
"docs/guides/qiskit-addons-obp-get-started.ipynb",
]

# The following notebooks submit jobs that are too big to mock with a simulator (or use functions that aren't supported on sims)
Expand Down
Loading

0 comments on commit 3b53138

Please sign in to comment.