Closed
[Bug-Report|缺陷反馈][工具检测]: matmul_a2b2_shareisA2B2Shared 模式下 InitShareBufEnd 条件跳过导致 PRIVATE 未初始化读 + IterateAll 尾部越界导致 GM 非法读写,mssanitizer memcheck/initcheck 报 603 条错误 #1678
h-glueAdd on Sep 16Closed at Sep 28
Hh-glue
Sep 16 Change title to "[Bug-Report|缺陷反馈][工具检测]: matmul_a2b2_shareisA2B2Shared 模式下 InitShareBufEnd 条件跳过导致 PRIVATE 未初始化读 + IterateAll 尾部越界导致 GM 非法读写,mssanitizer memcheck/initcheck 报 603 条错误", originally titled "[Bug-Report|缺陷反馈]: matmul_a2b2_shareisA2B2Shared 模式下 InitShareBufEnd 条件跳过导致 PRIVATE 未初始化读 + IterateAll 尾部越界导致 GM 非法读写,mssanitizer memcheck/initcheck 报 603 条错误".
Sep 16 Change title to "[Bug-Report|缺陷反馈][工具检测]: matmul_a2b2_shareisA2B2Shared 模式下 InitShareBufEnd 条件跳过导致 PRIVATE 未初始化读 + IterateAll 尾部越界导致 GM 非法读写,mssanitizer memcheck/initcheck 报 603 条错误", originally titled "[Bug-Report|缺陷反馈]: matmul_a2b2_shareisA2B2Shared 模式下 InitShareBufEnd 条件跳过导致 PRIVATE 未初始化读 + IterateAll 尾部越界导致 GM 非法读写,mssanitizer memcheck/initcheck 报 603 条错误".
Sep 16 Assign li-yuanjie-da as responsible person
li-yuanjie-da
Sep 16 Comments:
Sep 16 Comments:
感谢补充完整分类及关闭isA2B2Shared的对照结果。静态核对发现,普通half输入使用的MatmulType不含scalePosition,因此不能据此认定InitShareBufEnd被跳过;该函数也不负责恢复 L0A/L0B maxAddr。我们将结合对应地址的实际读写指令、对象初始化状态和950上的对照日志进一步定位。


ca1kw
Sep 28 Comments:
Sep 28 Comments:
您好,对于该Issue中GM 非法读、GM 非法写和 GM 未初始化读已由关联pr进行修复。修复方式是在尾部核上按实际剩余的 M/N/K 长度调用 SetTail(),避免 Matmul 调度器按完整 tile 长度继续访问 GM。
验证结果:
mssanitizer -t memcheck:0 errorverify_result.py:test pass!- 原 GM 非法读、GM 非法写、GM 未初始化读均已消除
对于当前 initcheck 仍剩余 216 条 PRIVATE 未初始化读,较原始 PRIVATE 报错数 243 条减少 27 条。剩余报错均来自 CANN 内部状态,不是样例侧 GM 访问逻辑问题:
| 数量 | 对应状态 | 说明 |
|---|---|---|
| 27 | Internal::g_bufId |
TPipe::ResetPool() 已执行 g_bufId = 0,但 initcheck 仍报未初始化,疑似工具未正确跟踪该写入 |
| 135 | gA2B2DBFlag_ |
CANN A2B2 共享实现内部的 __BLOCK_LOCAL__ 状态,首次读取前没有显式运行时写入。initcheck 的判定原理是读取某地址时检查该地址是否已被写过;如果之前没有写入,工具无法将其视为已初始化,也不能替业务补写。由于 __BLOCK_LOCAL__ 变量不支持声明时赋初始值,不能通过 gA2B2DBFlag_ = 0 的静态初始化方式规避,需 CANN/库侧在首次读取前提供合法的运行时初始化路径 |
| 54 | TPipe 内部 eventPool_ 状态 |
TPipe::ResetPool() 已遍历清零事件池,但 initcheck 仍报未初始化,说明工具对构造/Reset 阶段的写跟踪不完整 |
综上,本 issue 中的 GM 越界问题已解决;剩余 initcheck PRIVATE 报错建议转由 mssanitizer / CANN 内部实现侧继续排查,不建议在当前样例中通过强行初始化内部状态规避。


