From be2da71134ccde2cf751bd513cd448cc777d6894 Mon Sep 17 00:00:00 2001 From: Michael Broughton Date: Thu, 16 Jun 2022 13:14:29 -0700 Subject: [PATCH 1/2] Remove ion and NA tutorials from educators. --- docs/tutorials/educators/ion_device.ipynb | 345 ----------- docs/tutorials/educators/neutral_atom.ipynb | 639 -------------------- 2 files changed, 984 deletions(-) delete mode 100644 docs/tutorials/educators/ion_device.ipynb delete mode 100644 docs/tutorials/educators/neutral_atom.ipynb diff --git a/docs/tutorials/educators/ion_device.ipynb b/docs/tutorials/educators/ion_device.ipynb deleted file mode 100644 index e13523aa098..00000000000 --- a/docs/tutorials/educators/ion_device.ipynb +++ /dev/null @@ -1,345 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "cedf868076a2" - }, - "source": [ - "##### Copyright 2020 The Cirq Developers" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "id": "906e07f6e562" - }, - "outputs": [], - "source": [ - "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", - "# you may not use this file except in compliance with the License.\n", - "# You may obtain a copy of the License at\n", - "#\n", - "# https://www.apache.org/licenses/LICENSE-2.0\n", - "#\n", - "# Unless required by applicable law or agreed to in writing, software\n", - "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", - "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", - "# See the License for the specific language governing permissions and\n", - "# limitations under the License." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "bNlUyYQcgMF-" - }, - "source": [ - "# Ion Device Class" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "8478d245fbe2" - }, - "source": [ - "\n", - " \n", - " \n", - " \n", - " \n", - "
\n", - " View on QuantumAI\n", - " \n", - " Run in Google Colab\n", - " \n", - " View source on GitHub\n", - " \n", - " Download notebook\n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "f3591bc2d8e6" - }, - "source": [ - "The `IonDevice` represents a trapped ion quantum computer with all-to-all qubit connectivity. The number of qubits as well as the duration of gates and measurements are specified by the user when creating an ion device.\n", - "\n", - "Two-qubit gates are implemented by an Ising-type coupling known as the *Mølmer–Sørensen* gate. The Mølmer–Sørensen gate couples ions through the shared motional modes of the ion chain. The ion motion and internal state decouples at the end of each gate. The `IonDevice` class assumes this decoupling is perfect and does not explicitly model the ion motion. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "GTjMbjyAfJCK" - }, - "outputs": [], - "source": [ - "try:\n", - " import cirq\n", - "except ImportError:\n", - " print(\"installing cirq...\")\n", - " !pip install cirq --quiet\n", - " print(\"installed cirq.\")\n", - " import cirq\n", - "\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "v3YMaPw1hfV_" - }, - "source": [ - "## Defining an `IonDevice`" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "8691c551a2de" - }, - "source": [ - "To define an `IonDevice`, we specify\n", - "\n", - "- The set of qubits in the device,\n", - "- The duration of single-qubit gates,\n", - "- The duration of two-qubit gates, and\n", - "- The duration of measurement gates.\n", - "\n", - "The code below creates an `IonDevice` with four qubits in a linear array. The durations we use for each type of gate are reasonable order-of-magnitude estimates, though they will differ for different trapped ion computers." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "On6Wrh3XhSPO" - }, - "outputs": [], - "source": [ - "\"\"\"Create an IonDevice.\"\"\"\n", - "ion_device = cirq.IonDevice(\n", - " qubits=cirq.LineQubit.range(4),\n", - " oneq_gates_duration=cirq.Duration(micros=10),\n", - " twoq_gates_duration=cirq.Duration(micros=200),\n", - " measurement_duration=cirq.Duration(micros=100)\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "4e6219ddb8d1" - }, - "source": [ - "We can view some properties of the `ion_device` as shown below." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "18dc0362040d" - }, - "outputs": [], - "source": [ - "\"\"\"View some properties of the device.\"\"\"\n", - "# Display the ion device.\n", - "print(\"Ion Device:\\n\", ion_device)\n", - "\n", - "# Get all qubits in the device.\n", - "print(\"\\nQubits in the IonDevice:\\n\", sorted(ion_device.qubits))\n", - "\n", - "# Get a qubit at a certain position (if present).\n", - "pos = 2\n", - "print(f\"\\nQubit at position {pos}:\\n\", ion_device.at(pos))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "8d3f1c23ee97" - }, - "source": [ - "## Native Gate Set" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "ptv6T5WH8CLa" - }, - "source": [ - "An `IonDevice` can implement single-qubit rotations about the $X$, $Y$, and $Z$ axes of the Bloch sphere: namely, `cirq.rx`, `cirq.ry`, and `cirq.rz`. \n", - "\n", - "An `IonDevice` can implement the two-qubit Mølmer–Sørensen gate, a rotation about the $XX$ axis in the two-qubit Bloch sphere defined as\n", - "\n", - "\\begin{equation}\n", - " \\exp(-i t XX) = \\left[ \\begin{matrix}\n", - " \\cos t & 0 & 0 & -i \\sin t \\\\\n", - " 0 & \\cos t & -i \\sin t & 0 \\\\\n", - " 0 & -i \\sin t & \\cos t & 0 \\\\\n", - " -i \\sin t & 0 & 0 & \\cos t\n", - " \\end{matrix} \\right] .\n", - "\\end{equation}\n", - "\n", - "The Mølmer–Sørensen gate is defined in Cirq as `cirq.ms`." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "bb47425324e6" - }, - "source": [ - "One can check if a given gate is valid with `IonDevice.validate_gate`. This method raises an error if the gate is invalid (not supported by the device) and does nothing if the gate is valid (supported by the device)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "f43884525325" - }, - "outputs": [], - "source": [ - "\"\"\"Check if gates are valid. Invalid gates raise a ValueError.\"\"\"\n", - "# Single-qubit X rotation of any angle is supported.\n", - "ion_device.validate_gate(cirq.rx(np.pi / 7))\n", - "\n", - "# Single-qubit Z rotation of any angle is supported.\n", - "ion_device.validate_gate(cirq.rz(np.pi / 5))\n", - "\n", - "# Mølmer–Sørensen gate of any angle is supported.\n", - "ion_device.validate_gate(cirq.ms(np.pi / 4))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "e99a107bb042" - }, - "source": [ - "One can also validate operations and circuits with `IonDevice.validate_operation` and `IonDevice.validate_circuit`, respectively." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "f9064152b23a" - }, - "source": [ - "We can get the duration of valid operations as follows." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "256eb4b5280a" - }, - "outputs": [], - "source": [ - "\"\"\"Get the duration of valid operations.\"\"\"\n", - "# Duration of a single-qubit operation.\n", - "ion_device.duration_of(cirq.ry(np.pi / 2).on(ion_device.at(0)))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "114420a1171f" - }, - "source": [ - "## Decomposing Operations and Circuits" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "ea89fcfaefde" - }, - "source": [ - "Operations which are not valid on the device can be decomposed into a set of valid operations. For example, a CNOT gate is not supported but can be implemented with the following decomposition." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "217ab5ef3cdd" - }, - "outputs": [], - "source": [ - "\"\"\"Decompose a CNOT operation into valid IonDevice operations.\"\"\"\n", - "# Get a CNOT operation.\n", - "op = cirq.CNOT(ion_device.at(0), ion_device.at(1))\n", - "\n", - "# Decompose it for the IonDevice.\n", - "ion_device_ops = cirq.ConvertToIonGates().convert_one(op)\n", - "\n", - "# Print the sequence of operations to implement a CNOT.\n", - "print(\"Sequence of IonDevice operations for a CNOT:\\n\")\n", - "print(cirq.Circuit(ion_device_ops))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "0bb2fb2a1c27" - }, - "source": [ - "Circuits can also be decomposed in a similar manner using `IonDevice.decompose_circuit`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "Hotk4cHCpXCV" - }, - "outputs": [], - "source": [ - "\"\"\"Decompose a circuit into IonDevice operations.\"\"\"\n", - "# Example circuit to decompose.\n", - "circuit = cirq.Circuit(\n", - " cirq.H(cirq.LineQubit(0)),\n", - " cirq.CNOT(cirq.LineQubit(0), cirq.LineQubit(1)),\n", - " cirq.CNOT(cirq.LineQubit(0), cirq.LineQubit(2))\n", - ")\n", - "\n", - "# Display it.\n", - "print(\"Circuit to decompose:\\n\")\n", - "print(circuit)\n", - "\n", - "# Decompose the circuit.\n", - "ion_device_circuit = ion_device.decompose_circuit(circuit)\n", - "\n", - "# Display the decomposed circuit.\n", - "print(\"\\nIonDevice circuit:\\n\")\n", - "print(ion_device_circuit)" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "name": "ion_device.ipynb", - "toc_visible": true - }, - "kernelspec": { - "display_name": "Python 3", - "name": "python3" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} diff --git a/docs/tutorials/educators/neutral_atom.ipynb b/docs/tutorials/educators/neutral_atom.ipynb deleted file mode 100644 index a34f70a8dd0..00000000000 --- a/docs/tutorials/educators/neutral_atom.ipynb +++ /dev/null @@ -1,639 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "cedf868076a2" - }, - "source": [ - "##### Copyright 2020 The Cirq Developers" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "id": "906e07f6e562" - }, - "outputs": [], - "source": [ - "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", - "# you may not use this file except in compliance with the License.\n", - "# You may obtain a copy of the License at\n", - "#\n", - "# https://www.apache.org/licenses/LICENSE-2.0\n", - "#\n", - "# Unless required by applicable law or agreed to in writing, software\n", - "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", - "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", - "# See the License for the specific language governing permissions and\n", - "# limitations under the License." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "166af89a7bc3" - }, - "source": [ - "# Neutral atom device class" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "416c50754585" - }, - "source": [ - "\n", - " \n", - " \n", - " \n", - " \n", - "
\n", - " View on QuantumAI\n", - " \n", - " Run in Google Colab\n", - " \n", - " View source on GitHub\n", - " \n", - " Download notebook\n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "bNlUyYQcgMF-" - }, - "source": [ - "This tutorial provides an introduction to making circuits that are compatible with neutral atom devices.\n", - "\n", - "Neutral atom devices implement quantum gates in one of two ways. One method is by hitting the entire qubit array with microwaves to simultaneously act on every qubit. This method implements global $XY$ gates which take up to $100$ microseconds to perform. Alternatively, we can shine laser light on some fraction of the array. Gates of this type typically take around $1$ microsecond to perform. This method can act on one or more qubits at a time up to some limit dictated by the available laser power and the beam steering system used to address the qubits. Each category in the native gate set has its own limit, discussed more below." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "GTjMbjyAfJCK" - }, - "outputs": [], - "source": [ - "try:\n", - " import cirq\n", - "except ImportError:\n", - " print(\"installing cirq...\")\n", - " !pip install cirq --quiet\n", - " import cirq\n", - " print(\"installed cirq.\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "4927d86fa122" - }, - "outputs": [], - "source": [ - "from math import pi" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "b23c49ab588f" - }, - "source": [ - "## Defining a `NeutralAtomDevice`" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "Z0X2AWrhrcHR" - }, - "source": [ - "To define a `NeutralAtomDevice`, we specify\n", - "\n", - "- The set of qubits in the device.\n", - "- The maximum duration of gates and measurements.\n", - "- `max_parallel_z`: The maximum number of single qubit $Z$ rotations that can be applied in parallel.\n", - "- `max_parallel_xy`: The maximum number of single qubit $XY$ rotations that can be applied in parallel.\n", - "- `max_parallel_c`: The maximum number of atoms that can be affected by controlled gates simultaneously.\n", - " - Note that `max_parallel_c` must be less than or equal to the minimum of `max_parallel_z` and `max_parallel_xy`.\n", - "- `control_radius`: The maximum allowed distance between atoms acted on by controlled gates.\n", - "\n", - "We show an example of defining a `NeutralAtomDevice` below." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "On6Wrh3XhSPO" - }, - "outputs": [], - "source": [ - "\"\"\"Defining a NeutralAtomDevice.\"\"\"\n", - "# Define milliseconds and microseconds for convenience.\n", - "ms = cirq.Duration(nanos=10**6)\n", - "us = cirq.Duration(nanos=10**3)\n", - "\n", - "# Create a NeutralAtomDevice\n", - "neutral_atom_device = cirq.NeutralAtomDevice(\n", - " qubits=cirq.GridQubit.rect(2, 3),\n", - " measurement_duration=5 * ms,\n", - " gate_duration=100 * us,\n", - " max_parallel_z=3,\n", - " max_parallel_xy=3,\n", - " max_parallel_c=3,\n", - " control_radius=2\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "6342cf6147b2" - }, - "source": [ - "Note that all above arguments are required to instantiate a `NeutralAtomDevice`. The example device above has the following properties:\n", - "\n", - "- The device is defined on a $3 \\times 3$ grid of qubits.\n", - "- Measurements take $5$ milliseconds.\n", - "- Gates may take as long as $100$ microseconds if we utilize global microwave gates. Otherwise, a more reasonable bound would be $1$ microsecond.\n", - "- A maximum of $3$ qubits may be simultaneously acted on by any gate category (`max_parallel_c = 3`).\n", - "- Controlled gates have next-nearest neighbor connectivity (`control_radius = 2`).\n", - "\n", - "We can see some properties of the device as follows." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "de96b2753bec" - }, - "outputs": [], - "source": [ - "\"\"\"View some properties of the device.\"\"\"\n", - "# Display the neutral atom device.\n", - "print(\"Neutral atom device:\", neutral_atom_device, sep=\"\\n\")\n", - "\n", - "# Get the neighbors of a qubit.\n", - "qubit = cirq.GridQubit(0, 1)\n", - "print(f\"\\nNeighbors of qubit {qubit}:\")\n", - "print(neutral_atom_device.neighbors_of(qubit))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "8d75e1232082" - }, - "source": [ - "## Native gate set" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "v3YMaPw1hfV_" - }, - "source": [ - "The gates supported by the `NeutralAtomDevice` class can be placed into three categories:\n", - "\n", - "1. Single-qubit rotations about the $Z$ axis.\n", - "2. Single-qubit rotations about an arbitrary axis in the $X$-$Y$ plane. We refer to these as $XY$ gates in this tutorial.\n", - "3. Controlled gates: CZ, CNOT, CCZ, and CCNOT (TOFFOLI).\n", - "\n", - "Any rotation angle is allowed for single-qubit rotations. Some examples of valid single-qubit rotations are shown below." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "p3QZd4ayaq_V" - }, - "outputs": [], - "source": [ - "# Examine metadata gateset info.\n", - "for gate_family in neutral_atom_device.metadata.gateset.gates:\n", - " print(gate_family)\n", - " print('-' * 80)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "Hotk4cHCpXCV" - }, - "outputs": [], - "source": [ - "\"\"\"Examples of valid single-qubit gates.\"\"\"\n", - "# Single qubit Z rotations with any angle are valid.\n", - "neutral_atom_device.validate_gate(cirq.rz(pi / 5))\n", - "\n", - "# Single qubit rotations about the X-Y axis with any angle are valid.\n", - "neutral_atom_device.validate_gate(\n", - " cirq.PhasedXPowGate(phase_exponent=pi / 3, exponent=pi / 7)\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "239a75b7d5c6" - }, - "source": [ - "A Hadamard gate is invalid because it is a rotation in the $X$-$Z$ plane instead of the $X$-$Y$ plane." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "a8b877ad0a87" - }, - "outputs": [], - "source": [ - "\"\"\"Example of an invalid single-qubit gate.\"\"\"\n", - "invalid_gate = cirq.H\n", - "\n", - "try:\n", - " neutral_atom_device.validate_gate(invalid_gate)\n", - "except ValueError as e:\n", - " print(f\"As expected, {invalid_gate} is invalid!\", e)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "c29c2fd3d197" - }, - "source": [ - "For controlled gates, the rotation must be a multiple of $\\pi$ due to the physical implementation of the gates. In Cirq, this means the exponent of a controlled gate must be an integer. The next cell shows two examples of valid controlled gates." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "a2c2c1a49432" - }, - "outputs": [], - "source": [ - "\"\"\"Examples of valid multi-qubit gates.\"\"\"\n", - "# Controlled gates with integer exponents are valid.\n", - "neutral_atom_device.validate_gate(cirq.CNOT)\n", - "\n", - "# Controlled NOT gates with two controls are valid.\n", - "neutral_atom_device.validate_gate(cirq.TOFFOLI)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "62c881b20d63" - }, - "source": [ - "Any controlled gate with non-integer exponent is invalid." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "ChT4QK7TsabR" - }, - "outputs": [], - "source": [ - "\"\"\"Example of an invalid controlled gate.\"\"\"\n", - "invalid_gate = cirq.CNOT ** 1.5\n", - "\n", - "try:\n", - " neutral_atom_device.validate_gate(invalid_gate)\n", - "except ValueError as e:\n", - " print(f\"As expected, {invalid_gate} is invalid!\", e)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "533125e85e19" - }, - "source": [ - "Multiple controls are allowed as long as every pair of atoms (qubits) acted on by the controlled gate are close enough to each other. We can see this by using the `validate_operation` (or `validate_circuit`) method, as follows." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "59ce97fd61ec" - }, - "outputs": [], - "source": [ - "\"\"\"Examples of valid and invalid multi-controlled gates.\"\"\"\n", - "# This TOFFOLI is valid because all qubits involved are close enough to each other.\n", - "valid_toffoli = cirq.TOFFOLI.on(cirq.GridQubit(0, 0), cirq.GridQubit(0, 1), cirq.GridQubit(0, 2))\n", - "neutral_atom_device.validate_operation(valid_toffoli)\n", - "\n", - "# This TOFFOLI is invalid because all qubits involved are not close enough to each other.\n", - "invalid_toffoli = cirq.TOFFOLI.on(cirq.GridQubit(0, 0), cirq.GridQubit(1, 0), cirq.GridQubit(0, 2))\n", - "\n", - "try:\n", - " neutral_atom_device.validate_operation(invalid_toffoli)\n", - "except ValueError as e:\n", - " print(f\"As expected, {invalid_toffoli} is invalid!\", e)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "4ac323a867ad" - }, - "source": [ - "`NeutralAtomDevice`s do not currently support gates with more than two controls although these are in principle allowed by the physical realizations." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "30d77c374b01" - }, - "outputs": [], - "source": [ - "\"\"\"Any gate with more than two controls is invalid.\"\"\"\n", - "invalid_gate = cirq.ControlledGate(cirq.TOFFOLI)\n", - "\n", - "try:\n", - " neutral_atom_device.validate_gate(invalid_gate)\n", - "except ValueError as e:\n", - " print(f\"As expected, {invalid_gate} is invalid!\", e)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "88d8a175bcdd" - }, - "source": [ - "Finally, we note that the duration of any operation can be determined via the `duration_of` method." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "a8f7e867f019" - }, - "outputs": [], - "source": [ - "\"\"\"Example of getting the duration of a valid operation.\"\"\"\n", - "neutral_atom_device.duration_of(valid_toffoli)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "7f94b0d4ccdf" - }, - "source": [ - "### Moment and circuit rules" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "Ug-2oBPPtZzU" - }, - "source": [ - "In addition to consisting of valid operations as discussed above, valid moments on a `NeutralAtomDevice` must satisfy the following criteria:\n", - "\n", - "1. Only `max_parallel_c` gates of the same category may be performed in the same moment.\n", - "2. All instances of gates in the same category in the same moment must be identical.\n", - "3. Controlled gates cannot be applied in parallel with other gate types.\n", - " - Physically, this is because controlled gates make use of all types of light used to implement gates.\n", - "4. Qubits acted on by different controlled gates in parallel must be farther apart than the `control_radius`.\n", - " - Physically, this is so that the entanglement mechanism doesn't cause the gates to interfere with one another.\n", - "5. All measurements must be terminal.\n", - "\n", - "Moments can be validated with the `validate_moment` method. Some examples are given below." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "Nr-rfUgOtDxE" - }, - "outputs": [], - "source": [ - "\"\"\"Example of a valid moment with single qubit gates.\"\"\"\n", - "qubits = sorted(neutral_atom_device.qubits)\n", - "\n", - "# Get a valid moment.\n", - "valid_moment = cirq.Moment(cirq.Z.on_each(qubits[:3]) + cirq.X.on_each(qubits[3:6]))\n", - "\n", - "# Display it.\n", - "print(\"Example of a valid moment with single-qubit gates:\", cirq.Circuit(valid_moment), sep=\"\\n\\n\")\n", - "\n", - "# Verify it is valid.\n", - "neutral_atom_device.validate_moment(valid_moment)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "1393b2a6234e" - }, - "source": [ - "Recall that we defined `max_parallel_z = 3` in our device. Thus, if we tried to do 4 $Z$ gates in the same moment, this would be invalid." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "4b9f3915276b" - }, - "outputs": [], - "source": [ - "\"\"\"Example of an invalid moment with single qubit gates.\"\"\"\n", - "# Get an invalid moment.\n", - "invalid_moment = cirq.Moment(cirq.Z.on_each(qubits[:4]))\n", - "\n", - "# Display it.\n", - "print(\"Example of an invalid moment with single-qubit gates:\", cirq.Circuit(invalid_moment), sep=\"\\n\\n\")\n", - "\n", - "# Uncommenting raises ValueError: Too many simultaneous Z gates.\n", - "# neutral_atom_device.validate_moment(invalid_moment)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "5e47c71c4570" - }, - "source": [ - "This is also true for 4 $XY$ gates since we set `max_parallel_xy = 3`. However, there is an exception for $XY$ gates acting on *every* qubit, as illustrated below." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "fa06394e7497" - }, - "outputs": [], - "source": [ - "\"\"\"An XY gate can be performed on every qubit in the device simultaneously.\n", - "\n", - "If the XY gate does not act on every qubit, it must act on <= max_parallel_xy qubits.\n", - "\"\"\"\n", - "valid_moment = cirq.Moment(cirq.X.on_each(qubits))\n", - "neutral_atom_device.validate_moment(valid_moment)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "89c05574161d" - }, - "source": [ - "Although both $Z$ and $Z^{1.5}$ are valid gates, they cannot be performed simultaneously because all gates \"of the same type\" must be identical in the same moment." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "61112be5f754" - }, - "outputs": [], - "source": [ - "\"\"\"Example of an invalid moment with single qubit gates.\"\"\"\n", - "# Get an invalid moment.\n", - "invalid_moment = cirq.Moment(cirq.Z(qubits[0]), cirq.Z(qubits[1]) ** 1.5)\n", - "\n", - "# Display it.\n", - "print(\"Example of an invalid moment with single-qubit gates:\", cirq.Circuit(invalid_moment), sep=\"\\n\\n\")\n", - "\n", - "# Uncommenting raises ValueError: Non-identical simultaneous Z gates.\n", - "# neutral_atom_device.validate_moment(invalid_moment)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "35e2090ccb60" - }, - "source": [ - "### Exercise: Multiple controlled gates in the same moment" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "4b78afc8053d" - }, - "source": [ - "Construct a `NeutralAtomDevice` which is capable of implementing two `CNOT`s in the same moment. Verify that these operations can indeed be performed in parallel by calling the `validate_moment` method or showing that Cirq inserts the operations into the same moment." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "f8b1f29f22c9" - }, - "outputs": [], - "source": [ - "# Your code here!" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "86a3141cdfb2" - }, - "source": [ - "#### Solution" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "3231b8c17951" - }, - "outputs": [], - "source": [ - "\"\"\"Example solution for creating a device which allows two CNOTs in the same moment.\"\"\"\n", - "# Create a NeutralAtomDevice.\n", - "device = cirq.NeutralAtomDevice(\n", - " qubits=cirq.GridQubit.rect(2, 3),\n", - " measurement_duration=5 * cirq.Duration(nanos=10**6),\n", - " gate_duration=100 * cirq.Duration(nanos=10**3),\n", - " max_parallel_z=4,\n", - " max_parallel_xy=4,\n", - " max_parallel_c=4,\n", - " control_radius=1\n", - ")\n", - "print(\"Device:\")\n", - "print(device)\n", - "\n", - "# Create a circuit for a NeutralAtomDevice.\n", - "circuit = cirq.Circuit()\n", - "\n", - "# Append two CNOTs that can be in the same moment.\n", - "circuit.append(\n", - " [cirq.CNOT(cirq.GridQubit(0, 0), cirq.GridQubit(1, 0)), \n", - " cirq.CNOT(cirq.GridQubit(0, 2), cirq.GridQubit(1, 2))]\n", - ")\n", - "\n", - "# Append two CNOTs that cannot be in the same moment.\n", - "circuit.append(\n", - " cirq.Moment(cirq.CNOT(cirq.GridQubit(0, 0), cirq.GridQubit(1, 0))), \n", - " cirq.Moment(cirq.CNOT(cirq.GridQubit(0, 1), cirq.GridQubit(1, 1)))\n", - ")\n", - "\n", - "# Validate the circuit.\n", - "device.validate_circuit(circuit)\n", - "\n", - "# Display the circuit.\n", - "print(\"\\nCircuit:\")\n", - "print(circuit)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "d29db15ac256" - }, - "source": [ - "Note that the square brackets above/below the circuit indicate the first two `CNOT`s are in the same moment." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "name": "neutral_atom.ipynb", - "toc_visible": true - }, - "kernelspec": { - "display_name": "Python 3", - "name": "python3" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} From ce3324c002f84356bb226191eddb3d56faea5f5e Mon Sep 17 00:00:00 2001 From: Michael Broughton Date: Thu, 16 Jun 2022 14:23:43 -0700 Subject: [PATCH 2/2] Removed use in book and _index.yaml. --- docs/_book.yaml | 7 ------- docs/hardware/_index.yaml | 14 -------------- 2 files changed, 21 deletions(-) diff --git a/docs/_book.yaml b/docs/_book.yaml index da4050fb83a..87b5ae52855 100644 --- a/docs/_book.yaml +++ b/docs/_book.yaml @@ -146,13 +146,6 @@ upper_tabs: - title: "Getting started with Rigetti hardware" path: /cirq/tutorials/rigetti/getting_started - #### CUSTOM DEVICES #### - - heading: "Custom devices" - - title: "Neutral atom device" - path: /cirq/tutorials/educators/neutral_atom - - title: "Ion device" - path: /cirq/tutorials/educators/ion_device - - name: "Noise" contents: - title: "Overview" diff --git a/docs/hardware/_index.yaml b/docs/hardware/_index.yaml index c164c003ade..8afa1ca2f04 100644 --- a/docs/hardware/_index.yaml +++ b/docs/hardware/_index.yaml @@ -117,17 +117,3 @@ landing_page: path: /cirq/tutorials/rigetti/getting_started icon: name: menu_book - - - heading: Custom devices - description: How to write custom Device classes for quantum hardware. More information for vendors on integrating with cirq can be found on the RFC page. - items: - - heading: Neutral atom device - description: A custom device class for a neutral atom device. - path: /cirq/tutorials/educators/neutral_atom - icon: - name: menu_book - - heading: Ion device - description: A custom device class for an ion device. - path: /cirq/tutorials/educators/ion_device - icon: - name: menu_book