Skip to content

Commit 0c59f51

Browse files
author
MaheshRavishankar
committed
[mlir][Linalg] NFC: Expose some utility functions used for promotion.
Exposing some utility functions from Linalg to allow for promotion of fused views outside of the core tile+fuse logic. This is an alternative to patch D91322 which adds the promotion logic to the tileAndFuse method. Downside with that approach is that it is not easily customizable based on needs. Differential Revision: https://reviews.llvm.org/D91503
1 parent f8284d2 commit 0c59f51

File tree

4 files changed

+33
-21
lines changed

4 files changed

+33
-21
lines changed

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,20 @@ struct LinalgPromotionOptions {
234234
}
235235
};
236236

237+
/// Creates a new buffer using the `allocationFn` provided. The size of this
238+
/// buffer is the smallest constant bounding size along each dimension that can
239+
/// be computed for the size of the result of `subView`. Returns the allocated
240+
/// buffer as `fullLocalView` and the view that matches the size of the result
241+
/// of subview operation as `partialLocalView`.
242+
struct PromotionInfo {
243+
Value fullLocalView;
244+
Value partialLocalView;
245+
};
246+
Optional<PromotionInfo>
247+
promoteSubviewAsNewBuffer(OpBuilder &b, Location loc, SubViewOp subView,
248+
AllocBufferCallbackFn allocationFn,
249+
OperationFolder *folder = nullptr);
250+
237251
/// Promotes the `subViews` into a new buffer allocated at the insertion point
238252
/// `b`. Promotion occurs in 3 steps:
239253
/// 1. Create a new buffer for a full tile (i.e. not clipped at the boundary).

mlir/include/mlir/Dialect/Linalg/Utils/Utils.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "mlir/Dialect/StandardOps/EDSC/Intrinsics.h"
1818
#include "mlir/Dialect/StandardOps/IR/Ops.h"
1919

20+
#include "llvm/ADT/MapVector.h"
2021
#include "llvm/ADT/SetVector.h"
2122

