In MLIR, fusion is the process of merging adjacent operations within a computational graph to minimize intermediate memory transfers and kernel launch overhead. This is achieved using MLIR's dialect infrastructure, such as the linalg and affine dialects, to represent operations and their data dependencies. The compiler identifies fusion groups—sets of operations like elementwise ops or a Conv-BN-ReLU chain—and rewrites them into a single, compound operation. This transformation is guided by fusion heuristics and cost models that analyze data locality and hardware characteristics to ensure fusion profitability.
Primary Use Cases and Examples
Fusion in MLIR is not a single technique but a set of compiler transformations applied within the MLIR framework to combine operations for performance. These use cases demonstrate how MLIR's dialects and infrastructure enable targeted optimizations.
Loop Fusion for Data Locality
MLIR's Affine and SCF (Structured Control Flow) dialects provide the representation to analyze and fuse loops. This is a foundational optimization for memory-bound kernels.
- Mechanism: Identifies parallel
affine.fororscf.forloops with compatible iteration spaces and data dependencies. - Benefit: Fuses multiple passes over data into one, keeping intermediate values in fast cache or registers.
- Example: Fusing an elementwise
tanhoperation with a subsequent elementwiseaddthat uses the same tensor, eliminating a full write/read cycle to main memory.
Linalg Tiling and Fusion
The Linalg dialect represents tensor contractions and generic linear algebra operations in a declarative, loop-free form. Fusion is a key step in its compilation flow.
- Mechanism: After applying tiling (splitting work into blocks), the compiler fuses the producer of a tile with its consumer.
- Benefit: Enables producer-consumer fusion where the producer's output is consumed immediately within the same kernel, crucial for complex operators like
linalg.generic(elementwise ops) feeding intolinalg.matmul. - Result: Creates a single, efficient kernel for a sub-computation like a tiled and fused matrix multiplication chain.
Fusing Elementwise Operations
A common and highly profitable fusion target in MLIR is combining chains of pointwise operations.
- Representation: Often expressed as
linalg.genericops or sequences ofarithandmathdialect operations. - Process: The compiler pattern-matches a sequence of independent per-element ops (e.g.,
add→relu→cast) and generates a single loop body performing all computations. - Impact: Dramatically reduces kernel launch overhead and intermediate memory allocation for activation functions and data type conversions in neural networks.
Vertical Fusion of Producer-Consumer
This is the classic fusion case where an operation's output is an immediate input to another. MLIR's use-def chains and SSA form make these dependencies explicit for the compiler.
- Scope: Applied within a basic block or across logically connected operations in the IR.
- Example: Fusing a
linalg.conv_2doperation with its immediately followinglinalg.elemwise_binary(add bias) operation. The bias addition is pulled into the convolution's output computation. - MLIR Advantage: Dialects like Linalg maintain structured semantics, allowing the compiler to reason about and safely fuse these operations without breaking correctness.
Horizontal Fusion for Throughput
Horizontal fusion combines independent operations that could be executed in parallel, often to improve resource utilization and amortize memory access costs.
- Mechanism: Identifies operations that share similar input structures or iteration patterns but compute different outputs.
- Use Case: Fusing two independent
linalg.genericoperations that both read from the same input tensor but apply different transformations (e.g., computing both mean and variance in a single pass). - Benefit: Increases arithmetic intensity and improves cache line utilization by reading the input data once for multiple computations.
Pattern-Based Fusion for Known Kernels
MLIR uses rewrite patterns and pattern-driven generators (PDG) to recognize and replace specific subgraphs with hand-optimized or generated fused implementations.
- Canonical Patterns: The compiler has patterns for well-known fused operators like Conv-BN-ReLU. It matches a
linalg.conv_2d→linalg.generic(batch norm) →linalg.generic(relu) sequence. - Replacement: This subgraph is replaced by a call to a hand-tuned library implementation (e.g., via the
vectordialect or an external library like oneDNN) or by a newly generated, optimized fused kernel. - Link: This is a core methodology in projects like IREE, which uses MLIR to compile for GPUs and accelerators. https://iree.dev




