BGRAPH Schema#

BGRAPH is a work-in-progress file format (.bgraph) that can be used to facilitate interoperability between external lattice surgery (LS) tools.

While only a preliminary minimum baseline in need of improvement, the current BGRAPH specification already enjoys the following advantages:

  • Common format both Topologiq and TopoLS can produce

  • Human-readable (QASM-like) format that is easy to inspect

  • Clear structure that allows parsing using

  • Sufficiently complete as to enable read/write of any arbitrary blockgraph tqec can currently handle.

We welcome proposals for improved specifications that expand upon these minimum advantages. In the ideal scenario, we foresee future versions of BGRAPH being flexible enough as to enable interoperability at any stage of the LS process, which the current version cannot yet do.

Schema#

A BGRAPH file can be conceived as a QASM-like representation of a lattice surgery.

Any BGRAPH file should be divided into four main sections: - HEADER: The title of the document, with information about the source tool used to produce it. - METADATA: A short section with meta information on top - CUBES: A subsequent section with detailed information about the cubes in the blockgraph - PIPES: A final section with detailed information about the pipes in the blockgraph.

An example BGRAPH file is available from tqec.assets.

Metadata#

Contains the information needed to produce a blockgraph using the information available in other sections.

The information in this section is parseable, but the specific fields are optional: - source: The tool used to create the BGRAPH. - name of the circuit: used to give the blockgraph a reference name. - length of pipes used in the source tool: The length of the pipes between any two adjacent cubes (see note at the end of this section).

Each METADATA item should be given as a CSV-separated pair. If a field is not included, TQEC will assign default values.

Example

METADATA: attr_name; value;
source; name_of_tool_that_created_the_file;
circuit_name; CNOTs;
pipe_length; 2.0;

Note

Fields in this section are optional. Note, in particular, that if pipe_length is not given, the TQEC parser will default to pipe_length = 0.0.

Cubes#

Contains the information needed to translate each line of this section into a tqec cube <./terminology.rst>.

The information in this section is meant to be parsed and must contain, at a minimum: - index: the ID of the cube, ideally an integer but alphanumeric IDs also possible. - position: The (x, y, z) position of the cube, a tuple of integers. - kind: The kind of the cube, as a string (see Terminology, as well as the note below). - label (optional): An optional annotation that is typically used to denote when a cube is a PORT.

Each CUBE item should be given as a CSV-separated sequence. All separating semi-colons should be included even if the (optional) label field is blank. This helps communicating explicitly to the parser that there is no label (for robustness, the parses will fail if an incorrect number of semi-colons is used).

Example

CUBES: index;x;y;z;kind;label;
4;0;0;0;zxz;;
3;3;0;0;xxz;;
0;6;0;0;ooo;in_0;
8;-6;0;0;ooo;out_0;

Note

There is no fully-agreed denomination for open boundaries/ports or Y-cubes. For the time being, it is possible to use “ooo” or “P” for ports and “Y”, “yi”, “ym” to denote a Y-cube.

Pipes#

Contains the information needed to translate each line of this section into a tqec pipe <./terminology.rst>.

The information in this section is meant to be parsed and must contain, at a minimum: - index: the ID of the cube, typically an integer. - u: The ID of the cube at which the pipe starts (the source for the edge represented by the pipe). - v: The ID of the cube at which the pipe ends (the target for the edge represented by the pipe). - kind: The kind of the pipe (see Terminology for all possibilities.).

Each PIPE item should be given as a CSV-separated sequence. All separating semi-colons should be included and all fields should be given.

Example

PIPES: src;tgt;kind;
4;3;oxz;
4;5;zxo;
4;6;oxz;
16;18;ozxh;

General#

There are also a number of general practices to consider across sections.

Each section must include the header for the respective section, including the micro-schema for the section. In other words, the following lines should appear exactly as in the examples given above. - METADATA: attr_name; value; - CUBES: index;x;y;z;kind;label; - PIPES: src;tgt;kind;

Additionally, the following terms are reserved for usage only as first item in the respective metadata section. In other words, they cannot be used in other fields. So, for instance, it is not allowed use the word “source” as graph_name. - graph_name - source - pipe_length.

Additionally, while probably obvious due to the nature of lattice surgery and the use of semi-colon-separated-values: - the strings used as kinds for either cubes or pipes (e.g. zxz, xxz, oxz, ozxh, etc) should not be used for any other purpose. - no additional semi-colons can be used anywhere in the field except as separators for the specific fields in each of the lines in metadata, cubes, or pipes sections.

Parsing a BGRAPH#

If you have a BGRAPH file, you can easily convert it into a blockgraph using tqec’s tqec.computation.block_graph.from_bgraph.

from tqec import BlockGraph

filepath = "../assets/cnots.bgraph"
graph = BlockGraph.from_bgraph(filepath)

You can then display and use the resulting blockgraph using other TQEC methods.

For instance, you can call BlockGraph.view_as_html to visualize the blockgraph.

graph.view_as_html()

Additionally, you can attach the correlation surface to the model to visualize what the logical observable looks like:

correlation_surfaces = graph.find_correlation_surfaces()
graph.view_as_html(
    pop_faces_at_directions=("-Y",),
    show_correlation_surface=correlation_surfaces[0],
)

And, of course, you can follow the same instructions available in several gallery docs (for instance, this Steane code example) to produce circuits and simulate the blockgraph.

Producing a BGRAPH#

It is also possible to produce a BGRAPH of any TQEC blockgraph.

In the example below, we print the BGRAPH string. To produce a .bgraph file with the contents of the string, simply change path_to_output_file=None to Path (pathlib.Path or string).

from pathlib import Path
from tqec.gallery import cnot
from tqec.utils.enums import Basis

# Import blockgraph from gallery
graph = cnot(Basis.X)

# Write to BGRAPH
bgraph_out_str = graph.to_bgraph(
    filepath=None,  # Change to a path to write output as `.bgraph`
    graph_name="cnot",
)

# Inspect BGRAPH string
print(bgraph_out_str)
BLOCKGRAPH 0.1.0;

METADATA: attr_name; value;
source; TQEC.
circuit_name; cnot;

CUBES: index;x;y;z;kind;label;
(0, 0, 0);0;0;0;ZXX;;
(0, 0, 1);0;0;1;ZXX;;
(0, 0, 2);0;0;2;ZXZ;;
(0, 0, 3);0;0;3;ZXX;;
(0, 1, 1);0;1;1;ZXX;;
(0, 1, 2);0;1;2;ZXZ;;
(1, 1, 0);1;1;0;ZXX;;
(1, 1, 1);1;1;1;ZXZ;;
(1, 1, 2);1;1;2;ZXZ;;
(1, 1, 3);1;1;3;ZXX;;

PIPES: src;tgt;kind;
(0, 0, 0);(0, 0, 1);ZXO;
(0, 0, 1);(0, 0, 2);ZXO;
(0, 0, 1);(0, 1, 1);ZOX;
(0, 0, 2);(0, 0, 3);ZXO;
(0, 1, 1);(0, 1, 2);ZXO;
(0, 1, 2);(1, 1, 2);OXZ;
(1, 1, 0);(1, 1, 1);ZXO;
(1, 1, 1);(1, 1, 2);ZXO;
(1, 1, 2);(1, 1, 3);ZXO;