https://github.com/bviyer updated https://github.com/llvm/llvm-project/pull/76087
>From d97a5729f496fb603f4fb9cf2977b015d8e37ed6 Mon Sep 17 00:00:00 2001 From: "Balaji V. Iyer" <bvi...@gmail.com> Date: Thu, 30 Nov 2023 20:39:55 +0000 Subject: [PATCH 1/3] [mlir][Vectorizer] Vectorize `tensor.unpack` This patch allows vectorization of a `tensor.unpack` operation. --- .../Linalg/Transforms/Vectorization.cpp | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp b/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp index f9a53a8451a60..7a9846154bf34 100644 --- a/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp +++ b/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp @@ -19,6 +19,7 @@ #include "mlir/Dialect/Linalg/Transforms/Transforms.h" #include "mlir/Dialect/Linalg/Utils/Utils.h" #include "mlir/Dialect/Tensor/IR/Tensor.h" +#include "mlir/Dialect/Utils/IndexingUtils.h" #include "mlir/Dialect/Utils/StructuredOpsUtils.h" #include "mlir/Dialect/Vector/IR/VectorOps.h" #include "mlir/Dialect/Vector/Interfaces/MaskableOpInterface.h" @@ -1385,6 +1386,88 @@ vectorizeAsLinalgGeneric(RewriterBase &rewriter, VectorizationState &state, return success(); } +// Vectorize an `tensor::UnPackOp` without OuterDimsPerms to these 4 Ops: +// Vector::TransferReadOp - Reads the Vector Array of Source data +// vector::TransposeOp - Transpose the Source +// ShapeCastOp - Reshapes the data based on the target. +// vector::TransferWriteOp. - Write the result vector back. + +static LogicalResult vectorizeAsUnpackOp(RewriterBase &rewriter, + tensor::UnPackOp unpackOp, + ArrayRef<int64_t> inputVectorSizes, + SmallVectorImpl<Value> &newResults) { + + if (!unpackOp.getOuterDimsPerm().empty()) { + LDBG("outer dimensions perms NYI for: " << unpackOp); + return failure(); + } + + OpBuilder::InsertionGuard g(rewriter); + rewriter.setInsertionPoint(unpackOp); + + RankedTensorType packTensorType = unpackOp.getSourceType(); + auto maskType = + VectorType::get(packTensorType.getShape(), rewriter.getI1Type()); + auto vectorType = VectorType::get(packTensorType.getShape(), + packTensorType.getElementType()); + ReifiedRankedShapedTypeDims reifiedRetShapes; + LogicalResult status = + cast<ReifyRankedShapedTypeOpInterface>(unpackOp.getOperation()) + .reifyResultShapes(rewriter, reifiedRetShapes); + if (status.failed()) { + LDBG("Unable to reify result shapes of " << unpackOp); + return failure(); + } + + arith::ConstantIndexOp zeroOp = + rewriter.create<arith::ConstantIndexOp>(unpackOp->getLoc(), 0); + Value mask = rewriter.create<vector::CreateMaskOp>( + unpackOp.getLoc(), maskType, + tensor::getMixedSizes(rewriter, unpackOp.getLoc(), unpackOp.getSource())); + + vector::TransferReadOp readOp = rewriter.create<vector::TransferReadOp>( + unpackOp.getLoc(), vectorType, unpackOp.getSource(), + SmallVector<Value>(packTensorType.getRank(), zeroOp), + rewriter.getMultiDimIdentityMap(packTensorType.getRank())); + + vector::MaskOp maskedOp = + cast<vector::MaskOp>(mlir::vector::maskOperation(rewriter, readOp, mask)); + + int64_t numPackedDim = unpackOp.getInnerDimsPos().size(); + int64_t packRank = packTensorType.getRank(); + auto lastDims = + llvm::to_vector(llvm::seq<int64_t>(packRank - numPackedDim, packRank)); + PackingMetadata packMetadata = + computePackingMetadata(packRank, unpackOp.getInnerDimsPos()); + SmallVector<int64_t> lastDimToInsertPosPerm = computePermutationVector( + packRank, lastDims, packMetadata.insertPositions); + SmallVector<int64_t> stripMineShape(packTensorType.getShape()); + applyPermutationToVector(stripMineShape, lastDimToInsertPosPerm); + + RankedTensorType stripMineTensorType = + RankedTensorType::Builder(packTensorType).setShape(stripMineShape); + + RankedTensorType collapsedType = tensor::CollapseShapeOp::inferCollapsedType( + stripMineTensorType, packMetadata.reassociations); + auto vecCollapsedType = + VectorType::get(collapsedType.getShape(), collapsedType.getElementType()); + + vector::TransposeOp transposeOp = rewriter.create<vector::TransposeOp>( + unpackOp.getLoc(), maskedOp.getResult(0), lastDimToInsertPosPerm); + + vector::ShapeCastOp shapeCastOp = rewriter.create<vector::ShapeCastOp>( + unpackOp.getLoc(), vecCollapsedType, transposeOp->getResult(0)); + tensor::EmptyOp emptyOp = rewriter.create<tensor::EmptyOp>( + unpackOp.getLoc(), reifiedRetShapes[0], packTensorType.getElementType()); + + vector::TransferWriteOp writeOp = rewriter.create<vector::TransferWriteOp>( + unpackOp.getLoc(), shapeCastOp->getResult(0), emptyOp, + SmallVector<Value>(lastDims.size(), zeroOp), + SmallVector<bool>(lastDims.size(), true)); + + newResults.push_back(writeOp->getResult(0)); + return success(); +} /// Vectorize a `padOp` with (1) static result type, (2) constant padding value /// and (3) all-zero lowPad to @@ -1578,6 +1661,12 @@ vectorizeLinalgOpPrecondition(LinalgOp linalgOp, return success(); } +static LogicalResult +vectorizeUnpackOpPrecondition(tensor::UnPackOp unpackOp, + ArrayRef<int64_t> inputVectorSizes) { + return success(); +} + static LogicalResult vectorizePadOpPrecondition(tensor::PadOp padOp, ArrayRef<int64_t> inputVectorSizes) { @@ -1637,6 +1726,9 @@ LogicalResult mlir::linalg::vectorizeOpPrecondition( .Case<tensor::PadOp>([&](auto padOp) { return vectorizePadOpPrecondition(padOp, inputVectorSizes); }) + .Case<tensor::UnPackOp>([&](auto unpackOp) { + return vectorizeUnpackOpPrecondition(unpackOp, inputVectorSizes); + }) .Default([](auto) { return failure(); }); } @@ -1724,6 +1816,10 @@ LogicalResult mlir::linalg::vectorize(RewriterBase &rewriter, Operation *op, return vectorizeAsTensorPadOp(rewriter, padOp, inputVectorSizes, results); }) + .Case<tensor::UnPackOp>([&](auto unpackOp) { + return vectorizeAsUnpackOp(rewriter, unpackOp, inputVectorSizes, + results); + }) .Default([](auto) { return failure(); }); if (failed(vectorizeResult)) { >From a52d650fd8ff0f761fd2aa77671ffa858f3e9237 Mon Sep 17 00:00:00 2001 From: "Balaji V. Iyer" <bvi...@gmail.com> Date: Wed, 20 Dec 2023 11:45:20 -0600 Subject: [PATCH 2/3] Enabled tensor.unpack vectorization and added test case. --- .../TransformOps/LinalgTransformOps.cpp | 2 +- mlir/test/Dialect/Linalg/vectorization.mlir | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp b/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp index 14404d837ff74..4c456a5e671f5 100644 --- a/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp +++ b/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp @@ -3078,7 +3078,7 @@ DiagnosedSilenceableFailure transform::VectorizeOp::apply( // TODO: Check that the correct number of vectorSizes was provided. for (Operation *target : targets) { - if (!isa<linalg::LinalgOp, tensor::PadOp>(target)) { + if (!isa<linalg::LinalgOp, tensor::PadOp, tensor::UnPackOp>(target)) { return mlir::emitSilenceableFailure(target->getLoc()) << "Unsupported Op, cannot vectorize"; } diff --git a/mlir/test/Dialect/Linalg/vectorization.mlir b/mlir/test/Dialect/Linalg/vectorization.mlir index 610339405d1c2..acf7276626a4c 100644 --- a/mlir/test/Dialect/Linalg/vectorization.mlir +++ b/mlir/test/Dialect/Linalg/vectorization.mlir @@ -419,6 +419,31 @@ module attributes {transform.with_named_sequence} { // ----- +// CHECK-LABEL: func @test_vectorize_unpack +func.func @test_vectorize_unpack(%0 : tensor<7x1136x16x16xf32>) -> tensor<100x18176xf32> { + // CHECK %[[c0:.*]] = arith.constant 0 : index + // CHECK: %[[tr0:.*]] = vector.mask %[[m0:.*]] {{.*}} vector.transfer_read %{{.*}} : tensor<7x1136x16x16xf32>, vector<7x1136x16x16xf32> } : vector<7x1136x16x16xi1> -> vector<7x1136x16x16xf32> + // CHECK: %[[trans0:.*]] = vector.transpose %[[tr0]], [0, 2, 1, 3] : vector<7x1136x16x16xf32> to vector<7x16x1136x16xf32> + // CHECK: %[[sc0:.*]] = vector.shape_cast %[[trans0]] : vector<7x16x1136x16xf32> to vector<112x18176xf32> + // CHECK: %[[empt0:.*]] = tensor.empty() : tensor<100x18176xf32> + // CHECK: %[[tw0:.*]] = vector.transfer_write %[[sc0]], %[[empt0]] + // CHECK: return %[[tw0]] + %8 = tensor.empty() : tensor<100x18176xf32> + %unpack = tensor.unpack %0 inner_dims_pos = [0, 1] inner_tiles = [16, 16] into %8 : tensor<7x1136x16x16xf32> -> tensor<100x18176xf32> + return %unpack : tensor<100x18176xf32> +} + +module attributes {transform.with_named_sequence} { + transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) { + %0 = transform.structured.match ops{["tensor.unpack"]} in %arg1 + : (!transform.any_op) -> !transform.any_op + transform.structured.vectorize %0 vector_sizes [2, 4] : !transform.any_op + transform.yield + } +} + +// ----- + // CHECK-LABEL: func @test_masked_vectorize_pad func.func @test_masked_vectorize_pad( %0 : tensor<?x?xf32>, %h0 : index, %h1 : index) >From a77ac60ddd46e25a9183d83be302445552766e3f Mon Sep 17 00:00:00 2001 From: "Balaji V. Iyer" <bvi...@gmail.com> Date: Fri, 19 Jan 2024 19:11:04 -0600 Subject: [PATCH 3/3] Added some of the changes requested by Diego and HanHan --- .../Linalg/Transforms/Vectorization.cpp | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp b/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp index 7a9846154bf34..611dec4af0f93 100644 --- a/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp +++ b/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp @@ -1386,11 +1386,11 @@ vectorizeAsLinalgGeneric(RewriterBase &rewriter, VectorizationState &state, return success(); } -// Vectorize an `tensor::UnPackOp` without OuterDimsPerms to these 4 Ops: -// Vector::TransferReadOp - Reads the Vector Array of Source data -// vector::TransposeOp - Transpose the Source -// ShapeCastOp - Reshapes the data based on the target. -// vector::TransferWriteOp. - Write the result vector back. +/// Vectorize an `tensor::UnPackOp` without OuterDimsPerms to these 4 Ops: +/// Vector::TransferReadOp - Reads the Vector Array of Source data +/// vector::TransposeOp - Transpose the Source +/// ShapeCastOp - Reshapes the data based on the target. +/// vector::TransferWriteOp. - Write the result vector back. static LogicalResult vectorizeAsUnpackOp(RewriterBase &rewriter, tensor::UnPackOp unpackOp, @@ -1661,12 +1661,6 @@ vectorizeLinalgOpPrecondition(LinalgOp linalgOp, return success(); } -static LogicalResult -vectorizeUnpackOpPrecondition(tensor::UnPackOp unpackOp, - ArrayRef<int64_t> inputVectorSizes) { - return success(); -} - static LogicalResult vectorizePadOpPrecondition(tensor::PadOp padOp, ArrayRef<int64_t> inputVectorSizes) { @@ -1726,9 +1720,7 @@ LogicalResult mlir::linalg::vectorizeOpPrecondition( .Case<tensor::PadOp>([&](auto padOp) { return vectorizePadOpPrecondition(padOp, inputVectorSizes); }) - .Case<tensor::UnPackOp>([&](auto unpackOp) { - return vectorizeUnpackOpPrecondition(unpackOp, inputVectorSizes); - }) + .Case<tensor::UnPackOp>([&](auto unpackOp) { return success(); }) .Default([](auto) { return failure(); }); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits