Skip to content

Commit 2803905

Browse files
authored
[MLIR][Transform] Hoist Pad generates linalg.transpose (#109669)
For readability purpose, generate linalg named ops when possible. For maintainability purpose, get rid of duplicated code.
1 parent c808e66 commit 2803905

File tree

8 files changed

+27
-69
lines changed

8 files changed

+27
-69
lines changed

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ namespace detail {
549549
struct PackingResult {
550550
SmallVector<OpFoldResult> offsets, sizes, strides;
551551
SmallVector<Value> clonedLoopIvs, leadingPackedTensorIndexings;
552-
GenericOp maybeTransposeOp;
552+
TransposeOp maybeTransposeOp;
553553
tensor::PadOp hoistedPadOp;
554554
};
555555

@@ -568,9 +568,9 @@ buildPackingLoopNest(RewriterBase &rewriter, tensor::PadOp opToHoist,
568568
/// a larger tensor. On success, `opToHoist` is replaced by the cloned version
569569
/// in the packing loop so the caller can continue reasoning about the padding
570570
/// operation. If `transposeVector` is non-empty, hoist padding introduces a
571-
/// GenericOp to transpose the padded tensor before inserting it into the packed
572-
/// tensor. A `transposeVector` can change the storage order of the padded
573-
/// tensor but does not change the order of the pack or compute loops.
571+
/// TransposeOp to transpose the padded tensor before inserting it into the
572+
/// packed tensor. A `transposeVector` can change the storage order of the
573+
/// padded tensor but does not change the order of the pack or compute loops.
574574
///
575575
/// TODO: In the future, we should consider rewriting as a tensor.pack after
576576
/// hoisting since this abstraction is now available.
@@ -615,13 +615,13 @@ FailureOr<Value>
615615
hoistPaddingOnTensors(RewriterBase &rewriter, tensor::PadOp opToHoist,
616616
int64_t numLoops, ArrayRef<int64_t> transposeVector,
617617
tensor::PadOp &hoistedOp,
618-
SmallVectorImpl<GenericOp> &transposeOps);
618+
SmallVectorImpl<TransposeOp> &transposeOps);
619619
/// Calls into `hoistPaddingOnTensors` with a local IRRewriter.
620620
FailureOr<Value>
621621
hoistPaddingOnTensors(tensor::PadOp opToHoist, int64_t numLoops,
622622
ArrayRef<int64_t> transposeVector,
623623
tensor::PadOp &hoistedOp,
624-
SmallVectorImpl<GenericOp> &transposeOps);
624+
SmallVectorImpl<TransposeOp> &transposeOps);
625625

626626
/// Apply padding and hoisting to `linalgOp` according to the configuration
627627
/// specified in `options`.

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,6 @@ bool isReductionIterator(utils::IteratorType iteratorType);
7575
Value makeComposedPadHighOp(OpBuilder &b, Location loc, RankedTensorType type,
7676
Value source, Value pad, bool nofold);
7777

78-
/// Returns a GenericOp that transposes `inputTensor` into `outputTensor`
79-
/// using `transposeVector` to permute the `inputTensor` dimensions.
80-
GenericOp makeTransposeOp(OpBuilder &b, Location loc, Value inputTensor,
81-
Value outputTensor,
82-
ArrayRef<int64_t> transposeVector);
83-
8478
/// Returns GenericOp that copies an n-D memref. Unlike the current
8579
/// implementation of memref::CopyOp, this op can further tile, lower to loops
8680
/// or vectorize.

mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2000,7 +2000,7 @@ transform::HoistPadOp::applyToOne(transform::TransformRewriter &rewriter,
20002000
transform::ApplyToEachResultList &results,
20012001
transform::TransformState &state) {
20022002
tensor::PadOp hoistedPadOp;
2003-
SmallVector<GenericOp> transposeOps;
2003+
SmallVector<TransposeOp> transposeOps;
20042004
FailureOr<Value> result =
20052005
hoistPaddingOnTensors(rewriter, target, getNumLoops(), getTranspose(),
20062006
hoistedPadOp, transposeOps);

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

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -633,15 +633,15 @@ static FailureOr<PackingResult> buildPackingLoopNestImpl(
633633
rewriter.getIndexAttr(1));
634634

635635
// Step 3. Optionally transpose the padded tensor.
636-
GenericOp maybeTransposeOp;
636+
TransposeOp maybeTransposeOp;
637637
Value paddedTensor = bvm.lookup(opToHoist.getResult());
638638
if (!transposeVector.empty()) {
639639
Value outputTensor = rewriter.create<tensor::ExtractSliceOp>(
640640
loc, transposedTensorType, hoistedPackedTensor, offsets, sizes,
641641
strides);
642-
maybeTransposeOp = makeTransposeOp(rewriter, loc, paddedTensor,
643-
outputTensor, transposeVector);
644-
paddedTensor = maybeTransposeOp.getResult(0);
642+
maybeTransposeOp = rewriter.create<linalg::TransposeOp>(
643+
loc, paddedTensor, outputTensor, transposeVector);
644+
paddedTensor = maybeTransposeOp.getResult()[0];
645645
}
646646

647647
// Innermost tensor.insert_slice and yields are optional / need loops.
@@ -938,7 +938,7 @@ static Value replaceByPackingResult(RewriterBase &rewriter,
938938
FailureOr<Value> mlir::linalg::hoistPaddingOnTensors(
939939
RewriterBase &rewriter, tensor::PadOp opToHoist, int64_t numLoops,
940940
ArrayRef<int64_t> transposeVector, tensor::PadOp &hoistedOp,
941-
SmallVectorImpl<GenericOp> &transposeOps) {
941+
SmallVectorImpl<TransposeOp> &transposeOps) {
942942
LLVM_DEBUG(DBGS() << "\n"; DBGS() << " Try to hoist " << *(opToHoist) << "\n";
943943
DBGS() << " by " << numLoops << " loops\n");
944944

@@ -980,9 +980,9 @@ FailureOr<Value> mlir::linalg::hoistPaddingOnTensors(
980980
// Transpose the packed tensor back to the original storage order.
981981
Value emptyTensor = rewriter.create<tensor::EmptyOp>(
982982
loc, paddedTensorType.getShape(), paddedTensorType.getElementType());
983-
GenericOp unTransposeOp =
984-
makeTransposeOp(rewriter, loc, newResult, emptyTensor, transposeVector);
985-
newResult = unTransposeOp.getResult(0);
983+
TransposeOp unTransposeOp = rewriter.create<linalg::TransposeOp>(
984+
loc, newResult, emptyTensor, transposeVector);
985+
newResult = unTransposeOp.getResult()[0];
986986
transposeOps.push_back(unTransposeOp);
987987
}
988988

@@ -999,11 +999,10 @@ FailureOr<Value> mlir::linalg::hoistPaddingOnTensors(
999999
return newResult;
10001000
}
10011001

1002-
FailureOr<Value>
1003-
mlir::linalg::hoistPaddingOnTensors(tensor::PadOp opToHoist, int64_t numLoops,
1004-
ArrayRef<int64_t> transposeVector,
1005-
tensor::PadOp &hoistedOp,
1006-
SmallVectorImpl<GenericOp> &transposeOps) {
1002+
FailureOr<Value> mlir::linalg::hoistPaddingOnTensors(
1003+
tensor::PadOp opToHoist, int64_t numLoops,
1004+
ArrayRef<int64_t> transposeVector, tensor::PadOp &hoistedOp,
1005+
SmallVectorImpl<TransposeOp> &transposeOps) {
10071006
IRRewriter rewriter(opToHoist.getContext());
10081007
return hoistPaddingOnTensors(rewriter, opToHoist, numLoops, transposeVector,
10091008
hoistedOp, transposeOps);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ mlir::linalg::padAndHoistLinalgOp(RewriterBase &rewriter, LinalgOp linalgOp,
299299
}
300300

301301
tensor::PadOp hoistedOp;
302-
SmallVector<GenericOp> transposeOps;
302+
SmallVector<TransposeOp> transposeOps;
303303
SmallVector<int64_t> transposeVector =
304304
en.index() < options.transposePaddings.size()
305305
? options.transposePaddings[en.index()]

mlir/lib/Dialect/Linalg/Utils/Utils.cpp

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -249,41 +249,6 @@ Value makeComposedPadHighOp(OpBuilder &b, Location loc, RankedTensorType type,
249249
return sliceOp.getSource();
250250
}
251251

252-
GenericOp makeTransposeOp(OpBuilder &b, Location loc, Value inputTensor,
253-
Value outputTensor,
254-
ArrayRef<int64_t> transposeVector) {
255-
auto resultTensorType = cast<RankedTensorType>(outputTensor.getType());
256-
Type elementType = resultTensorType.getElementType();
257-
258-
assert(isPermutationVector(transposeVector) &&
259-
"expect transpose vector to be a permutation");
260-
assert(transposeVector.size() ==
261-
static_cast<size_t>(resultTensorType.getRank()) &&
262-
"expect transpose vector size to match result tensor rank");
263-
264-
// Compute the transpose and the indentity indexing maps.
265-
SmallVector<AffineMap> indexingMaps = {
266-
inversePermutation(AffineMap::getPermutationMap(
267-
SmallVector<unsigned>(transposeVector), b.getContext())),
268-
AffineMap::getMultiDimIdentityMap(transposeVector.size(),
269-
b.getContext())};
270-
SmallVector<utils::IteratorType> iteratorTypes(transposeVector.size(),
271-
utils::IteratorType::parallel);
272-
273-
// Create a GenericOp to transpose `inputTensor` into `outputTensor`.
274-
auto transposeOp =
275-
b.create<GenericOp>(loc, resultTensorType, inputTensor, outputTensor,
276-
indexingMaps, iteratorTypes);
277-
278-
// Create the body of the transpose operation.
279-
OpBuilder::InsertionGuard g(b);
280-
Region &body = transposeOp.getRegion();
281-
Block *bodyBlock = b.createBlock(&body, /*insertPt=*/{},
282-
{elementType, elementType}, {loc, loc});
283-
b.create<YieldOp>(loc, bodyBlock->getArgument(0));
284-
return transposeOp;
285-
}
286-
287252
GenericOp makeMemRefCopyOp(OpBuilder &b, Location loc, Value from, Value to) {
288253
auto memrefTypeTo = cast<MemRefType>(to.getType());
289254
#ifndef NDEBUG

mlir/test/Dialect/Linalg/transform-op-hoist-pad-build-packing-loop-nest.mlir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ func.func @pad_and_hoist_lhs_transpose(
115115
// BUILD-PACKING-LOOP-NEST: %[[PACKED:.*]] = scf.for %{{.*}} -> (tensor<?x12x5xf32>) {
116116
// BUILD-PACKING-LOOP-NEST: tensor.pad %{{.*}}
117117
// BUILD-PACKING-LOOP-NEST: : tensor<?x12xf32> to tensor<5x12xf32>
118-
// BUILD-PACKING-LOOP-NEST: linalg.generic
119-
// BUILD-PACKING-LOOP-NEST: -> tensor<12x5xf32>
118+
// BUILD-PACKING-LOOP-NEST: linalg.transpose
119+
// BUILD-PACKING-LOOP-NEST: ins({{.*}} : tensor<5x12xf32>) outs({{.*}} : tensor<12x5xf32>)
120120
// BUILD-PACKING-LOOP-NEST: tensor.insert_slice %{{.*}} into %{{.*}}[%{{.*}}, 0, 0] [1, 12, 5] [1, 1, 1]
121121
// BUILD-PACKING-LOOP-NEST-SAME: : tensor<12x5xf32> into tensor<?x12x5xf32>
122122
// BUILD-PACKING-LOOP-NEST: scf.for %{{.*}} -> (tensor<24x25xf32>)

mlir/test/Dialect/Linalg/transform-op-hoist-pad.mlir

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,17 +123,17 @@ func.func @pad_and_hoist_lhs_transpose(
123123
-> tensor<24x25xf32>
124124
{
125125
// CHECK: %[[PACKED:.*]] = scf.for %{{.*}} -> (tensor<5x12x5xf32>) {
126-
// CHECK: tensor.pad %{{.*}}
126+
// CHECK: %[[PAD:.*]] = tensor.pad %{{.*}}
127127
// CHECK: : tensor<?x12xf32> to tensor<5x12xf32>
128-
// CHECK: linalg.generic
129-
// CHECK: -> tensor<12x5xf32>
128+
// CHECK: linalg.transpose
129+
// CHECK: ins(%[[PAD]] : tensor<5x12xf32>) outs(%{{.*}} : tensor<12x5xf32>)
130130
// CHECK: tensor.insert_slice %{{.*}} into %{{.*}}[%{{.*}}, 0, 0] [1, 12, 5] [1, 1, 1]
131131
// CHECK-SAME: : tensor<12x5xf32> into tensor<5x12x5xf32>
132132
// CHECK: scf.for %{{.*}} -> (tensor<24x25xf32>) {
133133
// CHECK: %[[PADDED:.*]] = tensor.extract_slice %[[PACKED]][%{{.*}}, 0, 0] [1, 12, 5] [1, 1, 1]
134134
// CHECK-SAME: : tensor<5x12x5xf32> to tensor<12x5xf32>
135-
// CHECK: %[[TRANSPOSED:.*]] = linalg.generic
136-
// CHECK: -> tensor<5x12xf32>
135+
// CHECK: %[[TRANSPOSED:.*]] = linalg.transpose ins(%[[PADDED]] : tensor<12x5xf32>)
136+
// CHECK: outs(%{{.*}} : tensor<5x12xf32>
137137
// CHECK: linalg.matmul ins(%[[TRANSPOSED]]
138138
%0 = linalg.matmul ins(%arg0, %arg1 : tensor<24x12xf32>, tensor<12x25xf32>) outs(%arg2 : tensor<24x25xf32>) -> tensor<24x25xf32>
139139
func.return %0 : tensor<24x25xf32>

0 commit comments

Comments
 (0)