已开启
【代码侦探Challenge13】 个人开发者 - exercises #5637
【代码侦探Challenge13】 个人开发者 - exercises #5637
已开启
小久创建于 22 小时前
小久
小久
22 小时前

个人开发者

团队信息

  • 提交者: weixin_48190404 (zhaoyuea9@163.com)
  • 身份: 企业员工
  • 单位: 个人开发者

成员

算子: exercises

算子实现介绍

采用多核并行实现,每核至少处理1024个元素,UB内按双缓冲切分,搬运与计算均按32B对齐;negative_slope属性通过TilingData由Host下发至Kernel,half类型先转为float计算以保证精度。

likedislike
合并受阻
小久小久
22 小时前 创建了 pull request,commit 2180669f
atomgit-bot
atomgit-bot
22 小时前 评论:

变更摘要

本 PR 为 CANN「代码侦探」第十三期 exercises 算子题目提交,围绕自定义 Leakyrelu 算子补全了一套完整实现:包含算子定义与形状推导、Host 侧 Tiling、AscendC Kernel 实现、aclnn 样例调用、参考实现与数据校验脚本,以及基于 gtest 的 Host/Kernel UT 与构建脚本。整体上形成从算子注册、tiling 下发、kernel 计算到样例与单测验证的闭环。

主要改动

  • 算子定义与注册: 新增 op_host/leakyrelu_def.cpp,通过 OpDef 注册 Leakyrelu,输入 x、输出 y 均声明 REQUIRED 且支持 DT_FLOAT / DT_FLOAT16、格式 FORMAT_ND 并启用 AutoContiguous,属性 negative_slope 为 Float,AI Core 配置为 ascend910b;leakyrelu_infershape.cpp 中 InferShapeLeakyrelu 将输入 shape 直接传给输出。
  • Tiling 与模板键: op_host/leakyrelu_tiling.cpp 的 LeakyreluTilingFunc 依据 AIV 核数、UB 容量和 32B 对齐做多核与 UB 两级切分,读取 negative_slope 属性(缺失时回退默认值),写入 LeakyreluTilingData 并通过 SetTilingKey 按 dtype 选择 LEAKYRELU_TPL_SCH_MODE_0(half)或 MODE_1(float);leakyrelu_tiling_key.h 用 ASCENDC_TPL_ARGS_DECL 声明 schMode 模板参数。
  • Kernel 计算实现: op_kernel/leakyrelu.h 的 NsLeakyrelu::Leakyrelu<T> 使用 TQue 双缓冲搬运并按 blockFactor/ubFactor 循环,按 max(x,0) + negative_slope * min(x,0) 计算;half 分支先 Cast 到 float 再计算以降低精度损失,leakyrelu.cpp 按 tilingKey 分派 half / float 模板实例。
  • Tiling 数据结构与兼容标记: leakyrelu_tiling_data.h 定义 LeakyreluTilingData(totalNum、blockFactor、ubFactor、slopeTag、negativeSlope、reserved),并引入 LEAKYRELU_DEFAULT_SLOPE 与 LEAKYRELU_SLOPE_TAG 标记;kernel 在 slopeTag 不匹配时回退默认斜率,保证直接构造 tiling 数据的 Kernel UT 仍可正确计算。
  • 样例、构建与测试链路: 新增 build.sh(支持 -j、--make_clean、-u、-e,含源码指纹增量重建与产物检查)、examples/ 下基于 aclnnLeakyreluGetWorkspaceSize/aclnnLeakyrelu 的 NPU 样例和 samples/sample.py 的 generate/verify(含 rtol/atol 比对与 reference.impl 参考实现),以及 tests/ut 下 TilingContextFaker、InferShapeContextFaker、case executor 等测试基础设施和 test_leakyrelu_tiling.cpp、test_leakyrelu.cpp 等 Host/Kernel UT 用例。
likedislike
不准确?
小久
小久
22 小时前 评论:

/compile

likedislike
atomgit-bot
atomgit-bot
22 小时前 评论:

代码审查

审查结论

  • [建议] 2026/CANN-Code-Detective/Challenge13-LeakyReluCustom/PR_code/ZY_weixin_48190404_13/code/exercises/CMakeLists.txt:14 fix: 默认 ASCEND_COMPUTE_UNIT 覆盖三个 SoC 而算子仅注册 ascend910b
  • [建议] 2026/CANN-Code-Detective/Challenge13-LeakyReluCustom/PR_code/ZY_weixin_48190404_13/code/exercises/op_kernel/leakyrelu.h:112 fix: 尾块按 32B 对齐多读会越过输入张量 GM 边界
  • [建议] 2026/CANN-Code-Detective/Challenge13-LeakyReluCustom/PR_code/ZY_weixin_48190404_13/code/exercises/op_kernel/leakyrelu.h:160 fix: 尾块写回使用未按 32B 对齐的元素个数
  • [阻塞] 2026/CANN-Code-Detective/Challenge13-LeakyReluCustom/PR_code/ZY_weixin_48190404_13/code/exercises/tests/ut/op_host/test_leakyrelu_tiling.cpp:36 fix: op_host UT 的 expectTilingData 期望值与实际 tiling 输出不一致
