{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Build Computations\n",
"\n",
"In `tqec`, a logical computation is represented as a `BlockGraph`. There are several ways to build it:\n",
"\n",
"1. Build the structure interactively with [SketchUp](https://www.sketchup.com/app), export and convert it to a `BlockGraph`.\n",
"2. Build a `BlockGraph` programmatically with `add_cube` and `add_pipe` methods.\n",
"3. Build a `pyzx.GraphS` ZX graph representation of the computation and synthesize it to a `BlockGraph`.\n",
"\n",
"In this notebook, we will guide you through all the methods."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. Use SketchUp\n",
"\n",
"[SketchUp](https://www.sketchup.com/app) is a 3D modeling tool widely used in QEC community to build the spacetime diagram for logical computations. Its user-friendly interface allows you to easily create and manipulate the computation blocks. \n",
"\n",
"Once you make a Trimble account, you may freely use the web version of SketchUp to import a `.skp` file and create a scene. However, unless you are on a Windows machine, you must either activate a paid license or free trial to export a SketchUp `.skp` file as a COLLADA `.dae` file. On Windows, it suffices to use the [freeware version SketchUp8](https://google-sketchup.en.lo4d.com/download). \n",
"\n",
"Users that are not on Windows may fully use `tqec` via the programmatic construction below. Please notify a developer if you are aware of a way to export a SketchUp scene to a `.dae` file on Mac OSX or Linux.\n",
"\n",
"The workflow using SketchUp to build computations is as follows:\n",
"\n",
"1. Open the [template file](https://github.com/tqec/tqec/blob/main/assets/template.skp) in SketchUp.\n",
"2. Use the building blocks provided in the template file to build your computation. After you finish building, remove the template blocks from the scene.\n",
"3. Save and export the model to `.dae` file format.\n",
"4. Import the computation into `tqec` using the `tqec.read_block_graph_from_dae_file` or `BlockGraph.from_dae_file()` function."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Build `BlockGraph` directly\n",
"\n",
"You can add blocks to a `BlockGraph` by calling `add_cube` and `add_pipe`. Here we show how to build a logical CNOT directly with `BlockGraph`."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
""
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from tqec import BlockGraph, Position3D\n",
"\n",
"g = BlockGraph(\"CNOT\")\n",
"cubes = [\n",
" (Position3D(0, 0, 0), \"P\", \"In_Control\"),\n",
" (Position3D(0, 0, 1), \"ZXX\", \"\"),\n",
" (Position3D(0, 0, 2), \"ZXZ\", \"\"),\n",
" (Position3D(0, 0, 3), \"P\", \"Out_Control\"),\n",
" (Position3D(0, 1, 1), \"ZXX\", \"\"),\n",
" (Position3D(0, 1, 2), \"ZXZ\", \"\"),\n",
" (Position3D(1, 1, 0), \"P\", \"In_Target\"),\n",
" (Position3D(1, 1, 1), \"ZXZ\", \"\"),\n",
" (Position3D(1, 1, 2), \"ZXZ\", \"\"),\n",
" (Position3D(1, 1, 3), \"P\", \"Out_Target\"),\n",
"]\n",
"for pos, kind, label in cubes:\n",
" g.add_cube(pos, kind, label)\n",
"\n",
"pipes = [(0, 1), (1, 2), (2, 3), (1, 4), (4, 5), (5, 8), (6, 7), (7, 8), (8, 9)]\n",
"\n",
"for p0, p1 in pipes:\n",
" g.add_pipe(cubes[p0][0], cubes[p1][0])\n",
"\n",
"g.view_as_html()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. `pyzx.GraphS` and synthesis\n",
"\n",
"For large scale quantum computation, we might use `pyzx` as a upstream compiler and take optimized ZX diagrams as inputs to `tqec`. We need to synthesis the reduced ZX diagram to valid `BlockGraph` realization.\n",
"\n",
"Currently, we only support very naive syhthesis strategy that requires specifying positions of every vertex in the ZX diagram explicitly. Here we take logical S gate teleportation for example to show how to take a `pyzx` graph as input and synthesis it to a `BlockGraph`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
""
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from pyzx.graph.graph_s import GraphS\n",
"from pyzx import VertexType\n",
"from fractions import Fraction\n",
"\n",
"from tqec.interop import block_synthesis\n",
"from tqec import Position3D\n",
"\n",
"g_zx = GraphS()\n",
"g_zx.add_vertices(5)\n",
"g_zx.set_type(1, VertexType.Z)\n",
"g_zx.set_type(3, VertexType.Z)\n",
"g_zx.set_type(4, VertexType.Z)\n",
"g_zx.set_phase(4, Fraction(1, 2))\n",
"g_zx.add_edges([(0, 1), (1, 2), (1, 3), (3, 4)])\n",
"g_zx.set_inputs((0,))\n",
"g_zx.set_outputs((2,))\n",
"\n",
"positions = {\n",
" 0: Position3D(0, 0, 0),\n",
" 1: Position3D(0, 0, 1),\n",
" 2: Position3D(0, 0, 2),\n",
" 3: Position3D(1, 0, 1),\n",
" 4: Position3D(1, 0, 2),\n",
"}\n",
"\n",
"g = block_synthesis(g_zx, positions=positions)\n",
"g.view_as_html()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"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.12.8"
}
},
"nbformat": 4,
"nbformat_minor": 2
}