CANN opbase 算子错误码 EZ0005(Invalid_Input_ShapeSize)排查指南:输入张量形状大小校验失败
【免费下载链接】opbase本项目是CANN算子库的基础框架库,为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase
EZ0005 是 CANN opbase 算子库中用于标记"算子输入张量形状大小(shape size,即总元素数)与预期不符"的标准错误码。本文将以 EZ0005 英文文档 为主体,结合 opbase 仓库中的错误码定义、日志上报宏与错误码注册表源码,完整解析该错误码的报错格式、触发时机、底层实现与排查方法,帮助算子开发者在实现 shape 校验逻辑时准确上报、快速定位并修复此类错误。
一、EZ0005 在算子错误码体系中的位置
在 CANN opbase 仓库中,算子相关的预定义错误码统一归类于 "Operator Errors" 错误类,索引文档见 Operator-Errors.md。EZ0005 在该体系中表示Invalid_Input_ShapeSize,专门用于描述算子输入张量(input tensor)形状大小校验失败的情形。
它与相邻错误码的分工非常明确:
- EZ0001(Invalid_Input_Shape):输入张量的 shape 本身(各维度取值)错误;
- EZ0005(Invalid_Input_ShapeSize):输入张量的 shape size(即
GetShapeSize()返回的总元素数)错误; - EZ0014 / EZ0015 / EZ0016:面向**参数(Parameter)**而非输入张量的形状大小错误,例如算子属性参数、输出参数等。
也就是说,EZ0005 关注的是"这个输入张量里一共应该有多少个元素",而不是"每个维度具体是多少"。两者在排查思路上有本质区别,详见本文第五节。
二、错误信息格式解析
依据 EZ0005 官方文档,当算子输入张量的形状大小校验失败时,日志与错误上报会输出如下固定格式的信息:
The %sth input of %s has incorrect shape size %s. It should be %s.其中四个%s占位符的含义依次为:
| 占位符 | 含义 | 示例值 |
|---|---|---|
第 1 个%s(与前缀th组合) | 输入张量在算子输入列表中的序号(index) | 1 |
第 2 个%s | 算子名称或 aclnn 接口名称(entityName) | Conv2D |
第 3 个%s | 错误的形状大小(实际值,总元素数) | 3 |
第 4 个%s | 正确的形状大小(预期值,总元素数) | 4 |
官方给出的报错示例为:
The 1th input of Conv2D has incorrect shape size 3. It should be 4.这条信息直译为:Conv2D 算子的第 1 个输入,其形状大小实际为 3(总元素数),但预期应为 4。注意这里的1th是消息模板的固定书写形式(占位符与前缀拼接的结果),并不代表英文序数词的规范写法;序号从 0 开始计数时,第一条输入对应 "0th"。
三、源码级解析:EZ0005 错误码的完整链路
从仓库源码可以完整还原 EZ0005 从"枚举定义 → 消息模板注册 → 日志宏上报"的整条链路。
3.1 错误码枚举定义
在 include/op_common/log/error_code.h 中,ViewErrorCode枚举将 EZ0005 对应的数值常量定义为INVALID_SHAPE_SIZE = 70010:
enum ViewErrorCode { ... INVALID_SHAPE = 70009, INVALID_SHAPE_SIZE = 70010, // EZ0005 对应的数值错误码 INVALID_SHAPE_DIM = 70011, ... };从枚举布局可以看出,70000~70018 区间集中定义了算子 shape 与 dtype 相关的校验错误码(如INVALID_INPUT_FORMAT = 70002、INVALID_INPUT_DTYPE = 70003、INVALID_SHAPE_DIM = 70011等),EZ0005 归属于这一系列底层校验错误体系。
3.2 错误码注册表(消息模板与建议)
在 src/op_common/log/log.cpp 的错误码注册表中,EZ0005 条目被完整登记:
{ "errClass": "Operator Errors", "errTitle": "Invalid_Input_ShapeSize", "ErrCode": "EZ0005", "ErrMessage": "The %sth input of %s has incorrect shape size %s. It should be %s.", "Arglist": "index, op_name, incorrect_size, correct_size", "suggestion": { "Possible Cause": "N/A", "Solution": "Check whether the shape of the input tensor is correct." } }该注册表是 EZ0005 错误码的唯一事实来源:ErrMessage定义了最终对外呈现的消息模板,Arglist声明了四个参数(index、op_name、incorrect_size、correct_size)的填入顺序,suggestion则给出官方建议的排查方向——检查输入 tensor 的 shape 是否正确。
3.3 上报宏的实现原理
算子侧通过日志宏OP_LOGE_WITH_INVALID_INPUT_SHAPESIZE上报 EZ0005 错误,其宏定义位于 include/op_common/log/log.h:
#define OP_LOGE_WITH_INVALID_INPUT_SHAPESIZE(entityName, index, incorrectSize, correctSize) \ do { \ std::string _safe_entityName_(entityName); \ std::string _safe_incorrectSize_(incorrectSize); \ std::string _safe_correctSize_(correctSize); \ std::string index_str = std::to_string(index); \ OP_LOGE_LIBOPAPI_REPORT( \ _safe_entityName_.c_str(), "The %sth input of %s has incorrect shape size %s. It should be %s.", \ index_str.c_str(), _safe_entityName_.c_str(), _safe_incorrectSize_.c_str(), _safe_correctSize_.c_str()); \ const std::vector<const char*> msgKey = {"index", "op_name", "incorrect_size", "correct_size"}; \ const std::vector<const char*> msgvalue = {index_str.c_str(), _safe_entityName_.c_str(), \ _safe_incorrectSize_.c_str(), _safe_correctSize_.c_str()}; \ REPORT_PREDEFINED_ERR_MSG("EZ0005", msgKey, msgvalue); \ } while (0)从宏实现可以看到两层关键行为:
- 日志输出:通过
OP_LOGE_LIBOPAPI_REPORT以 ERROR 级别打印格式化消息,占位符依次填入index_str(由 int 型 index 经std::to_string转换)、entityName、incorrectSize、correctSize; - 错误码上报:通过
REPORT_PREDEFINED_ERR_MSG("EZ0005", msgKey, msgvalue)将结构化键值对(msgKey 与 msgvalue 一一对应)上报给上层错误处理框架,其中incorrectSize/correctSize实际传入的是字符串(调用方通常用std::to_string(xShape.GetShapeSize())转换)。
因此,最终呈现给用户的完整信息 = 注册表中的ErrMessage模板 + 调用宏时传入的四个实参,与本文第二节展示的报错格式完全一致。
四、算子侧上报示例(可运行思路)
结合 OP_LOGE_WITH_INVALID_INPUT_SHAPESIZE 接口文档,该宏的完整参数说明如下:
| 参数 | 输入/输出 | 类型 | 说明 |
|---|---|---|---|
| entityName | 输入 | const char* / std::string | 算子名称或 aclnn 接口名称 |
| index | 输入 | int | 输入张量索引(从 0 开始) |
| incorrectSize | 输入 | const char* / std::string | 实际形状大小(总元素数) |
| correctSize | 输入 | const char* / std::string | 预期形状大小(总元素数) |
一个典型的校验与上报代码模式如下(示例仅供理解,不可直接拷贝运行):
// 预期输出: The 0th input of MyOp has incorrect shape size 1024. It should be 2048. if (xShape.GetShapeSize() != 2048) { OP_LOGE_WITH_INVALID_INPUT_SHAPESIZE("MyOp", 0, std::to_string(xShape.GetShapeSize()), "2048"); return false; }在这个模式中需要注意几点工程细节:
- index 从 0 开始:第 0 个输入上报时消息呈现为 "The 0th input...";
- incorrectSize 必须是字符串:shape size 通常是数值类型,需用
std::to_string()转换,而不能直接传入 int,否则宏内对std::string的初始化会编译失败; - correctSize 建议书写为带引号的字符串字面量:它只是消息展示文本,因此既可以写
"2048",也可以写类似"> 0"的约束描述(后者用于表达"应大于 0"这类无法用单个数值表达的条件,参见 EZ0014 文档中的group_index示例)。
补充说明:中文接口文档标注OP_LOGE_WITH_INVALID_INPUT_SHAPESIZE已废弃,建议改用OP_LOGE_FOR_INVALID_SHAPESIZE(参见 OP_LOGE_FOR_INVALID_SHAPESIZE 文档,对应 EZ0014 参数形状大小错误)。不过从 log.h 的当前实现看,该宏仍然保留且能够正确上报 EZ0005,迁移时请结合算子实际语义选择:面向"输入张量"的总元素数校验使用 EZ0005 体系,面向"参数"的校验使用 EZ0014 体系,二者不要混用。
五、排查与解决步骤
官方文档给出的解决方向是:检查输入 tensor 的 shape 是否正确(对应注册表中 "Check whether the shape of the input tensor is correct.")。结合 EZ0005 的语义,推荐按以下步骤系统排查:
- 确认报错输入序号:定位消息中第 1 个字段(如
1th),确定是算子的第几个输入,回到算子定义(proto / infershape 实现)核对该输入声明的约束; - 核对"总元素数"的计算:EZ0005 校验的是
GetShapeSize()(各维度乘积),例如形状[2, 3, 4]的 shape size 为 24。若报错值恰好是"维度数"或"某一维大小",说明校验写错了对象——此时应该分别改用 EZ0011(shape dim 错误)或 EZ0001/EZ0008(shape 错误); - 对照预期值:将实际 shape size 与算子规格中声明的预期值(如固定大小、
> 0、与另一输入相等)逐一比对,检查上游构图/数据预处理是否传入了尺寸不符的张量; - 区分输入与参数:确认报错对象是输入张量(EZ0005)还是参数(EZ0014/EZ0015/EZ0016),避免按错误的方向排查。官方在 EZ0016 文档中给出了多参数场景的示例,如 "Parameters query, key, cos and sin of ApplyRotaryPosEmb have incorrect shape sizes...",可与单输入场景的 EZ0005 消息形态区分;
- 验证修复:修正张量形状或调整算子输入后重跑,确认 ERROR 日志消失。算子开发者在实现校验时,也应在返回失败前通过
OP_LOGE_WITH_INVALID_INPUT_SHAPESIZE上报 EZ0005,使上层框架与用户获得一致、可检索的错误信息。
六、与相邻错误码的区分对照
为避免排查方向混淆,将 EZ0005 与最容易混淆的相邻错误码整理如下(均以 Operator-Errors 索引 及对应文档为准):
| 错误码 | 错误标题 | 校验对象 | 消息形态示例 |
|---|---|---|---|
| EZ0001 | Invalid_Input_Shape | 输入张量的 shape(维度值) | The %sth input of %s has incorrect shape [%s]. It should be [%s]. |
| EZ0005 | Invalid_Input_ShapeSize | 输入张量的 shape size(总元素数) | The %sth input of %s has incorrect shape size %s. It should be %s. |
| EZ0008 | Invalid_Argument_Tensor_Shape | 参数(含输入/输出)的 shape | Parameter %s of %s has incorrect shape [%s]. It should be [%s]. |
| EZ0014 | Invalid_Argument_Tensor_Shape_Size | 单个参数的 shape size | Parameter %s of %s has incorrect shape size %s. It should be %s. |
| EZ0015 | Invalid_Argument_Tensor_Shape_Size | 单个参数,带失败原因 | Parameter %s of %s has incorrect shape size %s. Reason: %s. |
| EZ0016 | Invalid_Argument_Tensor_Shape_Size | 多个参数,带失败原因 | Parameters %s of %s have incorrect shape sizes %s. Reason: %s. |
判断口诀:EZ0005 的报错文本以 "The ... input of ..." 开头,其余 shape size 类错误以 "Parameter ..." 开头。看到前者的消息即定位到本篇文章的排查路径。
七、总结
EZ0005(Invalid_Input_ShapeSize)是 CANN opbase 中面向**算子输入张量形状大小(总元素数)**校验失败的标准化错误码。本文从 官方英文文档 出发,结合 error_code.h 的枚举定义、log.cpp 的错误码注册表与 log.h 的上报宏实现,完整还原了该错误码的生成链路,并给出了算子侧上报示例与系统化排查步骤。开发者只需抓住消息中"输入序号、算子名、实际大小、预期大小"四个要素,即可快速定位是输入构图错误还是校验实现错误。如需深入了解整套算子错误码体系与日志接口,可继续阅读 Operator-Errors 文档索引 与 op_common 日志接口文档。
【免费下载链接】opbase本项目是CANN算子库的基础框架库,为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考