类型 数量
🔴 阻塞 1
🟡 建议 3

⛔ 需要修改

likedislike
不准确?
CANN-robotCANN-robot成员
22 小时前 添加了label:cann-cla/yes
CANN-robot
CANN-robot成员
22 小时前 评论:

Thanks for your pull-request.
The full list of commands accepted by me can be found at here.
You can get sig-info at here.
You can self-configure the PR merge rules for this repository. For more details, please refer to Here.
For more, you also can visit HICANN.


PR Approval Progress

⚠️ This PR does not yet meet the following requirements:lgtm (requires ≥ 2 person(s) per module)、approve (requires ≥ 1 person(s) per module)

Module Approval Details

module lgtm status approve status
repo-cann/cann-outreach ❌ (0/2)(You can also ask: Carolina_yuan, li-shengxian3, shaoyf, 王艳秋, 颜亚文) ❌ (0/1)(You can also ask: shaoyf, 田晓亮, Carolina_yuan, 颜亚文, gcw_tgPdOLZT)

💡 Tip:

  • Committer can comment /approve or /lgtm
  • Commenting /approve implies both code review (lgtm) and intent to merge (approve)

CLA Signature Pass

weixin_48190404, thanks for your pull request. All authors of the commits have signed the CLA. 👍

likedislike
CANN-robotCANN-robot成员
22 小时前 将yanhf,jxlang,shaoyf,TianXL,yanyawen,fullt,gcw_tgPdOLZT,Carolina_yuan,luzx66,cherry_03,li-shengxian3设为评审人
CANN-robotCANN-robot成员
22 小时前 将yanhf,jxlang,shaoyf,TianXL,yanyawen,fullt,gcw_tgPdOLZT,Carolina_yuan,luzx66,cherry_03,li-shengxian3设为审查人
小久小久
21 小时前 修改了pull request 的描述
atomgit-bot
atomgit-bot21 小时前进行代码检视1
2026/CANN-Code-Detective/Challenge13-LeakyReluCustom/PR_code/ZY_weixin_48190404_13/code/exercises/tests/ut/op_host/test_leakyrelu_tiling.cpp
@@ -0,0 +33,4 @@
33+// expectTilingData: 参考 op_host/leakyrelu_tiling.cpp 中 TilingData 各字段的赋值
34+// expectWorkspaces: 参考 op_host/leakyrelu_tiling.cpp 中 GetWorkspaceSize 的逻辑
35+static LeakyreluTestParam testCases[] = {
36+ {"leakyrelu_0", {8, 2048}, ge::DT_FLOAT, ge::FORMAT_ND, {8, 2048}, ge::DT_FLOAT, ge::FORMAT_ND, "Ascend910B", ge::GRAPH_SUCCESS, 1UL, "0 1 0 ", {0}, 64, 262144, 4096},
atomgit-bot
atomgit-bot21 小时前评论:

🟠 High Priority

建议:先执行一次 tiling(可用 ExecuteTiling 取 TilingInfo),把 totalNum/blockFactor/ubFactor/slopeTag/negativeSlope+reserved 这 5 个 int64 槽位的真实值填入 expectTilingData;或改用字段级断言替代整段字符串比较。

likedislike
不准确?
atomgit-bot
atomgit-bot21 小时前进行代码检视1
2026/CANN-Code-Detective/Challenge13-LeakyReluCustom/PR_code/ZY_weixin_48190404_13/code/exercises/CMakeLists.txt
@@ -0,0 +13,4 @@
13+ 
14+if(NOT DEFINED ASCEND_COMPUTE_UNIT OR ASCEND_COMPUTE_UNIT STREQUAL "")
15+ set(ASCEND_COMPUTE_UNIT ${ARCH32_COMPUTE_UNITS} ${ARCH35_COMPUTE_UNITS})
16+endif()
atomgit-bot
atomgit-bot21 小时前评论:

🟡 Medium Priority

变更点:本文件第 14–16 行在未传入 -DASCEND_COMPUTE_UNIT 时,把 ASCEND_COMPUTE_UNIT 默认为 ascend910b ascend910_93 ascend950(5–16 行的 ARCH32/ARCH35 列表)。
受影响契约:npu_op_package 会按 ASCEND_COMPUTE_UNIT 逐 SoC 打包,而 op_host/leakyrelu_def.cpp:26 只写了 this->AICore().AddConfig("ascend910b"),即算子仅在 ascend910b 上注册。
失效模式:一旦不显式传参(例如直接 cmake -S . -B build && cmake --build build)构建,产出的 vendor 包里 ascend910_93 / ascend950 目录没有该算子(或 arch35 下 kernel 编译/调优路径无对应 op def),在这些 SoC 上运行 examples 会报“算子未注册/找不到算子”,而不是构建期就暴露。当前 build.sh:50/114 显式传了 -DASCEND_COMPUTE_UNIT=ascend910b,所以默认路径才触发,实测概率中等。

建议:将默认值收敛为算子实际注册的 SoC(ascend910b),或在 op_host/leakyrelu_def.cpp 中为 ARCH32/ARCH35 列表中的每个 SoC 追加 AICore().AddConfig(...),避免出现“包里有 SoC 目录、但没有该算子”的不一致。

likedislike
不准确?
atomgit-bot
atomgit-bot21 小时前进行代码检视1
2026/CANN-Code-Detective/Challenge13-LeakyReluCustom/PR_code/ZY_weixin_48190404_13/code/exercises/op_kernel/leakyrelu.h
@@ -0,0 +163,4 @@
163+ const int64_t offset = progress * ubLength_;
164+ // 只写回有效元素,避免越界污染输出张量尾部
165+ DataCopy(outputGMY[offset], yLocal, static_cast<int32_t>(currentNum));
166+ outputQueueY.FreeTensor(yLocal);
atomgit-bot
atomgit-bot21 小时前评论:

🟡 Medium Priority

变更行:leakyrelu.h:165 DataCopy(outputGMY[offset], yLocal, static_cast<int32_t>(currentNum));。

证据链:同一文件的 CopyIn(leakyrelu.h:117)刻意把搬入长度 AlignUp 到 alignElems_ 以满足 AscendC DataCopy 的 32B(datablock)长度对齐要求,而 CopyOut 却直接用未对齐的 currentNum。currentNum 来自 Process(第 177-178 行)remain < ubLength_ ? remain : ubLength_;host tiling 未对齐 totalNum(op_host/leakyrelu_tiling.cpp:96-105),所以末核最后一块的 currentNum 常常不是 alignElems_(float 8 / half 16)的整数倍。

失败模式:DataCopy 的搬运长度按 datablock 粒度处理,长度非 32B 整数倍时行为不符合接口约定——按 32B 向上取整会把 UB 中尾部未初始化/无意义数据写到 GM,对最后一个核就是写到输出张量末尾之外(破坏相邻输出或内存池数据,验证脚本按精确字节数比对时表现为越界污染);若硬件严格校验则直接报 AIC Error。

建议:尾块写回使用 DataCopyPad(按 currentNum*sizeof(T) 的真实字节长度),或统一按对齐长度写回并在 host 侧保证输出张量有对齐余量,避免向 GM 写入非 32B 对齐长度。

likedislike
不准确?
atomgit-bot
atomgit-bot21 小时前进行代码检视1
2026/CANN-Code-Detective/Challenge13-LeakyReluCustom/PR_code/ZY_weixin_48190404_13/code/exercises/op_kernel/leakyrelu.h
@@ -0,0 +115,4 @@
115+ const int64_t offset = progress * ubLength_;
116+ // 按 32B 对齐长度搬入;尾部多读的元素只参与计算,不会被写回 GM
117+ const int64_t copyNum = AlignUp(currentNum, alignElems_);
118+ DataCopy(xLocal, inputGMX[offset], static_cast<int32_t>(copyNum));
atomgit-bot
atomgit-bot21 小时前评论:

🟡 Medium Priority

变更行:leakyrelu.h:95-97 用 gmLength = AlignUp(blockLength_, alignElems_) 声明 GlobalTensor 长度,leakyrelu.h:117-118 再用 copyNum = AlignUp(currentNum, alignElems_) 搬入。

证据链:host 侧 tiling(op_host/leakyrelu_tiling.cpp:96-107)计算 totalNum 为各维乘积,未做 32B 对齐,只有 blockFactor = CeilAlign(CeilDiv(splitNum, usedCoreNum), alignElems) 对齐;因此最后一个核的 blockLength_ = totalNum - offset 可以是任意值(例如 float 输入 9 个元素、blockFactor=8 时,末核 blockLength_=1)。此时 gmLength = 8、copyNum = 8,但该核实际可用元素只有 1 个。

失败模式:DataCopy 会读取 x + totalNum 之后最多 alignElems_-1 个元素(float 为 28 字节、half 为 30 字节)的越界 GM 数据;SetGlobalBuffer 声明的长度本身也已超过真实张量长度,越界读到的内容依赖相邻内存,虽只用于计算不回写,但越过输入张量末尾属于典型 GM 越界访问,在尾部恰好压到内存池边界时可能触发 AIC Error/精度校验异常。

建议:把尾块搬入改为 DataCopyPad(blockLen 取 currentNum*sizeof(T),越界部分由 pad 参数补齐),并与 CopyOut 的对齐策略保持一致,避免按 AlignUp 后的长度读取输入张量之外的内存。

likedislike
不准确?
小久小久
21 小时前 修改标题为 “【代码侦探Challenge13】 个人开发者 - exercises”,原标题为“[代码侦探(第十三期)] 个人开发者 - exercises”
小久小久
21 小时前 关联了issue:【代码侦探Challenge13】 个人开发者 - exercises