Add 算子测试报告

发布时间:2026/7/4 1:40:35

Add 算子测试报告 【免费下载链接】cann-competitions本仓库用于 CANN 开源社区各类竞赛、开源课题、社区任务等课题发布、开发者作品提交和展示。项目地址: https://gitcode.com/cann/cann-competitions 元信息请如实填写此区块将由组委会脚本自动解析请保持字段名不变team_name: 不要垫底team_members:滕佳琳-广州大学李楚湘-广州大学operator_name: Addoperator_library: cann-ops-mathreport_date: 2026-04-25Add 算子测试报告测试环境Ascend 910 系列评测环境SOC 参数为ascend910_93CANN ops-math 仓库开启覆盖率编译。覆盖率统计采用gcov -b -c获取以评测相关的 op_api 层文件为统计对象。不同 CANN 版本、SOC 配置与算子支持情况可能导致覆盖率与边界行为存在差异本文记录本次实机运行结果。一、算子理解Add 算子执行带缩放系数的逐元素加法核心数学形式为out self alpha * other其中self与other可以是形状相同的张量也可以是满足 broadcasting 规则的张量alpha是标量系数用于控制第二个输入对输出的贡献。当alpha1时算子退化为普通逐元素加法当alpha0时输出应保持为self当alpha为负数或非整数小数时算子需要同时处理乘法缩放、加法累加以及数据类型转换带来的精度影响。本次测试关注的接口包括aclnnAdd、aclnnAdds、aclnnInplaceAdd、aclnnInplaceAdds以及aclnnAddV3。从输入形式看既包含 tensor tensor也包含 tensor scalar、scalar tensor 以及 inplace 原地写回场景。Add 算子本身不是规约类算子每个输出元素主要依赖对应位置的输入元素因此不存在类似 Cumsum 的长序列误差累积问题但它仍然具有若干值得重点验证的数值特征包括大小数相加导致的小量丢失、正负抵消导致的有效位损失、FP16/BF16 量化误差、NaN/Inf 传播、次正规数处理以及整数溢出或截断行为。在 dtype 方面本次测试覆盖了 FLOAT32、FLOAT16、BF16、INT32、INT64、INT8、UINT8、BOOL 等常见类型并补充了 FP16/BF16 与 FLOAT 混合输入的兼容性探索。浮点类型采用容差比较整数类型采用精确匹配或按类型语义解释特殊值场景则采用std::isinf、std::isnan、std::fpclassify等方式判断避免用单一绝对误差处理跨量级或非有限值。二、测试策略与用例设计本次在test_aclnn_add.cpp中设计了 55 个端到端测试用例测试目标不是只验证普通加法是否可运行而是围绕 Add 算子的关键输入维度做分层覆盖基础功能、数据类型、shape 与 broadcasting、API 变体、精度风险、特殊值、混合精度以及补充边界场景。每个正常计算用例均在 CPU 端计算期望值并在 NPU 算子执行完成后将输出拷贝回 host 进行逐元素比对。1. 基础功能与 alpha 参数覆盖。设计了alpha1、alpha1.2、alpha0、alpha-2.5等场景覆盖普通加法、非单位缩放、忽略第二输入、负系数减法化等典型路径。该部分能够直接验证out self alpha * other的基本语义是否正确尤其是alpha0与负数 alpha 这类容易暴露分支处理问题的边界值。2. 多数据类型覆盖。用例覆盖 FP32、FP16、BF16、INT32、INT64、INT8、UINT8、BOOL。FP16 与 BF16 没有直接把uint16_t位模式当作数值参与比较而是实现了floatToHalf、halfToFloat、floatToBF16、bf16ToFloat等辅助函数先完成编码/解码再进行 CPU 参考值计算和输出解释。这样可以避免把半精度位模式误当作普通整数保证 Oracle 与 NPU 输入在量化语义上保持一致。3. shape 与 broadcasting 覆盖。构造了[4,1] [1,4] - [4,4]、[4,2] [2] - [4,2]、[1] [4] - [4]、[2,3,4]高维张量以及[256,256]较大张量场景。该部分重点检查形状对齐、广播展开、高维 stride 计算以及较大数据量下的正确性。对于 Add 算子而言broadcasting 是比普通同形状加法更容易触发内部 shape 处理逻辑的输入形态因此本次将其作为重点覆盖方向之一。4. API 变体覆盖。除aclnnAdd主入口外还设计了aclnnAdds、aclnnInplaceAdd、aclnnInplaceAdds与aclnnAddV3相关用例分别覆盖 tensor scalar、原地更新、scalar tensor 等使用方式。其中 inplace 场景直接从原输入地址拷贝回结果进行验证能够检查算子是否正确写回 selfRef而不是仅验证普通 out tensor 写入。5. 精度与特殊值覆盖。精度专项包括大小数相加、正负抵消、非精确 alpha 缩放、极大值、极小 alpha 等场景特殊值专项包括 Inf、NaN、Subnormal。测试目的不是把所有现象简单判为错误而是区分“算子错误”和“数据类型固有行为”。例如大数加小数时小数可能因 FP32 有效位限制而无法改变结果正负抵消会放大相对误差BF16/FP16 的尾数位较短容差需要明显宽于 FP32。Oracle 与容差设置。浮点测试以 CPU double 计算作为参考基准expected (double)self (double)alpha * (double)otherFP32 常规场景使用1e-6 ~ 1e-5量级容差FP16 使用1e-3 ~ 1e-2量级容差BF16 使用1e-1量级容差特殊大数、极小 alpha 或混合精度场景根据输入量级适当放宽。整数场景以目标 dtype 的结果为基准进行精确比较避免将浮点误差判断逻辑套用到整数算子。三、覆盖率分析本次通过如下方式提取评分相关文件覆盖率gcov -b -c $(find build -name aclnn_add.cpp.gcda | head -1) gcov -b -c $(find build -name aclnn_add_v3.cpp.gcda | head -1) gcov -b -c $(find build -name add.cpp.gcda | grep /__/add/op_api/ | head -1)实机运行后得到的覆盖率如下文件代码行数行覆盖率分支覆盖率说明op_api/aclnn_add.cpp30330.69%约 93 行11.58%约 179/1546主 API 层当前测试主要命中 Add/Adds/Inplace 相关正向执行路径op_api/aclnn_add_v3.cpp770.00%0 行0.00%0/426V3 独立实现文件在当前运行环境下未形成有效覆盖率命中op_api/add.cpp590.00%0 行0.00%0/264底层路由文件在本次 gcov 统计中未被有效命中综合覆盖率按行数和分支数加权计算综合行覆盖率 (93 0 0) / (303 77 59) 93 / 439 ≈ 21.18% 综合分支覆盖率 (179 0 0) / (1546 426 264) 179 / 2236 ≈ 8.01%从结果看本次覆盖率主要集中在aclnn_add.cpp说明测试用例已经有效触达 Add 主入口中的正常执行路径、alpha 参数处理、不同 dtype 输入、broadcasting 以及 inplace 等功能分支。aclnn_add_v3.cpp与add.cpp当前为 0并不代表测试设计完全没有涉及相关语义测试源文件中已经补充了 AddV3、Adds、Inplace 等接口层用例但在当前编译/运行环境与算子路由条件下独立aclnn_add_v3.cpp和底层add.cpp未产生有效 gcov 命中。考虑到本次时间有限报告中将该结果如实记录同时把分析重点放在已经稳定运行并产生覆盖率的主入口文件上。需要说明的是Add 算子的 API 层包含大量参数校验、类型组合、异常输入、设备路由和宏控制分支。分支覆盖率低于行覆盖率是合理现象行覆盖只要求某行代码执行过而分支覆盖要求条件表达式的 true/false 两侧都被触发。当前用例更偏向“保证可通过的正向路径”和“数值语义验证”没有大量构造 nullptr、非法 dtype、形状不兼容等强异常路径因此分支覆盖率相对保守。这种取舍有利于保证提交用例整体稳定通过同时仍能展示较完整的功能与精度测试设计。四、精度分析Add 算子是逐元素运算不涉及长序列累积但仍会受到浮点有效位、舍入、特殊值传播和 dtype 转换的影响。本次精度分析围绕以下典型场景展开。场景一大小数相加导致小量贡献丢失测试思路构造类似1e8 1的输入。数学上结果应比1e8略大但在 FP32 中1e8附近相邻可表示数之间的间隔已经大于 1因此小数值可能无法改变最终表示。分析这不是 Add 算子的实现错误而是浮点数有效位有限导致的正常现象。FP32 只有约 7 位十进制有效数字当一个很小的数加到一个很大的数上时小数部分可能在对阶过程中被舍弃。本测试通过记录该现象说明测试不仅关注 pass/fail也关注用户在实际使用中可能遇到的静默精度损失。场景二正负抵消导致有效位损失测试思路构造大正数与大负数相加后只剩较小残差的场景例如1e8 (-1e8 delta)。这类输入的绝对误差可能不大但相对于最终残差的相对误差会被放大。分析正负抵消是加法算子中最典型的数值风险之一。两个大数相减后高位有效数字相互抵消输出主要依赖低位信息而低位信息在输入量化或计算过程中可能已经损失。因此本次没有简单套用固定相对误差而是结合输入量级选择容差并在报告中说明该现象属于浮点计算固有限制。场景三alpha 缩放引入的舍入误差测试思路使用alpha0.3、alpha1.2、alpha2.5、alpha1e-10等非整数或极小系数。由于多数十进制小数无法被二进制浮点精确表示alpha * other在进入加法前已经可能产生舍入误差。分析Add 算子实际包含“乘法缩放 加法”两个步骤因此精度误差不仅来自加法本身也来自 alpha 的二进制表示和乘法结果的舍入。对于 FP32 常规输入本次采用1e-5级容差对于极小 alpha 或边界值输入则根据量级适当放宽以避免把可解释的浮点舍入误差误判为算子错误。场景四FP16 与 BF16 的 dtype 差异测试思路使用同一语义输入分别构造 FP16、BF16 和 FP32 场景并通过手写编码/解码函数解释半精度输出。分析FP16 尾数位较短但指数范围也较小BF16 保留了与 FP32 相同宽度的指数位但尾数只有 7 位因此在普通数值区间内分辨率明显低于 FP32。测试中对 FP16 采用1e-3 ~ 1e-2量级容差对 BF16 采用1e-1量级容差这与两种 dtype 的表示精度相匹配。报告中特别强调半精度测试必须先将位模式解码为 float 再比较否则 Oracle 本身会出错。场景五Inf、NaN 与次正规数处理测试思路构造 Inf 输入、NaN 输入以及极小次正规数输入。Inf 场景使用std::isinf判断NaN 场景使用std::isnan判断Subnormal 场景使用std::fpclassify或量级检查。分析对特殊值不能使用普通abs(actual - expected) atol rtol * abs(expected)公式。例如 Inf 与任何有限 atol 比较都没有意义NaN 与自身也不相等。通过单独设计特殊值判断逻辑可以让测试更贴合 IEEE 浮点语义也能避免将特殊值传播行为误判为普通数值误差。五、反思与改进本次测试的主要优点在于用例数量较多覆盖维度较全面不仅验证了普通 FP32 加法还覆盖了 alpha 边界、整数类型、半精度类型、broadcasting、高维 shape、较大 tensor、inplace 写回、scalar 变体、特殊值和精度风险场景。相比只打印输出的示例测试本次每个主要用例都包含 CPU Oracle 与逐元素比对具备自动判断 pass/fail 的能力同时FP16/BF16 通过显式编解码处理避免了半精度测试中常见的 Oracle 错误。当前覆盖率的主要局限在于覆盖率命中集中在aclnn_add.cppaclnn_add_v3.cpp与add.cpp在本次环境下没有形成有效 gcov 命中。后续如果继续优化可以优先从三个方向入手第一确认 AddV3 在当前 SOC 与 CANN 版本下的真实路由条件使 V3 用例能够稳定进入独立实现文件第二补充更多 shape 不兼容、nullptr、非法 dtype、空 tensor 等异常路径以提升参数校验分支覆盖第三针对底层add.cpp的设备路由条件构造更贴近其分发逻辑的 dtype 与 shape 组合。总体而言本次测试策略优先保证了端到端运行稳定性、结果验证完整性和精度分析深度。在比赛提交场景下这种设计能够较好体现测试代码的实用性即使部分底层覆盖率受环境和路由影响测试本身仍覆盖了 Add 算子的主要用户可见行为并对容易出错的数据类型和数值边界给出了明确验证。【免费下载链接】cann-competitions本仓库用于 CANN 开源社区各类竞赛、开源课题、社区任务等课题发布、开发者作品提交和展示。项目地址: https://gitcode.com/cann/cann-competitions创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