已合并
[CANNBot] BNInferGrad算子支持Ascend950 Ascendc实现 #7960
yulianjie创建于 7月25日
[CANNBot] BNInferGrad算子支持Ascend950 Ascendc实现 #7960
已合并
yulianjie创建于 7月25日
yulianjie成员
7月25日

描述

背景与目标

为满足 Issue #4333 中 BNInferGrad 算子在 Ascend 950 上的支持需求,本 PR 新增 BNInferGrad 的 AscendC 实现,打通算子定义、图推导、Host Tiling、Kernel、GEIR 示例及 UT 测试链路。

算子用于计算 Batch Normalization 推理模式下输入的反向梯度:

x_backprop=grads×scalebatch_variance+epsilonx\_backprop = grads \times \frac{scale}{\sqrt{batch\_variance + epsilon}}

其中 scale 和 batch_variance 沿 grads 的 C 维广播。

功能规格

  • grads:支持 2D~5D ND 张量,数据类型支持 FLOAT16、FLOAT、BFLOAT16。
  • scale、batch_variance:仅支持一维 FLOAT 张量,长度必须与 grads 的 C 维一致。
  • epsilon:可选 FLOAT 属性,默认值为 0.0001。
  • x_backprop:shape 和数据类型与 grads 保持一致。

主要改动

  1. 算子定义与图推导

    • 新增 BNInferGrad 原型、OpDef 注册、Graph Infer、InferShape 和 InferDataType 实现。
    • 配置 Ascend 950 AI Core,支持动态 Shape、动态 Rank 和动态 Format。
  2. Host Tiling

    • 新增 arch35 Tiling 实现及容量计算,根据输入 rank 分发 RANK_4(rank 2~4)和 RANK_8(rank 5)TilingKey。
    • 实现通道广播归一化、UB 容量评估和多核切分。
    • 增加输入 rank、scale/batch_variance 一维约束及通道长度一致性校验,并处理空 Tensor 场景。
  3. AscendC Kernel

    • 新增 Ascend 950 Kernel 入口及 BnInferGradKernel 模板实现。
    • FP32 路径直接计算;FP16/BF16 路径转为 FP32 计算后再转换回原数据类型。
    • 通过 NDDMA 随路广播读取 scale 和 batch_variance,支持多核分片计算与结果搬出。
  4. 示例、测试与文档

    • 新增 FP16 多核广播、BF16 数值校验的 GEIR 图模式示例,并覆盖非法输入 rank 拒绝场景。
    • 新增 Tiling、InferShape、Kernel UT 及 Python Golden。
    • 新增算子 README,并更新中文算子清单。

关联的 Issue

测试

  • Tiling UT:覆盖 FP16/FP32/BF16、2D~5D、RANK_4/RANK_8 分发、C 维广播、空 Tensor、多核大 Shape,以及 rank/通道长度非法场景。
  • InferShape UT:覆盖 2D、4D、5D 输入,校验输出 shape 跟随 grads。
  • Kernel UT:覆盖 FP32 的 RANK_4、RANK_8 数值结果校验。
  • GEIR 示例:覆盖 FP16 多核广播数值校验、BF16 数值校验,以及非法 scale/batch_variance rank 拒绝场景。
  • CI:编译、ophost/opapi/kernel/opgraph UT、PreSmoke 和静态检查已通过;当前 API_Check 为 WARNING,后续以 PR 页面最新流水线结果为准。

文档更新

  • 新增 norm/bn_infer_grad/README.md,补充产品支持、计算公式、参数约束和调用示例。
  • 更新 docs/zh/op_list.md,新增 BNInferGrad 算子条目。

类型标签

AI/Agent生成声明

likedislike
Pull Request已成功合入, 合并人@CANN-robot
(感谢 yulianjie 的贡献)
Yyulianjie成员
7月25日 创建了 pull request,commit c5dee845
Yyulianjie成员
7月25日 关联了issue:[Requirement|需求建议]: BNInferGrad算子支持Ascend950 Ascendc实现
atomgit-bot
atomgit-bot
7月25日 评论:

