已关闭
[Requirement|需求建议]: EluGradV2算子Ascend C实现贡献 #3068
m0_60351100创建于  6月3日关闭于  6月27日
m0_60351100
m0_60351100
6月3日 创建

Thanks for sending an requirement! Please fill in the following template to help quickly solve your problem.

Backgroud(背景信息)

• ## 一、背景信息

使用 Ascend C 编程语言对自定义反向算子 EluGradV2 进行了实现与优化,完成了该算子在昇腾 AI Core 上的原生落地,并通过
aclnn 方式对外提供调用接口。当前代码层面已注册 ascend310b 与 ascend910b 两类 AICore 配置,实际验收场景为 Ascend
910B4。

二、价值/作用

EluGradV2 的主要功能是计算 ELU 类激活函数的反向梯度。输入为上游梯度 dy 与张量 x,其中 x 在不同模式下含义不同:

  • 当 is_result = false 时,x 表示前向输入;
  • 当 is_result = true 时,x 表示前向输出结果。

核心数学公式如下。

当 x > 0 时:

y=dy×scaley = dy \times scale

当 x \le 0 且 is_result = false 时:

y=dy×α×scale×inputscale×exp⁡(x×inputscale)y = dy \times \alpha \times scale \times input_scale \times \exp(x \times input_scale)

当 x \le 0 且 is_result = true 时:

y=dy×inputscale×(x+α×scale)y = dy \times input_scale \times (x + \alpha \times scale)

该实现以 Ascend C 原生 Kernel 替代通用组合式实现,围绕 dtype、is_result、数据规模和对齐特征进行了多路径调度设计,兼顾
精度稳定性与性能表现。

三、设计方案

3.1 使能方式

Aclnn 直调。

3.2 总体设计

3.2.1 算子支持的数据类型

float16、float32、bfloat16

3.2.2 Host侧设计

Host 侧由算子定义、推导和 tiling 三部分组成,负责输入输出描述、属性下发、分核策略和执行模式选择。

(1) 算子定义与推导行为

输入为 dy、x,输出为 y;属性为:

  • alpha
  • scale
  • input_scale
  • is_result

输出 shape 与输入 dy 保持一致。
输出 dtype 默认继承输入 dtype;若上层已预设输出 dtype,则保留预设结果。

代码中同时显式注册了多组 dtype 组合,避免完全依赖 InferDataType 进行隐式推导。

(2) 分核策略

遵循优先满核原则,结合 256B block 对齐规则进行分核。
先根据总数据量和 CORE_CHUNK 估算使用核数,再按 block 数均分:

  • 前若干核作为大核,处理 bigCoreDataNum
  • 其余核作为小核,处理 smallCoreDataNum
  • 最后一核额外记录 lastCoreDataNum,用于尾块处理

(3) 数据切分和内存优化策略

Host 侧根据以下因素联合决定 tileDataNum、bufferOpen 与 computeChunk:

  • 输入 dtype
  • is_result
  • 总长度与单核平均负载
  • 是否满足对齐 fast path 条件
  • UB 容量是否足够支撑双缓冲和临时 scratch buffer

当前实现中,generic 路径被刻意收敛为更保守的单 computeChunk tile 处理方式,以减少一个 tile 内继续细分子 chunk 带来的精
度风险。对 float16/bfloat16 路径,会额外为 float32 临时计算申请 scratch buffer。

(4) tilingKey 规划策略

当前采用 schMode 单模板参数方式下发调度模式,共规划 8 类模式:

  • SAFE_EXP
  • SAFE_RESULT
  • SINGLE_TILE_EXP
  • SINGLE_TILE_RESULT
  • MIXED_EXP_FAST
  • MIXED_RESULT_FAST
  • FLOAT16_EXP_FAST
  • FLOAT16_RESULT_FAST

其中:

  • SAFE_* 用于通用稳定路径
  • SINGLE_TILE_* 用于小张量单 tile 直通路径
  • MIXED_*_FAST 用于 bfloat16 对齐 fast path
  • FLOAT16_*_FAST 用于 float16 特定对齐 fast path

