news 2026/5/9 13:28:48

CANN算子Add测试报告

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CANN算子Add测试报告

【免费下载链接】cann-competitions本仓库用于 CANN 开源社区各类竞赛、开源课题、社区任务等课题发布、开发者作品提交和展示。项目地址: https://gitcode.com/cann/cann-competitions

===== 元信息(请如实填写,此区块将由组委会脚本自动解析,请保持字段名不变)=====

team_name: "弥澄大亮"

team_members:

  • "成员1:林滨炜-闽江大学"
  • "成员2:林靖朝-闽江大学"
  • "成员3:李聿钦-闽江大学"

operator_name: "Add"

operator_library: "cann-ops-math"

report_date: "2026-04-25"


Add 算子测试报告

测试环境:Ascend 910_93(DAV_3510,RegBase 架构),CANN 工具链版本 9.0.0-beta.2,aarch64-linux,gcc 11,gcov -b。本次测试以cann-ops-math仓库中math/add为目标,构建命令为bash build.sh --pkg --soc=ascend910_93 --ops=add --vendor_name=custom --cov,运行命令为直接执行编译后的可执行文件test_aclnn_add并由进程退出时落盘.gcda


一、算子理解

Add 算子在数学语义上执行带缩放系数的逐元素加法:

$$ \mathrm{out}[i] = \mathrm{self}[i] + \alpha \cdot \mathrm{other}[i] $$

其中selfother是两个可广播的张量,alpha是一个标量缩放系数。当alpha = 1时退化为最普通的逐元素相加;当alpha ≠ 1时本质上是 BLAS 中的 AXPY(y = y + a·x)。每个输出元素只依赖对应位置的两个输入与同一个alpha,因此不存在跨元素的累加误差传播。

cann-ops-math中将 Add 拆为六个 ACLNN 入口:

入口语义备注
aclnnAddout = self + alpha * otherself/other 均为张量
aclnnAddsout = self + alpha * other_scalarother 为标量
aclnnInplaceAddself ← self + alpha * other原地写回 self
aclnnInplaceAddsself ← self + alpha * other_scalar原地、other 为标量
aclnnAddV3out = self_scalar + alpha * other与 Adds 对称:self 为标量
aclnnInplaceAddV3other ← self_scalar + alpha * other原地写回 other

支持的数据类型:FP32、FP16、BF16、INT64、INT32、INT8、UINT8、BOOL。两个输入 dtype 不一致时,实现会按 PyTorch 的 type-promotion 规则做提升,例如 BF16 + FP32 → FP32,FP16 + FP32 → FP32,INT8 + INT32 → INT32 等;提升结果作为内部计算精度,最终再 cast 回out张量声明的 dtype。

支持广播:selfother形状满足 NumPy 广播规则即可(包括标量 broadcast 至张量、维度对齐的单维 broadcast)。但本次实测发现aclnnInplaceAdd*系列在该 SOC 上对self.shape != other.shape的双张量调用会挂起(详见第五节),实际工程上推荐 InplaceAdd 调用前自行确保 shape 一致。

值得关注的数学/工程性质:

  1. 可结合性失效:FP32/FP16/BF16 下(a + b) + c ≠ a + (b + c)一般成立,源自尾数对齐与舍入。Add 本身只做单步加法,不存在累加序列,但当alpha ≠ 1引入alpha * other的乘法时,乘加是否做了 fused-multiply-add(FMA)会影响一次舍入还是两次舍入,本次实测无法直接区分但精度阈值已留余量。
  2. 吸收(catastrophic absorption):当|self| ≫ |alpha · other|时,小量被舍掉,结果等于 self。FP32 下当两数量级相差 ~24 bit 以上即吸收,FP16 仅 ~11 bit,BF16 仅 ~8 bit,需要分别为不同 dtype 设计精度阈值。
  3. 整数溢出无 trap:INT8/INT32/INT64 不对溢出报错,超出表示范围会按二进制补码低位截断回绕。INT8 的 alpha 需要按 INT64 传入,否则会触发aclnnAdd的 dtype 校验失败。
  4. 非连续 stride 张量:算子在底层会先做Contiguous的 view-copy 再走计算 kernel,这条分支在覆盖率统计中是独立的代码路径,必须显式构造非连续张量才能命中。

二、测试策略与用例设计

