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

资讯详情

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

CANN opbase 算子参数占位宏 OP_EMPTY_ARG 详解:空参数占位与参数列表构建机制

CANN opbase 算子参数占位宏 OP_EMPTY_ARG 详解:空参数占位与参数列表构建机制 CANN opbase 算子参数占位宏 OP_EMPTY_ARG 详解空参数占位与参数列表构建机制【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbaseOP_EMPTY_ARG 是 CANN opbase 算子开发框架opdev中用于表示空参数的占位宏常与 ADD_TO_LAUNCHER_LIST_AICORE、INFER_SHAPE 等任务创建宏配合使用在算子参数列表中占位一个空的输入或输出。本文以官方接口文档 OP_EMPTY_ARG.md 为骨架结合 op_arg_def.h、kernel_arg.cpp 等源码讲清该宏的定义、工作原理与实战用法帮助开发者理解并正确使用这一参数占位机制。宏功能表示一个空参数OP_EMPTY_ARG 的核心功能是表示一个空的参数。在 aclnn 二阶段接口的算子执行任务创建过程中算子的输入、输出、属性等参数通过 OP_INPUT、OP_OUTPUT、OP_ATTR 等宏组织成参数列表op_args...而 OP_EMPTY_ARG 作为其中的一个特殊占位项不携带任何真实数据仅用于在参数序列中占据一个位置或作为空输入/空输出的占位符。根据 1_opdev_api_introduction.md 中的说明其典型应用场景是ADD_TO_LAUNCHER_LIST_AICORE 中用于占位一个空的输入或输出。也就是说当某个算子的参数列表中存在空缺例如可选的输入/输出当前为空时可以用 OP_EMPTY_ARG 显式占位保证参数序列的完整性。宏原型与定义链OP_EMPTY_ARG从形式上看OP_EMPTY_ARG 是一个对象形式的宏展开为某个具体对象实例而非函数式宏无需像 OP_INPUT(x...) 那样携带参数。其完整定义链位于 op_arg_def.h// 第 32 行枚举定义 OP_EMPTY_ARG 8, // 第 155 行通过 DEFINE_OP_ARG 生成 OpEmpty 结构体 DEFINE_OP_ARG(OpEmpty, OP_EMPTY_ARG) // 第 157 行生成空参数对象 inline const auto EMPTY_OP_ARG OpEmpty(); // 第 634 行宏定义 #define OP_EMPTY_ARG op::EMPTY_OP_ARG可以看到OP_EMPTY_ARG宏最终展开为op::EMPTY_OP_ARG即OpEmpty类型的一个实例。OpEmpty由DEFINE_OP_ARG(OpEmpty, OP_EMPTY_ARG)生成继承自OpArgBaseT...内部通过static constexpr int value OP_EMPTY_ARG;值为 8标记自身参数类型。参数说明无OP_EMPTY_ARG 不带任何参数这一点由宏形态天然决定它不是OP_EMPTY_ARG(x...)形式而是直接展开为预置对象无需开发者传参。这一点与 OP_INPUT、OP_OUTPUT 等需要携带 tensor 参数的宏有本质区别。约束说明无附使用前提官方文档声明 OP_EMPTY_ARG 无额外约束。但从框架实际使用方式看需要注意以下几点使用前提仅用于参数列表op_args...场景OP_EMPTY_ARG 的语义是参数列表中的占位项一般出现在 ADD_TO_LAUNCHER_LIST_AICORE 与 INFER_SHAPE 的 op_args... 中不要将其单独当作真实参数使用。顺序敏感性参数列表是按位置解析的OP_EMPTY_ARG 在列表中占据的位置对应算子签名中的空参数位插入时应与实际算子接口的参数顺序保持一致。与 nullptr 占位的区别在 INFER_SHAPE 的示例中可以看到空输入也可以直接用nullptr表示如OP_INPUT(x1, x2, bias, nullptr)OP_EMPTY_ARG 则用于在宏参数层级整体占位一个空的 OP_* 参数项两者使用层面不同。调用示例在任务创建宏中的占位官方文档给出的最小示例OP_EMPTY_ARG将该宏放入参数列表后即构成完整的占位用法。例如在 ADD_TO_LAUNCHER_LIST_AICORE 的参数列表中// 创建 add 算子的执行任务self 和 other 为输入addOut 为输出 ADD_TO_LAUNCHER_LIST_AICORE(Add, OP_INPUT(self, other), OP_OUTPUT(addOut));该宏的关联接口完整清单见官方文档约束说明OP_INPUT(x...) OP_OUTPUT(x...) OP_ATTR(x...) OP_WORKSPACE(x...) OP_OUTSHAPE(x...) OP_OPTION(x...) OP_EMPTY_ARG OP_MODE(x...)其中 OP_EMPTY_ARG 是唯一一个不需要携带参数即可直接写入参数列表的项。源码级原理OP_EMPTY_ARG 在参数上下文中的处理机制要理解 OP_EMPTY_ARG 为什么什么都不做却必须存在需要看参数上下文的构建过程。参数列表最终会通过GetOpArgContext(op_args...)生成OpArgContext见 make_op_executor.h 中 ADD_TO_LAUNCHER_LIST_AICORE 的实现#define ADD_TO_LAUNCHER_LIST_AICORE(KERNEL_NAME, op_args...) \ ({ \ aclnnStatus addToLaunchRet; \ do { \ op::OpArgContext* opArgCtx GetOpArgContext(op_args); \ addToLaunchRet CreatAiCoreKernelLauncher(#KERNEL_NAME, \ KERNEL_NAME##OpTypeId(), executor, opArgCtx); \ } while (0); \ addToLaunchRet; \ })参数解析核心是OpArgContextInitop_arg_def.h 第 563 行起其对每个参数项按类型分发处理int opArgType t.value; if (opArgType OP_INPUT_ARG || opArgType OP_EXEC_MODE_ARG) { // 超出 [OP_INPUT_ARG0, OP_EXEC_MODE_ARG6] 范围直接跳过 return OpArgContextInit(ctx, currArg, ts...); }OP_EMPTY_ARG 的 value 为 8大于OP_EXEC_MODE_ARG6因此会被跳过、不写入任何 OpArg。这从实现层面印证了其空参数占位、不产生实际参数的语义它既不增加参数个数也不占用 OpArg 存储空间仅作为编译期类型信息参与参数列表组织。此外kernel_arg.cpp 第 5979 行的OpArgTypeStr将各参数类型映射为字符串名称OP_EMPTY_ARG 对应emptymemset, /* OP_MEMSET_ARG */ empty, /* OP_EMPTY_ARG */ unknown /* OP_ARG_DEF_BUTT */这说明 OP_EMPTY_ARG 在参数类型体系中拥有独立的类型编号8是参数类别枚举OpArgDef的正式成员之一与其并列的还包括输入0、输出1、属性2、workspace3、outshape4、option5、执行模式6与 memset7。框架内的实际调用场景OP_EMPTY_ARG 并非纯文档概念在框架内部有真实调用。以复合算子引擎中的 MemSet 实现为例op_kernel.hOpArgContext tempCtx; OpArg opArg; OpArg* tempArg opArg; std::vectorint32_t tensorOffset; OpArgContextInit(tempCtx, tempArg, workspace, OP_EMPTY_ARG);这里OP_EMPTY_ARG作为参数列表的收尾占位项传入OpArgContextInit确保上下文构建流程完整结束。可以推断在参数个数不固定的泛型处理流程中OP_EMPTY_ARG 起到结束标记/占位收尾的作用避免模板展开时出现空参数列表的边界问题。相关宏速查宏功能是否带参OP_INPUT声明算子输入参数是OP_OUTPUT声明算子输出参数是OP_ATTR声明算子属性参数是OP_WORKSPACE声明 workspace 参数是OP_OUTSHAPE声明输出 shape 参数是OP_OPTION声明 option 参数是OP_MODE声明执行模式参数是OP_EMPTY_ARG占位一个空的输入或输出否总结OP_EMPTY_ARG 是 CANN opbase 算子参数体系中一个看似简单、实则关键的空参数占位宏它以枚举值 8 参与参数类型体系以op::EMPTY_OP_ARG对象形态出现在参数列表中在 ADD_TO_LAUNCHER_LIST_AICORE、INFER_SHAPE 等任务创建宏中占位空的输入/输出并作为参数列表的收尾占位项参与OpArgContextInit的上下文构建。理解它的定义链op_arg_def.h与处理机制有助于开发者正确组织算子参数列表避免在泛型参数展开过程中出现空列表等边界问题。【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表