Open
[Bug-Report|缺陷反馈]: aclnnRange 的 out 声明为 2/3 维时两段均返回 0(资料要求 1 维,应报 161002;实现只拒 0 维) #4257
liuhanwen8Add on  12 days ago
liuhanwen8
liuhanwen8
12 days ago Create

现象

aclnnRange 的 out 声明为 2 维或 3 维时,两段接口均返回 0(放行),并把前 N 个元素写满;资料参数表要求 out 是 1 维张量。实现只拒绝了 0 维(dim_num == 0)这一种情况。

实测(Atlas A2 910B2,CANN 9.2.0,start=-0.5, end=16, step=1,推导长度 17):

out 声明 元素数 第一段 第二段 实际写入
[17](合法对照) 17 0 0 17
[2, 8](2 维) 16 0 0 16
[1, 1, 17](3 维) 17 0 0 17
[](0 维) 1 161002 — —

复现脚本输出:

[D2 out=[17]      ] phase1=0 phase2=0 written=17
[D2 out=[2,8] 2-D ] phase1=0 phase2=0 written=16
[D2 out=[1,1,17] 3D] phase1=0 phase2=0 written=17
[D2 out=[] 0-D    ] phase1=161002

另:valid-fuzz 采样器在无 tensor 输入的接口上自然造出 out=fp16[8x8]ND(2 维),同样两段返回 0 —— 2 维放行是稳定行为,不是偶发。

期望

资料 math/range/docs/aclnnRange.md 的 out 参数行:

参数名 输入/输出 描述 数据类型 数据格式 维度(shape)
out 输出 指定的输出Tensor。 FLOAT16、FLOAT、DOUBLE、BFLOAT16、INT32、INT64 ND (1 维)

同文档「功能说明」也写明「返回大小为 ⌊end−startstep⌋+1\lfloor\frac{end-start}{step}\rfloor+1 的 1 维张量」。

非 1 维的 out 属于参数与接口契约不符,应按错误码表返回 161002(ACLNN_ERR_PARAM_INVALID),而不是静默按扁平化写入。

根因

math/range/op_api/aclnn_range.cpp:172-183:

inline static aclnnStatus CheckParamsLogic(const aclScalar* start, const aclScalar* end, const aclScalar* step,
                                           const aclTensor* out)
{
    size_t dim_num = out->GetViewShape().GetDimNum();
    OP_CHECK(dim_num != 0,                                  // ← 只排除 0 维
             OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Expected out to be a 1D tensor, but got %zu dimension(s).", dim_num),
             return ACLNN_ERR_PARAM_INVALID);
    ...
}

告警文案写的是「Expected out to be a 1D tensor」,但判定条件只写了 dim_num != 0 —— 文案与条件不一致,2/3/4 维全部通过。正确条件应为 dim_num == 1。

环境

  • Atlas A2 训练系列产品(910B2),CANN 9.2.0
  • 仓库 cann/ops-math,master 1b415030
  • 头文件 /usr/local/Ascend/ascend-toolkit/latest/include/aclnnop/aclnn_range.h(9.2.0 发布件)

复现步骤

  1. source $ASCEND_HOME_PATH/set_env.sh,确认 ASCEND_OPP_PATH=$ASCEND_HOME_PATH/opp。
  2. g++ -std=c++17 -O2 repro.cpp -o repro -I$ASCEND_HOME_PATH/include -I$ASCEND_HOME_PATH/include/aclnnop -L$ASCEND_HOME_PATH/lib64 -Wl,--allow-shlib-undefined -lascendcl -lopapi -lnnopbase
  3. 选一张 Health=OK 的卡(Health=Alarm 的 die 上 aclrtSetDevice 会永久挂死):PROBE_DEV=<n> ./repro
  4. 2 维与 3 维两组两段均返回 0(应为 161002)。

实测输出:

==== aclnnRange out 维数校验 ====
out=[17]      phase1=0 phase2=0 written=17/17   <- 合法对照
out=[2,8]     phase1=0 phase2=0 written=16/16   <- 2 维被放行(应 161002)
out=[1,1,17]  phase1=0 phase2=0 written=17/17   <- 3 维被放行(应 161002)
out=[]        phase1=161002                     <- 0 维被拦

复现脚本

完整脚本见附件 probe_range_contract.cpp(shape 组)。核心:

for (auto& sh : {std::vector<int64_t>{17}, {2,8}, {1,1,17}, {}}) {
    aclTensor* out = aclCreateTensor(sh.data(), (int)sh.size(), ACL_FLOAT,
                                     nullptr, 0, ACL_FORMAT_ND, sh.data(), (int)sh.size(), dev);
    aclnnStatus r1 = aclnnRangeGetWorkspaceSize(s, e, p, out, &ws, &ex);
    printf("rank=%zu phase1=%d\n", sh.size(), (int)r1);
}
likedislike
liuhanwen8liuhanwen8
12 days ago Added label: bug-report
yampolskiyyampolskiy
12 days ago Associated pull request
陈思
陈思Collaborators
12 days ago Comments:

/assign @yampolskiy

likedislike
CANN-robotCANN-robotCollaborators
12 days ago Assign yampolskiy as responsible person
陈思
陈思Collaborators
11 days ago Comments:

您好,感谢反馈!核查 cann/ops-math@ae087b184,这个维数检查缺口可以从源码确认。

问题分析

资料的功能说明要求返回一维张量,但 CheckParamsLogic 使用的是 dim_num != 0,只排除零维,二维及更高维会通过这一项检查,随后继续步长检查和任务构造。您给出的 [1,1,17] 与合法 [17] 元素数相同,也能清楚区分“维数不符”与“元素个数不符”两个问题。一维输出定义、现有检查。运行结果依据您提供的 910B2 / CANN 9.2.0 实测,本轮未重新上板。

处理方向

已关联的 PR !6839 当前为草稿、尚未合入。核查其 31ccd3cc 版本,实际修改是将条件收紧为 dim_num == 1,非一维输出在第一段返回 161002;并新增零维、二维、三维拒绝用例及 [17] 合法对照,其中二维、三维对照都保持 17 个元素,以隔离维数检查。这里说明的是已提交的改动与用例,不代表已完成 SDK 或设备验证。

该 PR 的范围是输出维数,#3972 涉及的输出元素数与推导长度校验仍属独立问题。我们会继续跟踪这项维数修正的进展。

likedislike