跳转到主要内容

使用pymatching解码示例stims电路。

项目描述

sinter:快速量子纠错采样

Sinter是一个用于进行快速蒙特卡洛采样的量子纠错电路的软件工具/库。

工作原理

Sinter接受带有噪声、检测器和逻辑可观察量的stims电路。它使用stim对电路进行采样,并使用解码器(如pymatching)预测逻辑可观察量是否翻转,给定检测器数据。它记录成功和失败的频率(错误率)。

Sinter使用python多进程在多个CPU核心之间进行并行采样,根据用户指定的参数(例如目标错误数量)动态决定哪些电路需要更多样本,将结果保存为简单的CSV格式,并提供一些基本的绘图功能以查看结果。

Sinter不支持云计算,但它在单台机器上具有良好的可扩展性。我已经在2核机器、4核机器和96核机器上测试过它。尽管存在潜在的风险(例如,设置批量大小过大导致抖动),sinter通常能够充分利用分配给它的进程资源。

如何安装

Sinter作为pypi包提供。可以使用pip进行安装

pip install sinter

当您处于已安装sinter的python虚拟环境中时,您可以通过命令行命令sinter执行任务。您还可以在python程序中import sinter以使用sinter的Python API。

如何使用:Python API

本示例假设您处于一个已安装sinterpymatching的Python环境。

import stim
import sinter
import matplotlib.pyplot as plt


# Generates surface code circuit tasks using Stim's circuit generation.
def generate_example_tasks():
    for p in [0.001, 0.005, 0.01]:
        for d in [3, 5]:
            yield sinter.Task(
                circuit=stim.Circuit.generated(
                    rounds=d,
                    distance=d,
                    after_clifford_depolarization=p,
                    code_task=f'surface_code:rotated_memory_x',
                ),
                json_metadata={
                    'p': p,
                    'd': d,
                },
            )


def main():
    # Collect the samples (takes a few minutes).
    samples = sinter.collect(
        num_workers=4,
        max_shots=1_000_000,
        max_errors=1000,
        tasks=generate_example_tasks(),
        decoders=['pymatching'],
    )

    # Print samples as CSV data.
    print(sinter.CSV_HEADER)
    for sample in samples:
        print(sample.to_csv_line())

    # Render a matplotlib plot of the data.
    fig, ax = plt.subplots(1, 1)
    sinter.plot_error_rate(
        ax=ax,
        stats=samples,
        group_func=lambda stat: f"Rotated Surface Code d={stat.json_metadata['d']}",
        x_func=lambda stat: stat.json_metadata['p'],
    )
    ax.loglog()
    ax.set_ylim(1e-5, 1)
    ax.grid()
    ax.set_title('Logical Error Rate vs Physical Error Rate')
    ax.set_ylabel('Logical Error Probability (per shot)')
    ax.set_xlabel('Physical Error Rate')
    ax.legend()

    # Save to file and also open in a window.
    fig.savefig('plot.png')
    plt.show()


# NOTE: This is actually necessary! If the code inside 'main()' was at the
# module level, the multiprocessing children spawned by sinter.collect would
# also attempt to run that code.
if __name__ == '__main__':
    main()

示例输出到stdout

     shots,    errors,  discards, seconds,decoder,strong_id,json_metadata
   1000000,       837,         0,    36.6,pymatching,9f7e20c54fec45b6aef7491b774dd5c0a3b9a005aa82faf5b9c051d6e40d60a9,"{""d"":3,""p"":0.001}"
     53498,      1099,         0,    6.52,pymatching,3f40432443a99b933fb548b831fb54e7e245d9d73a35c03ea5a2fb2ce270f8c8,"{""d"":3,""p"":0.005}"
     16269,      1023,         0,    3.23,pymatching,17b2e0c99560d20307204494ac50e31b33e50721b4ebae99d9e3577ae7248874,"{""d"":3,""p"":0.01}"
   1000000,       151,         0,    77.3,pymatching,e179a18739201250371ffaae0197d8fa19d26b58dfc2942f9f1c85568645387a,"{""d"":5,""p"":0.001}"
     11363,      1068,         0,    12.5,pymatching,a4dec28934a033215ff1389651a26114ecc22016a6e122008830cf7dd04ba5ad,"{""d"":5,""p"":0.01}"
     61569,      1001,         0,    24.5,pymatching,2fefcc356752482fb4c6d912c228f6d18762f5752796c668b6abeb7775f5de92,"{""d"":5,""p"":0.005}"

并相应的图像保存到plot.png

Example plot

python API实用方法

Sinter的Python模块公开了各种用于绘图或分析QEC数据的实用方法。请参阅sinter API参考

