ArcTN Rust原生张量网络收缩序优化

代码仓库

ArcTN 是用 Rust 编写的张量网络收缩库,提供收缩序优化、切片和数值执行,并通过 Python 接口接入 Quimb、opt_einsum 等工具。ArcTN 接收张量网络,不直接将量子线路任务转换为张量网络;量子线路对应的网络由 Quimb 等前端或用户自行构建。

本页目录

许可证与使用范围

ArcTN 公司有权授权的源码适用 Arclight 非商业源码可用许可证 1.0,禁止商用和闭源集成。这不是 OSI 认可的开源许可证;商业使用需另行取得授权。

完整许可说明见 ArcTN 代码仓库的许可证章节。商业授权及许可咨询:quill@arclightquantum.com。

张量网络与二叉收缩树

张量网络描述张量之间通过 index 连接的关系。采用两两收缩时,计算过程可以表示为一棵二叉收缩树:叶节点是输入张量,内部节点是一次收缩,根节点是最终结果。

同一个网络可以对应不同的收缩树。下面以四个矩阵的乘积 ABCDABCD 为例:两种顺序得到相同的 2×22\times2 结果,但计算量不同。

张量之间的连接

A:2×8 · B:8×2
C:2×8 · D:8×2

收缩树 1

(AB)(CD)

32 + 32 + 8 = 72 次

收缩树 2

((AB)C)D

32 + 32 + 32 = 96 次

图中统计普通矩阵乘法的标量乘法次数。

收缩树表示张量的组合方式,收缩路径列出具体的计算步骤。例如,第一棵树可以先算 ABAB,也可以先算 CDCD,最后合并两者。收缩序优化要做的,就是在不同收缩树之间搜索,根据计算量、读写量等目标选择代价更低的收缩序。Light / Heavy 采用启发式搜索,不保证全局最优。详见张量网络与收缩树。

收缩序优化与执行

用 inputs、output 和 size_dict 描述张量网络,并指定优化目标(objective),即可进行收缩序优化。

当中间张量太大、占用内存过多时,可以设置 target_size,通过切片把一次大收缩拆成多次较小的收缩。target_size 限制每个切片内单个收缩结果的最大元素数:例如,100 万个 float64 元素的数据占用约 8 MB。它不限制程序的总内存,输入数组和计算时的临时空间仍需另计。

ArcTN 既可以只做规划,也可以完成数值计算:路径和切片方案可保存为 ArcTNExecutionPlan,作为规划与执行之间的中间表示(IR);提供数组后,arctn_contract 可直接完成规划与执行。已有 Quimb 网络也可以通过 ArcTNOptimizer 使用 ArcTN 的规划结果。

量子线路应用推荐使用 Quimb 前端:在 Quimb 中构建电路,计算振幅或期望值时传入 optimize=ArcTNOptimizer(...),即可让 ArcTN 优化收缩序,无需手动整理 inputs、output 和 size_dict。Quimb 负责把任务转换为张量网络,并可在搜索前化简;数值收缩由 Quimb / Cotengra 完成。

VQE、QAOA 与量子机器学习

在这类算法中,电路前端根据参数化电路构建振幅、概率或期望值对应的张量网络,ArcTN 为该网络优化收缩序,外层经典优化器根据计算结果更新电路参数。使用 Quimb 时,可通过 optimize=ArcTNOptimizer(...) 接入,数值收缩由 Quimb / Cotengra 完成;也可以把网络与数组直接交给 arctn_contract 执行。

参数更新后,如果张量顺序、index 对应关系、维度和输出顺序不变,可以复用已有收缩序。ArcTN 不是完整的量子机器学习训练框架,损失函数、参数梯度和训练循环由应用或所用框架处理。具体调用见 VQE 与 QAOA 示例,重复执行见参数变化时复用收缩序。

量子计算任务
振幅 · 期望值 · 概率与采样

电路定义:Qiskit 或 Quimb

模拟方法
一般张量网络收缩构造目标物理量对应的网络,再优化收缩顺序。

其他张量网络方法:MPS 状态更新与可选截断;PEPS 更新与收缩算法。

其他方法:稠密状态向量/密度矩阵、稳定子方法、Pauli 传播。

网络输入
Quimb TensorNetwork 或用户构造的张量网络

inputs · output · size_dict

arrays (用于执行)

Qiskit 电路需要转换;兼容的 OpenQASM 2 电路可由 Quimb 导入。

收缩序优化
ArcTN
Light / Heavy 路径搜索可选 fixed / dynamic 切片

