Closed
[Bug-Report|缺陷反馈]: aclnnDistributeBarrier 的 group 空串/超长分支在 aclnnStatus 函数内 return false 被当作 SUCCESS,最终返回 161001 与空指针无法区分 #6566
liuhanwen8Add on 23 days agoClosed at 18 days ago
23 days ago Added label: bug-report
周云飞
23 days ago Comments:
23 days ago Comments:
感谢提供完整的复现用例和环境信息。您指出的返回值问题有明确依据:在所贴的 BarrierCheckParams 片段中,函数返回类型是 aclnnStatus,非法长度分支却返回 false。按片段中的成功码判断方式,false 转为数值 0 后会被当作成功,因此该分支虽然打印了错误日志,却没有阻止后续调用。
问题分析
这里需要区分两件事:一是参数校验错误地返回成功,二是后续流程最终返回了什么错误码。前者可由您提供的代码片段直接判断;空串和超长字符串最终返回 161001,则是您在 A2 910B2、CANN 9.2.0 环境下报告的实测结果,具体由后续哪一层产生仍需进一步确认。
V1 入口和 V2 入口确实都调用 aclnnDistributeBarrierGetWorkspaceSizeBase,因此处理范围需要同时考虑两个接口的工作空间查询阶段。不过,目前提供的实测结果仅覆盖 V1,不能直接视为 V2 已完成验证。
处理方向
一个可行的修正方向是:在 BarrierCheckParams 中,将空串或长度大于等于 HCCL_GROUP_NAME_MAX 的分支改为返回 ACLNN_ERR_PARAM_INVALID,保留 group == nullptr 的空指针错误返回。这样可以在参数检查阶段直接区分“指针为空”和“字符串取值非法”,而不是依赖后续流程报错。
文档也应与最终确认的返回行为保持一致,明确空串及超长字符串对应的错误码,并避免将 group 空指针仅描述为“必选 Tensor 是空指针”。验证时需要同时覆盖两个接口的空指针、空串、长度边界和有效通信域输入,确认错误码区分正确且正常调用不受影响。


游震
23 days ago Comments:
23 days ago Comments:
/assign @luobaiqing


23 days ago Assign luobaiqing as responsible person
22 days ago Assign SuperYuan as responsible person
22 days ago Removed responsible person luobaiqing
20 days ago Associated pull request
18 days ago Close issue
18 days ago Added label: resolved
问题描述
mc2/distribute_barrier/op_api/distribute_barrier_base.cpp的BarrierCheckParams声明为aclnnStatus,但 group 取值非法(空串 / 超长)分支里写的是return false;:aclnnStatus BarrierCheckParams(const aclTensor* xRef, const char* group) { CHECK_RET(BarrierCheckNullStatus(xRef, group), ACLNN_ERR_PARAM_NULLPTR); auto groupStrnLen = strnlen(group, HCCL_GROUP_NAME_MAX); if ((groupStrnLen >= HCCL_GROUP_NAME_MAX) || (groupStrnLen == 0)) { OP_LOGE_FOR_INVALID_VALUE_WITH_REASON("aclnnDistributeBarrier", "group", ...); return false; // ← 0 == ACLNN_SUCCESS,"取值非法"被吞成成功 } return ACLNN_SUCCESS; }false转aclnnStatus即0=ACLNN_SUCCESS,于是调用点的CHECK_RET(retParam == ACLNN_SUCCESS, retParam)直接放行,这段取值校验完全没有生效:接口继续带着空groupBuf进入aclnnInnerDistributeBarrierGetWorkspaceSize。用户可见后果:group 为空串 / 超长时返回
161001(资料定义为「必选参数 Tensor 是空指针」),与group=nullptr的返回码完全一样,无法区分「指针为空」与「取值非法」;日志里打印的是value must be in the range (0, HCCL_GROUP_NAME_MAX),返回码却是空指针语义,定位会走偏。资料docs/aclnnDistributeBarrier.md的错误码表只列了161001 = 输入的必选参数 Tensor 是空指针,没有覆盖「group 取值非法」这一实际路径。实测(A2 910B2):
group = nullptr161001161001group = ""(空串)161001(与 nullptr 相同)group = "aaa…"(127 字符,超HCCL_GROUP_NAME_MAX)161001(与 nullptr 相同)三种情况
workspaceSize均为 0,进程不崩溃。环境信息
npu-smi26.1.1)cann/ops-transformermasterce0faee2(2026-10-23 09:52)复现脚本
// 编译: g++ -std=c++17 -O2 dbarrier.cpp -o dbarrier \ // -I$ASCEND_HOME_PATH/include -L$ASCEND_HOME_PATH/lib64 \ // -lascendcl -lopapi -lnnopbase // 运行: ./dbarrier #include <acl/acl.h> #include <aclnnop/aclnn_distribute_barrier.h> #include <cstdio> #include <cstring> #include <vector> static aclTensor *mkT(std::vector<int64_t> s, aclDataType dt, void *d) { std::vector<int64_t> st(s.size()); int64_t k = 1; for (int i = (int)s.size() - 1; i >= 0; --i) { st[i] = k; k *= s[i]; } return aclCreateTensor(s.data(), s.size(), dt, st.data(), 0, ACL_FORMAT_ND, s.data(), s.size(), d); } static void trial(const char *tag, const char *group) { void *dx = nullptr; aclrtMalloc(&dx, 64, ACL_MEM_MALLOC_HUGE_FIRST); std::vector<float> h(2, 1.0f); aclrtMemcpy(dx, 8, h.data(), 8, ACL_MEMCPY_HOST_TO_DEVICE); aclTensor *x = mkT({2}, ACL_FLOAT, dx); uint64_t ws = 0; aclOpExecutor *ex = nullptr; printf("-- %-34s group=%s\n", tag, group ? (group[0] ? group : "<empty>") : "nullptr"); aclnnStatus r = aclnnDistributeBarrierGetWorkspaceSize(x, group, 1, &ws, &ex); printf(" ret=%d ws=%llu\n", (int)r, (unsigned long long)ws); } int main() { aclInit(nullptr); aclrtSetDevice(0); trial("CTRL nullptr group", nullptr); trial("BUG empty group", ""); char longg[128]; memset(longg, 'a', sizeof(longg) - 1); longg[127] = 0; trial("BUG overlong group", longg); aclrtResetDevice(0); aclFinalize(); return 0; }实测输出:
期望行为
BarrierCheckParams的取值非法分支返回ACLNN_ERR_PARAM_INVALID(161002),使「group 为空指针」与「group 取值非法」两条路径可区分;同时资料错误码表补一行「group 为空串或长度 ≥HCCL_GROUP_NAME_MAX」的说明。影响
aclnnDistributeBarrier/aclnnDistributeBarrierV2(共用distribute_barrier_base.cpp)在 group 参数写错时,给用户的返回码与「传了空指针」完全一致,日志文案又指向「取值范围」,排障时容易被引到错误方向;且 aclnn 层这道校验实际是死代码,后续 Inner 若变更对空 group 的处理,将直接落到 kernel 侧。