3.2.3 Kernel侧设计

Kernel 侧采用基于 schMode 的编译期分发机制,不同模式对应不同 Kernel 类或同一 Kernel 类下的不同行为分支。整体执行链路统
一为 Init 初始化与 Process 计算两阶段。

(1) 入口分发

算子入口根据 Host 下发的 tilingKey 选择具体实现,分发目标包括:

  • 通用 KernelEluGradV2
  • 小张量 KernelEluGradV2SingleTile
  • float16 fast path
  • bfloat16 fast path
  • result-mode mixed-output 专用路径

(2) Init阶段

完成以下初始化工作:

  • GM 输入输出地址绑定
  • 读取 tiling 参数:coreNum、bigCoreDataNum、smallCoreDataNum、tileDataNum、computeChunk 等
  • 计算当前核的起始偏移和处理长度
  • 初始化 TPipe
  • 初始化输入输出队列 TQue
  • 初始化临时缓冲区 TBuf,包括:
    • maskBuf
    • tmpBufF32
    • gradsBufF32
    • actBufF32

当命中小张量单 tile 直通条件时,直接初始化 direct buffer,不再走常规 queue 流水。

(3) Process与tile循环

根据调度模式执行不同流程:

  • 小张量单 tile:直接 CopyIn -> Compute -> CopyOut
  • 单缓冲或单 tile:顺序处理所有 tile
  • 双缓冲场景:执行 CopyIn / Compute / CopyOut 流水线重叠

(4) CopyIn阶段

从 GM 中按 tile 偏移读取 dy 和 x 到 UB。
对于尾 tile,使用 DataCopyPad 处理不足整块对齐的情况。

(5) Compute阶段

计算遵循 element-wise 范式,不同路径的核心逻辑如下:

  • float32 + is_result=true:调用 ComputeFloatResultMode
  • float32 + is_result=false:调用 ComputeFloatExpMode
  • float16/bfloat16 + is_result=true:调用 ComputeMixedResultMode
  • float16/bfloat16 + is_result=false:调用 ComputeMixedExpMode

为保证精度稳定性,generic 路径大量采用独立 tmpBufF32 保存负分支中间结果,而不是直接在输入 tensor 上原地复用。整体计算
过程通常为:

  1. 生成正负区间 mask
  2. 计算负分支结果到独立临时 buffer
  3. 计算正分支结果
  4. 通过 Select 完成正负分支合并

对于 float16 / bfloat16,先 Cast 到 float32 计算,再根据输出类型 Cast 回原类型。

(6) CopyOut阶段

将 UB 中的结果按 tile 写回 GM。
普通 tile 使用 DataCopy,尾 tile 使用 DataCopyPad,并释放对应输出队列资源。

3.3 支持硬件

aarch64 + Atlas 800I A2推理服务器

3.4 算子约束限制

  • 数据类型约束:dy 与 x 的数据类型必须一致,支持 float16、float32、bfloat16。
  • shape约束:dy、x、y 的 shape 必须一致。
  • 维度限制:aclnn 参数检查中限制输入维度不超过 8 维。
  • 属性类型约束:alpha、scale、input_scale 需可转换为 float32;is_result 为 bool。
  • 属性取值约束:当 is_result = true 时,alpha 不允许为负值。
  • 格式说明:当前实现以 ND 为主;若输入为某些特殊存储格式(如 FRACTAL_NZ),接口层会给出精度风险告警。

Origin(信息来源)

北京交通大学 赵宏智老师团队

Benefit / Necessity (价值/作用)

Design(设计方案)

likedislike
m0_60351100m0_60351100
6月3日 关联了pull request:Ascend C实现EluGradV2算子贡献
oscillatedoscillated成员
6月3日 将 hyy_bjtu 设为负责人
CANN-robotCANN-robot成员
6月27日 关闭了 issue
CANN-robotCANN-robot成员
6月27日 添加了label:resolved