已关闭
[Requirement|需求建议]: MulNoNan 算子新增 Ascend 910B(A2/A3)独立 Kernel 支持 #2841
gcw_6JDqrnev创建于  8月25日关闭于  8月25日
gcw_6JDqrnev
8月25日 创建

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

一、背景信息 (必填)

MulNoNan 算子实现 y = (x2 == 0) ? 0 : x1 * x2(逐元素乘,支持 ND 广播),用于在 x2 为 0 时输出 0 而不是 Inf*0 = NaN,避免 NaN 在计算图中传播。

当前 MulNoNan 仅支持 Ascend 950(A5 架构,arch35 tiling)。本需求为其新增 Ascend 910B(A2/A3,升腾 910b,arch22)的独立实现:新增 arch22 tiling(简化 key 配置)、vectorized 通用 kernel 入口,并补齐 op_api 平台判断、算子定义注册、README/CMake 与 arch22 tiling 单测;A5 路径保持不变(其 tiling 迁移至 arch35 目录,行为不变),同时移除调试用的 test.sh。

二、价值/作用 (必填)

  • 补齐 MulNoNan 在主流训练/推理卡 Ascend 910B(A2/A3)上的支持,使 aclnn 直调用户可在 910B 上直接使用该算子,消除 Inf*0=NaN 导致的精度/数值异常问题;
  • 支持 fp16/fp32/bf16 三种数据类型,覆盖常用训练/推理场景;
  • kernel 采用 AIV 纯 vector 化实现(Compares(NE) + Mul + Select),并对连续大段走 TQue 双缓冲流水,多核并行,保证 910B 上的性能;
  • 与原 A5 路径解耦,两代架构可独立演进、独立回归。

三、设计方案 (必填)

总体思路:沿用 A5(arch35)的 DAG 语义 mask = (x2 != 0); y = mask ? (x1 * x2) : 0,在 910B(arch22)上分别实现 host 侧 tiling 与 kernel 侧 vectorized 计算;host 侧按输出 word count 选择多核 block dim 并推导 ND 广播 strides,kernel 侧按 32B/整 tile 对齐做多核分块,未对齐头尾与小广播段走标量兜底。

3.1 使能方式(涉及哪些框架:如Aclnn直调、Pytorch训练等)

Aclnn 直调:通过 aclnnMulNoNan 接口使能;op_api 侧 IsAiCoreSupport 平台判断由仅 DAV_3510 扩展为 DAV_3510 || DAV_2201(A2/A3),同时注册 MulNoNan 的 op 定义(ge REG_OP)与 AICore ascend910b 配置。

3.2 总体设计
3.2.1 算子支持的数据类型
  • 输入 x1/x2、输出 y:DT_FLOAT16(fp16)、DT_FLOAT(fp32)、DT_BF16(bf16);
  • 约束:x1/x2/y 三者 dtype 必须一致,不一致或非上述类型(如 int32)直接拒绝;
  • kernel 内部:fp16/bf16 输入提升为 fp32 做 cmp/mul/select 计算,输出前再 round 回原类型(与 A5 FloatCast DAG 同一精度策略)。
3.2.2 host侧设计
  • op_api(op_api/mul_no_nan.cpp):扩展平台支持判断(DAV_3510 / DAV_2201);BroadcastInferShape 推导输出 shape;
  • arch22 tiling(op_host/arch22/mul_no_nan_tiling.cpp/h):
    • dtype 校验(fp16/fp32/bf16,且三者一致);
    • 生成 inline MulNoNanTilingData(rank / outputDims / x1、x2 strides);
    • 支持 ND 广播:输入 rank ≤ 输出 rank,维为 1 时 stride=0,否则必须与输出维相等;
    • 多核 block dim 按输出 word count 选择(≥256 words/block,上限 AIV core 数);
  • SetTilingKey(MUL_NO_NAN_TILING_KEY),配套 op_host/config/ascend910b/mul_no_nan_simplified_key.ini([MulNoNan] default=0);
  • 注册:op_host/mul_no_nan_def.cpp 增加 AddConfig("ascend910b");CMake SUPPORT_COMPUTE_UNIT 增加 ascend910b、SUPPORT_TILING_DIR 增加 arch22;
  • 单测:新增 tests/ut/op_host/arch22/test_mul_no_nan_tiling.cpp(fp16/fp32/bf16 同 shape、大 tensor 多核、dtype 不一致拒绝、int32 拒绝等用例)。
3.2.3 kernel侧设计
  • AIV vectorized kernel(op_kernel/mul_no_nan.cpp/h):
    • 计算序列:mask = Compares(x2, NE, 0) → mul = x1 * x2 → y = Select(mask, mul, 0);
    • Select 采用 VSEL_TENSOR_SCALAR_MODE(第二源为标量 0):910B AIV 上 tensor-tensor select 的 bitmap mask 链不可靠,标量模式是 Equal 算子已验证的可靠模式;相比早期 Abs+Muls+Mins 技巧,Select 在零分支不会产生 Inf*0=NaN;
    • 多核分块:GetBlockIdx/GetBlockNum 划分 [0,total),每个 core 的范围按 32B(对齐元素数)及整 tile(2048 元素)对齐,末核收尾保证全覆盖;
    • 连续大段走 TQue 双缓冲流水(DataCopy in → vector compute → DataCopy out);未对齐头尾(通常 <32B)与小广播复制段走标量 GM GetValue/SetValue 兜底(限制其规模,保证主体保持 vector 化);
    • 常量:tile 2048 元素、vector 最小 64 元素、repeat 64。
3.3 支持硬件
  • Ascend 910B(A2/A3,ascend910b / arch22),CANN 9.1.0 及以上(README 已更新);
  • 保留 Ascend 950PR / Ascend 950DT(A5,arch35)原有支持不变(tiling 文件迁移到 arch35 目录,逻辑不变)。

3.4 算子约束限制

  • 仅支持 ND 格式;输入 x1/x2 与输出 y 的 dtype 必须一致,仅支持 fp16/fp32/bf16,不支持整型(如 int32);
  • 支持 ND 广播:输入 rank 不能超过输出 rank,输入维必须为 1 或与输出对应维相等,不满足则报错拒绝;
  • 输出 rank 需在 [1, 8] 范围内,各维必须为正数;
  • 910B 侧暂为独立 kernel 实现,不再依赖调试脚本 test.sh(已删除)。
likedislike
CANN-robotCANN-robot成员
8月25日 关闭了 issue
CANN-robotCANN-robot成员
8月25日 添加了label:resolved
陈思陈思成员
9月22日 将 gcw_6JDqrnev 设为负责人