Sep 28 Added label: resolved
问题描述 (Mandatory / 必填)
在 asc-devkit 示例
examples/01_simd_cpp_api/04_advanced_api/00_matmul/matmul_a2b2_share上启用 mssanitizer(memcheck/racecheck/initcheck/synccheck)检测,共报告 603 条错误,可归为以下三类:illegal read of size 128(GM)illegal write of size 1024/896(GM)uninitialized read of size 8(PRIVATE)uninitialized read of size 128(GM)关键特征:
matmulObj1.IterateAll(c1Global)(.asc第 135 行)与matmulObj2.IterateAll(c2Global)(第 137 行);0x1201a1AB0000、a2 结束0x1201a20B0000;0x1201a3010000、c2 结束0x1201a4010000;HasScalePosition<half>::value = true导致InitShareBufEnd被条件跳过相关:scheduler_base.h:139的InitShareBufEnd调用点 ——HasScalePosition<half>为 true 时该调用被if constexpr跳过,L0A/L0B 缓冲区maxAddr未恢复;load_bias_to_c2.h:81—— 偏置加载使用了错误的地址(因maxAddr未正确恢复);tbuf_pool_l0_a2b2_shared.h:52—— A2B2 双缓冲标志WaitFlag等待混乱;copy_cube_in阶段,是同源错误的一体两面。环境信息 (Mandatory / 必填)
examples/01_simd_cpp_api/04_advanced_api/00_matmul/matmul_a2b2_shareCMAKE_ASC_RUN_MODE=npu),CMAKE_ASC_ARCHITECTURES=dav-3510重现步骤 (Mandatory / 必填)
cd examples/01_simd_cpp_api/04_advanced_api/00_matmul/matmul_a2b2_sharemkdir -p build && cd build export ASCFLAGS= "-g --cce-enable-sanitizer" cmake -DSCENARIO_NUM=1 -DCMAKE_ASC_ARCHITECTURES=dav-3510 -DCMAKE_ASC_LINK_FLAGS=--cce-enable-sanitizer .. makematmul_a2b2_share.asc中isA2B2Shared = true,形状 M=7680, N=480, K=320,half 输入、float 输出、带 bias):# 通过 MindStudio 运行,启用 --cce-enable-sanitizer=memcheck,racecheck,initcheck,synccheck ./demo mssanitizer -t initcheck --log-level=error --full-backtrace=yes -- ./demo预期结果 (Mandatory / 必填)
mssanitizer 检测不应报告任何错误。具体地:
HasScalePosition<half>为 true 时,InitShareBufEnd不应被跳过 —— L0A/L0B 缓冲区的maxAddr应正确恢复,偏置加载和 A2B2 双缓冲标志应正常工作;isA2B2Shared = true模式下,IterateAll对最后一个核的最后一个分块应正确做边界截断,不应发生越过 GM 缓冲区尾部的非法读(A 矩阵尾部)与非法写(C 矩阵尾部)。相关日志/截图 (Mandatory / 必填)
完整日志文件:
result_fix/matmul_a2b2_share/san.log(~1.5 MB,603 条错误)错误 1:PRIVATE uninitialized read(serialNo:282,全部 27 个核)—— InitShareBufEnd 被条件跳过:
错误 2:PRIVATE uninitialized read(serialNo:477,全部 27 个核)—— 偏置加载地址错误:
错误 3:GM illegal read(serialNo:154697,仅 aic(26))—— copy_cube_in 尾部越界:
错误 4:GM illegal write(serialNo:155243,仅 aic(26))—— copy_cube_out 尾部越界:
地址映射分析(基于 a1/acl MALLOC 基址 0x1201a1600000 与缓冲区大小推算):
备注 (Optional / 选填)
两类错误同源关联分析:
PRIVATE uninitialized read(243 条)的问题是HasScalePosition<half>类型检测 trait 在half上返回 true,导致scheduler_base.h:138-139中if constexpr (!HasScalePosition<A_TYPE>::value) { InitShareBufEnd(...); }被编译期跳过。这导致 L0A/L0B 共享缓冲区maxAddr在第二个 matmul 对象初始化时未正确恢复,进而偏置加载地址和 A2B2 双缓冲标志出现未初始化读。但该问题影响所有核且表现为 PRIVATE 空间错误,不直接导致 GM 越界。GM illegal read/write(210 条)与GM uninitialized read(150 条)是 尾部 last-tile 越界问题,仅影响最后一个核 aic(26)。copy_cube_in以固定 vector 长度(128B)从 GM 读取 A 分块时未对最后一个分块做边界截断,读入了缓冲区尾部缝隙,同时也解释了同地址的 GM 未初始化读。上述两类错误相互独立:PRIVATE uninit 是库调度逻辑缺陷(InitShareBufEnd 条件跳过),GM 越界是迭代器边界缺陷(last tile 截断缺失)。但两者在
isA2B2Shared = true模式下同时触发,建议库侧分别排查:scheduler_base.h:138—— 将HasScalePosition检查逻辑修正,确保half类型下InitShareBufEnd仍被调用;copy_tile_to_cube_common.h:471/scheduler_norm.h:206—— 在IterateAll最后一次迭代中对尾部 tile 做 GM 边界截断。当前功能正确性:
scripts/verify_result.py校验通过(输出与 golden 一致)。越界读写的目标地址落在缓冲区之间 ACL 硬件对齐填充的空闲缝隙中,未造成实际数据破坏,但技术上属不安全访问。对照验证:将
GetCustomCFG()中isA2B2Shared设为false(即退回CFG_NORM)后重新运行,GM 非法读写清零,PRIVATE 未初始化读亦消失,进一步印证上述分析。