CANN/cann-competitions Add算子测试报告
元信息请如实填写此区块将由组委会脚本自动解析请保持字段名不变【免费下载链接】cann-competitions本仓库用于 CANN 开源社区各类竞赛、开源课题、社区任务等课题发布、开发者作品提交和展示。项目地址: https://gitcode.com/cann/cann-competitionsteam_name: 不队 team_members:杨金鹏-广州大学刘畅-广州大学 operator_name: Add operator_library: cann-ops-math report_date: 2026-04-25Add 算子测试报告一、算子理解Add 算子用于执行两个张量的逐元素加法其在 CANN 库中的广义数学定义为out[i] x1[i] alpha * x2[i]其中alpha为标量乘子。除了支持基础的张量相加Add 算子家族在 API 层面提供了极其丰富的变体计算模式支持基础相加aclnnAdd/aclnnAddV3、张量与标量相加aclnnAdds以及对应的原地Inplace更新版本。数据类型与混合精度不仅支持 FP32, FP16, BF16, INT32, INT64, INT8, UINT8, BOOL 等常用类型还支持类似x1为 FP32 而x2为 FP16 的异构Mixed Dtype加法。Broadcasting广播支持将不同形状的张量如[4, 1]与[4, 4]隐式扩展为相同形状再进行计算。值得关注的数学性质与底层硬件路径 Add 虽然看似简单但在底层 Tiling 与内核实现上极度依赖输入类型和alpha的值。例如当alpha 1.0时可能走直接的AddWithoutCastCompute路径当alpha ! 1.0且类型满足条件时会触发特定硬件的Axpy或AxpyV2即 $Y \alpha X Y$路径若不支持 Axpy则退化为Mul Add路径。此外浮点加法的“大数吃小数”吸收效应、相近数相减的“灾难性相消”、以及整数的“溢出回绕”都是测试和业务使用中极易踩坑的重点。二、测试策略与用例设计考虑到 Add 算子底层庞大的分发路由与硬件特化路径我们在test_aclnn_addv8.cpp中设计了多达 133 个测试用例采用白盒与黑盒相结合的策略重点覆盖了以下几个维度1. 极高密度的 API 变体覆盖同时对aclnnAdd,aclnnAdds,aclnnInplaceAdd,aclnnInplaceAdds,aclnnAddV3,aclnnInplaceAddV36 套 API 进行全面测试。特别是针对新增的 V3 接口通过引入self标量乘子设计了相应的正向逻辑与异常校验逻辑。2. 核心路由与 Tiling 分支的精准触发通过调整dtype和alpha的组合精准打穿 Host 侧与 Device 侧的特化逻辑直接加法路径如FP32alpha1、INT32alpha1AddWithoutCastCompute。Axpy / AxpyV2 硬件加速路径构造如FP32alpha1.5、INT32alpha3验证AXPY_DTYPE_SUPPORT_LIST和ARCH_REGBASE_AXPY_DTYPE_SUPPORT_LIST的分发情况。退化路径 (Mul Add)对于不在 Axpy 列表的类型如 V3 接口下的INT8alpha2验证乘加分离运算的准确性。混合精度路径构造FP16 FP32和FP32 FP16验证AddMixDtypeCompute分支。布尔特化路径测试BOOL BOOL触发AddBoolComputeint8_t的按位或OR逻辑转换。3. 异常与防御性编程Error-Path设计了 TC-57 至 TC-91 的 30 个连续异常探测用例对 6 个 API 的GetWorkspaceSize进行轰炸。包括传入nullptr、维度超过 8 维dim_exceed_8用 9D 张量测试、输出类型不支持promote_outcast_BOOL、不支持的数据类型如UINT32以及Shape不匹配验证 API 拦截机制。4. 精度基准Oracle的降维打击设计CPU 侧的基准参考坚决避免与被测算子使用相同的float类型浮点数FP32/FP16/BF16全部提升至double进行高精度累加CpuAddF以避免标准库float自身带来的舍入掩盖了 NPU 算子的问题。整数INT32对于溢出测试若直接用 Cint32_t相加触发溢出会引发未定义行为UB。我们的 Oracle 显式将其转为uint32_t执行运算后再强转回int32_tCpuAddI32完美模拟 CANN 算子在底层基于二进制补码的低位截断回绕行为。三、覆盖率分析以下是基于流水线针对题目规定评分文件及底层算子实现提取的综合覆盖率数据目标文件核心代码行数行覆盖率分支覆盖率说明 / 未覆盖归因aclnn_add_v3.cpp7794.81%63.85% (272/426)API V3 层。行覆盖率极高分支未满主要是多条件判断及底层极小概率的校验抛错未触发。aclnn_add.cpp30366.01%45.86% (709/1546)V1/V2 基础 API 与类型推导校验层。庞大的宏展开与分支校验导致分子分母基数极大其中包含针对其他硬件架构的历史兼容校验逻辑未被走到。add.cpp5955.93%23.48% (62/264)设备路由层 (AiCore/AiCpu)。异常资源处理及部分备选硬件路径未能全部触达。add_tiling_arch35.cpp9389.25%57.29% (110/192)算子 Tiling 算法层。行覆盖率接近满分说明基础的 Block 切分、Axpy 路由等核心数学调度已充分激活。覆盖率总结我们在aclnn_add_v3.cpp及add_tiling_arch35.cpp取得了优异的行覆盖率89%这得益于我们针对 Dtype 和 Alpha 的正交测试。较低的 API 层分支覆盖率符合预期主要由系统级的防御性代码如aclrtMalloc失败、极罕见的数据类型组合检查带来。四、精度分析浮点运算的本质决定了“算子实现正确并不等于结果符合绝对数学真值”。我们专门设计了 TC-27 至 TC-33 等极端的精度场景进行剖析场景一大数吃小数吸收效应测试输入 (TC-27)FP32 下1e10 1e-5。实测输出与分析在 FP32 中1e10对应的 ULP (Unit in the Last Place) 大约是1024。因此加入1e-5就像往海里滴水结果的有效位完全无法表达这个增量。实测输出与理论真值的误差极大大于1e-4。这不是 CANN 的 Bug而是浮点精度的硬件极限表现测试给出了预期内的[PASS] No loss判定。场景二灾难性相消Catastrophic Cancellation测试输入 (TC-28)FP32 下1.0000001 (-1.0)。实测输出与分析两个极为相近的数值相减会导致前导有效位全部抵消剩余的小数部分被放大。在此测试中计算结果完美对齐了经量化后输入的 CPUdouble参考值误差小于1e-6说明 NPU 加法在局部精度的保持上非常稳健。场景三Alpha 标量的量化折损测试输入 (TC-29)X (1/3) * Y。实测输出与分析1/3在二进制中是无限循环小数。我们将已带有浮点量化误差的float av 1.0f / 3.0f作为 alpha 传入。测试验证 NPU 计算是否引入了额外的截断。结果表明实测值与使用同等量化av运算的 CPU reference 对比误差为0证明了乘法累加计算链路上没有额外掉精度。场景四异常值传染Inf 与 NaN测试输入 (TC-30, TC-31)3.4e38 3.4e38(溢出)NaN 1.0。实测输出与分析实测结果正确上溢输出inf对于 NaN 测试实测结果res[0]正确传递了NaN标志并且没有影响到同一个 tensor 中的res[1](即1.0 2.0 3.0)。符合 IEEE-754 标准证明底层矢量运算管线处理异常值规范。场景五整数溢出的无感回绕UB 陷阱测试输入 (TC-32)INT32 下2^30 2^30总和2147483648超出 INT32_MAX。实测输出与分析实测 NPU 输出-2147483648。算子对整数溢出不报错而是走底层 ALU 的二进制补码截断。我们在 CPU Oracle 端采用uint32_t模拟此行为。对于业务方这警示我们在处理如 Offset 加法时需严格留意数据量级必要时需提升为 INT64。五、反思与改进复杂的分发路由隐患通过测试发现Add 算子的实现不仅与数据类型挂钩还极度受alpha值影响例如决定是否走Axpy或MulAdd。这要求我们在未来的融合算子开发中务必对参数值为1.0,0.0,-1.0和一般小数的分支进行穷举测试。Oracle 陷阱的规避针对 INT32 溢出的设计是一个深刻的经验教训。如果直接在 C 用int32_t累加作为基准在-O3优化下编译器可能因 UB 产生非预期的常量折叠。因此CPU 的基准实现必须显式地规避编译器的 UB本次我们通过类型强制转换实现的回绕大大提升了测试代码的健壮性。环境差异与异步 Hang 死在测试执行阶段参看 Log我们发现部分涉及AiCpu路径如 INT16 乘加和复杂广播如TC-17在当前实机环境中存在挂死风险并进行了跳过[SKIP]。这提示我们底层框架针对部分边缘场景的 Tiling 切分可能与特定驱动或硬件版本存在兼容性隐患建议 CANN 底层进一步完善在不匹配架构上的平滑降级Fallback机制。【免费下载链接】cann-competitions本仓库用于 CANN 开源社区各类竞赛、开源课题、社区任务等课题发布、开发者作品提交和展示。项目地址: https://gitcode.com/cann/cann-competitions创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考