Closed
[Documentation|文档反馈]: [aclnnInplaceAtanh] 资料把 A2 已支持的 BFLOAT16/COMPLEX64/COMPLEX128 标为「Atlas A3系列产品额外支持」 #4175
liuhanwen8Add on  13 days agoClosed at  12 days ago
liuhanwen8
liuhanwen8
13 days ago Create

一、文档链接 (必填)

https://gitcode.com/cann/ops-math/blob/master/math/atanh/docs/aclnnAtanh%26aclnnInplaceAtanh.md

二、问题文档片段 (必填)

aclnnInplaceAtanhGetWorkspaceSize 参数表(L253 / L257),逐字:

      <td>inputRef(aclTensor*)</td>
      <td>FLOAT、FLOAT16、DOUBLE</td>

同文件 L285,逐字:

  - <term>Atlas A3系列产品</term>:inputRef数据类型额外支持COMPLEX64、COMPLEX128、BFLOAT16。

💡 存在的问题

按这两处,用户在 Atlas A2 系列上会认为 inputRef 只能是 FLOAT / FLOAT16 / DOUBLE,传 BFLOAT16 / COMPLEX64 / COMPLEX128 属于「数据类型不在支持范围」(资料 L314 的 161002 子项正是这一条)。

但同仓实现与真机都表明 A2 已支持这三种 dtype:

  • math/atanh/op_api/aclnn_atanh.cpp:38 起的 ASCEND910B_DTYPE_DTYPE_SUPPORT_LIST_ATANH 含 DT_COMPLEX64、DT_COMPLEX128、DT_BF16;
  • CheckInplaceDtypeValid() 用 GetDtypeSupportListV2(OUTPUT_DTYPE_SUPPORT_LIST_ATANH, ASCEND910_DTYPE_SELFREF_LIST_ATANH) 作为 inputRef 白名单,910B 上取到的是含这三种的那一组;
  • 910B3 实测:三种 dtype 两段均返回 0,数值与 CPU 标杆一致(下方「实测输出」)。

即资料把 A2 实际支持的三种 dtype 标成了「A3 才额外支持」。

期望

两者取一,使资料与实现自洽:

  1. 若 A2 确实支持这三种 dtype(实测是支持):把 L285 的「额外支持」限定到具体产品(例如仅写成 A3 之外还支持 …,或在 L257 的单元格补 BFLOAT16、COMPLEX64、COMPLEX128),不要让 A2 用户误以为只能用三种浮点;
  2. 若设计上 A2 不应支持:收紧 aclnn_atanh.cpp 的 CheckInplaceDtypeValid,让 910B 走不含这三种 dtype 的白名单,保持与资料一致。

同族 math/asinh/docs/aclnnAsinh&aclnnInplaceAsinh.md:283 是同样的措辞(inputRef数据类型额外支持BFLOAT16、COMPLEX64、COMPLEX128),建议一并核对该族的 A2 实际支持面(本次只针对 atanh 提单,asinh 未做本仓实测,不作断言)。

环境

  • 昇腾硬件:Atlas A2 训练系列(npu-smi 报 910B3),8 die,测试时 npu:3 独占,Health=OK
  • CANN:26.1.1(/usr/local/Ascend/ascend-toolkit/latest)
  • 操作系统:openEuler / Linux aarch64
  • 仓与提交:cann/ops-math master(2026-10-28 检出)

复现步骤

  1. 检出 cann/ops-math 仓根;
  2. 保存下方脚本为 aclnnInplaceAtanh_doc-A2dtype.py;
  3. 执行 python3 aclnnInplaceAtanh_doc-A2dtype.py --repo-root .;
  4. 观察输出:打印资料两条锚点与源码白名单,判定「资料与实现不一致」并以退出码 1 结束(输出含 [DEFECT])。

静态脚本只钉「资料 vs 源码」的对齐关系,不需要上板;上板事实见上面「实测」一节(C++ 探针,aclnnInplaceAtanhGetWorkspaceSize + aclnnInplaceAtanh 两段直调)。

复现脚本

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""aclnnInplaceAtanh 资料声明的 A2 支持面与 op_api 实现不一致(dtype 维度)。

判定:A) 资料 inputRef 的 dtype 列只写 FLOAT/FLOAT16/DOUBLE;
      B) 资料把 BFLOAT16/COMPLEX64/COMPLEX128 归为「Atlas A3系列产品」额外支持;
      C) op_api/aclnn_atanh.cpp 的 ASCEND910B(=Atlas A2)白名单已含这三种。
