非真实问题
报错可稳定复现,次数、size、block、地址均与 issue 完全一致。经核查,属mssanitizer 对 DataCopyPad(..., PaddingMode::Compact) 取数地址的建模偏差,不是算子真实越界,也不影响精度。
1. 复现
- 环境:CANN 9.3.0(
/home/LuckySun/Ascend)、Ascend950DT_9592(72 AIV)、TTK 3.0.0、mssanitizer 26.3.0.dev202611120100
mssanitizer --tool=memcheck --leak-check=yes --check-unused-memory=yes -- \
python3 -m ttk kernel -i <附件 trigger_cases.csv> \
--compile-opts op_debug_config=sanitizer --pc 1 --devices 0
| 用例 | 结果 |
|---|---|
L0_001(x=(14,47,45,15) fp32) |
L0_001_10000000,block aiv(0-46):3 × illegal read of size 236 |
L0_011(x=(54,12,59,12) fp32) |
L0_011_31000000,block aiv(0-11):6 × illegal read of size 304 |
L0_001_varp10 / L0_001_varm146 / L0_011_varp110 |
附件行本身非法(x 与 dy 形状不一致)→ Input shapes are invalid.,tiling 失败,非算子问题 |
合计 9 条 illegal read,地址 0x1b1a0、0x28de0、0x36b20,与 issue 日志逐地址一致;
records undetected = 0(覆盖完整,非漏扫)。
2. 根因
一句话:工具以为每行数据之间有 32B 对齐填充,按"加大后的行距"算读地址,于是算到了缓冲区外面;实际数据是紧挨着放的。
分四步:
-
搬运方式:
dx由CopyOutRAR()从 UB 搬回 GM ——
op_kernel/arch35/batch_norm3d_grad_full_load_regbase.h:615(tiling key 10000000)与
batch_norm3d_grad_split_r1_regbase.h:1098(tiling key 31000000)的
DataCopyPad<..., PaddingMode::Compact>,一次搬 r1 行(14 行),每行 =r0 × 4B
= 2700 B(r0=675)或 2832 B(r0=708)。UB 内行与行紧挨着,无填充;
缓冲按紧凑总长分配:14×2700 = 37800 B ≤ 37824 B、14×2832 = 39648 B ≤ 39680 B。 -
工具怎么算:mssanitizer 把行距按 32 B 向上取整(2700 → 2720、2832 → 2848),
第 14 行起点算成13×2720 = 35360 B,读 2700 B 到 38060 B,比 37824 B 的缓冲多出 236 B
—— 这与 issue 报的size 236精确吻合(另一条路径多出 176 B,对应size 304的同类量)。 -
实际怎么取数:CANN 实现里,Compact 模式的行步长直接用行字节数,不做 32 B 对齐;
只有 Normal 模式才对齐(asc/impl/basic_api/dav_3510/kernel_operator_data_copy_impl.h:102-123):
if constexpr (mode == PaddingMode::Normal) {
srcStride310 = srcStride * 32 + burstLength;
srcStride310 = DivCeil(srcStride310, 32) * 32; // 只有 Normal 强制 32B 对齐
} else {
srcStride310 = burstLength; // Compact:字节精确、忽略 srcStride
}
即第 14 行实际起点 13×2700 = 35100 B,读 2700 B 到 37800 B,仍在缓冲区内。
- 旁证:若真按 2720 步进,
dx从第 2 行起就会整体错位,精度必然失败;而该用例带 golden 的
对照轮次精度为PASS,PASS,PASS,100%,100%。


【缺陷】BatchNorm3DGrad 多用例 UB 越界读(illegal read size 236/304)
问题描述信息
【环境信息】:
【预置条件】:
【重现步骤】:
cd <ops仓> && bash build.sh --jit --soc=ascend950 --ops=batchnorm3dgrad
mssanitizer --tool=memcheck --leak-check=yes --check-unused-memory=yes --
/npu/miniconda3/envs/CI_py310_aclnn/bin/python3 -m ttk kernel
-i batchnorm3dgrad_cases.csv --compile-opts op_debug_config=sanitizer
--pc 1 --devices 0
【预期结果】:
无 mSAN ERROR(无越界读写、无内存泄漏)
【实际结果】:
mssanitizer memcheck 检出 9 条 ERROR(illegal read of size 236×3 + size 304×6),全部为 UB 越界读。触发 kernel 为 dyn_op_BatchNorm3DGrad_L0_001(block aiv(0-46), pc 0x331b8)和 dyn_op_BatchNorm3DGrad_L0_011(block aiv(0-11), pc 0x39a5c)。
【用户影响】:
多用例 UB 越界读——不同 shape 均触发,可能为系统性问题
附件
责任田:张磊(目标仓:wangyueting/changwei)