ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

CANN ops-math 中 Pdist 算子迭代 3 验收报告深度解读:性能优化、双 API 覆盖与 97 用例全量回归

CANN ops-math 中 Pdist 算子迭代 3 验收报告深度解读:性能优化、双 API 覆盖与 97 用例全量回归 CANN ops-math 中 Pdist 算子迭代 3 验收报告深度解读性能优化、双 API 覆盖与 97 用例全量回归【免费下载链接】ops-math本项目是CANN提供的数学类基础计算算子库实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-math导读本文基于 CANN ops-math 仓库中 Pdist 算子迭代 3 验收报告完整解读 Pdistp-范数成对距离算子第三轮迭代的验收结果13 项优化变更向量化热点路径、动态 UB 预算、防溢出加固、Forward API 扩展、97 条用例在 Real NPU 模式下 100% 通过、精度余量远超社区标准。阅读本文后你将掌握 Pdist 算子的功能语义、双段式 ACLNN 接口调用方式、tilingKey 三分支计算路径、本轮优化背后的源码级原理以及一套可复用的算子验收方法与 MERE/MARE 精度判定标准。一、Pdist 算子是什么功能语义与原型设计1.1 功能说明与计算公式Pdist 算子计算输入二维 tensor 各行之间的 p-范数成对距离等价于 PyTorch 的torch.nn.functional.pdist见 README.md。输入为形状(N, M)的二维 tensor输出为形状(N*(N-1)/2,)的一维 tensor按上三角行优先顺序排列。计算公式按 p 值分为三种情形与 aclnnPdist.md 一致$$ \text{dist}(i, j) \begin{cases} \left( \sum_{k0}^{M-1} |x_{ik} - x_{jk}|^p \right)^{1/p} 0 p \infty \ \sum_{k0}^{M-1} \mathbb{1}(x_{ik} \neq x_{jk}) p 0 \ \max_{k0}^{M-1} |x_{ik} - x_{jk}| p \infty \end{cases} $$即0 p ∞为闵可夫斯基距离Minkowskip0为汉明距离Hamming不等元素计数p∞为切比雪夫距离Chebyshev最大绝对差。输出数量为 C(N,2) N·(N-1)/2 个元素。1.2 算子原型与约束参数名类别描述数据类型数据格式x输入张量二维输入 tensor形状 (N, M)N ≥ 2, M ≥ 1FLOAT16、FLOAT32NDp属性距离参数p ≥ 0含 inf。可选默认 2.0FLOAT-y输出张量一维输出形状 (N*(N-1)/2,)与 x 一致ND约束说明输入 x 必须为二维 tensor 且 dim(0) ≥ 2输出 y 的数据类型必须与 x 一致p 取值范围为 [0, ∞]N 上限为 65535computeNum使用 uint64_t 且新增MAX_ROWS65535校验N 过大时输出规模超出实际内存限制。产品支持方面README 声明支持 Atlas A2 训练/推理系列产品与 Atlas A3 训练/推理系列产品接口文档进一步明确 Ascend 950PR/Ascend 950DT、Atlas 200I/500 A2 推理产品、Atlas 推理系列产品、Atlas 训练系列产品均不支持。算子注册代码中AICore().AddConfig(ascend910b)与AddConfig(ascend910_93)见 pdist_def.cpp与报告测试环境 Ascend910B (DAV_2201) 相互印证。1.3 双 API 设计aclnnPdist 与 aclnnPdistForward迭代 3 的关键验收内容之一就是Forward API 扩展。两个接口功能一致区别仅在于 p 参数的传入方式接口p 参数类型说明aclnnPdistdouble p标量直接传入见 aclnnPdist.mdaclnnPdistForwardconst aclScalar *p通过aclCreateScalar创建 aclScalar 传入见 aclnnPdistForward.md两个接口均采用 CANN 算子的两段式调用范式先调用aclnnPdistGetWorkspaceSize/aclnnPdistForwardGetWorkspaceSize获取 workspace 大小与执行器再调用aclnnPdist/aclnnPdistForward执行计算。第一段接口完成入参校验错误码约定如下返回值错误码描述ACLNN_ERR_PARAM_NULLPTR161001self、p、out 存在空指针ACLNN_ERR_PARAM_INVALID161002self 的数据类型不在支持范围之内ACLNN_ERR_PARAM_INVALID161002self 不是二维 tensor 或 N2ACLNN_ERR_PARAM_INVALID161002p 0ACLNN_ERR_PARAM_INVALID161002out 的 shape 与 N*(N-1)/2 不匹配二、迭代 3 验收全景97 用例全量通过2.1 基本信息与验收状态字段值算子名称PdistACLNN 接口aclnnPdist / aclnnPdistForward迭代编号3含性能优化 Forward API 扩展验收日期2026-05-13测试方式C 原生测试Real NPU Mock CPU Golden测试文件test_aclnn_pdist.cpp运行脚本run.sh验收状态通过。关键指标为总用例 97aclnnPdist 85 aclnnPdistForward 12通过 97失败 0通过率 100%。2.2 多维度用例分布按 API 分布aclnnPdist 85/85100%aclnnPdistForward 12/12100%。按级别分布L0 门槛用例 8/8L1 功能/精度用例 77/77Forward API 用例 12/12。按 dtype 分布float32 63/63float16 34/34覆盖报告中的核心验收标准全 dtype 用例通过。按 p 值分支分布——这是与算子内部实现直接对应的关键维度p 值分支用例数通过数p0不等计数tilingKey01818p0.5通用路径tilingKey177p1曼哈顿距离tilingKey11212p2欧氏距离tilingKey13030p3通用路径tilingKey166p10通用路径tilingKey144pinfReduceMaxtilingKey21717按场景分布核心功能直通L08、p 值分支覆盖 14、dtype×p 全交叉 12、形状边界 7N2/M1 最小、N2/M8、N3/M1、N3/M4、N5/M16、多核切分 16N20 共 190 对、N50 共 1225 对、UB 分块大 M 16M256/1024/2048、精度敏感 16相同行、全零、全相同、负值、混合、fp16 边界、极小值、宽范围、大数值、最小形状×p 组合 6、Forward API 覆盖 12。2.3 精度验证MERE/MARE 社区标准验收采用 CANN 社区标准的**平均相对误差MEREMean Relative Error与最大相对误差MAREMax Relative Error**判定dtypeMERE ThresholdMARE Thresholdfloat322^-13 1.22e-0410 × 2^-13 1.22e-03float162^-10 9.77e-0410 × 2^-10 9.77e-03Real NPU 代表性精度统计测试代码中的精度比较逻辑可参见 test_aclnn_pdist.cpp其中CompareResults对 NaN 对按 PyTorch 语义跳过、对 Inf 对要求符号一致mare_threshold 10.0 * thresholddtype场景最大MERE最大MARE阈值判定float32L1_multicore_N50_M32_pinf (1225 elems)1.91e-075.01e-061.22e-04通过float32L1_veryLargeM_N5_M2048_p2 (10 elems)1.43e-073.86e-071.22e-04通过float32L1_largeN_N100_M16_p2 (4950 elems)5.45e-086.74e-071.22e-04通过float32Fwd_multicore_N50_M32_p2 (1225 elems)5.13e-082.96e-071.22e-04通过float32Fwd_largeM_N10_M1024_p2 (45 elems)8.10e-083.08e-071.22e-04通过float16L1_multicore_N50_M32_p2 (1225 elems)1.86e-044.81e-049.77e-04通过float16L1_largeM_N10_M1024_p2 (45 elems)2.13e-043.91e-049.77e-04通过所有用例的 MERE 与 MARE 均远低于阈值精度余量充足约 24 个数量级。2.4 测试执行环境项目值OSLinux 5.10.0-60.139.0.166.oe2203.aarch64CANNcann-9.0.0-beta.2芯片Ascend910B (DAV_2201)编译器gstdc17, -O2测试模式Real (NPU)三、迭代 3 优化变更源码级解读13 项改动逐一拆解本轮验收的核心亮点是 13 项优化变更全部在性能优化后完成全量回归且无退化。以下结合源码逐项拆解。3.1 热点路径向量化3 项均在 op_kernel/pdist.hHamming 距离向量化p0 路径由标量循环改为CompareScalar Select ReduceSum全向量路径。对应源码 pdist.h 中tilingKey_ 0分支先CompareScalar(cmpLocal, src1, 0.0f, CMPMODE::NE, ...)对差值做不等比较生成 mask再Duplicate(src2, 1.0f, ...)填充 1.0Select按 mask 选择 1.0 或 0.0最后ReduceSum求和得到不等元素计数。ApplyInvP 向量化对求和结果施加 1/p 次幂时由标量 Ln/Exp 循环改为CompareScalar(mask) Select 向量 Ln/Muls/Exp。源码 pdist.h 中先以CompareScalar(..., CMPMODE::GT, ...)生成大于 0掩码Select将非正值替换为 1.0 以避免 Ln(0) 异常再按 p 值选择 Sqrtp2、Ln→Muls(invP)→Exp通用路径最后再次Select将原非正值恢复为 0.0——这保证了全零距离行相同行的输出严格为 0与精度敏感用例中的相同行/全零场景对应。WriteOutput fp16 向量化fp16 输出路径由逐元素SetValue循环改为单条 Cast 指令。见 pdist.hCast(outFp16, outLocal, RoundMode::CAST_RINT, 8)一次完成 float→half 转换后DataCopyPad写出。3.2 累加去同步与 workBuf 动态化累加去同步ReduceSum结果改为用scalar 寄存器累加每 k 仅 1 次SetValue。见 pdist.hProcessBlock中通过tempLocal.GetValue(0)同步取回 chunk 归约结果在 scalar 层累加accum chunkValtilingKey2 时取chunkVal accum的最大值每处理完一整行才执行一次outLocal.SetValue(k, accum)显著减少 UB 与 scalar 间的同步次数。ReduceSum workBuf 动态化硬编码 256 floats 改为GetReduceSumMaxMinTmpSize动态计算。Host 侧 pdist_tiling.cpp 的ComputeReduceBufSize同时查询 ReduceSum 与 ReduceMax 的最小临时尺寸并取较大者、按 32 字节对齐Kernel 侧pipe.InitBuffer(workBuf, reduceBufSize_ PDIST_SUM_TENSOR_SIZE * sizeof(float))pdist.h据此动态分配使 UB 预算随分块大小自适应而非固定浪费。3.3 健壮性加固4 项computeNum 防溢出uint32_t → uint64_t新增MAX_ROWS65535校验。常量定义于 pdist_constants.hPDIST_MAX_SUPPORTED_ROWS 65535Host 侧 pdist_tiling.cpp 在解析输入时校验computeNum在 Tiling 中按static_castuint64_t(rows) * (rows - 1) / 2计算pdist_tiling.cppKernel 侧PdistTilingData::computeNum亦为 uint64_t见 pdist_tiling_data.h。attr p 语义修正REQUIRED → OPTIONAL匹配默认值 2.0 语义。见 pdist_def.cppthis-Attr(p).AttrType(OPTIONAL).Float(2.0f);与 README可选默认 2.0及 Tiling 中pValue 2.0f的兜底逻辑pdist_tiling.cpp闭环一致——attrP-GetFloat(0)返回空指针时使用默认 2.0。UB 预算防下溢ComputeUbBudget新增ubSize ≤ reservedBytes校验。见 pdist_tiling.cpp先按 reduceBuf 两段 SUM_TENSORfp16 再叠加 fp16 缓冲计算 reservedBytes若 UB 总量不足则直接报错返回避免出现ubTensorEachLoop 0的除零/下溢。dead fields 清理删除numEachCore / numEachLoop两个无用字段PdistTilingData结构保持精简见 pdist_tiling_data.h。3.4 多核切分预计算与核数收敛多核切分预计算由 Host 预算numBlockEachCore等切分参数Kernel 侧零除法。见 pdist_tiling.cpp 的ComputeCoreSplit按每块 8 个输出元素PDIST_DATA_EACH_BLOCK 8将 computeNum 均匀切分到各核剩余部分拆分为完整块lastNumsBlocks与不完整块lastNumsNoneFullBlock。Kernel 侧 pdist.h 的Process()完全基于这些预算值循环无任何运行时除法。核数收敛usedCores min(cores, (computeNum7)/8)。当输出对数不足时收敛实际使用核数避免空核空转neededCores至少为 1pdist_tiling.cpp。共享常量头DATA_EACH_BLOCK / SUM_TENSOR_SIZE / MAX_ROWS统一收敛到 pdist_constants.hHost 与 Kernel 共用消除魔法数字漂移。3.5 Forward API 支持修正 aclnn_pdist_forward.h 的 include 路径并新增 ST 用例覆盖12 条使aclnnPdistForward与aclnnPdist达到同等验收标准。接口层入口可参见 pdist.cppl0op::Pdist通过INFER_SHAPE推导输出形状、ADD_TO_LAUNCHER_LIST_AICORE注册到 AICore 执行器。四、Kernel 三分支计算路径tilingKey 的源码映射验收报告中按 p 值分支分布的 tilingKey0/1/2与算子实现一一对应。Host 侧 pdist_tiling.cpp 依据 p 值决定 tilingKeypValue 0.0f→tilingKey0Hamming 不等计数CompareScalar(NE)SelectReduceSumstd::isinf(pValue)→tilingKey2Chebyshev 切比雪夫AbsReduceMax见 pdist.h其余 →tilingKey1通用闵可夫斯基路径其中 p1 为曼哈顿仅Abs后直接ReduceSum、p2 为欧氏AbsMul平方 ReduceSum、其余 p 走Abs → Ln → Muls(p) → Exp → ReduceSumpdist.h。值得注意的工程细节是 p2 与 p1 的专用快速路径被显式特判避免通用 Ln/Exp 幂运算的开销与精度损失——这正是报告p 值分支覆盖 14 用例p in {0, 0.5, 1, 2, 3, 10, inf} × fp16/fp32要验证的。此外行列索引反解使用GetIJFromIndexpdist.h将线性输出下标 idx 映射回 (rowI, rowJ)采用整数牛顿迭代求解三角形序号反函数全程无浮点除法是kernel 零除法优化的一部分。五、迭代 3 验收标准达成情况与结论验收标准达成状态说明全 dtype 用例通过通过float32: 63/63, float16: 34/34边界用例通过通过最小形状(N2,M1)、大N(N100)、大M(M2048)、fp16 边界值双 API 覆盖通过aclnnPdist: 85/85, aclnnPdistForward: 12/12累计通过率 100%通过97/97 100%无回归性能优化无回归通过向量化/去同步/动态 workBuf 等优化后全量回归通过结论迭代 3 验收通过。全部 97 个用例aclnnPdist: 85 aclnnPdistForward: 12在 Real NPU 模式下均 100% 通过、无回归本轮 13 项优化变更向量化热点路径、动态 UB 预算、防溢出加固、Forward API 扩展等经全量回归验证精度远优于社区标准阈值。六、延伸阅读如何在仓库中复现与验证Pdist 算子位于 experimental/math/pdist 目录完整目录结构见 README.md可按以下线索深入接口调用示例test_aclnn_pdist.cppp 以 float 传入与 test_aclnn_pdist_forward.cppp 以 aclScalar 传入二者均为可直接编译运行的两段式调用完整样例验收测试tests/st/test_aclnn_pdist.cpp97 条用例源码内含 CPU Golden 参考实现ComputeGoldenPdist与 MERE/MARE 比较器及 tests/st/run.sh运行脚本单元测试tests/ut/op_hostTiling InferShape UT 14 cases、tests/ut/op_apiACLNN 接口 UT 9 cases、tests/ut/op_kernelKernel CPU 模拟器 UT含数据生成脚本pdist_data/gen_data.py接口文档aclnnPdist.md 与 aclnnPdistForward.md 提供完整函数原型、参数表与错误码表。报告本身的测试方式为Real NPU Mock CPU GoldenGolden 参考实现在 test_aclnn_pdist.cpp 中以 double 精度计算三种 p 分支与 NPU 输出按 MERE/MARE 阈值比对NaN/Inf 对按 PyTorch 语义特判——这一Golden 对照 相对误差阈值的验收方法论同样适用于其他数学算子的质量把关。【免费下载链接】ops-math本项目是CANN提供的数学类基础计算算子库实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-math创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表