Closed
[Bug-Report|缺陷反馈]: aclnnInplaceDivMod shape 校验分支日志码 161001(空指针)与实际返回码 161002 不一致 #3962
liuhanwen8Add on 14 days agoClosed at 8 days ago
14 days ago Added label: bug-report
陈思
13 days ago Comments:
13 days ago Comments:
您好,感谢提供日志与返回值对照。按您报告的 584b2ea6cbaeba684a51a74296d82d4d50ab3b0f 核查,CheckInplace这个 shape 分支确实将日志标成 ACLNN_ERR_PARAM_NULLPTR,同时返回 ACLNN_ERR_PARAM_INVALID;这里应把日志标签统一为 161002,保留实际返回码。
本例两输入能广播到 [4,8],但原地输出 selfRef 只有 [1,8],不能据此扩大原地 Tensor,属于形状参数不合法。外层 CHECK_RET 的 561000 是另一条检查诊断,并不意味着函数改为返回内部错误;本项可先限定为修正具体 shape 分支的日志标签,真实空指针分支继续使用 161001。我们会继续确认日志与返回码的对齐方式。


13 days ago Assign chen_0715 as responsible person
13 days ago Added label: pending-confirmation
13 days ago Removed label: pending-confirmation
10 days ago Assign sakuraqqz as responsible person
10 days ago Removed responsible person chen_0715
8 days ago Close issue
8 days ago Added label: resolved
现象
aclnnInplaceDivMod在selfRef的 shape 不等于 broadcast 结果时,同一个错误路径上出现三个不同的错误码:aclnn_div.cpp:1085的OP_LOGEACLNN_ERR_PARAM_NULLPTR(空指针)aclnn_div.cpp:1164的外层OP_LOGEACLNN_ERR_INNER(内部错误)ACLNN_ERR_PARAM_INVALID(参数非法)实测(
ASCEND_SLOG_PRINT_TO_STDOUT=1):期望
日志码应与返回码一致。
CheckInplace中这个分支做的是 shape 校验:op::Shape broadcastShape; OP_CHECK(BroadcastInferShape(selfRef->GetViewShape(), other->GetViewShape(), broadcastShape), OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Shape of selfRef and other can't broadcast, ..."), return ACLNN_ERR_PARAM_INVALID); OP_CHECK(selfRef->GetViewShape() == broadcastShape, OP_LOGE(ACLNN_ERR_PARAM_NULLPTR, "Expected shape of selfRef should be %s, but got %s.", ...), return ACLNN_ERR_PARAM_INVALID); // <-- 日志写 NULLPTR,返回却是 PARAM_INVALID上一个分支(不能 broadcast)正确地用了
ACLNN_ERR_PARAM_INVALID;本条分支(shape 不等于 broadcast 结果)同样返回
ACLNN_ERR_PARAM_INVALID,但OP_LOGE写成了ACLNN_ERR_PARAM_NULLPTR。建议把
aclnn_div.cpp:1083的日志码改为ACLNN_ERR_PARAM_INVALID,与返回保持一致。环境
Atlas A3(Ascend910_93)单 die;CANN 9.2.0;driver 26.1.1 / 固件 7.8.0.6.201;
源码基线
cann/ops-mathmaster584b2ea6(已git fetch,local 与 origin 同 sha)。复现步骤
source /usr/local/Ascend/ascend-toolkit/set_env.shrepro.cppg++ -std=c++14 -O2 -I$ASCEND_HOME_PATH/include -I$ASCEND_HOME_PATH/include/aclnnop repro.cpp -o repro -L$ASCEND_HOME_PATH/lib64 -lascendcl -lopapi -lnnopbase -lpthreadASCEND_SLOG_PRINT_TO_STDOUT=1 ./repro161002,但其上方的日志行写的是errno[161001]复现脚本
#include <acl/acl.h> #include <aclnnop/aclnn_div.h> #include <cstdio> #include <vector> #define CK(x, m) do { int _r = (x); if (_r != ACL_SUCCESS) { \ printf(" [ERR] %s ret=%d\n", m, _r); return _r; } } while (0) class Buf { public: void* p = nullptr; aclTensor* t = nullptr; ~Buf() { if (t) aclDestroyTensor(t); if (p) aclrtFree(p); } }; static int MakeF32(Buf& b, const std::vector<int64_t>& sh, float fill) { int64_t n = 1; for (size_t i = 0; i < sh.size(); ++i) n *= sh[i]; size_t by = (size_t)n * sizeof(float); std::vector<float> h((size_t)n, fill); CK(aclrtMalloc(&b.p, by, ACL_MEM_MALLOC_HUGE_FIRST), "malloc"); CK(aclrtMemcpy(b.p, by, h.data(), by, ACL_MEMCPY_HOST_TO_DEVICE), "h2d"); 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]; b.t = aclCreateTensor(sh.data(), sh.size(), ACL_FLOAT, st.data(), 0, ACL_FORMAT_ND, sh.data(), sh.size(), b.p); return b.t ? 0 : -1; } static int One(const char* tag, std::vector<int64_t> sref, std::vector<int64_t> sother) { Buf A, B; if (MakeF32(A, sref, 2.0f) || MakeF32(B, sother, 1.5f)) { printf(" [%s] SETUP_FAIL\n", tag); return -1; } uint64_t ws = 0; aclOpExecutor* ex = nullptr; int r1 = (int)aclnnInplaceDivModGetWorkspaceSize(A.t, B.t, 0, &ws, &ex); printf(" [%s] GetWorkspaceSize = %d\n", tag, r1); return r1; } int main() { CK(aclInit(nullptr), "aclInit"); CK(aclrtSetDevice(0), "setDevice"); int c1 = One("对照组 CTRL selfRef=[4,8] other=[4,8]", { 4, 8 }, { 4, 8 }); int d1 = One("缺陷组 DEFECT selfRef=[1,8] other=[4,8]", { 1, 8 }, { 4, 8 }); printf("\n===== summary =====\n"); printf(" CTRL return code = %d (expect 0)\n", c1); printf(" DEFECT return code = %d (expect 161002)\n", d1); aclrtResetDevice(0); aclFinalize(); return 0; }实测输出(节选,日志行为
ASCEND_SLOG_PRINT_TO_STDOUT=1打印):影响
按错误码排障的人会被引向错误方向:资料里 161001 的唯一含义是「传入的 selfRef、other 是空指针」,
与本场景(shape 不匹配)无关。用户拿着
errno[161001]去查空指针,会白查一轮。外层再打一行
561000(内部错误)进一步干扰——真正的原因(shape 不等于 broadcast 结果)反而只在日志的文字部分才能看到。
建议
aclnn_div.cpp:1083的OP_LOGE首参改为ACLNN_ERR_PARAM_INVALID,与return一致;