跳转至

操作融合优化

本文引用的文件 - xla\backends\cpu\codegen\fusion_compiler.h - xla\backends\cpu\codegen\emitters\cpu_fusion_emitter.h - xla\backends\cpu\codegen\emitters\cpu_fusion_emitter_config.h - xla\backends\cpu\codegen\emitters\cpu_fusion_emitter.cc - xla\backends\cpu\codegen\fusion_compiler.cc - xla\backends\cpu\codegen\fusion_emitter.h - xla\backends\cpu\codegen\fusion_emitter.cc - xla\backends\cpu\codegen\tiled\tiled_fusion_emitter.h - xla\backends\cpu\codegen\tiled\tiled_fusion_emitter.cc - xla\backends\cpu\transforms\ynn_matcher.h - xla\backends\cpu\transforms\ynn_matcher.cc - xla\backends\cpu\transforms\onednn_matcher.h - xla\backends\cpu\transforms\onednn_matcher.cc - xla\backends\cpu\runtime\onednn\onednn_fusion_thunk.cc - xla\backends\cpu\runtime\onednn\onednn_fusion_thunk.h - xla\backends\cpu\codegen\tools\fusion_compiler_opt.cc - xla\backends\cpu\codegen\tools\fusion_to_mlir.cc - xla\hlo\pass\hlo_pass_interface.h - xla\hlo\ir\hlo_instruction.h - xla\hlo\ir\hlo_computation.h - docs\hlo_passes.md - xla\backends\cpu\benchmarks\fusion_benchmark_test.cc - xla\backends\cpu\benchmarks\ynn_fusion_benchmark_test.cc - xla\backends\autotuner\autotuner.cc - xla\backends\cpu\autotuner\llvm_kernel_backend.cc - xla\backends\cpu\autotuner\llvm_kernel_backend_test.cc

目录

  1. 引言
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考量
  8. 故障排查指南
  9. 结论
  10. 附录

引言

本文件聚焦于XLA在CPU后端的操作融合优化,系统性阐述融合类型(如逐元素融合、广播融合、卷积融合等)的识别与应用、融合算法实现机制、融合收益与成本评估方法、融合过程中的内存访问模式优化、融合后代码生成与优化策略,并给出融合配置选项、性能影响分析与最佳实践。文档同时提供可定位到具体源码路径的示例,帮助读者快速理解与验证不同融合类型的实现与效果。

项目结构

围绕“融合优化”的关键目录与文件如下: - 后端融合编译与发射:xla\backends\cpu\codegen\fusion_compiler.、xla\backends\cpu\codegen\emitters\cpu_fusion_emitter. - 瓦片化融合发射器:xla\backends\cpu\codegen\tiled\tiled_fusion_emitter. - 匹配器(识别融合模式):xla\backends\cpu\transforms\ynn_matcher.、xla\backends\cpu\transforms\onednn_matcher. - 运行时融合Thunk:xla\backends\cpu\runtime\onednn\onednn_fusion_thunk. - 工具链:xla\backends\cpu\codegen\tools\fusion_compiler_opt.cc、xla\backends\cpu\codegen\tools\fusion_to_mlir.cc - HLO层接口与管道:xla\hlo\pass\hlo_pass_interface.h、xla\hlo\ir\hlo_instruction.h、xla\hlo\ir\hlo_computation.h - 文档与基准测试:docs\hlo_passes.md、xla\backends\cpu\benchmarks\fusion_benchmark_test.cc、xla\backends\cpu\benchmarks\ynn_fusion_benchmark_test.cc - 自动调优与融合支持:xla\backends\autotuner\autotuner.cc、xla\backends\cpu\autotuner\llvm_kernel_backend.cc、xla\backends\cpu\autotuner\llvm_kernel_backend_test.cc

