Pull Request已成功合入, 合并人@CANN-robot
(感谢 ConanYao 的贡献)变更摘要
本 PR 实现了一个基于 AscendC 框架的逐元素除法算子 DivCustom(即 z = x / y),采用 Double Buffer(BUFFER_NUM=2)的 Tiling 策略完成 GM→UB→GM 的数据通路流水线。主要新增了核函数实现文件 div_custom.asc 和构建脚本 run.sh,涵盖 Device 侧核函数、Host 侧调度逻辑以及端到端的精度验证。
主要改动
- 新增
div_custom.asc核心算子文件:定义了DivCustomTilingDataTiling 参数结构体、KernelDiv算子类以及核函数入口div_custom,完整实现了 CopyIn→Compute(Div)→CopyOut 的流水线逻辑,使用TQue队列和TPipe管道管理 UB 上的 Double Buffer 内存。 - 实现 Host 侧调度函数
kernel_div:封装了 ACL 环境初始化、Device 端 GM 内存分配(aclrtMalloc)、Host-to-Device 数据拷贝(aclrtMemcpy)、单核启动核函数以及结果回拷的完整流程,并在结束时正确释放所有资源。 - 内置验证与测试逻辑:
VerifyResult函数对比算子输出与 CPU 侧计算的 golden 值(valueX / valueY),通过std::equal逐元素比较并在控制台打印结果;main函数使用 8×2048 长度的固定测试张量(x=1.2, y=2.3)驱动端到端测试。 - 新增
run.sh构建脚本:激活 CANN 工具链环境变量,使用 CMake 在build/目录下编译并运行div_test测试可执行文件。


代码审查
审查总结
| 文件 | 审查结果 |
|---|---|
CMakeLists.txt |
✅ 无问题(与模板一致,CMake 配置正确) |
div_custom.asc |
⚠️ 4 个问题(2 个 P2,2 个 P3) |
run.sh |
⚠️ 1 个问题(P2) |
按优先级统计: P0: 0,P1: 0,P2: 3,P3: 2
整体风险判断: 该实现的测试用例(totalLength=16384, tileNum=8)可在当前环境下正确运行并通过精度验证。但存在三个中等风险问题:① tiling 整除假设(当前测试恰好整除,通用输入会静默丢尾部元素);② ACL API 全链路无错误检查(显存不足等场景会崩溃);③ run.sh 缺少 set -e(环境异常时错误信息混乱)。此外 Double Buffer 资源已分配但未实现流水线重叠,属于设计实现偏差。建议在合入前至少修复前两个 P2 问题。
| 类型 | 数量 |
|---|---|
| 🔴 阻塞 | 0 |
| 🟡 建议 | 5 |
💬 仅评论


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
For more, you also can visit HICANN
PR Approval Progress
✅ Congratulations! All modules have met the lgtm and approve requirements.
Module Approval Details
| module | lgtm status | approve status |
|---|---|---|
| repo-cann/cann-outreach | ✅ shaoyf, 傅涛 (2/2) | ✅ 傅涛, shaoyf (2/1) |
💡 Tip:
- Committer can comment
/approveor/lgtm- Commenting
/approveimplies both code review (lgtm) and intent to merge (approve)
CLA Signature Pass
JaneConan, thanks for your pull request. All authors of the commits have signed the CLA. 👍


🟡 Medium Priority
第 35 行:this->tileLength = totalLength / tileNum; 使用整数除法计算每个 tile 的元素数。当 totalLength 不能被 tileNum(始终为 8)整除时,末尾 totalLength % tileNum 个元素会被静默丢弃,不会被处理或输出。
更严重的是当 totalLength < tileNum(例如输入向量长度 < 8)时,tileLength = 0,导致:
触发条件:kernel_div 是公开函数(第 130 行),接受任意长度的输入向量;tileNum = 8 硬编码(第 134 行),与输入长度无关。当前测试 totalLength = 8 * 2048 恰好整除,掩盖了此缺陷。
建议:增加尾块处理:前 tileNum-1 个 tile 使用均分长度,最后一个 tile 取剩余元素;或在上层 kernel_div 中确保 totalLength 对齐并拒绝不对齐的输入。