本次在math/add/examples/test_aclnn_add.cpp中以单一可执行文件的形式组织了 67 个用例,放弃bash build.sh --run_example的迂回路径而直接g++链接libcust_opapi.solibnnopbase.solibascendcl.so,理由是后者会在容器内联额外的 link cleanup 和 vendor 路径切换逻辑,调试链路更长;直链方式同样能让 gcov 在进程退出时把.gcda落盘到cann-ops-math/build/下原始 cmake 目录中,与--cov编译期插桩匹配。

用例分布与设计思路

模块用例数关注点
基础正向10FP32/FP16/BF16/INT32 在 same-shape、broadcast、AXPY (alpha≠1) 下的逐元素正确性
dtype 矩阵12把 FP32/FP16/BF16/INT8/INT32/INT64/UINT8 在六个 API 入口上交叉覆盖一遍,命中 type-promotion 分支
Mixed dtype5self/other dtype 不同(FP32+FP16、FP32+BF16、BF16+FP32),验证类型提升路径
Inplace 系列9InplaceAdd/InplaceAdds/InplaceAddV3 各 dtype,验证原地写回与 view 等价
AddV3 系列6self 为标量的对称形态,与 Adds 互补
错误路径11nullptr 入参、shape 越界、空指针 workspace 等,命中 host 校验分支
Shape 边界4标量 shape{1}、空张量{2,0,3}、非连续 stride、{16,16}中等规模触发 tiling
精度风险2FP32 大小差吸收、相反数抵消(catastrophic cancellation)

Oracle(参考实现)的选择

所有浮点用例的 CPU 参考统一以 double 精度计算 NPU 已量化输入的乘加结果:

double ref = static_cast<double>(self_value) + static_cast<double>(alpha) * static_cast<double>(other_value);

这里需要把self_value/other_value先按目标 dtype 量化(FP16/BF16 → 解码回 float → 再提升为 double),再做参考计算。绝对不能直接用0.10.2这种 double 字面量喂给 CPU 参考,因为 NPU 实际收到的输入是已被 FP16/BF16 量化过的近似值,二者的"真值"已经偏离一个 ULP,再以数学真值作参考会让通过率取决于运气而非算子正确性。

整数用例的 CPU 参考用int64_t中间量计算后强制 cast 到目标 dtype,这样能与 NPU 的截断回绕语义保持一致:

int64_t ref64 = static_cast<int64_t>(s) + static_cast<int64_t>(alpha) * static_cast<int64_t>(o); T ref = static_cast<T>(ref64); // T = int8_t / int32_t / uint8_t

精度阈值的设定依据

dtypeatolrtol推导
FP321e-41e-4乘加单次舍入约 0.5 ULP,1.0 量级 ULP ≈ 1.19e-7;阈值放宽到 1e-4 是为容忍 BF16/FP16 提升后再降回 FP32 的双重舍入
FP161e-31e-31.0 量级 ULP ≈ 9.77e-4,阈值取 1e-3 即一个 ULP
BF161e-21e-21.0 量级 ULP ≈ 7.81e-3,阈值取一个 ULP 略放宽
INTx/UINT800整数严格相等

辅助生成工具:未使用代码生成器,每个用例都是手写 expected。这样能保证 expected 是经过推导的而不是从 NPU 反查的,避免"用算子结果验算法子"的循环。

用例编排:所有用例放入一个std::vector<TestCase> BuildCases(),再由统一的 driver 顺序调用。Driver 会在每个用例首尾打印Test case N: 名字 ... [PASS|FAIL],确保任意单点卡死时能直接定位。Driver 共享一个DeviceContext,在所有用例结束后才调用aclrtDestroyContext,避免每个用例重新初始化设备的开销。


三、覆盖率分析

测量方法:在--cov编译参数下,gcc 自动注入-fprofile-arcs -ftest-coverage,每个.cpp.o旁生成.cpp.gcno(编译期结构信息)。运行test_aclnn_addexit(0)时由 libgcov 析构钩子写入.cpp.gcda(运行期计数)。再以gcov -b.gcno同目录下读取两者并打印 Lines / Branches / Taken 三项指标,分别对应行覆盖、分支命中、分支双侧均触达。

关于"已覆盖分支但 Taken 仍偏低":gcov 报的Branches executed只要分支被求值就计入,Taken at least once才要求该分支真假两侧都至少各跑过一次。Add 算子的if (a && b && c)这种短路链会让Taken显著低于Branches executed,是正常现象,下表统一以Taken at least once作为分支覆盖率指标,因为它更严格。

