Skip to content

Commit 44cfea0

Browse files
[mlir][Linalg] Retire LinalgStrategyTilePass and filter-based pattern.
Context: https://discourse.llvm.org/t/psa-retire-linalg-filter-based-patterns/63785 Uses of `LinalgTilingPattern::returningMatchAndRewrite` are replaced by a top-level `tileWithLinalgTilingOptions` function that is marked obsolete and serves as a temporary means to transition away from `LinalgTilingOptions`-based tiling. LinalgTilingOptions supports too many options that have been orthogonalized with the use of the transform dialect. Additionally, the revision introduces a `transform.structured.tile_to_scf_for` structured transform operation that is needed to properly tile `tensor.pad` via the TilingInterface. Uses of `transform.structured.tile` will be deprecated and replaced by this new op. This will achieve the deprecation of `linalg::tileLinalgOp`. Context: https://discourse.llvm.org/t/psa-retire-tileandfuselinalgops-method/63850 In the process of transitioning, tests that were performing tile and distribute on tensors are retired: transformations should be orthogonalized better in the future. In particular, tiling to specific loop types and tileAndDistribute behavior are not available via the transform ops. The behavior is still available as part of the `tileWithLinalgTilingOptions` method to allow downstream clients to transition without breakages but is meant to be retired soon. As more tests are ported to the transform dialect, it became necessary to introduce a test-transform-dialect-erase-schedule-pass to discard the transform specification once applied so that e2e lowering and execution is possible. Lastly, a number of redundant tests that were testing composition of patterns are retired as they are available with a better mechanism via the transform dialect. Differential Revision: https://reviews.llvm.org/D135573
1 parent df8264c commit 44cfea0

31 files changed

+588
-1705
lines changed

mlir/include/mlir/Dialect/Linalg/Passes.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,6 @@ std::unique_ptr<Pass> createFoldReshapeOpsByLinearizationPass();
3838

3939
std::unique_ptr<Pass> createLinalgNamedOpConversionPass();
4040

41-
std::unique_ptr<OperationPass<func::FuncOp>>
42-
createLinalgTilingPass(ArrayRef<int64_t> tileSizes = {},
43-
linalg::LinalgTilingLoopType loopType =
44-
linalg::LinalgTilingLoopType::Loops);
45-
4641
std::unique_ptr<OperationPass<func::FuncOp>>
4742
createLinalgInlineScalarOperandsPass();
4843

mlir/include/mlir/Dialect/Linalg/Passes.td

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -102,22 +102,6 @@ def LinalgBufferize : Pass<"linalg-bufferize", "func::FuncOp"> {
102102
];
103103
}
104104

105-
def LinalgTilingPass : Pass<"linalg-tile", "func::FuncOp"> {
106-
let summary = "Tile operations in the linalg dialect";
107-
let constructor = "mlir::createLinalgTilingPass()";
108-
let dependentDialects = [
109-
"AffineDialect",
110-
"linalg::LinalgDialect",
111-
"memref::MemRefDialect",
112-
"scf::SCFDialect"
113-
];
114-
let options = [
115-
ListOption<"tileSizes", "tile-sizes", "int64_t", "Tile sizes">,
116-
Option<"loopType", "loop-type", "std::string", /*default=*/"\"for\"",
117-
"Specify the type of loops to generate: for, parallel">
118-
];
119-
}
120-
121105
def LinalgGeneralization : Pass<"linalg-generalize-named-ops", "func::FuncOp"> {
122106
let summary = "Convert named ops into generic ops";
123107
let constructor = "mlir::createLinalgGeneralizationPass()";
@@ -162,19 +146,6 @@ def LinalgDetensorize : Pass<"linalg-detensorize", ""> {
162146
];
163147
}
164148

165-
def LinalgStrategyTilePass
166-
: Pass<"linalg-strategy-tile-pass", "func::FuncOp"> {
167-
let summary = "Configurable pass to apply pattern-based linalg tiling.";
168-
let constructor = "mlir::createLinalgStrategyTilePass()";
169-
let dependentDialects = ["linalg::LinalgDialect"];
170-
let options = [
171-
Option<"anchorFuncName", "anchor-func", "std::string", /*default=*/"",
172-
"Which func op is the anchor to latch on.">,
173-
Option<"anchorOpName", "anchor-op", "std::string", /*default=*/"",
174-
"Which linalg op within the func is the anchor to latch on.">,
175-
];
176-
}
177-
178149
def LinalgStrategyRemoveMarkersPass
179150
: Pass<"linalg-strategy-remove-markers-pass", "func::FuncOp"> {
180151
let summary = "Cleanup pass that drops markers.";

mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,63 @@ def TileToForeachThreadOp :
751751
}];
752752
}
753753

