CANN Runtime ACL 错误码 EH0001–EH0014 完全指南:错误格式、触发场景与排查方案
2026/9/19 22:40:19 网站建设 项目流程

CANN Runtime ACL 错误码 EH0001–EH0014 完全指南:错误格式、触发场景与排查方案

【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime

导读

本文基于 CANN runtime 开源仓库的官方错误码参考文档,系统讲解 ACL(Ascend Computing Language)模块下 EH0001~EH0014 共 14 个错误码的含义、输出格式、典型触发场景与解决思路。这些错误码覆盖了参数校验失败、空指针、文件操作失败、功能/接口不受支持、主机内存不足等 ACL 编程中最常见的异常类别,是排查aclrt*acltdt*等运行时 API 调用失败时的第一手依据。读完本文,你将能根据错误消息中的EH000x前缀快速定位问题类别,读懂消息中各占位符(%s)的实际含义,并结合仓库源码理解错误上报链路,从而准确修正调用参数或代码逻辑。

关联文档:本文内容主体来自 docs/en/error_code_ref/ACL-Errors/ 目录下的索引页与 15 个错误码详情页;源码佐证来自 src/acl/ 下的 ACL 运行时实现。

错误码概览:一张表看懂 14 个 ACL 错误

ACL 错误码统一以EH前缀开头,后接 4 位数字。下表汇总了各错误码的完整名称、错误类别和一句话定位提示(内容严格依据各详情页整理):

错误码错误名称错误类别一句话定位提示
EH0001Invalid Argument参数非法参数值超出合法范围或不符合约束
EH0002Invalid Argument Null Pointer参数非法(空指针)指针型参数为空
EH0003File Operation Error Invalid Path文件操作错误文件路径非法或文件不存在
EH0004File Operation Error文件操作错误文件内容/格式不合法
EH0005Invalid Argument参数非法(AIPP)AIPP 相关参数取值非法
EH0006Not Supported功能/接口不支持当前状态下不支持该功能或调用方式
EH0007Invalid Argument参数非法(带期望值)参数值非法,消息中给出期望值
EH0008Invalid Argument Null Pointer参数非法(空指针)错误发生在特定调用阶段,参数为空指针
EH0009Invalid Argument参数非法(越界类)参数值非法,消息中给出具体原因
EH0010Resource Error Insufficient Host Memory资源错误主机侧内存分配失败
EH0011Not Supported系统/设备不支持当前系统或设备不支持某 API
EH0012Invalid Argument参数非法特定阶段参数校验失败,附原因
EH0013Invalid Argument参数非法(底层标准函数失败)底层标准函数调用失败,附 errno
EH0014Invalid Argument Null Pointer参数非法(空指针)多个指针参数同时为空

从类别分布可以看出,参数非法(Invalid Argument)与空指针(Null Pointer)是 ACL 错误的主体,14 个错误码中占了 9 个;其次是功能不支持(2 个)与文件操作错误(2 个),以及 1 个主机内存资源错误。这与 ACL 运行时 API 的健壮性设计直接相关:绝大多数aclrt*入口函数都会先对入参做严格校验,校验失败即返回带有EH000x标记的错误消息。

读懂 EH 错误消息:占位符语义约定

EH 系列错误消息采用统一的模板化格式,消息中通过占位符%s注入具体信息。不同错误码的占位符含义各不相同,官方文档在每个错误码的 Symptom 一节中都有明确说明,本节统一汇总,方便速查:

错误码消息模板占位符顺序及含义
EH0001Value %s for %s is invalid. Reason: %s.参数值、参数名、错误原因
EH0002Argument %s must not be null.参数名
EH0003Path %s is invalid. Reason: %s.文件路径、错误原因
EH0004File %s is invalid. Reason: %s.文件路径、错误原因
EH0005AIPP argument %s is invalid. Reason: %s.参数名、错误原因
EH0006%s is not supported. Reason: %s.功能/接口名、错误原因
EH0007%s failed because value %s for parameter %s is invalid. Expected value: %s.错误阶段(或 API 名)、参数值、参数名、期望值
EH0008%s failed because %s cannot be a NULL pointer.错误阶段(或 API 名)、参数名
EH0009%s failed. Value %s for parameter %s is invalid. Reason: %s.错误阶段(或 API 名)、参数值、参数名、错误原因
EH0010Failed to allocate %s bytes of host memory via %s to ACL.内存大小、内存分配 API
EH0011The current system or device does not support %s.API 名
EH0012%s failed. Parameter %s is invalid. Reason: %s.错误阶段(或 API 名)、参数名、错误原因
EH0013%s failed. Reason: Standard function %s failed. [Errno %s] %s. %s调用失败的 API 名、底层标准函数名、errno、错误原因、扩展信息
EH0014%s failed because %s cannot be NULL pointers at the same time.API 名、参数名