如何使用:Linux命令行

本示例假设您正在使用安装了sinter的Python虚拟环境中的Linux命令行。

选择电路

对于本示例,我们将使用Stim的电路生成功能来生成用于基准测试的电路。我们将创建具有各种物理错误率的旋转表面代码电路,文件名如rotated_d5_p0.001_surface_code.stim

mkdir -p circuits
python -c "

import stim

for p in [0.001, 0.005, 0.01]:
    for d in [3, 5]:
        with open(f'circuits/d={d},p={p},b=X,type=rotated_surface_memory.stim', 'w') as f:
            c = stim.Circuit.generated(
                rounds=d,
                distance=d,
                after_clifford_depolarization=p,
                after_reset_flip_probability=p,
                before_measure_flip_probability=p,
                before_round_data_depolarization=p,
                code_task=f'surface_code:rotated_memory_x')
            print(c, file=f)
"

通常,制作电路文件是最困难的一步,因为它们指定了您从中抽取的问题。您所做的几乎所有工作都通常涉及创建完全符合您需求的精确电路文件。但这是一个示例,所以我们将使用常规表面代码电路。

收集

您可以使用sinter collect命令使用sinter收集每个电路的统计数据。此命令包含指定要收集多少数据、如何进行解码等选项。

processes参数决定使用多少个工作进程。将其设置为auto以将其设置为机器上的CPU数量。

metadata_func参数可用于指定将path转换为与电路相关联的字典或其他JSON对象的自定义Python表达式。如果您将metadata_func设置为auto,则将使用sinter.comma_separated_key_values(path)方法,该方法将解析如folder/a=2,b=test.stim的Stim电路路径,并将其转换为如{'a': 2, 'b': 'test'}的字典。

默认情况下,sinter将收集的统计数据以CSV数据的形式写入stdout。更改此行为的一个特别重要的选项是--save_resume_filepath,它允许命令在数据丢失的情况下中断并重新启动。由--save_resume_filepath指定的文件中已存在的任何数据都将计入请求收集的统计数据量,sinter将向此文件追加新统计数据而不是覆盖它。