收缩路径 + 切片索引

数值执行
由 ArcTN 执行

arctn_contract(…)

或保存收缩序与切片信息: ArcTNExecutionPlan (IR)

Native CPU 执行器(Rust)

或 opt_einsum + NumPy / CuPy / Torch / JAX

通过 Quimb 执行

ArcTNOptimizer.search()

↓ cotengra.ContractionTree

Quimb / Cotengra 执行 → autoray

CPU 或 GPU 数组后端

收缩结果:标量或张量

ArcTN 处理张量收缩问题,也可处理 MPS/PEPS 算法中的收缩子问题。状态更新、截断、采样与噪声模型由调用方管理。

从量子线路到收缩结果

两个量子比特从 ∣00⟩|00\rangle 出发,依次施加 H、Ry(π/3)R_y(\pi/3)、CNOT 和 Ry(π/4)R_y(\pi/4)。我们计算最后测到 11 的概率:先求振幅 A11=⟨11∣U∣00⟩A_{11}=\langle11|U|00\rangle,再计算 P(11)=∣A11∣2P(11)=|A_{11}|^2。这里的基顺序为 ∣q0q1⟩|q_0q_1\rangle。

逐步查看收缩

先把初态、量子门和末端的 ⟨1∣\langle1| 写成张量,再交给 ArcTN 搜索收缩路径。下图逐一对应电路中的门与张量;点击“下一步”,可查看已生成的收缩序和各步中间结果。

“运行 NumPy”可沿这条路径计算振幅与概率,并与 ArcTN 的结果、直接收缩和独立状态向量计算比较。

量子线路

两量子比特从零态开始,先执行 H 和 Ry,再执行 CNOT,最后对 q0 执行 Ry。q0 |0⟩⟨1|q1 |0⟩⟨1|HRy(π/3)CNOTRy(π/4)

时间从左向右。CNOT 的控制位是 q0,目标位是 q1;末端 ⟨1| 指定要计算的输出。

对应的张量网络

八个张量通过 a 到 g 七个 index 相连。T4 是四阶 CNOT 张量;初态和末端 bra 各是一阶张量。abcdefgT0T1T2T3T5T6T7T4

每条连线是一个共享 index,取值为 0 或 1。所有 index 都参与求和,结果是一个振幅。

量子门怎样变成张量?
电路中的对象张量index 与形状
两个初态 |0⟩T0、T1,向量 [1, 0][a]、[b],各 2 个元素
H、Ry(π/3)T2、T3,单比特门矩阵[c,a]、[d,b],各 2 × 2
CNOTT4,两个输出轴和两个输入轴[e,f,c,d],2 × 2 × 2 × 2
Ry(π/4)T5,单比特门矩阵[g,e],2 × 2
指定输出 11 的两个 ⟨1|T6、T7,对偶向量 [0, 1][g]、[f],各 2 个元素

门张量按“输出轴、输入轴”排列。CNOT 的 4 × 4 矩阵通过 reshape(2, 2, 2, 2) 写成 [e,f,c,d] 四个轴,不改变元素顺序。把末端向量也接入后,网络没有开放的 index,因此传给 ArcTN 的 output=[]。

本例用 NumPy 构造这些张量。ArcTN 从 inputs、output 和 size_dict 开始规划,不解析电路图或量子门。

ArcTN 的收缩路径 Light · seed 0
0 / 7

SSA path [(4, 7), (0, 2), (8, 9), (1, 3), (5, 6), (10, 11), (12, 13)]

  1. (4, 7) → 8待展示
  2. (0, 2) → 9待展示
  3. (8, 9) → 10待展示
  4. (1, 3) → 11待展示
  5. (5, 6) → 12待展示
  6. (10, 11) → 13待展示
  7. (12, 13) → 14待展示

T0…T7 是电路对应的输入张量;T8 起为每步新产生的结果。树的左右位置只用于排版,编号与实际路径一致。

二叉收缩树

叶节点是初态、量子门或末端 bra;内部节点表示一次两两收缩。

输入已就绪点击“下一步”查看输入张量如何依次合并。所有 index 求和后得到标量振幅。

当前保留:T0 [a]T1 [b]T2 [c,a]T3 [d,b]T4 [e,f,c,d]T5 [g,e]T6 [g]T7 [f]

T0[a]

2 · float64
1
0

T1[b]

2 · float64
1
0

T2[c,a]

2 × 2 · float64
0.7071070.707107
0.707107-0.707107