🟡 Medium Priority
kernel_div 函数(第 130–172 行)中调用了多个 ACL API,但所有返回值均未检查,包括:
每个 ACL API 都返回 aclError。如果任一失败(如 Device 内存分配失败返回 nullptr),后续代码会继续使用空指针或无效状态,导致:
- 空指针解引用崩溃(
aclrtMemcpy传入nullptr) - 核函数启动到无效设备指针,产生不可预测的结果
- Device 资源泄漏(前面成功的分配在后继失败时未释放)
建议:为每个 ACL API 调用增加返回值检查:若 != ACL_SUCCESS,记录错误、清理已分配资源,并抛出异常或返回错误码。至少应检查 aclrtMalloc / aclrtMemcpy 的返回值。


🟡 Medium Priority
changed line → affected behavior/contract → failure mode → suggested fix
第 139–169 行 kernel_div 函数中连续调用了 aclInit、aclrtSetDevice、aclrtCreateStream、aclrtMalloc(3 次)、aclrtMemcpy(3 次)、aclrtSynchronizeStream 共 10 个 ACL API,全部未检查返回值(aclError)。
失败模式:若任一 aclrtMalloc 因显存不足返回失败且指针保持 nullptr,后续 aclrtMemcpy 会向空指针拷数据导致段错误;若 aclrtMemcpy 失败,Device 侧数据未正确就绪,核函数计算的是随机/残留数据,最终 VerifyResult 可能通过(巧合一致)或失败但无明确错误诊断。
建议:对每个 ACL 调用检查返回值(如 ACL_RT_SUCCESS),失败时按逆序释放已分配的资源并报告错误。建议用 RAII 或 goto cleanup 模式统一管理资源释放路径。


🟡 Medium Priority
changed line → affected behavior/contract → failure mode → suggested fix
第 1–9 行整个 run.sh 脚本缺少 set -euo pipefail(或至少 set -e)。第 3 行 source "$ASCEND_TOOLKIT_HOME/set_env.sh" 若因 ASCEND_TOOLKIT_HOME 未设置而展开为 /set_env.sh(路径不存在),source 失败后脚本继续执行:第 5 行 ASCEND_HOME_PATH 同样为空,ASC_DIR 被设为无效路径;第 6–9 行用 && 串联,cmake 可能因找不到 ASC 包而失败,但之前 mkdir -p build 和 cd build/ 已成功执行,用户在 build 目录中看到 cmake 报错但难以定位根因(实际是环境未初始化)。
建议:在 #!/bin/bash 后添加 set -euo pipefail,并对 ASCEND_TOOLKIT_HOME 和 ASCEND_HOME_PATH 做非空检查,为空时输出明确错误信息并退出。
|
14 | + #!/bin/bash |
|
15 | + set -euo pipefail |
|
16 | + # 激活cann环境,可根据实际情况修改,在线环境一般不用修改, |
|
17 | + : "${ASCEND_TOOLKIT_HOME:?ASCEND_TOOLKIT_HOME is not set}" |
|
18 | + source "$ASCEND_TOOLKIT_HOME/set_env.sh" |
|
19 | + mkdir -p build |
|
20 | + : "${ASCEND_HOME_PATH:?ASCEND_HOME_PATH is not set}" |
|
21 | + export ASC_DIR="$ASCEND_HOME_PATH/aarch64-linux/tikcpp/ascendc_kernel_cmake/" |
|
22 | + cd build/ |
|
23 | + cmake .. |
|
24 | + make |
| 14
25 | ./div_test |