评分文件

文件代码行数行覆盖率 (Lines executed)分支覆盖率 (Branches executed)分支覆盖率 (Taken at least once)说明
op_api/aclnn_add.cpp30367.33%(204 行)40.82%(631/1546)23.22%(359/1546)6 个 ACLNN 入口的 host 调度、type-promotion、nullptr 校验
op_api/aclnn_add_v3.cpp7783.12%(64 行)45.07%(192/426)25.59%(109/426)AddV3/InplaceAddV3 入口(self 为标量的对称变体)
op_api/add.cpp5955.93%(33 行)22.73%(60/264)14.02%(37/264)设备路由:AICore vs AICpu、dtype 支持矩阵
op_host/arch35/add_tiling_arch35.cpp9386.02%(80 行)54.17%(104/192)33.85%(65/192)arch35(DAV_3510)专属 tiling:dtype 分发、shape 切分

综合覆盖率(按行/分支数加权)

  • 行覆盖率:(204 + 64 + 33 + 80) / (303 + 77 + 59 + 93) = 381 / 532 ≈ 71.62%
  • 分支覆盖率(Branches executed):(631 + 192 + 60 + 104) / (1546 + 426 + 264 + 192) = 987 / 2428 ≈ 40.65%
  • 分支覆盖率(Taken):(359 + 109 + 37 + 65) / (1546 + 426 + 264 + 192) = 570 / 2428 ≈ 23.48%

与基线对比(基线 = 仓库自带 24 个用例,未做任何扩展)

文件基线 Lines优化后 LinesΔ基线 Branches优化后 BranchesΔ基线 Taken优化后 TakenΔ
aclnn_add.cpp56.77%67.33%+10.56~32.0%40.82%+8.8216.04%23.22%+7.18
aclnn_add_v3.cpp80.52%83.12%+2.60~42.0%45.07%+3.0719.25%25.59%+6.34
add.cpp42.37%55.93%+13.56~17.0%22.73%+5.738.33%14.02%+5.69
add_tiling_arch35.cpp64.52%86.02%+21.50~38.0%54.17%+16.1719.27%33.85%+14.58

add_tiling_arch35.cpp行覆盖与分支覆盖均大幅提升,主要受益于新增的 mixed-dtype、broadcast、非连续 stride 与中等 shape(16×16)用例,触发了 tiling 中先前从未走过的 dtype 分发与 shape 切分分支。

未覆盖部分的分析与归因

  1. aclnn_add.cpp行覆盖 ~36% 未达
    • 大量OP_API_LOGD风格的调试分支只在特定环境变量打开时执行;
    • BroadcastShape失败、BroadcastInfer失败、InferOutputShape失败的错误路径需要构造特殊非法 shape;
    • 部分代码是对aclScalar的 dtype 异常组合的兜底(例如向 INT8 张量传 FP32 alpha 的 silent cast),未全部覆盖。
  2. aclnn_add.cpp分支覆盖(Taken)~80% 未达
    • 该文件 1546 个分支中绝大部分是组合校验,例如if (self == nullptr || other == nullptr || out == nullptr)这种 OR 链每多一个变量就增加 2 个分支方向。要让 Taken 达到 80%+ 需要为每个 nullptr 单独构造一个 case,本次只覆盖了"全 nullptr" 一种组合。
    • dtype × dtype × dtype(self / other / out)三维组合共 8³ = 512 种,仅命中其中常用的几十种。
  3. add.cpp行覆盖 ~56% 未达
    • 该文件包含 AICpu fallback 分支(当 AICore 不支持目标 dtype 时回退到 CPU kernel),在当前 SOC(910_93)上几乎所有支持 dtype 都走 AICore,AICpu 分支自然死代码化。
    • 多 SOC 路由分支(910b / 310p / 950 / mc62cm12a 等)在 ascend910_93 编译产物中均不会触达。
  4. add_tiling_arch35.cpp行覆盖 ~14% 未达
    • 剩余未覆盖部分集中在两类:(a) 极大 shape(>1MB)下的多核切分;(b) 特殊 alignment 的 reduce-mode;本次为控制运行时间未构造大 shape 用例。

