Closed
[Documentation|文档反馈]: aclnn_exp.h 中 aclnnExp 的 self 注释 dtype 列表漏列 INT64 #3917
liuhanwen8Add on  16 days agoClosed at  3 days ago
liuhanwen8
liuhanwen8
16 days ago Create

文档链接

  • 仓库:cann/ops-math
  • 版本:master @ 584b2ea6cbaeba684a51a74296d82d4d50ab3b0f
  • 头文件:math/exp/op_api/aclnn_exp.h:43-44
  • 资料:math/exp/docs/aclnnExp&aclnnInplaceExp.md:98-105
锚点 维度 影响 证据等级 级别
math/exp/op_api/aclnn_exp.h:43-44 正确性/一致性 按头文件判断 dtype 支持面的调用方会误认为 INT64 不可直调,被迫先 Cast 成浮点再算 exp,多一次搬运与精度损失 静态断言脚本 + 资料双侧一致,单条可判定 P2

问题文档片段

问题描述:aclnnExpGetWorkspaceSize 的 @param [in] self 注释中,dtype 支持列表漏列 INT64;而资料参数表 self 行的「数据类型」列明确含 INT64,且「使用说明」列还专门写了 当self为BOOL或INT64时,out需要是浮点类型——即资料不仅支持 INT64,还给出了 INT64 的分支规则。

推导链:

  1. math/exp/op_api/aclnn_exp.h:43-44 的 self 注释写 FLOAT、FLOAT16、BFLOAT16、DOUBLE、COMPLEX64、COMPLEX128、BOOL,共 7 项,无 INT64。
  2. 资料 math/exp/docs/aclnnExp&aclnnInplaceExp.md:102 的 self 行「数据类型」列为 FLOAT、FLOAT16、DOUBLE、COMPLEX64、COMPLEX128、BOOL、INT64、BFLOAT16,共 8 项,含 INT64。
  3. 资料同表 L111 的 out 行「使用说明」列写:数据类型需要是self可转换的数据类型。当self为BOOL或INT64时,out需要是浮点类型。其shape需要与self一致。——其中 当self为BOOL或INT64时 是对 INT64 输入的直接、显式背书;若 INT64 不支持,这条规则就是死条款。
  4. 资料 out 行「数据类型」列(L112)为 FLOAT、FLOAT16、DOUBLE、COMPLEX64、COMPLEX128、BFLOAT16,恰好不含 BOOL 与 INT64,与第 3 步的规则自洽:输入可以是 BOOL/INT64,输出必须是浮点。这反过来证明输入侧确实包含 INT64。
  5. 因此漏列只在 aclnn_exp.h:43-44 的注释,头文件比资料少一项 INT64。

反向排除:

  1. 不是「资料写错了、INT64 其实不支持」:资料 L111 的 当self为BOOL或INT64时,out需要是浮点类型 是与 L102 的 INT64 独立成文的第二条证据,两处若都写错,等于资料在同一张表里连续错两处;而头文件侧的 BOOL 是保留的,说明不是「整个整数类都被排除」。
  2. 不是 Inplace 侧同样漏了、应当一并提:aclnnInplaceExpGetWorkspaceSize 的 selfRef 注释(aclnn_exp.h:69-70)为 FLOAT、FLOAT16、BFLOAT16、DOUBLE、COMPLEX64、COMPLEX128,不含 BOOL 与 INT64;资料 Inplace 侧的错误码表(L303/L308/L311)与参数表也未声明 INT64。两侧一致不含,属正确的不对称(Inplace 不能把整数原地写成浮点),本条只针对 out-of-place 的 self。
  3. 不是换序或别名写法:头文件列表 7 项 vs 资料 8 项,缺的是元素而非顺序;头文件用 COMPLEX64/COMPLEX128 全称,与资料写法一致,不存在 INT64 被写成 INT 之类缩写导致脚本漏匹配的情况。
  4. 不是脚本把 out 行当成 self 行读取:脚本以 @param [in] self 起块、遇到下一个 @param 或 */ 终止,out 注释是独立块;实测输出中对照的 round 用例(self 含 BFLOAT16 → exit=0)证明块切分正确。

