---
title: "Compiled contraction"
description: "把固定网络与 SSA path 的数据无关执行几何编译一次，再对多组数值数组重复执行。"
eyebrow: "切片与执行"
---

## compile once, execute many {#compile-once}

`compile` 根据固定网络和 SSA path，预先计算每步的求和轴、轴排列和矩阵乘法形状。后续执行检查数组 shape，并复用这些信息。

编译对象不保存输入数值，也不重新运行寻路。它适合网络结构、维度和 SSA path 不变，而数组值反复变化的场景。

## Rust CompiledContraction 的保存内容 {#native-plan}

| 编译期内容 | 执行期行为 |
| --- | --- |
| 输入 trace / diagonal 操作序列 | 对当前输入数组执行相同 unary preprocessing |
| 每步需要先求和的轴 | 按预计算轴号消去独占腿 |
| A/B permutations | 重排到 batch/free/contraction 布局 |
| batch、m、k、n 和结果 shape | 调用经过边界检查的 batched GEMM |
| 最终求和轴与 output permutation | 恢复声明的输出轴顺序 |
| log10\_flops、log2\_peak\_size | 作为编译计划的结构统计 |

每次 `execute` 仍检查输入数量、shape 和 DenseTensor layout。预编译减少的是重复推导几何的工作，不会取消输入验证。

```text
CompiledContraction::compile(net: &TensorNetwork, path: &SsaPath)
```

| 参数 | 类型 | 说明 |
| --- | --- | --- |
| net | &TensorNetwork | 固定的网络结构和维度。 |
| path | &SsaPath | 明确使用 SSA 坐标的完整路径。 |

**返回：** Result\<CompiledContraction, String\>

## Python 复用对象 {#python-usage}

```python
from arctn import ArcTNCompiledContraction

compiled = ArcTNCompiledContraction.compile(
    inputs, output, size_dict,
    ssa_path=ssa_path,
    backend="numpy",
)
y0 = compiled.execute(arrays0)
y1 = compiled.execute(arrays1)
print(compiled.stats())
```

| backend | compile 保存的对象 | execute |
| --- | --- | --- |
| native | Rust CompiledContraction | 调用 Rust CPU executor |
| 任意显式非 native 名称 | 一个固定 opt\_einsum contract\_expression | 把同一 backend 名交给表达式 |

> [!WARNING]
> **路径格式必须显式**
>
> `ssa_path=` 必须是 SSA 格式，不是 opt\_einsum 的 recycled linear path。两种格式都是整数对列表，但整数所引用的坐标系不同。

## 生命周期与不支持项 {#lifecycle}

| 对象 | 用途 | 是否等同于 compiled contraction |
| --- | --- | --- |
| ArcTNCompiledContraction | 当前进程重复执行固定网络和 SSA path | 是 |
| ArcTNExecutionPlan | 跨进程保存、验证和重放完整计划 | 否 |
| tnpath execution-plan v2 JSON | 跨进程交给 tnexec 严格复验并重放 | 否 |
| PathCache entry | 相同输入和 planner config 下避免重新寻路 | 否 |

- compiled object 不是跨 ArcTN build 或版本的序列化缓存。
- 当前 Python ArcTNCompiledContraction 不封装 sliced legs；已保存的切片计划使用 ArcTNExecutionPlan.execute() 或 to\_tree()。
- Rust `execute_stripped` 在每个 GEMM 后，当最大幅值为正且有限时按该幅值归一化，并单独累计十进制 exponent；它用于数值尺度控制，不是截断或近似。
- 改变网络结构、维度或 SSA path 后必须重新 compile。