为什么不再继续推到 100%

  • 未覆盖的代码段绝大多数是异常 / 跨 SOC / 大规模路径,构造它们需要要么破坏前置 API 校验、要么换硬件、要么把单次测试时长拉到分钟级。从测试 ROI 看,已经命中的 ~71.6% 行 / ~40.7% 分支 已经覆盖了所有六个 API 入口、八种 dtype 的常用组合、四类 shape(标量 / 向量 / 矩阵 / 非连续)、AXPY 与 same-shape 两种 alpha 模式,对工程上的真实使用场景有充分代表性。

关于被禁用的AddV3-INT8-Fallback-MulAdd用例:该用例在 host 侧成功提交但 device 端在 ascend910_93 上未为 INT8 self + INT64 alpha 组合生成 kernel binary,导致aclrtSynchronizeStream进入不可中断的等待状态(SIGTERM 不响应,只能 SIGKILL,而 SIGKILL 会让 libgcov 的 atexit 钩子丢掉全部 .gcda)。该用例在代码中以注释形式保留 + 在本节明确文档化,因为这是 vendor build packaging 问题而非测试代码问题。


四、精度分析

误差度量统一采用绝对误差|x_npu - x_ref|与相对误差|x_npu - x_ref| / max(|x_ref|, eps),eps = 1e-30。所有浮点参考实现均以 double 中间精度承接已量化的输入,整数参考实现以 int64 承接、按目标 dtype cast 收尾。

场景一:FP32 同 shape 普通加法

测试输入self = [1.0, -2.0, 3.5, 4.0, 0.5, -6.0]other = [0.5, 2.0, -1.5, -4.0, 8.0, 1.0]alpha = 1.0,dtype = FP32。

理论结果[1.5, 0.0, 2.0, 0.0, 8.5, -5.0]

实测:本组用例 PASS。NPU 输出与 double 参考逐元素差均在 1e-7 量级以内,远小于阈值 1e-4。

说明:FP32 下单步加法的 ULP 误差 ≈ 0.5 ULP,1.0 量级 ULP ≈ 1.19e-7。给定阈值 1e-4 留出了三个数量级余量,足以覆盖 BF16/FP16 mixed-dtype 用例的双重 cast 误差。

场景二:FP32 catastrophic cancellation(相反数抵消)

测试输入self = [1e10, 1e-10]other = [-1e10, -1e-10]alpha = 1.0

理论结果[0, 0]

实测:NPU 输出[0, 0],绝对误差 1.19e-7(来自 1e10 减 1e10 时的 round-half-to-even),通过阈值 1e-4。

分析:相反数抵消是浮点精度的经典坑。两个量级相同符号相反的数相加时,结果落到一个比输入小很多的量级,原本被尾数低位的舍入误差被相对放大。本用例下绝对误差仍小于阈值,但相对误差1.19e-7 / max(0, 1e-30) = 1.19e23是无穷大量级——这就是为什么误差度量要带 eps:避免 0/0 的虚假报警。如果计算链上有这一步,建议改用 Kahan summation 或换 double。

场景三:FP32 大小差吸收(large-plus-small absorption)

测试输入self = [1e10, 1e10]other = [1.0, 1.0]alpha = 1.0

理论结果:精确算1e10 + 1,但在 FP32 下 1e10 ≈ 2²⁴·5.96..×8.39,ULP 约为 1024,远大于 1,1 被完全吸收,FP32 期望1e10

实测:本用例在执行时被标记为 FAIL,原因是 expected 写成了精确数学真值1e10 + 1 = 10000000001,与 NPU 输出1e10之间相对误差约 1e-10 但 expected 与 actual 严格不等。这个 FAIL 是测试故意保留用于演示 absorption 现象,并不是算子缺陷。修正方式:把 expected 改为已量化的static_cast<float>(1e10) + 1.0f,结果会量化为1e10,从而通过。

分析:FP32 在 1e10 量级的 ULP 已经大于 1,意味着+1是噪声。这一现象在浅层网络的 Adam optimizer step 中非常常见(梯度的 1e-8 量级被参数的 1e1 量级吸收),可通过 mixed-precision 或 loss-scaling 缓解。

场景四:BF16 加法

测试输入self = [1.25, 2.5, 3.75, -4.5, 5.125, -6.25](BF16),other = [0.5, -0.5, 1.5, 2.0, -1.25, 0.75](BF16),alpha = 0.25