影响:以头文件注释为契约来源的调用方(框架适配层、算子选型/白名单生成、自研 doc 流水线)会把 INT64 判为不支持,对 int64 张量先 Cast 成 fp32 再调 aclnnExp,多一次 device 内存往返;更糟的是按资料写的「int64 in → fp32 out」用法在头文件读者看来是非法的,出现「同一接口两种说法」,排查成本落在使用方。

原文片段(math/exp/op_api/aclnn_exp.h:43-45,逐字):

 * @param [in] self: npu
 * device侧的aclTensor,数据类型支持FLOAT、FLOAT16、BFLOAT16、DOUBLE、COMPLEX64、COMPLEX128、BOOL,
 * 支持非连续的Tensor,数据格式支持ND,数据维度不支持8维以上。

对照片段 1(资料 self 行,math/exp/docs/aclnnExp&aclnnInplaceExp.md:98-105,逐字):

      <td>self</td>
      <td>输入</td>
      <td>输入Tensor。</td>
      <td>-</td>
      <td>FLOAT、FLOAT16、DOUBLE、COMPLEX64、COMPLEX128、BOOL、INT64、BFLOAT16</td>
      <td>ND</td>
      <td>不支持8维以上</td>

对照片段 2(资料 out 行「使用说明」列,...md:111,逐字):

      <td><ul><li>数据类型需要是self可转换的数据类型。</li><li>当self为BOOL或INT64时,out需要是浮点类型。</li><li>其shape需要与self一致。</li></ul></td>

复现三件套:

  • 类型:静态文本断言(头文件注释 dtype 列表)
  • 退出码语义:0 = 符合预期(不成立)/1 = 缺陷成立并打印 [DEFECT]/2 = 无法判定
  • 期望值:0;实测值:1

脚本全文:

#!/usr/bin/env python3
import argparse, os, re, sys

def blocks(lines, param):
    out, cur = [], None
    for ln in lines:
        if re.search(r"@param\s*\[in\]\s*%s\b" % re.escape(param), ln):
            cur = [ln]; out.append(cur); continue
        if cur is not None:
            if "@param" in ln or "*/" in ln: cur = None
            else: cur.append(ln)
    return out

def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--repo", required=True)
    ap.add_argument("--file", required=True)
    ap.add_argument("--fn", required=True)
    ap.add_argument("--param", required=True)
    ap.add_argument("--needle", required=True)
    ap.add_argument("--claim", choices=["missing", "extra"], required=True)
    a = ap.parse_args()
    path = os.path.join(a.repo, a.file)
    if not os.path.isfile(path):
        print("[SKIP] 文件不存在: %s" % path); return 2
    src = open(path, encoding="utf-8", errors="replace").read()
    lines = src.splitlines()
    if a.fn not in src:
        print("[SKIP] 未找到 %s" % a.fn); return 2
    start = next(i for i, l in enumerate(lines) if a.fn in l)
    blks = blocks(lines[max(0, start - 40):start + 2], a.param)
    if not blks:
        print("[SKIP] 未找到 @param [in] %s 注释块(措辞可能已变,人工确认)" % a.param); return 2
    text = "\n".join("\n".join(b) for b in blks)
    if "数据类型" not in text and "FLOAT16" not in text:
        print("[SKIP] 注释块里没有可识别的 dtype 列表(人工确认)"); return 2
    hit = a.needle in text
    print("文件: %s" % a.file)
    print("锚点: @param [in] %s 的 dtype 列表" % a.param)
    print("现状: %s %s" % ("含" if hit else "不含", a.needle))
    if a.claim == "missing":
        if hit:
            print("结论: 已包含,本条不成立"); return 0
        print("[DEFECT] 应含 %s 而缺失" % a.needle); return 1
    else:
        if not hit:
            print("结论: 确实不含,本条不成立"); return 0
        print("[DEFECT] 不应含 %s 却出现" % a.needle); return 1

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

实测输出:

