CANN Runtime 错误消息(ErrMsg)文案模板详解:EE/EH 系列错误码的 Arglist、Reason 与整改示例
【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime
本篇基于 CANN Runtime 仓库中的 ErrMessage 翻译总表,系统讲解 Runtime(EE 系列)与 ACL(EH 系列)错误消息的文案模板、参数列表(Arglist)与各错误码的典型 Reason 取值,并结合 error_code.json、error_code_meta.h 等事实来源,说明这些模板如何被上报宏填充、最终呈现给用户。读完后,你可以准确解读一条带ErrorCode=EExxxx的错误输出,也知道在整改或新增错误文案时应如何选择参数与措辞。
一、错误消息体系速览:模板、Arglist 与 Reason
CANN Runtime 的错误消息(ErrMsg)不是随意的日志字符串,而是"模板 + 参数"的结构化文本。每个外部错误码(后四位为 0001~8999 的码)在 error_code.json 中定义,核心字段为:
- ErrMessage:printf 风格的文案模板,其中的
%s/%u等占位符按固定顺序取参; - Arglist:占位符对应的参数名列表,如
func, value, param, expect; - suggestion:面向用户的
Possible Cause与Solution,随错误码一起展示。
上报时,error_code_meta.h 中的 X-Macro 参数表会把error_code.json的模板同步成 C++ 侧格式串,并在末尾追加ErrorCode=EExxxx.后缀。例如 meta.h 中 EE1018 的定义:
X(EE1018, "EE1018", ("func", "reason"), "%s failed. Reason: %s. ErrorCode=EE1018.\n", DLOG_ERROR)而 message-examples.md 这份"翻译总表",正是对其中一批错误码(EE1003、EE1006、EE1007、EE1009、EE1011、EE1012、EE1014、EE1015、EE1016、EE1017、EE1018、EE9999、EH0009、EH0011)的ErrMessage 模板、Arglist 与 reason 具体描述清单的逐码汇总。下面按错误码逐一展开。
二、参数非法类(Invalid_Argument)
EE1003:值非法且能给出期望值
- errTitle:Invalid_Argument
- ErrMessage:
%s failed because value %s for parameter %s is invalid. Expected value: %s. - Arglist:
func, value, param, expect - 典型 reason:
- 参数值与
RT_EVENT_FLAG存在互斥(exclusive OR); - 参数值需大于或等于 0。
- 参数值与
- Solution:1. 检查函数输入参数范围;2. 检查函数调用关系。
该码是 Runtime 层"输入参数非法"的首选通用码(在 error-code-guide.md 中标注 ⭐)。func参数建议传入语义化描述而非__func__。例如仓库中的实际用法(引自 error-code-guide.md 的示例):
RT_LOG_OUTER_MSG_WITH_FUNC_DESC(ErrorCode::EE1003, "Obtaining the logical device ID based on the user device ID", userDevId, "userDevId", "[0, " + std::to_string(userDeviceCnt) + ")");打屏效果:Obtaining the logical device ID based on the user device ID failed because value 8 for parameter userDevId is invalid. Expected value: [0, 4). ErrorCode=EE1003.
EE1011 vs EE1012:同 Arglist、不同模板
两者 Arglist 完全相同(func, value, param, reason),仅文案模板存在一词之差:
| 错误码 | ErrMessage 模板 | 第 3 个参数前的措辞 |
|---|---|---|
| EE1011 | %s failed. Value %s for parameter %s is invalid. Reason: %s. | for parameter %s |
| EE1012 | %s failed. Value %s for %s is invalid. Reason: %s. | for %s(省去 parameter) |
EE1011 典型 reason(翻译总表原文,节选):
- 非持久流
%u不支持清空流任务(Non-persistent stream does not support stream task clearance); - 流
%u必须绑定到模型(Stream %u must be bound to a model); - AI CPU 流
%u不支持清空流任务; count不能超过最大值destMax %" PRIu64 ";memcpyAddrInfo未做 64 字节对齐;- 无法通过
stubFunc找到对应 kernel——指定的函数地址无效或 kernel 状态异常; - 无法通过
tilingKey找到对应 kernel——tilingKey 无效或 kernel 状态异常; - 流
%d不属于当前 context; - 流未绑定到模型(The stream is not bound to a model);
- 带
ACL_STREAM_DEVICE_USE_ONLYflag 的流不能绑定到模型。
EE1012 典型 reason:
- 当前 device 无法下发 Notify Wait——对应的 Notify Wait 必须在创建 IPC Notify 的 device 上下发。
EE1012 的 suggestion 中Possible Cause标注为 "The host memory is insufficient"(注意:这是总表原文的字段内容,属于该码预置 suggestion,而非每个场景的通用结论)。
选择规则(与 error-code-guide.md 的决策树一致):把第 3 个参数代入两种模板,读起来哪个自然用哪个。参数名是普通单词(如deviceId)时优先 EE1011;参数名本身已是描述性短语(如queue name length)时用 EE1012,避免 "for parameter queue name length" 的冗余。仓库中 EE1011 的真实调用示例:
// src/acl 层对应码为 EH0009,Runtime 层示例: kernel = Runtime::Instance()->KernelLookup(stubFunc); COND_RETURN_AND_MSG_OUTER(kernel == nullptr, RT_ERROR_KERNEL_NULL, ErrorCode::EE1011, __func__, static_cast<const char_t *>(stubFunc), "stubFunc", "The corresponding kernel cannot be found through stubFunc. " "The specified function address is invalid or the kernel status is abnormal");打屏效果:rtKernelLaunch failed. Value "kernel_Add" for parameter stubFunc is invalid. Reason: The corresponding kernel cannot be found through stubFunc.... ErrorCode=EE1011.
EE1017:无法给出参数具体值
- errTitle:Invalid_Argument
- ErrMessage:
%s failed. Parameter %s is invalid. Reason: %s. - Arglist:
func, param, reason(注意:没有value,因为该场景下拿不到或不应打印参数具体值) - Solution:无(suggestion 为 N/A)
翻译总表给出了 15 条典型 reason,覆盖模型/流/label 的归属与状态校验,节选:
- 流
%u所在的模型%u尚未加载,需在模型加载后再清空流任务; - 指定地址必须是 device 地址;
- 无法通过 device ID
%d、stream ID%u、task ID%u三元组找到对应任务; - 配置中待更新数据存放的 device 内存地址与当前指定地址不一致,多次任务更新必须使用相同的 device 内存地址;
- 与 label
[%u]关联的流%d不在当前 context 中; - 与 label
[%u]关联的流%d不在模型中,需先调用rtLabelSet将流绑定到模型; - 与 label
[%u]关联的流和 label[0]关联的流不属于同一模型; - 仅随机数生成任务支持该更新操作;
argHandle中para.type为 place holder 的参数个数(%u)必须小于%u;- 绑定到流的模型
%u与 label 所属模型%u不一致; - 当前流
%u与 label 关联的流%u不一致; - 持久流(persistent stream)不支持查询任务执行状态;
- 回调函数
fn已注册,不能重复注册; - 回调函数
fn尚未注册; - 当前任务类型不支持该操作。
EE1017 的适用前提是"无法给出参数具体值"——例如参数是句柄/对象属性,或其取值本身无诊断意义;若两个及以上用户参数间关系不满足(如要求 A < B),也推荐用 EE1017,把具体参数值和关系写进 Reason。
EH0009:ACL 层对应码(参数非法 + 原因)
- errTitle:Invalid_Argument
- ErrMessage:
%s failed. Value %s for parameter %s is invalid. Reason: %s. - Arglist:
func, value, param, reason - Solution:1. 检查函数输入参数范围;2. 检查函数调用关系。
翻译总表列出的典型 reason:
- 该流未注册到任何 allocator(The stream is not registered with any allocator);
- 指定参数
%d短于算力组(computing power group)信息的长度,无法保存该信息; - 当前数据类型不支持;
- 当前物理内存属性不支持。
EH0009 与 EE1011 的模板完全一致,层级不同:EE 用于src/runtime/代码,EH 用于src/acl/代码。ACL 层的真实调用示例(引自 macro-selection-guide.md 中 EH0009 专用宏说明):
// ACL_CHECK_INVALID_PARAM_WITH_REASON 系列宏上报 EH0009 acl::AclErrorLogManager::ReportInputError(acl::INVALID_PARAM_REASON_MSG, {"func", "value", "param", "reason"}, {"Checking the synchronous memory copy parameter validity", widthVal.c_str(), "width", errMsg.c_str()}); // 输出:Checking the synchronous memory copy parameter validity failed. // Value 2048 for parameter width is invalid. Reason: must be less than spitch and dpitch. // ErrorCode=EH0009.三、不支持类(Not_Supported)
EE1006:配置参数级不支持(三参数模板)
- errTitle:Not_Supported
- ErrMessage:
%s failed. %s is not supported. Reason: %s. - Arglist:
func, type, reason - suggestion.Possible Cause:
- 当前 CANN 软件版本不支持;
- 当前驱动软件版本不支持;
- 当前芯片版本不支持。
- suggestion.Solution:1. 升级 CANN 软件版本;2. 升级驱动软件版本。
翻译总表列出了 8 条典型 reason,是理解"流/事件/模型运行时哪些操作被禁止"的好材料:
- OFFLINE 模式下不支持 P2P 内存类型;
- 融合任务仅支持 HCOMM+AI Core、AI CPU+AI Core、CCU+AIC 的组合,或单个 CCU 任务;
- 当前 SoC 仅支持任务数正常的流,不支持巨量任务流(huge stream);
- Device-only event 只能在 device 上调用;
- 当前流用于承载 AI CPU 调度任务,不支持设置优先级;
- 当前 SoC 不支持该数据类型的 reduce 操作;
- 当前 SoC 不支持 P2P 内存分配;
- "仅分配巨页内存"策略与"分配底层 cache 内存"策略冲突。
使用要点:若不支持可通过升级解决,Reason 中应写明支持的软件版本信息;type参数优先使用语义化描述。仓库中的真实调用(节选自 api_error.cc 中的 EE1006 调用点,如 stream flag 检查):
COND_RETURN_AND_MSG_OUTER((stm != nullptr) && ((stm->Flags() & RT_STREAM_AICPU) != 0U), RT_ERROR_STREAM_INVALID, ErrorCode::EE1006, "Synchronizing a stream", "Stream flags value " + std::to_string(stm->Flags()), "The current stream is used to carry AI CPU scheduling tasks " "and does not support stream synchronization");打屏效果:Synchronizing a stream failed. Stream flags value 4 is not supported. Reason: The current stream is used to carry AI CPU scheduling tasks and does not support stream synchronization. ErrorCode=EE1006.
EE1015:驱动版本能力不足
- errTitle:Package_Error_Incorrect_Driver_Version
- ErrMessage:
%s failed. Reason: The driver version capability is insufficient. %s - Arglist:
func, reason - 典型 reason:当前版本
%u早于要求的版本%u。 - Solution:升级驱动软件版本。
该码专用于"升级驱动包即可解决"的场景,例如驱动.so中找不到所需符号:
COND_RETURN_AND_MSG_OUTER(tsdOpenNetService_ == nullptr, RT_ERROR_DRV_TSD_ERR, ErrorCode::EE1015, "Starting the HCCP process", "Symbol TsdOpenNetService not found in libtsdclient.so.");打屏效果:Starting the HCCP process failed. Reason: The driver version capability is insufficient. Symbol TsdOpenNetService not found in libtsdclient.so. ErrorCode=EE1015.
EE1016:场景/功能不支持(两参数模板)
- errTitle:Not_Supported
- ErrMessage:
%s failed. Reason: %s. - Arglist:
func, reason
翻译总表给出的 3 条典型 reason 均与ACL Graph 捕获模式相关:
- 当前 context 的其他线程处于捕获状态,当前线程无法执行该操作;可调用
aclmdlRICaptureThreadExchangeMode切换捕获模式(模板给出aclmdlRICaptureBegin设置的模式、当前线程模式、aclmdlRICaptureThreadExchangeMode设置的模式三个值); - 当前线程
%d处于捕获模式且当前操作不被支持——只有 RELAXED 模式支持该操作; - 其他线程处于捕获状态的紧凑变体:
contextCaptureMode=%d, threadCaptureMode=%d, exchangeCaptureMode=%d。
- Solution:检查
aclmdlRICaptureBegin设置的模式是否支持当前线程中的当前操作。
EE1016 覆盖两类"固有不支持":某状态/场景下不支持某类操作(如从 stop 模式切到 continue 模式),以及与芯片无关的完整功能不支持。capture mode 场景有专用宏CHECK_CAPTURE_MODE_SUPPORT_AND_RETURN[_WITH_DESC],其内部通过RT_LOG_OUTER_MSG_IMPL(ErrorCode::EE1016, funcName, reason)完成上报。
EH0011:ACL 层"芯片不支持"专用码
- errTitle:Not_Supported
- ErrMessage:
The current system or device does not support %s. - Arglist:
func(无 reason 字段) - 典型 reason(体现在 func 参数文案中):仅支持 Ascend 910 芯片。
EH0011 与 EE1005 模板一致(The current system or device does not support %s.),用于"换芯片可解决"的场景。ACL 层真实示例(引自 macro-selection-guide 与 error-code-guide 的示例):
acl::AclErrorLogManager::ReportInputError(acl::UNSUPPORTED_SYSTEM_MSG, {"func"}, {"aclrtSetDeviceWithoutTsdVXX, only Ascend 910 chips are supported"});注意:非芯片原因的不支持(配置参数、软件版本、固有限制)在 ACL 层应使用 EH0006 而非 EH0011。
四、资源与执行类
EE1007:流绑定模型失败
- errTitle:Resource_Error_Bind_Stream
- ErrMessage(总表版本):
Failed to bind stream with ID %s. Reason: %s.;error_code.json 与 error_code_meta.h 中的现行模板为Failed to bind stream (stream_id=%s). Reason: %s. - Arglist:
id, reason - 典型 reason:
- 流绑定失败,
stm参数不能是指定 flag(%u)的流; - 非持久流不能绑定到模型;
- 该流绑定了多个 mdlRI(Size: %u);
- 该流已被绑定;
- AI CPU 流被复用;
- 模型已绑定到另一个流。
- 流绑定失败,
- Solution:先将流从已绑定的模型上解绑,再绑定到当前模型。
仓库真实调用示例(模型输入流绑定检查):
if (streamIn->IsModelStream()) { RT_LOG_OUTER_MSG_IMPL(ErrorCode::EE1007, streamId, RtFmtMsg("The current stream has been bound to a model (model_id=%u) " "and cannot be bound to the input model (model_id=%u)", streamIn->Model_()->Id_(), Id_())); return RT_ERROR_STREAM_MODEL; }EE1009:模型执行失败
- errTitle:Execution_Error_Model
- ErrMessage(总表版本):
Failed to execute model with ID %s. Reason: %s.;现行模板为Failed to execute model (model_id=%s). Reason: %s. - Arglist:
id, reason(id 为模型 ID) - 典型 reason:
- 当前流不能与模型流相同;
- 指定 flag(%u)的流不能用于模型执行;
- 当前 ACL Graph 模型运行实例既不包含任何可执行任务,也不包含任何可执行流。
示例:Failed to execute model (model_id=1). Reason: The current aclgraph model running instance neither contains any executable task nor contains any executable stream. ErrorCode=EE1009.
EE9999:内部错误(无模板,仅原始消息)
EE9999 是 Runtime 内部错误码,没有 JSON 模板——总表为其预留了空的 errTitle/ErrMessage/Arglist 字段,仅汇总典型 reason 清单,共 40 条,反映的是内部逻辑断言的常见形态。上报时格式为XX9999: Inner Error!加原始消息(由_INNER系列宏写入,如COND_RETURN_AND_MSG_INNER)。其 reason 清单可视为"内部第一现场"的故障字典,节选:
- 模块加载失败:程序大小应为大于 0 的值,实际为 0;
- 为
rtArgsEx_t.args分配 device 内存失败; - 基于 SO 名获取 SO 地址失败;
- 当前流状态不满足下发任务的条件;
- 任务提交后的后处理失败;
- label 列表中已存在相同 label;
- label 信息从 host 拷贝到 device 失败;
- Label ID
%u被重复释放; devDstAddr被重复设置;- 当前线程与执行
StreamBeginCapture的线程不同; - 模型执行前设置 notify 失败;
- 等待流内所有任务完成失败;
- 流与模型解绑失败——指定流未绑定到当前模型;
- 模型不包含任何流;
str长度必须大于 0;- 流中最后一个任务类型不是 event record;
- 捕获事件尚未被记录;
- 重新申请的 SQ/CQ/逻辑 CQ 与原始值不一致;
- 当前流的 SQ 和 CQ 已申请过,不能再次申请;
- 远端 SQ 不能被复用;
- 订阅同步调度的线程数超过最大值
%u; - TS 状态异常;
- Device
%u故障; - 流状态为
%u; - 模型流已满;
sendSqenum的值%u不能大于任务允许的最大 SQE 数(%u);- SQE 总数(%u)不能大于 SQ 深度
%u; - Device
%u不可用; - 任务数不能超出任务组大小;
- 清理任务期间必须禁用 SQ;
- DQS 流不能用
ts_id %u创建,应使用ts_id %u; qid %u对应的 mbuf pool 信息不存在,检查配置流程;- 被依赖的程序可能已被释放;
- 当前 label 已被设置到另一个流;
- 从 device 查询到的 abort 状态无效;
- 流回收超时;
- 任务回收失败;
- 绑定到当前流
%u的 ACL Graph 模型%u不满足更新条件——运行或捕获状态的 ACL Graph 模型均不可更新; - 下发 CmoAddr 任务的流不在模型中;
- 指定 DVPP 组的流
%d不能绑定到模型。
从源码结构看,内部错误码的获取规则是:一次错误获取中若混合了外部/内部错误码,优先取第一条外部错误码作为"首错"(带 title/cause/solution),其余进入 TraceBack;若全部是内部错误码,则第一条作为首错(XX9999: Inner Error!),其余进入 TraceBack。
五、文件解析与整改要点
EE1014:算子 ELF 二进制解析失败
- errTitle:File_Operation_Error_Parse
- ErrMessage:
Failed to parse the binary file of the operator. Reason: %s. - Arglist:
reason - suggestion.Possible Cause:1. 算子二进制文件损坏;2. 构建参数不正确。
- suggestion.Solution:重新构建并加载算子二进制文件。
翻译总表列出的 10 条典型 reason 精确对应 ELF 文件头与 section header 的校验逻辑,是排查算子.so/bin 损坏的直接依据:
- 算子二进制 ELF 文件头中
e_shentsize的值%u或e_shnum的值%u不正确——两者均不能为 0,且乘积不能超过uint64_t最大值; - ELF 文件头中
e_shentsize的值%u必须等于 ELF section header 的大小%u; - ELF section header 地址不能为空;
- 排名
%u的 section 的偏移量%u超出 ELF 对象大小%u; - 排名
%u的 section 的sh_link值%u无效,有效范围[%u, %u]; section->sh_entsize的值%lu无效,有效范围(0, %lu];section->sh_entsize的值%zu无效,必须大于或等于%u;- 排名
%u的sh_ent偏移量%u超出 ELF 对象大小%u; - ELF 文件必须是 64 位文件;
- 获取 meta section 失败:
kernelName=%s, meta type=%u。
该码只能用于算子 ELF bin 解析失败;其他文件操作场景(如路径不可访问)误用会输出误导性的 "Failed to parse the binary file of the operator" 前缀。
文案整改的三条硬约束
结合总表所在目录的 README、rectification-principles.md 与 review-checklist.md,使用/修改这些模板时需满足:
- 参数数量严格一致:宏调用传入的参数个数必须等于 Arglist 长度,
%s占位符与参数按序一一对应(EE1003 为 4 个,EE1017 为 3 个,EE1014 只有 1 个 reason)。 - 双源同步:错误码元数据以 error_code.json 为准,修改模板时须同步 error_code_meta.h(X-Macro 表);总表中的"new ErrMessage"与 json/meta 的现行措辞可能因整改进度略有差异(如 EE1007 的 "with ID %s" 与 "stream_id=%s"),以代码为准。
- 参数拼接用
RtFmtMsg:_OUTER宏的参数需转换为 string,动态内容禁止std::string直接相加(会导致 .so 膨胀),应使用RtFmtMsg("Changing stream %u is not supported", id)之类的栈上格式化。
六、如何阅读一条实际的错误输出
把总表倒过来用即可定位问题。以一条真实形态的输出为例:
Setting the stream error reporting mode failed. Reason: Changing stream 15 from stop mode to continue mode is not supported. ErrorCode=EE1016.- 由
ErrorCode=EE1016查总表 → errTitle 为 Not_Supported,Arglist 为func, reason; - 第一个
%s填了 "Setting the stream error reporting mode"(语义化 func 描述); Reason:之后到ErrorCode之前整段是 reason 参数;- 该码 suggestion 为 N/A,处理方向由 reason 本身指示(固有不支持,无需升级)。
对照之下,Expected value:结尾的 EE1003、%s is not supported结构的 EE1006、以及带stream_id=/model_id=资源标识的 EE1007/EE1009,都能按同一方式拆解。
小结与延伸阅读
- 错误码全量清单、决策树与常见误用示例:error-code-guide.md;
- 上报宏(
COND_RETURN_AND_MSG_OUTER、ACL_CHECK_INVALID_PARAM_WITH_REASON等)的选择规则:macro-selection-guide.md; - 整改边界、第一现场与打印格式规范:rectification-principles.md;
- 提交前自检(双源同步、参数数量、文案语法):review-checklist.md;
- 元数据事实来源:error_code.json、error_code_meta.h、error_manager.h。
【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考