Closed
[Bug-Report|缺陷反馈]: aclnnMultinomial / aclnnMultinomialTensor 空 self 早退不填非空输出(返回 SUCCESS 但 out 保持未初始化,脏数据流出) #3560
liuhanwen8Add on 26 days agoClosed at 24 days ago
26 days ago Added label: bug-report
陈思
25 days ago Comments:
25 days ago Comments:
您好,感谢反馈!
问题分析
核查 cann/ops-math master 8f1aae7e1927 的 Multinomial 实现,两个第一段入口共用 CheckShape/CheckValueRange:当前限制 numsamples 为正、无放回时不超过类别数,但没有排除类别维 C=0。因此在 replacement=true 时,self=[0] → out=[2] 或 self=[3,0] → out=[3,2] 可通过检查,再从 self->IsEmpty() 分支直接成功返回,未构造采样或写回节点。这与您提供的 out 哨兵值不变现象一致。
处理方向
一个更符合采样含义的方向是在共用校验中拒绝 C=0,使标量 seed/offset 和 Tensor seed/offset 两个入口保持一致。类别集合为空时,填索引 0 也不能代表一个有效采样结果,因此不宜仅通过回填 0 让接口返回成功。
还需要区分“零类别”与“零批次”:[0,C] 且 C>0 的结果 [0,numsamples] 本身为空,不能因为 self->IsEmpty() 就与 [N,0] 一并拒绝。可分别覆盖这两类形状以及 replacement 的两个取值,确认错误码和合法空输出路径。我们会持续跟踪这一参数校验问题。


yue-ma
25 days ago Comments:
25 days ago Comments:
assign @ji-songyuan


24 days ago Close issue
24 days ago Added label: resolved
现象
aclnnMultinomialGetWorkspaceSize/aclnnMultinomialTensorGetWorkspaceSize在self为空张量时裸早退:置workspaceSize=0直接返回ACLNN_SUCCESS,不进入计算、也不对输出out做任何写入。当out为非空张量时(shape 不小于self的对应维度),调用方拿到的是未初始化内存(脏数据/随机值),且接口无任何报错。代码位置
random/stateless_sample_multinomial/op_api/aclnn_multinomial.cpp// :463-467 aclnnMultinomialGetWorkspaceSize if (self->IsEmpty()) { *workspaceSize = 0; uniqueExecutor.ReleaseTo(executor); return ACLNN_SUCCESS; // <- out 完全未被写入 } // :569-573 aclnnMultinomialTensorGetWorkspaceSize(同型) if (self->IsEmpty()) { *workspaceSize = 0; uniqueExecutor.ReleaseTo(executor); return ACLNN_SUCCESS; }相关校验:
CheckShape(:153-182):仅约束self维度数 ∈ {1,2}、out维度数 ==self维度数、out末维 ==numsamples、2 维时out首维 ==self首维;未约束out空性随self联动。CheckValueRange(:184-203):numsamples > 0恒强制;!replacement && numsamples > C报错;C ≤ 2^24。⇒
C=0(self末维为 0)时,仅replacement=true可通过校验并抵达早退(replacement=false会因numsamples > C=0被拒)。影响
取
self末维C=0、replacement=true、numsamples ≥ 1:CheckShape放行:1 维self=[0]→out=[numsamples];2 维self=[N,0]→out=[N, numsamples],均为非空张量;CheckValueRange放行(numsamples>0;replacement=true跳过numsamples ≤ C;C=0 ≤ 2^24);:463早退,返回ACLNN_SUCCESS,out保持分配时的未初始化显存 → 调用方读到脏数据。正确语义:
C=0表示无类别可采样,应报错拒绝(PyTorch 对空输入 multinomial 抛错),或按outshape 填默认值;当前「成功却不写输出」属静默脏数据。复现(NPU 实测)
环境:CANN 9.2.0-beta.2,Ascend 910B2,device 2。以 ctypes 直调
libopapi_math.so;self用 FP32 全 0.25,out为 INT64 并预填哨兵999999,seed=1, offset=0:[0](C=0,空)[2](非空)ret=0 ACLNN_SUCCESS, workspaceSize=0,out 全 999999(未写)[3,0](C=0,空)[3,2](非空)ret=0 ACLNN_SUCCESS, workspaceSize=0,out 全 999999(未写)即接口返回成功,但非空
out完全未被写入(应为报错或全 0)。期望行为
C == 0时:① 返回ACLNN_ERR_PARAM_INVALID(161002)拒绝,或 ② 对out填默认值后再返回成功。二者取其一,保持「成功 ⇒ 输出有定义」。修复建议
任选其一:
self空且out空」;CheckParams/CheckParamsTensor增加C > 0约束,C == 0时返回ACLNN_ERR_PARAM_INVALID;out做Fill 0+ViewCopy回填(参考 ops-cvaclnn_roi_align.cpp:189-197空张量填 0 范式)。aclnnMultinomial与aclnnMultinomialTensor两处早退需一并处理。环境
关联(同机理、不同算子,非重复)