Closed
[Documentation|文档反馈]: aclnnInplaceMaskedFillTensor 资料错误码表缺少「value 维度不为 0」子项(实测 1 维 value 返回 161002) #3970
liuhanwen8Add on  17 days agoClosed at  14 days ago
liuhanwen8
liuhanwen8
17 days ago Create

现象

aclnnInplaceMaskedFillTensor 的 value 必须是 0 维张量(传 1 维返回 161002),但同一份资料的错误码表里没有这一条,调用方从错误码表读不出该约束。

输入 phase1 说明
value=fp32[[]](0 维) 0 对照组,放行
value=fp32[4](1 维) 161002 实测拒绝,但错误码表无此子项

资料 conversion/masked_fill/docs/aclnnInplaceMaskedFillTensor.md:L99 参数表 value 写
数据类型需要可以推导到selfRef的数据类型(参见互转换关系),维度仅支持0维。;
而错误码表(L152-167)只有三条 161002 子项(dtype/format 不在支持范围、broadcast 不成立、value dtype 不能转),没有「value 维度不为 0」。

期望

错误码表补一条 161002 子项 「value 的维度不为 0」,与参数表 L99 的「维度仅支持0维」对应,使调用方只读错误码表也能知道 161002 的这一种来源。

环境

  • 硬件:Atlas A2(910B2),npu-smi 26.1.1,aarch64
  • CANN:9.2.0,g++ 11.4.0,glibc 2.35
  • 仓库与提交:cann/ops-math 584b2ea6
  • 复现日期:2026-10-25

复现步骤

  1. 保存下方代码为 repro.cpp
  2. source $ASCEND_HOME_PATH/set_env.sh
  3. g++ -std=c++17 -O2 repro.cpp -o repro -I$ASCEND_HOME_PATH/include -L$ASCEND_HOME_PATH/lib64 -Wl,-rpath,$ASCEND_HOME_PATH/lib64 -Wl,--allow-shlib-undefined -lascendcl -lopapi -lnnopbase
  4. REPRO_DEVICE=1 ./repro(0 号 die 非健康时换健康 die 编号)
  5. 观察第 2 组输出为 phase1=161002

复现脚本

// aclnnInplaceMaskedFillTensor: the parameter table says "value 维度仅支持0维", and the
// implementation does reject a 1-dim value with 161002 -- but the error-code table of the
// same document has no such item, so a caller cannot learn this constraint from the doc.
// Control group: 0-dim value -> 0/0.
#include <cstdio>
#include <cstdlib>
#include <vector>
#include "acl/acl.h"
#include "aclnnop/aclnn_masked_fill_tensor.h"

static aclTensor* Mk(std::vector<int64_t> sh, aclDataType dt, void* dev) {
    std::vector<int64_t> st(sh.size(), 1);
    for (int i = (int)sh.size() - 2; i >= 0; --i) st[i] = sh[i + 1] * st[i + 1];
    return aclCreateTensor(sh.data(), sh.size(), dt, st.data(), 0, ACL_FORMAT_ND,
                           sh.data(), sh.size(), dev);
}

static int Run(std::vector<int64_t> vsh, void* self, void* mask, void* val) {
    aclTensor* ts = Mk({4, 3}, ACL_FLOAT, self);
    aclTensor* tm = Mk({4, 3}, ACL_BOOL, mask);
    aclTensor* tv = Mk(vsh, ACL_FLOAT, val);
    uint64_t ws = 0;
    aclOpExecutor* ex = nullptr;
    int r = (int)aclnnInplaceMaskedFillTensorGetWorkspaceSize(ts, tm, tv, &ws, &ex);
    printf("  value ndim=%zu -> phase1=%d", vsh.size(), r);
    if (r == 0) {
        void* p = nullptr;
        if (ws > 0) aclrtMalloc(&p, ws, ACL_MEM_MALLOC_HUGE_FIRST);
        int r2 = (int)aclnnInplaceMaskedFillTensor(p, ws, ex, nullptr);
        printf("  phase2=%d  sync=%d\n", r2, (int)aclrtSynchronizeStream(nullptr));
        if (p) aclrtFree(p);
    } else {
        printf("\n");
    }
    aclDestroyTensor(ts); aclDestroyTensor(tm); aclDestroyTensor(tv);
    return r;
}