754+
def TileToScfForOp : Op<Transform_Dialect, "structured.tile_to_scf_for",
755+
[DeclareOpInterfaceMethods<TransformOpInterface>,
756+
DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
757+
let description = [{
758+
Indicates that the given `target` op should be tiled with the given sizes.
759+
This transform generates a loop nest with a smaller ("tiled") target
760+
operation in its body. The target must implement TilingInterface.
761+
762+
Tile sizes may be known at transformation time, in which case they are
763+
expected to be provided in the `static_size` attribute, or not, in which
764+
case the tile value must be computed by the payload IR and the handle to the
765+
operation computing it must be provided through `dynamic_sizes`. When the
766+
sizes are not known statically, the corresponding entry in the
767+
`static_sizes` attribute must be set to `ShapedType::kDynamicSize`. Only
768+
the dynamic sizes must be provided in `dynamic_sizes`, i.e., there should
769+
be as many handles as `ShapedType::kDynamicSize` values in the
770+
`static_sizes` attribute. A static size of `0` indicates that the dimension
771+
should not be tiled. No loop will be generated for such dimensions. If all
772+
tile sizes are `0`, this transform is effectively a no-op.
773+
774+
This op returns handles to the tiled op (in the generated loop nest) and the
775+
generated loops. The number of loops is the number of tile sizes that are
776+
statically known to be non-zero.
777+
778+
#### Return modes
779+
780+
On success, the resulting handles are associated with co-indexed lists of
781+
tiled operations and loops around them.
782+
783+
This operation only supports TilingInterface ops and produces a silenceable
784+
failure if the input contains any non-TilingInterface ops. The ops preceding
785+
it in the list associated with the `target` handle will have been tiled.
786+
787+
This operation produces a silenceable failure if the `dynamic_sizes` handles
788+
are associated with lists of payload operations of a size different than
789+
that of the list associated with the `target` handle.
790+
791+
If the internal implementation of tiling for any of the operations fails,
792+
produces a definite failure.
793+
}];
794+
795+
let arguments = (ins PDL_Operation:$target,
796+
Variadic<PDL_Operation>:$dynamic_sizes,
797+
DefaultValuedAttr<I64ArrayAttr, "{}">:$static_sizes,
798+
DefaultValuedAttr<I64ArrayAttr, "{}">:$interchange);
799+
let results = (outs PDL_Operation:$tiled_linalg_op,
800+
Variadic<PDL_Operation>:$loops);
801+
802+
let hasCustomAssemblyFormat = 1;
803+
804+
let extraClassDeclaration = [{
805+
/// Returns the list of tile sizes, which may be static (Attribute) or
806+
/// dynamic (Value).
807+
SmallVector<OpFoldResult> getMixedSizes();
808+
}];
809+
}
810+
754811
def VectorizeOp : Op<Transform_Dialect, "structured.vectorize",
755812
[FunctionalStyleTransformOpTrait, MemoryEffectsOpInterface,
756813
TransformEachOpTrait, TransformOpInterface]> {

mlir/include/mlir/Dialect/Linalg/Transforms/CodegenStrategy.h

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -30,41 +30,8 @@ struct Transformation {
3030
LinalgTransformationFilter::FilterFunction filter = nullptr;
3131
};
3232

33-
/// Represent one application of LinalgStrategyTilePass.
34-
struct Tile : public Transformation {
35-
Tile(StringRef name, linalg::LinalgTilingOptions options,
36-
LinalgTransformationFilter::FilterFunction f = nullptr)
37-
: Transformation(std::move(f)), opName(name),
38-
options(std::move(options)) {}
39-
40-
void addToPassPipeline(OpPassManager &pm,
41-
LinalgTransformationFilter m) const override {
42-
pm.addPass(createLinalgStrategyTilePass(opName, options, m));
43-
}
44-
45-
private:
46-
std::string opName;
47-
linalg::LinalgTilingOptions options;
48-
};
49-
5033
/// Codegen strategy controls how a Linalg op is progressively lowered.
5134
struct CodegenStrategy {
52-
/// Append a pattern to add a level of tiling for Op `opName` with tiling
53-
/// `options`.
54-
CodegenStrategy &
55-
tile(StringRef opName, const linalg::LinalgTilingOptions &options,
56-
const LinalgTransformationFilter::FilterFunction &f = nullptr) {
57-
transformationSequence.emplace_back(
58-
std::make_unique<Tile>(opName, options, f));
59-
return *this;
60-
}
61-
/// Conditionally append a pattern to add a level of tiling for
62-
/// `LinalgOpType` with tiling `options`.
63-
CodegenStrategy &
64-
tileIf(bool b, StringRef opName, linalg::LinalgTilingOptions options,
65-
LinalgTransformationFilter::FilterFunction f = nullptr) {
66-
return b ? tile(opName, std::move(options), std::move(f)) : *this;
67-
}
6835
/// Configure the post staged-patterns global enabling passes options.
6936
CodegenStrategy &
7037
setVectorTransferToSCFOptions(LinalgEnablingOptions options) {

mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h

Lines changed: 19 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -696,57 +696,26 @@ struct LinalgTilingOptions {
696696
RewritePatternSet getLinalgTilingCanonicalizationPatterns(MLIRContext *ctx);
697697
void populateLinalgTilingCanonicalizationPatterns(RewritePatternSet &patterns);
698698

699-
///
700-
/// Linalg tiling pattern.
701-
///
702-
/// Apply the `tiling` transformation as a pattern.
703-
/// `filter` controls LinalgTransformMarker matching and update when specified.
704-
/// See `tiling` for more details.
705-
// TODO: TiledOpInterface
706-
struct LinalgTilingPattern : public OpInterfaceRewritePattern<LinalgOp> {
707-
/// Construct a generic pattern applied to all LinalgOp that verify `filter`.
708-
LinalgTilingPattern(
709-
MLIRContext *context, LinalgTilingOptions options,
710-
LinalgTransformationFilter f = LinalgTransformationFilter(),
711-
PatternBenefit benefit = 1);
712-
713-
/// Construct a pattern specifically applied to `opName`.
714-
LinalgTilingPattern(
715-
StringRef opName, MLIRContext *context, LinalgTilingOptions options,
716-
LinalgTransformationFilter f = LinalgTransformationFilter(),
717-
PatternBenefit benefit = 1);
718-
719-
/// `matchAndRewrite` implementation that returns the significant transformed
720-
/// pieces of IR.
721-
FailureOr<TiledLinalgOp>
722-
returningMatchAndRewrite(LinalgOp op, PatternRewriter &rewriter) const;
723-
724-
LogicalResult matchAndRewrite(LinalgOp op,
725-
PatternRewriter &rewriter) const override {
726-
return returningMatchAndRewrite(op, rewriter);
727-
}
728-
729-
private:
730-
/// LinalgTransformMarker handles special attribute manipulations.
731-
LinalgTransformationFilter filter;
732-
/// Options to control tiling;
733-
LinalgTilingOptions options;
734-
};
699+
/// Perform tiling using LinalgTilingOptions.
700+
/// Note: this is on a path to deprecation that only works on LinalgOp.
701+
/// Clients should favor using `tileUsingSCFForOp` that more generally works on
702+
/// TilingInterface.
703+
FailureOr<TiledLinalgOp>
704+
tileWithLinalgTilingOptions(RewriterBase &rewriter, LinalgOp op,
705+
const LinalgTilingOptions &options);
735706

736707
///
737708
/// Linalg padding pattern.
738709
///
739710
/// Apply the `padding` transformation as a pattern.
740-
/// `filter` controls LinalgTransformMarker matching and update when specified.
741711
/// See `padding` for more details.
742712
struct LinalgPaddingPattern : public OpInterfaceRewritePattern<LinalgOp> {
743-
/// Construct a generic pattern applied to all LinalgOp that verify `filter`.
744713
LinalgPaddingPattern(MLIRContext *context,
745714
LinalgPaddingOptions options = LinalgPaddingOptions(),
746715
PatternBenefit benefit = 1);
747716

748-
/// `matchAndRewrite` implementation that returns the significant transformed
749-
/// pieces of IR.
717+
/// `matchAndRewrite` implementation that returns the significant
718+
/// transformed pieces of IR.
750719
FailureOr<LinalgOp> returningMatchAndRewrite(LinalgOp op,
751720
PatternRewriter &rewriter) const;
752721

@@ -954,9 +923,9 @@ void populateLinalgNamedOpsGeneralizationPatterns(
954923

955924
/// Linalg decompose convolutions patterns
956925

957-
/// Populates patterns to decompose high-D convolution ops into low-D ones. This
958-
/// is a step in progressive lowering for convolution ops, afterwards we can
959-
/// vectorize the low-D convolution ops.
926+
/// Populates patterns to decompose high-D convolution ops into low-D ones.
927+
/// This is a step in progressive lowering for convolution ops, afterwards we
928+
/// can vectorize the low-D convolution ops.
960929
void populateDecomposeConvolutionPatterns(RewritePatternSet &patterns,
961930
PatternBenefit benefit = 1);
962931

@@ -977,8 +946,8 @@ struct PadOpTransformationPattern : public OpRewritePattern<tensor::PadOp> {
977946
/// a static bounding box. Use `paddingValues` and `packPaddings` to set padding
978947
/// value and nofold attribute of the created tensor::PadOps, respectively.
979948
/// Update `paddedOp` to the cloned operation with statically shaped
980-
/// `paddingDimensions` and return the extracted dynamically shaped results. If
981-
/// padding fails, return failure.
949+
/// `paddingDimensions` and return the extracted dynamically shaped results.
950+
/// If padding fails, return failure.
982951
FailureOr<SmallVector<Value>>
983952
rewriteAsPaddedOp(OpBuilder &b, LinalgOp opToPad,
984953
ArrayRef<int64_t> paddingDimensions,
@@ -1132,29 +1101,6 @@ class VectorizationPatterns<> {
11321101
const LinalgTransformationFilter &f) {}
11331102
};
11341103

1135-
template <typename... OpTypes>
1136-
class TilingPatterns;
1137-
1138-
template <>
1139-
class TilingPatterns<> {
1140-
public:
1141-
static void insert(RewritePatternSet &patterns,
1142-
const LinalgTilingOptions &options,
1143-
const LinalgTransformationFilter &f) {}
1144-
};
1145-
1146-
template <typename OpTy, typename... OpTypes>
1147-
class TilingPatterns<OpTy, OpTypes...> {
1148-
public:
1149-
static void insert(RewritePatternSet &patterns,
1150-
const LinalgTilingOptions &options,
1151-
const LinalgTransformationFilter &f) {
1152-
patterns.add<LinalgTilingPattern>(OpTy::getOperationName(),
1153-
patterns.getContext(), options, f);
1154-
TilingPatterns<OpTypes...>::insert(patterns, options, f);
1155-
}
1156-
};
1157-
11581104
/// Split Reduction options.
11591105
struct SplitReductionOptions {
11601106
// Ratio used to split the reduction dimension. If the ratio is <= 1, nothing
@@ -1181,8 +1127,10 @@ void populateSplitReductionPattern(
11811127

11821128
/// Apply transformation to split the single linalg op reduction into a parallel
11831129
/// and reduction dimension. Then create a new linalg.generic op doing the rest
1184-
/// of the reduction. Return the new linalg op with an extra parallel dimension
1185-
/// or failure if the transformation didn't happen.
1130+
/// of the reduction.
1131+
/// Return the new linalg op with an extra parallel dimension or failure if the
1132+
/// transformation didn't happen.
1133+
///
11861134
/// Example:
11871135
/// ```
11881136
/// %r = linalg.generic {indexing_maps = [affine_map<(d0) -> (d0)>,
@@ -1265,7 +1213,7 @@ splitReduction(PatternRewriter &b, LinalgOp op,
12651213
/// %3 = linalg.generic {indexing_maps = [#map0, #map1, #map2, #map3],
12661214
/// iterator_types = ["parallel", "parallel", "parallel", "reduction"]}
12671215
/// ins(%A, %B, %2 : tensor<16x256xf32>, tensor<256x32xf32>, tensor<64x4xi1>)
1268-
/// outs(%1 : tensor<16x32x64xf32>) {
1216+
/// outs(%1 : tensor<16x32x64xf32>) {
12691217
/// ^bb0(%arg3: f32, %arg4: f32, %arg5: i1, %arg6: f32):
12701218
/// %5 = arith.mulf %arg3, %arg4 : f32
12711219
/// %6 = arith.addf %arg6, %5 : f32

0 commit comments

Comments
 (0)