DOI: 10.5281/zenodo.13312436
title: Code and data for "Concatenated Steane code with single-flag syndrome checks"

description: Introduction

This repository contains code to reproduce the results in "Concatenated Steane code with single-flag syndrome checks" by Balint Pato, Theerapat Tansuwannont, Kenneth R. Brown (https://arxiv.org/abs/2403.09978).

Setup

This code was developed and is only tested on Linux. It can potentially work on Mac with some rough edges, but for Windows, we recommend WSL only.

Getting the repository

Uncompress the downloaded Zenodo file and switch into the directory:

cd concatenated_steane


Python setup



We require Python version to be larger or equal to 3.8 and less than or equal to 3.11.

We need venv and pip - if you don't have it, you can install it for example with


sudo apt install python3-venv -y
sudo apt install python3-pip -y 




Setup a virtual environment


python3 -m venv ~/.virtualenvs/conc_steane




Activate virtual environment


source ~/.virtualenvs/conc_steane/bin/activate


this should result in (conc_steane) added in front of your prompt.



Install dependencies


pip install -r requirements.txt -r requirements.dev.txt


C++ setup

Requirements

The following tools are required:



CMake

ninja-build

gcc++

git

Python (see above) for circuit generation


sudo apt install gcc-11 -y
sudo apt install cmake -y 
sudo apt install clang-format -y 
sudo apt-get install ack -y 
sudo apt install g++  -y   
sudo apt install ninja-build -y 
sudo apt-get install lcov -y 
sudo apt-get install texlive dvipng texlive-latex-extra texlive-fonts-recommended cm-super -y
sudo apt install entr -y


Setup steps



Setup cmake


cmake -S . -B build -G Ninja




Setup config/lookup table files


hack/genconf



It should finish with a similar output to below:

...
Combination stats:
        4:91,386,541
        3:1,703,016
        2:23,653
        1:218
 elapsed: 50,306 ms
 cadence: 1,853,933 items/s 100% processed:  93,263,997 items Memory used: 2.04558 GB ETA: 00:00:00
cache size: 67,166,572
Combination stats:
        4:91,537,110
        3:1,703,016
        2:23,653
        1:218
Writing file...
Success!


Running tests

Running tests can ensure that everything works well.

Python unit tests

pytest concatenated_steane

It should finish with an output similar to this:

================================================== 34 passed in 8.81s ==================================================


C++ unit tests

Run all tests:

hack/tests

Should finish with something similar to this:

[----------] Global test environment tear-down
[==========] 71 tests from 9 test suites ran. (65662 ms total)
[  PASSED  ] 71 tests.


End to end tests

To run all end to end tests the simplest way:

hack/e2e.py


It should finish with something similar to this:

hack/e2e.py .............                                                                                        [100%]

============================================ 13 passed in 222.89s (0:03:42) ============================================


The end-to-end tests generate circuits, sample and decode from them for a certain combination of time decoder and space decoder for a given code, and then counts the number of logical errors for a given number of shots. This number is the same on each run on the same machine. However, across machines it might differ. Thus, if you see deviation failures in the number of expected errors, that should be okay. Sometimes this can be relatively large as well, up to 50%, because the number of samples is relatively low to have faster feedback. Admittedly, this fraigle system is far from perfect, but it is good enough for local testing.

Guide to reproducing the data

General architecture

In this project, we provide the framework to sample from quantum CSS codes memory simulations and decode those results. There are multiple, separately executable pieces in the architecture that the user has to tie together on the command line. On a high level, the following components are used:



concatenated_steane/gen/main.py - to generate the circuit schema for the d=9 6.6.6 color code, and the concatenated Steane code

stim - Stim is installed as part of the dependencies. It can be used as a standalone command line tool, Python library or as a C++ library. It is at the heart of the sampling part of this project.

hack/run lookup_tables - generates the two decoder lookup tables using the "effective code" formalism for the concatenated Steane code and the d=9 color code. It uses the same JSON file that the online decoder outputs.

hack/run online_decode (C++) - based on the parameters and the generated circuits, this is the entry point where the direct simulation of the circuit happens using Stim as a C++ library, and decoding is done sample-by-sample.

hack/run offline_decode (C++) - this is an advanced workflow for ~ 20x faster sampling and decoding. It only works for fixed-length number of rounds, and circuits have to follow interleaving of ideal measurements. The input for offline decoding is samples in r8 format, generated by stim. This methodology was used in the paper Balint Pato, Theerapat Tansuwannont, Shilin Huang, and Kenneth R. Brown "Optimization Tools for Distance-Preserving Flag Fault-Tolerant Error Correction" (https://journals.aps.org/prxquantum/abstract/10.1103/PRXQuantum.5.020336, https://arxiv.org/abs/2306.12862) to test most of the time decoders except the XZ/ZX time decoders. However, in this project we only use it for code capacity decoding, and as such, we won't describe the details of the construction.


Automated script to reproduce data

In order to reproduce data for this paper, one has to run the following Python file:

python concatenated_steane/reproduce.py


Now, the number of samples is reduced here, so that the python file can run in an hour or so depending on the number of cores on the system. We refer the experimenter to this file for the parametrization of the above mentioned tools.

The data will be stored under the data/repro folder.

Guide to reproducing the figures

The data used in the paper is under the data/49_qubit_paper_v1 folder. The following command generates the two main figures of the paper:

export PYTHONPATH="."
python concatenated_steane/plot/figures.py


This will produce two files:



.tmp/d9paper_fig_cc.pdf

.tmp/d9paper_fig_circuit.pdf


In order to use this plotting utility with the newly generated data, pass the -repo repro flag to it:

export PYTHONPATH="."
python concatenated_steane/plot/figures.py -repo repro 


Data

As mentioned above the data for this paper is under the data/49_qubit_paper_v1 folder. The number of data points and location of the data files can be found in the tables below:

=======stl2_mim_twotail_twopart.zx.delta_no_flags.exit_early============
==== ['data/49_qubit_paper_v1/stl2_mim_twotail_twopart.zx.delta_no_flags.exit_early_01/samples.csv', 'data/49_qubit_paper_v1/stl2_mim_twotail_twopart.zx.delta_no_flags.exit_early_02/samples.csv', 'data/49_qubit_paper_v1/stl2_mim_twotail_twopart.zx.delta_no_flags.exit_early_03/samples.csv', 'data/49_qubit_paper_v1/stl2_mim_twotail_twopart.zx.delta_no_flags.exit_early_04/samples.csv', 'data/49_qubit_paper_v1/stl2_mim_twotail_twopart.zx.delta_no_flags.exit_early_05/samples.csv'] ==== 

p         num_logical_error   num_samples  total_rounds  min_rounds  max_rounds           p_l
                                                                                             
0.000063                  1  2.000000e+09  2.018127e+10           4          17  5.000000e-10
0.000126                243  3.264735e+10  3.320122e+11           3          17  7.443176e-09
0.000251                207  1.032400e+09  1.063034e+10           3          17  2.005037e-07
0.000501                187  3.264736e+07  3.410516e+08           3          17  5.727876e-06
0.001000               2422  1.742560e+07  1.822017e+08           3          17  1.389909e-04
0.001995               1581  6.468740e+05  6.421796e+06           3          16  2.444062e-03
0.003981               1495  5.196800e+04  4.511360e+05           3          16  2.876770e-02
0.007943               1078  6.010000e+03  5.147000e+04           3          12  1.793677e-01
=======ccd9_mim_twotail_twopart.zx.delta_no_flags.exit_early============
==== ['data/49_qubit_paper_v1/ccd9_mim_twotail_twopart.zx.delta_no_flags.exit_early_01/samples.csv', 'data/49_qubit_paper_v1/ccd9_mim_twotail_twopart.zx.delta_no_flags.exit_early_02/samples.csv', 'data/49_qubit_paper_v1/ccd9_mim_twotail_twopart.zx.delta_no_flags.exit_early_03/samples.csv', 'data/49_qubit_paper_v1/ccd9_mim_twotail_twopart.zx.delta_no_flags.exit_early_04/samples.csv', 'data/49_qubit_paper_v1/ccd9_mim_twotail_twopart.zx.delta_no_flags.exit_early_05/samples.csv', 'data/49_qubit_paper_v1/ccd9_mim_twotail_twopart.zx.delta_no_flags.exit_early_06/samples.csv', 'data/49_qubit_paper_v1/ccd9_mim_twotail_twopart.zx.delta_no_flags.exit_early_07/samples.csv', 'data/49_qubit_paper_v1/ccd9_mim_twotail_twopart.zx.delta_no_flags.exit_early_08/samples.csv', 'data/49_qubit_paper_v1/ccd9_mim_twotail_twopart.zx.delta_no_flags.exit_early_09/samples.csv'] ==== 

p         num_logical_error   num_samples  total_rounds  min_rounds  max_rounds           p_l
                                                                                                
0.000063                  2  5.540000e+09  5.603199e+10           3          17  3.610108e-10
0.000126                 36  3.857589e+09  3.938440e+10           3          17  9.332253e-09
0.000251                 43  1.427300e+08  1.477526e+09           3          17  3.012681e-07
0.000501                 31  4.513513e+06  4.731112e+07           3          17  6.868264e-06
0.001000                273  1.330000e+06  1.377237e+07           3          16  2.052632e-04
0.001995               1713  4.300000e+05  4.105978e+06           3          16  3.983721e-03
0.003981               4000  9.810600e+04  8.231380e+05           3          15  4.077223e-02
0.007943               4000  1.805600e+04  1.641790e+05           3          12  2.215330e-01
0.015849               3000  6.517000e+03  6.467900e+04           3          10  4.603345e-01
0.031623               3000  6.002000e+03  6.001700e+04           7          10  4.998334e-01
0.063096               3000  6.045000e+03  6.045000e+04          10          10  4.962779e-01
0.125893               3000  5.956000e+03  5.956000e+04          10          10  5.036938e-01
0.251189               3000  5.998000e+03  5.998000e+04          10          10  5.001667e-01
0.501187               3000  5.927000e+03  5.927000e+04          10          10  5.061583e-01
1.000000               3000  6.015000e+03  6.015000e+04          10          10  4.987531e-01

=======stl2_mim_codecap============
==== ['data/49_qubit_paper_v1/stl2_mim_codecap_01/samples.csv', 'data/49_qubit_paper_v1/stl2_mim_codecap_02/samples.csv'] ==== 
p         num_logical_error   num_samples  total_rounds  min_rounds  max_rounds           p_l

0.003981               1015  1.000000e+11  1.000000e+11           1           1  1.015000e-08
0.007943                959  3.162278e+09  3.162278e+09           1           1  3.032624e-07
0.015849                840  1.000000e+08  1.000000e+08           1           1  8.400000e-06
0.031623                779  3.162280e+06  3.162280e+06           1           1  2.463412e-04
0.063096                536  1.000000e+05  1.000000e+05           1           1  5.360000e-03
0.125893               1242  1.752000e+04  1.752000e+04           1           1  7.089041e-02
0.251189               1031  2.866000e+03  2.866000e+03           1           1  3.597348e-01
0.501187                150  3.030000e+02  3.030000e+02           1           1  4.950495e-01

=======ccd9_mim_codecap============
==== ['data/49_qubit_paper_v1/ccd9_mim_codecap_01/samples.csv', 'data/49_qubit_paper_v1/ccd9_mim_codecap_02/samples.csv'] ==== 
p         num_logical_error   num_samples  total_rounds  min_rounds  max_rounds           p_l
                                                                                                
0.003981                122  2.401000e+10  2.401000e+10           1           1  5.081216e-09
0.007943                135  7.592629e+08  7.592629e+08           1           1  1.778040e-07
0.015849                105  2.401000e+07  2.401000e+07           1           1  4.373178e-06
0.031623                117  7.592630e+05  7.592630e+05           1           1  1.540968e-04
0.063096                106  2.401000e+04  2.401000e+04           1           1  4.414827e-03
0.125893               1042  1.425500e+04  1.425500e+04           1           1  7.309716e-02
0.251189                956  2.424000e+03  2.424000e+03           1           1  3.943894e-01
0.501187                 51  1.010000e+02  1.010000e+02           1           1  5.049505e-01


Algorithms for the 4.8.8 code analysis

As mentioned in the paper, the 4.8.8 code analysis can be found in a separate Colab notebook. To find the definitions of the partitions of weight 5 logical operators with overlap 2 and 4, one can use the following command:

hack/run find_488_d5_logicals


This results in the following output:

Parity check matrix:
1111_____________
1_1_11___________
____11__11_______
________11__11___
_______1___1___11
______11__11_____
__________11__11_
__11_11__11__11__
Logicals of weight 5 with overlap 4
__11_1___1__1____
__11_1__1____1___
__111____1___1___
_11__1___1___1___
1_1___1___1___1__
1__1_1___1___1___
_1_1__1___1___1__
____111___1___1__
______1_111___1__
______1___1_111__
Logicals of weight 5 with overlap 2
__111___1___1____
_11__1__1___1____
1_1___1____1___1_
_11_1____1__1____
1_1____1__1____1_
_11_1___1____1___
1_1____1___1__1__
1__1_1__1___1____
_1_1__1____1___1_
1__11____1__1____
_1_1___1__1____1_
1__11___1____1___
_1_1___1___1__1__
____111____1___1_
11___1___1__1____
____11_1__1____1_
11___1__1____1___
____11_1___1__1__
______1_11_1___1_
______1____111_1_
_______1111____1_
11__1____1___1___
_______111_1__1__
_______1__1_11_1_
_______1___1111__


Here each string is a Pauli X (or Z) operator supported on the 1 characters and having identity on the _ characters. These should correspond to Figures 10 and 11 in the paper.