ARTICLE · 1002484
PAC 2026 | 优化组决赛赛题说明【题一:张量缩并优化】
01

赛题简介

本赛题聚焦FP64张量缩并的并行加速。参赛队需在大赛指定平台的单CPU(304核、8个MPI进程)平台上,运用C/C++、汇编及Intrinsics等技术对特定规模的张量计算进行性能调优。在确保相对误差小于1e-8的精度底线下,以最终实现的Time值决定成绩。
02

准备说明

(1)按照《PAC决赛算力平台使用手册》进行账户认证,强烈建议初次登陆修改密码。
(2)上传赛题工程代码以及工具包到个人账户目录。赛题工程代码以及工具包下载(密码由组委会单独发放):
https://pan.baidu.com/s/1fRr5duy0FfDECwJaUYc-6w
(3)在用户的工作目录/home/share/user_name,解压并安装工具包:

tar -xzvf XXXXX.tar.gz
找到工具包中的install.sh脚本,执行:

bash install.sh
安装过程以此会提示安装选项,默认参数即可,如果特殊需要可参考:
https://www.hikunpeng.com/developer/hpc/hpckit-download
(4) 在用户的工作目录
/home/share/user_name/workspace,解压赛题1压缩包:

unzip tensor_contraction_3way.zip
03

赛题说明

本版本实现3-张量连续缩并,包含两个测试用例:
testcase1: (s,t,p) × (s,u,q) × (t,u,r) → (p,q,r)
testcase2: (s,p,t) × (t,q,u) × (u,r,s) → (p,q,r)
样例程序实现如下,不得改变数据规模和精度类型;收缩顺序、通信方式以及缩并算法可以修改。

testcase1: (s,t,p) × (s,u,q) × (t,u,r) → (p,q,r)
张量A: (s,t,p) = (4,4000,4000),按p维分布
张量B: (s,u,q) = (4,4000,4000),按q维分布
张量C: (t,u,r) = (4000,4000,4),全局广播
收缩顺序: B×C over u → D(s,q,t,r),然后 D×A over s,t

testcase2: (s,p,t) × (t,q,u) × (u,r,s) → (p,q,r)
张量A: (s,p,t) = (8000,8000,2),按p维分布
张量B: (t,q,u) = (2,4000,4000),按q维分布
张量C: (u,r,s) = (4000,2,8000),全局广播
收缩顺序: B×C over u → E(t,q,r,s),然后 E×A over s,t
不可修改计时范围,计时区间包括 MPI通信+张量缩并计算;文件数据读取和最后多进程数据合并不计入耗时
编译
用GCC编译

source /TOOL_PATH/HPCKit/26.1.RC1/setvars.sh --use-gcc
# 以实际工具包安装路径为准
mpic++ -O2 -march=armv9-a+sme+sve2 -std=c++17 -fopenmp
tensor_contraction_3way_mpi.cpp -o
tensor_contraction_3way_mpi
# 如果要查看DEBUG信息,编译时使用宏 -DDEBUG
用Bisheng编译

source /TOOL_PATH/HPCKit/26.1.RC1/setvars.sh
# 以实际HPCKit安装路径为准
mpic++ -O2 -march=armv9-a+sme+sve2 -std=c++17 -fopenmp
tensor_contraction_3way_mpi.cpp -o
tensor_contraction_3way_mpi
运行
运行前准备
创建rankfile_8x36.txt文件,用于MPI任务绑定

# 要求8个进程绑分别绑到8个NUMA,这里用的是NUMA ID为8~15的NUMA上的CPU核心ID,每个进程可设置36个线程,每个线程对应一个CPU核心
# 跳过每个NUMA节点的前1个和后1个核心(保留中间36个)
rank 0=localhost slot=305-340
rank 1=localhost slot=343-378
rank 2=localhost slot=381-416
rank 3=localhost slot=419-454
rank 4=localhost slot=457-492
rank 5=localhost slot=495-530
rank 6=localhost slot=533-568
rank 7=localhost slot=571-606
检查tensor_data目录下是否有以下输入文件。

