{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Qubit mapping and routing\n", "\n", "**Download this notebook - {nb-download}`mapping_example.ipynb`**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this tutorial we will show how the problem of mapping from logical quantum circuits to physically permitted circuits is solved automatically in TKET. The basic examples require only the installation of pytket, ```pip install pytket```." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There is a wide variety of different blueprints for realising quantum computers, including the well known superconducting and ion trap devices. Different devices come with different constraints, such as a limited primitive gate set for universal quantum computing. Often this limited gate set accommodates an additional constraint, that two-qubit gates can not be executed between all pairs of qubits." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In software, typically this constraint is presented as a \"connectivity\" graph where vertices connected by an edge represents pairs of physical qubits which two-qubit gates can be executed on. As programmers usually write logical quantum circuits with no sense of architecture (or may want to run their circuit on a range of hardware with different connectivity constraints), most quantum software development kits offer the means to automatically solve this constraint. One common way is to automatically add logical ```SWAP``` gates to a Circuit, changing the position of logical qubits on physical qubits until a two-qubit gate can be realised. This is an active area of research in quantum computing and a problem we discuss in our paper \"On The Qubit Routing Problem\" - arXiv:1902.08091." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In TKET this constraint is represented by the ```Architecture``` class. An Architecture object requires a coupling map to be created, a list of pairs of qubits which defines where two-qubit primitives may be executed. A coupling map can be produced naively by the integer indexing of nodes and edges in some architecture." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from pytket.architecture import Architecture\n", "from pytket.circuit import Node" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import networkx as nx\n", "from typing import List, Union, Tuple" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "def draw_graph(coupling_map: List[Union[Tuple[int, int], Tuple[Node, Node]]]):\n", " coupling_graph = nx.Graph(coupling_map)\n", " nx.draw(coupling_graph, labels={node: node for node in coupling_graph.nodes()})" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "simple_coupling_map = [(0, 1), (1, 2), (2, 3)]\n", "simple_architecture = Architecture(simple_coupling_map)\n", "draw_graph(simple_coupling_map)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Alternatively we could use the `Node` class to assign our nodes - you will see why this can be helpful later. Lets create an Architecture with an identical graph:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "node_0 = Node(\"e0\", 0)\n", "node_1 = Node(\"e1\", 1)\n", "node_2 = Node(\"e2\", 2)\n", "node_3 = Node(\"e3\", 3)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "id_coupling_map = [(node_0, node_1), (node_1, node_2), (node_2, node_3)]\n", "id_architecture = Architecture(id_coupling_map)\n", "draw_graph(id_coupling_map)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also create an ID with an arbitrary-dimensional index. Let us make a 2x2x2 cube:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "node_000 = Node(\"cube\", [0, 0, 0])\n", "node_001 = Node(\"cube\", [0, 0, 1])\n", "node_010 = Node(\"cube\", [0, 1, 0])\n", "node_011 = Node(\"cube\", [0, 1, 1])\n", "node_100 = Node(\"cube\", [1, 0, 0])\n", "node_101 = Node(\"cube\", [1, 0, 1])\n", "node_110 = Node(\"cube\", [1, 1, 0])\n", "node_111 = Node(\"cube\", [1, 1, 1])" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "cube_coupling_map = [\n", " (node_000, node_001),\n", " (node_000, node_010),\n", " (node_010, node_011),\n", " (node_001, node_011),\n", " (node_000, node_100),\n", " (node_001, node_101),\n", " (node_010, node_110),\n", " (node_011, node_111),\n", " (node_100, node_101),\n", " (node_100, node_110),\n", " (node_110, node_111),\n", " (node_101, node_111),\n", "]" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "image/png": "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2L9/PwYOHKh8jaGhIU6fPo1Vq1YhNDQUwcHBMDU1hb29PVasWIHGjRsDAFo1eZpBLH7xeZwFZ0JUPi6+clL5338tlIonZQBE0DN+unyvJxZB2q6pym0Xn9m+fTtOnz6t/DgmJgYxMTEAgLfffltZKGUyGYAXbwf0/3l5eeGnn37CihUr8PHHH6NZs2ZYsmQJPvvss398LxER1X0iRXU34yMitT2bBbQeFQBxCweIGxpDJNZ77XHuBc2DxLQ5mg3/BABgIBEjel4/2PyvsFbHokWLsHfvXqSnp79wS6DqKC4uRmlpKT7++GMcOXJEWVqJiKhu4zmURFrgbugXuL1xPCpyf3/t98rLS1Bx/w+YufoqH/t8SCe1yiTwdOYyICBAY2USAD799FM0a9YM+/bt09iYREQkPM5QEgno8ePHuHDhAgAg/NJtRNw1gthAvSK4cMAbmOXWXhPxNC41NVV5XqpEIsE777wjbCAiItIIFkoiLbLvfBaWRVxHpVyBKvmrf2nqiUWQiEX4fEgnjHF6/kIcIiKimsRCSaRlsh+VYMmhqziTngc9sehvi+Wz513bW2DV8C5qL3MTERFVBwslkZZKyy3C7qQsxKTeR9bDEvz1C1WEp5uWu9k3h69z6xdezU1ERFRbWCiJ6oDi8kpkPixGRaUc+hIx2jQ1qvE74BAREb0qFkoiIiIiUgu3DSIiIiIitbBQEhEREZFaWCiJiIiISC0slERERESkFhZKIiIiIlILCyURERERqYWFkoiIiIjUwkJJRERERGphoSQiIiIitbBQEhEREZFaWCiJiIiISC0slERERESkFhZKIiIiIlILCyURERERqYWFkoiIiIjUwkJJRERERGphoSQiIiIitbBQEhEREZFaWCiJiIiISC0slERERESkFhZKIiIiIlILCyURERERqYWFkoiIiIjUwkJJRERERGphoSQiIiIitbBQEhEREZFaWCiJiIiISC0slERERESkFhZKIiIiIlILCyURERERqYWFkoiIiIjUwkJJRERERGphoSQiIiIitbBQEhEREZFaWCiJiIiISC0slERERESkFhZKIiIiIlLL/wEq2KWkoJLp/wAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "cube_architecture = Architecture(cube_coupling_map)\n", "draw_graph(cube_coupling_map)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To avoid that tedium though we could just use our SquareGrid Architecture:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "from pytket.architecture import SquareGrid" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "image/png": "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7twZPj4+yMvLq70vhhDSYGVkZEBfX1+hVm4NTYsWLfDXX39h3759+P333+Hk5FTtgzMIaejoljeL0tLSYGZmhqMnfofzZ/1QLBBBU10N1iZ60NOq+THrxcXF2LBhA5YvXw4zMzNs375dqTuxCSEN35IlS3D06FG8ePGC7VJUUmJiIqZMmYIrV65g6tSp2LBhAx0hSxo1mqFkkaTfpqN9W3AtjNDJqim4FkYKhUkA0NTUxOLFixEbGws7Ozt4enpixIgRMkddEkJIZRpLU/OasrKywqVLl/DLL7/g6NGjcHJywrVr19guixDWUKBkkSRQ2tra1sr4tra2uHjxIn777TeEh4fD3t4e27Ztkzn3mxBCykOBsmoMw2DatGmIiYlB69at0a9fP8yePVt6MhkhjQkFShbxeDy0bNkSurqVr49UBMMwGD16NB4/foyxY8dizpw56NGjB6KiomrtPQkh9R8Fyupr3bo1/v77b2zduhW//vorOnTogBs3brBdFiF1igIli3g8Xp01cW/SpAl27tyJW7duobCwEF26dMH8+fPpN2lCSLkoUMpHTU0Ns2fPxsOHD2FhYQE3Nzf88MMP1T7NjJD6jgIli+oyUEr06NED//77L1atWoVffvkF7du3x7lz5+q0BkKI6qNAWTNt2rRBWFgYNmzYgF27dqFjx464desW22URUusoULJELBazEigBQENDAz4+PoiLi4OTkxOGDh2KYcOGISkpqc5rIYSoHpFIhMzMTAqUNcThcDBv3jw8ePAAJiYm6N27N3x8fFBYWMh2aYTUGgqULElJSUFeXh6r55a3bt0a58+fx8mTJxEZGYn27dtj06ZNEAgErNVECGFfdnY2hEIhBUoF2dnZISIiAqtWrcLmzZvRuXNn/PPPP2yXRUitoEDJEskObzYDJVC6aefrr79GfHw8JkyYgPnz58PFxQX//vsvq3URQtgjOSWHAqXiOBwOfHx8cP/+fejq6qJHjx5YsmQJioqK2C6NEKWiQMkSHo8HhmFgY2PDdikAACMjI2zbtg137tyBUChEt27dMHfuXLx//57t0gghdYwCpfJxuVzcvn0by5cvx7p169ClSxfcv3+f7bIIURoKlCzh8XiwsrJSuWPNunXrhnv37mHdunXYu3cv2rdvj9OnT4MOVCKk8aBzvGuHhoYGlixZgnv37kFdXR0uLi4I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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "alternative_cube_architecture = SquareGrid(2, 2, 2)\n", "draw_graph(alternative_cube_architecture.coupling)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The current range of quantum computers are commonly referred to as Noisy-Intermediate-Scale-Quantum devices i.e. NISQ devices. The impact of noise is a primary concern during compilation and incentivizes producing physically permitted circuits that have a minimal number of gates. For this reason benchmarking in this area is often completed by comparing the final number of two-qubit (or particularly SWAP gates) in compiled circuits." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "However it is important to remember that adding logical SWAP gates to minimise gate count is not the only way this constraint can be met, with large scale architecture-aware synthesis methods and fidelity aware methods amongst other approaches producing viable physically permitted circuits. It is likely that no SINGLE approach is better for all circuits, but the ability to use different approaches where best fitted will give the best results during compilation." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Producing physically valid circuits is completed via the `MappingManager` class, which aims to accommodate a wide range of approaches." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "from pytket.mapping import MappingManager" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A `MappingManager` object requires an `Architecture` object at construction." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "mapping_manager = MappingManager(id_architecture)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "All mapping is done through the `MappingManager.route_circuit` method. The `MappingManager.route_circuit` method has two arguments, the first a Circuit to be routed (which is mutated), the second a `List[RoutingMethodCircuit]` object that defines how the mapping is completed." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Later we will look at defining our own `RoutingMethodCircuit` objects, but initially lets consider one thats already available." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "from pytket.mapping import LexiLabellingMethod, LexiRouteRoutingMethod" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "lexi_label = LexiLabellingMethod()\n", "lexi_route = LexiRouteRoutingMethod(10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `lexi_route` object here is of little use outside `MappingManager`. Note that it takes a lookahead parameter, which will affect the performance of the method, defining the number of two-qubit gates it considers when finding `SWAP` gates to add." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "from pytket import Circuit, OpType\n", "from pytket.circuit import display" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "
\n", " \n", "
\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "c = (\n", " Circuit(4)\n", " .CX(0, 1)\n", " .CX(1, 2)\n", " .CX(0, 2)\n", " .CX(0, 3)\n", " .CX(2, 3)\n", " .CX(1, 3)\n", " .CX(0, 1)\n", " .measure_all()\n", ")\n", "display.render_circuit_jupyter(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also look at which logical qubits are interacting." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "from pytket.utils import Graph" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "Qubit connectivity\n", "\n", "\n", "\n", "q[0]\n", "\n", "q[0]\n", "\n", "\n", "\n", "q[1]\n", "\n", "q[1]\n", "\n", "\n", "\n", "q[0]--q[1]\n", "\n", "\n", "\n", "\n", "q[2]\n", "\n", "q[2]\n", "\n", "\n", "\n", "q[0]--q[2]\n", "\n", "\n", "\n", "\n", "q[3]\n", "\n", "q[3]\n", "\n", "\n", "\n", "q[0]--q[3]\n", "\n", "\n", "\n", "\n", "q[1]--q[2]\n", "\n", "\n", "\n", "\n", "q[1]--q[3]\n", "\n", "\n", "\n", "\n", "q[2]--q[3]\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Graph(c).get_qubit_graph()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By running the `MappingManager.route_circuit` method on our circuit `c` with the `LexiLabellingMethod` and `LexiRouteRoutingMethod` objects as an argument, qubits in `c` with some physical requirements will be relabelled and the qubit graph modified (by the addition of SWAP gates and relabelling some CX as BRIDGE gates) such that the qubit graph is isomorphic to some subgraph of the full architecture." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "
\n", " \n", "
\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "mapping_manager.route_circuit(c, [lexi_label, lexi_route])\n", "display.render_circuit_jupyter(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The graph:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "Qubit connectivity\n", "\n", "\n", "\n", "e1[1]\n", "\n", "e1[1]\n", "\n", "\n", "\n", "e0[0]\n", "\n", "e0[0]\n", "\n", "\n", "\n", "e1[1]--e0[0]\n", "\n", "\n", "\n", "\n", "e2[2]\n", "\n", "e2[2]\n", "\n", "\n", "\n", "e1[1]--e2[2]\n", "\n", "\n", "\n", "\n", "e3[3]\n", "\n", "e3[3]\n", "\n", "\n", "\n", "e2[2]--e3[3]\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Graph(c).get_qubit_graph()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The resulting circuit may also change if we reduce the lookahead parameter." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "
\n", " \n", "
\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "c = (\n", " Circuit(4)\n", " .CX(0, 1)\n", " .CX(1, 2)\n", " .CX(0, 2)\n", " .CX(0, 3)\n", " .CX(2, 3)\n", " .CX(1, 3)\n", " .CX(0, 1)\n", " .measure_all()\n", ")\n", "mapping_manager.route_circuit(c, [lexi_label, LexiRouteRoutingMethod(1)])\n", "display.render_circuit_jupyter(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also pass multiple `RoutingMethod` options for Routing in a ranked List. Each `RoutingMethod` option has a function for checking whether it can usefully modify a subcircuit at a stage in Routing. To choose, each method in the List is checked in order until one returns True. This will be discussed more later." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can aid the mapping procedure by relabelling qubits in advance. This can be completed using the `Placement` class." ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "from pytket.placement import Placement, LinePlacement, GraphPlacement" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The default ```Placement``` assigns logical qubits to physical qubits as they are encountered during routing. ```LinePlacement``` uses a strategy described in https://arxiv.org/abs/1902.08091. ```GraphPlacement``` is described in Section 7.1 of https://arxiv.org/abs/2003.10611. Lets look at how we can use the ```LinePlacement``` class.`" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "line_placement = LinePlacement(id_architecture)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c = (\n", " Circuit(4)\n", " .CX(0, 1)\n", " .CX(1, 2)\n", " .CX(0, 2)\n", " .CX(0, 3)\n", " .CX(2, 3)\n", " .CX(1, 3)\n", " .CX(0, 1)\n", " .measure_all()\n", ")\n", "line_placement.place(c)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "
\n", " \n", "
\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display.render_circuit_jupyter(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that one qubit remains unplaced in this example. `LexiRouteRoutingMethod` will dynamically assign it during mapping." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Different placements will lead to different selections of SWAP gates being added. However each different routed circuit will preserve the original unitary action of the full circuit while respecting connectivity constraints." ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "
\n", " \n", "
\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "mapping_manager.route_circuit(c, [lexi_label, lexi_route])\n", "display.render_circuit_jupyter(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The graph:" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "Qubit connectivity\n", "\n", "\n", "\n", "e0[0]\n", "\n", "e0[0]\n", "\n", "\n", "\n", "e1[1]\n", "\n", "e1[1]\n", "\n", "\n", "\n", "e0[0]--e1[1]\n", "\n", "\n", "\n", "\n", "e2[2]\n", "\n", "e2[2]\n", "\n", "\n", "\n", "e0[0]--e2[2]\n", "\n", "\n", "\n", "\n", "e1[1]--e2[2]\n", "\n", "\n", "\n", "\n", "e3[3]\n", "\n", "e3[3]\n", "\n", "\n", "\n", "e2[2]--e3[3]\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Graph(c).get_qubit_graph()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "However, small changes to the depth of lookahead or the original assignment of `Architecture` `Node` can greatly affect the resulting physical circuit for the `LexiRouteRoutingMethod` method. Considering this variance, it should be possible to easily throw additional computational resources at the problem if necessary, which is something TKET is leaning towards with the ability to define custom `RoutingCircuitMethod` objects." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To define a new `RoutingMethodCircuit` method though, we first need to understand how it is used in `MappingManager` and routing. The `MappingManager.route_circuit` method treats the global problem of mapping to physical circuits as many sequential sub-problems. Consider the following problem." ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [], "source": [ "from pytket import Circuit" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [], "source": [ "from pytket.placement import place_with_map" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "Circuit\n", "\n", "\n", "cluster_q_inputs\n", "\n", "\n", "\n", "cluster_q_outputs\n", "\n", "\n", "\n", "cluster_8\n", "\n", "CX\n", "\n", "\n", "cluster_9\n", "\n", "CX\n", "\n", "\n", "cluster_10\n", "\n", "CX\n", "\n", "\n", "cluster_11\n", "\n", "CX\n", "\n", "\n", "cluster_12\n", "\n", "CX\n", "\n", "\n", "cluster_13\n", "\n", "CX\n", "\n", "\n", "cluster_14\n", "\n", "CX\n", "\n", "\n", "\n", "(0, 0)\n", "\n", "e0[0]\n", "\n", "\n", "\n", "(8, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(0, 0)->(8, 0)\n", "\n", "\n", "\n", "\n", "\n", "(2, 0)\n", "\n", "e1[1]\n", "\n", "\n", "\n", "(8, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(2, 0)->(8, 1)\n", "\n", "\n", "\n", "\n", "\n", "(4, 0)\n", "\n", "e2[2]\n", "\n", "\n", "\n", "(9, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(4, 0)->(9, 1)\n", "\n", "\n", "\n", "\n", "\n", "(6, 0)\n", "\n", "e3[3]\n", "\n", "\n", "\n", "(11, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(6, 0)->(11, 1)\n", "\n", "\n", "\n", "\n", "\n", "(1, 0)\n", "\n", "e0[0]\n", "\n", "\n", "\n", "(3, 0)\n", "\n", "e1[1]\n", "\n", "\n", "\n", "(5, 0)\n", "\n", "e2[2]\n", "\n", "\n", "\n", "(7, 0)\n", "\n", "e3[3]\n", "\n", "\n", "\n", "(10, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(8, 0)->(10, 0)\n", "\n", "\n", "\n", "\n", "\n", "(9, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(8, 1)->(9, 0)\n", "\n", "\n", "\n", "\n", "\n", "(13, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(9, 0)->(13, 0)\n", "\n", "\n", "\n", "\n", "\n", "(10, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(9, 1)->(10, 1)\n", "\n", "\n", "\n", "\n", "\n", "(11, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(10, 0)->(11, 0)\n", "\n", "\n", "\n", "\n", "\n", "(12, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(10, 1)->(12, 0)\n", "\n", "\n", "\n", "\n", "\n", "(14, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(11, 0)->(14, 0)\n", "\n", "\n", "\n", "\n", "\n", "(12, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(11, 1)->(12, 1)\n", "\n", "\n", "\n", "\n", "\n", "(12, 0)->(5, 0)\n", "\n", "\n", "\n", "\n", "\n", "(13, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(12, 1)->(13, 1)\n", "\n", "\n", "\n", "\n", "\n", "(14, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(13, 0)->(14, 1)\n", "\n", "\n", "\n", "\n", "\n", "(13, 1)->(7, 0)\n", "\n", "\n", "\n", "\n", "\n", "(14, 0)->(1, 0)\n", "\n", "\n", "\n", "\n", "\n", "(14, 1)->(3, 0)\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "circ = Circuit(4).CX(0, 1).CX(1, 2).CX(0, 2).CX(0, 3).CX(2, 3).CX(1, 3).CX(0, 1)\n", "naive_map = {\n", " circ.qubits[0]: node_0,\n", " circ.qubits[1]: node_1,\n", " circ.qubits[2]: node_2,\n", " circ.qubits[3]: node_3,\n", "}\n", "place_with_map(circ, naive_map)\n", "Graph(circ).get_DAG()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So what happens when we run the following?" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "Circuit\n", "\n", "\n", "cluster_q_inputs\n", "\n", "\n", "\n", "cluster_q_outputs\n", "\n", "\n", "\n", "cluster_8\n", "\n", "CX\n", "\n", "\n", "cluster_9\n", "\n", "CX\n", "\n", "\n", "cluster_10\n", "\n", "CX\n", "\n", "\n", "cluster_11\n", "\n", "CX\n", "\n", "\n", "cluster_12\n", "\n", "CX\n", "\n", "\n", "cluster_13\n", "\n", "CX\n", "\n", "\n", "cluster_14\n", "\n", "SWAP\n", "\n", "\n", "cluster_15\n", "\n", "SWAP\n", "\n", "\n", "cluster_16\n", "\n", "BRIDGE\n", "\n", "\n", "\n", "(0, 0)\n", "\n", "e0[0]\n", "\n", "\n", "\n", "(8, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(0, 0)->(8, 0)\n", "\n", "\n", "\n", "\n", "\n", "(2, 0)\n", "\n", "e1[1]\n", "\n", "\n", "\n", "(8, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(2, 0)->(8, 1)\n", "\n", "\n", "\n", "\n", "\n", "(4, 0)\n", "\n", "e2[2]\n", "\n", "\n", "\n", "(9, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(4, 0)->(9, 1)\n", "\n", "\n", "\n", "\n", "\n", "(6, 0)\n", "\n", "e3[3]\n", "\n", "\n", "\n", "(15, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(6, 0)->(15, 0)\n", "\n", "\n", "\n", "\n", "\n", "(1, 0)\n", "\n", "e1[1]\n", "\n", "\n", "\n", "(3, 0)\n", "\n", "e0[0]\n", "\n", "\n", "\n", "(5, 0)\n", "\n", "e3[3]\n", "\n", "\n", "\n", "(7, 0)\n", "\n", "e2[2]\n", "\n", "\n", "\n", "(14, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(8, 0)->(14, 0)\n", "\n", "\n", "\n", "\n", "\n", "(9, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(8, 1)->(9, 0)\n", "\n", "\n", "\n", "\n", "\n", "(14, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(9, 0)->(14, 1)\n", "\n", "\n", "\n", "\n", "\n", "(10, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(9, 1)->(10, 1)\n", "\n", "\n", "\n", "\n", "\n", "(10, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(11, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(10, 0)->(11, 0)\n", "\n", "\n", "\n", "\n", "\n", "(15, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(10, 1)->(15, 1)\n", "\n", "\n", "\n", "\n", "\n", "(16, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(11, 0)->(16, 1)\n", "\n", "\n", "\n", "\n", "\n", "(11, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(12, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(11, 1)->(12, 1)\n", "\n", "\n", "\n", "\n", "\n", "(12, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(12, 0)->(5, 0)\n", "\n", "\n", "\n", "\n", "\n", "(16, 2)\n", "\n", "2\n", "\n", "\n", "\n", "(12, 1)->(16, 2)\n", "\n", "\n", "\n", "\n", "\n", "(13, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(13, 0)->(1, 0)\n", "\n", "\n", "\n", "\n", "\n", "(13, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(13, 1)->(3, 0)\n", "\n", "\n", "\n", "\n", "\n", "(16, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(14, 0)->(16, 0)\n", "\n", "\n", "\n", "\n", "\n", "(14, 1)->(10, 0)\n", "\n", "\n", "\n", "\n", "\n", "(15, 0)->(12, 0)\n", "\n", "\n", "\n", "\n", "\n", "(15, 1)->(11, 1)\n", "\n", "\n", "\n", "\n", "\n", "(16, 0)->(13, 1)\n", "\n", "\n", "\n", "\n", "\n", "(16, 1)->(13, 0)\n", "\n", "\n", "\n", "\n", "\n", "(16, 2)->(7, 0)\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mapping_manager.route_circuit(circ, [lexi_route])\n", "Graph(circ).get_DAG()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sequential mapping typically works by partitioning the circuit into two, a first partition comprising a connected subcircuit that is physically permitted, a second partition that is not. Therefore, the first thing `MappingManager.route_circuit` does is find this partition for the passed circuit, by iterating through gates in the circuit." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will construct the partitions ourselves for illustrative purposes. Lets assume we are routing for the four qubit line architecture (qubits are connected to adjacent indices) \"simple_architecture\" we constructed earlier." ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "Circuit\n", "\n", "\n", "cluster_q_inputs\n", "\n", "\n", "\n", "cluster_q_outputs\n", "\n", "\n", "\n", "cluster_8\n", "\n", "CX\n", "\n", "\n", "cluster_9\n", "\n", "CX\n", "\n", "\n", "\n", "(0, 0)\n", "\n", "e0[0]\n", "\n", "\n", "\n", "(8, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(0, 0)->(8, 0)\n", "\n", "\n", "\n", "\n", "\n", "(2, 0)\n", "\n", "e1[1]\n", "\n", "\n", "\n", "(8, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(2, 0)->(8, 1)\n", "\n", "\n", "\n", "\n", "\n", "(4, 0)\n", "\n", "e2[2]\n", "\n", "\n", "\n", "(9, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(4, 0)->(9, 1)\n", "\n", "\n", "\n", "\n", "\n", "(6, 0)\n", "\n", "e3[3]\n", "\n", "\n", "\n", "(7, 0)\n", "\n", "e3[3]\n", "\n", "\n", "\n", "(6, 0)->(7, 0)\n", "\n", "\n", "\n", "\n", "\n", "(1, 0)\n", "\n", "e0[0]\n", "\n", "\n", "\n", "(3, 0)\n", "\n", "e1[1]\n", "\n", "\n", "\n", "(5, 0)\n", "\n", "e2[2]\n", "\n", "\n", "\n", "(8, 0)->(1, 0)\n", "\n", "\n", "\n", "\n", "\n", "(9, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(8, 1)->(9, 0)\n", "\n", "\n", "\n", "\n", "\n", "(9, 0)->(3, 0)\n", "\n", "\n", "\n", "\n", "\n", "(9, 1)->(5, 0)\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "circ_first_partition = Circuit(4).CX(0, 1).CX(1, 2)\n", "place_with_map(circ_first_partition, naive_map)\n", "Graph(circ_first_partition).get_DAG()" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "Circuit\n", "\n", "\n", "cluster_q_inputs\n", "\n", "\n", "\n", "cluster_q_outputs\n", "\n", "\n", "\n", "cluster_8\n", "\n", "CX\n", "\n", "\n", "cluster_9\n", "\n", "CX\n", "\n", "\n", "cluster_10\n", "\n", "CX\n", "\n", "\n", "cluster_11\n", "\n", "CX\n", "\n", "\n", "cluster_12\n", "\n", "CX\n", "\n", "\n", "\n", "(0, 0)\n", "\n", "e0[0]\n", "\n", "\n", "\n", "(8, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(0, 0)->(8, 0)\n", "\n", "\n", "\n", "\n", "\n", "(2, 0)\n", "\n", "e1[1]\n", "\n", "\n", "\n", "(11, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(2, 0)->(11, 0)\n", "\n", "\n", "\n", "\n", "\n", "(4, 0)\n", "\n", "e2[2]\n", "\n", "\n", "\n", "(8, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(4, 0)->(8, 1)\n", "\n", "\n", "\n", "\n", "\n", "(6, 0)\n", "\n", "e3[3]\n", "\n", "\n", "\n", "(9, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(6, 0)->(9, 1)\n", "\n", "\n", "\n", "\n", "\n", "(1, 0)\n", "\n", "e0[0]\n", "\n", "\n", "\n", "(3, 0)\n", "\n", "e1[1]\n", "\n", "\n", "\n", "(5, 0)\n", "\n", "e2[2]\n", "\n", "\n", "\n", "(7, 0)\n", "\n", "e3[3]\n", "\n", "\n", "\n", "(9, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(8, 0)->(9, 0)\n", "\n", "\n", "\n", "\n", "\n", "(10, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(8, 1)->(10, 0)\n", "\n", "\n", "\n", "\n", "\n", "(12, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(9, 0)->(12, 0)\n", "\n", "\n", "\n", "\n", "\n", "(10, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(9, 1)->(10, 1)\n", "\n", "\n", "\n", "\n", "\n", "(10, 0)->(5, 0)\n", "\n", "\n", "\n", "\n", "\n", "(11, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(10, 1)->(11, 1)\n", "\n", "\n", "\n", "\n", "\n", "(12, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(11, 0)->(12, 1)\n", "\n", "\n", "\n", "\n", "\n", "(11, 1)->(7, 0)\n", "\n", "\n", "\n", "\n", "\n", "(12, 0)->(1, 0)\n", "\n", "\n", "\n", "\n", "\n", "(12, 1)->(3, 0)\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "circ_second_partition = Circuit(4).CX(0, 2).CX(0, 3).CX(2, 3).CX(1, 3).CX(0, 1)\n", "place_with_map(circ_second_partition, naive_map)\n", "Graph(circ_second_partition).get_DAG()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that there are gates in the second partition that would be physically permitted, if they were not dependent on other gates that are not." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The next step is to modify the second partition circuit to move it closer being physically permitted. Here the `LexiRouteRoutingMethod` as before will either insert a SWAP gate at the start of the partition, or will substitute a CX gate in the first slice of the partition with a BRIDGE gate." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The option taken by `LexiRouteRoutingethod(1)` is to insert a SWAP gate between the first two nodes of the architecture, swapping their logical states. How does this change the second partition circuit?" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "Circuit\n", "\n", "\n", "cluster_q_inputs\n", "\n", "\n", "\n", "cluster_q_outputs\n", "\n", "\n", "\n", "cluster_8\n", "\n", "SWAP\n", "\n", "\n", "cluster_9\n", "\n", "CX\n", "\n", "\n", "cluster_10\n", "\n", "CX\n", "\n", "\n", "cluster_11\n", "\n", "CX\n", "\n", "\n", "cluster_12\n", "\n", "CX\n", "\n", "\n", "cluster_13\n", "\n", "CX\n", "\n", "\n", "\n", "(0, 0)\n", "\n", "e0[0]\n", "\n", "\n", "\n", "(8, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(0, 0)->(8, 0)\n", "\n", "\n", "\n", "\n", "\n", "(2, 0)\n", "\n", "e1[1]\n", "\n", "\n", "\n", "(8, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(2, 0)->(8, 1)\n", "\n", "\n", "\n", "\n", "\n", "(4, 0)\n", "\n", "e2[2]\n", "\n", "\n", "\n", "(9, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(4, 0)->(9, 1)\n", "\n", "\n", "\n", "\n", "\n", "(6, 0)\n", "\n", "e3[3]\n", "\n", "\n", "\n", "(10, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(6, 0)->(10, 1)\n", "\n", "\n", "\n", "\n", "\n", "(1, 0)\n", "\n", "e0[0]\n", "\n", "\n", "\n", "(3, 0)\n", "\n", "e1[1]\n", "\n", "\n", "\n", "(5, 0)\n", "\n", "e2[2]\n", "\n", "\n", "\n", "(7, 0)\n", "\n", "e3[3]\n", "\n", "\n", "\n", "(12, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(8, 0)->(12, 0)\n", "\n", "\n", "\n", "\n", "\n", "(9, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(8, 1)->(9, 0)\n", "\n", "\n", "\n", "\n", "\n", "(10, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(9, 0)->(10, 0)\n", "\n", "\n", "\n", "\n", "\n", "(11, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(9, 1)->(11, 0)\n", "\n", "\n", "\n", "\n", "\n", "(13, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(10, 0)->(13, 0)\n", "\n", "\n", "\n", "\n", "\n", "(11, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(10, 1)->(11, 1)\n", "\n", "\n", "\n", "\n", "\n", "(11, 0)->(5, 0)\n", "\n", "\n", "\n", "\n", "\n", "(12, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(11, 1)->(12, 1)\n", "\n", "\n", "\n", "\n", "\n", "(13, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(12, 0)->(13, 1)\n", "\n", "\n", "\n", "\n", "\n", "(12, 1)->(7, 0)\n", "\n", "\n", "\n", "\n", "\n", "(13, 0)->(3, 0)\n", "\n", "\n", "\n", "\n", "\n", "(13, 1)->(1, 0)\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "circ_second_partition = (\n", " Circuit(4).SWAP(0, 1).CX(1, 2).CX(1, 3).CX(2, 3).CX(0, 3).CX(1, 0)\n", ")\n", "place_with_map(circ_second_partition, naive_map)\n", "Graph(circ_second_partition).get_DAG()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Leaving the full circuit as:" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "Circuit\n", "\n", "\n", "cluster_q_inputs\n", "\n", "\n", "\n", "cluster_q_outputs\n", "\n", "\n", "\n", "cluster_8\n", "\n", "CX\n", "\n", "\n", "cluster_9\n", "\n", "CX\n", "\n", "\n", "cluster_10\n", "\n", "SWAP\n", "\n", "\n", "cluster_11\n", "\n", "CX\n", "\n", "\n", "cluster_12\n", "\n", "CX\n", "\n", "\n", "cluster_13\n", "\n", "CX\n", "\n", "\n", "cluster_14\n", "\n", "CX\n", "\n", "\n", "cluster_15\n", "\n", "CX\n", "\n", "\n", "\n", "(0, 0)\n", "\n", "e0[0]\n", "\n", "\n", "\n", "(8, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(0, 0)->(8, 0)\n", "\n", "\n", "\n", "\n", "\n", "(2, 0)\n", "\n", "e1[1]\n", "\n", "\n", "\n", "(8, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(2, 0)->(8, 1)\n", "\n", "\n", "\n", "\n", "\n", "(4, 0)\n", "\n", "e2[2]\n", "\n", "\n", "\n", "(9, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(4, 0)->(9, 1)\n", "\n", "\n", "\n", "\n", "\n", "(6, 0)\n", "\n", "e3[3]\n", "\n", "\n", "\n", "(12, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(6, 0)->(12, 1)\n", "\n", "\n", "\n", "\n", "\n", "(1, 0)\n", "\n", "e0[0]\n", "\n", "\n", "\n", "(3, 0)\n", "\n", "e1[1]\n", "\n", "\n", "\n", "(5, 0)\n", "\n", "e2[2]\n", "\n", "\n", "\n", "(7, 0)\n", "\n", "e3[3]\n", "\n", "\n", "\n", "(10, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(8, 0)->(10, 0)\n", "\n", "\n", "\n", "\n", "\n", "(9, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(8, 1)->(9, 0)\n", "\n", "\n", "\n", "\n", "\n", "(10, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(9, 0)->(10, 1)\n", "\n", "\n", "\n", "\n", "\n", "(11, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(9, 1)->(11, 1)\n", "\n", "\n", "\n", "\n", "\n", "(14, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(10, 0)->(14, 0)\n", "\n", "\n", "\n", "\n", "\n", "(11, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(10, 1)->(11, 0)\n", "\n", "\n", "\n", "\n", "\n", "(12, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(11, 0)->(12, 0)\n", "\n", "\n", "\n", "\n", "\n", "(13, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(11, 1)->(13, 0)\n", "\n", "\n", "\n", "\n", "\n", "(15, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(12, 0)->(15, 0)\n", "\n", "\n", "\n", "\n", "\n", "(13, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(12, 1)->(13, 1)\n", "\n", "\n", "\n", "\n", "\n", "(13, 0)->(5, 0)\n", "\n", "\n", "\n", "\n", "\n", "(14, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(13, 1)->(14, 1)\n", "\n", "\n", "\n", "\n", "\n", "(15, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(14, 0)->(15, 1)\n", "\n", "\n", "\n", "\n", "\n", "(14, 1)->(7, 0)\n", "\n", "\n", "\n", "\n", "\n", "(15, 0)->(3, 0)\n", "\n", "\n", "\n", "\n", "\n", "(15, 1)->(1, 0)\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "full_circuit = (\n", " Circuit(4).CX(0, 1).CX(1, 2).SWAP(0, 1).CX(1, 2).CX(1, 3).CX(2, 3).CX(0, 3).CX(1, 0)\n", ")\n", "place_with_map(full_circuit, naive_map)\n", "Graph(full_circuit).get_DAG()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "After a modification is made the partition is updated." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The first partition:" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "Circuit\n", "\n", "\n", "cluster_q_inputs\n", "\n", "\n", "\n", "cluster_q_outputs\n", "\n", "\n", "\n", "cluster_8\n", "\n", "CX\n", "\n", "\n", "cluster_9\n", "\n", "CX\n", "\n", "\n", "cluster_10\n", "\n", "SWAP\n", "\n", "\n", "cluster_11\n", "\n", "CX\n", "\n", "\n", "\n", "(0, 0)\n", "\n", "e0[0]\n", "\n", "\n", "\n", "(8, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(0, 0)->(8, 0)\n", "\n", "\n", "\n", "\n", "\n", "(2, 0)\n", "\n", "e1[1]\n", "\n", "\n", "\n", "(8, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(2, 0)->(8, 1)\n", "\n", "\n", "\n", "\n", "\n", "(4, 0)\n", "\n", "e2[2]\n", "\n", "\n", "\n", "(9, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(4, 0)->(9, 1)\n", "\n", "\n", "\n", "\n", "\n", "(6, 0)\n", "\n", "e3[3]\n", "\n", "\n", "\n", "(7, 0)\n", "\n", "e3[3]\n", "\n", "\n", "\n", "(6, 0)->(7, 0)\n", "\n", "\n", "\n", "\n", "\n", "(1, 0)\n", "\n", "e0[0]\n", "\n", "\n", "\n", "(3, 0)\n", "\n", "e1[1]\n", "\n", "\n", "\n", "(5, 0)\n", "\n", "e2[2]\n", "\n", "\n", "\n", "(10, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(8, 0)->(10, 0)\n", "\n", "\n", "\n", "\n", "\n", "(9, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(8, 1)->(9, 0)\n", "\n", "\n", "\n", "\n", "\n", "(10, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(9, 0)->(10, 1)\n", "\n", "\n", "\n", "\n", "\n", "(11, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(9, 1)->(11, 1)\n", "\n", "\n", "\n", "\n", "\n", "(10, 0)->(1, 0)\n", "\n", "\n", "\n", "\n", "\n", "(11, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(10, 1)->(11, 0)\n", "\n", "\n", "\n", "\n", "\n", "(11, 0)->(3, 0)\n", "\n", "\n", "\n", "\n", "\n", "(11, 1)->(5, 0)\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "circ_first_partition = Circuit(4).CX(0, 1).CX(1, 2).SWAP(0, 1).CX(1, 2)\n", "place_with_map(circ_first_partition, naive_map)\n", "Graph(circ_first_partition).get_DAG()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The second partition:" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "Circuit\n", "\n", "\n", "cluster_q_inputs\n", "\n", "\n", "\n", "cluster_q_outputs\n", "\n", "\n", "\n", "cluster_8\n", "\n", "CX\n", "\n", "\n", "cluster_9\n", "\n", "CX\n", "\n", "\n", "cluster_10\n", "\n", "CX\n", "\n", "\n", "cluster_11\n", "\n", "CX\n", "\n", "\n", "\n", "(0, 0)\n", "\n", "e0[0]\n", "\n", "\n", "\n", "(10, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(0, 0)->(10, 0)\n", "\n", "\n", "\n", "\n", "\n", "(2, 0)\n", "\n", "e1[1]\n", "\n", "\n", "\n", "(8, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(2, 0)->(8, 0)\n", "\n", "\n", "\n", "\n", "\n", "(4, 0)\n", "\n", "e2[2]\n", "\n", "\n", "\n", "(9, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(4, 0)->(9, 0)\n", "\n", "\n", "\n", "\n", "\n", "(6, 0)\n", "\n", "e3[3]\n", "\n", "\n", "\n", "(8, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(6, 0)->(8, 1)\n", "\n", "\n", "\n", "\n", "\n", "(1, 0)\n", "\n", "e0[0]\n", "\n", "\n", "\n", "(3, 0)\n", "\n", "e1[1]\n", "\n", "\n", "\n", "(5, 0)\n", "\n", "e2[2]\n", "\n", "\n", "\n", "(7, 0)\n", "\n", "e3[3]\n", "\n", "\n", "\n", "(11, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(8, 0)->(11, 0)\n", "\n", "\n", "\n", "\n", "\n", "(9, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(8, 1)->(9, 1)\n", "\n", "\n", "\n", "\n", "\n", "(9, 0)->(5, 0)\n", "\n", "\n", "\n", "\n", "\n", "(10, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(9, 1)->(10, 1)\n", "\n", "\n", "\n", "\n", "\n", "(11, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(10, 0)->(11, 1)\n", "\n", "\n", "\n", "\n", "\n", "(10, 1)->(7, 0)\n", "\n", "\n", "\n", "\n", "\n", "(11, 0)->(3, 0)\n", "\n", "\n", "\n", "\n", "\n", "(11, 1)->(1, 0)\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "circ_second_partition = Circuit(4).CX(1, 3).CX(2, 3).CX(0, 3).CX(1, 0)\n", "place_with_map(circ_second_partition, naive_map)\n", "Graph(circ_second_partition).get_DAG()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This pattern of modification and updating the partition is repeated until the partition has reached the end of the circuit, i.e. the back side of the partition has no gates in it. Also note that the process of updating the partition has been simplified for this example with \"physically permitted\" encapsulating two-qubit gate constraints only - in the future we expect other arity gates to provide constraints that need to be met. Also note that any modification to the second circuit can willfully modify the qubit labelling and a token swapping network will be automatically added to conform to the new labelling." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We now enough about how `MappingManager` works to add our own `RoutingMethodCircuit`. While `LexiRouteRoutingMethod` is implemented in c++ TKET, giving it some advantages, via lambda functions we can define our own `RoutingMethodCircuit` in python." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A python defined `RoutingMethodCircuit` requires three arguments. The first is a function that given a Circuit (the circuit after the partition) and an Architecture, returns a bool (determining whether the new circuit should be substituted in a full routing process), a new Circuit (a modification of the original circuit such as an added SWAP) a Dict between qubits reflecting any relabelling done in the method, and a Dict between qubits giving any implicit permutation of qubits (such as by adding a SWAP). For some clarity (we will write an example later), lets look at an example function declaration." ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [], "source": [ "from typing import Dict" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [], "source": [ "def route_subcircuit_func(\n", " circuit: Circuit, architecture: Architecture\n", ") -> Tuple[bool, Circuit, Dict[Node, Node], Dict[Node, Node]]:\n", " return ()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The first return is a bool which detemrines if a given `RoutingMethodCircuit` is suitable for providing a solution at a given partition. `MappingManager.route_circuit` accepts a List of of `RoutingMethod` defining how solutions are found. At the point the partition circuit is modified, the circuit is passed to `RoutingMethodCircuit.routing_method` which additionally to finding a subcircuit substitution, should determine whether it can or can't helpfully modify the partition boundary circuit, and return True if it can. The first `RoutingMethodCircuit` to return True is then used for modification - meaning the ordering of List elements is important." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The third argument sets the maximum number of gates given in the passed Circuit and the fourth argument sets the maximum depth in the passed Circuit." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`LexiRouteRoutingMethod` will always return True, because it can always find some helpful SWAP to insert, and it can dynamically assign logical to physical qubits. Given this, lets construct a more specialised modification - an architecture-aware decomposition of a distance-2 CRy gate. Lets write our function type declarations for each method:" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [], "source": [ "def distance2_CRy_decomp(\n", " circuit: Circuit, architecture: Architecture\n", ") -> Tuple[bool, Circuit, Dict[Node, Node], Dict[Node, Node]]:\n", " return (False, Circuit(), {}, {})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Where do we start? Lets define a simple scope for our solution: for a single gate in the passed circuit (the circuit after the partition) that has OpType CRy, if the two qubits it's acting on are at distance 2 on the architecture, decompose the gate using BRIDGE gates." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The first restriction is to only have a single gate from the first slice - we can achieve this by setting both the maximum depth and size parameters to 1." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The second restriction is for the gate to have OpType CRy and for the qubits to be at distance 2 - we can check this restriction in a `distance2_CRy_check` method." ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [], "source": [ "def distance2_CRy_check(circuit: Circuit, architecture: Architecture) -> bool:\n", " if circuit.n_gates != 1:\n", " raise ValueError(\n", " \"Circuit for CRy check should only have 1 gate, please change parameters of method declaration.\"\n", " )\n", " command = circuit.get_commands()[0]\n", " if command.op.type == OpType.CRy:\n", " # Architecture stores qubits under `Node` identifier\n", " n0 = Node(command.qubits[0].reg_name, command.qubits[0].index)\n", " n1 = Node(command.qubits[1].reg_name, command.qubits[1].index)\n", " # qubits could not be placed in circuit, so check before finding distance\n", " if n0 in architecture.nodes and n1 in architecture.nodes:\n", " # means we can run the decomposition\n", " if architecture.get_distance(n0, n1) == 2:\n", " return True\n", " return False" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `distance2_CRy_check` confirms whether the required restrictions are respected. Given this, if the `distance2_CRy_decomp` method is called we know where to add the decomposition." ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [], "source": [ "def distance2_CRy_decomp(\n", " circuit: Circuit, architecture: Architecture\n", ") -> Tuple[bool, Circuit, Dict[Node, Node], Dict[Node, Node]]:\n", " worthwhile_substitution = distance2_CRy_check(circuit, architecture)\n", " if worthwhile_substitution == False:\n", " return (False, Circuit(), {}, {})\n", " command = circuit.get_commands()[0]\n", " qubits = command.qubits\n", " # Architecture stores qubits under `Node` identifier\n", " n0 = Node(qubits[0].reg_name, qubits[0].index)\n", " n1 = Node(qubits[1].reg_name, qubits[1].index)\n", "\n", " # need to find connecting node for decomposition\n", " adjacent_nodes_0 = architecture.get_adjacent_nodes(n0)\n", " adjacent_nodes_1 = architecture.get_adjacent_nodes(n1)\n", " connecting_nodes = adjacent_nodes_0.intersection(adjacent_nodes_1)\n", " if len(connecting_nodes) == 0:\n", " raise ValueError(\"Qubits for distance-2 CRy decomp are not at distance 2.\")\n", " connecting_node = connecting_nodes.pop()\n", " c = Circuit()\n", "\n", " # the \"relabelling map\" empty, and the permutation map is qubit to qubit, so add here\n", " permutation_map = dict()\n", " for q in circuit.qubits:\n", " permutation_map[q] = q\n", " c.add_qubit(q)\n", " # rotation, can assume only parameter as CRy\n", " angle = command.op.params[0]\n", " c.Ry(angle, qubits[1])\n", " # distance-2 CX decomp\n", " c.CX(qubits[0], connecting_node).CX(connecting_node, qubits[1])\n", " c.CX(qubits[0], connecting_node).CX(connecting_node, qubits[1])\n", " # rotation\n", " c.Ry(-1 * angle, qubits[1])\n", " # distance-2 CX decomp\n", " c.CX(qubits[0], connecting_node).CX(connecting_node, qubits[1])\n", " c.CX(qubits[0], connecting_node).CX(connecting_node, qubits[1])\n", "\n", " # the \"relabelling map\" is just qubit to qubit\n", " return (True, c, {}, permutation_map)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Before turning this into a `RoutingMethod` we can try it ourselves." ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "Circuit\n", "\n", "\n", "cluster_q_inputs\n", "\n", "\n", "\n", "cluster_q_outputs\n", "\n", "\n", "\n", "cluster_8\n", "\n", "CRy(0.6)\n", "\n", "\n", "\n", "(0, 0)\n", "\n", "e0[0]\n", "\n", "\n", "\n", "(8, 0)\n", "\n", "0\n", "\n", "\n", "\n", "(0, 0)->(8, 0)\n", "\n", "\n", "\n", "\n", "\n", "(2, 0)\n", "\n", "e1[1]\n", "\n", "\n", "\n", "(3, 0)\n", "\n", "e1[1]\n", "\n", "\n", "\n", "(2, 0)->(3, 0)\n", "\n", "\n", "\n", "\n", "\n", "(4, 0)\n", "\n", "e2[2]\n", "\n", "\n", "\n", "(8, 1)\n", "\n", "1\n", "\n", "\n", "\n", "(4, 0)->(8, 1)\n", "\n", "\n", "\n", "\n", "\n", "(6, 0)\n", "\n", "e3[3]\n", "\n", "\n", "\n", "(7, 0)\n", "\n", "e3[3]\n", "\n", "\n", "\n", "(6, 0)->(7, 0)\n", "\n", "\n", "\n", "\n", "\n", "(1, 0)\n", "\n", "e0[0]\n", "\n", "\n", "\n", "(5, 0)\n", "\n", "e2[2]\n", "\n", "\n", "\n", "(8, 0)->(1, 0)\n", "\n", "\n", "\n", "\n", "\n", "(8, 1)->(5, 0)\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "test_c = Circuit(4)\n", "test_c.CRy(0.6, 0, 2)\n", "place_with_map(test_c, naive_map)\n", "Graph(test_c).get_DAG()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As we can see, our circuit has one CRy gate at distance two away." ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "print(distance2_CRy_check(test_c, id_architecture))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Our method returns True, as expected! We should also test cases where it returns errors or False." ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "test_c_false = Circuit(4)\n", "test_c_false.CRy(0.4, 0, 1)\n", "place_with_map(test_c_false, naive_map)\n", "print(distance2_CRy_check(test_c_false, id_architecture))" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Error reached!\n" ] } ], "source": [ "test_c_error = Circuit(4)\n", "test_c_error.CRy(0.6, 0, 2)\n", "test_c_error.CRy(0.4, 0, 1)\n", "place_with_map(test_c_error, naive_map)\n", "try:\n", " distance2_CRy_check(test_c_error, id_architecture)\n", "except ValueError:\n", " print(\"Error reached!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Does the decomposition work?" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "
\n", " \n", "
\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "test_c = Circuit(4)\n", "test_c.CRy(0.6, 0, 2)\n", "place_with_map(test_c, naive_map)\n", "decomp = distance2_CRy_decomp(test_c, id_architecture)\n", "display.render_circuit_jupyter(decomp[1])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Great! Our check function and decomposition method are both working. Lets wrap them into a `RoutingMethodCircuit` and try them out." ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [], "source": [ "from pytket.mapping import RoutingMethodCircuit" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [], "source": [ "cry_rmc = RoutingMethodCircuit(distance2_CRy_decomp, 1, 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can use our original `MappingManager` object as it is defined for the same architecture. Lets try it out on a range of circumstances." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we pass it a full CX circuit without `LexiRouteRoutingMethod`, we should find that `MappingManager` throws an error, as none of the passed methods can route for the given circuit." ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Error reached!\n" ] } ], "source": [ "c = (\n", " Circuit(4)\n", " .CX(0, 1)\n", " .CX(1, 2)\n", " .CX(0, 2)\n", " .CX(0, 3)\n", " .CX(2, 3)\n", " .CX(1, 3)\n", " .CX(0, 1)\n", " .measure_all()\n", ")\n", "place_with_map(c, naive_map)\n", "try:\n", " mapping_manager.route_circuit(c, [cry_rmc])\n", "except RuntimeError:\n", " print(\"Error reached!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Alternatively, we can add `LexiRouteRoutingMethod` on top:" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "
\n", " \n", "
\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "c = (\n", " Circuit(4)\n", " .CX(0, 1)\n", " .CX(1, 2)\n", " .CX(0, 2)\n", " .CX(0, 3)\n", " .CX(2, 3)\n", " .CX(1, 3)\n", " .CX(0, 1)\n", " .measure_all()\n", ")\n", "place_with_map(c, naive_map)\n", "mapping_manager.route_circuit(c, [cry_rmc, LexiRouteRoutingMethod(10)])\n", "display.render_circuit_jupyter(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "However as there are no CRy gates our new method is unused. We can add one:" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "
\n", " \n", "
\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "c = (\n", " Circuit(4)\n", " .CRy(0.6, 0, 2)\n", " .CX(0, 1)\n", " .CX(1, 2)\n", " .CX(0, 2)\n", " .CX(0, 3)\n", " .CX(2, 3)\n", " .CX(1, 3)\n", " .CX(0, 1)\n", " .measure_all()\n", ")\n", "mapping_manager.route_circuit(c, [lexi_label, cry_rmc, LexiRouteRoutingMethod(10)])\n", "display.render_circuit_jupyter(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This time we can see our decomposition! If we reorder the methods though `LexiRouteRoutingMethod` is checked first (and returns True), so our new method is unused. The order is important!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, lets see what happens if the gate is not at the right distance initially." ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "
\n", " \n", "
\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "c = (\n", " Circuit(4)\n", " .CRy(0.6, 0, 3)\n", " .CX(0, 1)\n", " .CX(1, 2)\n", " .CX(0, 2)\n", " .CX(0, 3)\n", " .CX(2, 3)\n", " .CX(1, 3)\n", " .CX(0, 1)\n", " .measure_all()\n", ")\n", "mapping_manager.route_circuit(c, [lexi_label, cry_rmc, LexiRouteRoutingMethod(10)])\n", "display.render_circuit_jupyter(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Above a SWAP gate is inserted by `LexiRouteRoutingMethod` before anything else." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For anyone interested, a simple extension exercise could be to extend this to additionally work for distance-2 CRx and CRz. Alternatively one could improve on the method itself - this approach always decomposes a CRy at distance-2, but is this a good idea?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Also note that higher performance solutions are coded straight into the TKET c++ codebase. This provides advantages, including that Circuit construction and substitution is unnecessary (as with python) as the circuit can be directly modified, however the ability to produce prototypes at the python level is very helpful. If you have a great python implementation but are finding some runtime bottlenecks, why not try implementing it straight into TKET (the code is open source at https://github.com/CQCL/tket)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Besides the `LexiRouteRoutingMethod()` and the `LexiLabellingMethod()` there are other routing methods in pytket, such as the `AASRouteRoutingMethod()` and the corresponding `AASLabellingMethod()`, which are used to route phase-polynomial boxes using architecture-aware synthesis. Usually circuits contain non-phase-polynomial operations as well, so it is a good idea to combine them with the `LexiRouteRoutingMethod()`, as in the following example:" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [], "source": [ "from pytket.mapping import AASRouteRoutingMethod, AASLabellingMethod\n", "from pytket.circuit import PhasePolyBox, Qubit\n", "import numpy as np" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "
\n", " \n", "
\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "
\n", " \n", "
\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "c = Circuit(3, 3)\n", "n_qb = 3\n", "qubit_indices = {Qubit(0): 0, Qubit(1): 1, Qubit(2): 2}\n", "phase_polynomial = {(True, False, True): 0.333, (False, False, True): 0.05}\n", "linear_transformation = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])\n", "p_box = PhasePolyBox(n_qb, qubit_indices, phase_polynomial, linear_transformation)\n", "c.add_phasepolybox(p_box, [0, 1, 2])\n", "c.CX(0, 1).CX(0, 2).CX(1, 2)\n", "display.render_circuit_jupyter(c)\n", "nodes = [Node(\"test\", 0), Node(\"test\", 1), Node(\"test\", 2)]\n", "arch = Architecture([[nodes[0], nodes[1]], [nodes[1], nodes[2]]])\n", "mm = MappingManager(arch)\n", "mm.route_circuit(\n", " c,\n", " [\n", " AASRouteRoutingMethod(1),\n", " LexiLabellingMethod(),\n", " LexiRouteRoutingMethod(),\n", " AASLabellingMethod(),\n", " ],\n", ")\n", "display.render_circuit_jupyter(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this case the order of the methods is not very relevant, because in each step of the routing only one of the methods is suitable. In the first part of the circuit the mapping is done without inserting swaps by the AAS method; in the second part one swap gate is added to the circuit." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.2" } }, "nbformat": 4, "nbformat_minor": 2 }