
同步注入 Pass — InjectSync / GraphSyncSolver【免费下载链接】cannbot-skillsCANNBot 是面向 CANN 开发的用于提升开发效率的系列智能体本仓库为其提供可复用的 Skills 模块。项目地址: https://gitcode.com/cann/cannbot-skills关键词InjectSync, GraphSyncSolver, SyncMode, Event ID Allocation, IR 变换概述HIVM 编译器提供自动同步注入机制在用户编写的 IR 中自动插入set_flag/wait_flag等同步操作保证多 Pipeline 执行的正确性。用户通常不需要手动编写同步操作编译器会根据操作间的数据依赖自动注入。HIVM 提供两种同步注入 PassInjectSync Pass基于启发式规则的同步注入按操作顺序分析数据依赖并插入同步操作。GraphSyncSolver Pass基于图的同步求解器构建操作依赖图后求解最优同步方案通常能生成更优的同步代码。InjectSync PassPass 定义从 Passes.td 提取def InjectSync : Passhivm-inject-sync, func::FuncOp { let summary auto inject sync; let options [ OptionsyncMode, sync-mode, hivm::SyncMode, hivm::SyncMode::NORMAL, inject sync mode, OptionenableUnitFlag, enable-unit-flag, bool, false, Enable unit-flag modes for synchronization, OptionassumeAliveLoops, assume-alive-loops, bool, false, Assume that all loops will execute at least once. ]; }Pass 选项选项类型默认值说明sync-modeSyncModeNORMAL同步模式NORMAL正常注入或 BARRIERALL注入 pipe_barrier仅用于调试enable-unit-flagboolfalse启用 UnitFlag 模式处理循环可能不执行的同步场景assume-alive-loopsboolfalse假设所有循环至少执行一次简化同步分析SyncMode 枚举模式说明NORMAL正常模式根据数据依赖插入 set_flag/wait_flagBARRIERALL调试模式在每个操作前后插入 pipe_barrierIR 变换效果变换前func.func example(%src : memref16x16xf16, #hivm.address_spacegm, %dst_l1 : memref16x16xf16, %dst_l0c : memref16x16xf32) { hivm.hir.load ins(%src : ...) outs(%dst_l1 : ...) hivm.hir.mmadL1 ins(%a, %b, %init, ...) outs(%dst_l0c : ...) hivm.hir.fixpipe ins(%dst_l0c : ...) outs(%res : ...) return }变换后NORMAL 模式func.func example(%src : memref16x16xf16, #hivm.address_spacegm, %dst_l1 : memref16x16xf16, %dst_l0c : memref16x16xf32) { hivm.hir.load ins(%src : ...) outs(%dst_l1 : ...) hivm.hir.set_flag [#hivm.pipePIPE_MTE2, #hivm.pipePIPE_M, #hivm.eventEVENT_ID0] hivm.hir.wait_flag [#hivm.pipePIPE_MTE2, #hivm.pipePIPE_M, #hivm.eventEVENT_ID0] hivm.hir.mmadL1 ins(%a, %b, %init, ...) outs(%dst_l0c : ...) hivm.hir.set_flag [#hivm.pipePIPE_M, #hivm.pipePIPE_FIX, #hivm.eventEVENT_ID1] hivm.hir.wait_flag [#hivm.pipePIPE_M, #hivm.pipePIPE_FIX, #hivm.eventEVENT_ID1] hivm.hir.fixpipe ins(%dst_l0c : ...) outs(%res : ...) return }变换后BARRIERALL 模式调试用func.func example(...) { hivm.hir.load ins(%src : ...) outs(%dst_l1 : ...) hivm.hir.pipe_barrier [#hivm.pipePIPE_MTE2] hivm.hir.pipe_barrier [#hivm.pipePIPE_M] hivm.hir.mmadL1 ins(%a, %b, %init, ...) outs(%dst_l0c : ...) hivm.hir.pipe_barrier [#hivm.pipePIPE_M] hivm.hir.pipe_barrier [#hivm.pipePIPE_FIX] hivm.hir.fixpipe ins(%dst_l0c : ...) outs(%res : ...) return }GraphSyncSolver PassPass 定义从 Passes.td 提取def GraphSyncSolver : Passhivm-graph-sync-solver, func::FuncOp { let summary graph sync solver; let options [ OptionenableUnitFlag, enable-unit-flag, bool, false, Enable unit-flag modes for synchronization, OptionenableTesterMode, enable-tester-mode, bool, false, Enable sync-tester mode, ListOptionsyncTesterOptions, sync-tester-options, int64_t, Sync-tester options ]; }Pass 选项选项类型默认值说明enable-unit-flagboolfalse启用 UnitFlag 模式enable-tester-modeboolfalse启用同步测试模式sync-tester-optionslisti64[]同步测试选项num_runs, init_seed, num_ops, num_ptrs, enable-multibuffer工作原理GraphSyncSolver 的工作流程IR 转换将 MLIR IR 转换为内部同步图表示SyncSolverIR图构建构建操作依赖图节点为操作边为数据依赖求解在图上求解最优同步方案包括 Event ID 分配和同步点选择代码生成将求解结果转换回 MLIR IR插入 set_flag/wait_flag 操作与 InjectSync 的对比特性InjectSyncGraphSyncSolver算法启发式规则图求解Event ID 使用可能较多更优化同步粒度操作级可优化到更细粒度编译速度较快较慢同步质量基本正确更优减少不必要的同步调试支持BARRIERALL 模式Tester 模式Pipeline 中的选择从 HIVMPipelines.cpp 可以看到Pipeline 中的选择逻辑如果enableHIVMGraphSyncSolvertrue且enableHIVMInjectBarrierAllSyncfalse使用 GraphSyncSolver否则使用 InjectSyncInjectBlockSync Pass除了 Pipe 内同步还有跨 Block 同步注入 Passdef InjectBlockSync : Passhivm-inject-block-sync, func::FuncOp { let options [ OptionblockAllSync, block-all-sync, bool, false, Enable inject all block sync, OptionassumeAliveLoops, assume-alive-loops, bool, false, Assume that all loops will execute at least once. ]; }常见问题Q: 应该使用 InjectSync 还是 GraphSyncSolverA: 默认使用 InjectSync。如果需要更优的同步方案减少同步开销可以启用 GraphSyncSolver。GraphSyncSolver 编译时间较长但生成的同步代码通常更高效。Q: assume-alive-loops 选项的作用A: 当设置为 true 时编译器假设所有循环至少执行一次可以简化同步分析避免插入不必要的 UnitFlag。但如果不满足假设可能导致同步错误。Q: BARRIERALL 模式有什么用A: BARRIERALL 是调试模式在每个操作前后插入 pipe_barrier。虽然性能很差但可以排除同步问题导致的错误帮助定位问题。相关文档源码参考Passes.tdInjectSync 实现InjectSync.cppGraphSyncSolver 实现GraphSyncSolver.cppPipeline 配置HIVMPipelines.cpp【免费下载链接】cannbot-skillsCANNBot 是面向 CANN 开发的用于提升开发效率的系列智能体本仓库为其提供可复用的 Skills 模块。项目地址: https://gitcode.com/cann/cannbot-skills创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考