graph TB
subgraph "HLO层"
HloPass["HloPassInterface<br/>HLO优化管线"]
HloInst["HloInstruction<br/>融合指令与种类"]
HloComp["HloComputation<br/>计算图与调用关系"]
end
subgraph "CPU融合编译与发射"
FC["FusionCompiler<br/>MLIR->LLVM编译"]
Emitter["CpuFusionEmitter<br/>融合发射器"]
Tile["TiledFusionEmitter<br/>瓦片化发射"]
Tools["工具链<br/>fusion_compiler_opt / fusion_to_mlir"]
end
subgraph "匹配器与运行时"
Ynn["YnnMatcher<br/>识别融合模式"]
Onednn["OnednnMatcher<br/>识别融合模式"]
Thunk["OnednnFusionThunk<br/>运行时执行"]
end
HloPass --> HloInst
HloInst --> Emitter
HloInst --> Ynn
HloInst --> Onednn
Emitter --> FC
Tile --> FC
Ynn --> FC
Onednn --> FC
FC --> Thunk
Tools --> FC

图表来源 - xla\hlo\pass\hlo_pass_interface.h - xla\hlo\ir\hlo_instruction.h - xla\backends\cpu\codegen\fusion_compiler.h - xla\backends\cpu\codegen\emitters\cpu_fusion_emitter.h - xla\backends\cpu\codegen\tiled\tiled_fusion_emitter.h - xla\backends\cpu\transforms\ynn_matcher.h - xla\backends\cpu\transforms\onednn_matcher.h - xla\backends\cpu\runtime\onednn\onednn_fusion_thunk.h

章节来源 - docs\hlo_passes.md - xla\hlo\pass\hlo_pass_interface.h - xla\hlo\ir\hlo_instruction.h

核心组件

  • 融合编译器(FusionCompiler)
  • 将MLIR模块编译为LLVM IR,区分标量与瓦片化两种流水线,支持向量化宽度、快速数学标志等选项。
  • 关键接口:Compile(MLIR->LLVM)、Compile(MlirKernelSource->LlvmKernelSource)、CreateContext/Registry。
  • 融合发射器(CpuFusionEmitter)
  • 生成入口函数API、调用目标、命名融合模块、默认索引映射等;支持C风格内核命名策略。
  • 瓦片化融合发射器(TiledFusionEmitter)
  • 面向瓦片化内核的发射逻辑,与标量路径并行存在。
  • 匹配器(YnnMatcher/OnednnMatcher)
  • 识别特定融合模式(如Ynn、OneDNN),返回融合种类字符串,驱动后续编译与运行时执行。
  • 运行时融合Thunk(OnednnFusionThunk)
  • 承载融合算子的运行时执行,连接发射结果与后端执行环境。
  • 工具链
  • fusion_compiler_opt:融合编译器的命令行工具入口。
  • fusion_to_mlir:将融合转换为MLIR模块的工具。

章节来源 - xla\backends\cpu\codegen\fusion_compiler.h - xla\backends\cpu\codegen\emitters\cpu_fusion_emitter.h - xla\backends\cpu\codegen\tiled\tiled_fusion_emitter.h - xla\backends\cpu\transforms\ynn_matcher.h - xla\backends\cpu\transforms\onednn_matcher.h - xla\backends\cpu\runtime\onednn\onednn_fusion_thunk.h - xla\backends\cpu\codegen\tools\fusion_compiler_opt.cc - xla\backends\cpu\codegen\tools\fusion_to_mlir.cc

架构总览

下图展示了从HLO融合指令到最终LLVM/运行时执行的整体流程,包括匹配器识别、发射器生成、编译器编译与运行时Thunk执行。

sequenceDiagram
participant Hlo as "HloInstruction<br/>融合指令"
participant Matcher as "匹配器<br/>YnnMatcher/OnednnMatcher"
participant Emitter as "CpuFusionEmitter/TiledFusionEmitter"
participant Compiler as "FusionCompiler"
participant Thunk as "OnednnFusionThunk"
Hlo->>Matcher : "识别融合模式"
Matcher-->>Hlo : "返回融合种类"
Hlo->>Emitter : "生成入口函数/调用目标"
Emitter->>Compiler : "构建MLIR模块并编译"
Compiler-->>Thunk : "输出LLVM/内核"
Thunk-->>Hlo : "执行融合算子"

图表来源 - xla\hlo\ir\hlo_instruction.h - xla\backends\cpu\transforms\ynn_matcher.h - xla\backends\cpu\transforms\onednn_matcher.h - xla\backends\cpu\codegen\emitters\cpu_fusion_emitter.h - xla\backends\cpu\codegen\fusion_compiler.h - xla\backends\cpu\runtime\onednn\onednn_fusion_thunk.cc