T3[d,b]

2 × 2 · float64
0.866025-0.5
0.50.866025

T4[e,f,c,d]

2 × 2 × 2 × 2 · float64
1000
0100
0001
0010
表格行:[e,f];列:[c,d]

T5[g,e]

2 × 2 · float64
0.92388-0.382683
0.3826830.92388

T6[g]

2 · float64
0
1

T7[f]

2 · float64
0
1

这里按输入轴展示元素,CNOT 的 4 × 4 表格将 [e,f] 合为行、[c,d] 合为列。点击“下一步”后,矩阵按该步的求和 index 重新排列和分组。

ArcTN 最终振幅 A₁₁

0.701057
已保存的 native 执行结果

测到 11 的概率 P(11) = |A₁₁|²

0.491481
概率由振幅计算,不是测量采样频率

完整路径: 42 FLOPs · 最大收缩结果: 8 个元素

路径与指标
text
{
  "ssa_path": [[4, 7], [0, 2], [8, 9], [1, 3], [5, 6], [10, 11], [12, 13]],
  "linear_path": [[4, 7], [0, 2], [4, 5], [0, 1], [0, 1], [0, 1], [0, 1]],
  "metrics": {
    "log10_flops": 1.6232492903979006,
    "log2_max_size": 3,
    "log2_max_contraction_size": 4.700439718141093,
    "log2_total_size": 4.392317422778761,
    "log2_read_write": 6.266786540694901,
    "log2_peak_size": 5.459431618637297,
    "log2_n_slices": null,
    "sliced_log10_flops_total": null,
    "sliced_log2_max_size": null,
    "sliced_log2_max_contraction_size": null,
    "sliced_log2_peak_size": null,
    "max_intermediate_log2_elements_per_slice": null
  }
}

表格显示最多 6 位小数。逐步演示按原生执行器的轴顺序展开矩阵:左矩阵的列与右矩阵的行对应求和 index,其余 index 在乘法后还原为结果张量的轴。

用 NumPy 执行完整路径

沿 ArcTN 已返回的路径执行,不重新寻路。首次运行会从 jsDelivr 加载 Pyodide 和 NumPy;计算在浏览器中完成。

尚未运行。点击“运行 NumPy”在浏览器中计算。

执行步骤(伪代码)
text
tensors = 按 SSA 编号保存输入数组(arrays)
for left, right, out, axis_orders, matrix_shapes, output_shape in contractions:
    A = 重排轴并合并为矩阵(tensors[left], axis_orders.left, matrix_shapes.left)
    B = 重排轴并合并为矩阵(tensors[right], axis_orders.right, matrix_shapes.right)
    tensors[out] = reshape(A @ B, output_shape)
    del tensors[left], tensors[right]
amplitude = 取最终张量(tensors)
probability = abs(amplitude) ** 2
核对振幅(amplitude, ArcTN结果, 直接收缩结果, 状态向量结果)
return amplitude, probability

本例使用默认目标 FLOPs + 64 × read/write。步骤按钮展示已保存的结果,不重新寻路;“运行 NumPy”执行这条收缩路径。FLOPs 在本例中按标量乘法次数计数。

数值执行与第三方接入

直接执行收缩

提供数值数组后,arctn_contract 可在一次调用中完成规划、可选切片和执行。默认使用 ArcTN 的原生 CPU 执行器,也可以指定外部数组后端。return_info=True 同时返回规划和执行报告。

在 Quimb 中使用

向 Quimb 的 optimize= 传入 ArcTNOptimizer,即可使用 ArcTN 搜索路径。ArcTNOptimizer.search() 返回包含路径和切片 index 的 ContractionTree,后续数值收缩由 Quimb / Cotengra 执行。

保存与复用收缩序

同一网络结构和维度下,数组值变化时无需重新寻路。用 arctn_plan 得到收缩序和切片信息,保存后可用于后续收缩。

核心能力

能力 实现方式 相关说明
路径生成 贪心、随机贪心、动态规划与递归超图二分 寻路算法
路径改进 子树重构、模拟退火、副本交换与固定叶序动态规划 退火与副本交换、子树重构
自动收缩序优化 Light / Heavy 预设,安排路径生成与改进 方法组合调度
切片 Fixed 固定路径,Dynamic 允许局部调整路径 切片
数值执行 原生 CPU 执行器,或指定 opt_einsum 数组后端 执行后端
并行与分布式 Rayon 单机并行,以及 tnmpi 分布式切片执行 并行设置

功能范围