使用要点:

  • 先看错误码,再看消息正文EH000x直接圈定排查方向,正文用于精确锁定出错的参数或文件;
  • %s是注入信息而非字面量:例如 EH0001 的消息模板是固定的,但参数值、参数名和原因会动态填充;
  • EH0007 与 EH0009 形态相近但语义不同:EH0007 会明确给出期望值(Expected value),便于直接对比;EH0009 则给出**错误原因(Reason)**描述;
  • EH0013 是唯一带 errno 的错误码:其消息会嵌套标准函数失败信息(如memcpy_s[Errno 22]),需要结合 errno 进一步定位底层原因。

从源码看 EH 错误码的产生:错误上报链路

ACL 模块的错误码并非运行时动态拼出来的随机文本,而是由统一的错误上报机制生成。在仓库源码中可以看到明确的定义与调用证据:

  • 错误码宏定义位于 src/acl/aclrt_c/common/log_inner.h:#define INVALID_PARAM_MSG "EH0001"#define INVALID_NULL_POINTER_MSG "EH0002",说明 EH0001/EH0002 作为“无效参数/空指针”的标识常量贯穿 ACL 公共层;
  • 实际上报入口在 src/acl/aclrt_impl/memory.cpp:例如符号信息查询函数GetSymbolInfo中,当offset + count > symbolSize时,先记录日志[Check][Offset]offset[%zu] + count[%zu] must be <= symbolSize[%zu].,再通过acl::AclErrorLogManager::ReportInputError(acl::INVALID_PARAM_MSG, std::vector<const char*>({"param", "value", "reason"}), ...)上报 EH0001 错误。
// src/acl/aclrt_impl/memory.cpp(节选,GetSymbolInfo 参数校验) if (totalSize > *symbolSize) { ACL_LOG_ERROR( "[Check][Offset]offset[%zu] + count[%zu] must be <= symbolSize[%zu].", offset, count, *symbolSize); acl::AclErrorLogManager::ReportInputError( acl::INVALID_PARAM_MSG, std::vector<const char*>({"param", "value", "reason"}), std::vector<const char*>({"offset+count", std::to_string(totalSize).c_str(), "must be <= symbolSize"})); return ACL_ERROR_INVALID_PARAM; }

