CANN Runtime 错误码 EK0002 深度解析:Profiling 接口调用顺序错误(Invalid_Argument_API_Call_Sequence)
2026/9/19 22:28:08 网站建设 项目流程

CANN Runtime 错误码 EK0002 深度解析:Profiling 接口调用顺序错误(Invalid_Argument_API_Call_Sequence)

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

EK0002 是 CANN Runtime 维测组件(msprof)在 Profiling 采集过程中,检测到上层应用以错误的顺序调用 Profiling 接口时上报的参数类错误码。当用户在使用aclprofInitaclprofStartaclprofWarmupaclprofCreateStamp等采集接口时,若跳过前置初始化或越过生命周期阶段,就会收到形如 "Please call the APIs in the following order: call %s first, then %s." 的报错。阅读本文后,你将能够准确解读 EK0002 报错中的两个占位符含义,理解 msprof 内部的状态检查机制,掌握 Profiling 接口的正确调用顺序与排查修复方法。

一、错误码定义与报错格式

EK0002 的完整定义位于错误码注册表 error_code.json 中,归属Profiling Errors错误类:

字段
errClassProfiling Errors
errTitleInvalid_Argument_API_Call_Sequence
ErrCodeEK0002
ErrMessagePlease call the APIs in the following order: call %s first, then %s.
Arglistintf1, intf2

从定义可以看到,该错误码的报文模板中携带两个占位符参数

  • intf1(第一个%s):必须先调用的接口名;
  • intf2(第二个%s):当前错误调用的接口名。

报错格式

报错文本统一为以下格式(占位符%s均为接口名):

Please call the APIs in the following order: call %s first, then %s.

报错示例

以文档中的原始示例为例,当应用在未调用aclprofInit的情况下直接调用aclprofStart时,输出如下:

Please call the APIs in the following order: call aclprofInit first, then aclprofStart.

该提示语义清晰:系统要求用户先调用aclprofInit完成 Profiling 模块初始化,再调用aclprofStart启动数据采集

二、底层实现:EK0002 是如何被触发的

EK0002 并非凭空产生,而是 msprof 组件在各 Profiling 接口入口处对"初始化状态"和"生命周期阶段"做前置校验后,通过统一错误上报机制打出的。整个链路可分为两层。

2.1 统一错误上报宏 MSPROF_INPUT_ERROR

msprof 组件将所有"入参/状态不合法"类错误统一封装进宏MSPROF_INPUT_ERROR,其定义位于 msprof_error_manager.h:

#define MSPROF_INPUT_ERROR(errorCode, key, value) \ Analysis::Dvvp::MsprofErrMgr::MsprofErrorManager::instance()->ReportErrorMessage(errorCode, key, value)

调用时传入三个参数:

  • errorCode:错误码字符串(如"EK0002");
  • key:参数名列表(对 EK0002 固定为{"intf1", "intf2"},对应错误码注册表中的Arglist);
  • value:参数值列表(即两个真实接口名的字符串数组)。

ReportErrorMessage会结合 error_code.json 中的ErrMessage模板,将key/value一一对应地填充进%s占位符,最终生成用户在日志中看到的完整报错文本。

2.2 状态前置校验触发点

从源码结构看,EK0002 主要在以下三类场景中被抛出:

  1. 启动采集前未初始化aclprofStart/aclprofWarmup入口先调用ProfAclMgr::ProfStartPrecheck()做预检查,若返回ACL_ERROR_PROF_NOT_RUN(表示 Profiling 尚未初始化),随即上报 EK0002,提示先调用aclprofInit
  2. Warmup 与 Start 顺序冲突aclprofWarmup若在aclprofStart之后被调用,会因阶段冲突上报 EK0002;
  3. Stamp 创建前未启动采集:msproftx(时间戳打点)管理器MsprofTxManager未初始化时调用aclprofCreateStamp,上报 EK0002 提示先调用aclprofStart

这些校验逻辑的具体位置与示例见下一节。

三、典型触发场景与源码佐证

场景一:未调用 aclprofInit 就调用 aclprofStart / aclprofWarmup

在 msprofiler_acl_api.cpp 的ProfWarmup实现中,预检查失败(ACL_ERROR_PROF_NOT_RUN)时上报:

int32_t ret = ProfAclMgr::instance()->ProfStartPrecheck(); if (ret != ACL_SUCCESS) { if (ret == ACL_ERROR_PROF_NOT_RUN) { MSPROF_INPUT_ERROR( "EK0002", std::vector<std::string>({"intf1", "intf2"}), std::vector<std::string>({"aclprofInit", "aclprofWarmup"})); } return ret; }

同理,aclprofStart入口的预检查失败路径上报(见 msprofiler_acl_api.cpp):

MSPROF_INPUT_ERROR( "EK0002", std::vector<std::string>({"intf1", "intf2"}), std::vector<std::string>({"aclprofInit", "aclprofStart"}));

即:必须先aclprofInit,再aclprofStart——这正是文档示例报错的来源。

场景二:aclprofWarmup 在 aclprofStart 之后调用

aclprofWarmup用于在正式采集前预分配 Profiling 配置资源,代码中通过ProfAclMgr::IsAclApiReady()判断采集是否已启动,若已启动则报错(见 msprofiler_acl_api.cpp):