2223
using mlir::edsc::intrinsics::AffineIndexedValue;
@@ -82,6 +83,13 @@ bool isProducerLastWriteOfView(const LinalgDependenceGraph &graph,
8283
bool isFusableInto(const LinalgDependenceGraph &graph, LinalgOp consumer,
8384
Value consumedView, LinalgOp producer);
8485

86+
using FusableOpDependencesTy = llvm::MapVector<
87+
Operation *,
88+
SmallVector<LinalgDependenceGraph::LinalgDependenceGraphElem, 1>>;
89+
FusableOpDependencesTy
90+
findAllFusableDependences(ArrayRef<LinalgOp> ops,
91+
const LinalgDependenceGraph &dependenceGraph);
92+
8593
/// Fuses producer into consumer if the producer is structurally feasible and
8694
/// the fusion would not violate dependencies.
8795
/// Implements the fusion part of the "tileAndFuse on buffers"

mlir/lib/Dialect/Linalg/Transforms/Fusion.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -531,10 +531,6 @@ static AffineMap pruneReductionDimsFromMap(ArrayRef<Attribute> iteratorTypes,
531531
return getProjectedMap(map, projectedDims);
532532
}
533533

534-
using FusableOpDependencesTy = llvm::MapVector<
535-
Operation *,
536-
SmallVector<LinalgDependenceGraph::LinalgDependenceGraphElem, 1>>;
537-
538534
/// Returns the mapping from iterations in the consumer that write to the same
539535
/// location as the iterations in the producer. To do so use
540536
/// - indexing map of the fused view in the consumer : consumerIndexMap
@@ -718,10 +714,9 @@ collectFusableLoops(ArrayRef<LinalgOp> ops,
718714
return fusableLoops;
719715
}
720716

721-
/// Find all dependences that are to be fusable.
722-
static FusableOpDependencesTy
723-
findAllFusableDependences(ArrayRef<LinalgOp> ops,
724-
const LinalgDependenceGraph &dependenceGraph) {
717+
/// Find all dependences that are fusable.
718+
FusableOpDependencesTy mlir::linalg::findAllFusableDependences(
719+
ArrayRef<LinalgOp> ops, const LinalgDependenceGraph &dependenceGraph) {
725720
FusableOpDependencesTy fusableDependences;
726721
// TODO: Currently fusion would not be legal if the fusable dependence is to
727722
// the same producer but different indexing map in the consumer. Fix this, but
@@ -825,6 +820,7 @@ fuseOperations(OpBuilder &builder, LinalgOp tiledOp,
825820
fusedLoopsAndRanges[loop] = getRangeFromOperandShape(
826821
builder, tiledOp.getLoc(), shapeDim.shape, shapeDim.dimension);
827822
}
823+
828824
SmallVector<LinalgOp, 1> fusedOps(fusionCandidates.size());
829825
for (auto candidate : enumerate(llvm::reverse(fusionCandidates))) {
830826
LinalgOp fusedOp = fuse(builder, candidate.value(), fusedLoopsAndRanges);

mlir/lib/Dialect/Linalg/Transforms/Promotion.cpp

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,6 @@ struct LinalgOpInstancePromotionOptions {
166166
/// Alignment of promoted buffer.
167167
Optional<unsigned> alignment;
168168
};
169-
170-
struct PromotionInfo {
171-
Value fullLocalView;
172-
Value partialLocalView;
173-
};
174169
} // namespace
175170

176171
LinalgOpInstancePromotionOptions::LinalgOpInstancePromotionOptions(
@@ -233,10 +228,10 @@ LinalgOpInstancePromotionOptions::LinalgOpInstancePromotionOptions(
233228
// To account for general boundary effects, padding must be performed on the
234229
// boundary tiles. For now this is done with an unconditional `fill` op followed
235230
// by a partial `copy` op.
236-
static Optional<PromotionInfo>
237-
promoteSubviewAsNewBuffer(OpBuilder &b, Location loc, SubViewOp subView,
238-
LinalgOpInstancePromotionOptions const &options,
239-
OperationFolder *folder) {
231+
Optional<PromotionInfo> mlir::linalg::promoteSubviewAsNewBuffer(
232+
OpBuilder &b, Location loc, SubViewOp subView,
233+
AllocBufferCallbackFn allocationFn, OperationFolder *folder) {
234+
ScopedContext scopedContext(b, loc);
240235
auto viewType = subView.getType();
241236
auto rank = viewType.getRank();
242237
SmallVector<Value, 4> fullSizes, partialSizes;
@@ -254,8 +249,7 @@ promoteSubviewAsNewBuffer(OpBuilder &b, Location loc, SubViewOp subView,
254249
SmallVector<int64_t, 4> dynSizes(fullSizes.size(), -1);
255250
// If a callback is not specified, then use the default implementation for
256251
// allocating the promoted buffer.
257-
Optional<Value> fullLocalView =
258-
options.allocationFn(b, subView, fullSizes, folder);
252+
Optional<Value> fullLocalView = allocationFn(b, subView, fullSizes, folder);
259253
if (!fullLocalView)
260254
return {};
261255
auto zero = folded_std_constant_index(folder, 0);
@@ -279,8 +273,8 @@ promoteSubViews(OpBuilder &b, Location loc,
279273

280274
for (auto v : options.subViews) {
281275
SubViewOp subView = cast<SubViewOp>(v.second.getDefiningOp());
282-
Optional<PromotionInfo> promotionInfo =
283-
promoteSubviewAsNewBuffer(b, loc, subView, options, folder);
276+
Optional<PromotionInfo> promotionInfo = promoteSubviewAsNewBuffer(
277+
b, loc, subView, options.allocationFn, folder);
284278
if (!promotionInfo)
285279
return {};
286280
promotionInfoMap[v.first] = *promotionInfo;

0 commit comments

Comments
 (0)