[Mlir-commits] [mlir] [mlir][Vectorizer] Added support to Vectorize tensor.unpack (PR #76087)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon Feb 19 08:05:52 PST 2024
================
@@ -1559,6 +1558,111 @@ vectorizeAsTensorPackOp(RewriterBase &rewriter, tensor::PackOp packOp,
return success();
}
+/// Vectorize a `tensor::UnPackOp` to these 4 Ops:
+/// Vector::TransferReadOp - Reads a vector from the source tensor
+/// vector::TransposeOp - Transpose the Source tensor
+/// ShapeCastOp - Reshape the data based on the target.
+/// vector::TransferWriteOp. - Write the result vector back to the destination
+/// tensor
+static LogicalResult vectorizeAsUnpackOp(RewriterBase &rewriter,
+ tensor::UnPackOp unpackOp,
+ ArrayRef<int64_t> inputVectorSizes,
+ SmallVectorImpl<Value> &newResults) {
+
+ OpBuilder::InsertionGuard g(rewriter);
+ rewriter.setInsertionPoint(unpackOp);
+
+ RankedTensorType unpackTensorType = unpackOp.getSourceType();
+
+ ArrayRef<int64_t> innerDimPos = unpackOp.getInnerDimsPos();
+ ArrayRef<int64_t> innerTiles = unpackOp.getStaticInnerTiles();
+
+ SmallVector<int64_t> readMaskShape(inputVectorSizes.begin(),
+ inputVectorSizes.end());
+ ArrayRef<int64_t> outerDimsPerm = unpackOp.getOuterDimsPerm();
+ if (!outerDimsPerm.empty()) {
+ applyPermutationToVector(readMaskShape, outerDimsPerm);
+ }
+ ArrayRef<int64_t> sourceShape = unpackTensorType.getShape();
+ readMaskShape.append(sourceShape.begin() + inputVectorSizes.size(),
+ sourceShape.end());
+
+ // ReadMask is the size of tensor used to read and apply mask. It is
+ // set like this: Let's say the vectorSize (VS) array is size 'N' and
+ // the sourceShape(SS) is 'M' where M >= N and InnerTileSizes (IT) of
+ // size M-N
+ // Thus:
+ // - initially: ReadMaskShape = vectorInputSizes
+ // - if outer_dims_perms is present: do that permutation on readMaskShape.
+ // - Append the remaining shape from SS
+ // - Divide all the readMaskShape locations pointed by innerDimPos
+ // by the innerTileSize attribute value.
+ // E.g. let's say let's say unpackTensorType.getShape() = <8x8x32x16>
+ // inner Dim Pos = [0, 1] and Inner Tiles = [32, 16], vector_sizes are [512,
+ // 128] and outer_dims_perm is [1, 0] then read shape is:
+ // ReadMaskShape(initial): [512, 128]
+ // After applying outer_dims_perm: [128, 512]
+ // After appending the rest of the sourceShape: [128, 512, 32, 16]
+ // Final Value(after innerDim Adjustment): [128/32, 512/16, 32, 16]
+ // = [4, 32, 32, 16]
+ for (auto [index, size] : enumerate(innerTiles)) {
+ readMaskShape[innerDimPos[index]] =
+ llvm::divideCeil(readMaskShape[innerDimPos[index]], size);
+ }
+
+ ReifiedRankedShapedTypeDims reifiedRetShapes;
+ LogicalResult status =
+ cast<ReifyRankedShapedTypeOpInterface>(unpackOp.getOperation())
+ .reifyResultShapes(rewriter, reifiedRetShapes);
+ if (status.failed()) {
+ LDBG("Unable to reify result shapes of " << unpackOp);
+ return failure();
+ }
+ Location loc = unpackOp->getLoc();
+
+ auto padValue = rewriter.create<arith::ConstantOp>(
+ loc, rewriter.getZeroAttr(unpackOp.getSourceType().getElementType()));
+
+ // Read result, mask if necessary. If transferReadOp shape is not equal
+ // to shape of source, then a mask is necessary.
+ Value readResult = createReadOrMaskedRead(
+ rewriter, loc, unpackOp.getSource(),
+ ArrayRef<int64_t>(readMaskShape.begin(), readMaskShape.end()), padValue);
+
+ PackingMetadata packMetadata;
+ SmallVector<int64_t> lastDimToInsertPosPerm = invertPermutationVector(
+ tensor::getUnPackInverseSrcPerm(unpackOp, packMetadata));
----------------
Max191 wrote:
I think this should not be the inverted permutation. One of the tests seems to have an incorrect transpose, and I think this is the reason for it.
https://github.com/llvm/llvm-project/pull/76087
More information about the Mlir-commits
mailing list