diff --git a/examples/pennylane/5_Tracking_resource_usage/5_Tracking_resource_usage.ipynb b/examples/pennylane/5_Tracking_resource_usage/5_Tracking_resource_usage.ipynb index 3cef5f64e..5d4bad40a 100644 --- a/examples/pennylane/5_Tracking_resource_usage/5_Tracking_resource_usage.ipynb +++ b/examples/pennylane/5_Tracking_resource_usage/5_Tracking_resource_usage.ipynb @@ -11,7 +11,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "In this notebook we will explore how to use the PennyLane device tracker feature with Amazon Braket.\n", + "In this notebook we explore how to use the PennyLane device tracker feature with Amazon Braket.\n", "As is demonstrated in the [optimization of quantum circuits notebook](https://github.com/aws/amazon-braket-examples/blob/main/examples/pennylane/1_Parallelized_optimization_of_quantum_circuits/1_Parallelized_optimization_of_quantum_circuits.ipynb), computing gradients of quantum circuits involves multiple devices executions.\n", "This can lead to a large number of executions when optimizing quantum circuits.\n", "So to help users keep track of their usage, Amazon Braket works with PennyLane to record and make available useful information during the computation.\n", @@ -31,6 +31,67 @@ "cell_type": "code", "execution_count": 1, "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Looking in indexes: https://pypi.org/simple, https://pip.repos.neuron.amazonaws.com\n", + "Collecting git+https://github.com/PennyLaneAI/pennylane.git@318d0044c0c8683c97f5927376ffd504b60243ab\n", + " Cloning https://github.com/PennyLaneAI/pennylane.git (to revision 318d0044c0c8683c97f5927376ffd504b60243ab) to /tmp/pip-req-build-9uz55d9y\n", + " Running command git clone --filter=blob:none --quiet https://github.com/PennyLaneAI/pennylane.git /tmp/pip-req-build-9uz55d9y\n", + " Running command git rev-parse -q --verify 'sha^318d0044c0c8683c97f5927376ffd504b60243ab'\n", + " Running command git fetch -q https://github.com/PennyLaneAI/pennylane.git 318d0044c0c8683c97f5927376ffd504b60243ab\n", + " Running command git checkout -q 318d0044c0c8683c97f5927376ffd504b60243ab\n", + " Resolved https://github.com/PennyLaneAI/pennylane.git to commit 318d0044c0c8683c97f5927376ffd504b60243ab\n", + " Installing build dependencies ... \u001b[?25ldone\n", + "\u001b[?25h Getting requirements to build wheel ... \u001b[?25ldone\n", + "\u001b[?25h Preparing metadata (pyproject.toml) ... \u001b[?25ldone\n", + "\u001b[?25hRequirement already satisfied: numpy in /home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages (from PennyLane==0.27.0.dev0) (1.19.5)\n", + "Requirement already satisfied: cachetools in /home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages (from PennyLane==0.27.0.dev0) (4.2.4)\n", + "Requirement already satisfied: scipy in /home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages (from PennyLane==0.27.0.dev0) (1.5.2)\n", + "Requirement already satisfied: autograd in /home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages (from PennyLane==0.27.0.dev0) (1.5)\n", + "Requirement already satisfied: retworkx in /home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages (from PennyLane==0.27.0.dev0) (0.12.0)\n", + "Requirement already satisfied: networkx in /home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages (from PennyLane==0.27.0.dev0) (2.4)\n", + "Requirement already satisfied: appdirs in /home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages (from PennyLane==0.27.0.dev0) (1.4.4)\n", + "Requirement already satisfied: autoray>=0.3.1 in /home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages (from PennyLane==0.27.0.dev0) (0.5.1)\n", + "Collecting pennylane-lightning>=0.26\n", + " Downloading PennyLane_Lightning-0.26.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (13.7 MB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m13.7/13.7 MB\u001b[0m \u001b[31m20.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0m\n", + "\u001b[?25hRequirement already satisfied: toml in /home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages (from PennyLane==0.27.0.dev0) (0.10.2)\n", + "Requirement already satisfied: semantic-version>=2.7 in /home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages (from PennyLane==0.27.0.dev0) (2.10.0)\n", + "Requirement already satisfied: ninja in /home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages (from pennylane-lightning>=0.26->PennyLane==0.27.0.dev0) (1.10.2.4)\n", + "Requirement already satisfied: future>=0.15.2 in /home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages (from autograd->PennyLane==0.27.0.dev0) (0.18.2)\n", + "Requirement already satisfied: decorator>=4.3.0 in /home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages (from networkx->PennyLane==0.27.0.dev0) (4.4.0)\n", + "Requirement already satisfied: rustworkx==0.12.0 in /home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages (from retworkx->PennyLane==0.27.0.dev0) (0.12.0)\n", + "Building wheels for collected packages: PennyLane\n", + " Building wheel for PennyLane (pyproject.toml) ... \u001b[?25ldone\n", + "\u001b[?25h Created wheel for PennyLane: filename=PennyLane-0.27.0.dev0-py3-none-any.whl size=1064472 sha256=2d1c45a8bea4ac1222fd565c44e1053e9e5ce86ee2617e2600836e892b2e69d9\n", + " Stored in directory: /home/ec2-user/.cache/pip/wheels/cb/d9/6d/f4bb3339a47a7d20c3773e356b1fb576d0280bc2ce45fadb18\n", + "Successfully built PennyLane\n", + "Installing collected packages: pennylane-lightning, PennyLane\n", + " Attempting uninstall: pennylane-lightning\n", + " Found existing installation: PennyLane-Lightning 0.25.1\n", + " Uninstalling PennyLane-Lightning-0.25.1:\n", + " Successfully uninstalled PennyLane-Lightning-0.25.1\n", + " Attempting uninstall: PennyLane\n", + " Found existing installation: PennyLane 0.25.1\n", + " Uninstalling PennyLane-0.25.1:\n", + " Successfully uninstalled PennyLane-0.25.1\n", + "Successfully installed PennyLane-0.27.0.dev0 pennylane-lightning-0.26.1\n" + ] + } + ], + "source": [ + "#Get the pennylane repo content for null qubit support which hasn't been part of an official release yet (as of 11/2/22)\n", + "!pip install git+https://github.com/PennyLaneAI/pennylane.git@318d0044c0c8683c97f5927376ffd504b60243ab" + ] + }, + + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, "outputs": [], "source": [ "import pennylane as qml\n", @@ -39,24 +100,40 @@ "import time" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Using The PennyLane null.qubit Dummy Device" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We demonstrate using the resource tracker with different devices. We start with the Pennylane null.qubit, followed by the Braket local simulator and finally a Braket Managed Simulator\n", + "The Pennylane null.qubit acts as a dummy device that short circuits prior to creating Braket Tasks. If device usage is desired without creating actual tasks,\n", + "this device can be used with some limitations described in the following example." + ] + }, + { "cell_type": "markdown", "metadata": {}, "source": [ "Before we show the device resource tracker, let's first set up a circuit for demonstration and experimenting.\n", - "We will use a simple two qubit circuit with two parameters throughout this notebook.\n", - "We will start by evaluating it using the local Braket simulator." + "We will use a simple two qubit circuit with two parameters throughout this notebook.\n" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "wires = 2 # Number of qubits\n", "\n", - "dev = qml.device(\"braket.local.qubit\", wires=wires)\n", + "dev = qml.device(\"null.qubit\", wires=wires)\n", "\n", "def circuit(params):\n", " qml.RX(params[0], wires=0)\n", @@ -64,7 +141,7 @@ " qml.CNOT(wires=[0, 1])\n", " return qml.expval(qml.PauliZ(1))\n", "\n", - "qnode_local = qml.QNode(circuit, dev)\n", + "qnode_dummy = qml.QNode(circuit, dev)\n", "params = np.array([0.1, 0.2], requires_grad=True)" ] }, @@ -86,20 +163,20 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Expectation value of circuit: 0.9751703272018161\n" + "Expectation value of circuit: 0.0\n" ] } ], "source": [ "with qml.Tracker(dev) as tracker:\n", - " print(\"Expectation value of circuit:\", qnode_local(params))" + " print(\"Expectation value of circuit:\", qnode_dummy(params))" ] }, { @@ -117,19 +194,19 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "{'executions': [1], 'shots': [None], 'braket_task_id': ['3e22ac39-a7e7-425d-af6a-1d4f3cc7974f'], 'batches': [1], 'batch_len': [1]}\n" + "Expectation tracker history: {'executions': [1], 'shots': [None], 'batches': [1], 'batch_len': [1]}\n" ] } ], "source": [ - "print(tracker.history)" + "print(\"Expectation tracker history: \", tracker.history)" ] }, { @@ -138,9 +215,10 @@ "source": [ "We can see that this evaluation lead to a single circuit execution.\n", "This single execution had no shots, and was evaluated with a single batch of length 1.\n", - "When using the Braket local simulator, the device tracker records the unique id that the simulator assigns to new tasks.\n", + "When using the Pennylane null.qubit, there are no actual tasks created so there is no braket task ID, however there is a single execution.\n", "\n", - "Next, let's evaluate the gradient of this circuit and track the device usage." + "Next, let's evaluate the gradient of this circuit and track the device usage. The null.qubit short circuits such that no gradient is produced.\n", + "In addition note that we receive a warning about that the output is independent of the input. This is due to the null.qubit short circuit path." ] }, { @@ -152,16 +230,24 @@ "name": "stdout", "output_type": "stream", "text": [ - "Gradient of circuit: [-0.0978434 -0.19767681]\n", - "{'executions': [1, 1, 1, 1, 1], 'shots': [None, None, None, None, None], 'braket_task_id': ['7602e62c-dd42-40bf-a214-147fdeec9c93', '9e924369-432e-4e86-bd28-c18a3bd7ea2d', 'fe68b242-166c-496a-b1e2-df72bc7eedc6', '8e1f1427-6b2a-4261-a229-dec502fc008f', 'c6426b8f-6b25-4c9f-abac-ad60ae96c4c8'], 'batches': [1, 1], 'batch_len': [1, 4]}\n" + "Gradient of circuit: [0. 0.]\n", + "Gradient tracker history: {'executions': [1], 'shots': [None], 'batches': [1], 'batch_len': [1]}\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/ec2-user/anaconda3/envs/Braket/lib/python3.7/site-packages/autograd/tracer.py:14: UserWarning: Output seems independent of input.\n", + " warnings.warn(\"Output seems independent of input.\")\n" ] } ], "source": [ "with qml.Tracker(dev) as tracker:\n", - " print(\"Gradient of circuit:\", qml.grad(qnode_local)(params))\n", + " print(\"Gradient of circuit:\", qml.grad(qnode_dummy)(params))\n", "\n", - "print(tracker.history)" + "print(\"Gradient tracker history: \", tracker.history)" ] }, { @@ -169,7 +255,7 @@ "metadata": {}, "source": [ "Recall that evaluating the gradient of a quantum circuit will result in multiple circuit evaluations.\n", - "Here we see that to calculate this gradient, 5 new tasks were created and recorded in the device tracker.\n", + "With a simulator or QPU, 5 new tasks would be created in the device tracker. However with the Pennylane null.qubit this short circuits to a single execution\n", "For values which are numeric, such as the `executions`, the device tracker will accumulate all of the recorded data into `tracker.totals`" ] }, @@ -182,12 +268,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'executions': 5, 'batches': 2, 'batch_len': 5}\n" + "Gradient tracker totals: {'executions': 1, 'batches': 1, 'batch_len': 1}\n" ] } ], "source": [ - "print(tracker.totals)" + "print(\"Gradient tracker totals: \", tracker.totals)" ] }, { @@ -209,14 +295,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'executions': 5, 'shots': 500, 'batches': 2, 'batch_len': 5}\n" + "Gradient 100 shot totals: {'executions': 5, 'shots': 500, 'batches': 2, 'batch_len': 5}\n" ] } ], "source": [ "with qml.Tracker(dev) as tracker:\n", - " qml.grad(qnode_local)(params, shots=100)\n", - "print(tracker.totals)" + " qml.grad(qnode_dummy)(params, shots=100)\n", + "print(\"Gradient 100 shot totals: \", tracker.totals)" ] }, { @@ -237,19 +323,73 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'batches': 1, 'batch_len': 4}\n" + "Gradient 100 shot latest: {'batches': 1, 'batch_len': 4}\n" + ] + } + ], + "source": [ + "print(\"Gradient 100 shot latest: \", tracker.latest)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Using The Amazon Braket Local Simulators" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The Amazon Braket local simulator creates tasks in Braket that run locally, which reports additional information relative to the Pennylane null.qubit device.\n", + "Let's run the same example as above but create a new QNode using the Braket local simulator instead of the Pennylane null.qubit dummy device. We see that we get non-zero expected circuit values,\n", + "gradient circuit values, and we have Braket tasks and task IDs." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Expectation value of circuit: 0.9751703272018161\n", + "Expectation tracker history: {'executions': [1], 'shots': [None], 'braket_task_id': ['ffd99227-e493-4a8d-81f0-9145369b695b'], 'batches': [1], 'batch_len': [1]}\n", + "Gradient of circuit: [-0.0978434 -0.19767681]\n", + "Gradient tracker history: {'executions': [1, 1, 1, 1, 1], 'shots': [None, None, None, None, None], 'braket_task_id': ['26a7b50d-4dd3-4be2-b2de-f41e2b3f1302', '1477bef8-52b7-4ebb-a682-9ac44d029718', '7a786f90-c962-499a-8648-6b46aa4431de', 'e6abb1c1-642d-4114-abd2-9168a74fd8df', '70d47920-7bc0-461a-8727-d09fee3658d3'], 'batches': [1, 1], 'batch_len': [1, 4]}\n", + "Gradient tracker totals: {'executions': 5, 'batches': 2, 'batch_len': 5}\n", + "Gradient 100 shot totals: {'executions': 5, 'shots': 500, 'batches': 2, 'batch_len': 5}\n", + "Gradient 100 shot latest: {'batches': 1, 'batch_len': 4}\n" ] } ], "source": [ - "print(tracker.latest)" + "wires = 2 # Number of qubits\n", + "\n", + "dev = qml.device(\"braket.local.qubit\", wires=wires)\n", + "\n", + "qnode_local = qml.QNode(circuit, dev)\n", + "with qml.Tracker(dev) as tracker:\n", + " print(\"Expectation value of circuit:\", qnode_local(params))\n", + "print(\"Expectation tracker history: \", tracker.history)\n", + "with qml.Tracker(dev) as tracker:\n", + " print(\"Gradient of circuit:\", qml.grad(qnode_local)(params))\n", + "print(\"Gradient tracker history: \", tracker.history)\n", + "print(\"Gradient tracker totals: \", tracker.totals)\n", + "with qml.Tracker(dev) as tracker:\n", + " qml.grad(qnode_local)(params, shots=100)\n", + "print(\"Gradient 100 shot totals: \", tracker.totals)\n", + "print(\"Gradient 100 shot latest: \", tracker.latest)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Using Amazon Braket Simulators" + "## Using Amazon Braket Managed Simulators" ] }, { @@ -439,7 +579,7 @@ "\n", "print(\"Completed\", i + 1, \"steps of optimization.\")\n", "print(\"Optimized cost:\", cost)\n", - "print(\"Optimized parameters:\", params)\n" + "print(\"Optimized parameters:\", params)" ] }, { @@ -489,7 +629,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": {}, "outputs": [ {