从这段实现可以看出两点关键信息:

  1. ReportInputError的第一个参数就是错误码标识(如INVALID_PARAM_MSG="EH0001",第二个参数是占位符名称序列,第三个参数是占位符对应的实际值——这正好对应文档中 EH0001 消息模板Value %s for %s is invalid. Reason: %s.paramvaluereason三要素;
  2. 错误上报与ACL_ERROR_INVALID_PARAM返回码同时发生:源码在调用ReportInputError后返回ACL_ERROR_INVALID_PARAM,即 EH 错误消息是伴随标准 ACL 错误码一起暴露给调用方的诊断信息。这意味着排查时除了阅读 EH 消息,还应当关注 API 的实际返回值(aclError)以确定错误语义层级。

类似的校验宏(如ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORTACL_CHECK_RANGE_INT)在 src/acl/aclrt_c/common/log_inner.h 中定义,负责空指针与取值范围的前置检查,一旦失败即返回ACL_ERROR_INVALID_PARAM——这正是 EH0002 等空指针类错误码的上游触发点。

各错误码详解与排查实战

EH0001 / EH0005 / EH0007 / EH0009 / EH0012:参数校验类错误

这一类错误码都表示“某个参数值不合法”,区别在于触发阶段与消息中携带的信息不同:

EH0001 参数值非法(通用)

消息模板:

Value %s for %s is invalid. Reason: %s.

错误示例:

Value 0 for size is invalid. Reason: size must be greater than zero.

解决方案:根据消息中 Reason 给出的约束调整参数值。例如上例中size不能为 0,需要传入大于 0 的值。此类错误最常见于aclrtMalloc(分配大小)、aclrtMemcpy(拷贝长度)等内存相关 API,以及各类需要指定数量/尺寸参数的接口。

EH0005 AIPP 参数非法

消息模板:

AIPP argument %s is invalid. Reason: %s.

错误示例:

AIPP argument batch_index is invalid. Reason: batch_index 3 is greater than or equal to batch_number 2.

解决方案:AIPP(AI Preprocessing,图像预处理)参数常用于模型推理前的图像处理配置。示例中batch_index必须小于batch_number,即批次索引不能超出配置的批次数量(索引从 0 开始,batch_index 3batch_number 2已越界)。请核对 AIPP 配置中批次相关参数的一致性。

EH0007 参数值非法(带期望值)

消息模板:

%s failed because value %s for parameter %s is invalid. Expected value: %s.

错误示例:

aclrtMemcpyKindTranslate failed because value ACL_MEMCPY_INNER_DEVICE_TO_DEVICE for parameter kind is invalid. Expected value: ACL_MEMCPY_HOST_TO_DEVICE

解决方案:

  1. 核对函数的输入参数取值范围;
  2. 检查函数调用关系(确认是否在错误的上下文/阶段调用了该函数)。

示例中aclrtMemcpyKindTranslate是内存拷贝方向转换的辅助函数,kind参数被传入了不支持的枚举值,消息直接给出了期望的枚举值ACL_MEMCPY_HOST_TO_DEVICE,按提示替换即可。

EH0009 参数值非法(带原因)

消息模板:

%s failed. Value %s for parameter %s is invalid. Reason: %s.

错误示例:

acltdtGetDataItem failed. Value 5 for parameter index is invalid. Reason: index 5 is greater than or equal to dataset size 10.

解决方案:与 EH0007 相同的两步法——先查参数范围,再查调用关系。示例为 TDT 数据集接口acltdtGetDataItem越界访问:数据集中只有 10 个元素(索引 0~9),却请求索引 5(注意:示例中dataset size 10index 5的表述表明越界判定是index >= dataset size,此处索引 5 实际未越界,仅为演示占位符填充格式)。

EH0012 参数非法(阶段上下文)

消息模板:

%s failed. Parameter %s is invalid. Reason: %s.

错误示例:

aclrtAllocatorGetByStream failed. Parameter stream is invalid. Reason: The stream is not registered with any allocator.

解决方案:根据 Reason 调整参数。示例中自定义内存分配器 APIaclrtAllocatorGetByStream要求传入的stream必须已注册过分配器,需要在调用前先完成分配器与流的绑定。

EH0002 / EH0008 / EH0014:空指针类错误

空指针是 C/C++ 编程中最常见的 ACL 错误来源,三种错误码的判别要点在于“哪个参数为空”以及“是否多个参数同时为空”:

EH0002 参数不能为空(通用)

消息模板:

Argument %s must not be null.

错误示例:

Argument dataset must not be null.

解决方案:传入正确的指针参数。排查时先确认指针是否已被初始化、是否在调用前被释放。

EH0008 特定阶段空指针

消息模板:

%s failed because %s cannot be a NULL pointer.

错误示例:

aclrtSynchronizeStream failed because stream cannot be a NULL pointer.

解决方案:传入正确的指针参数。与 EH0002 的区别在于消息首部带出了错误发生的阶段或 API 名(示例中为aclrtSynchronizeStream),便于快速定位是哪个调用链上的空指针。

EH0014 多个参数不能同时为空

消息模板:

%s failed because %s cannot be NULL pointers at the same time.

错误示例:

aclrtFunctionGetParamInfo failed because paramOffset and paramSize cannot be NULL pointers at the same time.

解决方案:传入正确的指针参数。注意语义是“不能同时为空”,即两个出参中至少提供一个有效指针。示例中aclrtFunctionGetParamInfoparamOffsetparamSize可以只关心其中一个,但两个都传 NULL 即触发本错误。

与源码的对应ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(val)宏(src/acl/aclrt_c/common/log_inner.h)正是这类检查的实现——当val == NULL时记录[Check][%s]param must not be NULL.日志并返回ACL_ERROR_INVALID_PARAM。凡是 ACL 接口实现中调用该宏的位置,都是空指针类错误的潜在触发点。

EH0003 / EH0004:文件操作类错误

EH0003 路径非法/文件不存在

消息模板:

Path %s is invalid. Reason: %s.

错误示例:

Path /tmp/invalid.json is invalid. Reason: file open failed.

解决方案:根据错误消息检查文件是否存在,以及路径拼写、访问权限是否正确。

EH0004 文件内容/格式不合法

消息模板:

File %s is invalid. Reason: %s.

错误示例:

File /home/acl.json is invalid. Reason: config content differs from the first aclInit config file path: /etc/acl.json.

解决方案:根据错误消息检查文件内容是否正确。该示例直接展示了 ACL 的典型场景——aclInit初始化时配置文件路径必须全局一致:同一进程中首次aclInit指定的配置文件(/etc/acl.json)与后续传入的配置内容不一致时,即触发 EH0004。这是多模块/多库同时初始化时常见的配置冲突问题,排查时应统一所有调用方传入的配置文件路径。

EH0006 / EH0011:不支持类错误

EH0006 功能或调用方式不支持

消息模板:

%s is not supported. Reason: %s.

错误示例:

acltdtAddDataItem is not supported. Reason: item cannot be added because internal item already exists.

解决方案:根据 Reason 调整代码逻辑。注意 EH0006 的“不支持”可能并非硬件能力问题,而是当前对象状态下不允许该操作(示例中数据集内部已存在 item,重复添加被拒绝),属于逻辑约束。

EH0011 当前系统或设备不支持某 API

消息模板:

The current system or device does not support %s.

错误示例:

The current system or device does not support aclrtGetDevice.

解决方案:根据错误消息调整代码逻辑。EH0011 通常与硬件平台能力相关——某个 API 只在特定昇腾芯片型号或系统版本上可用。排查时应核对当前设备的 SoC 版本与 CANN runtime 版本的配套关系(可参考 docs/zh/FAQ/Runtime版本与CANN版本不匹配导致的问题.md),或在代码中先查询设备能力再调用对应接口。

EH0010:主机内存不足

消息模板:

Failed to allocate %s bytes of host memory via %s to ACL.

错误示例:

Failed to allocate 1024 bytes host memory for ACL.

可能原因:主机侧内存不足导致内存分配失败(该错误码属于资源错误类别,非参数问题)。

解决方案:确保系统有足够可用内存,可以通过停止不必要的进程释放内存后重试。

排查建议:在容器、多进程推理等场景下,除了系统物理内存,还需要关注进程的RLIMIT_AS/RLIMIT_DATA限制以及 cgroup 内存上限;可通过free -h观察内存水位,用ulimit -a查看进程资源限制。

EH0013:底层标准函数失败(带 errno)

消息模板:

%s failed. Reason: Standard function %s failed. [Errno %s] %s. %s

错误示例:

acltdtSendTensor failed. Reason: Standard function memcpy_s failed. [Errno 22] Invalid argument. src=0x1234, dst=0x5678, dstLen=1024, srcLen=512

解决方案:根据错误消息定位问题。EH0013 是 14 个错误码中最“深入”的一个——它表明 ACL 接口内部的标准 C 库/安全函数调用失败

  • %s failed:哪个 ACL API 失败(示例为acltdtSendTensor);
  • Standard function %s failed:底层哪个标准函数失败(示例为memcpy_s);
  • [Errno %s] %s:errno 编号与含义(示例Errno 22EINVAL,参数无效);
  • %s:扩展信息(示例给出了srcdstdstLensrcLen的具体值,可直接判断dstLensrcLen是否匹配)。

示例中dstLen=1024srcLen=512,若memcpy_s要求dstLen >= srcLen,则此例参数本身合法,问题可能出在源/目的地址有效性上;实际排查时结合扩展信息逐一核对即可。

实战排查流程:遇到 EH 错误码怎么处理

结合前文各错误码的解决方案,可归纳出一套通用的四步排查法:

  1. 识别错误码类别:从消息首部的EH000x判断属于参数类、空指针类、文件类、不支持类还是资源类;
  2. 解析占位符信息:按本文的占位符语义表,把消息中的参数名、参数值、期望值/原因、errno、扩展信息逐项拆解出来;
  3. 定位到具体 API 与调用链:根据消息中的 API 名(如aclrtSynchronizeStreamacltdtSendTensor)回到调用代码,检查入参来源与调用顺序。若涉及初始化类错误,重点检查aclInit配置一致性(EH0004)与设备初始化顺序;
  4. 结合返回值与日志:EH 错误消息通常伴随ACL_ERROR_INVALID_PARAM等返回值,可参考 docs/en/error_code_ref/ACL-Errors/ 索引逐项对照;同时可开启 CANN 日志(参考 docs/zh/env_vars/ASCEND_GLOBAL_LOG_LEVEL.md)查看[Check]前缀的详细校验日志,日志中的检查点信息往往比错误消息更早暴露问题。

进一步阅读

  • docs/en/error_code_ref/ACL-Errors/:ACL 错误码索引页,可跳转 15 个详情文档;
  • docs/en/error_code_ref/RTS-Errors/:Runtime 侧(RTS)错误码参考,涵盖更多底层运行时错误;
  • docs/zh/FAQ/如何获取和解读Runtime异步错误码.md:异步错误码的获取与解读方法;
  • docs/zh/FAQ/如何通过plog日志定位Device侧异常.md:Device 侧异常的日志定位手段;
  • docs/en/error_code_ref/ACL-Errors/ 中每个错误码详情页的 Solution 一节,均给出了该错误码的针对性解决步骤。

【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询