57 linalg Dialect
57.1 Beginner Summary
linalg is MLIR’s dialect for structured linear algebra and tensor computation.
It represents computations such as elementwise maps, reductions, matrix multiplication, convolution, pooling, packing, transposition, and more. The important word is structured: a Linalg operation describes a regular iteration space, how operands are indexed in that space, and what scalar computation runs at each point.
A beginner can think of Linalg as this idea:
for every point in a structured iteration space:
read scalar elements from inputs
read scalar elements from outputs when needed
run a small scalar body
write yielded scalar values to outputs
The dialect is used heavily in MLIR because it is high-level enough for tensor and machine-learning transformations, but regular enough to lower to loops, vectors, buffers, library calls, or target-specific code.
The most important op is linalg.generic. Named ops such as linalg.matmul, linalg.add, or linalg.conv_2d_nhwc_hwcf are specialized forms that make common computations easier to recognize. Many passes convert between those forms.
57.2 Why This Dialect Exists
Compilers need a representation that sits between high-level math and low-level loops.
If a compiler lowers directly from a model operation to loops, it loses useful structure. A loop nest can compute a matrix multiplication, but the compiler may no longer know that it is a matrix multiplication. That makes tiling, fusion, vectorization, library-call replacement, and layout changes harder.
If a compiler stays at the model level too long, it cannot express general low-level transformations. A source op such as “convolution” or “add” is often too coarse for hardware-specific scheduling.
linalg solves this by giving computations a structured shape:
- operands are tensors or memrefs
- each operand has an affine indexing map
- each loop dimension has an iterator type such as
parallelorreduction - scalar computation lives in a region
- outputs are explicit destinations
That structure lets MLIR run transformations while still understanding the computation.
57.3 When It Matters
linalg matters in tensor, ML, and accelerator pipelines.
You are likely to see it when:
- TOSA or another ML dialect lowers into tensor computations
- tensor padding, elementwise math, matmul, convolution, or pooling must be optimized before code generation
- a pipeline wants to tile, fuse, vectorize, or distribute computation
- tensor IR is being prepared for bufferization
- bufferized computation is being lowered to
scforaffineloops - a known operation should become a library call
- a generic computation should be recognized as a named operation
It is one of the central bridge dialects in MLIR. Many pipelines flow through Linalg even if they do not start or end there.
57.4 When To Use It
Use linalg when the computation has a regular iteration space over tensors or memrefs.
Good uses:
- elementwise tensor math
- reductions
- matrix multiplication and other contractions
- convolution and pooling
- layout packing and unpacking
- transposes and broadcasts that move or materialize data
- tensor-level intermediate IR before bufferization
- memref-level loop generation after bufferization
Avoid using linalg when:
- the control flow is irregular and not naturally an affine-indexed iteration space
- the computation is mostly scalar control flow
- the operation is only a metadata view change, such as
memref.transpose - the target representation already needs explicit low-level instructions
- the source semantics require a specialized dialect that has not yet been lowered
In practice, a common path is:
model dialect -> tensor/linalg -> bufferization -> linalg on memrefs -> loops/vector/gpu/llvm
57.5 Core Concepts
57.5.1 Structured Operations
A Linalg structured operation describes:
- inputs
- output destinations
- an iteration space
- indexing maps
- iterator types
- a scalar body
The scalar body works on individual elements, not whole tensors. Linalg uses the operation metadata to decide which elements those scalar arguments correspond to.
57.5.2 Destination-Passing Style
Linalg uses destination-passing style.
An op does not simply say “produce a result”. It also says where the result is initialized or written.
For tensors:
%empty = tensor.empty() : tensor<4x16xf32>
%result = linalg.fill ins(%cst : f32)
outs(%empty : tensor<4x16xf32>)
-> tensor<4x16xf32>
The output tensor operand is the destination. The op returns a new tensor value.
For memrefs:
linalg.fill ins(%cst : f32) outs(%buffer : memref<4x16xf32>)
The destination is written in place and the operation has no tensor result.
This distinction is important:
- tensor semantics are value semantics
- memref semantics are buffer mutation semantics
57.5.3 Inputs, Outputs, And Inits
Linalg often calls its destination operands outs or inits.
An output operand may be used in the scalar body. For example, matrix multiplication accumulates into the current output element:
C[m, n] = C[m, n] + A[m, k] * B[k, n]
That means the output is both the destination and the initial accumulator.
Other ops, such as a pure elementwise map, may ignore the previous output value and use the destination only for shape and storage.
57.5.4 Indexing Maps
Indexing maps connect loop dimensions to operand dimensions.
For matrix multiplication, the logical loops are (m, n, k):
affine_map<(m, n, k) -> (m, k)> // A
affine_map<(m, n, k) -> (k, n)> // B
affine_map<(m, n, k) -> (m, n)> // C
The maps explain:
- how to read
A - how to read
B - how to read or write
C
This is the core of linalg.generic. The scalar body does the math, while the indexing maps describe how that math is applied over tensors or buffers.
57.5.5 Iterator Types
Each loop dimension has an iterator type.
The most important iterator types are:
parallel: iterations are independentreduction: iterations contribute to an accumulated valuewindow: used by windowed operations such as convolution and pooling
For matmul:
m: parallel
n: parallel
k: reduction
This tells transformations which loops can be parallelized and which loops must combine values.
57.5.6 Regions And linalg.yield
linalg.generic, linalg.map, linalg.reduce, and many named structured ops contain regions.
The region receives scalar block arguments. It must end with linalg.yield, which returns scalar values for the output destinations.
Example:
^bb0(%a: f32, %b: f32, %out: f32):
%sum = arith.addf %a, %b : f32
linalg.yield %sum : f32
linalg.yield is not a function return. It returns one scalar iteration result to the enclosing Linalg op.
57.5.7 Named, Category, And Generic Forms
Linalg operations come in several levels of specificity.
linalg.generic is the most general structured form. It explicitly stores indexing maps, iterator types, and a scalar region.
Category ops are structured but more constrained. Examples include:
linalg.elementwiselinalg.contractlinalg.maplinalg.reducelinalg.broadcastlinalg.transpose
Named ops are the most recognizable forms:
linalg.matmullinalg.conv_2d_nhwc_hwcflinalg.addlinalg.pooling_nhwc_max
The dialect has passes that convert between these forms. Generalization goes from named or category ops toward linalg.generic. Specialization tries to recognize a generic op as a category or named op.
57.5.8 Tensor And MemRef Semantics
The same Linalg computation can exist over tensors or memrefs.
Tensor form:
ins(tensor values) outs(init tensor) -> result tensor
Memref form:
ins(memrefs) outs(output memref)
Tensor form is better before bufferization. Memref form is better when lowering to explicit loops and stores.
57.5.9 Library Calls
Some Linalg ops can lower to external library calls. The generic path is convert-linalg-to-std, which turns a Linalg op with a library call name into a func.call.
This is not the same as loop lowering. Loop lowering expands the operation into explicit loads, scalar computation, and stores. Library-call lowering delegates the computation to an external implementation.
57.6 Operations
The generated Linalg dialect operation inventory has 99 operations.
57.6.1 Structural And Support Operations
| Operation | Meaning |
|---|---|
linalg.generic |
Fully explicit structured op with indexing maps, iterator types, inputs, outputs, and scalar region. |
linalg.yield |
Terminator for Linalg regions. Yields scalar values to the enclosing structured op. |
linalg.index |
Reads the current loop induction value for a dimension inside a Linalg structured op. |
57.6.2 Category Operations
| Operation | Meaning |
|---|---|
linalg.map |
Elementwise map with a user-provided scalar mapper region. |
linalg.reduce |
Reduction over selected dimensions with a combiner region. |
linalg.transpose |
Materializing transpose. Moves data according to a permutation. |
linalg.broadcast |
Materializing broadcast into a larger destination shape. |
linalg.elementwise |
Category op for unary, binary, or ternary elementwise functions. |
linalg.contract |
General contraction op with explicit indexing maps. |
57.6.3 Elementwise Named Operations
Unary named elementwise ops:
| Operation | Meaning |
|---|---|
linalg.abs |
Elementwise absolute value. |
linalg.ceil |
Elementwise ceiling. |
linalg.erf |
Elementwise error function. |
linalg.exp |
Elementwise exponential. |
linalg.floor |
Elementwise floor. |
linalg.log |
Elementwise logarithm. |
linalg.negf |
Elementwise floating-point negation. |
linalg.reciprocal |
Elementwise reciprocal. |
linalg.round |
Elementwise round. |
linalg.rsqrt |
Elementwise reciprocal square root. |
linalg.sqrt |
Elementwise square root. |
linalg.square |
Elementwise square. |
linalg.tanh |
Elementwise hyperbolic tangent. |
Binary and ternary named elementwise ops:
| Operation | Meaning |
|---|---|
linalg.add |
Elementwise add. |
linalg.sub |
Elementwise subtract. |
linalg.mul |
Elementwise multiply. |
linalg.div |
Elementwise signed or floating division depending on type. |
linalg.div_unsigned |
Elementwise unsigned integer division. |
linalg.max |
Elementwise max. |
linalg.min |
Elementwise min. |
linalg.powf |
Elementwise floating-point power. |
linalg.select |
Elementwise select. |
57.6.4 Fill, Copy, And Random Fill
| Operation | Meaning |
|---|---|
linalg.fill |
Fill an output tensor or memref with a scalar value. |
linalg.copy |
Copy from one shaped value to another. |
linalg.fill_rng_2d |
Fill a 2D output with pseudo-random values in a range. |
57.6.5 Contractions And Matrix-Like Operations
| Operation | Meaning |
|---|---|
linalg.matmul |
Matrix multiplication. |
linalg.batch_matmul |
Batched matrix multiplication. |
linalg.batch_reduce_matmul |
Batched/reduced matrix multiplication form. |
linalg.matvec |
Matrix-vector multiplication. |
linalg.vecmat |
Vector-matrix multiplication. |
linalg.batch_matvec |
Batched matrix-vector multiplication. |
linalg.batch_vecmat |
Batched vector-matrix multiplication. |
linalg.dot |
Dot product. |
linalg.mmt4d |
4D packed matrix multiplication micro-kernel style operation. |
linalg.batch_mmt4d |
Batched mmt4d. |
linalg.quantized_matmul |
Quantized matrix multiplication with zero-point operands. |
linalg.quantized_batch_matmul |
Batched quantized matrix multiplication. |
57.6.6 Convolution Operations
Generic convolution forms:
| Operation | Meaning |
|---|---|
linalg.conv_1d |
Generic 1D convolution. |
linalg.conv_2d |
Generic 2D convolution. |
linalg.conv_3d |
Generic 3D convolution. |
Named convolution layout forms:
| Operation |
|---|
linalg.conv_1d_ncw_fcw |
linalg.conv_1d_nwc_wcf |
linalg.conv_2d_nchw_fchw |
linalg.conv_2d_nchw_fchw_q |
linalg.conv_2d_ngchw_fgchw |
linalg.conv_2d_ngchw_gfchw |
linalg.conv_2d_ngchw_gfchw_q |
linalg.conv_2d_nhwc_fhwc |
linalg.conv_2d_nhwc_fhwc_q |
linalg.conv_2d_nhwc_hwcf |
linalg.conv_2d_nhwc_hwcf_q |
linalg.conv_2d_nhwgc_gfhwc |
linalg.conv_2d_nhwgc_gfhwc_q |
linalg.conv_3d_ncdhw_fcdhw |
linalg.conv_3d_ndhwc_dhwcf |
linalg.conv_3d_ndhwc_dhwcf_q |
The suffix describes the layout of input and filter tensors. For example, nhwc_hwcf indicates input layout N,H,W,C and filter layout H,W,C,F. The _q variants represent quantized convolution forms.
57.6.7 Depthwise Convolution Operations
| Operation |
|---|
linalg.depthwise_conv_1d_ncw_cw |
linalg.depthwise_conv_1d_nwc_wc |
linalg.depthwise_conv_1d_nwc_wcm |
linalg.depthwise_conv_2d_nchw_chw |
linalg.depthwise_conv_2d_nhwc_hwc |
linalg.depthwise_conv_2d_nhwc_hwc_q |
linalg.depthwise_conv_2d_nhwc_hwcm |
linalg.depthwise_conv_2d_nhwc_hwcm_q |
linalg.depthwise_conv_3d_ncdhw_cdhw |
linalg.depthwise_conv_3d_ndhwc_dhwc |
linalg.depthwise_conv_3d_ndhwc_dhwcm |
Depthwise convolution is separated because its channel semantics differ from ordinary convolution.
57.6.8 Pooling Operations
1D pooling:
| Operation |
|---|
linalg.pooling_ncw_max |
linalg.pooling_ncw_sum |
linalg.pooling_nwc_max |
linalg.pooling_nwc_max_unsigned |
linalg.pooling_nwc_min |
linalg.pooling_nwc_min_unsigned |
linalg.pooling_nwc_sum |
2D pooling:
| Operation |
|---|
linalg.pooling_nchw_max |
linalg.pooling_nchw_sum |
linalg.pooling_nhwc_max |
linalg.pooling_nhwc_max_unsigned |
linalg.pooling_nhwc_min |
linalg.pooling_nhwc_min_unsigned |
linalg.pooling_nhwc_sum |
3D pooling:
| Operation |
|---|
linalg.pooling_ndhwc_max |
linalg.pooling_ndhwc_min |
linalg.pooling_ndhwc_sum |
57.6.9 Relayout Operations
| Operation | Meaning |
|---|---|
linalg.pack |
Convert a tensor or memref into a tiled packed layout, optionally with padding and outer-dimension permutation. |
linalg.unpack |
Convert a packed layout back to an unpacked destination layout. |
57.6.10 Aggregate And Special Operations
| Operation | Meaning |
|---|---|
linalg.softmax |
Aggregate softmax op. Decomposes to smaller structured operations. |
linalg.winograd_filter_transform |
Filter transform for Winograd Conv2D lowering. |
linalg.winograd_input_transform |
Input transform for Winograd Conv2D lowering. |
linalg.winograd_output_transform |
Output transform for Winograd Conv2D lowering. |
57.7 Attributes And Interfaces
57.7.1 Iterator Type Attribute
Linalg iterator types describe loop dimensions:
iterator_types = ["parallel", "parallel", "reduction"]
They are represented by the dialect’s iterator type enum attribute.
57.7.2 Elementwise And Function Attributes
The dialect defines attributes for generated region builders and category ops:
#linalg.elementwise_kind<...>#linalg.unary_fn<...>#linalg.binary_fn<...>#linalg.ternary_fn<...>#linalg.type_fn<...>
Beginners usually encounter these indirectly through named ops and category ops.
57.7.3 LinalgOp Interface
Most structured Linalg ops implement the Linalg structured interface. This lets passes ask common questions:
- how many loops does the op have?
- which loops are parallel?
- which loops are reductions?
- what are the indexing maps?
- which operands are inputs?
- which operands are destinations?
- does the payload use a destination value?
This interface is why generic transformations can work on many different Linalg ops.
57.7.4 Contraction And Convolution Interfaces
Contraction ops such as linalg.matmul, linalg.batch_matmul, and linalg.contract implement contraction-related interfaces. This is important for vectorization and matmul-specific rewrites.
Convolution ops implement convolution-related interfaces. This lets passes recognize image/filter/output structure without hard-coding every operation name.
57.8 Transformations
57.8.1 Form Conversion
Linalg has several ways to represent the same computation:
named op <-> category op <-> linalg.generic
Important passes:
| Pass | Meaning |
|---|---|
linalg-morph-ops |
Converts Linalg ops between named, category, and generic forms. |
linalg-generalize-named-ops |
Deprecated compatibility path from named ops to linalg.generic. |
linalg-specialize-generic-ops |
Deprecated compatibility path that tries to recognize linalg.generic as named ops. |
Generalization is reliable because every named structured op can be described as a generic structured op. Specialization is best-effort because not every generic op matches a known named op.
57.8.2 Loop Lowering
Linalg can lower to loops once it has buffer semantics.
| Pass | Meaning |
|---|---|
convert-linalg-to-loops |
Lowers Linalg ops to scf.for loops. |
convert-linalg-to-parallel-loops |
Lowers parallel iterator dimensions to scf.parallel where possible. |
convert-linalg-to-affine-loops |
Lowers Linalg ops to affine.for style loops. |
The important precondition is buffer semantics. Tensor operands and tensor results usually need bufferization before loop lowering.
57.8.3 Elementwise Conversion And Fusion
| Pass | Meaning |
|---|---|
convert-elementwise-to-linalg |
Converts ranked tensor elementwise ops with the ElementwiseMappable trait to Linalg. |
linalg-fuse-elementwise-ops |
Fuses elementwise Linalg ops on tensors. |
linalg-fold-into-elementwise |
Folds linalg.transpose and linalg.broadcast producers into linalg.elementwise indexing maps when legal. |
linalg-inline-scalar-operands |
Inlines scalar operands into linalg.generic bodies. |
These passes are common in tensor pipelines where many small elementwise operations should be combined before bufferization or vectorization.
57.8.4 Shape And Layout Simplification
| Pass | Meaning |
|---|---|
linalg-fold-unit-extent-dims |
Removes unit-extent dimensions from Linalg ops on tensors. |
linalg-block-pack-matmul |
Packs matmul into blocked layouts, uses linalg.mmt4d, then unpacks back. |
simplify-depthwise-conv |
Simplifies depthwise convolution forms. |
linalg.pack and linalg.unpack are central to layout changes. They make tiled layouts explicit so later transformations can reason about them.
57.8.5 Aggregate And Decomposition Patterns
Some ops are intentionally aggregate forms. For example:
linalg.softmax- Winograd transform ops
- selected pack/unpack patterns
- selected convolution rewrites
These are usually decomposed by pattern-driven transformations or transform dialect ops rather than a single public pass with the exact op name.
57.8.6 Transform Dialect Extension
Linalg also provides many transform dialect operations under names such as:
transform.structured.matchtransform.structured.tile_using_fortransform.structured.tile_using_foralltransform.structured.fusetransform.structured.generalizetransform.structured.specializetransform.structured.vectorizetransform.structured.packtransform.structured.padtransform.structured.lower_packtransform.structured.lower_unpacktransform.structured.split_reductiontransform.structured.convert_conv2d_to_img2coltransform.structured.winograd_conv2d
These are not linalg dialect operations. They are transform dialect ops that target Linalg payload operations. They matter when a pipeline uses explicit transform scripts instead of only pass pipelines.
57.9 Conversions / Lowering Paths
57.9.1 Into Linalg
Common paths into Linalg:
| Pass | Direction |
|---|---|
convert-elementwise-to-linalg |
Ranked tensor elementwise ops to linalg.generic. |
convert-tensor-to-linalg |
Some Tensor dialect ops, notably tensor padding patterns, to Linalg-oriented IR. |
tosa-to-linalg |
TOSA ops to tensor and Linalg operations. |
tosa-to-linalg-named |
TOSA ops to Linalg named operations where possible. |
This is why Linalg often appears after model-level dialects.
57.9.2 Linalg To Loops
After bufferization, Linalg can lower to loops:
linalg.matmul on memrefs
-> scf.for / scf.parallel / affine.for
-> scalar arith + memref.load + memref.store
The lowering inlines the Linalg region into the innermost loop and replaces linalg.index with the corresponding induction variable.
57.9.3 Linalg To Library Calls
convert-linalg-to-std lowers Linalg ops with library call names to func.call.
The conversion canonicalizes memref layouts in function signatures because library-call ABIs do not use MLIR’s full layout information directly.
This path is different from loop lowering:
- loop lowering expands the computation
- library-call lowering delegates the computation
57.9.4 Linalg To Vector And GPU-Oriented Forms
Vectorization, tiling, distribution, and GPU mapping are mostly implemented as patterns and transform dialect operations rather than one simple public conversion pass.
Conceptually:
linalg structured op
-> tiled linalg/scf form
-> vector operations
-> gpu or target-specific dialects
The reason this works is that Linalg exposes iterator types, indexing maps, and contraction/convolution interfaces.
57.10 Example IR
57.10.1 Tensor Matmul
func.func @matmul_tensor(%a : tensor<4x8xf32>,
%b : tensor<8x16xf32>) -> tensor<4x16xf32> {
%zero = arith.constant 0.0 : f32
%empty = tensor.empty() : tensor<4x16xf32>
%init = linalg.fill ins(%zero : f32)
outs(%empty : tensor<4x16xf32>)
-> tensor<4x16xf32>
%result = linalg.matmul
ins(%a, %b : tensor<4x8xf32>, tensor<8x16xf32>)
outs(%init : tensor<4x16xf32>)
-> tensor<4x16xf32>
return %result : tensor<4x16xf32>
}
This is tensor-value Linalg. The destination tensor initializes the result, and the op returns a new tensor value.
57.10.2 Generic Elementwise Add
#id2 = affine_map<(d0, d1) -> (d0, d1)>
func.func @generic_add(%lhs : tensor<?x?xf32>,
%rhs : tensor<?x?xf32>,
%out : tensor<?x?xf32>) -> tensor<?x?xf32> {
%result = linalg.generic {
indexing_maps = [#id2, #id2, #id2],
iterator_types = ["parallel", "parallel"]}
ins(%lhs, %rhs : tensor<?x?xf32>, tensor<?x?xf32>)
outs(%out : tensor<?x?xf32>) {
^bb0(%a : f32, %b : f32, %old : f32):
%sum = arith.addf %a, %b : f32
linalg.yield %sum : f32
} -> tensor<?x?xf32>
return %result : tensor<?x?xf32>
}
The indexing maps are identity maps, so every result element reads the matching element from both inputs.
57.10.3 Buffer Matmul
func.func @matmul_buffer(%a : memref<4x8xf32>,
%b : memref<8x16xf32>,
%c : memref<4x16xf32>) {
linalg.matmul
ins(%a, %b : memref<4x8xf32>, memref<8x16xf32>)
outs(%c : memref<4x16xf32>)
return
}
This is buffer Linalg. It can lower directly to loops because the destination is a memref that can be loaded and stored.
57.10.4 Packing A Tensor
func.func @pack_tensor(%src : tensor<16x32xf32>,
%dst : tensor<2x4x8x8xf32>)
-> tensor<2x4x8x8xf32> {
%packed = linalg.pack %src
inner_dims_pos = [0, 1]
inner_tiles = [8, 8]
into %dst : tensor<16x32xf32> -> tensor<2x4x8x8xf32>
return %packed : tensor<2x4x8x8xf32>
}
This makes a blocked layout explicit. The original 16x32 shape becomes 2x4x8x8, where the last two dimensions are tile dimensions.
57.10.5 Softmax
func.func @softmax(%input : tensor<2x4xf32>,
%out : tensor<2x4xf32>) -> tensor<2x4xf32> {
%result = linalg.softmax dimension(1)
ins(%input : tensor<2x4xf32>)
outs(%out : tensor<2x4xf32>) -> tensor<2x4xf32>
return %result : tensor<2x4xf32>
}
linalg.softmax is an aggregate op. It represents a useful high-level pattern, but it can be decomposed into smaller structured operations.
57.11 Mental Model
Read a Linalg op in this order:
- Look at
insandouts. - Ask whether the op is tensor-value form or memref-buffer form.
- Look at iterator types to see which loops are parallel and which reduce.
- Look at indexing maps to see how each loop indexes each operand.
- Look at the scalar region or named op to see the element computation.
For named ops, the first pass is easier:
linalg.matmul means a contraction
linalg.add means elementwise add
linalg.pooling_nhwc_max means max pooling in NHWC layout
For optimization, the named op can be generalized:
linalg.matmul -> linalg.generic
Then later it can be tiled, fused, vectorized, bufferized, or lowered to loops.
57.12 Gotchas
linalg.transposemoves data.memref.transposeis a metadata view change.- Tensor Linalg and memref Linalg have different lowering options. Loop lowering expects buffer semantics.
outsare not just outputs. They are destination operands and may be read as initial accumulator values.linalg.genericis powerful, but not every generic op can be recognized as a named op.- Indexing maps are part of the computation. Changing a map can change the meaning as much as changing the scalar body.
- Iterator types matter. Marking a reduction dimension as parallel is a semantic bug.
convert-linalg-to-stdis for library-call lowering, not the normal structured loop expansion path.- Named op layout suffixes are meaningful.
nchw_fchwandnhwc_hwcfare different data layouts. - Pack/unpack can imply padding behavior. Missing padding values can be undefined behavior when tile sizes do not divide dimensions evenly.
- The transform dialect operations that target Linalg are not themselves Linalg dialect ops.
57.13 Source Map
Primary source files:
mlir/include/mlir/Dialect/Linalg/IR/LinalgBase.tdmlir/include/mlir/Dialect/Linalg/IR/LinalgDoc.tdmlir/include/mlir/Dialect/Linalg/IR/LinalgOps.tdmlir/include/mlir/Dialect/Linalg/IR/LinalgStructuredOps.tdmlir/include/mlir/Dialect/Linalg/IR/LinalgNamedStructuredOps.yamlmlir/include/mlir/Dialect/Linalg/IR/LinalgRelayoutOps.tdmlir/include/mlir/Dialect/Linalg/IR/LinalgInterfaces.tdmlir/include/mlir/Dialect/Linalg/IR/LinalgEnums.tdmlir/lib/Dialect/Linalg/IR/LinalgDialect.cppmlir/lib/Dialect/Linalg/IR/LinalgOps.cppmlir/lib/Dialect/Linalg/IR/LinalgInterfaces.cpp
Transform source files:
mlir/include/mlir/Dialect/Linalg/Passes.tdmlir/lib/Dialect/Linalg/Transforms/Loops.cppmlir/lib/Dialect/Linalg/Transforms/Generalization.cppmlir/lib/Dialect/Linalg/Transforms/ElementwiseToLinalg.cppmlir/lib/Dialect/Linalg/Transforms/ElementwiseOpFusion.cppmlir/lib/Dialect/Linalg/Transforms/FoldIntoElementwise.cppmlir/lib/Dialect/Linalg/Transforms/DropUnitDims.cppmlir/lib/Dialect/Linalg/Transforms/BlockPackMatmul.cppmlir/lib/Dialect/Linalg/Transforms/SimplifyDepthwiseConv.cppmlir/lib/Dialect/Linalg/Transforms/Vectorization.cppmlir/lib/Dialect/Linalg/Transforms/Tiling.cppmlir/lib/Dialect/Linalg/Transforms/Fusion.cpp
Conversion source files:
mlir/include/mlir/Conversion/LinalgToStandard/LinalgToStandard.hmlir/lib/Conversion/LinalgToStandard/LinalgToStandard.cppmlir/include/mlir/Conversion/TensorToLinalg/TensorToLinalg.hmlir/lib/Conversion/TensorToLinalg/TensorToLinalg.cppmlir/lib/Conversion/TensorToLinalg/TensorToLinalgPass.cppmlir/include/mlir/Conversion/TosaToLinalg/TosaToLinalg.hmlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cppmlir/lib/Conversion/TosaToLinalg/TosaToLinalgNamed.cppmlir/lib/Conversion/TosaToLinalg/TosaToLinalgPass.cpp
Transform dialect extension files:
mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.tdmlir/include/mlir/Dialect/Linalg/TransformOps/LinalgMatchOps.tdmlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cppmlir/lib/Dialect/Linalg/TransformOps/LinalgMatchOps.cpp
Useful tests:
mlir/test/Dialect/Linalg/roundtrip.mlirmlir/test/Dialect/Linalg/named-ops.mlirmlir/test/Dialect/Linalg/generalize-named-ops.mlirmlir/test/Dialect/Linalg/linalg-morph-category-ops.mlirmlir/test/Dialect/Linalg/loops.mlirmlir/test/Dialect/Linalg/convert-elementwise-to-linalg.mlirmlir/test/Dialect/Linalg/decompose-ops.mlirmlir/test/Dialect/Linalg/simplify-depthwise-conv.mlirmlir/test/Dialect/Linalg/block-pack-matmul.mlirmlir/test/Dialect/Linalg/transform-ops.mlirmlir/test/Conversion/TensorToLinalg/tensor-ops-to-linalg.mlirmlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlirmlir/test/Conversion/TosaToLinalg/tosa-to-linalg-named.mlir