变更摘要

此 PR 为 BNInferGrad 算子新增 Ascend950 平台的 AscendC 实现,补充了从算子定义、形状推导、Tiling 到 Kernel 计算的完整链路。算子计算逻辑为 x_backprop = grads * scale / sqrt(batch_variance + epsilon),其中 scale 和 batch_variance 沿通道维广播。Kernel 采用 Broadcast 范式,通过 NDDMA 随路广播和 TBuf 管理实现多核 tile 切分,支持 fp16/fp32/bf16 三种数据类型,并覆盖 rank≤4 和 rank=5 两种 TilingKey 场景。

主要改动

  • 算子定义与注册:新增 bn_infer_grad_def.cpp、bn_infer_grad_proto.h,定义 BnInferGrad 算子的 3 输入(grads/scale/batch_variance)、1 输出(x_backprop)和一个 epsilon 属性,grads 与 x_backprop 支持 DT_FLOAT16/DT_FLOAT/DT_BF16,scale 与 batch_variance 固定为 DT_FLOAT

  • 形状与数据类型推导:新增 bn_infer_grad_infershape.cpp,实现 InferShape4BnInferGrad 和 InferDataType4BnInferGrad,使输出 x_backprop 的 shape 和 dtype 完全跟随输入 grads

  • Tiling 框架与 UB 切分策略:新增 bn_infer_grad_tiling_data.h/tiling_key.h/tiling_capacity.h/tiling_arch35.h/tiling_arch35.cpp,实现 FindSplitAxis(C 维禁止作为切分轴但计入 inner 累乘)、PadAndSqueeze(广播维归一化)、MultiCoreSplit(多核 tile 分配)及容量计算,TilingKey 按 RANK_4/RANK_8 区分,与数据类型无关

  • AscendC Kernel 实现:新增 bn_infer_grad.h 中的 BnInferGradKernel<T, RANK> 模板类,FP32 路径直接运算,FP16/BF16 路径先 Cast 到 FP32 再计算最后 Cast 回原类型;通过 CopyInBrc 借助 loopSrcStride=0 实现 NDDMA 随路广播,CopyOutOne 采用 DataCopyPad 搬出结果

  • Kernel 入口与 TilingKey 分发:新增 bn_infer_grad.cpp,作为 Ascend950 唯一 __global__ 入口,根据 RANK 模板参数选择 TilingData4 或 TilingData8,实例化对应的 BnInferGradKernel

likedislike
不准确?
atomgit-bot
atomgit-bot
7月25日 评论:

代码审查

经过对全部 16 个变更文件的逐文件详细审查,包括对以下维度的重点排查:

  • Ascend C 整数溢出与类型收窄:所有乘法链均在 int64_t 域完成,NPU 64GB 显存约束下无溢出风险;FindSplitAxis、MultiCoreSplit、stride 计算等关键路径均已保护。
  • 内存与 GM 偏移:GM 偏移全部使用 int64_t;workspace 固定 16MB 系统预留,无动态溢出风险。
  • 并发与流水线同步:SetFlag/WaitFlag(MTE2↔V↔MTE3↔MTE2)逐级成对,无遗漏;空 tensor 路径通过 start>=end 早退安全。
  • 算子接口 / Tiling:TilingKey 仅含 RANK,无历史字段顺序问题;epsilon 从 GetAttrs() 正确获取;shape/dtype 通过 GetInputShape/GetInputDesc 取得。
  • Pipeline 槽位分配:FP32 路径用 UB0-UB4,FP16/BF16 路径同样分配 5 个 TBuf,无槽位冲突。
  • 边界值:a_o、per_buf_elems、count 等关键变量在非空 tensor 路径上均正值且无除零风险。
  • 测试文件:FloatToHalfBits / FloatToBf16Bits 转换正确,GE API 返回值均已校验,无资源泄漏。

