Closed
[Bug-Report|缺陷反馈]: aclnnAscendQuant 未校验 x/y 的 0 维(rank=0)输入,资料声明 rank 1-8 却返回 0 #7094
liuhanwen8Add on  21 days agoClosed at  20 days ago
liuhanwen8
liuhanwen8
21 days ago Create

Describe the current behavior / 问题描述 (Mandatory / 必填)

aclnnAscendQuant 的第一段接口没有校验 x / y 的 rank 下界:0 维(rank=0,numel=1)的 x 和 y 被直接接受,两段都返回 0,结果被正常算出。

资料 quant/ascend_quant_v2/docs/aclnnAscendQuant.md 的参数表里 x、y 的「维度(shape)」都写 1-8,且错误码表 161002 的子项明确包含「x、scale、offset、y 的 shape 不满足限制条件」。因此 0 维入参应返回 161002(ACLNN_ERR_PARAM_INVALID),而不是 0。

  • 实测(A2 / CANN 9.2.0):GetWorkspaceSize ret = 0,Execute ret = 0,y 被正确写入 round((x*scale)+offset) 的结果;
  • 期望:GetWorkspaceSize ret = 161002。

补充:同一个「rank 1-8」约束在 rank=9 时是生效的(rank 9 正确返回 161002),所以这里缺的是下界这一条判断,不是整条 rank 校验缺失。

Environment Information / 环境信息 (Mandatory / 必填)

  • 昇腾硬件型号:Atlas A2 训练系列产品(910B2,npu-smi 26.1.1)
  • CANN 版本:9.2.0(Ascend-cann-toolkit + Ascend-cann-910b-ops)
  • 调用方式:aclnn 原生 C 两段式接口直调(不经框架)

Steps to reproduce the issue / 重现步骤 (Mandatory / 必填)

独立 C 程序(只依赖 CANN 自带头文件与库):

#include <cstdio>
#include <cstdint>
#include <vector>
#include "acl/acl.h"
#include "aclnnop/aclnn_ascend_quant.h"

int main()
{
    aclInit(nullptr);
    aclrtSetDevice(0);
    aclrtStream stream = nullptr;
    aclrtCreateStream(&stream);

    // x: 0 维 fp32(1 个元素);scale / offset: 1 维 fp32;y: 0 维 int8
    float xv = 2.0f, sv = 0.5f, ov = 0.5f;
    void *xDev = nullptr, *sDev = nullptr, *oDev = nullptr, *yDev = nullptr;
    aclrtMalloc(&xDev, sizeof(float), ACL_MEM_MALLOC_HUGE_FIRST);
    aclrtMalloc(&sDev, sizeof(float), ACL_MEM_MALLOC_HUGE_FIRST);
    aclrtMalloc(&oDev, sizeof(float), ACL_MEM_MALLOC_HUGE_FIRST);
    aclrtMalloc(&yDev, sizeof(int8_t), ACL_MEM_MALLOC_HUGE_FIRST);
    aclrtMemcpy(xDev, 4, &xv, 4, ACL_MEMCPY_HOST_TO_DEVICE);
    aclrtMemcpy(sDev, 4, &sv, 4, ACL_MEMCPY_HOST_TO_DEVICE);
    aclrtMemcpy(oDev, 4, &ov, 4, ACL_MEMCPY_HOST_TO_DEVICE);

    int64_t shape1[1] = {1};
    aclTensor *x      = aclCreateTensor(shape1, 0, ACL_FLOAT, nullptr, 0, ACL_FORMAT_ND, shape1, 0, xDev);
    aclTensor *scale  = aclCreateTensor(shape1, 1, ACL_FLOAT, shape1, 0, ACL_FORMAT_ND, shape1, 1, sDev);
    aclTensor *offset = aclCreateTensor(shape1, 1, ACL_FLOAT, shape1, 0, ACL_FORMAT_ND, shape1, 1, oDev);
    aclTensor *y      = aclCreateTensor(shape1, 0, ACL_INT8,  nullptr, 0, ACL_FORMAT_ND, shape1, 0, yDev);

    uint64_t ws = 0;
    aclOpExecutor *exec = nullptr;
    aclnnStatus ret = aclnnAscendQuantGetWorkspaceSize(x, scale, offset, false, "round", 2, y, &ws, &exec);
    printf("GetWorkspaceSize ret = %d (期望 161002)\n", (int)ret);   // 实测 0
    if (ret == ACL_SUCCESS) {
        void *wsAddr = nullptr;
        if (ws > 0) { aclrtMalloc(&wsAddr, ws, ACL_MEM_MALLOC_HUGE_FIRST); }
        printf("Execute ret = %d\n", (int)aclnnAscendQuant(wsAddr, ws, exec, stream));  // 实测 0
        aclrtSynchronizeStream(stream);
        int8_t out = -99;
        aclrtMemcpy(&out, 1, yDev, 1, ACL_MEMCPY_DEVICE_TO_HOST);
        printf("y[0] = %d\n", (int)out);                              // 实测 2(= round(1.5))
    }
    aclrtDestroyStream(stream);
    aclrtResetDevice(0);
    aclFinalize();
    return 0;
}

编译与运行:

g++ -std=c++17 repro.cpp -o repro \
    -I$ASCEND_HOME_PATH/include -L$ASCEND_HOME_PATH/lib64 \
    -lascendcl -lnnopbase -lopapi

./repro
# GetWorkspaceSize ret = 0 (期望 161002)
# Execute ret = 0
# y[0] = 2

同样形态把 x 改成 rank=9(shape[9]={1,1,1,1,1,1,1,2,16})时,第一段正确定返回 161002,可作为对照。

影响 / 建议

  • 依赖「非法 rank → 161002」做负向验收或监控的用例会漏判,把非法入参当成合法执行;
  • 0 维输入会一路走到 kernel 并算出结果,属于「契约外的形态被放行」,与同仓多数接口(rank 越界统一拦 161002)口径不一致;
  • 建议在 host 侧的 rank 校验里补上界与下界两个判断(dimNum < 1 || dimNum > 8 → ACLNN_ERR_PARAM_INVALID);若 0 维是有意放行,请同步更新资料参数表的「维度」列与错误码说明。
likedislike
liuhanwen8liuhanwen8
21 days ago Added label: bug
yuning_chen
yuning_chenCollaborators
21 days ago Comments:

初步分析

感谢反馈。

现象理解:aclnnAscendQuant 没有校验 x、y 的 0 维输入。资料声明 rank 是 1 到 8,0 维却返回成功。

当前判断:初步判断,待复现确认。

涉及范围:ascend_quant 的 rank 检查。

下一步:用 rank 为 0 的 x 或 y 看返回码。确认后按资料拒绝。

likedislike
yuning_chenyuning_chenCollaborators
21 days ago Assign fengying555682 as responsible person
yuning_chen
yuning_chenCollaborators
20 days ago Comments:

您好,该问题已收到,当前问题 @liujie12345678 处理中

likedislike
yuning_chenyuning_chenCollaborators
20 days ago Removed responsible person fengying555682
yuning_chenyuning_chenCollaborators
20 days ago Assign liujie12345678 as responsible person
CcuijieCollaborators
20 days ago Associated pull request
CANN-robotCANN-robotCollaborators
20 days ago Close issue
CcuijieCollaborators
20 days ago Assign cuijie25 as responsible person
CANN-robotCANN-robotCollaborators
20 days ago Added label: resolved