一文搞懂 HIVM 的 hir.custom_macro:跨 Pipe 宏操作完整解析与速查

发布时间:2026/9/19 13:22:06
一文搞懂 HIVM 的 hir.custom_macro:跨 Pipe 宏操作完整解析与速查 一文搞懂 HIVM 的 hir.custom_macro跨 Pipe 宏操作完整解析与速查【免费下载链接】BiliBiliToolProB 站bilibili自动任务工具支持docker、青龙、k8s等多种部署方式。全面拥抱AI。敏感肌也能用。项目地址: https://gitcode.com/GitHub_Trending/bi/BiliBiliToolProhir.custom_macro是 AscendNPU-IR 项目中 HIVM 方言的跨 Pipe 宏操作把「数据加载 向量计算 后处理」这类横跨多条流水线的活打包成一个 IR 操作再由编译器根据你声明的pipe_in/pipe_out自动补齐跨 Pipe 同步。如果你之前只用过单流水线的hir.custom遇到进出的管道不一样的场景就会卡住——这篇就是为此准备的。场景速览什么时候需要跨 Pipeline 的宏操作典型的融合核里数据往往先由 MTE2 流水线从 GM全局内存取回再交给 V 流水线Vector Core做向量运算最后把结果写回。用hir.custom描述这条链路会立刻碰壁——它只能绑定一条流水线。hir.custom_macro就是为这种进门管道 ≠ 出门管道的融合而生同一个操作上声明入口与出口中间的握手交给编译器。先看 IR再拆细节两个完整示例与 TableGen 定义先上手感。下面是一个手写的自定义宏操作注意属性区里那对pipe_in/pipe_out它们分别记录了数据进来和结果出去的流水线%empty tensor.empty() : tensor3x3xf32 %0 hivm.hir.custom_macro { hivm.tcore_type #hivm.tcore_typeVECTOR, hivm.vf_mode #hivm.vf_modeSIMD, hivm.pipe_in #hivm.pipePIPE_MTE2, hivm.pipe_out #hivm.pipePIPE_V } my_custom_op ins(%arg0, %arg1, %c4_i64, %c0_i32, %c2_i64, %c1_i64, %c2_i32, %c2_i32, %c0_i32, %c0_i32 : memref?xf32, tensor3x3xi64, i64, i32, i64, i64, i32, i32, i32, i32) outs(%empty : tensor3x3xf32) - tensor3x3xf32对比一个内置宏操作名字以__builtin_开头IR 文本里不再手写属性区核类型、管道、VF 模式全部由编译器在构造时补全%empty tensor.empty() : tensor3x3xf32 %0 hivm.hir.custom_macro __builtin_gather_load ins(%arg0, %arg1, %c4_i64, %c0_i32, %c2_i64, %c1_i64, %c2_i32, %c2_i32, %c0_i32, %c0_i32 : memref?xf32, tensor3x3xi64, i64, i32, i64, i64, i32, i32, i32, i32) outs(%empty : tensor3x3xf32) - tensor3x3xf32这两个写法背后的 TableGen 定义位于bishengir/include/bishengir/Dialect/HIVM/IR/HIVMOps.tdCustomMacroOp段约 L1105–L1167def CustomMacroOp : HIVM_CustomOpcustom_macro, [MacroOpTrait] { let arguments (ins StrAttr:$name, VariadicAnyType:$inputs, VariadicAnyType:$outputs); let results (outs VariadicAnyType:$results); }怎么读这段定义操作在方言里登记的名字是custom_macro继承自定义操作族的公共基类HIVM_CustomOp与hir.custom最本质的差别是它挂着MacroOpTrait——等于提前向编译器报备这是个要跨多条流水线跑的宏同步分析时别拿单步操作那套规则套我。arguments段声明了三个输入操作数results段声明了可变长的结果。操作拆解输入、输出与属性的完整清单操作数一侧ins段一共有三个$name是StrAttr类型的字符串也就是操作名如my_custom_op$inputs是可变长的任意类型参数承担真正的计算输入$outputs同样是可变长任意类型扮演输出缓冲区的角色DPS init。outs段则以可变长$results返回结果。必需属性按职责分成两组一组回答在哪儿跑另一组回答绑到哪条流水线上。执行环境属性类型用途hivm.tcore_typeTCoreTypeAttr指定运行的核类型如VECTORhivm.vf_modeVFModeAttr向量执行模式如SIMD流水线绑定属性类型用途hivm.pipe_inPipeAttr入口流水线数据从哪条 Pipe 进入宏hivm.pipe_outPipeAttr出口流水线结果从哪条 Pipe 离开宏可选属性属性类型用途gm_addr_args_indicesDenseI32ArrayAttr索引列表标记哪些参数携带 GM全局内存地址⚡️ 跨 Pipe 同步编译器如何自动补齐握手单 Pipe 的hir.custom只需在自己那条流水线内部做同步而宏操作横跨两条管道生产者写过的数据消费者不能立刻读中间必须有一次标志位握手。MacroOpTrait就是编译器做这件事的钩子InjectSync与GraphSyncSolver这两个同步分析 Pass 在构建依赖图时会读取你声明的hivm.pipe_in/hivm.pipe_out自动在宏操作前后插上一对set_flag/wait_flag——入口管道写完数据后抬旗出口管道等旗落下再开工。换句话说跨哪两条 Pipe 由你在 IR 里声明什么时机同步由 Pass 推导整条链路不需要手写任何同步代码。 选型对比hir.custom 还是 hir.custom_macro维度hir.customhir.custom_macroTraitSinglePipeOpTraitMacroOpTraitPipe 属性单个hivm.pipehivm.pipe_inhivm.pipe_out一对涉及流水线数1 条2 条入口 出口同步方式仅限 Pipe 内同步需要跨 Pipe 同步由 Pass 自动插入BuiltinInfo 字段coreType、pipe、vfModecoreType、inPipe、outPipe、vfMode一句话选型建议整个操作能塞进一条流水线就用custom数据要从一条管道进比如 MTE2 从 GM 取数、从另一条管道出比如 V 管道做向量计算就换custom_macro。 API 速查CustomMacroOp 访问器与 Pipe 名称常量C 侧CustomMacroOp在基类接口之外还提供了一组专门访问器方便 Pass 与工具链读写方法返回类型作用getInPipe()PIPE读取入口管道setInPipe(PIPE)void写入入口管道getOutPipe()PIPE读取出口管道setOutPipe(PIPE)void写入出口管道getCoreType()optionalTCoreType读取核类型setCoreType(TCoreType)void写入核类型getVFMode()optionalVFMode读取 VF 模式setVFMode(VFMode)void写入 VF 模式isBuiltin()bool判断是否为内置宏操作另外两个 Pipe 属性名还以类内常量的形式给出编译器在 IR 上查找属性时用的就是它们static constexpr StringLiteral inPipeName hivm.pipe_in; static constexpr StringLiteral outPipeName hivm.pipe_out;编译器会校验什么五条硬性规则custom_macro进入编译流程后以下几条规则会被逐一检查MacroOpTrait 语义——操作会被识别为宏操作同步分析阶段走专门的处理路径而不是按单流水线 custom 对待。pipe_in / pipe_out 必须齐备——两个属性缺一不可编译器靠它们推导该插入哪一对跨 Pipe 同步。跨 Pipe 同步插入——InjectSync/GraphSyncSolver依据声明的入口/出口管道在操作前后自动补上set_flag/wait_flag。DPS 语义——操作实现了DestinationStyleOpInterface$outputs操作数承担目的地缓冲DPS init职责结果直接写进你给的 buffer。内置宏额外校验——当isBuiltin()返回 true即名字是__builtin_前缀的内置宏时编译器还会对它的参数做正确性检查。❓ 你可能想问三个高频问题Qpipe_in 和 pipe_out 到底怎么定A顺着数据流方向看。数据进宏时走的那条管道是pipe_in——例如从 GM 取数就填PIPE_MTE2结果出宏时走的那条是pipe_out——向量计算落在 V 管道就填PIPE_V。只要你能说清数据从哪儿来、往哪儿去选型就定了。Q我的操作其实只涉及一条流水线还要写 custom_macro 吗A不用。入口和出口在同一条管道上的话hir.custom就够了custom_macro专治入口、出口管道不同的情况比如 MTE2 加载 V 管道计算的融合。Qset_flag / wait_flag 需要我在 IR 里手写吗A不需要。你只负责声明pipe_in/pipe_out剩下的由InjectSync/GraphSyncSolver两个 Pass 推导跨管道依赖并自动在宏操作周围插入标志位同步。延伸阅读TableGen 定义HIVMOps.tdCustomMacroOp段约 L1105–L1167测试用例custom-op.mlir关联文档单 Pipe 版hir.custom解析——01-custom-op.md【免费下载链接】BiliBiliToolProB 站bilibili自动任务工具支持docker、青龙、k8s等多种部署方式。全面拥抱AI。敏感肌也能用。项目地址: https://gitcode.com/GitHub_Trending/bi/BiliBiliToolPro创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询