Closed
[Documentation|文档反馈]: aclnnCummin 参数表要求 valuesOut 与 self 同 dtype,与错误码表「不能转换才报错」自相矛盾(实测 int32→fp32 放行) #3969
liuhanwen8Add on  14 days agoClosed at  10 days ago
liuhanwen8
liuhanwen8
14 days ago Create

现象

aclnnCummin 的实现接受 self 与 valuesOut 的 跨 dtype(int32 → fp32),两段返回 0 且结果正确;而同一份资料的参数表要求两者 dtype 必须一致。

输入 phase1 phase2 说明
self=int32 valuesOut=int32 0 0 对照组
self=int32 valuesOut=fp32 0 0 参数表要求同 dtype,实测放行

资料 math/cummin/docs/aclnnCummin.md 内部两处措辞互相冲突:L113(参数表 valuesOut 使用说明)
数据类型需要与self一致,shape需要与self一致。;L190(错误码 161002 子项)
参数self的数据类型不能转换为valuesOut的数据类型。 —— 参数表说"必须一致",错误码表说"不能转换才报错",后者隐含"可转换就可以"。

期望

两处统一为一种口径:若以错误码表为准(实现当前行为),参数表应改为 「数据类型需要能转换为 valuesOut 的数据类型」(与 self 行写法一致);
若以参数表为准,则第一段应对 self=int32 / valuesOut=fp32 返回 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=0 phase2=0

复现脚本

// aclnnCummin: doc parameter table says valuesOut must have the SAME dtype as self,
// but the implementation accepts a cross-dtype (int32 self -> fp32 valuesOut).
// Control group: same-dtype call (also 0/0).
#include <cstdio>
#include <cstdlib>
#include <vector>
#include "acl/acl.h"
#include "aclnnop/aclnn_cummin.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(aclDataType sdt, aclDataType vdt, void* self, void* val, void* idx) {
    aclTensor* ts = Mk({4, 3}, sdt, self);
    aclTensor* tv = Mk({4, 3}, vdt, val);
    aclTensor* ti = Mk({4, 3}, ACL_INT64, idx);
    uint64_t ws = 0;
    aclOpExecutor* ex = nullptr;
    int r = (int)aclnnCumminGetWorkspaceSize(ts, 1, tv, ti, &ws, &ex);
    printf("  self=%-9s valuesOut=%-6s -> phase1=%d", sdt == ACL_INT32 ? "int32" : "int32",
           vdt == ACL_FLOAT ? "fp32" : "int32", r);
    if (r == 0) {
        void* p = nullptr;
        if (ws > 0) aclrtMalloc(&p, ws, ACL_MEM_MALLOC_HUGE_FIRST);
        int r2 = (int)aclnnCummin(p, ws, ex, nullptr);
        printf("  phase2=%d  sync=%d\n", r2, (int)aclrtSynchronizeStream(nullptr));
        if (p) aclrtFree(p);
    } else {
        printf("\n");
    }
    aclDestroyTensor(ts); aclDestroyTensor(tv); aclDestroyTensor(ti);
    return r;
}

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

    void *s32 = nullptr, *f32 = nullptr, *i64 = nullptr;
    aclrtMalloc(&s32, 48, ACL_MEM_MALLOC_HUGE_FIRST);
    aclrtMalloc(&f32, 48, ACL_MEM_MALLOC_HUGE_FIRST);
    aclrtMalloc(&i64, 96, ACL_MEM_MALLOC_HUGE_FIRST);
    int32_t host[12] = {5, -3, 5, 2, -3, 0, 7, -8, 2, 2, -8, 3};
    aclrtMemcpy(s32, 48, host, 48, ACL_MEMCPY_HOST_TO_DEVICE);

    printf("[1] control: self=int32 valuesOut=int32\n");
    Run(ACL_INT32, ACL_INT32, s32, s32, i64);
    printf("[2] defect : self=int32 valuesOut=fp32 (doc: same dtype required)\n");
    Run(ACL_INT32, ACL_FLOAT, s32, f32, i64);

    aclrtFree(s32); aclrtFree(f32); aclrtFree(i64);
    aclrtResetDevice(dev);
    aclFinalize();
    return 0;
}

实测输出(910B2,CANN 9.2.0):

[1] control: self=int32 valuesOut=int32
  self=int32     valuesOut=int32  -> phase1=0  phase2=0  sync=0
[2] defect : self=int32 valuesOut=fp32 (doc: same dtype required)
  self=int32     valuesOut=fp32   -> phase1=0  phase2=0  sync=0

影响

按参数表实现的前端会先做 self 与 valuesOut 同 dtype 的断言或 Cast,多一次无谓转换;按实现写的前端则与参数表"必须一致"的要求冲突。"到底该不该 Cast"变成猜测。

建议

选定一种口径后改资料(math/cummin/docs/aclnnCummin.md L113 或 L190 择一),并在参数表 valuesOut 行补一句「允许可转换的跨 dtype(例如 int32 self + fp32 valuesOut)」,与错误码表措辞保持同一句话。

likedislike
liuhanwen8liuhanwen8
14 days ago Added label: bug-report
陈思
陈思Collaborators
13 days ago Comments:

您好,感谢指出。按您给出的 584b2ea6cbaeba684a51a74296d82d4d50ab3b0f 核查,参数表确实存在口径冲突:self 行要求能转换为 valuesOut 类型,而 valuesOut 行又要求与 self 完全一致;错误码表和头文件说明采用的也是可转换口径。

A2 使用的 ExecCummin会先按 self 类型计算累积最小值,再显式 Cast 到 valuesOut 类型,没有要求两者必须相同。因此 self=INT32、valuesOut=FLOAT 被接受有源码依据,并非跳过了全部类型检查,也不表示输入先降成 FLOAT 再进行比较。

建议将 valuesOut 行明确为:“self 的数据类型应能按接口支持的规则转换为 valuesOut 的数据类型,shape 需与 self 一致。”具体组合仍应核对支持列表和转换规则,不能仅由一条错误码描述推出任意跨类型组合都无条件支持;可转换也不等于数值无精度损失。您附带脚本目前展示的是执行状态,完整数值验证还需分别读回 valuesOut 与 indicesOut,并避免对照组的输入输出别名影响后续输入。我们会继续确认参数表、转换规则和实现行为的对齐方式。

likedislike
陈思陈思Collaborators
13 days ago Assign chen_0715 as responsible person
陈思陈思Collaborators
13 days ago Added label: pending-confirmation
陈思陈思Collaborators
13 days ago Removed label: pending-confirmation
Nice tryNice tryCollaborators
12 days ago Assign Nice_try as responsible person
Nice tryNice tryCollaborators
11 days ago Associated pull request
CANN-robotCANN-robotCollaborators
10 days ago Close issue
CANN-robotCANN-robotCollaborators
10 days ago Added label: resolved