int main() {
    int dev = getenv("REPRO_DEVICE") ? atoi(getenv("REPRO_DEVICE")) : 0;
    aclInit(nullptr);
    aclrtSetDevice(dev);

    void *self = nullptr, *mask = nullptr, *v0 = nullptr, *v1 = nullptr;
    aclrtMalloc(&self, 48, ACL_MEM_MALLOC_HUGE_FIRST);
    aclrtMalloc(&mask, 12, ACL_MEM_MALLOC_HUGE_FIRST);
    aclrtMalloc(&v0, 4, ACL_MEM_MALLOC_HUGE_FIRST);
    aclrtMalloc(&v1, 16, ACL_MEM_MALLOC_HUGE_FIRST);
    float host[12] = {1.5f, -2.25f, 0.f, 100.5f, -100.5f, 0.125f,
                      -0.125f, 7.5f, -7.5f, 0.5f, 3.f, -4.f};
    unsigned char mk[12] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1};
    float vh[4] = {1.5f, 1.5f, 1.5f, 1.5f};
    aclrtMemcpy(self, 48, host, 48, ACL_MEMCPY_HOST_TO_DEVICE);
    aclrtMemcpy(mask, 12, mk, 12, ACL_MEMCPY_HOST_TO_DEVICE);
    aclrtMemcpy(v0, 4, vh, 4, ACL_MEMCPY_HOST_TO_DEVICE);
    aclrtMemcpy(v1, 16, vh, 16, ACL_MEMCPY_HOST_TO_DEVICE);

    printf("[1] control: value=fp32[[]] (0-dim)\n");
    Run({}, self, mask, v0);
    printf("[2] defect : value=fp32[4] (1-dim, doc says only 0-dim)\n");
    Run({4}, self, mask, v1);

    aclrtFree(self); aclrtFree(mask); aclrtFree(v0); aclrtFree(v1);
    aclrtResetDevice(dev);
    aclFinalize();
    return 0;
}

实测输出:

[1] control: value=fp32[[]] (0-dim)
  value ndim=0 -> phase1=0  phase2=0  sync=0
[2] defect : value=fp32[4] (1-dim, doc says only 0-dim)
  value ndim=1 -> phase1=161002

影响

按错误码表分诊时会把 161002 一律理解为 dtype/broadcast 问题,去改 dtype 或重排 shape,而真实原因是 value 维度传错(例如把 torch.tensor(v) 写成 torch.tensor([v])),定位路径被拉长。

建议

在 aclnnInplaceMaskedFillTensor.md 错误码表 161002 的 rowspan 里增加子项「value 的维度不为 0」,与另外三条并列;aclnnInplaceMaskedFillScalar 的 value 是标量,不受此约束,无需改动。

likedislike
liuhanwen8liuhanwen8
17 days ago Added label: bug-report
陈思
陈思Collaborators
16 days ago Comments:

您好,感谢反馈!在 cann/ops-math@584b2ea6 中,参数表已经明确 value 仅支持 0 维,但错误码表的三个 161002 子项确实没有列出这一来源。参数约束、错误码表。

实现中,CheckShape 显式要求 value 的维度为 0,失败后由 CheckParams 映射为 ACLNN_ERR_PARAM_INVALID,并由第一段返回,因此您报告的一维 value 返回 161002 与现有检查一致。维度检查及返回映射。这里判断的是维度数,只有一个元素的 [1] 也仍是一维,与零维张量不同。

可行的资料修正是增加“value 的维度不为 0”这一 161002 子项,并同步调整表格跨行数,使错误码说明与参数表、实现一致;现有零维约束和原地填充行为无需因此改变。本条补充范围适用于 Tensor 接口,Scalar 接口无需增加该张量维度条件。

likedislike
陈思陈思Collaborators
16 days ago Assign chen_0715 as responsible person
陈思陈思Collaborators
16 days ago Added label: pending-confirmation
陈思陈思Collaborators
16 days ago Removed label: pending-confirmation
CchenyifengCollaborators
15 days ago Assign Anthony0331 as responsible person
CchenyifengCollaborators
15 days ago Removed responsible person chen_0715
wangchao661wangchao661Collaborators
15 days ago Assign wangchao661 as responsible person
wangchao661wangchao661Collaborators
15 days ago Associated pull request
CANN-robotCANN-robotCollaborators
14 days ago Close issue
CANN-robotCANN-robotCollaborators
14 days ago Added label: resolved