---
title: "保存收缩序与切片信息"
description: "ArcTNExecutionPlan 的保存内容、JSON 格式，以及加载后的检查、转换和执行方法。"
eyebrow: "数值执行"
---

## 收缩序与相关对象 {#representations}

| 表示 | 保存什么 | 主要用途 |
| --- | --- | --- |
| SSA path | 每一步参与收缩的两个张量编号 | 指定收缩序；本身不含网络或切片集合 |
| arctn\_schedule report | 收缩序、指标和搜索诊断 | 查看搜索结果；保存时可用 ArcTNExecutionPlan 补入网络信息 |
| ArcTNExecutionPlan | 网络的连接关系和维度、SSA 收缩序、切片集合和大小限制 | 保存为文件，加载后检查或执行 |
| ArcTNCompiledContraction | 原生后端的轴变换与矩阵乘法参数，或外部后端的收缩表达式 | 在当前进程中重复执行无切片收缩 |
| Cotengra ContractionTree | 树结构和切片 index | 交给 Quimb/Cotengra 执行 |

`ArcTNExecutionPlan` 不只是收缩序列表：它还保存网络和切片信息。数值数组和已编译的计算内核不在保存内容中。

## 保存与加载 {#lifecycle}

先用 `arctn_plan` 进行收缩序优化，得到 `ArcTNExecutionPlan` 对象，再保存或执行。加载后复用原有收缩序和切片集合，不再次进行收缩序优化；执行后端在调用 `execute` 或 `compile` 时选择。

完整例子见[保存与复用收缩序](/docs/tutorial-reuse#save-load)。

## version 2 JSON 的保存内容 {#schema}

| 字段 | 含义 |
| --- | --- |
| schema / schema\_version | arctn-execution-plan / 2 |
| path\_format | ssa-v1；明确表示路径中的整数是 SSA 张量编号，不是 linear path 的列表位置 |
| network | inputs、output 和 size\_dict；index 标签统一保存为从 0 开始的整数 |
| network\_canon | 根据连接关系、张量顺序、轴顺序和维度生成的字符串，用于比较是否为同一网络 |
| ssa\_path | 已检查每步引用、可从全部输入得到最终结果的路径 |
| sliced.legs | 执行时使用的切片 index 集合；无切片时为空数组 |
| target\_size | 可选的每个 slice 二元收缩结果元素数上限；单张量网络则检查最终输出 |
| metrics / planning / provenance | 紧凑指标、公开调用设置和版本来源 |

Python 调用可以使用字符串等可哈希 index 标签。保存时按首次出现顺序将标签映射为整数，例如 `"a"`、`"b"`、`"c"` 对应 `0`、`1`、`2`；只改变标签的写法，不改变数组顺序、轴顺序或连接关系。这样，JSON 文件不需要依赖原来的 Python 标签对象。内存中新建的 plan 可保留原标签供查看；加载后的 plan 使用文件中的整数标签。

加载 version 2 文件时，Rust 会检查网络、SSA path、切片集合和 `target_size` 是否相符，并根据网络与路径重新计算文件中已有的核心指标。这样可以发现路径引用无效、切片 index 不存在或保存的指标与路径不一致等问题；加载不会重新搜索路径。错误处理的例子见[检查保存的收缩序文件](/docs/validation#plan-example)。`planning` 和 `provenance` 记录搜索设置和版本来源，不参与数值执行正确性的判定。

`target_size` 不是 RSS、VRAM、分配器缓存或后端工作区的上限。version 2 只要指定这个限制，就必须同时保存正整数 `target_size`、对应的对数值 `memory_target_log2_elements`，以及 `memory_constraint_metric="max_intermediate_elements_per_slice"`；加载时 Rust 会根据保存的路径与切片集合重新校验。

## 转换与执行 {#operations}

| 方法 | 是否重新规划 | 限制 |
| --- | --- | --- |
| to\_linear\_path() | 否 | 返回 opt\_einsum 使用的 linear path |
| to\_tree() | 否 | 需要 Cotengra；将路径和切片 index 转为收缩树 |
| execute(arrays, backend=...) | 否 | 按保存的收缩序和切片集合执行 |
| compile(backend=...) | 否 | 只在切片集合为空时可用；返回可在当前进程中复用的编译对象 |

`plan.execute()`、`plan.to_tree()` 和 `plan.compile()` 都不再次进行收缩序优化。`native` 使用 ArcTN 的 Rust CPU 实现；其他显式指定的后端由 opt\_einsum 和相应数组库执行。外部后端的切片当前由 Python 顺序枚举取值组合；native 切片由 Rust/Rayon 执行。

切片集合非空时不能调用 `plan.compile()`，因为 `ArcTNCompiledContraction` 当前不支持切片执行。此时可通过 `plan.execute()` 执行，或用 `plan.to_tree()` 转为 Cotengra 收缩树。

## 兼容性 {#compatibility}

- Python ArcTNExecutionPlan.load() 只接受自包含的 version 2 文件。
- Rust 与 CLI 读取器兼容 version 1 和 version 2；version 1 必须由调用者提供并核对外部网络。
- tnpath --save-path 写 version 2；tnexec 当前仍要求 --net，并核对文件所含网络与传入的网络是否一致。
- 没有 schema 标识的旧格式文件只有显式允许时才读取，不属于默认安全格式。
