From 333ab23877cbdece7d65b881277c736677103c71 Mon Sep 17 00:00:00 2001 From: Michael Broughton Date: Mon, 23 May 2022 16:04:12 -0700 Subject: [PATCH 1/6] Device tutorial rework. --- docs/devices.ipynb | 357 +++++++++++++++++++++++++++++++++++++++++++++ docs/devices.md | 63 -------- 2 files changed, 357 insertions(+), 63 deletions(-) create mode 100644 docs/devices.ipynb delete mode 100644 docs/devices.md diff --git a/docs/devices.ipynb b/docs/devices.ipynb new file mode 100644 index 00000000000..56b14ab1afa --- /dev/null +++ b/docs/devices.ipynb @@ -0,0 +1,357 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "DkA0Fobtb9dM" + }, + "source": [ + "##### Copyright 2020 The Cirq Developers" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "cellView": "form", + "id": "tUshu7YfcAAW" + }, + "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": "igOQCrBOcF5d" + }, + "source": [ + "# Devices" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "LHRAvc9TcHOH" + }, + "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": "code", + "execution_count": null, + "metadata": { + "id": "bd9529db1c0b" + }, + "outputs": [], + "source": [ + "try:\n", + " import cirq\n", + "except ImportError:\n", + " print(\"installing cirq...\")\n", + " !pip install --quiet cirq\n", + " print(\"installed cirq.\")\n", + " import cirq " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "x6s7QnYKAdo7" + }, + "source": [ + "## 1. Validation basics\n", + "\n", + "When you are looking to run an algorithm on a real quantum computer (not a simulated one), there are often many additional constraints placed on the circuits you would like to run. Qubit connectivity, algorithm layout and types of gates used in the circuit all become much more important. Cirq uses the abtract class `Device` to represent constraints of an actual quantum processor, an example implementation of a device can be seen in the `cirq_google.Sycamore` class:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "BFcKF8Xp-A2S" + }, + "outputs": [], + "source": [ + "import cirq_google\n", + "my_device = cirq_google.Sycamore\n", + "my_device" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bN7O0XCLAH7G" + }, + "source": [ + "All devices are capable of validing moments, operations and circuits with the `validate_***` method to verify if they would work on that device or not. You can check if the following operations work on the Sycamore device:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "53z2ucqZAFz7" + }, + "outputs": [], + "source": [ + "q1, q2, q3 = cirq.GridQubit(7, 4), cirq.GridQubit(7, 5), cirq.GridQubit(7, 6)\n", + "op1 = cirq.X(cirq.GridQubit(7 ,7))\n", + "\n", + "try:\n", + " my_device.validate_operation(op1)\n", + "except Exception as e:\n", + " print(e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "jkgV8lhEB7L5" + }, + "source": [ + "Above you used a qubit that wasn't on the device and was invalid. Most validate operations also take into account things like supported gates and connectivity as well:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "VM3kDY6QCRPY" + }, + "outputs": [], + "source": [ + "op1 = cirq.H(q1)\n", + "op2 = cirq_google.SYC(q1, q3)\n", + "\n", + "try:\n", + " my_device.validate_operation(op1)\n", + "except Exception as e:\n", + " print(e)\n", + "\n", + "try:\n", + " my_device.validate_operation(op2)\n", + "except Exception as e:\n", + " print(e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "EcTgQg5xCxzG" + }, + "source": [ + "These validation operations can also be used with full circuits:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "EiolyMKLC262" + }, + "outputs": [], + "source": [ + "my_circuit = cirq.Circuit(\n", + " cirq.PhasedXPowGate(phase_exponent=0.3)(q1),\n", + " cirq.PhasedXPowGate(phase_exponent=0.3)(q2),\n", + " cirq_google.SYC(q1, q2),\n", + " cirq_google.SYC(q2, q3),\n", + ")\n", + "my_device.validate_circuit(my_circuit)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-sNjRTCKDb2D" + }, + "source": [ + "`my_circuit` satisfies all the device constraints and could be run on a Sycamore device." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BrxB0eCUDvlI" + }, + "source": [ + "## 2. Metadata features\n", + "\n", + "Some devices will also expose additional information via the `metadata` property. You can look at the metadata information of the Sycamore device with:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "clsvdcXzEOIV" + }, + "outputs": [], + "source": [ + "metadata = my_device.metadata\n", + "metadata" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "glMmeLevElt-" + }, + "source": [ + "The Sycamore device is a 2d grid device that exposes a `cirq.GridDeviceMetadata` with a uniform set of gates across all the qubits as well as a connectivity graph. You can explore the properties below:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "9Zm_1IsFEiHT" + }, + "outputs": [], + "source": [ + "type(metadata)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "JbwrPD_AETiX" + }, + "outputs": [], + "source": [ + "qubit_set = metadata.qubit_set\n", + "nx_graph = metadata.nx_graph\n", + "gateset = metadata.gateset\n", + "\n", + "print(gateset)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fo6ZTYN4HBVL" + }, + "source": [ + "These metadata features can be useful when designing/building algorithms around certain device information in order to tailor them for that device." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RvC4xz_OHT3s" + }, + "source": [ + "## 3. The `cirq.Device` interface\n", + "\n", + "For advanced users (such as vendors) it is also possible to implement your own Device with its own unique constraints and metadata information. Below you can implement our own fictituous device:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "cA7AdVWJCpRr" + }, + "outputs": [], + "source": [ + "class MyDevice(cirq.Device):\n", + " \"\"\"Five qubits on a line, supporting X/Y/Z and CZ between neighbors.\"\"\"\n", + " def __init__(self):\n", + " self._qubits = set(cirq.LineQubit.range(5))\n", + " self._supported_gates = cirq.Gateset(\n", + " cirq.XPowGate, cirq.YPowGate, cirq.ZPowGate, cirq.CZPowGate\n", + " )\n", + "\n", + " def validate_operation(self, operation):\n", + " if any(x not in self._qubits for x in operation.qubits):\n", + " raise ValueError(\"Using qubits not found on device.\")\n", + "\n", + " if len(operation.qubits) == 2:\n", + " p, q = operation.qubits\n", + " if not p.is_adjacent(q):\n", + " raise ValueError('Non-local interaction: {}'.format(repr(operation)))\n", + "\n", + " if operation not in self._supported_gates:\n", + " raise ValueError(\"Unsupported operation type.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9oRUQuGGI7MJ" + }, + "source": [ + "and use it to validate circuits:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "2e_UnChLDeOC" + }, + "outputs": [], + "source": [ + "my_device = MyDevice()\n", + "\n", + "my_circuit = cirq.Circuit(\n", + " cirq.X(cirq.LineQubit(0)),\n", + " cirq.X(cirq.LineQubit(2)),\n", + " cirq.X(cirq.LineQubit(4)),\n", + " cirq.CZ(*cirq.LineQubit.range(2))\n", + ")\n", + "\n", + "my_device.validate_circuit(my_circuit)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "OZxolGY3I82H" + }, + "source": [ + "Success! You have used Devices in Cirq to validate circuits for compatability when running as well as explored metadata information on the device and implemented your own boilerplate device." + ] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [], + "name": "devices.ipynb", + "toc_visible": true + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/docs/devices.md b/docs/devices.md deleted file mode 100644 index 14d3bb8d130..00000000000 --- a/docs/devices.md +++ /dev/null @@ -1,63 +0,0 @@ -# Devices - -``Device`` is an abstract concept in Cirq, that can represent constraints of an actual quantum processor. -This page describes this abstract concept. - -If you are looking for ways of running quantum algorithms, take a look at - - [Simulation](simulation.ipynb), that is available on any computer - - Quantum processors, that are provided by different Quantum Service Providers: - - [Google Quantum Computing Service](tutorials/google/start.ipynb) - - [Alpine Quantum Technologies](tutorials/aqt/getting_started.ipynb) - - [Pasqal](tutorials/pasqal/getting_started.ipynb) - - [IonQ](tutorials/ionq/getting_started.ipynb) - -## The `cirq.Device` class - -The ``Device`` class is an abstract class which encapsulates constraints -(or lack thereof) that come when running a circuit on actual hardware. -For instance, most hardware only allows certain gates to be enacted -on qubits. Or, as another example, some gates may be constrained to not -be able to run at the same time as neighboring gates. Further the -``Device`` class knows more about the scheduling of ``Operations``. - -Here for example is a ``Device`` made up of 10 qubits on a line: -```python -import cirq -from cirq.devices import GridQubit -class Xmon10Device(cirq.Device): - - def __init__(self): - self.qubits = [GridQubit(i, 0) for i in range(10)] - - def validate_operation(self, operation): - if not isinstance(operation, cirq.GateOperation): - raise ValueError('{!r} is not a supported operation'.format(operation)) - if not isinstance(operation.gate, (cirq.CZPowGate, - cirq.XPowGate, - cirq.PhasedXPowGate, - cirq.YPowGate)): - raise ValueError('{!r} is not a supported gate'.format(operation.gate)) - if len(operation.qubits) == 2: - p, q = operation.qubits - if not p.is_adjacent(q): - raise ValueError('Non-local interaction: {}'.format(repr(operation))) - - - def validate_circuit(self, circuit): - for moment in circuit: - for operation in moment.operations: - self.validate_operation(operation) -``` -This device, for example, knows that two qubit gates between -next-nearest-neighbors is not valid: -```python -device = Xmon10Device() -circuit = cirq.Circuit() -circuit.append([cirq.CZ(device.qubits[0], device.qubits[2])]) -try: - device.validate_circuit(circuit) -except ValueError as e: - print(e) -# prints something like -# ValueError: Non-local interaction: Operation(cirq.CZ, (GridQubit(0, 0), GridQubit(2, 0))) -``` From 71d86b90b10d857f8ee2b04298b73fec670dfb1f Mon Sep 17 00:00:00 2001 From: Michael Broughton Date: Tue, 31 May 2022 12:08:46 -0700 Subject: [PATCH 2/6] feedback. --- docs/devices.ipynb | 65 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/docs/devices.ipynb b/docs/devices.ipynb index 56b14ab1afa..4aa943a74b7 100644 --- a/docs/devices.ipynb +++ b/docs/devices.ipynb @@ -6,7 +6,7 @@ "id": "DkA0Fobtb9dM" }, "source": [ - "##### Copyright 2020 The Cirq Developers" + "##### Copyright 2022 The Cirq Developers" ] }, { @@ -99,6 +99,7 @@ "outputs": [], "source": [ "import cirq_google\n", + "import networkx as nx\n", "my_device = cirq_google.Sycamore\n", "my_device" ] @@ -120,7 +121,6 @@ }, "outputs": [], "source": [ - "q1, q2, q3 = cirq.GridQubit(7, 4), cirq.GridQubit(7, 5), cirq.GridQubit(7, 6)\n", "op1 = cirq.X(cirq.GridQubit(7 ,7))\n", "\n", "try:\n", @@ -146,6 +146,7 @@ }, "outputs": [], "source": [ + "q1, q2, q3 = cirq.GridQubit(7, 4), cirq.GridQubit(7, 5), cirq.GridQubit(7, 6)\n", "op1 = cirq.H(q1)\n", "op2 = cirq_google.SYC(q1, q3)\n", "\n", @@ -299,7 +300,20 @@ " raise ValueError('Non-local interaction: {}'.format(repr(operation)))\n", "\n", " if operation not in self._supported_gates:\n", - " raise ValueError(\"Unsupported operation type.\")" + " raise ValueError(\"Unsupported operation type.\")\n", + " \n", + " def validate_circuit(self, circuit):\n", + " super().validate_circuit(circuit) # calls our `validate_operation`\n", + " cz_count = sum(1 for mom in circuit for op in mom if len(op.qubits) == 2)\n", + " if cz_count >= 10:\n", + " raise ValueError(\"Too many total CZs\")\n", + "\n", + " @property\n", + " def metadata(self):\n", + " return cirq.GridDeviceMetadata(\n", + " qubit_pairs=[(p, q) for p in self._qubits for q in self._qubits if p.is_adjacent(q)],\n", + " gateset=self._supported_gates\n", + " )" ] }, { @@ -315,11 +329,11 @@ "cell_type": "code", "execution_count": null, "metadata": { - "id": "2e_UnChLDeOC" + "id": "uFKsR1qLe24M" }, "outputs": [], "source": [ - "my_device = MyDevice()\n", + "my_custom_device = MyDevice()\n", "\n", "my_circuit = cirq.Circuit(\n", " cirq.X(cirq.LineQubit(0)),\n", @@ -327,8 +341,47 @@ " cirq.X(cirq.LineQubit(4)),\n", " cirq.CZ(*cirq.LineQubit.range(2))\n", ")\n", + "too_many_czs = cirq.Circuit(\n", + " cirq.CZ(*cirq.LineQubit.range(2)) for _ in range(11)\n", + ")\n", "\n", - "my_device.validate_circuit(my_circuit)" + "# Valid for my_custom_device.\n", + "my_custom_device.validate_circuit(my_circuit)\n", + "\n", + "\n", + "# too_many_czs operation(s) are fine locally.\n", + "for moment in too_many_czs:\n", + " for op in moment:\n", + " my_custom_device.validate_operation(op)\n", + "\n", + "# But the device has global constraints which the circuit does not meet:\n", + "try:\n", + " my_custom_device.validate_circuit(too_many_czs)\n", + "except Exception as e:\n", + " print(e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "eG7JY2IVZGEQ" + }, + "source": [ + "By default calling `validate_circuit` calls `validate_moment` on all the moments which calls `validate_operation` on all the operations. Depending on the scoping of constraints the device has, certain less local constraints might be better placed in `validate_moment` and certain global constraints might belong in `validate_circuit`. In addition to this you can also add metadata options to your device. You can define a metadata subclass of `cirq.DeviceMetadata` or you can use an inbuilt metadata class like `cirq.GriDeviceMetadata`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "bbTat2DMf1VE" + }, + "outputs": [], + "source": [ + "my_metadata = my_custom_device.metadata\n", + "\n", + "# Display device graph:\n", + "nx.draw(my_metadata.nx_graph)" ] }, { From 914dbafda7a03aeaa94ab0ccbae14e8328089906 Mon Sep 17 00:00:00 2001 From: Michael Broughton Date: Fri, 3 Jun 2022 14:28:11 -0700 Subject: [PATCH 3/6] more feedback. --- docs/devices.ipynb | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/docs/devices.ipynb b/docs/devices.ipynb index 4aa943a74b7..8849913f3cc 100644 --- a/docs/devices.ipynb +++ b/docs/devices.ipynb @@ -204,7 +204,7 @@ "source": [ "## 2. Metadata features\n", "\n", - "Some devices will also expose additional information via the `metadata` property. You can look at the metadata information of the Sycamore device with:" + "Some devices will also expose additional information via the `metadata` property. Metadata is usually exposed via the an instance (or subclass instance) of the `cirq.DeviceMetadata` class. You can look at the metadata information of the Sycamore device with:" ] }, { @@ -225,7 +225,7 @@ "id": "glMmeLevElt-" }, "source": [ - "The Sycamore device is a 2d grid device that exposes a `cirq.GridDeviceMetadata` with a uniform set of gates across all the qubits as well as a connectivity graph. You can explore the properties below:" + "The Sycamore device is a 2d grid device that exposes a `cirq.GridDeviceMetadata` with a uniform set of gates across all the qubits as well as a planar neearest neighbor connectivity graph. You can explore the properties below:" ] }, { @@ -239,6 +239,17 @@ "type(metadata)" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "LvaYZjANb7_n" + }, + "outputs": [], + "source": [ + "issubclass(type(metadata), cirq.DeviceMetadata)" + ] + }, { "cell_type": "code", "execution_count": null, @@ -247,9 +258,13 @@ }, "outputs": [], "source": [ + "# Properties common to all `cirq.DeviceMetadata`\n", "qubit_set = metadata.qubit_set\n", "nx_graph = metadata.nx_graph\n", + "\n", + "# Properties unique to `cirq.GridDeviceMetadata`\n", "gateset = metadata.gateset\n", + "durations = metadata.gate_durations\n", "\n", "print(gateset)" ] @@ -284,6 +299,7 @@ "source": [ "class MyDevice(cirq.Device):\n", " \"\"\"Five qubits on a line, supporting X/Y/Z and CZ between neighbors.\"\"\"\n", + "\n", " def __init__(self):\n", " self._qubits = set(cirq.LineQubit.range(5))\n", " self._supported_gates = cirq.Gateset(\n", @@ -291,6 +307,16 @@ " )\n", "\n", " def validate_operation(self, operation):\n", + " \"\"\"Check to make sure `operation` is valid.\n", + "\n", + " `operation` must be on qubits found on the device\n", + " and if it is a two qubit gate the qubits must be adjacent\n", + "\n", + " Raises:\n", + " ValueError: if operation acts on qubits not found on the device.\n", + " ValueError: if two qubit gates have non-local interactions.\n", + " ValueError: if the operation is not in the supported gates.\n", + " \"\"\"\n", " if any(x not in self._qubits for x in operation.qubits):\n", " raise ValueError(\"Using qubits not found on device.\")\n", "\n", @@ -303,6 +329,16 @@ " raise ValueError(\"Unsupported operation type.\")\n", " \n", " def validate_circuit(self, circuit):\n", + " \"\"\"Check to make sure `circuit` is valid.\n", + "\n", + " Calls validate_operation on all operations as well as imposing\n", + " a global limit on the total number of CZ gates.\n", + "\n", + " Raises:\n", + " ValueError: if `validate_operation` raises for any operation in the\n", + " circuit.\n", + " ValueError: if there are more than 10 CZ gates in the entire circuit.\n", + " \"\"\"\n", " super().validate_circuit(circuit) # calls our `validate_operation`\n", " cz_count = sum(1 for mom in circuit for op in mom if len(op.qubits) == 2)\n", " if cz_count >= 10:\n", @@ -310,6 +346,10 @@ "\n", " @property\n", " def metadata(self):\n", + " \"\"\"MyDevice GridDeviceMetadata.\"\"\"\n", + " # Since `MyDevice` is planar it is a good idea to subclass the\n", + " # GridDeviceMetadata class to communicate additional device information to\n", + " # the user.\n", " return cirq.GridDeviceMetadata(\n", " qubit_pairs=[(p, q) for p in self._qubits for q in self._qubits if p.is_adjacent(q)],\n", " gateset=self._supported_gates\n", @@ -367,7 +407,7 @@ "id": "eG7JY2IVZGEQ" }, "source": [ - "By default calling `validate_circuit` calls `validate_moment` on all the moments which calls `validate_operation` on all the operations. Depending on the scoping of constraints the device has, certain less local constraints might be better placed in `validate_moment` and certain global constraints might belong in `validate_circuit`. In addition to this you can also add metadata options to your device. You can define a metadata subclass of `cirq.DeviceMetadata` or you can use an inbuilt metadata class like `cirq.GriDeviceMetadata`:" + "By default calling `validate_circuit` calls `validate_moment` on all the moments which calls `validate_operation` on all the operations. Depending on the scoping of constraints the device has, certain less local constraints might be better placed in `validate_moment` and certain global constraints might belong in `validate_circuit`. In addition to this you can also add metadata options to your device. You can define a metadata subclass of `cirq.DeviceMetadata` or you can use an inbuilt metadata class like `cirq.GridDeviceMetadata`:" ] }, { From fa6f1cb5a20b0ada8a69c586e08f4e9eb40c23f0 Mon Sep 17 00:00:00 2001 From: Michael Broughton Date: Tue, 14 Jun 2022 13:00:52 -0700 Subject: [PATCH 4/6] final typo. --- docs/devices.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/devices.ipynb b/docs/devices.ipynb index 8849913f3cc..90f8ea578f2 100644 --- a/docs/devices.ipynb +++ b/docs/devices.ipynb @@ -225,7 +225,7 @@ "id": "glMmeLevElt-" }, "source": [ - "The Sycamore device is a 2d grid device that exposes a `cirq.GridDeviceMetadata` with a uniform set of gates across all the qubits as well as a planar neearest neighbor connectivity graph. You can explore the properties below:" + "The Sycamore device is a 2d grid device that exposes a `cirq.GridDeviceMetadata` with a uniform set of gates across all the qubits as well as a planar nearest neighbor connectivity graph. You can explore the properties below:" ] }, { From 690b3c42c42e69fb20819f433d1ec1693b7048f5 Mon Sep 17 00:00:00 2001 From: Michael Broughton Date: Tue, 14 Jun 2022 14:16:55 -0700 Subject: [PATCH 5/6] format. --- docs/devices.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/devices.ipynb b/docs/devices.ipynb index 90f8ea578f2..aadf9ec02d4 100644 --- a/docs/devices.ipynb +++ b/docs/devices.ipynb @@ -286,7 +286,7 @@ "source": [ "## 3. The `cirq.Device` interface\n", "\n", - "For advanced users (such as vendors) it is also possible to implement your own Device with its own unique constraints and metadata information. Below you can implement our own fictituous device:" + "For advanced users (such as vendors) it is also possible to implement your own Device with its own unique constraints and metadata information. Below you can implement our own fictituous device that has 5 qubits, supports X/Y/Z single qubit and CZ gates between neighbors, and has a maximum of 10 CZ gates per circuit. You could then create a subclass of the `cirq.Device` class that has a `validate_operation` to validate the gate types and adjacency requirements, and implement a `validate_circuit` to enforce the maximum number of CZs:" ] }, { From 9fe4818418b22e0e7b4ea1838d592535b4bcbf6e Mon Sep 17 00:00:00 2001 From: Michael Broughton Date: Tue, 14 Jun 2022 14:28:24 -0700 Subject: [PATCH 6/6] more metadata. --- docs/devices.ipynb | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/docs/devices.ipynb b/docs/devices.ipynb index aadf9ec02d4..ca4828290c7 100644 --- a/docs/devices.ipynb +++ b/docs/devices.ipynb @@ -250,18 +250,46 @@ "issubclass(type(metadata), cirq.DeviceMetadata)" ] }, + { + "cell_type": "markdown", + "metadata": { + "id": "358DyXIsGdPE" + }, + "source": [ + "Some properties that are common to all devices and belong to the `cirq.DeviceMetadata` class include the set of qubits on the device (`qubit_set`) and the connectivity graph of those qubits (`nx_graph`)" + ] + }, { "cell_type": "code", "execution_count": null, "metadata": { - "id": "JbwrPD_AETiX" + "id": "BeW0hnFPGkyB" }, "outputs": [], "source": [ "# Properties common to all `cirq.DeviceMetadata`\n", "qubit_set = metadata.qubit_set\n", "nx_graph = metadata.nx_graph\n", - "\n", + "print(qubit_set)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "oM6dpucFGoCK" + }, + "source": [ + "Some properties are unique to the subclass. For `cirq.GridDeviceMetadata` you can explore the `gateset` (supported gates across all qubits) and the gate_durations (Dictionary of times that it takes to execute these gates on the device) fields:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "JbwrPD_AETiX" + }, + "outputs": [], + "source": [ "# Properties unique to `cirq.GridDeviceMetadata`\n", "gateset = metadata.gateset\n", "durations = metadata.gate_durations\n", @@ -286,7 +314,7 @@ "source": [ "## 3. The `cirq.Device` interface\n", "\n", - "For advanced users (such as vendors) it is also possible to implement your own Device with its own unique constraints and metadata information. Below you can implement our own fictituous device that has 5 qubits, supports X/Y/Z single qubit and CZ gates between neighbors, and has a maximum of 10 CZ gates per circuit. You could then create a subclass of the `cirq.Device` class that has a `validate_operation` to validate the gate types and adjacency requirements, and implement a `validate_circuit` to enforce the maximum number of CZs:" + "For advanced users (such as vendors) it is also possible to implement your own Device with its own unique constraints and metadata information. Below you can implement our own fictituous device:" ] }, {