sinter collect \
    --processes auto \
    --circuits circuits/*.stim \
    --metadata_func auto \
    --decoders pymatching \
    --max_shots 1_000_000 \
    --max_errors 1000 \
    --save_resume_filepath stats.csv

请注意,如果使用SIGKILL或SIGTEM终止sinter,而不是仅使用SIGINT,那么您可能(尽管不太可能)恰好在与sinter正在写入CSV数据行时将其终止。这将截断数据,您需要手动干预(例如,使用文本编辑器删除部分行)来修复它。

组合

请注意,sinter写入的CSV数据将包含每个案例的多个行,因为sinter首先运行小批量以大致了解错误率,然后再转到更大的批量大小。

您可以使用sinter combine获取每个案例单行的CSV文件。

sinter combine stats.csv
     shots,    errors,  discards, seconds,decoder,strong_id,json_metadata
     58591,      1067,         0,    5.50,pymatching,bb46c8fca4d9fd9d4d27a5039686332ac5e24011a7f2aea5a65f6040445567c0,"{""b"":""X"",""d"":3,""p"":0.005,""type"":""rotated_surface_memory""}"
   1000000,       901,         0,    73.4,pymatching,4c0780830fe1747ab22767b69d1178f803943c83dd4afa6d241acf02e6dfa71f,"{""b"":""X"",""d"":3,""p"":0.001,""type"":""rotated_surface_memory""}"
     16315,      1026,         0,    2.39,pymatching,64d81b177ef1a455644ac3e03f374394cd8ad385ba2ee0ac147b2405107564fc,"{""b"":""X"",""d"":3,""p"":0.01,""type"":""rotated_surface_memory""}"
   1000000,       157,         0,   116.5,pymatching,100855c078af0936d098cecbd8bfb7591c0951ae69527c002c9c5f4c79bde129,"{""b"":""X"",""d"":5,""p"":0.001,""type"":""rotated_surface_memory""}"
     61677,      1005,         0,    21.2,pymatching,6d7b8b312a5460c7fe08119d3c7a040daa25bd34d524611160e4aac6196293fe,"{""b"":""X"",""d"":5,""p"":0.005,""type"":""rotated_surface_memory""}"
     10891,      1021,         0,    7.43,pymatching,477252e968f0f22f64ccb058c0e1e9c77b765f60f74df8b6707de7ec65ed13b7,"{""b"":""X"",""d"":5,""p"":0.01,""type"":""rotated_surface_memory""}"

绘图

您可以使用sinter plot查看已收集的结果。此命令接受一个CSV文件,一个表示如何将统计数据分组为曲线的--group_func参数,一个表示如何选择每个点的X坐标的--x_func参数,以及其他各种参数。每个*_func参数接受一个将作为Python表达式评估的字符串,其中包含各种有用的值,例如一个包含各种点的json元数据的metadata值。还有一个特殊的m值,其中m.keymetadata.get('key', None)的简写。

这是一个sinter plot命令的示例

sinter plot \
    --in stats.csv \
    --group_func "f'''Rotated Surface Code d={m.d}'''" \
    --x_func m.p \
    --xaxis "[log]Physical Error Rate" \
    --fig_size 1024 1024 \
    --out surface_code_figure.png \
    --show

它将保存一个png图像,并打开一个窗口显示一个像这样的图形

Example plot

样本统计的csv格式

Sinter使用逗号分隔值格式将样本保存为表。例如

  shots,errors,discards,seconds,decoder,strong_id,json_metadata
1000000,   837,       0,   36.6,pymatching,9f7e20c54fec45b6aef7491b774dd5c0a3b9a005aa82faf5b9c051d6e40d60a9,"{""d"":3,""p"":0.001}"
  53498,  1099,       0,   6.52,pymatching,3f40432443a99b933fb548b831fb54e7e245d9d73a35c03ea5a2fb2ce270f8c8,"{""d"":3,""p"":0.005}"
  16269,  1023,       0,   3.23,pymatching,17b2e0c99560d20307204494ac50e31b33e50721b4ebae99d9e3577ae7248874,"{""d"":3,""p"":0.01}"
1000000,   151,       0,   77.3,pymatching,e179a18739201250371ffaae0197d8fa19d26b58dfc2942f9f1c85568645387a,"{""d"":5,""p"":0.001}"
  11363,  1068,       0,   12.5,pymatching,a4dec28934a033215ff1389651a26114ecc22016a6e122008830cf7dd04ba5ad,"{""d"":5,""p"":0.01}"
  61569,  1001,       0,   24.5,pymatching,2fefcc356752482fb4c6d912c228f6d18762f5752796c668b6abeb7775f5de92,"{""d"":5,""p"":0.005}"

列包括

  • shots(无符号整数):电路被采样的次数。
  • errors(无符号整数):解码器未能预测任何逻辑可观察量的次数。
  • 丢弃次数 (无符号整数):射击被丢弃的次数,原因是一个后选探测器发射或解码器错误地预测了后选可观察量的值。被丢弃的射击从未计为错误。
  • 秒数 (非负浮点数):模拟和解码这些射击所需的CPU核心秒数。
  • 解码器 (字符串):使用的解码器。
  • strong_id (字符串):从其中采样问题的加密哈希的十六进制表示。哈希数据包括模拟的确切电路、使用的解码器、提供给解码器确切的检测器错误模型、应用的后选规则以及与电路相关的元数据。强ID的目的是使从不同电路或电路的不同版本中意外组合射击变得不可能。
  • json_metadata (JSON):一个自由格式字段,可以存储任何可在 Java Script Object Notation 中表示的值。例如,这可以是一个包含如 "noise_level" 或 "circuit_name" 等有帮助的键的字典。JSON值被序列化为JSON,然后转义,以便可以将其放入CSV数据中(例如,引号被加倍)。
  • custom_counts (JSON[Dict[str, int]]): 可选字段,可以存储一个从字符串键到整数计数的字典,表示为 Java Script Object Notation。计数可以是各种各样的,从每个可观察的错误计数到检测事件计数。通常,任何在合并行时应添加的值都可以在这些计数器中。

注意射击可能分布在多行中。例如,以下数据

  shots,errors,discards,seconds,decoder,strong_id,json_metadata
 500000,   437,       0,   20.5,pymatching,9f7e20c54fec45b6aef7491b774dd5c0a3b9a005aa82faf5b9c051d6e40d60a9,"{""d"":3,""p"":0.001}"
 500000,   400,       0,   16.1,pymatching,9f7e20c54fec45b6aef7491b774dd5c0a3b9a005aa82faf5b9c051d6e40d60a9,"{""d"":3,""p"":0.001}"

具有与以下数据相同的总统计数据

  shots,errors,discards,seconds,decoder,strong_id,json_metadata
1000000,   837,       0,   36.6,pymatching,9f7e20c54fec45b6aef7491b774dd5c0a3b9a005aa82faf5b9c051d6e40d60a9,"{""d"":3,""p"":0.001}"

只是分成两行而不是合并为一行。

项目详细信息


发布历史 发布通知 | RSS源

下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分布

sinter-1.14.0.tar.gz (174.3 kB 查看散列值)

上传时间

由以下机构支持