CANN Runtime 错误码 EK0201 深度解析:Profiling 主机内存分配失败(Resource_Error_Insufficient_Host_Memory)
【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime
导读
EK0201 是 CANN Runtime 中 Profiling 错误码系列(EK 前缀)下的资源类错误,表示 Profiling 数据采集过程在**主机侧(Host)**申请内存失败。本文以 CANN runtime 仓库的错误码参考文档为核心,结合 error_code.json 中的错误码定义、error_manager.c 中的错误码上报模板,以及 msprof 采集链路中多个触发点的源码实现,完整讲解 EK0201 的错误格式、触发场景、底层上报机制与排查思路。读完本文,你将能够准确识别 EK0201 的出现时机、理解%s占位符所代表的实际含义,并掌握一套可落地的排查与规避方法。
错误码概览
EK0201 属于 Profiling Errors(EK 系列)中的资源错误类别,其错误标题为Resource_Error_Insufficient_Host_Memory,语义为"Profiling 所需的主机内存不足"。在 error_code.json 中,该错误码的完整登记信息如下:
| 字段 | 值 |
|---|---|
| errClass | Profiling Errors |
| errTitle | Resource_Error_Insufficient_Host_Memory |
| ErrCode | EK0201 |
| ErrMessage | Failed to allocate %s host memory for Profiling. |
| Arglist | buf_size |
| Possible Cause | Allocation failed due to insufficient host memory. |
| Solution | Stop unnecessary processes and ensure that the required memory is available. |
从仓库中同一错误码族可以看到,EK0202(Failed to allocate host memory by %s.)与 EK0203(Failed to create host thread for Profiling. Reason: %s.)同属 Profiling 主机资源类错误,EK0201 专门针对**内存分配(allocation)**失败这一场景,是 Profiling 初始化与配置阶段最常遇到的资源类错误之一。
错误格式与示例
原文档给出的错误格式模板如下:
Failed to allocate %s host memory for Profiling.其中占位符%s表示申请失败的内存大小。实际报错示例:
Failed to allocate 100M host memory for Profiling.结合仓库源码可以更精确地理解%s的取值。在 prof_api_common.cpp 中,aclprofCreateSubscribeConfig创建配置结构体失败时上报的%s参数为std::to_string(sizeof(aclprofSubscribeConfig)) + "B",即内存大小以字节(B)为单位;同样在 prof_acl_api.cpp 中,aclprofCreateConfig失败时上报的是std::to_string(sizeof(aclprofConfig)) + "B"。因此实际报错中的%s形如"100M"、"512B"或"1048576B"等带单位的内存大小描述,而非抽象的错误代码。
源码中的错误码定义与模板
EK0201 在仓库中存在两处登记,分别服务于不同的错误码框架:
1. 新框架:error_code.json(msprof / acl 侧)
src/dfx/error_manager/error_code.json 中定义了 EK0201 的完整信息,包括错误模板Failed to allocate %s host memory for Profiling.、参数列表Arglist: buf_size,以及建议的 Possible Cause 与 Solution。msprof 采集侧的MSPROF_ENV_ERROR("EK0201", ...)宏调用即以此模板为基础,将buf_size替换为实际申请大小后输出错误。
2. 旧框架:error_manager.c(runtime_compact 侧)
runtime_compact/c_base/src/error_manager.c 的ERROR_MAP中登记了 EK0201:
{"EK0201", "Failed to allocate host memory for Profiling: %s.", "Available memory is insufficient.", "Close unused applications.", {"buf_size"}},该数组结构依次为错误码、错误消息模板、可能原因、解决方案与参数列表。单元测试 error_manager_test.cc 验证了该模板的最终输出格式:
EK0201: Failed to allocate host memory for Profiling: 100. PossibleCause: Available memory is insufficient. Solution: Close unused applications.从测试断言可以看出,错误码上报后最终以错误码: 消息开头,随后逐行附带PossibleCause与Solution,方便用户直接根据输出定位问题。
哪些场景会触发 EK0201
从源码结构看,EK0201 主要出现在 Profiling 配置对象创建与内部缓冲池初始化的内存分配失败路径上,典型触发点包括:
1. aclprofCreateConfig:Profiling 配置结构创建失败
prof_acl_api.cpp 中,aclprofCreateConfig使用new (std::nothrow)创建aclprofConfig时若返回空指针,则通过MSPROF_ENV_ERROR("EK0201", {"buf_size"}, {sizeof(aclprofConfig)})上报,随后返回nullptr。
2. aclgrphProfCreateConfig:图引擎侧 Profiling 配置创建失败
prof_ge_core.cpp 中,图(Graph)场景下的aclgrphProfCreateConfig创建aclgrphProfConfig失败时同样上报 EK0201。
3. aclprofCreateSubscribeConfig:订阅配置创建失败
prof_api_common.cpp 中,aclprofCreateSubscribeConfig创建aclprofSubscribeConfig失败时上报 EK0201。
4. MsprofTxManager:戳(stamp)缓冲池初始化失败
msprof_tx_manager.cpp 中,MsprofTxManager::Init初始化ProfStampPool(stamp 缓冲池,大小为CURRENT_STAMP_SIZE)失败时上报 EK0201,并返回PROFILING_FAILED。该场景与 msproftx(通过aclprofInit初始化 Profiling 数据采集)密切相关。
5. uploader_mgr:数据上传管理器初始化失败
uploader_mgr.cpp 中,Profiling 数据上传管理器初始化分配内存失败时同样上报 EK0201。
6. 其他 msprof 内部路径
prof_acl_core.cpp、msprofiler_acl_api.cpp 等文件中也存在 EK0201 的上报调用。
归纳而言,EK0201 的触发共同点是:Profiling 子系统在 Host 侧通过new、缓冲池初始化等途径申请内存失败,涉及的 API 覆盖aclprofCreateConfig、aclgrphProfCreateConfig、aclprofCreateSubscribeConfig以及 msproftx 的初始化流程。
底层上报机制:MSPROF_ENV_ERROR 与错误消息的产出链路
从源码结构看,EK0201 的上报遵循"登记模板 → 宏替换参数 → 拼接错误消息"的链路:
- 模板登记:错误码与消息模板在 error_code.json(新框架)或 error_manager.c(runtime_compact 的
ERROR_MAP)中登记,参数列表明确为buf_size。 - 宏上报:各触发点调用
MSPROF_ENV_ERROR("EK0201", std::vector<std::string>({"buf_size"}), std::vector<std::string>({实际大小}))或REPORT_INPUT_ERROR,将模板中的%s替换为实际申请的内存大小(如"100M"、"1048576B")。 - 消息输出:错误消息最终以
EK0201: Failed to allocate host memory for Profiling: <大小>.的格式输出,并附上PossibleCause与Solution提示(参见 error_manager_test.cc 的断言)。
值得注意的是,runtime_compact 侧的ERROR_MAP还通过SearchFromErrorMap使用二分查找(bsearch)按错误码检索模板(见 error_manager.c),并且错误消息按线程存储(__thread ErrorInfoThread* g_errorThread),每个线程可独立获取自己产生的错误消息。
可能原因
根据原文档以及 error_code.json 中的登记信息,EK0201 的可能原因表述为:
Allocation failed due to insufficient host memory.
即:Profiling 组件在申请主机内存时,系统可用内存不足导致new/ 缓冲池初始化失败。常见的加剧因素包括:
- 同一主机上运行的 Profiling 进程(如 msprof 命令行采集)与应用进程同时采集,内存占用叠加;
- 主机侧同时运行多个训练/推理任务或其他内存密集型进程;
- 系统内存碎片化严重,虽然总量有余,但无法满足 Profiling 需要的连续大块内存(如 stamp 池、上传缓冲等)。
解决方案与排查步骤
原文档给出的解决方案为:
Stop unnecessary processes and ensure that the required memory is available.
即停止不必要的进程,确保所需内存可用。结合源码中的实际申请场景,可进一步细化为以下排查步骤:
- 定位报错中的内存大小:查看报错信息中
%s携带的大小(如100M、1048576B),判断是否为异常的大块申请。若大小与该次 Profiling 采集的数据量级严重不符,需排查是否为配置错误导致异常申请。 - 检查主机内存余量:使用系统命令(如
free -h查看可用内存、top/htop查看进程内存占用)确认主机当前可用内存是否充足。 - 关闭无关进程:停掉不再需要的应用、后台服务或其他 Profiling 采集任务,释放内存后重试。
- 减少并发采集:避免在同一个主机上同时启动多个 Profiling 采集任务(包括 msprof 命令行与应用内 ACL API 采集同时开启),降低内存峰值;同时注意 EK0007 相关说明中"不要同时启用两种以上采集模式"的约束。
- 检查系统内存限制:确认进程是否受 cgroup、ulimit 等资源限制(如
ulimit -v虚拟内存上限),必要时调整限制值。 - 重试验证:释放内存后重新运行 Profiling 采集,确认 EK0201 不再出现;若仍然出现,则结合该时刻的 Profiling 日志(msprof 侧日志)进一步定位具体申请点。
如何进一步查阅
- 本文依据的原始文档:EK0201 Resource_Error_Insufficient_Host_Memory(中文版)
- Profiling 错误码总览:Profiling-Errors
- 错误码模板登记:src/dfx/error_manager/error_code.json、src/runtime_compact/c_base/src/error_manager.c
- 触发点源码:src/dfx/msprof/collector/dvvp/msprofiler/prof_acl_api.cpp、src/dfx/msprof/collector/dvvp/msprofiler/prof_ge_core.cpp、src/dfx/msprof/collector/dvvp/msprofiler/prof_api_common.cpp、src/dfx/msprof/collector/dvvp/msprof/msproftx/src/msprof_tx_manager.cpp
- 单元测试验证:tests/ut/runtime/runtime_c/testcase/c_base/error_manager_test.cc
总结
EK0201 是 CANN Runtime Profiling 子系统中典型的主机内存资源不足错误,它集中出现在 Profiling 配置对象创建与内部缓冲池初始化的内存分配失败路径上。理解其错误格式(%s即内存大小)、触发场景(aclprofCreateConfig、aclgrphProfCreateConfig、aclprofCreateSubscribeConfig、msproftx stamp 池初始化等)以及底层模板替换机制,可以帮助开发者在收到该错误时快速定位是"哪个组件在申请多大内存失败",从而通过释放内存、降低并发采集等方式高效解决,保证 Profiling 数据采集流程正常启动。
【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考