尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

CANN opbase 日志宏 OP_LOGE_FOR_INVALID_TENSORNUM 详解:张量数量校验与 EZ0022 错误码上报实战

CANN opbase 日志宏 OP_LOGE_FOR_INVALID_TENSORNUM 详解:张量数量校验与 EZ0022 错误码上报实战 CANN opbase 日志宏 OP_LOGE_FOR_INVALID_TENSORNUM 详解张量数量校验与 EZ0022 错误码上报实战【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase导读OP_LOGE_FOR_INVALID_TENSORNUM是 CANN opbase 算子库为算子开发Host 侧 InferShape / 参数校验与 aclnn 接口实现提供的参数张量数量校验日志宏当算子的指定参数如动态列表类输入的张量数量与预期不符时它会在输出 ERROR 级别日志的同时向算子错误码体系上报 EZ0022Invalid Argument错误码形成日志可查、错误码可定位的完整排障闭环。读完本文你将掌握该宏的完整签名与参数语义、它在 opbase 日志框架中的底层展开机制OP_LOGE_LIBOPAPI_REPORTREPORT_PREDEFINED_ERR_MSG双通道并能在自己的算子或 aclnn 实现中正确、规范地使用它完成张量数量的参数校验。功能定位何时使用该宏在 CANN 算子开发中很多算子的输入参数本身就是一个张量列表Tensor List例如 foreach 类、Attention 类算子的多个输入。这类参数除了要校验单个张量的 shape、dtype、format 之外还必须校验列表内张量的个数是否满足算子的协议约束。当实际张量数量与预期不符时就属于参数校验错误应使用本宏记录并上报。OP_LOGE_FOR_INVALID_TENSORNUM的行为可以概括为两点依据 关联文档记录日志输出 ERROR 级别日志日志中包含算子/接口名称、参数名称、实际张量数量与预期张量数量上报错误码通过 opbase 错误码框架上报EZ0022Invalid Argument错误码携带param_name、op_name、incorrect_num、correct_num四个结构化字段。它属于 opbase 日志宏家族中通用参数校验宏EZ0xxx 系列的一员与 OP_LOGE_FOR_INVALID_TENSORNUMS_WITH_REASON上报 EZ0023支持多参数并附原因互为补充。完整宏清单可参考 log 接口列表 与 op_common 接口总览。函数原型与参数说明该宏以函数式宏的形式提供声明位于头文件include/op_common/log/log.h中对应安装环境下的${INSTALL_DIR}/include目录以 root 安装为例即/usr/local/Ascend/cann/include。OP_LOGE_FOR_INVALID_TENSORNUM(entityName, paramName, incorrectNum, correctNum)参数名输入/输出说明entityName输入算子名称或 aclnn 接口名称支持const char*或std::string类型。paramName输入参数名称支持const char*或std::string类型。incorrectNum输入实际张量数量int64_t类型。correctNum输入预期张量数量支持const char*或std::string类型。返回值说明无。约束说明无。宏内对传入的字符串参数进行了本地拷贝std::string副本不会对调用方的临时变量生命周期产生依赖。底层实现原理宏展开与双通道上报要正确理解该宏的行为需要看它在 log.h 中的完整定义#define OP_LOGE_FOR_INVALID_TENSORNUM(entityName, paramName, incorrectNum, correctNum) \ do { \ std::string _safe_entityName_(entityName); \ std::string _safe_paramName_(paramName); \ std::string _safe_correctNum_(correctNum); \ OP_LOGE_LIBOPAPI_REPORT(_safe_entityName_.c_str(), \ Parameter %s of %s has invalid tensor num %ld. It should be %s., \ _safe_paramName_.c_str(), _safe_entityName_.c_str(), \ static_castint64_t(incorrectNum), _safe_correctNum_.c_str()); \ const std::vectorconst char* msgKey {param_name, op_name, incorrect_num, correct_num}; \ std::string incorrectNumStr std::to_string(static_castint64_t(incorrectNum)); \ const std::vectorconst char* msgvalue {_safe_paramName_.c_str(), _safe_entityName_.c_str(), \ incorrectNumStr.c_str(), _safe_correctNum_.c_str()}; \ REPORT_PREDEFINED_ERR_MSG(EZ0022, msgKey, msgvalue); \ } while (0)从实现可以看到三个关键设计1. 参数安全拷贝。宏先把三个字符串类参数entityName、paramName、correctNum分别拷贝进局部std::string再通过.c_str()使用。这样即使调用方传入的是临时构造的std::string如示例中的(within the range [1, std::to_string(MAX_COUNT) ]).c_str()在宏展开后的语句序列中也不会出现悬垂指针。这一点对correctNum尤为重要——它天然就是用来拼装描述性文本的。2. 日志通道。宏内部调用OP_LOGE_LIBOPAPI_REPORT同样定义于 log.h。该基础宏首先通过CheckLogLevel(OP_MODULE_ID, DLOG_ERROR)判断是否开启了 ERROR 级别日志模块 ID 为OP_MODULE_ID 63DLOG_ERROR 3满足条件后调用DlogRecord写入日志日志前缀自动携带__FILE__、__LINE__、OP_SUBMOD_NAME默认OPS_BASE、__FUNCTION__、线程 ID通过syscall(__NR_gettid)获取以及OpName等上下文信息。也就是说即使错误码上报被框架过滤排障时也能从运行日志中拿到精确的文件行号和线程信息。3. 错误码通道。宏通过REPORT_PREDEFINED_ERR_MSG(EZ0022, msgKey, msgvalue)上报预定义错误码。EZ0022 的完整定义注册在 src/op_common/log/log.cpp 的 JSON 错误信息表中errClass: Operator Errors, errTitle: Invalid_Argument, ErrCode: EZ0022, ErrMessage: Parameter %s of %s has invalid tensor num %ld. It should be %s., Arglist: param_name, op_name, incorrect_num, correct_num, suggestion: { Solution: Check whether the number of tensor in the input tensor list meets the condition. }注意incorrectNum作为数值参数在两个通道中处理方式不同日志通道直接以%ld格式化输出错误码通道则先static_castint64_t再std::to_string转为字符串作为incorrect_num字段值上报。int64_t的强制转换也意味着调用方传入其它整数类型如size_t、int时宏仍然可用。调用示例与典型场景以下示例完整引自 关联文档关键代码仅供参考不支持直接拷贝运行// 预期输出: Parameter instance of Foreach has invalid tensor num 1000. // It should be within the range [1, 950]. if (tensorCount MAX_COUNT || tensorCount 0) { OP_LOGE_FOR_INVALID_TENSORNUM(Foreach, instance, static_castint64_t(tensorCount), (within the range [1, std::to_string(MAX_COUNT) ]).c_str()); return ge::GRAPH_FAILED; }这个示例完整展示了该宏的典型使用套路先校验后上报先编写数量校验条件tensorCount MAX_COUNT || tensorCount 0命中后立即调用宏并return失败码如ge::GRAPH_FAILEDcorrectNum 是自由文本它不要求是字面量数字可以动态拼接成范围描述within the range [1, 950]、固定值2、倍数关系sp * 2等任意可读性文本这正是它被设计为字符串类型的原因数值显式转换incorrectNum参数显式static_castint64_t传入保证%ld格式化与错误码字段的类型一致性。其他常见写法示意// 固定数量校验 if (inputCount ! 4) { OP_LOGE_FOR_INVALID_TENSORNUM(SomeOp, inputs, static_castint64_t(inputCount), 4); return ge::GRAPH_FAILED; } // 多参数数量的组合校验等价于一个描述性 correctNum if (aCount ! n || bCount ! n) { std::string expect both equal to std::to_string(n); OP_LOGE_FOR_INVALID_TENSORNUM(SomeOp, a and b, static_castint64_t(aCount), expect.c_str()); return ge::GRAPH_FAILED; }若需要同时校验多个参数并附带失败原因可改用上报 EZ0023 的多参数版本 OP_LOGE_FOR_INVALID_TENSORNUMS_WITH_REASON其语义为多个参数张量数量不正确 原因说明适用于AttentionUpdate这类多输入数量需满足相互关系的场景。日志与错误码的输出格式命中该宏后将产生以下两路可观测输出1. ERROR 级别日志前缀含文件、行号、模块、函数、线程 ID[文件:行号][OPS_BASE][函数名][线程ID] OpName:[entityName] Parameter paramName of entityName has invalid tensor num 1000. It should be within the range [1, 950].2. EZ0022 错误码信息格式定义见 EZ0022 错误码文档Parameter %s of %s has invalid tensor num %ld. It should be %s.各占位符含义依次为参数名paramName、算子名或接口名entityName、tensor 数量错误值incorrectNum、tensor 数量正确值correctNum。典型示例Parameter instance of Foreach has invalid tensor num 1000. It should be within the range [1, 950].排障与解决方法当运行时出现 EZ0022 报错时说明某个算子的输入/输出张量列表数量不满足该算子的协议约束。按照 EZ0022 错误码文档 的指引解决方法是检查输入或输出 tensor 的数量是否满足条件。结合日志与错误码中的incorrect_num实际值和correct_num预期值字段对比算子规格文档确认正确数量常见诱因包括动态列表输入个数与算子属性如sp等的倍数关系不满足、调用方传入的张量个数少于/多于协议要求、图编译阶段张量数量推导错误等若错误来自自定义算子实现重点检查算子 Host 侧 InferShape/参数校验逻辑中的数量判断条件是否与算子注册的输入输出定义一致。头文件与依赖使用该宏需要在算子工程中 include 对应头文件#include op_common/log/log.h该头文件位于仓库 include/op_common/log/log.h安装后位于${INSTALL_DIR}/include对外依赖base/err_msg.h提供REPORT_PREDEFINED_ERR_MSG上报机制、graph/error_codes.h提供ge::GRAPH_FAILED等返回值常量以及op_common/op_host/util/opbase_export.h等公共头文件。日志宏家族与其它 EZ0xxx 校验宏形状、维度、dtype、format、value、list size、config、文件操作等均声明于同一头文件完整接口清单见 op_common 接口列表。总结OP_LOGE_FOR_INVALID_TENSORNUM是 opbase 为张量数量类参数校验提供的标准化出口一个宏同时完成 ERROR 日志记录与 EZ0022 错误码上报日志侧自动携带文件行号与线程上下文错误码侧输出四个结构化字段便于上层框架与开发者定位。在算子开发中遵循先校验、命中即上报并返回失败码、correctNum 用可读文本描述预期的用法即可获得规范、可检索、可自动解析的参数错误告警这也是整个 op_common log 宏体系 的一致设计风格。【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表