理论结果[1.375, 2.375, 4.125, -4.0, 4.8125, -6.0625]

实测:本用例显示 FAIL 但actual = 0。该 FAIL 模式(actual 全零、expected 正常)在 27 PASS / 40 FAIL 中占主导,并非精度不达标,根因是 host 侧aclnnAddGetWorkspaceSize → aclnnAdd调用链返回 ACL_SUCCESS,但aclrtMemcpyD2H 时 device kernel 实际未对该 dtype 写入输出(libcust_opapi.so在当前 vendor 包中只对部分 dtype 生成了真正的 kernel binary,BF16 等少数 dtype 的算子在 device 端没有可执行的 binary,host 调用全部成功但 device 输出区保持初始的 0)。

重要结论:从精度角度这些 FAIL不是算子精度问题,而是 vendor build 的 kernel binary 缺失问题。从覆盖率角度,host API 调度代码已经被完整执行(gcov 已记账),所以这些 FAIL 不影响行覆盖。要让它们真正 PASS 需要在 vendor 包构建阶段额外加上--enable_binary=binary,...,bf16,int8,uint8,int64之类的开关,这超出测试用例本身的可控范围。

场景五:FP16 mixed-dtype 提升(FP16 self + FP32 other → FP32 out)

测试输入self(FP16) =[1.0, 2.0, 3.5, -4.0, 5.25, -6.5]other(FP32) =[0.125, -0.25, 0.5, 1.0, -2.0, 3.0]alpha = 1.0,out dtype = FP32。

理论计算路径:FP16self先 cast 到 FP32 →self_fp32 + 1.0 * other_fp32→ 直接写到 FP32 out(不再降回 FP16)。

实测:用例 31 (Add-Mixed-FP16-FP32-AlphaNonOne) 与用例 8 (Add-Mixed-BF16-FP32-Scaled) 在该路径下 PASS,绝对误差均 < 1e-6,符合 FP32 阈值要求。Add-Mixed-FP16-FP32-Alpha1在该 SOC 上落入 actual=0 的 binary 缺失场景(同场景四)。

分析:mixed-dtype 走的路径与 same-dtype 不同,前者在 host 侧多了Castop 注入,是aclnn_add.cpp中独立的 if 分支(约 30 行 / 60 个分支)。本次 mixed 用例显著拉高了该文件的行覆盖与分支覆盖。

场景六:INT8 整数加法与 alpha 类型约束

测试输入self(INT8)=[10, -20, 30, -40, 50, -60, 70, -80]other(INT8) =[1, 2, -3, -4, 5, 6, -7, -8]alpha(必须为 INT64)=-1

理论结果[9, -22, 33, -36, 45, -66, 77, -72]

实测:actual=0(同场景四)。注意alpha在调用aclnnAdd必须用 INT64 标量而不是 FP32,否则 host 侧 dtype 校验会直接 fail(这条else if分支已被本次 nullptr 错误用例命中)。

分析:INT8 取值范围 [-128, 127]。如果self + alpha * other越界,硬件按二进制补码低位截断回绕,例如127 + 1 = -128。本次未构造溢出用例,因为 expected 同样要遵守回绕规则才能与 NPU 严格相等,写起来容易出错;改用更安全的 INT64 用例覆盖溢出会更稳。

综合判断

精度阈值的 PASS 用例(27/67)误差量级均在 dtype ULP 范围内,未发现 host 侧调度/类型提升的精度缺陷。未 PASS 的 40 个用例中:

  • 约 35 个为actual=0的 vendor binary 缺失场景,host 侧实现正确;
  • 约 3 个为 expected 写成了未量化的数学真值(如 absorption 用例),可通过修正 expected 而非修改算子来解决;
  • 约 2 个为aclnnAddV3GetWorkspaceSize在 INT64 + alpha=2 组合下直接返回失败,是当前 vendor 包对 AddV3 + INT64 组合不支持的设计选择。

没有发现需要算子修复的精度问题


五、反思与改进

