Closed
[Documentation|文档反馈]: aclnnInplaceZero 头文件 aclnn_zero.h 的 selfRef 注释声明支持 QINT8/UINT32/UINT64 等 7 个 dtype,实测第一段返回 161002 #4253
liuhanwen8Add on  11 days agoClosed at  7 days ago
liuhanwen8
liuhanwen8
11 days ago Create

现象

aclnnInplaceZero 的公开头文件 include/aclnnop/aclnn_zero.h 在 aclnnInplaceZeroGetWorkspaceSize 的 @param [in] selfRef 注释里声明 selfRef 支持 18 种数据类型:

device侧的aclTensor,数据类型支持INT8、INT16、INT32、INT64、QINT8、QINT16、QINT32、UINT8、UINT16、UINT32、
UINT64、QUINT8、QUINT16、FLOAT16、FLOAT32、DOUBLE、COMPLEX64、COMPLEX128、FLOAT8_E5M2、FLOAT8_E4M3FN、
HIFLOAT8、FLOAT4_E1M2、FLOAT4_E2M1。(后 5 项另注「仅支持 Ascend950 及后续芯片」)

其中 QINT8 / QINT16 / QINT32 / UINT32 / UINT64 / QUINT8 / QUINT16 在实现里一项都不存在:实现白名单
math/zero_op/op_api/aclnn_zero.cpp 的 DTYPE_SUPPORT_LIST 只有 13 项;实测 ACL_UINT32 的 selfRef
两段式调用返回 161002,而按头文件注释它应当被接受。同仓资料 docs/aclnnInplaceZero.md 的 dtype 表是对的(13 项 + 950 专属),
即头文件注释与资料表互不一致,而下游通常直接读头文件注释。

期望

头文件 @param [in] selfRef 的 dtype 列表与实现 DTYPE_SUPPORT_LIST 一致;或若这些 dtype 本应支持,
则实现补齐(当前 uint32 在第一段就被拒)。

环境

  • 硬件:Atlas A2(Ascend910B2);CANN 9.2.0($ASCEND_HOME_PATH 指向 ascend-toolkit 安装目录,source set_env.sh 即可)
  • 算子仓:cann/ops-math master 584b2ea6(2026-10-29 浅克隆)
  • 涉及文件:math/zero_op/op_api/aclnn_zero.h:44-48、math/zero_op/op_api/aclnn_zero.cpp:36-41;
    安装包内同名头文件与仓内文件逐字节相同(diff 无输出)

复现步骤

  1. 将下面 repro.cpp 与 build.sh 存到同一目录。
  2. bash build.sh 编译。
  3. export ASCEND_RT_VISIBLE_DEVICES=<空闲卡号> 后执行 ./repro。
  4. 观察 4 行输出:fp32 对照组 rc1=0 rc2=0;uint32 组 rc1=161002(与头文件注释冲突);
    selfRef=nullptr 组 rc1=161001;int16(AICPU 分支)组 rc1=0 rc2=0。

复现脚本

g++ -std=c++17 -O2 -o repro repro.cpp -I$ASCEND_HOME_PATH/include \
  -I$ASCEND_HOME_PATH/include/aclnnop -L$ASCEND_HOME_PATH/lib64 \
  -lascendcl -lnnopbase -lopapi
#include <cstdint>
#include <cstdio>
#include <vector>
#include "acl/acl.h"
#include "aclnnop/aclnn_zero.h"
static void Call(aclTensor* t, int* r1, int* r2, aclrtStream s)
{
    uint64_t ws = 0; aclOpExecutor* e = nullptr;
    *r1 = (int)aclnnInplaceZeroGetWorkspaceSize(t, &ws, &e); *r2 = 0;
    if (*r1 != 0) { return; }
    void* w = nullptr;
    if (ws > 0 && aclrtMalloc(&w, ws, ACL_MEM_MALLOC_HUGE_FIRST) != ACL_SUCCESS) { *r2 = -1; return; }
    *r2 = (int)aclnnInplaceZero(w, ws, e, s);
    if (*r2 == 0) { aclrtSynchronizeStream(s); }
    if (w) { aclrtFree(w); }
}
static aclTensor* Make(aclDataType dt, void** dev)
{
    std::vector<int64_t> sh{4, 4}, st{4, 1};
    size_t esz = (dt == ACL_INT16) ? 2 : 4, bytes = 16 * esz;
    if (aclrtMalloc(dev, bytes, ACL_MEM_MALLOC_HUGE_FIRST) != ACL_SUCCESS) { return nullptr; }
    std::vector<uint8_t> raw(bytes, 0x3f);          // 非零金丝雀:只有写 0 才过
    aclrtMemcpy(*dev, bytes, raw.data(), bytes, ACL_MEMCPY_HOST_TO_DEVICE);
    return aclCreateTensor(sh.data(), 2, dt, st.data(), 0, ACL_FORMAT_ND, sh.data(), 2, *dev);
}
int main()
{
    if (aclInit(nullptr) != ACL_SUCCESS || aclrtSetDevice(0) != ACL_SUCCESS) { return -1; }
    aclrtStream s = nullptr; aclrtCreateStream(&s);
    const aclDataType dts[3] = {ACL_FLOAT, ACL_UINT32, ACL_INT16};
    const char* names[3] = {"fp32(对照)", "uint32(头文件声明支持)", "int16(AICPU 分支)"};
    for (int i = 0; i < 3; ++i) {
        void* dev = nullptr; aclTensor* t = Make(dts[i], &dev);
        int r1 = -1, r2 = -1; Call(t, &r1, &r2, s);
        printf("[%s] rc1=%d rc2=%d\n", names[i], r1, r2);
        aclDestroyTensor(t); aclrtFree(dev);
    }
    int r1 = -1, r2 = -1; Call(nullptr, &r1, &r2, s);
    printf("[selfRef=nullptr] rc1=%d\n", r1);
    aclrtDestroyStream(s); aclrtResetDevice(0); aclFinalize();
    return 0;
}