详细组件分析

组件A:融合编译器(FusionCompiler)

  • 职责
  • 接收MLIR模块,通过标量/瓦片化两条Pass Pipeline编译为LLVM IR或LLVM Kernel Source。
  • 提供静态上下文与方言注册能力,便于测试与工具链集成。
  • 关键点
  • 选项包含向量化宽度、验证级别、快速min/max开关、快速数学标志等。
  • 标量与瓦片化流水线语义差异较大,未来有统一化的重构空间。
  • 典型使用场景
  • 在CPU后端,将匹配器识别出的融合模式转换为可执行的LLVM内核。
classDiagram
class FusionCompiler {
+Options options_
+HloModule* hlo_module_
+PassManager scalar_pass_manager_
+PassManager tiled_pass_manager_
+Compile(llvm_context, mlir_module) LlvmKernelSource
+Compile(mlir_kernel_source) LlvmKernelSource
+CreateContext() MLIRContext
+CreateDialectRegistry(register_pass_pipelines) DialectRegistry
}

图表来源 - xla\backends\cpu\codegen\fusion_compiler.h

章节来源 - xla\backends\cpu\codegen\fusion_compiler.h

组件B:融合发射器(CpuFusionEmitter)

  • 职责
  • 生成融合入口函数API、命名融合模块、默认索引映射、调用目标提供者。
  • 支持C风格内核命名策略,结合父模块名与融合名生成稳定符号名。
  • 关键点
  • 与BufferAssignment协作,确保内存布局与访问模式优化。
  • 与ComputationPartitioner配合,将复杂融合拆分为多个分区计算。
flowchart TD
Start(["开始"]) --> Name["获取融合名称"]
Name --> Entry["生成入口函数API"]
Entry --> Targets["生成调用目标"]
Targets --> Module["创建命名MLIR模块"]
Module --> End(["结束"])

图表来源 - xla\backends\cpu\codegen\emitters\cpu_fusion_emitter.h

章节来源 - xla\backends\cpu\codegen\emitters\cpu_fusion_emitter.h

组件C:匹配器(YnnMatcher / OnednnMatcher)

  • 职责
  • 识别符合特定融合模式的子图,返回融合种类字符串(如Ynn、OneDNN)。
  • 作为融合编译前的关键判定环节,决定是否进行融合以及采用何种融合策略。
  • 关键点
  • 通过融合种类字符串与运行时Thunk对接,形成“识别—编译—执行”的闭环。
sequenceDiagram
participant Subgraph as "子图"
participant Ynn as "YnnMatcher"
participant Onednn as "OnednnMatcher"
participant Compiler as "FusionCompiler"
Subgraph->>Ynn : "检查是否满足Ynn融合条件"
Ynn-->>Subgraph : "返回融合种类"
Subgraph->>Onednn : "检查是否满足Onednn融合条件"
Onednn-->>Subgraph : "返回融合种类"
Subgraph->>Compiler : "根据种类生成MLIR并编译"

图表来源 - xla\backends\cpu\transforms\ynn_matcher.h - xla\backends\cpu\transforms\onednn_matcher.h

章节来源 - xla\backends\cpu\transforms\ynn_matcher.h - xla\backends\cpu\transforms\onednn_matcher.h

组件D:运行时融合Thunk(OnednnFusionThunk)

  • 职责
  • 承载融合算子的运行时执行,负责调度与执行已编译的融合内核。
  • 关键点
  • 与发射器/编译器输出的内核格式保持一致,确保执行路径稳定可靠。

章节来源 - xla\backends\cpu\runtime\onednn\onednn_fusion_thunk.h - xla\backends\cpu\runtime\onednn\onednn_fusion_thunk.cc

组件E:HLO融合指令与种类

  • 职责
  • 定义融合指令的种类(如Loop、Custom等),并提供查询/设置融合种类的接口。
  • 关键点
  • 融合种类是匹配器与编译器之间的契约,直接影响后续编译策略与运行时行为。
classDiagram
class HloInstruction {
+FusionKind fusion_kind()
+set_fusion_kind(kind)
}
class FusionKind {
<<enumeration>>
Loop
Custom
Scatter
Conv
Broadcast
...
}
HloInstruction --> FusionKind : "使用"

图表来源 - xla\hlo\ir\hlo_instruction.h - xla\hlo\ir\hlo_instruction.h

章节来源 - xla\hlo\ir\hlo_instruction.h - xla\hlo\ir\hlo_instruction.h

组件F:HLO优化管线与融合的关系

  • 职责
  • HLO Pass框架提供统一的优化与变换入口,融合通常在Pass流水线中被识别与应用。
  • 关键点
  • 通过RunState与变更集合,Pass可以迭代地作用于计算图,逐步完成融合与优化。

章节来源 - xla\hlo\pass\hlo_pass_interface.h - docs\hlo_passes.md

依赖关系分析

  • 耦合与内聚
  • 匹配器与发射器之间通过“融合种类”耦合,编译器与运行时Thunk之间通过“内核格式”耦合。
  • 发射器与编译器共享MLIR上下文与方言注册,保证生成与编译的一致性。
  • 外部依赖
  • MLIR/LLVM作为编译后端,提供强大的中间表示与优化能力。
  • 潜在循环依赖
  • 当前设计以“识别→发射→编译→执行”单向流动为主,未见明显循环依赖。
graph LR
Matcher["匹配器"] --> Emitter["发射器"]
Emitter --> Compiler["编译器"]
Compiler --> Thunk["运行时Thunk"]
Hlo["HLO指令/种类"] --> Matcher
Hlo --> Emitter

图表来源 - xla\backends\cpu\transforms\ynn_matcher.h - xla\backends\cpu\transforms\onednn_matcher.h - xla\backends\cpu\codegen\emitters\cpu_fusion_emitter.h - xla\backends\cpu\codegen\fusion_compiler.h - xla\backends\cpu\runtime\onednn\onednn_fusion_thunk.h - xla\hlo\ir\hlo_instruction.h

性能考量

  • 融合收益与成本评估
  • 收益:减少内存往返、降低函数调用开销、提升缓存局部性、利用SIMD向量化。
  • 成本:增加内核复杂度、可能引入额外的索引计算与分支。
  • 内存访问模式优化
  • 通过默认索引映射与瓦片化发射器,尽量使访问模式对缓存友好。
  • 与BufferAssignment协作,避免临时缓冲区与重复加载。
  • 向量化与快速数学
  • FusionCompiler选项支持向量化宽度与快速数学标志,可在精度与吞吐间权衡。
  • 基准测试参考
  • 提供多种融合类型的基准测试,可用于对比不同融合策略的性能表现。

章节来源 - xla\backends\cpu\codegen\fusion_compiler.h - xla\backends\cpu\codegen\emitters\cpu_fusion_emitter.h - xla\backends\cpu\benchmarks\fusion_benchmark_test.cc - xla\backends\cpu\benchmarks\ynn_fusion_benchmark_test.cc

故障排查指南

  • 融合未生效
  • 检查匹配器是否识别到融合模式(查看匹配器返回的融合种类)。
  • 确认发射器是否成功生成入口函数与命名模块。
  • 编译失败
  • 使用工具链fusion_to_mlir与fusion_compiler_opt进行最小化复现,逐步缩小问题范围。
  • 检查MLIR上下文与方言注册是否完整。
  • 运行时异常
  • 对照OnednnFusionThunk的输入输出格式,确认与发射器/编译器输出一致。
  • 自动调优相关
  • 若启用自动调优,检查Autotuner对融合模块的处理逻辑与提取策略。

章节来源 - xla\backends\cpu\codegen\tools\fusion_to_mlir.cc - xla\backends\cpu\codegen\tools\fusion_compiler_opt.cc - xla\backends\cpu\runtime\onednn\onednn_fusion_thunk.cc - xla\backends\autotuner\autotuner.cc

结论

XLA在CPU后端的融合优化以“识别—发射—编译—执行”为主线,通过匹配器识别融合模式、发射器生成MLIR模块、编译器将MLIR编译为LLVM内核、运行时Thunk执行融合算子,形成完整的流水线。该体系兼顾了灵活性与可扩展性,既支持通用融合(如逐元素、广播),也支持专用融合(如Ynn、OneDNN)。通过基准测试与自动调优,可进一步量化融合收益并指导配置选择。

附录