MPI 执行
读取已有收缩序和切片,在多个 MPI 进程间分配计算并合并结果。
本页目录
按切片分配计算
tnmpi 读取已保存的收缩序和切片集合,将不同切片分给不同 MPI 进程。所有切片使用同一条收缩路径,各进程先累加自己的部分结果,再通过 MPI 的 Allreduce 将各进程的结果逐元素相加,让每个进程都得到完整结果。
收缩序优化与切片选择在执行前完成,可使用 Light、Heavy 或独立算法。各 MPI 进程沿保存的路径执行分配到的切片,在本地完成每片的矩阵计算,并保存完整输入张量和完整输出。
保存收缩序与切片
用 arctn_plan 生成收缩序文件:
from arctn import arctn_plan
plan = arctn_plan(
inputs, output, size_dict,
preset="heavy", target_size=1048576,
)
plan.save("plan.json")
文件保存网络结构、SSA 路径和切片 index,不保存数组数值。MPI 执行使用其中的最终路径和切片,不受生成时采用 fixed 或 dynamic 模式的影响。切片集合为空时,只有一个完整网络任务。
也可以用 tnpath 的 --save-path 保存独立算法的结果。第 2 版文件包含网络,无需再传 --net;第 1 版文件需要额外提供对应的网络 JSON。
构建与运行
安装系统 MPI 后构建执行程序,见安装说明。
cargo build --release --locked --features mpi --bin tnmpi
mpirun -n 4 target/release/tnmpi \
--load-path plan.json --data tensors.bin
--dtype 选择输入和收缩计算的数据类型,默认 f64:
--dtype |
每个元素的表示 | 每个元素的字节数 |
|---|---|---|
f32 |
32 位实数 | 4 |
f64 |
64 位实数 | 8 |
complex64 |
实部和虚部各为一个 f32 |
8 |
complex128 |
实部和虚部各为一个 f64 |
16 |
tensors.bin 按输入张量顺序连续存放数组,各数组使用行优先、小端格式,不含文件头。复数的每个元素先存实部,再存虚部;所有输入必须使用与 --dtype 一致的数据类型。complex128 表示总共 128 位的复数,不是 128 位实数。例如:
mpirun -n 4 target/release/tnmpi \
--load-path plan.json --data tensors-complex128.bin --dtype complex128
各进程必须能访问相同数据。未指定 --data 时,会按 --seed 生成所选类型的相同演示数组;这个 seed 不参与收缩序优化。最终 Allreduce 使用与所选类型对应的 MPI 数据类型逐元素求和。
执行后,编号为 0 的 MPI 进程(rank 0)输出 JSON 摘要,包括进程数、切片数、单片路径指标和时间:
load_wall_seconds_max:各进程读取、校验、广播收缩序与准备输入所用时间的最大值。execution_wall_seconds_max:各进程执行时间的最大值,包括局部切片计算和最终 Allreduce,不包括输入准备或数值对照。
复用同一份收缩序文件和输入,就能比较不同进程数下的执行。若切片数小于进程数,多出的进程没有切片可算,但仍参与结果合并。
结果核对
mpirun -n 2 target/release/tnmpi \
--load-path plan.json --data tensors.bin --check
--check 在 rank 0 用单进程切片收缩核对结果。输出超过 个元素或切片超过 个时跳过对照,并在摘要中标明。浮点求和顺序可能随进程数和 MPI 实现变化,因此不同运行的结果不保证逐位相同。
target_size 限制每片产生的单个中间张量元素数,不是进程 RSS 上限。输入、最终输出和执行临时空间仍需各进程容纳,增加进程数不会使这些内存自动按比例缩小。
线程与作业设置
每个 MPI 进程的切片循环顺序执行。Rayon 默认每进程 1 个线程,可通过 RAYON_NUM_THREADS 设置。启用 mt feature 后,可通过 MATMUL_NUM_THREADS 设置进程内矩阵乘法的线程数。
CPU 绑定和作业时间上限由 MPI 启动器或作业调度器管理。