A_tc1.bin A_tc2.bin B_tc1.bin B_tc2.bin C_tc1.bin C_tc2.bin
# tc1表示testcase1,tc2表示testcase2;A,B,C对应输入的ABC矩阵
执行命令
本地执行

mpirun -np 8 --rankfile rankfile_8x36.txt --allow-run-as-root -x OMP_NUM_THREADS=36 -x OMP_PLACES=cores -x OMP_PROC_BIND=close ./tensor_contraction_3way_mpi
通过多瑙提交作业
编写run.sh脚本

source /TOOL_PATH/HPCKit/26.1.RC1/setvars.sh --use-gcc;
# 以实际HPCKit安装路径为准
export UCX_TLS=sm,self;
export OMPI_MCA_btl=vader,self;
mpirun -np 8 --rankfile rankfile_8x36.txt -x UCX_TLS -x OMPI_MCA_btl -x OMP_NUM_THREADS=36 -x OMP_PLACES=cores -x OMP_PROC_BIND=close ./tensor_contraction_3way_mpi
dsub命令提交作业

dsub -q q_pacopt -x job -o `pwd`/out_%J.log -e `pwd`/err_%J.log -rpn 8 "sh ./run.sh"
输出示例

Test Case 1: (s,t,p) x (s,u,q) x (t,u,r) -> (p,q,r), shapes: (4,4000,4000) x (4,4000,4000) x (4000,4000,4) -> (4000,4000,4)
Optimization: Reorder layouts for contiguous inner loops
rank 0 time: 20.8991 s
Result written to tensor_data/result_tc1.bin
Test Case 2: (s,p,t) x (t,q,u) x (u,r,s) -> (p,q,r), shapes: (8000,8000,2) x (2,4000,4000) x (4000,2,8000) -> (8000,4000,2)
Optimization: Reorder layouts for contiguous inner loops
rank 0 time: 13.6636 s
Result written to tensor_data/result_tc2.bin
所用时间越短表示性能越好。
结果校验
使用verify_result.cpp做结果校验

clang++ verify_result.cpp -o verify_result # 编译校验程序
./verify_result tensor_data/result_tc1_check.bin tensor_data/result_tc1.bin 4000 4000 4 #检查testcase1
./verify_result tensor_data/result_tc2_check.bin tensor_data/result_tc2.bin 8000 4000 2 #检查testcase2
显示 结果: PASS 即表示检查通过

校验配置:
标准答案: tensor_data/result_tc1.bin
结果: tensor_data/result_tc1_check.bin
维度: p=4000, q=4000, r=4
元素数: 64000000
================================
结果: PASS
误差元素数: 0 / 64000000
最大绝对误差: 0.000000e+00
最大相对误差: 0.000000e+00
容差: 1.000000e-10
Baselines分值:
case1: 20.8991 s
case2: 13.6636 s
04

评分规则

编程语言:C/C++,汇编,intrinsics。
编译器:GCC/毕昇编译器(推荐毕昇编译器)
评分标准:以Time为评分标准,越高越好。成绩计算公式:

参赛队成绩 = 30(基础分)+ 70 ×(所有参赛队最长耗时 - 参赛队优化耗时)/(所有参赛队最长耗时 - 所有参赛队最短耗时)
假设所有参赛队中耗时最长(最慢)为 200s,耗时最短(最快)为 100 s,参赛队伍甲优化后的耗时为 150s,则参赛队伍甲的成绩 = 30 + 70 × (200 - 150) / (200 - 100) = 65 分。
两个case独立计算分值,每个case在该题中分别按照50%计算上机成绩总分值。
决赛上机成绩=题一上机成绩(50%)+题二上机成绩(50%);
决赛成绩=上机成绩(80%)+现场答辩成绩(20%);
最终总决赛成绩=初赛成绩(20%)+决赛成绩(80%)
05

提交作品

(1)最终优化后的源代码、编译文件、out_*.log等文件,存储在大赛指定目录/user_name/commit_result/1目录中
(2)全部代码和编译文件,以及编译环境和命令说明文件一份(Markdown格式:comm.md)
(3)技术报告PPT(官网资料站下载模板),参加线下决赛现场答辩。