未发现正确性、安全性、可靠性或破坏性变更方面的问题。


关闭摘要:

优先级 数量
P0 0
P1 0
P2 0
P3 0

整体风险判定:低风险。代码结构清晰,遵循 AscendC Broadcast 范式与参考算子实现,流水线同步正确,tiling 与 kernel 数据流对齐,无发现性缺陷。

逐文件审查确认:

  • docs/zh/op_list.md — 无问题
  • norm/bn_infer_grad/CMakeLists.txt — 无问题
  • norm/bn_infer_grad/README.md — 无问题
  • norm/bn_infer_grad/examples/arch35/test_geir_bn_infer_grad.cpp — 无问题
  • norm/bn_infer_grad/examples/test_geir_bn_infer_grad.cpp — 无问题
  • norm/bn_infer_grad/op_graph/bn_infer_grad_proto.h — 无问题
  • norm/bn_infer_grad/op_graph/fusion_pass/.geikeep — 无问题(空文件)
  • norm/bn_infer_grad/op_host/arch35/bn_infer_grad_tiling_arch35.cpp — 无问题
  • norm/bn_infer_grad/op_host/arch35/bn_infer_grad_tiling_arch35.h — 无问题
  • norm/bn_infer_grad/op_host/arch35/bn_infer_grad_tiling_capacity.h — 无问题
  • norm/bn_infer_grad/op_host/bn_infer_grad_def.cpp — 无问题
  • norm/bn_infer_grad/op_host/bn_infer_grad_infershape.cpp — 无问题
  • norm/bn_infer_grad/op_kernel/arch35/bn_infer_grad.h — 无问题
  • norm/bn_infer_grad/op_kernel/arch35/bn_infer_grad_tiling_data.h — 无问题
  • norm/bn_infer_grad/op_kernel/arch35/bn_infer_grad_tiling_key.h — 无问题
  • norm/bn_infer_grad/op_kernel/bn_infer_grad.cpp — 无问题

⚠️ 已识别出整体风险,但无法提取行内评论,请参考整体评估。

likedislike
不准确?
CANN-robotCANN-robot成员
7月25日 添加了label:cann-cla/yes
此处折叠了183条消息 查看更多
CANN-robotCANN-robot成员
7月30日 添加了label:lgtm
CANN-robotCANN-robot成员
7月30日 关闭了关联的issue
CANN-robotCANN-robot成员
7月30日 合入了pull request
CANN-robot
CANN-robot成员
7月30日 评论:

Pull Request 已合并或已关闭。

If you want to solve this problem, you can click here to do it in the FAQs.

likedislike
conv2d_ci
7月31日 评论:
pipeline history
TimeNameResultLink
2026-07-31 10:26:00commit2026-07-30T09:33:32+08:00cbf4f38e
Compile_Result :x: NOT_RUN
SC_Result :x: FAILURE>>>
RDV_Result:ALL :x: RUNNING>>>
本次未执行的rdv任务为
序号任务名未执行理由
1tbe该组的RDV疑似不需要运行:[1951DC, 1951MDC, rdv_tbe_1971_01, rdv_tbe_1981_01, rdv_tbe_1951dc_01, Smoke_1951lite, Smoke_1911mdc, rdv_tbe_1971_02, rdv_tbe_1911rc_01, rdv_tbe_1911ep_01, Smoke_davinci_rdv_Nano, Smoke_nanoc11, rdv_tbe_1952_01]
2David该组的RDV疑似不需要运行:[rdv_tbe_david_01, rdv_tbe_david_02, rdv_tbe_david_03]
3transpose该组的RDV疑似不需要运行:[Davinci_RDV_conv_back_V121, conv_backward_1982_rdv, conv_backward_1971_rdv, conv_transpose_1952_rdv]
likedislike