CANN opbase 算子开发错误码 EZ0017 解析:Tensor Format 校验失败的定位与修复
【免费下载链接】opbase本项目是CANN算子库的基础框架库,为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase
导读
EZ0017 是 CANN opbase 算子基础框架库中针对 Tensor 数据排布格式(format)参数校验失败定义的标准错误码。当调用某个算子或 aclnn 接口时,如果传入 Tensor 的实际 format 不在该接口允许的范围内,框架就会抛出形如Parameter x of ResizeBilinearV2 has incorrect format ND. It should be NCHW or NHWC.的报错。本文以 EZ0017 错误码文档 为核心骨架,结合 opbase 仓库中日志宏、错误码注册表与 format 工具类的源码实现,帮助你完整理解 EZ0017 的报错格式、占位符含义、触发场景,并掌握在自研算子或 aclnn 接口中如何主动上报该错误、如何快速定位并修复 format 参数问题。
EZ0017 错误码定位:它属于哪一类算子错误
在 CANN opbase 的错误码体系中,错误码按错误域(errClass)分类,EZ0017 属于Operator Errors(算子错误),错误标题(errTitle)为Invalid_Argument_Tensor_Format,即“Tensor 参数 format 非法”。该错误码与算子参数校验体系中的其他错误码(EZ0001~EZ0038)并列,专门用于描述 Tensor 的 format 维度上的参数问题。
从 错误码注册表源码 可以看到,EZ0017 在框架内部注册的完整定义为:
{ "errClass": "Operator Errors", "errTitle": "Invalid_Argument_Tensor_Format", "ErrCode": "EZ0017", "ErrMessage": "Parameter %s of %s has incorrect format %s. It should be %s.", "Arglist": "param_name, op_name, incorrect_format, correct_format", "suggestion": { "Possible Cause": "N/A", "Solution": "Check whether the format of input/output tensor is correct." } }Arglist定义了报错文案中 4 个%s占位符依次对应的参数名:param_name(参数名)、op_name(算子名或接口名)、incorrect_format(错误的 format 值)、correct_format(正确的 format 值)。suggestion.Solution给出了官方建议的解决方向:检查输入或输出 tensor 的 format 是否正确。
在格式类错误中,EZ0017 属于“单个参数、给出正确格式”的语义变体,与它相邻的还有两个同主题错误码:
- EZ0035:单个参数 format 错误但带具体原因(
Reason: %s); - EZ0018:多个参数 format 同时错误(
Parameters %s ... have incorrect formats %s. Reason: %s.)。
三者共同构成完整的 format 参数校验错误上报矩阵。
错误信息逐字解析
报错模板与占位符
EZ0017 的报错模板原文如下:
Parameter %s of %s has incorrect format %s. It should be %s.四个占位符%s的含义按出现顺序依次为:
| 占位符序号 | 含义 | 对应 Arglist |
|---|---|---|
| 1 | 参数名(如输入/输出 tensor 的名称x) | param_name |
| 2 | 算子名称或 aclnn 接口名称(如ResizeBilinearV2) | op_name |
| 3 | format 错误值(即实际传入的非法 format,如ND) | incorrect_format |
| 4 | format 正确值(即接口允许的 format,如NCHW or NHWC) | correct_format |
报错示例
文档给出的典型报错示例为:
Parameter x of ResizeBilinearV2 has incorrect format ND. It should be NCHW or NHWC.逐段解读这条报错:
Parameter x:发生错误的参数名为x,通常是算子的某个输入或输出 tensor;of ResizeBilinearV2:报错来源算子为ResizeBilinearV2(双线性插值算子);has incorrect format ND:该 tensor 当前实际 format 为ND;It should be NCHW or NHWC:该算子要求 format 必须是NCHW或NHWC二者之一。
也就是说,调用方为x传入了ND格式的 tensor,而ResizeBilinearV2只接受NCHW/NHWC,因此框架拒绝执行并抛出 EZ0017。
算子侧如何产生 EZ0017:OP_LOGE_FOR_INVALID_FORMAT 宏
EZ0017 并不是由框架隐式抛出的,而是由算子或 aclnn 实现主动调用日志上报宏触发的。opbase 在 log.h 中提供了专门宏OP_LOGE_FOR_INVALID_FORMAT,其源码实现如下:
#define OP_LOGE_FOR_INVALID_FORMAT(entityName, paramName, incorrectFormat, correctFormat) \ do { \ std::string _safe_entityName_(entityName); \ std::string _safe_paramName_(paramName); \ std::string _safe_incorrectFormat_(incorrectFormat); \ std::string _safe_correctFormat_(correctFormat); \ OP_LOGE_LIBOPAPI_REPORT(_safe_entityName_.c_str(), \ "Parameter %s of %s has incorrect format %s. It should be %s.", \ _safe_paramName_.c_str(), _safe_entityName_.c_str(), _safe_incorrectFormat_.c_str(), \ _safe_correctFormat_.c_str()); \ const std::vector<const char*> msgKey = {"param_name", "op_name", "incorrect_format", "correct_format"}; \ const std::vector<const char*> msgvalue = {_safe_paramName_.c_str(), _safe_entityName_.c_str(), \ _safe_incorrectFormat_.c_str(), _safe_correctFormat_.c_str()}; \ REPORT_PREDEFINED_ERR_MSG("EZ0017", msgKey, msgvalue); \ } while (0)宏的内部行为可以拆成三步:
- 参数安全化:先把 4 个入参拷贝为
std::string局部变量(_safe_entityName_等),避免字符串指针生命周期问题; - 打 ERROR 日志:通过
OP_LOGE_LIBOPAPI_REPORT输出一条 ERROR 级别日志,日志文案与 EZ0017 报错模板完全一致; - 结构化上报:通过
REPORT_PREDEFINED_ERR_MSG("EZ0017", msgKey, msgvalue)将错误码、键值对(msgKey与msgvalue一一对应)上报给上层,供框架做统一错误码映射与问题诊断。
参数说明
| 参数名 | 说明 |
|---|---|
entityName | 算子名称或 aclnn 接口名称,支持const char*或std::string |
paramName | 参数名(如"x"),支持const char*或std::string |
incorrectFormat | 实际传入的错误 format 值(如"ND"),支持const char*或std::string |
correctFormat | 预期正确的 format 值或取值列表(如"NCHW or NHWC"),支持const char*或std::string |
调用示例(来自 opbase 日志 API 文档)
OP_LOGE_FOR_INVALID_FORMAT 使用文档 给出了与 EZ0017 文档示例完全对应的实现代码:
// 预期输出: Parameter x of ResizeBilinearV2 has incorrect format ND. It should be // NCHW or NHWC. if (format_ != ge::FORMAT_NCHW && format_ != ge::FORMAT_NHWC) { OP_LOGE_FOR_INVALID_FORMAT("ResizeBilinearV2", "x", Ops::Base::ToString(format_).c_str(), "NCHW or NHWC"); return ge::GRAPH_FAILED; }可见典型用法是:在算子的格式校验逻辑中判断 format 是否属于允许集合,不满足时调用宏上报 EZ0017 并返回失败码。示例中Ops::Base::ToString(format_)用于把枚举类型 format 转成字符串(如ND),第三个参数即文档报错示例中的ND。
同类 format 错误宏对照
| 错误码 | 宏 | 语义 |
|---|---|---|
| EZ0017 | OP_LOGE_FOR_INVALID_FORMAT | 单参数 format 错误,给出正确格式 |
| EZ0035 | OP_LOGE_FOR_INVALID_FORMAT_WITH_REASON | 单参数 format 错误,附报错原因 |
| EZ0018 | OP_LOGE_FOR_INVALID_FORMATS_WITH_REASON | 多参数 format 错误,附报错原因 |
这三个宏均定义于 include/op_common/log/log.h,与 错误码注册表 中的定义一一对应。若需要带原因说明的报错(例如“所有输入的 format 必须一致”),应优先使用..._WITH_REASON系列宏;若仅需指示单个参数的正确取值,使用 EZ0017 对应的宏即可。
format 的来源:算子侧如何拿到 format 字符串
报错信息中出现的ND、NCHW、NHWC等字符串,来自 opbase 的 format 工具类 format_utils.cpp。该文件维护了一张Format枚举到字符串的映射表(kFormatToStringMap),例如:
{Format::FORMAT_NCHW, "NCHW"}, {Format::FORMAT_NHWC, "NHWC"}, {Format::FORMAT_ND, "ND"},ToString(Format)函数在内部还会先调用GetPrimaryFormat取出主 format 再查表,说明该工具对含附加信息的复合 format(如 5D/NC1HWC0 系列)做了归一化处理。这意味着 EZ0017 报错中展示的incorrect_format与correct_format都应是主 format 的规范化字符串,便于开发者对照算子规格文档(如 ResizeBilinearV2 的NCHW/NHWC约束)快速定位问题。
触发场景与排查步骤
EZ0017 通常由以下几类情况触发:
- 调用方传错了 format:例如将默认的
ND格式 tensor 直接传给只接受NCHW/NHWC的算子,未做 format 转换(如TransData算子)或未按接口要求显式指定 format。 - 算子规格核对遗漏:开发者在使用自定义算子或 aclnn 接口前,未查阅该接口支持的 format 列表,直接沿用其他框架的格式假设。
- 图中 format 推导不一致:在网络构图阶段,上游算子输出的 format 与下游算子期望的 format 不匹配,且缺少 format 转换节点。
按官方文档给出的解决方法,建议按以下步骤排查:
- 核对报错中的关键字段:从报错文案中提取
paramName(哪个参数)、opName(哪个算子/接口)、incorrectFormat(实际值)与correctFormat(期望值)。 - 检查输入或输出 tensor 的 format 是否正确:确认调用侧构造 tensor 时指定的 format 与期望值一致;若不一致,要么在调用前完成 format 转换,要么显式设置符合要求的 format。
- 对照算子规格文档:确认
correctFormat列出的取值(如NCHW or NHWC)是否与目标算子的官方约束一致,避免规格理解偏差。 - 若为图执行场景:检查图中是否存在缺失的 format 转换算子,或上游算子的 format 设置是否被错误覆盖。
总结
EZ0017 是 CANN opbase 算子参数校验体系中专门描述“单个 tensor 参数 format 非法并给出正确取值”的标准错误码。开发者既可以把它作为排障索引——通过报错中的参数名、算子名、错误值与期望值四元组快速定位 format 不匹配点;也可以在自研算子或 aclnn 接口中通过OP_LOGE_FOR_INVALID_FORMAT宏主动上报该错误码,与框架的REPORT_PREDEFINED_ERR_MSG结构化上报机制打通,从而在算子侧实现与官方错误码体系一致、可被上层统一解析的 format 校验反馈。更多相邻错误码可参考 Operator-Errors 错误码总览。
【免费下载链接】opbase本项目是CANN算子库的基础框架库,为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考