MUSA Compute Sanitizer 最佳实践
本文档提供场景化的快速参考,帮助你快速选择 mt-compute-sanitizer 的运行方式、判断结果并收集可复现日志。
快速命令参考
推荐基础命令:
# 默认检查:global memory 越界 + MUSA API error,并保存 sanitizer 日志
/usr/local/musa/bin/mt-compute-sanitizer \
--log-file san.log \
./my_program --case-args
# 检查显存泄漏:必须显式启用 --leak-check=full
/usr/local/musa/bin/mt-compute-sanitizer \
--leak-check=full \
--log-file leak.log \
./my_program --case-args
# 不关注 API error 时关闭 API error 报告
/usr/local/musa/bin/mt-compute-sanitizer \
--report-api-errors=no \
--log-file san.log \
./my_program --case-args
常用选项:
| 选项 | 默认值 | 使用建议 |
|---|---|---|
--log-file <file> | stdout | 建议总是使用,便于归档和上报问题。 |
--leak-check=full | no | 显存泄漏检查默认关闭,排查泄漏时必须显式启用。 |
--report-api-errors=<all/no> | all | 默认报告 MUSA API error;日志过多且明确不关注 API error 时可设为 no。 |
--print-limit <N> | 100 | 错误很多时限制日志量;需要完整详情时可设为 0。 |
--num-callers-host <N> | 0 | 控制 host backtrace 打印层数,0 表示不限制。 |
--show-backtrace=<yes/no> | yes | 日志过长时可关闭回溯,但定位问题时建议保留。 |
--backtrace-short=<yes/no> | yes | 需要更多内部 frame 时可设为 no。 |
--strip-paths=<yes/no> | yes | 需要完整源码路径时可设为 no。 |
推荐排查顺序
- 先普通运行原始测试,确认功能结果和退出码,并保存应用日志。
- 再使用
mt-compute-sanitizer --log-file san.log包装原始命令。 - 先处理默认检查发现的 global memory 越界和 MUSA API error。
- 怀疑显存泄漏时,再加
--leak-check=full单独检查。 - 错误太多或回溯不够时,再调整
--print-limit、--strip-paths、--backtrace-short等参数。
建议同时保存 sanitizer 日志和应用输出:
/usr/local/musa/bin/mt-compute-sanitizer \
--log-file san.log \
./my_program --case-args \
> app.out 2>&1
| 文件 | 内容 |
|---|---|
san.log | sanitizer 检查到的 OOB、leak、API error 和 ERROR SUMMARY。 |
app.out | 被测程序自己的 stdout/stderr、测试框架日志和退出信息。 |
场景一:首次使用 - 检查程序错误
用户问题
“我刚写完一个 MUSA 程序,运行时报错了,但我不知道具体哪里有问题,该怎么排查?”
解决步骤
先使用默认检查运行程序:
/usr/local/musa/bin/mt-compute-sanitizer --log-file san.log ./my_program
默认检查会覆盖:
- global memory 越界访问。
- MUSA Runtime / Driver API error。
默认检查不会检查显存泄漏。显存泄漏需要进入 场景三,显式加 --leak-check=full。
预期输出
无错误时应看到:
========= COMPUTE-SANITIZER
========= ERROR SUMMARY: 0 error
如果有错误,ERROR SUMMARY 会非 0。OOB 输出示例:
========= COMPUTE-SANITIZER
========= ERROR SUMMARY: 448 errors
========= ERROR SUMMARY: 448 errors were not printed. Use --print-limit option to adjust the number of printed errors
下一步
ERROR SUMMARY: 0 error:说明当前版本、当前输入、当前运行没有检出 sanitizer 问题。ERROR SUMMARY非 0:根据错误类型查看对应场景。- 没有完整 summary 或 sanitizer 异常退出:保存
san.log、app.out、退出码和环境信息,收敛最小复现。
场景二:检查内存越界访问
用户问题
“我的程序有时候能跑、有时候不能跑,怀疑是数组访问越界了,怎么确定?”
快速解决
/usr/local/musa/bin/mt-compute-sanitizer \
--log-file oob.log \
./my_program --case-args \
> oob.out 2>&1
grep "ERROR SUMMARY" oob.log
grep -n "Out of bounds memory access\|ERROR SUMMARY" oob.log
典型输出
========= COMPUTE-SANITIZER
========= Out of bounds memory access
========= at onePastEndKernel(float*, int)+0xb8
========= Address 0x... is out of bounds
========= Saved host backtrace up to driver entry point at kernel launch time
========= Host Frame: __device_stub__onePastEndKernel(float*, int) [...]
========= Host Frame: main [...]
========= ERROR SUMMARY: 1 error
常见原因速查
| 原因 | 快速修复 |
|---|---|
| 无边界检查 | 添加 if (idx < n)。 |
| blockSize / gridSize 过大 | 确认多余线程不会访问非法地址。 |
| 指针计算错误 | 检查 offset、stride、shape、pitch 等计算。 |
完整错误示例和修复代码,可参考 用户指南 - 越界检查。
场景三:检查显存泄漏
用户问题
“我的程序运行一段时间后显存越来越少,怀疑有显存泄漏,怎么检测?”
快速解决
显存泄漏检查默认关闭,必须显式启用:
/usr/local/musa/bin/mt-compute-sanitizer \
--leak-check=full \
--log-file leak.log \
./my_program --case-args \
> leak.out 2>&1
grep "ERROR SUMMARY" leak.log
grep -n "Leaked\|musaMalloc\|ERROR SUMMARY" leak.log
典型输出
========= COMPUTE-SANITIZER
========= Leaked 4096 bytes at 0x1006b600000
========= Saved host backtrace up to driver entry point at allocation time
========= Host Frame: main [0x1155] in your_program
========= ERROR SUMMARY: 1 error
常见原因速查
| 原因 | 快速修复 |
|---|---|
缺少 musaFree() | 为每个 musaMalloc() 添加对应 musaFree()。 |
| 提前 return | 确保所有返回路径都释放显存。 |
| 异常路径未释放 | 使用统一 清理路径或 RAII 封装资源。 |
完整错误示例和修复代码,可参考 用户指南 - 泄漏检查。
场景四:检查 API 错误
用户问题
“我的程序有时候返回错误码,但不知道具体是什么错误,怎么办?”
快速解决
API error 报告默认开启:
/usr/local/musa/bin/mt-compute-sanitizer \
--log-file api.log \
./my_program --case-args
典型输出:
========= COMPUTE-SANITIZER
========= Program hit musaErrorInvalidDevice (error 101) due to "invalid device ordinal" on MUSA API call to musaSetDevice.
========= Saved host backtrace up to driver entry point at error
========= Host Frame: main [0x1149] in your_program
========= ERROR SUMMARY: 1 error
如果明确不关注 API error,可以关闭:
/usr/local/musa/bin/mt-compute-sanitizer \
--report-api-errors=no \
--log-file no_api_error.log \
./my_program --case-args
常见 API 错误速查
| 错误 | 含义 | 常见原因 |
|---|---|---|
| invalid argument | 无效参数 | size 为 0、空指针、重复释放等。 |
| out of memory | GPU 内存耗尽 | 申请过多显存或显存泄漏。 |
| invalid device | 无效 GPU 设备 | 设备 ID 错误或设备未初始化。 |
完整 API 错误示例,可参考 用户指南 - MUSA API 错误检查。
场景五:组合使用多种检查
用户问题
“我想同时检查内存越界和显存泄漏,该怎么操作?”
快速解决
/usr/local/musa/bin/mt-compute-sanitizer \
--leak-check=full \
--log-file full.log \
./my_program --case-args
检查组合对比
| 命令 | 越界 | 泄漏 | API 错误 |
|---|---|---|---|
mt-compute-sanitizer ./app | ✅ | ❌ | ✅ |
mt-compute-sanitizer --leak-check=full ./app |