{ "cells": [ { "attachments": {}, "cell_type": "markdown", "id": "a477c993", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# How to run Qiskit on Amazon Braket" ] }, { "cell_type": "code", "execution_count": 1, "id": "3a9504c9", "metadata": {}, "outputs": [], "source": [ "# Use Braket SDK Cost Tracking to estimate the cost to run this example\n", "from braket.tracking import Tracker\n", "t = Tracker().start()" ] }, { "attachments": {}, "cell_type": "markdown", "id": "c885d164", "metadata": {}, "source": [ "If you're like many people who learned quantum computing in the past several years, you might have learned how to program quantum circuits with [Qiskit](https://qiskit.org): the open-source quantum Software Development Kit (SDK) first released in 2017. With the [Qiskit-Braket provider](https://github.com/qiskit-community/qiskit-braket-provider/blob/main/docs/tutorials/0_tutorial_qiskit-braket-provider_overview.ipynb), you can run your Qiskit code across any of the gate-based devices on the [Amazon Braket](https://aws.amazon.com/braket/) quantum computing service.\n", "\n", "**Note**: if you're running this in your local development environment (i.e. not from the Braket console), you'll need to make sure you've got your AWS account configured properly first to access Braket devices. Check out [this tutorial](https://aws.amazon.com/blogs/quantum-computing/setting-up-your-local-development-environment-in-amazon-braket/) for a walkthrough." ] }, { "attachments": {}, "cell_type": "markdown", "id": "b23c5287", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Access Braket devices from Qiskit \n", "\n", " There are quite a few different backend devices on Amazon Braket, so we'll walk through them one by one and give an example of recommended use cases for each." ] }, { "attachments": {}, "cell_type": "markdown", "id": "a94feb7b", "metadata": {}, "source": [ "### Quantum simulators\n", "Let's start with the ***local simulator***. This is a quantum full state vector simulator which runs *locally* -- that means wherever you're running this Jupyter notebook (e.g. your local development environment or a notebook instance on the Braket console).\n", "\n", "**Recommended use case:** Noiseless circuits up to ~12 qubits" ] }, { "cell_type": "code", "execution_count": 2, "id": "f162ba69", "metadata": {}, "outputs": [], "source": [ "from qiskit_braket_provider import BraketLocalBackend\n", "\n", "local_simulator = BraketLocalBackend()" ] }, { "attachments": {}, "cell_type": "markdown", "id": "17e2ab4d", "metadata": {}, "source": [ "Next, we have the ***local density matrix simulator***. This simulator also runs on your local machine, but allows you to simulate the effects of *noise* on your quantum circuit. Because density matrices are twice the size of state vectors, the number of qubits you can effectively simulate is half the size as the local state vector simulator.\n", "\n", "**Recommended use case:** Noisy circuits up to ~6 qubits" ] }, { "cell_type": "code", "execution_count": 3, "id": "2bfe0170", "metadata": {}, "outputs": [], "source": [ "local_dm_simulator = BraketLocalBackend(name='braket_dm')" ] }, { "attachments": {}, "cell_type": "markdown", "id": "de912d0e", "metadata": {}, "source": [ "Now let's look at Braket's *on-demand* simulators: these run on AWS computing resources and have some expanded features in addition to those of the local simulator. We can list all the available Braket simulators with the following code:" ] }, { "cell_type": "code", "execution_count": 4, "id": "70a24c64", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[BraketBackend[SV1], BraketBackend[TN1], BraketBackend[dm1]]" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from qiskit_braket_provider import AWSBraketProvider\n", "\n", "provider = AWSBraketProvider()\n", "\n", "provider.backends(statuses=[\"ONLINE\"], types=[\"SIMULATOR\"])" ] }, { "attachments": {}, "cell_type": "markdown", "id": "d846e7f2", "metadata": {}, "source": [ "First up for on-demand simulators is ***SV1***. This is a full state vector simulator which allows you to simulate larger circuits than the local simulator, along with the ability to [batch tasks](https://docs.aws.amazon.com/braket/latest/developerguide/braket-batching-tasks.html) and run them in parallel, as well as use advanced techniques like [adjoint gradient calculations](https://pennylane.ai/blog/2022/12/computing-adjoint-gradients-with-amazon-braket-sv1/) for variational quantum algorithms. \n", "\n", "**Recommended use case:** Noiseless variational algorithms on up to 34 qubits" ] }, { "cell_type": "code", "execution_count": 5, "id": "19024712", "metadata": {}, "outputs": [], "source": [ "aws_sv1 = provider.get_backend(\"SV1\")" ] }, { "attachments": {}, "cell_type": "markdown", "id": "41c66765", "metadata": {}, "source": [ "The next on-demand simulator is ***DM1***. This is a density matrix simulator which, like SV1, allows you to simulate a larger number of qubits, as well as take advantage of batch execution. \n", "\n", "**Recommended use case:** Noisy variational algorithms on up to 17 qubits" ] }, { "cell_type": "code", "execution_count": 6, "id": "54e855a5", "metadata": {}, "outputs": [], "source": [ "aws_dm1 = provider.get_backend(\"dm1\")" ] }, { "attachments": {}, "cell_type": "markdown", "id": "ae97b1a1", "metadata": {}, "source": [ "Lastly for on-demand simulators, we have ***TN1***. This is a tensor-network simulator, which represents each gate in a circuit as a tensor. TN1 can simulate a larger number of qubits for circuits with local gates or other special structure, but will typically be slower than SV1 or DM1 for circuits with long-range or all-to-all gate structure.\n", "\n", "**Recommended use case:** Noiseless quantum circuits with local connectivity and up to 50 qubits" ] }, { "attachments": {}, "cell_type": "markdown", "id": "ad54a536", "metadata": {}, "source": [ "**Note**: Each AWS resource, (like a file or CPU or QPU) lives in a specific region and may only be accessible from that region. For example, TN1 is only available in the `eu-west-2`, `us-east-1`, and `us-west-2` regions. \n", "\n", "To change your AWS region if you're running in a managed notebook, you'll need to use the GUI in the top right hand corner of the AWS console to select your new region, then relaunch or create your notebook from the Braket console.\n", "\n", "To change your AWS region if you're running in your local development environment, you run the following code snippet:\n", "```\n", "import os\n", "os.environ[\"AWS_REGION\"] = \"your-desired-region\"\n", "```" ] }, { "cell_type": "code", "execution_count": 7, "id": "cd711dcb", "metadata": {}, "outputs": [], "source": [ "# If you've switched to one of the regions where TN1 is accessible, feel free to uncomment the following code\n", "# aws_tn1 = provider.get_backend(\"TN1\")" ] }, { "attachments": {}, "cell_type": "markdown", "id": "dc6910f0", "metadata": {}, "source": [ "### Quantum Processing Units (QPUs)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "8bfc8706", "metadata": {}, "source": [ "Amazon Braket also provides access to a number of third-party quantum hardware devices. The following code shows how to view the supported QPUs which are currently online:" ] }, { "cell_type": "code", "execution_count": null, "id": "f5329bca", "metadata": {}, "outputs": [], "source": [ "provider.backends(statuses=[\"ONLINE\"], types=[\"QPU\"])" ] }, { "attachments": {}, "cell_type": "markdown", "id": "4c7a21d4", "metadata": {}, "source": [ "For a closer look at each quantum computer, you can peruse the [Providers Overview](https://aws.amazon.com/braket/quantum-computers/) on the Braket homepage, or the Devices tab on the left side of the Braket console. \n", "Currently only gate-based QPUs (IonQ, OQC, Rigetti) are supported with the Qiskit-Braket provider. " ] }, { "attachments": {}, "cell_type": "markdown", "id": "0800b99f", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Running circuits on Braket devices\n", "\n" ] }, { "attachments": {}, "cell_type": "markdown", "id": "6bf048f4", "metadata": {}, "source": [ "Now that we've walked through each of the quantum devices available through the Qiskit-Braket provider, let's take them for a spin! For this example, we'll create a 3-GHZ state on the Rigetti device, but feel free to choose a different QPU from the commented out devices below." ] }, { "cell_type": "code", "execution_count": null, "id": "a5beeb7b", "metadata": {}, "outputs": [], "source": [ "qpu_backend = provider.get_backend(\"Aspen-M-3\")\n", "# qpu_backend = provider.get_backend(\"Lucy\")\n", "# qpu_backend = provider.get_backend(\"Aria\")\n", "\n", "print(qpu_backend)" ] }, { "cell_type": "code", "execution_count": 18, "id": "e9d90ed2", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
┌───┐ \n", "q_0: ┤ H ├──■────■──\n", " └───┘┌─┴─┐ │ \n", "q_1: ─────┤ X ├──┼──\n", " └───┘┌─┴─┐\n", "q_2: ──────────┤ X ├\n", " └───┘" ], "text/plain": [ " ┌───┐ \n", "q_0: ┤ H ├──■────■──\n", " └───┘┌─┴─┐ │ \n", "q_1: ─────┤ X ├──┼──\n", " └───┘┌─┴─┐\n", "q_2: ──────────┤ X ├\n", " └───┘" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from qiskit import QuantumCircuit\n", "\n", "circuit = QuantumCircuit(3)\n", "circuit.h(0)\n", "circuit.cx(0, 1)\n", "circuit.cx(0, 2)\n", "circuit.draw()" ] }, { "cell_type": "code", "execution_count": 19, "id": "32fd1f51", "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "# run circuit\n", "qpu_task = qpu_backend.run(circuit, shots=10)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "9515c95b", "metadata": {}, "source": [ "Each task you run is assigned a unique ARN (Amazon Resource Name), which you can save and use to retrieve the data for your task after its run, even if you close your notebook." ] }, { "cell_type": "code", "execution_count": 20, "id": "d6f5d0da", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'arn:aws:braket:eu-west-2:567402972798:quantum-task/51449f9f-5b0b-476e-98e8-231fb90af30e'" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "task_id = qpu_task.job_id()\n", "task_id" ] }, { "attachments": {}, "cell_type": "markdown", "id": "3b7ee5ac", "metadata": {}, "source": [ "**Note**: Qiskit uses the name \\\"job\\\" to refer to what is called a \\\"task\\\" in Amazon Braket. This is why you access the ARN for the task by calling `.job_id()`. \n", "\n", "Now, Braket has a separate feature called \\\"Hybrid *Jobs*\\\", which is beyond the scope of this notebook, but which you can read about in the [developer guide](https://docs.aws.amazon.com/braket/latest/developerguide/braket-jobs.html)." ] }, { "cell_type": "code", "execution_count": 21, "id": "dec44bb5", "metadata": {}, "outputs": [], "source": [ "# Retrieve task data\n", "retrieved_task = qpu_backend.retrieve_job(job_id=task_id)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "355472d4", "metadata": {}, "source": [ "Then you can check the status of the task to see if it's finished:" ] }, { "cell_type": "code", "execution_count": 22, "id": "bb84627d", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "