尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

CANN opbase 算子精度模式详解:OpImplMode 枚举类与 OP_OPTION 使用指南

CANN opbase 算子精度模式详解:OpImplMode 枚举类与 OP_OPTION 使用指南 CANN opbase 算子精度模式详解OpImplMode 枚举类与 OP_OPTION 使用指南【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbaseCANN opbase 算子库通过OpImplMode枚举类统一表达算子的精度/性能实现模式配合OP_OPTION宏在算子调用侧声明期望的运行模式。本文围绕 OpImplMode 文档 展开结合仓库源码深入解析枚举取值、字符串映射、JSON 配置解析以及缓存 key 生成机制帮助算子开发者准确选择精度模式并在算子实现中正确使用。1. OpImplMode 枚举类定义OpImplMode定义于公共头文件 include/nnopbase/opdev/op_def.h位于op命名空间下是一个基于uint32_t的强类型枚举namespace op { enum class OpImplMode : uint32_t { // ImplMode support OR operation IMPL_MODE_DEFAULT 0x1, IMPL_MODE_HIGH_PERFORMANCE 0x2, IMPL_MODE_HIGH_PRECISION 0x4, IMPL_MODE_SUPER_PERFORMANCE 0x8, IMPL_MODE_SUPPORT_OUT_OF_BOUND_INDEX 0x10, IMPL_MODE_ENABLE_FLOAT32_EXECUTION 0x20, IMPL_MODE_ENABLE_HI_FLOAT32_EXECUTION 0x40, IMPL_MODE_KEEP_FP16 0x80, IMPL_MODE_RESERVED 0xFFFFFFFF }; } // namespace op源码注释明确说明这些取值支持按位或OR组合这决定了它天然适合用位图bitmap来记录算子支持的模式集合。1.1 各枚举值含义枚举值位值语义说明IMPL_MODE_DEFAULT0x1默认模式未显式指定精度模式时的兜底取值IMPL_MODE_HIGH_PERFORMANCE0x2高性能模式优先吞吐与执行速度IMPL_MODE_HIGH_PRECISION0x4高精度模式优先计算精度IMPL_MODE_SUPER_PERFORMANCE0x8超高性能模式IMPL_MODE_SUPPORT_OUT_OF_BOUND_INDEX0x10支持越界索引如越界 index/gather 场景IMPL_MODE_ENABLE_FLOAT32_EXECUTION0x20使能 FP32 执行路径IMPL_MODE_ENABLE_HI_FLOAT32_EXECUTION0x40使能 HI FP32高精度 FP32执行路径IMPL_MODE_KEEP_FP160x80保持 FP16 计算不做精度提升IMPL_MODE_RESERVED0xFFFFFFFF保留值同时作为“未知/非法模式”的哨兵值其中IMPL_MODE_RESERVED在字符串解析失败时被用作兜底返回值见下文ToOpImplMode实现0xFFFFFFFF保证了它能与所有合法位值区分开。1.2 与 OpExecMode 的区分在同一个头文件中还定义了OpExecMode枚举include/nnopbase/opdev/op_def.henum class OpExecMode : uint32_t { OP_EXEC_MODE_DEFAULT 0, OP_EXEC_MODE_HF32 1, OP_EXEC_MODE_RESERVED 0xFFFFFFFF };两者定位不同OpImplMode描述算子实现的精度/性能模式可用于多 kernel 二进制的选择而OpExecMode描述执行级的模式开关如 HF32 执行模式。编写算子时需要注意区分不要混用。2. 字符串与枚举的双向映射OpImplMode需要与算子二进制描述文件JSON中的字符串配置互转该逻辑实现在 src/nnopbase/composite_op/utils/op_def.cpp 中通过两张静态映射表完成。2.1 字符串 → 枚举ToOpImplModestatic const std::mapstd::string, OpImplMode STRING_TO_OP_IMPL_MODE_MAP { {high_performance, OpImplMode::IMPL_MODE_HIGH_PERFORMANCE}, {high_precision, OpImplMode::IMPL_MODE_HIGH_PRECISION}, {super_performance, OpImplMode::IMPL_MODE_SUPER_PERFORMANCE}, {support_out_of_bound_index, OpImplMode::IMPL_MODE_SUPPORT_OUT_OF_BOUND_INDEX}, {enable_float32_execution, OpImplMode::IMPL_MODE_ENABLE_FLOAT32_EXECUTION}, {enable_hi_float32_execution, OpImplMode::IMPL_MODE_ENABLE_HI_FLOAT32_EXECUTION}, {keep_fp16, OpImplMode::IMPL_MODE_KEEP_FP16}, {default, OpImplMode::IMPL_MODE_DEFAULT}};ToOpImplMode(const std::string)查表转换若未命中打印告警日志Unknown OpImplMode: %s.并返回IMPL_MODE_RESERVED。因此 JSON 中写错模式名会静默退化为保留值需注意日志排查。2.2 枚举 → 字符串ToString / ImplModeToStringstatic const std::mapOpImplMode, ge::AscendString OP_IMPL_MODE_TO_STRING_MAP { {OpImplMode::IMPL_MODE_HIGH_PERFORMANCE, ge::AscendString(high_performance)}, {OpImplMode::IMPL_MODE_HIGH_PRECISION, ge::AscendString(high_precision)}, {OpImplMode::IMPL_MODE_SUPER_PERFORMANCE, ge::AscendString(super_performance)}, {OpImplMode::IMPL_MODE_SUPPORT_OUT_OF_BOUND_INDEX, ge::AscendString(support_out_of_bound_index)}, {OpImplMode::IMPL_MODE_ENABLE_FLOAT32_EXECUTION, ge::AscendString(enable_float32_execution)}, {OpImplMode::IMPL_MODE_ENABLE_HI_FLOAT32_EXECUTION, ge::AscendString(enable_hi_float32_execution)}, {OpImplMode::IMPL_MODE_KEEP_FP16, ge::AscendString(keep_fp16)}, {OpImplMode::IMPL_MODE_DEFAULT, ge::AscendString(default)}, {OpImplMode::IMPL_MODE_RESERVED, ge::AscendString(unknown)}};ToString返回ge::AscendStringImplModeToString返回其常量引用查不到时统一回落到unknown。IMPL_MODE_RESERVED对应字符串为unknown是解析失败后的统一显示形式。2.3 位索引转换ToIndex / ToIndexCharopbase 内部用单字符表示模式以压缩缓存 key相关工具函数定义在 src/nnopbase/composite_op/utils/op_def.cppint64_t ToIndex(OpImplMode implMode) { return ffs(static_castint64_t(implMode)) - 1; } wchar_t ToIndexChar(OpImplMode implMode) { return static_castwchar_t(0) static_castwchar_t(ffs(static_castint64_t(implMode)) - 1); }ffsfind first set返回最低置 1 位的位置。由于各模式取值均为 2 的幂ToIndex得到 07 的索引ToIndexChar将其转为字符07用于拼接 kernel 缓存 key。3. OP_OPTION 宏与 OpOption 参数类型3.1 宏定义与用法在文档配套的 OP_OPTION 说明 中该宏用于“封装算子的精度模式”调用示例如下// 封装算子的精度模式为高精度模式 OP_OPTION(IMPL_MODE_HIGH_PRECISION);宏本身定义于 include/nnopbase/opdev/op_arg_def.h#define OP_OPTION(x...) op::OpOption(std::make_tuple(x))可见OP_OPTION是op::OpOption(...)构造函数的语法糖参数数量可变x...支持多个模式位值与OP_INPUT、OP_ATTR等宏同族见 include/nnopbase/opdev/op_arg_def.h。3.2 底层参数类型 OpOptionOpOption是 opbase 参数系统中的一种 OpArg 类型注册编号为OP_OPTION_ARG 5include/nnopbase/opdev/op_arg_def.h并通过DEFINE_OP_ARG(OpOption, OP_OPTION_ARG)声明include/nnopbase/opdev/op_arg_def.h。OpImplMode作为参数值传入时通过OpArgValue的构造函数被存入参数数据区OpArgValue(op::OpImplMode value) { data.value static_castuint64_t(value); }见 include/nnopbase/opdev/op_arg_def.h并在追加参数时由重载的AppendOpArg处理include/nnopbase/opdev/op_arg_def.h。3.3 运行期上下文SetOpImplModeCtx算子执行前opbase 从OP_OPTION参数中读出模式并写入线程局部 Launch 上下文inline void SetOpImplModeCtx(OpArgList optionArg) { internal::GetLauncherCtx().SetImplMode(OpImplMode::IMPL_MODE_DEFAULT); // ... 遍历 optionArg将每个 arg-value 强转为 OpImplMode 后 SetImplMode }见 src/nnopbase/composite_op/aclnn_engine/launcher_ctx.h。LauncherCtx默认模式为IMPL_MODE_DEFAULTlauncher_ctx.h并提供SetImplMode/GetImplMode存取。该上下文在复合算子composite op执行路径与独立算子individual op路径中都会被消费复合算子op::internal::SetOpImplModeCtx(*args-GetOpArg(op::OP_OPTION_ARG))op_executor.cpp独立算子op::internal::SetOpImplModeCtx(*args-GetOpArg(op::OP_OPTION_ARG))kernel_launcher.h4. 模式在 JSON 描述文件中的配置与解析每个算子的 kernel 二进制对应一个 JSON 描述文件其中可包含implMode字段用于声明该 kernel 支持哪种精度模式。4.1 解析入口与特殊取值ParseImplModeByJson实现在 op_kernel.cpp核心逻辑若implMode取值为high_performance,high_precision,enable_float_32_execution,enable_hi_float_32_execution常量ALL_PRECISION_MODEop_kernel.cpp表示支持全部四种主流模式直接展开为对应枚举集合否则调用ToOpImplMode单个转换解析失败返回IMPL_MODE_RESERVED时告警并默认回落为高精度模式JSON 中缺失implMode字段时同样告警并回落为IMPL_MODE_HIGH_PRECISION。4.2 模式与缓存 key 的绑定OpKernel::ParseContext将 implMode 编入 kernel 匹配 keyop_kernel.cpp优先从 JSON 文件路径中识别high_performance/high_precision/support_out_of_bound_index子串直接确定模式否则走ParseImplModeByJson每个 implMode 以ToIndexChar字符形式写入key形如deterministic/模式索引/...并通过AppendImplModeBm累加到implModeBm_位图op_kernel.cpp。4.3 位图驱动的模式支持判定OpKernel类用uint64_t implModeBm_记录算子支持的模式集合op_kernel.hinline void AppendImplModeBm(OpImplMode implMode) { implModeBm_ | static_castuint32_t(implMode); } inline bool IsSupportImplMode(OpImplMode implMode) const { return implModeBm_ static_castuint32_t(implMode); }这正对应了文档中“ImplMode support OR operation”的注释——多个模式位通过|聚合判断是否支持。4.4 运行期模式选择GetCurrentImplMode最终选择哪个 kernel 由GetCurrentImplMode决定op_kernel.h读取用户通过OP_OPTION传入的模式GetLauncherCtx().GetImplMode()若用户模式非IMPL_MODE_DEFAULT且算子支持该模式IsSupportImplMode直接采用否则按算子能力回退支持高精度则用IMPL_MODE_HIGH_PRECISION否则用IMPL_MODE_HIGH_PERFORMANCE。该模式值随后被写入 kernel 缓存 keyToIndex/ToIndexChar见 op_kernel.h 与 op_kernel.h保证不同精度模式对应不同 kernel 缓存项。此外OpKernelBin::ParseStaticImplMode还会从静态 JSON 的supportInfo中解析implMode字段op_kernel_bin.cpp。5. 实测参考与进阶阅读单元测试 tests/nnopbase/ut/composite_op/test_op_def.cpp 覆盖了OpImplMode相关定义的使用test_op_arg_def.cpp 与 test_op_kernel.cpp 可辅助理解OP_OPTION参数与 kernel 匹配逻辑。常见问题定位JSON 中implMode写错或缺失时源码会打印Cannot find impl mode in json或Invalid op impl mode告警并回退为高精度模式排查时可先从这两类日志入手。若需封装多模式算子可参考仓库内 built-in 算子 JSON如 tests/nnopbase/mock/built-in/op_impl 中的描述文件了解implMode字段的书写格式配合 op_kernel.cpp 的解析规则使用。总结OpImplMode是 CANN opbase 中算子精度/性能模式的事实标准调用侧通过OP_OPTION(IMPL_MODE_XXX)声明期望模式描述侧通过 JSON 的implMode字段声明 kernel 能力运行时由GetCurrentImplMode综合用户意图与算子能力完成选择最终以字符索引形式进入缓存 key 实现模式隔离。理解从位值定义、字符串映射到缓存 key 生成的完整链路是编写多模式算子和排查精度模式问题的前提。【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表