A∧B∧C ⇒ [DEFECT]。退出码 0=无不一致 / 1=缺陷成立 / 2=无法判定。
"""
import argparse, os, re, sys

REL_DOC = os.path.join("math", "atanh", "docs", "aclnnAtanh&aclnnInplaceAtanh.md")
REL_SRC = os.path.join("math", "atanh", "op_api", "aclnn_atanh.cpp")
ALIAS = {"BFLOAT16": "DT_BF16", "COMPLEX64": "DT_COMPLEX64", "COMPLEX128": "DT_COMPLEX128"}


def find_repo(explicit=""):
    cands = []
    if explicit:
        cands += [explicit, os.path.join(explicit, "ops-math")]
    env = os.environ.get("OPS_MATH_ROOT", "")
    if env:
        cands.append(env)
    for base in (os.getcwd(), os.path.dirname(os.path.abspath(__file__))):
        cur = os.path.abspath(base)
        for _ in range(6):
            cands += [cur, os.path.join(cur, "ops-math")]
            cur = os.path.dirname(cur) or "/"
    return next((c for c in cands if c and os.path.isfile(os.path.join(c, REL_DOC))), "")


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--repo-root", default="")
    a = ap.parse_args()
    root = find_repo(a.repo_root)
    if not root:
        print("[UNKNOWN] 找不到 %s" % REL_DOC)
        return 2
    lines = open(os.path.join(root, REL_DOC), encoding="utf-8").read().split("\n")

    inref = next(((i, l.strip()) for i, l in enumerate(lines, 1)
                  if "inputRef" in l and "aclTensor" in l and l.strip().startswith("<td>")), None)
    if not inref:
        print("[UNKNOWN] 找不到 inputRef 参数表行")
        return 2
    print("[INFO] inputRef 参数表行 L%d: %s" % (inref[0], inref[1][:120]))
    for j in range(inref[0], min(inref[0] + 8, len(lines))):
        if "FLOAT" in lines[j] and "<td>" in lines[j]:
            print("[INFO] dtype 单元格 L%d: %s" % (j + 1, lines[j].strip()[:120]))
            break

    a3_no, a3_line = 0, ""
    for i, l in enumerate(lines, 1):
        if "inputRef" in l and "额外支持" in l:
            a3_no, a3_line = i, l.strip()
            break
    print("[INFO] A3 额外支持声明 L%d: %s" % (a3_no, a3_line or "未找到"))

    src = open(os.path.join(root, REL_SRC), encoding="utf-8").read()
    m = re.search(r"ASCEND910B_DTYPE_DTYPE_SUPPORT_LIST_ATANH\s*=\s*\{(.*?)\};", src, re.S)
    if not m:
        print("[UNKNOWN] 找不到 ASCEND910B_DTYPE_DTYPE_SUPPORT_LIST_ATANH")
        return 2
    line_no = src[:m.start()].count("\n") + 1
    block = m.group(1)
    src_has = [d for d in ("DT_BF16", "DT_COMPLEX64", "DT_COMPLEX128") if d in block]
    print("[INFO] 源码 ASCEND910B 白名单 L%d 覆盖: %s" % (line_no, ",".join(src_has) or "无"))

    a3_has = [d for d in ALIAS if d in a3_line]
    print("[INFO] A3 条款覆盖: %s" % (",".join(a3_has) or "无"))
    overlap = [d for d in a3_has if ALIAS[d] in src_has]
    if overlap:
        print("[DEFECT] 资料 L%d 把 %s 标为「Atlas A3系列产品」额外支持,而 %s:%d 的 "
              "ASCEND910B(=Atlas A2 训练系列) 白名单已包含 %s"
              % (a3_no, "/".join(overlap), REL_SRC, line_no,
                 "/".join(ALIAS[d] for d in overlap)))
        print("[DEFECT] 资料 inputRef dtype 列(L%d)只写 FLOAT、FLOAT16、DOUBLE,与实现不一致"
              % inref[0])
        return 1
    print("[INFO] 未发现资料与实现的不一致")
    return 0


if __name__ == "__main__":
    sys.exit(main())

实测输出(仓根 master,2026-10-28)

[INFO] inputRef 参数表行 L253: <td>inputRef(aclTensor*)</td>
[INFO] dtype 单元格 L257: <td>FLOAT、FLOAT16、DOUBLE</td>
[INFO] A3 额外支持声明 L285: - <term>Atlas A3系列产品</term>:inputRef数据类型额外支持COMPLEX64、COMPLEX128、BFLOAT16。
[INFO] A3 条款覆盖: BFLOAT16,COMPLEX64,COMPLEX128
[INFO] 源码 ASCEND910B 白名单 L38 覆盖: DT_BF16,DT_COMPLEX64,DT_COMPLEX128
[DEFECT] 资料 L285 把 BFLOAT16/COMPLEX64/COMPLEX128 标为「Atlas A3系列产品」额外支持,而 math/atanh/op_api/aclnn_atanh.cpp:38 的 ASCEND910B(=Atlas A2 训练系列) 白名单已包含 DT_BF16/DT_COMPLEX64/DT_COMPLEX128
[DEFECT] 资料 inputRef dtype 列(L253)只写 FLOAT、FLOAT16、DOUBLE,与实现不一致:A2 上这三种 dtype 实测两段均返回 0 且数值正确

退出码 1。

查重说明

已翻页检索 cann/ops-math 全部 700 条 issue(state=all,7 页),标题含 atanh 的命中 5 条,均与本条不同:

issue 标题 状态 与本条关系
#3793 aclnnInplaceAtanh error 场景 case_5 inputRef 为 nullptr 时进程 core closed 空指针崩溃,与 dtype 支持面无关;本轮 error-scenario 复测 161001 已 MATCH,修复有效
#3791 aclnnAtanh error 场景 case_10 out 为 nullptr 时进程 core closed 同上,非原地接口
#3563 修正 acosh/asinh/atanh/cosh 算子 aclnn 接口的 Ascend 950 支持声明为不支持 closed 方向相反(950 声明收紧),未涉及 A2 的 bf16/complex
#3933 aclnnTanhBackward DOUBLE + broadcast 抛 507018 open 不同接口/不同现象
#3552 add/cast/tanh/mul/real_div 算子适配 5162A open 需求类,非文档契约

同类先例:#4143(aclnnAcosh 支持表与实现不符,documentation 通道,已修)——本条是另一个接口的 dtype 维度不一致,按「一个 aclnn 接口一条 issue」单列,不与 #4143 合并。

💡 备注:本轮同接口的其余五条测试线(精度 1000 条、确定性、内存 sanitizer、多线程 fuzz、异常场景)未发现实现缺陷,测试结论另见归档报告。

likedislike
liuhanwen8liuhanwen8
13 days ago Added label: documentation
陈思
陈思Collaborators
12 days ago Comments:

您好,感谢反馈!

问题分析

核对 cann/ops-math 8c1f633e 的文档与接口实现,您指出的 A2 类型支持说明缺口存在:原地接口的 inputRef 表只列 FLOAT/FLOAT16/DOUBLE,扩展说明仅标注 A3;而 A2 对应的类型检查列表包含 BFLOAT16/COMPLEX64/COMPLEX128。

具体调用中,CheckInplaceDtypeValid 先校验 inputRef,再将同一张量作为输入和输出进入公共执行路径;上述三种类型也均在后续输入、输出检查列表中。因此,仅因这三种 dtype 就应在 A2 返回 161002 的理解,与当前源码的校验行为不符。您报告的 910B3/CANN 26.1.1 两段成功结果与此一致;本轮核查确认的是源码路径与文档差异。

调整方向

一个可行的修订方向是在原地接口的扩展支持说明中明确补充 Atlas A2 对这三种类型的支持,并同步调整产品筛选标记,使 A2 文档也能展示该说明。其他产品的 BFLOAT16 支持仍有平台差异,不宜直接把六种类型统一写成所有产品的公共支持列表;原地接口也应继续与非原地输入允许的整型、BOOL 区分。

根据现有证据,更合适的方向是核对并补齐文档的产品范围,而非仅为匹配现有措辞收紧 A2 的类型检查。我们会继续确认产品约定并跟踪文档调整。

likedislike
陈思陈思Collaborators
12 days ago Assign chen_0715 as responsible person
陈思陈思Collaborators
12 days ago Added label: pending-confirmation
CchenyifengCollaborators
12 days ago Assign m0_55003149 as responsible person
CchenyifengCollaborators
12 days ago Removed responsible person chen_0715
weikeweikeCollaborators
12 days ago Associated pull request
CANN-robotCANN-robotCollaborators
12 days ago Close issue
weike
weikeCollaborators
12 days ago Comments:

已在接口描述单元格中补充BFLOAT16、COMPLEX64、COMPLEX128类型

likedislike
weikeweikeCollaborators
12 days ago changed custom state from 进行中 to 已完成
CANN-robotCANN-robotCollaborators
12 days ago Added label: resolved