Closed
[Bug-Report|缺陷反馈]: aclnnCdist 出参与 x1 的 batch 维不匹配时返回 561103 而非 161002 #3929
liuhanwen8Add on 13 days agoClosed at 8 days ago
13 days ago Added label: bug-report
陈思
13 days ago Comments:
13 days ago Comments:
您好,感谢提供对照用例!按您报告的 584b2ea6cbaeba684a51a74296d82d4d50ab3b0f 核查,CheckShape确实没有比较 out 与预期结果形状,这一校验缺口需要处理。
问题分析
这里有两点需要澄清:对于二维输入 [P,M],第一维是点数 P,并非 batch 维。因此 x1=[2,5]、x2=[1,5] 的合法输出是 [2,1]。更一般地,输出应为 broadcast(x1[:-2], x2[:-2]) + [P,R];p 决定距离范数,不参与输出形状推导,也不能要求 x1、x2 的点数相同。
当前实现只在前置检查中限制秩和尾部特征维 M,之后才广播输入、构建结果,并在末尾通过 ViewCopy 写入 out;该处空返回会映射为内部错误。因此漏检允许错误 out 继续进入构图,存在返回内部错误的路径。不过,本次 561103 具体在哪一步触发,仍需结合第一段日志确认,不能仅由返回码认定是 reshape、broadcast 或最终复制中的某一步。
文档已经规定输出形状关系,但该版本错误码表没有单列“out 与推导结果形状不一致”这一项;建议补充明确说明,而非把现有“维度不在支持范围内”直接等同于完整形状关系校验。
处理方向
可在第一段参数检查中先验证前导维广播关系、推导预期输出,再逐维比较 out,不匹配统一返回 161002。这项检查应放在空输入提前返回及后续构图之前,兼顾零点数、零特征维的现有语义。
回归可覆盖本例、正确的 [2,1] 输出、合法的不同点数 P/R、带前导维广播和错误输出秩/各轴长度,以及空 Tensor 分支。以上为固定版本源码核查,尚未独立设备复验;我们会继续确认具体报错点及前置校验方案。


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
现象
aclnnCdist在x1=[2,5]、x2=[1,5]、out=[1,1](out 与 x1 的 batch 维不一致)时,第一段返回 561103(ACLNN_ERR_INNER_NULLPTR);资料错误码表要求 161002。x1=[1,5]、x2=[1,5]、out=[1,1]→ 两段均 0。x1=[2,5]、out=[1,1]→ 第一段 561103(应为 161002)。CheckShape只校验了维度个数与「x1/x2 最后一维相同」,没有校验 out 与 x1/x2 推导出的期望形状一致。期望
out形状与x1/x2推导出的结果形状不一致时,第一段返回161002(ACLNN_ERR_PARAM_INVALID)。环境
soc=Ascend910B2)584b2ea6复现步骤
math/cdist/op_api/aclnn_cdist.h;库用 CANN 的libopapi.so/libnnopbase.so/libascendcl.so。repro:先跑对照(x1/x2/out 形状匹配),再跑缺陷组(x1 第 0 维改成 2、out 保持 [1,1])。复现脚本
g++ -std=c++17 -O1 repro.cpp -o repro \ -I$ASCEND_HOME/include -I$ASCEND_HOME/aarch64-linux/include/aclnnop \ -I<ops-math>/math/cdist/op_api \ -I<ops-math>/common/inc/external -I<ops-math>/third_party/opbase/include \ -L$ASCEND_HOME/lib64 -lopapi -lnnopbase -lascendcl LD_LIBRARY_PATH=$ASCEND_HOME/lib64 ./repro 0// aclnnCdist:x1 与 out 的 batch 维不一致(x1=[2,5]、out=[1,1])返回 561103;资料要求 161002。 // 对照:x1=[1,5]、x2=[1,5]、out=[1,1] → 两段均 0。 #include <acl/acl.h> #include <cstdio> #include <vector> #include "aclnn_cdist.h" static aclTensor* mk(std::vector<int64_t>& d, void* p) { std::vector<int64_t> s(d.size(), 1); for (int i = static_cast<int>(d.size()) - 2; i >= 0; --i) { s[i] = s[i + 1] * d[i + 1]; } return aclCreateTensor(d.data(), d.size(), ACL_FLOAT, s.data(), 0, ACL_FORMAT_ND, d.data(), d.size(), p); } static void run(const char* tag, std::vector<int64_t> d1, std::vector<int64_t> d2, std::vector<int64_t> dOut, aclrtStream st) { auto numel = [](const std::vector<int64_t>& d) { size_t n = 1; for (auto v : d) { n *= static_cast<size_t>(v); } return n; }; void *x1 = nullptr, *x2 = nullptr, *o = nullptr; aclrtMalloc(&x1, numel(d1) * 4, ACL_MEM_MALLOC_HUGE_FIRST); aclrtMalloc(&x2, numel(d2) * 4, ACL_MEM_MALLOC_HUGE_FIRST); aclrtMalloc(&o, numel(dOut) * 4, ACL_MEM_MALLOC_HUGE_FIRST); std::vector<float> h1(numel(d1), 1.0f), h2(numel(d2), 2.0f); aclrtMemcpy(x1, numel(d1) * 4, h1.data(), numel(d1) * 4, ACL_MEMCPY_HOST_TO_DEVICE); aclrtMemcpy(x2, numel(d2) * 4, h2.data(), numel(d2) * 4, ACL_MEMCPY_HOST_TO_DEVICE); aclTensor* t1 = mk(d1, x1); aclTensor* t2 = mk(d2, x2); aclTensor* to = mk(dOut, o); uint64_t ws = 0; aclOpExecutor* ex = nullptr; aclnnStatus r1 = aclnnCdistGetWorkspaceSize(t1, t2, 2.0f, 2, to, &ws, &ex); int r2 = -1; if (r1 == ACL_SUCCESS) { void* wsp = nullptr; if (ws > 0) { aclrtMalloc(&wsp, ws, ACL_MEM_MALLOC_HUGE_FIRST); } r2 = static_cast<int>(aclnnCdist(wsp, ws, ex, st)); aclrtSynchronizeStream(st); if (wsp != nullptr) { aclrtFree(wsp); } } printf("%-32s phase1=%-7d phase2=%d\n", tag, static_cast<int>(r1), r2); fflush(stdout); aclDestroyTensor(t1); aclDestroyTensor(t2); aclDestroyTensor(to); aclrtFree(x1); aclrtFree(x2); aclrtFree(o); } int main(int argc, char** argv) { int dev = (argc > 1) ? atoi(argv[1]) : 0; aclInit(nullptr); aclrtSetDevice(dev); aclrtStream st = nullptr; aclrtCreateStream(&st); run("[对照] x1[1,5] x2[1,5] out[1,1]", {1, 5}, {1, 5}, {1, 1}, st); run("[缺陷] x1[2,5] x2[1,5] out[1,1]", {2, 5}, {1, 5}, {1, 1}, st); aclrtDestroyStream(st); aclrtResetDevice(dev); aclFinalize(); return 0; }实测输出:
影响
形状参数错误未被参数校验拦下,返回内部错误码,调用方无法据码定位;非法形状继续进入 reshape/broadcast 构图路径,后续报错点与真正原因脱节。
建议
math/cdist/op_api/aclnn_cdist.cpp的CheckShape增加出参联动校验:按p/维度关系推导期望 out 形状([x1.dim0, x2.dim0]等)并与out的 view shape 逐维比较,不一致返回ACLNN_ERR_PARAM_INVALID;参考同仓aclnnSplitTensor的同类修复(#3918)。