-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #45 from entropicalabs/dev
Dev
- Loading branch information
Showing
13 changed files
with
166 additions
and
7 deletions.
There are no files selected for viewing
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,47 @@ | ||
# Adding a new Backend Plug-in in OpenQAOA | ||
|
||
Since OpenQAOA is designed with modularity and multi-backend support in mind a user can easily add a new backend plugin in OpenQAOA. | ||
OpenQAOA distinguishes between parts of the QAOA workflow that are a backend agnositc and backend dependent. The backend agnostic parts that can be abstracted away uniformly across all devices and cloud providers form the core functionality of the package, and are therefore, placed in `openqaoa-core`. The parts that are specific to each backend device or cloud provider are placed in their respective plugins. Therefore, to run a QAOA workflow on Amazon AWS quantum computers, one needs `openqaoa-core` for the backend agnostic components and `openqaoa-braket` to communicate with the devices on AWS Braket. | ||
|
||
In similar spirit, one can add new backends that add a new hardware provider to the existing list of openqaoa plugins. This tutorial provides a guide on how to begin adding a new backend plugin. For the rest of this tutorial, we assume that the new backend will be called `xyz` | ||
|
||
## Create the new plugin folder | ||
|
||
- Create a new folder `/src/openqaoa-xyz` | ||
|
||
This folder will contain all the necessary code to support the new `XYZ` plugin. | ||
Within this folder will be the following files containing instructions to convert the plugin into an installable package: | ||
- LICENSE: Since OpenQAOA is licensed using MIT License, the individual plugins will follow the same license as well. | ||
- MANIFEST.in: This file will include the requirements file to install package dependencies for `openqaoa-xyz` | ||
- pyproject.toml: This file should contain the following instructions | ||
```Python | ||
[build-system] | ||
requires = ["setuptools>=61.0"] | ||
build-backend = "setuptools.build_meta" | ||
``` | ||
- README.md: A readme file to describe the plugin | ||
- requirements.txt: A textfile describing all the necessary python dependencies for the plugin | ||
- setup.py: Setup instructions to install the package as a python module | ||
- tests/ : A tests folder containing all backend specific unit-tests for the new plugin | ||
|
||
All the code supporting this new plugin will go inside a `src/openqaoa-xyz/openqaoa_xyz`. The naming conventions of all files and folders are crucial for the proper functioning of the plugin. | ||
|
||
### `openqaoa_xyz` | ||
The folder contains the following: | ||
- `__init__.py`: | ||
- `_version.py`: This file should set the same version number of the plugin as `openqaoa-core` | ||
- backend_config.py: This file should contain instructions on how the plugin device object is paired to the QAOABackend object. | ||
|
||
Finally, the code implementation of the device and backend lives inside the `src/openqaoa-xyz/openqaoa_xyz/backends` folder. This folder contains three different kinds of files: | ||
|
||
- `gates_xyz.py`: This file provides a mapping between the gates in the OpenQAOA intermediate representation and the gates of the backend, and an implementation of the `apply_gate` methods that are used by `openqaoa-core` to construct the QAOA circuit. All these functions are implemented as methods of the `XYZGateApplicator` class. | ||
|
||
- `devices.py`: Implement the `DeviceXYZ` object here. The user must pay attention towards the requirements for the specific cloud provider and their methods of authentication. These must be built into the device object. Moreover, this object must inherit from the `DeviceBase` object defined in `openqaoa-core` | ||
|
||
- `qaoa_xyz.py`: The name of this file can be chosen at will. The file should contain the QAOA Backend implementation for the `XYZ` hardware provider. It must contain the basic methods expected from a QAOA Backend class, for instance, `qaoa_circuit`, `get_counts` and so on. More formally, this class is responsible for converting the QAOA circuit from the OpenQAOA intermediate representation into the respective language supported by the `XYZ` hardware provider. Some template classes are defined in `openqaoa-core/openqaoa/backends/basebackends.py` that can be used as parent classes for this class. For instance, a QAOA Backend class implemeting a QPU that requires authentication, supports parametric circuit construction must inherit from `QAOABaseBackendShotBased`, `QAOABaseBackendCloud` and `QAOABaseBackendParametric`. | ||
|
||
## Recycling Backends from other plugins | ||
|
||
Sometimes, a hardware provider supports circuit construction and job execution via an already existing software framework, for example, `Qiskit`. In such a case, the backend plugin may import the `QAOAQiskitQPUBackend` class from the `openqaoa-qiskit` package to be used to support the new plugin instead of re-writing the whole class from scratch. Be sure to add `openqaoa-qiskit` as a requirement for the new plugin if this import is used. | ||
|
||
In an another situation, a backend may permit using `Qiskit` to define the circuit and then using some existing converters to transform the circuit into instructions parseable by the hardware. In such a case, the user may consider writing a new QAOA Backend class that inherits from the `QAOAQiskitQPUBackend` instead of the base-backend classes defined in `openqaoa-core`. |
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,76 @@ | ||
# SPAM Twirling | ||
|
||
!!! info "Note" | ||
This feature is present only in openqaoa 0.1.4 and above! | ||
|
||
|
||
State Preparation and Measurement (SPAM) Twirling is a simple error mitigation technique used to remove any preferred direction due to readout noise. It works by diagonalizing the noise associated with measurements by randomly flipping qubits via X gates right before the measurement and flipping the corresponding measured bit classically. | ||
A calibration factor from the diagonal noise channel is obtained by measuring quantum circuits initialized in the zero states. As a result, the expectation values of the circuit in the presence of readout noise is much closer to the noise-free one. | ||
|
||
!!! info "For the curious" | ||
The technique has been developed theoretically by E. v. d. Berg et al. [1] and by A. W. R. Smith, et al. [2] and implemented within Qiskit as one of their “resilience levels” under the name “Twirled Readout Error eXtinction (TREX)”. Experimentally has been applied by Layden et al. [3] to ensure that the symmetry requirement $Q(s'| s) = Q(s |s')$ is met. Note that this requirement is specific to the Monte Carlo algorithm and therefore irrelevant to QAOA. | ||
|
||
|
||
### The algorithm | ||
I. Obtain calibration data (ideally for the whole device) under the Bit Flipping Averaging (BFA) subroutine | ||
|
||
1. Initialize the circuit in the |000…0> state. | ||
2. Measure under BFA (subroutine) | ||
3. Save the counts and the registers (this is how the measurement string outcomes map to the physical qubits on the device) and all other relevant information to a json (see [the code](https://github.com/entropicalabs/openqaoa/blob/dev/tests/qpu_calibration_data/README_calibration_files.md) for the exact format). | ||
|
||
II. Run the quantum experiment under BFA | ||
|
||
1. Calculate calibration factors | ||
2. Prepare the desired quantum circuit | ||
3. Measure under BFA (subroutine) | ||
4. Correct the expectation values by term | ||
5. Combine all corrected terms into the final expectation value | ||
|
||
#### Subroutine: Bit Flip Averaging (BFA) technique | ||
|
||
1. Divide the total number of shots into $n$ batches and for each batch choose a set of qubits to be flipped. Note that since we usually don’t have a very accurate model of the noise and to keep it general, we choose the qubits within each batch uniformly at random. | ||
2. The bit flip before the measurement can be done by applying an X gate, absorbing the X gate into the last layer of RX rotations or propagating it to the front (and then absorbing it into the initial |+> state). | ||
3. The bit flip after the measurement is performed by applying a classical `not` to the outcome bitstring, which is implemented as changing the keys in the count dictionary. | ||
4. Combine the negated counts from all batches into a single count dictionary which is then used for calculating the calibration factors or estimating the expectation values. | ||
|
||
Let's look at a simple example of a 2-qubit system for which the QAOA circuit is: | ||
![circuit_original](/img/spam_twirling_circuit_0.png) | ||
|
||
Under BFA, every batch implements the desired QAOA circuit with single X gates prepended/appended randomly on a subset of the qubits. Considering,as an example, a simple two qubit circuit, there are 3 posibilities for the X gates. They can be applied to the first qubit | ||
![circuit_XI](/img/spam_twirling_circuit_2.png) | ||
to the second one | ||
![circuit_IX](/img/spam_twirling_circuit_3.png) | ||
or to both: | ||
![circuit_XX](/img/spam_twirling_circuit_1.png) | ||
|
||
### How to do this within OpenQAOA? | ||
|
||
In the workflows, this can be implemented by simply doing: | ||
```Python | ||
q = QAOA() | ||
q.set_error_mitigation_properties( | ||
error_mitigation_technique="spam_twirling", | ||
n_batches=4, | ||
calibration_data_location="filename", | ||
) | ||
``` | ||
|
||
Internally, OpenQAOA modifies the backend object in order to divide the computation in batches and applies the conditional X gate on a set of qubits choosen uniformly at random | ||
```Python | ||
if error_mitigation_properties.error_mitigation_technique == 'spam_twirling': | ||
backend = SPAMTwirlingWrapper(backend=self.backend, | ||
n_batches=self.error_mitigation_properties.n_batches, | ||
calibration_data_location=error_mitigation_properties.calibration_data_location) | ||
``` | ||
|
||
### What to expect? | ||
Let's see the technique in practice by solving MaxCut on a u3R graph for n=6 qubits. In this example, we simulate a 7 qubit device using the (noisy) Quantum Virtual MAchine, an emulator developed by Rigetti. We have a total of 1000 shots, we divided them into into 10 batches of equal number of shots (note that the number of batches and shots may be tweaked to improve the result!). | ||
|
||
![results_rigetti](/img/spam_twirling_results_rigetti.png) | ||
The plot above shows a slice of the landscape at $\gamma=0.25$ and for various $\beta$. It is clear that by performing SPAM Twirling we obtain (the orange line) energies much closer to the theoretically simulated ones (dark blue line). | ||
|
||
## References | ||
---------- | ||
1. [Berg, E., Minev, Z. K., Temme, K.](https://journals.aps.org/pra/abstract/10.1103/PhysRevA.105.032620), Phys. Rev. A 105, 032620 (2022) | ||
2. [Smith, A.W.R., Khosla, K.E., Self, C.N., Kim, M.S.](https://www.science.org/doi/10.1126/sciadv.abi8009), Science Advances, vol. 7, 47 (2021) | ||
3. [Layden, D., Mazzola, G., Mishmash, R. V., Motta, M., Wocjan, P., Kim, J.-S., Sheldon, S.](https://arxiv.org/abs/2203.12497), arXiv:2203.12497, (see Appendix IV, sec.A2) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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,28 @@ | ||
# Bring your own OpenQAOA container to Amazon Braket Hybrid Jobs | ||
|
||
If you are wondering what is an Amazon Braket Hybrid Jobs, check out [Braket's very own answer](https://docs.aws.amazon.com/braket/latest/developerguide/braket-what-is-hybrid-job.html) | ||
|
||
> With Hybrid Jobs, you can run algorithms that use both classical and quantum compute resources. These hybrid quantum-classical algorithms can help you optimize the performance of the quantum devices currently available. These algorithms are designed to maximize the benefits and reduce the drawbacks of both types of computational systems and are generally used to find the ground state or global minimum of a particular system. | ||
QAOA is a great example of such hybrid quantum-classical algorithms, and we here provide a simple procedure to prepare your own OpenQAOA container. | ||
|
||
## Steps to create your own OpenQAOA container | ||
|
||
First of all, these instructions are based on Amazon Braket's documentation. Therefore, a safe place to check if you are an experienced Docker and AWS practitioner is to head to the [Bring your own container](https://docs.aws.amazon.com/braket/latest/developerguide/braket-jobs-byoc.html) page! | ||
|
||
The following instructions will allow you to create your OpenQAOA container. Note that they will work out of the box only for Linux and macOs. | ||
|
||
1. Make sure all the dependencies are installed and credentials are properly set: | ||
- Clone openqaoa from github `git clone https://github.com/entropicalabs/openqaoa.git` | ||
- Install docker on your system | ||
- Install the [AWS command line interface](https://aws.amazon.com/cli/) | ||
- Create an Amazon Elastic Container Registry (Amazon ECR) repository (see step 3 [here](https://docs.aws.amazon.com/braket/latest/developerguide/braket-jobs-byoc.html)) | ||
2. Authenticate with AWS: to build the repository we first authenticate with AWS. We need to authenticate twice because we first need to download the Braket docker image which will be used as a base for building the OpenQAOA image, and a second time to upload the OpenQAOA image to your own ECR. | ||
- Authenticate through the AWS command line interface: | ||
- `docker login -u AWS -p $(aws ecr get-login-password --region ${REGION}) 292282985366.dkr.ecr.${REGION}.amazonaws.com`, this command is needed to download the base- | ||
- `docker login -u AWS -p $(aws ecr get-login-password --region ${REGION}) ${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com` | ||
- Note that you will need to re-do this procedure for any `${REGION}` of interest, and you will also need to insert your own `$ACCOUNT_ID` | ||
3. Build the image, and push it to the repository: | ||
- Go to the OpenQAOA root folder and type `docker build -t ${REPOSITORY_NAME}`, where you can choose the tag you wish | ||
- Then create an image tag (alias) with the full repository path for the ECR`docker tag ${REPOSITORY_NAME}:latest ${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/${REPOSITORY_NAME}:latest` | ||
- And finally push the image to: `${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/${REPOSITORY_NAME}:latest]` where all the names have been changed accordingly |
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
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
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
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
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