已关闭
[Bug-Report|缺陷反馈]: aclnnApplyTopKTopP 的 p/k 双空校验仅记日志未返回,非法入参被放行并产生静默错误结果 #5999
liuhanwen8创建于 25 天前关闭于 15 天前
25 天前 添加了label:bug-report
yuning_chen
24 天前 评论:
24 天前 评论:
初步分析
感谢反馈,我们已开始核对这个问题。
现象理解:期望 p 与 k 同时为空时,第一段接口拦截并返回空指针类错误码;正文称 CheckNotNull 仅打日志后仍返回成功,非法组合被放行,可能静默写出未过滤结果或变成内部错误码。
当前判断:初步判断,待复现确认。从给出的代码看,双空分支缺少失败返回的可能性存在,但实际返回码和 out 内容需按「二者均为空指针」实测,不能当作已确认根因。
涉及范围:aclnnApplyTopKTopP 的空指针校验(aclnn_apply_top_k_top_p.cpp)。
下一步:我们会按该组合补充核对与复现,确认是否需补失败返回、对齐资料错误码,以及是否漏测。


24 天前 将 bartonfang 设为负责人
yuning_chen
24 天前 评论:
24 天前 评论:
您好,问题已收到,目前 @bartonfang 正在处理中。


yangziqi007
22 天前 评论:
22 天前 评论:
/assign


22 天前 将 yangziqi_007 设为负责人
22 天前 修改了issue 的描述
19 天前 关联了pull request:fix(apply_top_k_top_p): 拦截 p 和 k 同时为空
15 天前 关闭了 issue
yangziqi007
15 天前 评论:
15 天前 评论:
感谢指出,问题已修复合入


15 天前 添加了label:resolved
问题描述
aclnnApplyTopKTopP第一段接口中,对「p与k同时为空」这一非法组合的校验只打印日志、未返回失败,导致该非法入参被判定为合法并继续执行,最终产生静默错误结果或语义失真的内部错误码。算子契约(
README.md约束说明)与接口资料均明确要求:p和k为可选输入,二者不能同时为空,至少传入一个。代码中的错误文本也逐字复述了这条约束,但控制流没有落实。问题代码位置
index/apply_top_k_top_p_with_sorted/op_api/aclnn_apply_top_k_top_p.cpp:47-55static bool CheckNotNull(const aclTensor* logits, const aclTensor* p, const aclTensor* k, const aclTensor* out) { OP_CHECK_NULL(logits, return false); if (p == nullptr && k == nullptr) { OP_LOGE(ACLNN_ERR_PARAM_INVALID, "The inputs, p and k, should not be nullptr at the same time."); } OP_CHECK_NULL(out, return false); return true; }第 50-52 行检测到「双空」后仅记录日志,缺少
return false;,函数继续执行到第 54 行return true;。一、调用链推演:非法组合被判定为合法
CheckParams()(同文件:121-137)按顺序调用四个校验,双空时逐个「顺利通过」:p==nullptr && k==nullptr)时的行为CheckNotNull(:47-55)OP_LOGE→ 落到 L54return trueCheckDtypeValid(:57-75)if (p != nullptr)、L64if (k != nullptr)均跳过CheckShapeValid(:77-98)if (p != nullptr)、L84if (k != nullptr)均跳过CheckFormatValid(:100-119)if (p != nullptr)、L110if (k != nullptr)均跳过即
CheckParams()于 L136return ACLNN_SUCCESS;。后续:152-165的pIsEmpty/kIsEmpty因p、k皆为nullptr而保持false,L160 的空 tensor 短路分支也不会命中,非法入参被完整放行至下游。二、非对称性证据:同文件同函数族唯一被漏掉的
return统计同文件
OP_LOGE与其下一行语句的配对关系,可以清楚看到漏改的孤立性:OP_LOGE之后的语句:103CheckFormatValidreturn false;:107CheckFormatValidreturn false;:111CheckFormatValidreturn false;:115CheckFormatValidreturn false;:88(返回在:90)CheckShapeValidreturn false;:93(返回在:95)CheckShapeValidreturn false;:51CheckNotNull}(直接落入return true)全文件 7 处
OP_LOGE中,唯独第 51 行之后没有返回语句。同文件其余 6 处校验均采用「记日志 + 返回失败」的一致写法(该文件return false共 18 处、CHECK_RET共 13 处),属单点遗漏而非有意设计。三、错误码与资料契约不符
接口资料
docs/aclnnApplyTopKTopP.md:195-203的第一段接口报错表明确划分了两种返回码:ACLNN_ERR_PARAM_NULLPTRACLNN_ERR_PARAM_INVALID按资料,「p 与 k 同为空指针」应返回 161001。但代码第 51 行:
ACLNN_ERR_PARAM_INVALID(对应 161002)作为OP_LOGE的首个参数传入 —— 与资料规定的 161001 类别不符;return false,这个错误码只出现在日志文本里,不会作为返回码对外返回。四、实际后果(两条下游路径,均为错误行为)
放行后
logits的尾维大小决定走向哪条路径:路径 A ——
logits尾维为 1(命中:181-182)179: bool isLastDimSizeOne = logits->GetViewShape()[DIM_ONE] == 1; 180: auto viewCopyResult = logitsContiguous; 181: if (isLastDimSizeOne) { 182: viewCopyResult = l0op::ViewCopy(logitsContiguous, out, uniqueExecutor.get());该分支只做一次直拷,既不执行 top-k 也不执行 top-p,随后于
:197-199正常返回ACLNN_SUCCESS。即:out被静默写为logits原值,未做任何过滤。这是静默错误结果:调用方拿到「成功」与全量未过滤的 logits,无任何异常提示。同时该行为也与算子资料给出的计算公式(
probsValue = softmax(...)、probsSum = cumsum(...)、topPMask过滤)完全不符——out本应是过滤后的结果。路径 B ——
logits尾维大于 1(命中:189-191)189: auto res = l0op::ApplyTopKTopPWithSorted(sortedValue, sortedIndices, pContiguous, kContiguous, logitsContiguous, 190: uniqueExecutor.get()); 191: CHECK_RET(res != nullptr, ACLNN_ERR_INNER_NULLPTR);此时
pContiguous/kContiguous均为nullptr(:169-178因p == nullptr、k == nullptr未赋值),被直接传入 l0op。若 l0op 因双空返回nullptr,接口将返回ACLNN_ERR_INNER_NULLPTR—— 属内部错误码,用户无从判断是「入参组合非法」,排障语义失真。