完全指南:从内部错误到自定义错误码的注册与上报)
CANNAscend人工智能任务调度【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址https://gitcode.com/cann/runtime点击查看免费下载CANN Runtime 的错误上报接口Error Reporting APIs是定制开发 CANN 组件与自定义算子场景下向统一错误管理框架注册、上报错误信息的标准入口。本文围绕liberror_manager提供的四个核心接口ReportInnerErrMsg、ReportPredefinedErrMsg、ReportUserDefinedErrMsg、RegisterFormatErrorMessage展开讲解其函数原型、参数语义、错误码编码规则、配套宏以及底层实现原理并给出可直接落地的 JSON 注册与调用示例。读完本文你将能够为自定义算子或定制组件设计符合 CANN 规范的错误码并通过官方推荐的宏在进程加载期或运行期完成错误注册与上报。使用须知接口定位与依赖文件该部分接口仅在定制开发 CANN 组件及自定义算子开发场景下使用用于注册和上报各类预定义与自定义的错误信息。本文介绍这部分接口的功能、参数等仅为了便于您了解这部分接口在 CANN 开放代码中的作用进而更好地使用或修改 CANN 开放代码。接口涉及的头文件与库文件路径如下${INSTALL_DIR}请替换为 CANN 软件安装后文件存储路径以 root 用户安装为例默认路径为/usr/local/Ascend/cann头文件所在路径${INSTALL_DIR}/include/base/err_msg.h该头文件中的接口命名空间为ge底层实现在error_message命名空间ge空间通过using声明复用。依赖的库文件所在路径${INSTALL_DIR}/lib64/liberror_manager.so。在开源仓库中该头文件的源码位于 include/dfx/base/err_msg.h库的完整实现位于 src/dfx/error_manager/error_manager.cc构建脚本 src/dfx/error_manager/CMakeLists.txt 展示了liberror_manager.so以及静态库liberror_manager.a的编译与安装方式。需要说明的是错误上报接口的声明全部带有WEAK_SYMBOL弱符号属性并同时导出了GE_FUNC_HOST_VISIBILITY与GE_FUNC_DEV_VISIBILITY可见性因此无论链接到正式实现库还是 src/dfx/error_manager/stub/gen_stubapi.py 生成的 stub 库调用方都能正常编译链接。错误码编码规则6 位字符的组成在深入各接口前先统一说明 CANN 错误码的编码约定。错误码以6 位字符形式体现例如E19999、E10001、EU0001其结构为位置含义取值第 1 位级别E错误、W告警、I提示第 2 位模块标识模块代号后 4 位错误码号0000~8999 为用户类错误9000~9999 为内部错误码从源码 error_manager.cc 可印证该规则的落地实现IsValidErrorCode()强制校验错误码长度为 6 位kErrorCodeValidLength 6UIsInnerErrorCode()判断后 4 位是否等于9999kInterErrorCodePrefix 9999或将后 4 位等于8888kParamCheckErrorSuffix 8888参数校验类的码也视为内部错误码IsUserDefinedErrorCode()则要求错误码既不是内部错误码也不在预定义错误码表中满足条件即为合法的用户自定义码。在error_message命名空间中W 级告警错误会被写入独立的 warning 容器E 级错误写入 error 容器后续GetErrorMessage()/GetWarningMessage()会分别汇聚输出。ReportInnerErrMsg上报 CANN 内部错误函数原型int32_t ReportInnerErrMsg(const char_t *file_name, const char_t *func, uint32_t line, const char *error_code, const char_t *format, ...)函数功能用于上报CANN 预定义好的内部错误信息同时也会自动附带调用处的文件名、函数名以及行号便于问题定位。内部错误码的后 4 位落在 9000~9999 区间例如E19999。该接口带有FORMAT_PRINTF(5, 6)编译属性见 include/dfx/base/err_msg.h编译器可对format与可变参数进行 printf 风格的类型/个数检查减少格式化串写错的风险。1024 字节长度限制当用户提供的格式化字符串**长度超过 1024包括末尾的\0**时接口返回错误码-1表示失败。该限制来源于实现中的LIMIT_PER_MESSAGE 1024U定义于 error_manager.h。文档给出的判断示例如下若格式化字符串为Error:%s传入的字符串长度为 1000加上Error:与末尾\0后总长度为 1007未超限接口调用成功若传入的字符串长度为 1020加上Error:与末尾\0后总长度变为 1027超过 1024接口调用失败并返回-1。配套宏 REPORT_INNER_ERR_MSG为简化调用接口提供了封装宏REPORT_INNER_ERR_MSG自动填充__FILE__、__FUNCTION__、__LINE__#define REPORT_INNER_ERR_MSG(error_code, format, ...) \ (void)ge::ReportInnerErrMsg(__FILE__, __FUNCTION__, __LINE__, (error_code), (format), ##__VA_ARGS__)实际宏定义见 include/dfx/base/err_msg.h其中##__VA_ARGS__支持可变参数为空的情况。作为参考仓库内部 src/acl/common/log_inner.cpp 即使用REPORT_INNER_ERR_MSG(EH9999, %s, errorMsgStr)的方式上报 ACL 内部错误。参数说明参数名输入/输出说明file_name输入文件名表示用户在哪个文件中调用ReportInnerErrMsg接口固定配置为__FILE__。func输入函数名表示用户在哪个函数中调用ReportInnerErrMsg接口固定配置为__FUNCTION__。line输入行号表示用户在哪一行中调用ReportInnerErrMsg接口固定配置为__LINE__。error_code输入CANN 预定义好的内部错误。错误码以 6 位字符形式体现例如E19999第 1 位表示级别E/W/I第 2 位表示模块后 4 位中 9000~9999 为内部错误码。format输入错误信息。在调用格式化函数时format 中参数的类型、个数必须与实际参数类型、个数保持一致。...输入format 中的可变参数根据错误信息添加。返回值0成功。-1失败。底层实现原理从 error_manager.cc 的实现可以看到完整链路ReportInnerErrMsg内部使用vsprintf_s按LIMIT_PER_MESSAGE长度对format与可变参数做安全格式化随后通过sprintf_s在消息尾部追加[FUNC:%s][FILE:%s][LINE:%u]调用点信息文件路径会经TrimPath只保留文件名部分最后交给ErrorManager::ReportInterErrMessage完成内部错误码校验、work_stream_id 归属与去重入队。若格式化失败或错误码非内部错误码均返回-1并记录 GELOGE 日志。ReportPredefinedErrMsg上报预定义用户类错误函数原型接口提供两个重载版本不带参数的错误码信息int32_t ReportPredefinedErrMsg(const char *error_code)带参数的错误码信息int32_t ReportPredefinedErrMsg(const char *error_code, const std::vectorconst char * key, const std::vectorconst char * value)函数功能用于上报CANN 预定义好的用户类错误信息。用户类错误码的后 4 位落在 0000~8999 区间例如E10001。CANN 预定义好的用户类错误可参见仓库内的错误码参考文档如 docs/zh/error_code_ref/README.md 及其下 ACL/FE/Profiling/RTS/TEfusion 等错误码章节。配套宏 REPORT_PREDEFINED_ERR_MSG针对两个重载提供了可变参数分派的封装宏REPORT_PREDEFINED_ERR_MSG根据实参个数自动选择 1 参数或 3 参数版本#define REPORT_PREDEFINED_ERRMSG_CHOOSER(_1, _2, _3, NAME, ...) NAME #define REPORT_PREDEFINED_ERRMSG_1PARAMS(error_code) error_message::ReportPredefinedErrMsg(error_code) #define REPORT_PREDEFINED_ERRMSG_3PARAMS(error_code, key, value) \ error_message::ReportPredefinedErrMsg((error_code), (key), (value)) #define REPORT_PREDEFINED_ERR_MSG(...) \ REPORT_PREDEFINED_ERRMSG_CHOOSER(__VA_ARGS__, REPORT_PREDEFINED_ERRMSG_3PARAMS, , \ REPORT_PREDEFINED_ERRMSG_1PARAMS)(__VA_ARGS__)参数说明参数名输入/输出说明error_code输入错误码以 6 位字符形式体现例如E10001。第 1 位表示级别E/W/I第 2 位表示模块后 4 位中 0000~8999 为用户类错误。key输入预定义的参数。每个错误码支持的参数可查看 error_code.json 文件中的Arglist字段仓库内置的错误码清单见 src/dfx/error_manager/error_code.json。value输入参数 key 中参数对应的实际值。这些实际值会替换 error_code.json 文件中ErrMessage字段的占位符得到最终的错误码信息。返回值0成功。-1失败。底层实现原理带参数版本在实现见 error_manager.cc 的ReportPredefinedErrMsg中会先校验key与value两个 vector 的长度是否相等不等则直接返回-1随后将二者组装为std::mapstd::string, std::string args_map交给ErrorManager::ReportErrMessage处理。该函数从内存中解析好的error_map_中按error_code查找对应配置error_title、error_message、possible_cause、solution、arg_list并逐个用实际值替换ErrMessage中的%s占位符按arg_list顺序替换每个参数替换一个%skLength 2即%s的长度。若错误码未注册返回-1并记录告警日志若arg_list中某参数在 map 中缺失或ErrMessage中找不到%s占位符同样返回-1。最终错误条目中还会携带suggestion中的 Possible Cause 与 Solution供上层组装完整错误提示。ReportUserDefinedErrMsg上报自定义错误码函数原型int32_t ReportUserDefinedErrMsg(const char *error_code, const char *format, ...)函数功能用于开发者上报自定义错误码推荐使用 U 码段例如EU0001。该接口同样带有FORMAT_PRINTF(2, 3)编译属性。推荐形式为 6 位字符对于空格、非 6 位字符、以 8888 或 9999 结尾等不推荐的形式函数内部会以错误码EU0000进行上报。该兜底逻辑在 error_manager.cc 的ReportErrMsgWithoutTpl中实现先调用IsUserDefinedErrorCode校验若错误码不满足非内部错误码、非预定义错误码的 6 位字符串条件则打印告警日志suggest using the recommended U segment. The error code EU0000 is reported!并将最终错误码强制改写为EU0000。与ReportInnerErrMsg相同该接口也存在1024 字节长度限制格式化结果含末尾\0超过 1024 时返回-1。判断方法与上文示例完全一致。参数说明参数名输入/输出说明error_code输入用户自定义的错误码。format输入错误码对应的错误信息。...输入format 中的可变参数表示 format 中占位符对应的变量值。返回值0成功。-1失败。底层实现原理实现中ReportUserDefinedErrMsg同样使用vsprintf_s以LIMIT_PER_MESSAGE为上限完成安全格式化失败返回-1随后调用ErrorManager::ReportErrMsgWithoutTpl。与预定义错误不同自定义错误不经过错误模板表直接以用户提供的最终文本作为error_message入队因此该接口适合上报无法用统一模板描述的场景。RegisterFormatErrorMessage注册自定义错误码信息函数原型int32_t RegisterFormatErrorMessage(const char *error_msg, size_t error_msg_len)函数功能按照规定的 JSON 格式调用本接口给 CANN注册预定义的错误码信息后再调用 ReportPredefinedErrMsg 接口上报错误码。可一次注册多个错误码注册成功后即可通过ReportPredefinedErrMsg按注册的ErrCode上报并自动完成占位符替换。同时为了方便使用封装了宏REG_FORMAT_ERROR_MSG用户可直接使用该宏注册。该宏直接定义静态变量进程加载时就会完成注册#define REG_FORMAT_ERROR_MSG(error_msg, error_msg_len) \ REG_FORMAT_ERROR_MSG_UNIQ_HELPER((error_msg), (error_msg_len), __COUNTER__) #define REG_FORMAT_ERROR_MSG_UNIQ_HELPER(error_msg, error_msg_len, counter) \ REG_FORMAT_ERROR_MSG_UNIQ((error_msg), (error_msg_len), counter) #define REG_FORMAT_ERROR_MSG_UNIQ(error_msg, error_msg_len, counter) \ static const auto register_error_msg_##counter ATTRIBUTE_USED []() - int32_t { \ return error_message::RegisterFormatErrorMessage((error_msg), (error_msg_len)); \ }()宏中利用__COUNTER__保证多次调用生成互不重复的静态变量名ATTRIBUTE_USEDGCC 下展开为__attribute__((used))确保静态变量在编译优化下不被丢弃从而保证注册逻辑一定被执行。参数说明参数名输入/输出说明error_msg输入错误码信息可一次注册多个错误码。错误码信息需按 JSON 格式组织示例请参见下方调用示例。error_msg_len输入error_msg 长度不包含末尾的\0。返回值0成功。-1失败。调用示例error_msg错误码信息需按照 JSON 格式组织error_info_list是一个包含错误信息对象的数组至少需要包含一个元素其中各字段含义如下errClass错误分类。errTitle错误标题。ErrCode错误码。注意不要与当前已有的错误码重复已有的错误码可参考 docs/zh/error_code_ref/README.md 中的错误码章节。ErrMessage错误消息可以包含格式化占位符%s。Arglist参数列表用于说明ErrMessage中占位符对应的参数参数列表长度与ErrMessage里格式化占位符个数必须相等。suggestion建议信息包含Possible Cause可能的原因。Solution解决方法。#include string #include base/err_msg.h const std::string error_msg R( { error_info_list: [ { errClass: GE Errors, errTitle: Invalid_Dynamic_Shape_Argument, ErrCode: E10018, ErrMessage: Value [%s] for shape [%s] is invalid. When [--dynamic_batch_size] is included, only batch size N can be -1 in [--input_shape]., Arglist: shape,index, suggestion: { Possible Cause: When [--dynamic_batch_size] is included, only batch size N can be -1 in the shape., Solution: Try again with a valid [--input_shape] argument. Make sure that non-batch size axes are not -1. } }, { errClass: GE Errors, errTitle: Invalid_--input_shape_Argument, ErrCode: E10019, ErrMessage: When [--dynamic_image_size] is included, only the height and width axes can be -1 in [--input_shape]., Arglist: , suggestion: { Possible Cause: When [--dynamic_image_size] is included, only the height and width axes can be -1 in the shape., Solution: Try again with a valid [--input_shape] argument. Make sure that axes other than height and width are not -1. } } ] } ); REG_FORMAT_ERROR_MSG(error_msg.c_str(), error_msg.size());注意上例中E10018、E10019仅为说明 JSON 结构所用示例错误码实际注册时务必与仓库内置错误码见 src/dfx/error_manager/error_code.json保持不重复避免覆盖或冲突。底层实现原理RegisterFormatErrorMessage的实现位于 error_manager.cc先用nlohmann::json对传入的error_msg按[error_msg, error_msg error_msg_len)区间解析JSON 语法错误直接返回-1解析成功后调用ErrorManager::ParseJsonFormatString并传入priority 1。ParseJsonFormatString会做以下校验与处理必须包含error_info_list字段且该字段必须是非空的数组否则返回-1遍历每个错误对象读取ErrCode、ErrMessage可选读取errTitle与suggestion含Possible Cause、SolutionArglist按逗号分割成参数列表对每个错误码执行注册/更新决策若错误码尚未注册则直接加入error_map_若已存在则优先级更高者覆盖。用户通过RegisterFormatErrorMessage注册的priority 1高于内置 error_code.json 文件的默认priority 0因此用户注册的定义可覆盖同名内置错误码。仓库内置错误码文件 src/dfx/error_manager/error_code.json 与上文 JSON 结构完全一致error_info_list数组元素含errClass、errTitle、ErrCode、ErrMessage、Arglist、suggestion其内容涵盖 FE Errors、GE Errors、ACL Errors、Profiling Errors、Dump Errors、RTS Errors 等多个分类是了解预定义错误模板的最佳参考资料。该文件在运行时由ErrorManager::Init从库目录下的../conf/error_manager/error_code.json加载解析并通过懒初始化EnsureInitialized保证多线程并发调用下只执行一次解析。补充上下文粒度与 C 语言接口除上述四个面向开发者的上报接口外仓库还提供了配套的底层设施理解它们有助于在定制组件中正确使用错误上报错误消息模式ErrorMsgMode定义于 pkg_inc/base/err_mgr.hINTERNAL_MODE默认推理按线程粒度、训练按 session 粒度记录与PROCESS_MODE以进程为粒度所有错误汇聚到同一容器输出时附加[THREAD:xxx]标识。可通过ErrMgrInit(ErrorMessageMode)初始化。work_stream_id 上下文ErrorManager以线程局部error_context_维护当前 work_stream_id默认由pid * 100000 tid生成GenWorkStreamIdDefault也可通过GetErrMgrContext/SetErrMgrContext在父子线程间传递。错误信息获取GetErrMgrErrorMessage、GetErrMgrWarningMessage、GetErrMgrRawErrorMessages可在上报后取回并清空当前上下文下的错误、告警及原始错误条目含 error_id、error_title、possible_cause、solution、args、report_time 等方便调用方自定义加工输出。C 语言接口对 C 使用者error_manager.h 通过extern C导出了RegisterFormatErrorMessageForC、ReportPredefinedErrMsgForC、ReportInnerErrMsgForC三个等价接口参数以const char**数组与arg_num传递并对空指针入参做了防御性校验。产品支持情况汇总上述四个错误上报接口ReportInnerErrMsg、ReportPredefinedErrMsg、ReportUserDefinedErrMsg、RegisterFormatErrorMessage的产品支持情况完全一致汇总如下产品系列支持情况Ascend 950PR / Ascend 950DT支持Atlas A3 训练系列产品 / Atlas A3 推理系列产品支持Atlas A2 训练系列产品 / Atlas A2 推理系列产品支持Atlas 200I/500 A2 推理产品支持Atlas 推理系列产品支持Atlas 训练系列产品支持IPV350不支持实践要点小结选接口内部组件问题用REPORT_INNER_ERR_MSG自动携带文件/函数/行号上报 CANN 预定义用户错误用REPORT_PREDEFINED_ERR_MSG自动做占位符替换自定义错误信息用REPORT_USER_DEFINED_ERR_MSG直接传文本错误码推荐 U 码段。注册模板需要带结构化 suggestion 与占位符替换的错误用REG_FORMAT_ERROR_MSG在进程加载期注册 JSON 模板注册后再走ReportPredefinedErrMsg上报。遵守约束错误码必须为 6 位字符用户自定义码不要以 8888/9999 结尾否则会回退为EU0000格式化消息总长含\0不得超过 1024注册的ErrCode不要与 src/dfx/error_manager/error_code.json 及 docs/zh/error_code_ref 中已有错误码重复。编译链接包含 include/dfx/base/err_msg.h 头文件链接liberror_manager.so或静态库即可在定制 CANN 组件与自定义算子中使用上述能力。赞分享CANNAscend人工智能任务调度【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址https://gitcode.com/cann/runtime点击查看免费下载相关推荐CANN Runtime 错误消息ErrMsg开发规范全指南错误码、上报宏与检视流程CANN Runtime 错误消息ErrMsg开发规范全指南错误码、上报宏与检视流程 导读 本文基于 CANN/runtime 仓库中 error_mesCANNAscend人工智能任务调度CANN Runtime EZ2001 Execution_Error 错误码解析AI Core 错误与 RAS 故障联动上报机制CANN Runtime EZ2001 Execution_Error 错误码解析AI Core 错误与 RAS 故障联动上报机制 EZ2001 是 CANNCANNAscend人工智能任务调度CANN opbase 算子库 OP_LOGE_FOR_INVALID_CONFIGS_WITH_REASON 宏多配置项无效错误的 ERROR 日志与 EZ0034 错误码上报指南CANN opbase 算子库 OP_LOGE_FOR_INVALID_CONFIGS_WITH_REASON 宏多配置项无效错误的 ERROR 日志与 EZ人工智能算子库CANNAscend创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考