// ProfWarmup will not work after ProfStart called if (ProfAclMgr::instance()->IsAclApiReady()) { MSPROF_LOGE("aclprofWarmup cannot be called after aclprofStart."); MSPROF_INPUT_ERROR( "EK0002", std::vector<std::string>({"intf1", "intf2"}), std::vector<std::string>({"aclprofWarmup", "aclprofStart"})); return ACL_ERROR_PROF_API_CONFLICT; }

场景三:未启动采集就创建时间戳

在 msprof_tx_manager.cpp 的MsprofTxManager::CreateStamp()中,管理器未初始化(isInit_为 false)时上报:

ACL_PROF_STAMP_PTR MsprofTxManager::CreateStamp() const { if (!isInit_) { MSPROF_LOGE("[CreateStamp]MsprofTxManager is not inited yet"); MSPROF_INPUT_ERROR( "EK0002", std::vector<std::string>({"intf1", "intf2"}), std::vector<std::string>({"aclprofStart", "aclprofCreateStamp"})); return nullptr; } return stampPool_->CreateStamp(); }

即:必须先aclprofStart,再aclprofCreateStamp。同理,prof_acl_mgr.cpp 中还有多处aclprofInit与各类采集接口之间的顺序校验,均以 EK0002 上报。

四、Profiling 接口的正确调用顺序

根据上述源码中的状态机约束,可以归纳出 Profiling 接口的标准生命周期为:

aclprofInit ──> aclprofStart ──> aclprofStop ──> aclprofFinalize │ └── 采集过程中可使用 aclprofCreateStamp 等打点接口

其中各接口的声明可见 acl_prof.h:

  • aclprofInit:初始化 Profiling 模块,传入结果目录与路径长度;
  • aclprofStart:按aclprofConfig配置启动采集;
  • aclprofStop:停止采集(停止后仍可通过再次aclprofStart续采);
  • aclprofFinalize:去初始化,释放 Profiling 资源;
  • aclprofWarmup:可选,在aclprofStart之前调用以预分配配置资源;
  • aclprofCreateStamp/aclprofDestroyStamp:在采集已启动后用于打点与销毁时间戳。

推荐的正确调用伪代码

#include "acl/acl_prof.h" // 1. 初始化 Profiling(必须先调用) const char *resultPath = "./prof_result"; aclprofInit(resultPath, strlen(resultPath)); // 2. (可选)在启动前预分配资源 aclprofConfig *cfg = ...; // 组装设备、数据类型、指标等配置 aclprofWarmup(cfg); // 3. 启动数据采集 aclprofStart(cfg); // 4. 采集过程中打点 void *stamp = aclprofCreateStamp(); // ... 记录自定义时间戳 ... // 5. 停止采集 aclprofStop(cfg); // 6. 去初始化 aclprofFinalize();

注意:上述接口的详细参数说明请参考仓库中的 02_initialization_and_deinitialization.md 与 19-01_data_profiling_apis.md。

五、排查与解决方法

根据文档给出的官方解法并结合源码校验逻辑,处理 EK0002 请按以下步骤进行:

  1. 读取报错中的两个接口名:确认intf1(应先调用)与intf2(当前非法调用)。报错语义是"先调用 A,再调用 B",即 B 的执行依赖 A 已成功完成。
  2. 检查应用调用顺序:对照标准生命周期核对代码。常见根因包括:
    • 忘记调用aclprofInit就直接aclprofStart
    • 多个线程/模块并发采集,其中一个线程抢先aclprofStopaclprofFinalize,导致另一线程后续接口调用落空;
    • aclprofWarmup放在了aclprofStart之后;
    • 程序退出清理阶段重复调用aclprofFinalize
  3. 补充前置接口调用:在intf2对应的接口调用之前,确保intf1对应的接口已经成功返回,并妥善处理其返回值(aclError)。
  4. 注意生命周期与线程安全:从源码看,msprof 对各接口的预检查在全局互斥锁(如 msprofiler_acl_api.cpp 中的g_profMutex)保护下执行,因此应用侧应避免在多线程中交叉调用aclprofStart/aclprofStop/aclprofFinalize等全局状态接口。
  5. 对照官方接口清单复核:完整的 Profiling 错误码索引见 Profiling-Errors.md,同族错误码还包括 EK0001(参数值非法)、EK0004(接口不支持)等,可一并参考以区分错误类型。

六、测试验证

仓库单元测试 prof_acl_core_utest.cpp 中通过桩件MsprofUtestStub::GetMsprofLastInputErrorCode()对 EK0002 的上报行为做了断言:

EXPECT_EQ("EK0002", MsprofUtestStub::GetMsprofLastInputErrorCode());

该测试文件在多处(如 L4514、L5225、L5440-L5457)针对不同的非法调用顺序场景校验了最终上报错误码是否为 EK0002,读者可以结合这些用例深入理解各触发分支的判定条件。

七、小结

EK0002(Invalid_Argument_API_Call_Sequence)是 msprof Profiling 组件在接口调用顺序违反生命周期约束时上报的参数类错误。其报文通过intf1intf2两个占位符明确告知"应先调用谁、当前调用了谁"。修复的核心思路非常简单:严格按照aclprofInit → aclprofStart → aclprofStop → aclprofFinalize的顺序调用,并确保aclprofWarmupaclprofCreateStamp等依赖型接口位于其前置接口之后。理解 error_code.json 中的模板定义与 msprof_error_manager.h 的上报机制,可以帮助你在遇到类似顺序类错误时快速定位问题代码。

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

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

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

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

立即咨询