ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

OP_OPTION 宏详解:CANN opbase 中算子精度模式的封装与 OpImplMode 使用指南

OP_OPTION 宏详解:CANN opbase 中算子精度模式的封装与 OpImplMode 使用指南 OP_OPTION 宏详解CANN opbase 中算子精度模式的封装与 OpImplMode 使用指南【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase导读OP_OPTION是 CANN opbase 算子库中用于**封装算子精度模式ImplMode**的声明式宏。在开发基于 op_arg_def.h 的参数定义体系时开发者通过OP_OPTION(x...)将 OpImplMode 枚举值作为一类特殊的算子选项注入参数上下文供底层调度框架在启动 kernel 时解析并作用于精度计算策略。读完本文你将掌握OP_OPTION的宏原型、参数取值含OpImplMode全量枚举、底层实现原理、组合使用方式以及它在 kernel 启动链路中的实际流转路径。OP_OPTION 宏的定位与功能在 opbase 的参数定义体系中一个算子的入参通常由若干参数组构成每组参数通过一个声明式宏来标记其角色。与 OP_INPUT、OP_OUTPUT、OP_ATTR 等宏分别声明输入、输出与属性不同OP_OPTION的职责非常单一用于封装算子的精度模式。它本身不承载张量数据也不属于计算属性而是描述这个算子实例期望以何种精度/性能策略执行属于影响 kernel 分派与执行选项的控制信息。从源码的OpArgDef枚举op_arg_def.h可以看到OP_OPTION_ARG 5在参数分类中被独立编为一类enum OpArgDef { OP_INPUT_ARG 0, OP_OUTPUT_ARG 1, OP_ATTR_ARG 2, OP_WORKSPACE_ARG 3, OP_OUTSHAPE_ARG 4, OP_OPTION_ARG 5, // OP_OPTION 宏对应的参数类型 OP_EXEC_MODE_ARG 6, OP_MEMSET_ARG 7, OP_EMPTY_ARG 8, OP_ARG_DEF_BUTT 9, };在算子参数打包Launcher 参数列表阶段携带OP_OPTION的参数组会以OP_OPTION_ARG的身份进入OpArgContext并在运行期被单独取出设置到算子实现模式上下文SetOpImplModeCtx中。宏原型与参数说明OP_OPTION的宏原型声明为可变参数形式OP_OPTION(x...)参数说明如下参数输入/输出说明x...输入指定算子精度模式具体取值参见 OpImplMode。x...采用 C/C 变参写法即允许在括号内传入一个或多个精度模式取值。由于OpImplMode枚举设计上支持按位或OR组合源码注释明确标注 ImplMode support OR operationOP_OPTION的变参形式天然适合传入组合后的模式值例如同时声明高精度与保持 FP16等多个约束。精度模式取值OpImplMode 全量枚举OP_OPTION的参数取值类型为OpImplMode枚举类其完整定义位于 op_def.henum 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 };各枚举值的用途说明如下枚举值位掩码语义IMPL_MODE_DEFAULT0x1默认模式不附加任何特殊精度/性能策略IMPL_MODE_HIGH_PERFORMANCE0x2高性能模式执行策略偏向计算性能IMPL_MODE_HIGH_PRECISION0x4高精度模式执行策略偏向计算精度IMPL_MODE_SUPER_PERFORMANCE0x8超高性能模式IMPL_MODE_SUPPORT_OUT_OF_BOUND_INDEX0x10支持越界索引的处理IMPL_MODE_ENABLE_FLOAT32_EXECUTION0x20使能 Float32 执行IMPL_MODE_ENABLE_HI_FLOAT32_EXECUTION0x40使能 HI Float32高精度 Float32执行IMPL_MODE_KEEP_FP160x80保持 FP16 计算IMPL_MODE_RESERVED0xFFFFFFFF保留位全 1通常用于异常兜底或占位各枚举值均为 2 的幂IMPL_MODE_RESERVED除外这种位掩码布局保证了多个模式可以通过|按位或组合为单一uint32_t值传入。与OpImplMode配套op_def.h 还声明了以下辅助转换接口便于在字符串与枚举、索引之间互转OpImplMode ToOpImplMode(const std::string implModeStr); // 字符串 - 枚举 ge::AscendString ToString(OpImplMode implMode); // 枚举 - 字符串 const ge::AscendString ImplModeToString(OpImplMode implMode); int64_t ToIndex(OpImplMode implMode); // 枚举 - 索引 wchar_t ToIndexChar(OpImplMode implMode);宏的源码实现原理OP_OPTION并非空壳宏其展开结果与其他参数宏一致定义于 op_arg_def.h#define OP_INPUT(x...) op::OpInput(std::make_tuple(x)) #define OP_OUTPUT(x...) op::OpOutput(std::make_tuple(x)) #define OP_ATTR(x...) op::OpAttr(std::make_tuple(x)) #define OP_WORKSPACE(x...) op::OpWorkspace(std::make_tuple(x)) #define OP_OUTSHAPE(x...) op::OpOutshape(std::tupleaclTensor*, uint64_t(x)) #define OP_OPTION(x...) op::OpOption(std::make_tuple(x)) // OP_OPTION 宏定义 #define OP_EMPTY_ARG op::EMPTY_OP_ARG #define OP_MODE(x...) op::OpMode(std::make_tuple(x))展开后实际构造的是op::OpOption模板对象。OpOption由DEFINE_OP_ARG宏批量生成op_arg_def.h#define DEFINE_OP_ARG(op_arg, op_type) \ template typename... T \ struct op_arg : public OpArgBaseT... { \ static constexpr int value op_type; \ using type op_arg; \ op_arg(std::tupleT... arg) : OpArgBaseT...(std::forwardstd::tupleT...(arg)) {} \ op_arg(const std::tupleT... arg) : OpArgBaseT...(arg) {} \ op_arg() {} \ constexpr int Type() const { return value; } \ }; DEFINE_OP_ARG(OpOption, OP_OPTION_ARG) // OpOption 的静态 value 即为 OP_OPTION_ARG由此可以梳理出OP_OPTION的三层实现逻辑包装std::make_tuple(x)把传入的精度模式值打包进std::tuple交给OpOption基类OpArgBaseT...持有arg_成员见 op_arg_def.h。标识OpOption::value OP_OPTION_ARG(5)用于在参数集合中按类型区分。落地当这些参数对象进入OpArgContextInitop_arg_def.h时VisitByNoReturn会遍历 tuple 中每个元素并调用AppendOpArg重载其中针对op::OpImplMode类型有专门的重载op_arg_def.h将参数类型标记为OPARG_IMPLMODE并写入OpArg数组最终归类到ctx.argLists[OP_OPTION_ARG]。OpArgType枚举中也存在独立的OPARG_IMPLMODE类型op_arg_def.h与输入张量、标量、字符串等类型并列进一步印证了精度模式在参数类型体系中被当作一等公民处理。调用示例原文档给出的标准用法是封装高精度模式// 封装算子的精度模式为高精度模式 OP_OPTION(IMPL_MODE_HIGH_PRECISION);结合变参与按位或特性还可以在同一算子声明中组合多个模式例如同时声明高精度并保持 FP16// 组合多个精度模式 OP_OPTION(IMPL_MODE_HIGH_PRECISION | IMPL_MODE_KEEP_FP16);模式参数在启动链路中的流转OP_OPTION声明的精度模式并不会停留在参数声明阶段而是会随执行流程被底层框架实际读取并应用。从源码可以梳理出两条核心流转路径kernel_launcher 路径在 kernel_launcher.h 中通过op::internal::SetOpImplModeCtx(*args_-GetOpArg(op::OP_OPTION_ARG))从OpArgContext中取出OP_OPTION_ARG对应的参数组并设置算子实现模式上下文。op_executor 路径在 op_executor.cpp 中算子执行器同样执行op::internal::SetOpImplModeCtx(*args-GetOpArg(op::OP_OPTION_ARG))将精度模式注入执行上下文。此外kernel_arg.cpp 中给出了OP_OPTION_ARG的参数名映射option并在OpArgType序列化/校验逻辑中识别OPARG_IMPLMODE类型见 kernel_arg.cpp。也就是说OP_OPTION声明的模式信息会参与到 kernel 参数的序列化、缓存 key 生成与校验过程中最终影响 kernel 的调度与执行策略。约束说明原文档对该宏的约束说明为无即OP_OPTION在使用上不施加额外的格式或组合限制。不过结合源码实现仍可总结出两点使用注意参数取值须为OpImplMode枚举传入的值最终会经AppendOpArg的OpImplMode重载匹配并标记为OPARG_IMPLMODE因此应传入 OpImplMode 定义中的枚举值或其按位或组合。一个算子通常只需声明一组OP_OPTIONOpArgContextInit在首次遇到某类参数时记录起始指针同类参数会累计countop_arg_def.h将多个模式合并到一次OP_OPTION(...)调用中是更清晰、可预期的写法。测试验证OP_OPTION 的打包行为仓库单元测试 test_op_arg_def.cpp 直接验证了OP_OPTION的打包行为TEST_F(OpArgDefUt, OpArgType_other) { op::OpImplMode mode op::OpImplMode::IMPL_MODE_HIGH_PRECISION; auto workspace OP_WORKSPACE(std::move(tensor)); auto ctx1 op::MakeOpArgContext(workspace, OP_OPTION(mode)); EXPECT_EQ(ctx1-ContainsOpArgType(op::OpArgDef::OP_OPTION_ARG), true); op::OpArgList option *ctx1-GetOpArg(op::OpArgDef::OP_OPTION_ARG); EXPECT_EQ(option.count, 1); EXPECT_EQ(option.args[0].type, op::OpArgType::OPARG_IMPLMODE); op::DestroyOpArgContext(ctx1); }该用例使用OP_OPTION(IMPL_MODE_HIGH_PRECISION)构造参数上下文断言OP_OPTION_ARG类型确实被记录、参数组数量为 1、且实际落地为OPARG_IMPLMODE类型。这从测试层面印证了本文前述的宏实现与参数类型映射关系tests/nnopbase/ut/composite_op/test_op_arg_def.cpp中另有多处如 第 372 行继续使用OP_OPTION(implMode)覆盖相关场景。此外test_kernel_launch_newrts.cpp 与 test_op_executor.cpp 也引用了OP_OPTION覆盖其在 kernel 启动与执行器链路中的实际使用。小结OP_OPTION是 opbase 参数定义体系中描述算子执行选项的统一入口它以OpOption/OP_OPTION_ARG/OPARG_IMPLMODE三层结构宏 → 参数容器 → 运行时类型完成精度模式的声明、打包与流转并最终通过SetOpImplModeCtx在 kernel 启动阶段生效。掌握其原型、OpImplMode取值与按位组合能力是在自定义算子中声明精度/性能策略的关键一步。【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表