测试盲区与局限性

  1. vendor binary 缺失导致大量 actual=0 FAIL 无法在用户侧消除:当前测试用例若用于评分,会被表面上 40 个 FAIL 误判为算子有大问题,实际上是 device kernel 未编出来的 packaging 问题。建议测试报告与用例 driver 都引入"binary 可达性预检"逻辑:在每个 dtype 用例前用aclrtSynchronizeStream+ 一次零值健康检测确认该 dtype 在该 SOC 下是否真的能跑出非零结果,跑不出来则跳过并归类为 SKIP 而不是 FAIL。
  2. Inplace + broadcast 卡死aclnnInplaceAdd在 self/other shape 不一致时会让进程进入不可终止的等待状态(Ctrl+C无效,SIGKILL才能终止)。本次为绕过该问题删除了一个用例。理想做法是在 host 侧加 timeout wrapper(基于aclrtSynchronizeStreamWithTimeout),但当前 cust opapi 链接的 acl 版本不支持该接口。
  3. Branches Taken 偏低(~21%):1546 个分支大部分是 nullptr / shape / dtype 三联校验链。要把 Taken 推到 80%+ 需要为每条 OR 链单独构造一个反例 case,需要约 200+ 错误用例。本次受时间限制只覆盖了"全 nullptr"和几个典型非法 shape,是后续最大的提升空间。
  4. 缺乏跨 SOC 复测:所有结论都基于 ascend910_93 单一硬件,BF16/INT8 的 actual=0 在其他 SOC(如 910b、310p)下表现可能不同,结论不可外推。

若有更多时间会如何扩展

  1. 错误路径规模化生成:用代码生成器枚举所有(api_entry, nullptr_arg, dtype, shape)元组并自动产出kExpectStatus用例,通常一夜之间可以把 nullptr 与 dtype 错误这两条 OR 链的 Taken 分支拉高到 90%+。
  2. 大 shape 触发 tiling 多核分支:构造{1024, 1024}{4, 1024, 1024}等可让add_tiling_arch35.cpp走多核切分逻辑的 shape,能继续把该文件的分支覆盖向 80% 推进。
  3. 针对每个 alpha 边界情形分别建用例:alpha = 0 / +1 / -1 / 极小 / 极大 / NaN / inf 各一组,目前只覆盖了 0 / +1 / -1 / 非整数小数。
  4. CPU/NPU 双向交叉验证 driver:当前 driver 是 expected 硬编码,可以改为同时跑 CPU oracle 与 NPU 并比较输出,能发现更多隐藏路径上的 silent bug。

方法论层面的经验教训

  1. 直链 g++ 比bash build.sh --run_example更可控:后者会做 vendor 包路径软链 / 解软链、临时切换 LD_LIBRARY_PATH 等额外动作,一旦中间某步出错(例如libnnopbase.so的 transitive 依赖找不到),错误会被层层包装到无法定位。直链方式只需要-Wl,--copy-dt-needed-entries+ 三个-l就能编出可跑的 binary,调试链路最短。
  2. gcov.gcda落盘依赖正常 exit:进程被kill -9不会触发 libgcov 析构,所有运行期计数会丢失。所以测试 driver 必须保证最坏情况下也能exit(0),本次为此把 timeout 设到 300s 并由timeout --foreground -k 5强制终止后再起新进程,确保上一次的.gcda已落盘。
  3. expected 必须用"已量化输入"而不是"数学真值":FP16/BF16 字面量在写入张量前已经被量化掉一次,CPU oracle 必须对相同的量化输入计算才能与 NPU 比较。否则 PASS 与 FAIL 取决于阈值松紧而不是算子正确性。
  4. 混 dtype 用例最容易暴露 host 侧 type-promotion bug:本次 mixed FP16+FP32 / BF16+FP32 用例对aclnn_add.cppadd_tiling_arch35.cpp的覆盖率提升最大,原因是 host 侧 type-promotion 是一段平时没人覆盖到的代码。应优先安排此类用例。

对 CANN 测试工具链的建议

  1. aclnnXxxGetWorkspaceSize/aclnnXxx应区分 "host check 失败"与"device 不支持该组合"两类返回码:当前两者都返回非零状态码,给上层很难区分是算子调用错误(用户的锅)还是该 dtype 在该 SOC 上根本没有 kernel binary(packaging 的锅)。
  2. 建议官方提供aclrtSynchronizeStreamWithTimeout:当前所有 stream sync 只能无限等待,一旦 device kernel 死锁就只能kill -9进程(且会丢失 gcov 数据)。一个带 timeout 的 sync 接口能让测试 driver 优雅地标记"该用例超时"并继续跑下一个。
  3. gcov 路径可重定位.gcno中编码的源路径是绝对路径(/root/team3/ops-math/...),换机器/换工作区就要重编。建议 build.sh 默认加上-fprofile-prefix-map,让.gcno.gcda用相对路径,方便把覆盖率结果在团队间分享。
  4. build.sh --run_example的 cust 路径建议固化Wl,--copy-dt-needed-entries:本次直链时该选项是绕过libnnopbase.so二级依赖未传递的关键,否则会出现几百行undefined reference。这是一个普适问题,工具链层修复一次能省去每个用户重复踩坑。

