CANN opbase 算子日志接口 OP_LOGI 使用指南:INFO 级别日志打印的原理与实战
2026/9/18 6:12:40 网站建设 项目流程

CANN opbase 算子日志接口 OP_LOGI 使用指南:INFO 级别日志打印的原理与实战

【免费下载链接】opbase本项目是CANN算子库的基础框架库,为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase

导读

OP_LOGI是 CANN opbase(算子库基础框架库)为算子开发者提供的 INFO 级别日志打印宏,用于在算子实现、tiling 逻辑或公共工具函数中输出关键流程信息,配合日志级别过滤机制实现可观测性。本文以 OP_LOGI.md 为骨架,结合 op_log.h 的宏定义与src/nnopbase下的底层实现,讲解该接口的函数原型、参数语义、调用示例、日志级别体系与底层调用链,帮助你正确地在算子代码中埋点打印 INFO 日志并理解其输出行为。

功能说明

OP_LOGI用于打印算子 INFO 级别日志。INFO 级别日志适合记录算子执行过程中的关键状态信息(例如输入输出的 shape、分配的设备扩展信息大小、节点 kernelId 更新等),用于在正常运行流程中提供可追踪的运行轨迹,而不会像 DEBUG 级别日志那样频繁输出、影响性能。

从实现上看,OP_LOGI在 op_log.h 中被定义为宏,非 Android 平台下展开为:

#define OP_LOGI(...) D_OP_LOGI(GetOpName().c_str(), __VA_ARGS__)

其中D_OP_LOGI进一步调用OpLogSub(OP_ID, OP_LOG_INFO, opname, fmt, ...)OP_ID为 63(NNOP 子模块),OP_LOG_INFO的值为 1。可见OP_LOGI本质是"NNOP 子模块 + INFO 级别"的日志入口。

函数原型

OP_LOGI(opName, ...)

OP_LOGI是可变参数宏:第一个参数opName用于标识日志主体,其余参数为 printf 风格的可变参数(格式化字符串与对应变量),遵循 C 标准库printf的格式化语法(如%d%ld%s等)。

参数说明

参数名输入/输出说明
opName输入待打印对象,可以是算子名,表示打印算子信息;也可以是某个函数名,表示打印函数内相关信息。支持const char*std::string类型。

关于opName的进一步说明:

  • 传算子名时,日志会带上算子维度的上下文信息,便于在整条执行链路中定位到具体算子;
  • 传函数名时,日志表示该函数内部的信息,例如广播维度检查等工具函数;
  • 由于宏内部会调用GetOpName()获取当前算子上下文(见 op_log.h),实际输出中会自动拼接OpName:[...]前缀,opName本身会被作为日志格式前缀的一部分参与输出。

返回值说明

无返回值。