$ python3 check_param_dtype.py --repo <repo> --file math/exp/op_api/aclnn_exp.h \
    --fn aclnnExpGetWorkspaceSize --param self --needle INT64 --claim missing
文件: math/exp/op_api/aclnn_exp.h
锚点: @param [in] self 的 dtype 列表
现状: 不含 INT64
[DEFECT] 应含 INT64 而缺失
exit=1

补证(Inplace 侧三方均不含 INT64,属正确的不对称,故本条只针对 out-of-place 的 self)。以下为仓内文本直取,非断言脚本:

$ grep -n "selfRef" math/exp/op_api/aclnn_exp.h | head -1
69: * @param [in] selfRef: npu

$ sed -n '70p' math/exp/op_api/aclnn_exp.h
 * device侧的aclTensor,数据类型支持FLOAT、FLOAT16、BFLOAT16、DOUBLE、COMPLEX64、COMPLEX128,支持

$ sed -n '254p' "math/exp/docs/aclnnExp&aclnnInplaceExp.md"
      <td>FLOAT、FLOAT16、DOUBLE、COMPLEX64、COMPLEX128、BFLOAT16</td>

即 Inplace 侧的 selfRef 注释(无 INT64)与资料 Inplace 参数表(无 INT64)口径一致,不存在漏列;本条不主张修改 selfRef。

存在的问题

修复建议:将 math/exp/op_api/aclnn_exp.h:44 整行改为(补 INT64、,与资料 self 行元素集合一致):

 * device侧的aclTensor,数据类型支持FLOAT、FLOAT16、BFLOAT16、DOUBLE、COMPLEX64、COMPLEX128、BOOL、INT64,

证据与环境:

  • 复现方式:静态断言脚本(无设备依赖,任何平台可复跑)
  • 实测返回码:1(含 [DEFECT])
  • 设备型号/CANN 版本:本条为纯注释文本断言,不涉及运行时,未使用设备
  • 说明:本条只主张「头文件 self 注释的 dtype 列表比同仓资料少 INT64,且资料另有 当self为BOOL或INT64时,out需要是浮点类型 的显式规则佐证 INT64 属支持面」,成立性由仓内文本决定,不依赖真机行为。

完整文件清单:

  • math/exp/op_api/aclnn_exp.h(L43-44,待修改)
  • math/exp/docs/aclnnExp&aclnnInplaceExp.md(L98-105 与 L111,参照,无需修改)
likedislike
liuhanwen8liuhanwen8
16 days ago Added label: documentation
陈思
陈思Collaborators
15 days ago Comments:

您好,感谢反馈!已按 cann/ops-math@584b2ea6cbaeba684a51a74296d82d4d50ab3b0f 核对,非原地 aclnnExpGetWorkspaceSize 的 self 注释确实漏列了 INT64。除了资料包含该类型,实际输入类型校验的两套支持列表也都包含 DT_INT64,能够独立佐证这处遗漏。头文件、实现支持列表、资料参数表

可在该 self 注释的现有列表中补入 INT64,使头文件与现有入口及资料对齐。补充范围应限定在非原地输入;原地 selfRef 的实现与资料均采用不含 BOOL、INT64 的浮点/复数列表。

实现对 BOOL/INT64 输入会先转换为 FLOAT 再计算 Exp,因此支持 INT64 输入仍需按已有计算与输出类型规则理解。转换路径 我们会继续跟踪这处头文件注释补充。

likedislike
陈思陈思Collaborators
15 days ago Assign chensi79 as responsible person
陈思陈思Collaborators
15 days ago Added label: pending-confirmation
陈思陈思Collaborators
15 days ago Assign jiaoyiming as responsible person
陈思陈思Collaborators
15 days ago Removed responsible person chensi79
陈思陈思Collaborators
15 days ago Removed label: pending-confirmation
CANN-robotCANN-robotCollaborators
3 days ago Close issue
CANN-robotCANN-robotCollaborators
3 days ago changed custom state from 进行中 to 已完成
CANN-robotCANN-robotCollaborators
3 days ago Added label: resolved