实测输出(910B2 / CANN 9.2.0 / 2026-10-29):

[fp32(对照)] rc1=0 rc2=0
[uint32(头文件声明支持)] rc1=161002 rc2=0
[int16(AICPU 分支)] rc1=0 rc2=0
[selfRef=nullptr] rc1=161001

影响

下游与用户通常直接按 $ASCEND_HOME_PATH/include/aclnnop/*.h 的注释判断 dtype 是否可用。按本头文件,
UINT32/UINT64/QINT8/QINT16/QINT32/QUINT8/QUINT16 的 selfRef 是「支持」的,实际第一段即返回 161002:
①用户按注释构造被拒却找不到原因;②从注释抽支持表的工具会把 7 个不存在的 dtype 写进下游支持矩阵;
③头文件与同仓资料两处口径不一致,后续维护容易以头文件为准改错资料。

建议

  1. 把 aclnn_zero.h 的 @param [in] selfRef 注释改成与 aclnn_zero.cpp:36-41 的 DTYPE_SUPPORT_LIST
    一致(INT8、INT32、INT64、UINT8、FLOAT16、FLOAT32、BOOL、DOUBLE、INT16、UINT16、COMPLEX128、COMPLEX64、BF16),
    950 专属窄浮点单列一句;
  2. 若这 7 个 dtype 本应支持,则在 DTYPE_SUPPORT_LIST 与 ZerosLike 派发里补齐;
  3. 建议加 CI 校验:从 op_api/aclnn_*.h 的 @param 注释抽 dtype 列表与 DTYPE_SUPPORT_LIST 比对,
    差集非空即失败 —— 「注释照抄兄弟接口」在 CANN 头文件里普遍存在(本次顺带发现 aclnn_copy.h:44
    的注释里也写着 aclnnInplaceZeroGetWorkspaceSize)。
likedislike
liuhanwen8liuhanwen8
11 days ago Added label: documentation
陈思
陈思Collaborators
11 days ago Comments:

您好,核对 ae087b184,头文件 确实列出了当前 类型检查 不接受的 QINT8、QINT16、QINT32、UINT32、UINT64、QUINT8、QUINT16;同时未列出实现名单中的 BOOL、BFLOAT16。建议按实际产品分支同步注释,并保留新增低精度类型的产品和连续性限制。

您提供的 A2 UINT32 返回 161002 与白名单检查一致。本项优先按头文件资料修正处理;若要新增类型支持,应另行评估实现与测试,不能仅凭现有注释认定运行时已经支持。当前源码还区分 DAV_9201 与其他 RegBase 名单,不能将一份列表无条件推广到全部后续产品。本轮未执行设备复现。

likedislike
陈思陈思Collaborators
11 days ago Assign chen_0715 as responsible person
陈思陈思Collaborators
11 days ago Added label: pending-confirmation
陈思陈思Collaborators
11 days ago Removed label: pending-confirmation
CchenyifengCollaborators
7 days ago Assign VoyageZhou as responsible person
CchenyifengCollaborators
7 days ago Removed responsible person chen_0715
CANN-robotCANN-robotCollaborators
7 days ago Close issue
fitZepHYr
fitZepHYrCollaborators
7 days ago Comments:

当前UINT32和UINT64已在A2/A3支持,PR:aclnnInplaceZero支持UINT32/UINT64类型,未涉及的其他类型请后续再评审是否支持,此Issue关闭

likedislike
fitZepHYr
fitZepHYrCollaborators
7 days ago Comments:

/close

likedislike
CANN-robotCANN-robotCollaborators
7 days ago Added label: resolved