约束说明

  • 无参数类型、调用位置的硬性约束,可在算子 host 侧实现、tiling 函数或公共工具函数中自由使用;
  • 需包含日志头文件opdev/op_log.h(通过#include "opdev/op_log.h"引入);
  • 日志是否真正输出受运行时日志级别控制:只有当前配置的日志级别允许 INFO(即级别过滤通过)时才会落盘,详见下文"级别过滤与底层调用链"。

调用示例

以下示例来自 OP_LOGI.md,展示在广播维度检查函数中使用OP_LOGI打印无法广播的维度信息,仅供参考,不支持直接拷贝运行:

bool BroadcastDim(int64_t& dim1, const int64_t dim2) { if ((dim1 != 1) && (dim2 != 1)) { OP_LOGI("BroadcastDim", "%ld and %ld cannot broadcast!", dim1, dim2); return false; } return true; }

在该示例中:

  • "BroadcastDim"作为opName,标识日志来自BroadcastDim函数;
  • 格式化串"%ld and %ld cannot broadcast!"dim1dim2两个int64_t变量一一对应,输出类似BroadcastDim: 1024 and 512 cannot broadcast!(实际还会带模块、线程、行列号等前缀,见下节)。

日志级别体系与同级接口

OP_LOGI属于 opbase 日志宏家族中的 INFO 级别一员。在 op_log.h 中定义了完整的级别常量:

#define OP_LOG_DEBUG 0 #define OP_LOG_INFO 1 #define OP_LOG_WARN 2 #define OP_LOG_ERROR 3 #define OP_LOG_EVENT 0x10

对应关系如下:

级别值适用场景
OP_LOGD0(DEBUG)调试期详细过程信息
OP_LOGI1(INFO)正常运行的关键状态信息
OP_LOGW2(WARN)可疑但可继续执行的情况
OP_LOGE3(ERROR)错误信息,且会联动错误码上报(见 op_log.h)
OP_EVENT0x10(EVENT)事件类日志

日志宏完整清单见 log.md。选择建议:能用OP_LOGI表达"正常流程中的关键节点"就不要降级用OP_LOGD刷屏,也不要用OP_LOGE打正常提示;OP_LOGE会额外触发错误码上报(REPORT_ERROR_MESSAGE),成本更高,仅用于真正的错误场景。

底层实现:级别过滤与调用链

OP_LOGI的底层链路在 op_error_manager.cpp 与 op_log.h 中可以看到完整实现:

#define DOplogSub(moduleId, submodule, level, fmt, ...) \ do { \ if (unlikely(CheckLogLevelInner(moduleId, level) == 1)) { \ DlogRecordInner(moduleId, level, "[%s:%d][%s]" fmt, \ GetFileName(__FILE__), __LINE__, submodule, \ ##__VA_ARGS__); \ } \ } while (false)

关键点如下:

  1. 先查级别再打印DOplogSub首先调用CheckLogLevelInner(moduleId, level)判断当前模块(NNOP/OP_ID=63)在该级别下是否允许输出,只有允许时才继续拼接日志并调用DlogRecordInner。这样避免了在日志级别被过滤时仍然执行耗时的格式化操作,属于性能优化设计(头文件注释明确说明"call CheckLogLevelInner in advance to optimize performance")。
  2. 自动补充上下文:日志会携带[文件名:行号][子模块]前缀,其中文件名通过GetFileName(__FILE__)只保留 basename,行号为宏展开处__LINE__opName前缀则由GetOpName()从算子执行上下文动态获取(见 op_log.h,其实现op::internal::GetLogApiInfo()位于 op_dfx.cpp)。
  3. 最终落盘DlogRecordInner封装DlogVaList(moduleId, level, fmt, args)将日志交给 dlog 框架(见 op_error_manager.cpp)。

此外,在单元测试/系统测试构建(NNOPBASE_UT/NNOPBASE_ST)下,OP_LOGI会被重定向为OP_TEST_LOG,直接通过fprintf(stdout, ...)输出并带线程号(OpLog::GetTid(),基于syscall(__NR_gettid)获取,见 op_log.h),便于测试工程直接观察日志。相关测试可参考 test_log.cpp,其中对OP_LOGI的实际调用验证了该宏在测试环境下的可用性。

在 AICPU 场景下的对应实现

如果算子运行在 AICPU 侧,日志输出走的是另一套自定义日志通道。aicpu命名空间提供了DumpCustomLogCustLogInfo等接口(见 cust_op_log.cc 与 cust_dlog_record.cc),其 INFO 级别(DLOG_INFO)日志最终通过CustCpuKernelUtils::CustLogInfo写入工作空间缓冲区,并自动补齐[INFO] CUST_AICPU_OP [时间戳]前缀与换行符,单条消息长度上限为 1024 字节(见 cust_op_log.cc)。该机制与 host 侧的OP_LOGI相互独立,开发者可按运行环境选择对应打印通道。

使用建议与排查要点

  • 格式化串与参数必须匹配OP_LOGI的参数语义与printf一致,%ld对应int64_t%s对应const char*,类型不匹配可能导致日志内容错乱;
  • 日志输出受环境级别控制:若设置日志级别高于 INFO(例如 ERROR),OP_LOGI会被CheckLogLevelInner过滤而不输出,排查时可通过调整日志级别或确认NNOP子模块级别配置来验证;
  • 测试构建输出到 stdout:在NNOPBASE_UT/NNOPBASE_ST构建下日志直接打印到终端,便于调试;正式构建下则走 dlog 框架统一落盘;
  • INFO 日志不宜过度埋点:INFO 介于 DEBUG 与 WARN 之间,建议只记录对问题定位有直接价值的关键路径信息,避免高频打印影响性能。

相关文档

  • 日志宏总览:log.md
  • 警告级别日志:OP_LOGW.md
  • 调试级别日志:OP_LOGD.md
  • 错误级别日志:OP_LOGE.md
  • 日志宏头文件定义:op_log.h
  • 底层日志实现:op_error_manager.cpp

【免费下载链接】opbase本项目是CANN算子库的基础框架库,为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase

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

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

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

立即咨询