您好,感谢反馈!
问题分析
经代码核查,这个问题成立。当前 master 的 public conversion/im2col/op_api/aclnn_im2col.cpp 中,div_rtn<int64_t> 的入参和返回值均为 int64_t,但商和余数仍由 int q、int r 承接。当商或余数超出 int 可表示范围时会发生窄化,可能直接改变返回的输出尺寸,也可能破坏余数的符号判断并错误执行 --q。
此外,输出尺寸分子中的 2 * padding、dilation * (kernelSize - 1),以及后续输出 channel/spatial 的连乘都直接在 int64_t 中计算;现有参数校验只限制正负,没有对这些乘加做溢出检查。因此,仅将 q/r 改成模板类型可以修复窄化,但还不足以覆盖完整的溢出链路。
该问题在 9.1.0、9.2.0 和当前 master 的 public 路径中都存在。
处理方向
experimental 实现提供了一种可参考的处理方式:使用 __int128 计算 effective kernel、分子和除法结果,确认结果落在 int64_t 范围后再转换;输出 channel 和 spatial 的乘法则通过 SafeMul 检查。
相关实现由 PR !4358 合入,但该 PR 明确面向独立的 A2/A3 experimental 实现,不覆盖本 Issue 所指的 public Ascend950 路径,因此当前 public 实现仍需单独处理。
一个可行的解决方案是参考其中的宽类型中间计算与 SafeMul 保护,但不能直接假定两条路径可以整体复用;还需要评估 public 路径的参数错误语义、现有行为兼容性和边界 UT 覆盖。我们将继续确认这些修复边界,并评估适合 public 实现的处理方式。


Thanks for sending an issue! Please fill in the following template to help quickly solve your problem.
一、问题描述 (必填)
文件:行号:conversion/im2col/op_api/aclnn_im2col.cpp:47-60(定义)、:106-113(调用)
对照:experimental/conversion/im2col/op_api/aclnn_im2col.cpp:51-79(已用 __int128/SafeMul 做溢出防护)
代码片段(原样引用):
// aclnn_im2col.cpp:46-60
46 // Integer division rounding to -Infinity
47 template
48 static inline auto div_rtn(T x, T y) -> T
49 {
50 if (y == 0) {
51 OP_LOGE(ACL_ERROR_INVALID_PARAM, "Division by zero!");
52 return -1;
53 }
54 int q = x / y;
55 int r = x % y;
56 if ((r != 0) && ((r < 0) != (y < 0))) {
57 --q;
58 };
59 return q;
60 }
// aclnn_im2col.cpp:106-113(调用,T 实参为 int64_t)
106 int64_t outputHeight = div_rtn<int64_t>(
107 (inputHeight + 2 * (*padding)[0] - ((*dilation)[0] * ((*kernelSize)[0] - 1) + 1)),
108 (*stride)[0]) +
109 1;
110 int64_t outputWidth = div_rtn<int64_t>(
111 (inputWidth + 2 * (*padding)[1] - ((*dilation)[1] * ((*kernelSize)[1] - 1) + 1)),
112 (*stride)[1]) +
113 1;
缺陷描述:模板返回类型声明为 T(此处 int64_t),但函数体内 q、r 用 int(32 位)声明,对 64 位商/余数做隐式窄化;且 (*dilation)[i] * ((kernelSize)[i]-1)、2 * (padding)[i] 等乘法无溢出保护。当分子超过 INT32 范围时结果错误。对照实现(experimental 版本)已改用 __int128/SafeMul,证明该缺陷真实且修复方案已知。
触发条件:用户传入较大的 padding/kernelSize/dilation(仅校验 >0,未做上界约束),使 inputHeight + 2padding - (dilation(kernelSize-1)+1) 超出 INT32 范围(约 2.1e9)。
潜在影响:outputHeight/Width 计算错误 → 后续 outShape 与实际 out 比对错乱,出现「本应报错却通过」或「合法输入被误拒」;属静默数值/形状偏差。
修复建议:将 :54-55 的 q、r 改为 T;并参照 experimental 版本对分子乘法做溢出防护。
二、环境信息 (可选)
白盒检视不涉及
三、重现步骤 (可选)
白盒检视不涉及
四、预期结果 (可选)
无溢出问题
💡 备注(选填)