多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

custom_macro 跨 Pipe 宏操作详解

custom_macro 跨 Pipe 宏操作详解 custom_macro 跨 Pipe 宏操作详解【免费下载链接】BiliBiliToolProB 站bilibili自动任务工具支持docker、青龙、k8s等多种部署方式。全面拥抱AI。敏感肌也能用。项目地址: https://gitcode.com/GitHub_Trending/bi/BiliBiliToolPro在昇腾 NPU 上写融合算子的初期我踩过一个同步的坑数据还在 MTE2 流水线上搬运计算却已经在向量流水线上开跑结果偶尔就是错的。这种跨两条流水线的场景正是 HIVM 的custom_macro要解决的问题。它到底是什么CustomMacroOp 是 HIVM 方言里的跨 Pipe 宏操作你显式声明数据从哪条流水线进来hivm.pipe_in、结果从哪条流水线出去hivm.pipe_out剩下的跨流水线同步由编译器补齐。它服务的是数据加载 计算 后处理这类没法塞进单条 Pipe 完成的融合算子。跨 Pipe 的活编译器怎么接手和普通 custom 操作相比机制上变化的不是 op 的外形而是同步的分工方式。大致分四步MacroOpTraitMLIR 里给 op 贴的行为标签可理解为 trait把它标记为宏操作让同步分析 pass 区别于普通单 Pipe op 处理。hivm.pipe_in和hivm.pipe_out两个属性描述数据流向一个回答数据从哪来一个回答数据到哪去。InjectSync / GraphSyncSolver pass 读取这两个属性在 op 前后插入 set_flag / wait_flag 这类跨 Pipe 同步op 本体不用自己管同步。hivm.tcore_type执行核类型和hivm.vf_mode向量运行模式如 SIMD进一步限定跑在哪个核、以什么模式跑和两条 Pipe 一起构成完整的调度描述。可选属性gm_addr_args_indices用来标出哪些 ins 参数是 GM全局显存地址。C 侧有getInPipe/setInPipe、getOutPipe/setOutPipe这组配套访问器还有getCoreType、getVFMode、isBuiltin内置信息BuiltinInfo存的是 coreType、inPipe、outPipe、vfMode 四个字段。一个能跑通的 IR 长什么样// 典型形态MTE2 流水线加载V 流水线计算 %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 : memref?xf32, tensor3x3xi64, i64, i32) // … 省略 … 其余标量参数 outs(%empty : tensor3x3xf32) - tensor3x3xf32有个容易漏的细节outs(%empty)是结果的初始化操作数——custom_macro 实现了 DestinationStyleOpInterfaceDPSdestination-passing style算子把写好的 buffer 当输入再输出所以 op 之前得自己备好一个空 tensor。name是 StrAttr写编译器内置名如__builtin_gather_load时参数会被严格校验。和 custom 的区别到底在哪两者在 tablegen 层是同一副壳——name 变长inputs/outputs——真正的差别在元数据和同步策略对比维度CustomOpCustomMacroOpTrait 标记SinglePipeOpTraitMacroOpTraitPipe 属性单个hivm.pipehivm.pipe_inhivm.pipe_out流水线跨度单 Pipe跨 Pipe同步策略Pipe 内同步编译器自动插跨 Pipe 同步BuiltinInfo 字段coreType、pipe、vfModecoreType、inPipe、outPipe、vfMode一句话记法op 全程待在同一 Pipeline 里就用 custom只要横跨两条就切 custom_macro。这不是风格问题是正确性问题。别把 pipe_in 和 pipe_out 搞反⚠️ 几个容易翻车的地方按踩中概率排一下进和出写反了依赖边方向画错同步插错位置运行时可能死等或读到脏数据。MTE2 是搬运入口数据从 GM 进来V 流水线是计算出口按数据从哪来、到哪去的顺序写就不会错。该用 custom_macro 却用了 custom声明单 Pipe内核实际跨了两条编译器只补 Pipe 内同步留下平时能跑、偶尔出错的竞态。排查同步问题先翻 trait。outs 忘了给 init结果恒为 0 或验证阶段报缺 init 操作数原因是 DPS 风格必须显式传空 tensor。内置算子参数乱改类型__builtin_gather_load这类内置 op 签名是固定的ins/outs 类型对不上直接编译报错写内置的先对签名。 记不住细节时的兜底问法pipe_in 回答数据怎么进来pipe_out 回答结果怎么出去。想再往深处挖的话源码想翻的话CustomMacroOp的 tablegen 定义在bishengir/include/bishengir/Dialect/HIVM/IR/HIVMOps.td后半部分hivm.pipe_in/hivm.pipe_out这两个属性名常量就定义在旁边。合法 IR 形态去bishengir/test/Dialect/HIVM/IR/custom-op.mlir看最省事custom 和 custom_macro 的样例都在里面。至于同步到底插在哪读一下InjectSync和GraphSyncSolver两个 pass 的实现是跨 Pipe 同步这件事的另一半答案。【免费下载链接】BiliBiliToolProB 站bilibili自动任务工具支持docker、青龙、k8s等多种部署方式。全面拥抱AI。敏感肌也能用。项目地址: https://gitcode.com/GitHub_Trending/bi/BiliBiliToolPro创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表