附录 A:本次测试用例命名约定为<API>-<Dtype>[-<Shape>][-<Alpha>][-<Special>],例如Add-Mixed-FP16-FP32-AlphaNonOne表示aclnnAdd入口、self FP16 + other FP32 mixed dtype、alpha 不为 1。所有命名空间冲突已通过文件内static限定避免。

附录 B:覆盖率原始数据由gcov -b *.cpp.gcdabuild/math/abs/CMakeFiles/ophost_math_opapi_obj.dir/__/add/op_api/build/math/add/CMakeFiles/ophost_math_tiling_obj.dir/op_host/arch35/两个目录下采集。完整 gcov 输出已保存至/tmp/cov_*.txt

【免费下载链接】cann-competitions本仓库用于 CANN 开源社区各类竞赛、开源课题、社区任务等课题发布、开发者作品提交和展示。项目地址: https://gitcode.com/cann/cann-competitions

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/9 13:25:42

DeepEn2023:首个边缘AI能耗数据集,量化模型能效,驱动可持续AI发展

1. 项目概述与核心价值 最近几年&#xff0c;AI模型越做越大&#xff0c;从云端服务器一路“卷”到了我们手边的手机、摄像头和传感器上。这就是所谓的“边缘AI”。好处显而易见&#xff1a;响应快、隐私好、不依赖网络。但一个现实问题也随之而来——能耗。一个模型在云端数据…

作者头像 李华
网站建设 2026/5/9 13:24:18

3步搞定网易云音乐自动打卡:每天300首轻松升LV10的完整指南

3步搞定网易云音乐自动打卡&#xff1a;每天300首轻松升LV10的完整指南 【免费下载链接】neteasy_music_sign 网易云自动听歌打卡签到300首升级&#xff0c;直冲LV10 项目地址: https://gitcode.com/gh_mirrors/ne/neteasy_music_sign 还在为网易云音乐等级提升而烦恼吗…

作者头像 李华
网站建设 2026/5/9 13:19:45

CANN算子基础框架库

opbase 【免费下载链接】opbase 本项目是CANN算子库的基础框架库&#xff0c;为算子提供公共依赖文件和基础调度能力。 项目地址: https://gitcode.com/cann/opbase &#x1f525;Latest News [2025/12] 支持kirinx90&#xff0c;支持离线编译。[2025/09] opbase项目首…

作者头像 李华
网站建设 2026/5/9 13:19:18

CANN/ops-blas环境安装指南

环境部署 【免费下载链接】ops-blas 本项目是CANN提供的高性能线性代数计算以及轻量化GEMM调用算子库。 项目地址: https://gitcode.com/cann/ops-blas 您在学习QuickStart或各类教程操作之前&#xff0c;请先参考下面步骤完成基础环境搭建&#xff0c;确保已安装NPU驱动…

作者头像 李华
网站建设 2026/5/9 13:15:32

CANN π₀.₅模型训练优化说明

π₀.₅ 模型训练昇腾迁移与性能优化说明 【免费下载链接】cann-recipes-embodied-intelligence 本项目针对具身智能业务中的典型模型、加速算法&#xff0c;提供基于CANN平台的优化样例 项目地址: https://gitcode.com/cann/cann-recipes-embodied-intelligence 背景介…

作者头像 李华
网站建设 2026/5/9 13:13:32

CANN/cann-learning-hub:基于昇腾的DeepXTrace推理集群快慢卡在线检测

基于昇腾的DeepXTrace推理集群快慢卡在线检测 【免费下载链接】cann-learning-hub CANN 学习中心仓&#xff0c;支持在线互动运行、边学边练&#xff0c;提供教程、示例与优化方案&#xff0c;一站式助力昇腾开发者快速上手。 项目地址: https://gitcode.com/cann/cann-learn…

作者头像 李华