CANN Runtime 错误码 EE1003 Invalid_Argument 深度解析从报错格式到源码排查实战【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime导读EE1003 是 CANN RuntimeRTS对外暴露的“参数非法Invalid Argument”错误码用于在运行时接口收到超出合法范围的输入参数时给出统一的、带四段式结构化信息的报错。本文以官方错误码参考文档为主体结合cann/runtime仓库中的错误码定义表src/dfx/error_manager/error_code.json、RTS 接口声明pkg_inc/runtime/runtime/rts/rts_stream.h以及错误码上报宏实现src/runtime/core/inc/base.hpp、src/runtime/core/inc/common/error_message_manage.hpp进行纵深解读帮助开发者准确读懂 EE1003 报错信息、快速定位非法参数根因并掌握参数范围校验与接口调用关系的排查方法。1. EE1003 是什么RTS 错误码家族中的“参数校验哨兵”CANN Runtime 在运行过程中会通过统一的错误码体系向 Host 侧上报异常错误码以EE前缀标识 Execution Error执行类错误。在docs/en/error_code_ref/RTS-Errors/目录下围绕同一类问题往往有多个细分错误码例如EE1001Invalid_Argument参数无效报错格式为The argument is invalid. Reason: %s通过附加信息说明原因EE1003Invalid_Argument参数值非法本文主题报错中直接给出非法参数值、参数名与期望值EE1004Invalid_Argument_Null_Pointer参数为空指针报错格式为%s failed because %s cannot be a NULL pointer.EE1005Not_Supported当前系统或设备不支持该功能。其中 EE1003 的特点在于报错信息自带“回放”能力——它把出错的函数、传入的非法值、参数名以及期望值四项关键信息全部嵌入错误文本开发者无需额外的上下文即可判断是哪一次调用、哪个参数、传了什么值、应该传什么值。在仓库的错误码定义表 src/dfx/error_manager/error_code.json 中EE1003 的登记信息如下{ errClass: RTS Errors, errTitle: Invalid_Argument, ErrCode: EE1003, ErrMessage: %s failed because value %s for parameter %s is invalid. Expected value: %s., Arglist: func, value, param, expect, suggestion: { Possible Cause: N/A, Solution: 1. Check the input parameter range of the function. 2. Check the function invocation relationship. } }这里ErrMessage中的四个%s占位符与Arglist中的func, value, param, expect一一对应构成了 EE1003 报错的固定模板也是本文第 2 节将详细拆解的格式来源。2. 读懂 EE1003 的报错格式四个占位符的含义根据官方错误码参考文档EE1003-Invalid_Argument.mdEE1003 的报错模板为%s failed because value %s for parameter %s is invalid. Expected value: %s.其中各占位符%s的语义按出现顺序依次为序号占位符含义示例1%s报错阶段Error stage或发起调用的 API 名称rtsStreamSetAttribute2%s传入的非法参数值Parameter value-53%s参数名Parameter namestmAttrId4%s期望值Expected value即该参数的合法取值范围[0, 5)文档给出的完整报错示例如下rtsStreamSetAttribute failed because value -5 for parameter stmAttrId is invalid. Expected value: [0, 5).逐段解读这行报错报错发生在rtsStreamSetAttribute接口调用中开发者向该接口的stmAttrIdStream 属性 ID参数传入了-5-5不在stmAttrId的合法取值区间[0, 5)内因此接口校验失败并返回错误。说明报错示例中的期望值[0, 5)是演示用区间用于展示“区间/范围”类期望值的写法左闭右开。实际合法范围以当前版本的头文件与接口校验逻辑为准——例如当前仓库 pkg_inc/runtime/runtime/rts/rts_stream.h 中rtStreamAttr枚举的合法值为 1~6详见第 4 节不同版本、不同 SoC 上的合法范围可能不同。期望值也可能以(a, b]、[a, b]、 x、枚举名列表等其它形式呈现。3. 从源码看 EE1003 是如何被“拼装”出来的EE1003 的报错文本并非由各接口自行printf而是由 Runtime 的错误上报宏统一生成。理解这条链路有助于你反推“报错里的每个字段到底从哪来”。3.1 核心上报宏在 src/runtime/core/inc/base.hpp 中定义了 EE1003 专用的上报宏// EE1003错误码上报 #define RT_LOG_OUTER_MSG_INVALID_PARAM(parm, ...) \ RT_LOG_OUTER_MSG_WITH_FUNC(ErrorCode::EE1003, (parm), #parm, ##__VA_ARGS__)其作用是把错误码EE1003、当前函数名通过__func__注入见RT_LOG_OUTER_MSG_WITH_FUNC以及参数名通过#parm字符串化组合成一次错误上报。继续追踪RT_LOG_OUTER_MSG_IMPL同样位于 base.hpp#define RT_LOG_OUTER_MSG_WITH_FUNC(error_code, ...) RT_LOG_OUTER_MSG_IMPL((error_code), __func__, ##__VA_ARGS__) #define RT_LOG_OUTER_MSG_IMPL(error_code, ...) \ do { \ ErrorCodeProcess((error_code), __FILE__, __LINE__, __func__ [0], { RT_ERRVAL_VALUES(__VA_ARGS__) }); \ } while (false)ErrorCodeProcess内部base.hpp 第 280 行附近会进一步调用ProcessErrorCodeImpl与ErrorManager::GetInstance().ATCReportErrMessage(...)将错误码文本与参数值一起上报给错误管理模块ErrorManager最终以文档第 2 节所述模板输出。可见报错阶段/API 名第 1 个 %s 出错处所在函数的__func__参数名第 3 个 %s 宏中#parm字符串化后的源码参数名参数值第 2 个 %s 宏调用时显式传入的可读值表达式通常用ToString(var)之类的转换得到期望值第 4 个 %s 宏的可变参数部分追加传入。3.2 配合条件判断的“判参即上报”宏在 src/runtime/core/inc/common/error_message_manage.hpp 中还封装了“条件不满足 → 上报 EE1003 → 返回错误码”的惯用宏// EE1003错误码使用value与参数名分开传入 #define COND_RETURN_AND_MSG_OUTER_WITH_PARAM_NAME(COND, RTERRCODE, value, paramName, ...) \ if (unlikely((COND))) { \ RT_LOG_OUTER_MSG_WITH_FUNC(ErrorCode::EE1003, (value), (paramName), ##__VA_ARGS__); \ return (RTERRCODE); \ }该宏的注释明确说明了两个实参的约定value可读值表达式运行时求值如ToString(var)paramName参数名的字符串字面量如level、flag。从源码结构可以推断Runtime 各接口在校验输入时若发现参数超出合法区间会优先走这套宏组合从而保证同一错误码EE1003的报错格式在全仓库范围内完全一致——这正是错误码参考文档能用一个统一模板覆盖所有场景的原因。4. 以示例接口rtsStreamSetAttribute为例参数范围到底怎么查EE1003 报错示例中出现的是rtsStreamSetAttribute这是 RTS 层pkg_inc/runtime/runtime/rts/提供的 Stream 属性设置接口。查看其声明 pkg_inc/runtime/runtime/rts/rts_stream.h/** * ingroup dvrt_stream * brief set stream attribute * param [in] stm stream handle * param [in] stmAttrId stream attribute id * param [in] attrValue stream attribute value * return RT_ERROR_NONE for ok * return RT_ERROR_INVALID_VALUE for error input */ RTS_API RT_DEPRECATED_MESSAGE(RT_RUNTIME_DEPRECATED_MESSAGE) rtError_t rtsStreamSetAttribute(rtStream_t stm, rtStreamAttr stmAttrId, rtStreamAttrValue_t* attrValue);注意接口返回值的注释成功返回RT_ERROR_NONE参数错误返回RT_ERROR_INVALID_VALUE——这与 EE1003 的“非法值”定位一致。下面拆解stmAttrId的合法范围。4.1 参数类型rtStreamAttr枚举stmAttrId的类型rtStreamAttr在 rts_stream.h 中定义typedef enum { RT_STREAM_ATTR_FAILURE_MODE 1, // 遇错模式继续执行 / 遇错即停 RT_STREAM_ATTR_FLOAT_OVERFLOW_CHECK 2, // 浮点溢出检查开关 RT_STREAM_ATTR_USER_CUSTOM_TAG 3, // 用户自定义标签 RT_STREAM_ATTR_CACHE_OP_INFO 4, // 算子缓存信息开关 RT_STREAM_ATTR_PRIORITY 5, // Stream 优先级 RT_STREAM_ATTR_LAUNCH_BLOCKING_MODE 6, // Launch 阻塞模式 RT_STREAM_ATTR_MAX 7, // 哨兵值属性总数 } rtStreamAttr;因此当前仓库中stmAttrId的合法取值为枚举成员 1~6RT_STREAM_ATTR_MAX是用于表示“属性个数/上限”的哨兵值不应作为合法属性 ID 传入。4.2 参数类型rtStreamAttrValue_t联合体attrValue的类型rtStreamAttrValue_t是一个联合体不同属性复用同一块存储按属性类型解释typedef union { uint64_t failureMode; // RT_STREAM_ATTR_FAILURE_MODE0继续执行1遇错即停 uint32_t overflowSwitch; // RT_STREAM_ATTR_FLOAT_OVERFLOW_CHECK uint32_t userCustomTag; // RT_STREAM_ATTR_USER_CUSTOM_TAG uint32_t cacheOpInfoSwitch;// RT_STREAM_ATTR_CACHE_OP_INFO uint32_t streamPriority; // RT_STREAM_ATTR_PRIORITY uint32_t launchBlockingMode;// RT_STREAM_ATTR_LAUNCH_BLOCKING_MODE uint32_t rsv[4]; } rtStreamAttrValue_t;例如RT_STREAM_ATTR_FAILURE_MODE的取值可参考同一头文件中的宏定义#define RT_STREAM_FAILURE_MODE_CONTINUE_ON_FAILURE (0x0U) // 默认值task出错时处理完异常后继续执行流上的任务 #define RT_STREAM_FAILURE_MODE_STOP_ON_FAILURE (0x1U) // 遇错即停4.3 排查思路的落地对照上述头文件报错示例中stmAttrId被传入-5该值既不是rtStreamAttr枚举中的任何成员也不在 1~6 的取值范围内接口在校验阶段即判定非法从而触发 EE1003 上报。这直观展示了“检查接口输入参数范围”在实践中的做法——以头文件中的枚举定义、宏定义、以及接口注释中标注的取值范围为准而不是凭经验猜值。5. 官方解决方法逐条展开两步定位 EE1003官方参考文档给出的解决方法是两条Check the input parameter range of the function.检查接口的输入参数范围Check the function invocation relationship.检查接口的调用关系下面结合仓库实际展开这两步。5.1 第一步核对接口输入参数范围这是 EE1003 的首要排查方向因为报错本身已经明确告诉了你“哪个参数、什么值、期望什么”。排查建议读报错中的参数名与期望值报错第 3、4 段已经给出了参数名和合法范围直接对比即可确认是否为“值越界”回查头文件中的枚举/宏定义对于枚举类型参数核对传入值是否为枚举成员参考第 4.1 节的rtStreamAttr对于布尔开关核对是否为 0/1如 rts_stream.h 中的RT_STREAM_FAILURE_MODE_*、RT_STREAM_LAUNCH_BLOCKING_MODE_*等宏确认传参类型与接口签名一致注意rtStreamAttrValue_t是联合体若按错误的成员类型赋值例如给uint64_t字段填入超过uint32_t的值也可能触发校验失败关注接口注释的返回值说明如rtsStreamSetAttribute注释所示非法输入会返回RT_ERROR_INVALID_VALUE与 EE1003 语义一致。5.2 第二步检查接口的调用关系当“传入值本身合法、但仍报 EE1003”时问题往往出在调用上下文而非参数值本身。典型场景包括接口未初始化前置依赖例如在 Stream 创建/上下文绑定完成之前就调用属性设置接口导致接口内部校验到流句柄或上下文状态异常间接以参数非法形式返回多线程/多 Device 场景下的参数串扰调用方在不同线程间复用了同一参数缓存或未初始化内存如attrValue指向的联合体未被正确赋值读出的“参数值”不可预期版本能力差异某些属性或取值仅在特定 SoC如 Arch 版本上支持跨版本复用参数可能导致校验失败——仓库中runtime_api_stub_catalog.def、arch5162_unsupported_runtime_api.def等文件的存在说明不同芯片架构对外暴露的 Runtime API 集合存在差异这是排查时值得留意的一点。此时建议梳理从应用入口到出错接口的完整调用链初始化 → Device/Context 绑定 → Stream 创建 → 属性设置确认每一环的返回值与调用顺序是否符合接口文档要求。6. EE1003 与相邻错误码的区分与联动排查 EE1003 时常常会遇到“报错相似但错误码不同”的情况区分它们有助于快速收敛方向错误码标题报错模板典型触发场景EE1001Invalid_ArgumentThe argument is invalid. Reason: %s参数语义不合法原因以附加信息给出EE1003Invalid_Argument%s failed because value %s for parameter %s is invalid. Expected value: %s.参数值超出合法范围本文主题EE1004Invalid_Argument_Null_Pointer%s failed because %s cannot be a NULL pointer.指针参数为空参见 EE1004 文档EE1005Not_SupportedThe current system or device does not support %s.当前系统/设备不支持某功能以上模板均可从 error_code.json 的ErrMessage字段逐一核对。简化的判断口诀报错里出现非法值 期望值→ EE1003报错里只提空指针→ EE1004报错里说明设备不支持→ EE1005报错里仅给出通用原因描述→ EE1001。7. 快速自查清单FAQ 式小结Q1EE1003 报错中的“期望值 [0, 5)”是全局统一的范围吗不是。期望值由具体接口及其所在版本的校验逻辑决定报错示例中的[0, 5)仅用于演示格式。实际范围请以当前版本的头文件枚举、宏定义与接口文档为准。Q2报错里的函数名一定是我调用的那个 API 吗通常是。EE1003 模板第 1 个%s由上报宏自动填充当前函数名__func__即错误发生处所属的接口如果你的代码直接调用了该接口那么它就是报错者如果是间接调用则需要沿调用链回溯。Q3为什么参数明明“看起来合法”还是会报 EE1003优先按第 5.2 节检查调用关系与上下文状态初始化、Device/Context 绑定、并发与版本能力差异并确认传给接口的参数对象尤其是指针指向的联合体/结构体确实被正确初始化。Q4EE1003 与 EE1004 有什么区别EE1004 专用于空指针参数模板含cannot be a NULL pointerEE1003 用于非空但值越界的参数。两者同属 RTS Errors 的 Invalid_Argument 类别可对照 RTS 错误码总览 查看完整家族。8. 结语EE1003 是 CANN Runtime 对外输出“参数非法”信息的标准化通道一方面它以固定模板承载了函数名、非法值、参数名、期望值四要素让报错信息本身具备极强的自解释性另一方面仓库在 error_code.json、base.hpp、error_message_manage.hpp 中的实现保证了全仓库错误文本格式统一、可被日志与上层工具稳定解析。遇到 EE1003 时先读清四段式报错内容再对照对应接口头文件的枚举与宏定义核查参数范围最后审视调用关系与上下文状态即可快速定位并消除问题。【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考