Build Computations#

In tqec, a logical computation is represented as a BlockGraph. There are several ways to build it:

  1. Build the structure interactively with SketchUp, export and convert it to a BlockGraph.

  2. Build a BlockGraph programmatically with add_cube and add_pipe methods.

  3. Build a pyzx.GraphS ZX graph representation of the computation and synthesize it to a BlockGraph.

In this notebook, we will guide you through all the methods.

1. Use SketchUp#

SketchUp 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.

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.

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.

The workflow using SketchUp to build computations is as follows:

  1. Open the template file in SketchUp.

  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.

  3. Save and export the model to .dae file format.

  4. Import the computation into tqec using the tqec.read_block_graph_from_dae_file or BlockGraph.from_dae_file() function.

2. Build BlockGraph directly#

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.

[1]:
from tqec import BlockGraph, Position3D

g = BlockGraph("CNOT")
cubes = [
    (Position3D(0, 0, 0), "P", "In_Control"),
    (Position3D(0, 0, 1), "ZXX", ""),
    (Position3D(0, 0, 2), "ZXZ", ""),
    (Position3D(0, 0, 3), "P", "Out_Control"),
    (Position3D(0, 1, 1), "ZXX", ""),
    (Position3D(0, 1, 2), "ZXZ", ""),
    (Position3D(1, 1, 0), "P", "In_Target"),
    (Position3D(1, 1, 1), "ZXZ", ""),
    (Position3D(1, 1, 2), "ZXZ", ""),
    (Position3D(1, 1, 3), "P", "Out_Target"),
]
for pos, kind, label in cubes:
    g.add_cube(pos, kind, label)

pipes = [(0, 1), (1, 2), (2, 3), (1, 4), (4, 5), (5, 8), (6, 7), (7, 8), (8, 9)]

for p0, p1 in pipes:
    g.add_pipe(cubes[p0][0], cubes[p1][0])

g.view_as_html()
[1]:

3. pyzx.GraphS and synthesis#

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.

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.

[ ]:
from pyzx.graph.graph_s import GraphS
from pyzx import VertexType
from fractions import Fraction

from tqec.interop import block_synthesis
from tqec import Position3D

g_zx = GraphS()
g_zx.add_vertices(5)
g_zx.set_type(1, VertexType.Z)
g_zx.set_type(3, VertexType.Z)
g_zx.set_type(4, VertexType.Z)
g_zx.set_phase(4, Fraction(1, 2))
g_zx.add_edges([(0, 1), (1, 2), (1, 3), (3, 4)])
g_zx.set_inputs((0,))
g_zx.set_outputs((2,))

positions = {
    0: Position3D(0, 0, 0),
    1: Position3D(0, 0, 1),
    2: Position3D(0, 0, 2),
    3: Position3D(1, 0, 1),
    4: Position3D(1, 0, 2),
}

g = block_synthesis(g_zx, positions=positions)
g.view_as_html()