🟡 Medium Priority
changed line → affected behavior/contract → failure mode → suggested fix
第 35 行:this->tileLength = totalLength / tileNum;(整数除法)。当 totalLength 不能被 tileNum(硬编码为 8)整除时,tileLength 向下取整。Process() 循环(第 52 行)处理 tileNum 个 tile,每个 tile 固定处理 tileLength 个元素,总处理量 = tileNum × (totalLength / tileNum) ≤ totalLength,余数 totalLength % tileNum 个尾部元素永远不会被处理——对应 zGm 输出位置保持不变(未写入),而 golden 期望这些位置有正确结果,导致验证失败。
当前 main() 中 totalLength = 8 × 2048 = 16384 恰好整除,故测试通过。但 kernel_div 是公开接口,接受任意长度 vector,触发条件是调用者传入长度不为 8 的倍数的数据。
建议:在 Init 中将 tileLength 向上取整,并在最后一个 tile 的 CopyIn/Compute/CopyOut 中根据剩余元素数调整实际处理长度;或者在 kernel_div 入口处校验整除性并报错。


/ai review


/ai summary


变更摘要
本 PR 实现了一个基于昇腾 AscendC 框架的逐元素除法算子 DivCustom,完成向量 z = x / y 的核函数计算。核心采用 Double Buffer(BUFFER_NUM=2)Tiling 策略,将 GM→UB 的数据搬运(CopyIn)与 UB 上的向量除法计算(Compute/Div)流水线重叠,最后将结果从 UB 写回 GM(CopyOut),并配套 Host 侧的 ACL 资源管理与精度验证逻辑。
主要改动
- 新增
div_custom.asc核函数实现文件:包含KernelDiv类,封装了基于TPipe/TQue队列的 Double Buffer 流水线(CopyIn→Compute→CopyOut),使用Div指令完成逐元素 float 除法,并通过CalcTileLength处理尾部不完整 tile 以避免数据丢失。 - 定义 Tiling 参数结构体
DivCustomTilingData:将totalLength、tileNum、tileLength从 Host 侧传入核函数,以固定TILE_LENGTH=2048向上取整分块,支撑任意长度输入。 - 实现 Host 侧驱动函数
kernel_div:通过ACL_CHECK宏统一管理 AscendCL 初始化、Device 内存分配、Host↔Device 数据搬运、核函数启停及资源释放,失败时跳转至cleanup标签统一回收资源。 - 提供
VerifyResult精度验证与main测试入口:构造 x=1.2、y=2.3 的测试向量,调用kernel_div后在 Host 侧与 golden 值逐元素比对,输出验证结果。 - 新增
run.sh构建执行脚本:使用set -euo pipefail严格错误处理,自动激活 CANN 环境并执行 cmake 构建与运行。


/compile


The MR can not be merged, because of CodeReview discussion not resolved
If you want to solve this problem, you can click here to do it in the FAQs.


当前PR是否有AI参与:
[x] 否
[ ] 是
__1. AI Agent 平台:
__2. AI 模型:
__3. Prompt上下文 :
PR功能描述 / 为什么需要这个合入:
实现代码侦探 Challenge01-DivCustom 的逐元素除法算子 DivCustom(z = x / y)。
基于 Double Buffer(BUFFER_NUM=2)完成 Tiling 切分与 CopyIn/Compute/CopyOut 流水线;
使用 AscendC 的 Div 指令完成逐元素除法运算;
数据通路:GM(x,y) --CopyIn--> UB --Compute(Div)--> UB --CopyOut--> GM(z)。
环境:昇腾 910B3,CANN 9.0.0;
构造 x=1.2、y=2.3,输出与 golden 一致,运行结果 [Success] Case accuracy is verification passed.
该PR关联的issue
https://gitcode.com/cann/cann-learning-hub/issues/215
希望检视人员了解:
改动类型 / Change Type
测试信息 / Testing
检查清单 / Checklist
以下为测试结果