diff options
| author | Lei Zhang <antiagainst@google.com> | 2022-09-22 15:07:43 -0400 |
|---|---|---|
| committer | Lei Zhang <antiagainst@google.com> | 2022-09-22 17:28:50 -0400 |
| commit | bd81524e7f52c38ad0bc689934343a476e545265 (patch) | |
| tree | 68dbd3c8d04c4d8fe89991ef547ab2a12d151e16 /mlir/lib/Dialect/Tensor/Transforms/MergeConsecutiveInsertExtractSlicePatterns.cpp | |
| parent | 9d236d4dabf711ce30cc6049e644458d205afbf7 (diff) | |
Reland "[mlir][tensor] Support more cases in MergeConsecutiveExtractSlice"
This relands commit 5d4603a02d0c3e0106b10d245322b1d2072c0c3d.
It cludes fixes to GCC test failures and simplification to
the implementation.
Co-authored-by: Mahesh Ravishankar <ravishankarm@google.com>
Co-authored-by: Christopher Bate <cbate@nvidia.com>
Diffstat (limited to 'mlir/lib/Dialect/Tensor/Transforms/MergeConsecutiveInsertExtractSlicePatterns.cpp')
| -rw-r--r-- | mlir/lib/Dialect/Tensor/Transforms/MergeConsecutiveInsertExtractSlicePatterns.cpp | 108 |
1 files changed, 69 insertions, 39 deletions
diff --git a/mlir/lib/Dialect/Tensor/Transforms/MergeConsecutiveInsertExtractSlicePatterns.cpp b/mlir/lib/Dialect/Tensor/Transforms/MergeConsecutiveInsertExtractSlicePatterns.cpp index 48977a90ffb3..a065ba2e6724 100644 --- a/mlir/lib/Dialect/Tensor/Transforms/MergeConsecutiveInsertExtractSlicePatterns.cpp +++ b/mlir/lib/Dialect/Tensor/Transforms/MergeConsecutiveInsertExtractSlicePatterns.cpp @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// #include "mlir/Dialect/Affine/IR/AffineOps.h" -#include "mlir/Dialect/Arithmetic/Utils/Utils.h" #include "mlir/Dialect/Tensor/IR/Tensor.h" +#include "mlir/Dialect/Tensor/Transforms/TransformUtils.h" #include "mlir/Dialect/Tensor/Transforms/Transforms.h" #include "mlir/IR/BuiltinTypes.h" #include "mlir/IR/OpDefinition.h" @@ -17,29 +17,68 @@ using namespace mlir; using namespace mlir::tensor; -/// Adds each corresponding pair of offsets in `offsets1` and `offsets2` and -/// returns the results. -static SmallVector<OpFoldResult> mergeOffsets(Location loc, - ArrayRef<OpFoldResult> offsets1, - ArrayRef<OpFoldResult> offsets2, - OpBuilder &builder) { - SmallVector<OpFoldResult> foldedOffsets; - assert(offsets1.size() == offsets2.size()); - foldedOffsets.reserve(offsets1.size()); - - AffineExpr dim1, dim2; - bindDims(builder.getContext(), dim1, dim2); - - for (const auto &pair : llvm::zip(offsets1, offsets2)) { - auto offset0 = - getValueOrCreateConstantIndexOp(builder, loc, std::get<0>(pair)); - auto offset1 = - getValueOrCreateConstantIndexOp(builder, loc, std::get<1>(pair)); - auto foldedOffset = - makeComposedAffineApply(builder, loc, dim1 + dim2, {offset0, offset1}); - foldedOffsets.push_back(foldedOffset.getResult()); +LogicalResult tensor::mergeOffsetsSizesAndStrides( + OpBuilder &builder, Location loc, ArrayRef<OpFoldResult> producerOffsets, + ArrayRef<OpFoldResult> producerSizes, + ArrayRef<OpFoldResult> producerStrides, + const llvm::SmallBitVector &droppedProducerDims, + ArrayRef<OpFoldResult> consumerOffsets, + ArrayRef<OpFoldResult> consumerSizes, + ArrayRef<OpFoldResult> consumerStrides, + SmallVector<OpFoldResult> &combinedOffsets, + SmallVector<OpFoldResult> &combinedSizes, + SmallVector<OpFoldResult> &combinedStrides) { + combinedOffsets.resize(producerOffsets.size()); + combinedSizes.resize(producerOffsets.size()); + combinedStrides.resize(producerOffsets.size()); + + AffineExpr s0, s1, s2; + bindSymbols(builder.getContext(), s0, s1, s2); + + unsigned consumerPos = 0; + for (auto i : llvm::seq<unsigned>(0, producerOffsets.size())) { + if (droppedProducerDims.test(i)) { + // For dropped dims, get the values from the producer. + combinedOffsets[i] = producerOffsets[i]; + combinedSizes[i] = producerSizes[i]; + combinedStrides[i] = producerStrides[i]; + continue; + } + SmallVector<OpFoldResult> offsetSymbols, strideSymbols; + // The combined offset is computed as + // producer_offset + consumer_offset * producer_strides. + combinedOffsets[i] = makeComposedFoldedAffineApply( + builder, loc, s0 * s1 + s2, + {consumerOffsets[consumerPos], producerStrides[i], producerOffsets[i]}); + combinedSizes[i] = consumerSizes[consumerPos]; + // The combined stride is computed as + // consumer_stride * producer_stride. + combinedStrides[i] = makeComposedFoldedAffineApply( + builder, loc, s0 * s1, + {consumerStrides[consumerPos], producerStrides[i]}); + + consumerPos++; } - return foldedOffsets; + return success(); +} + +LogicalResult tensor::mergeOffsetsSizesAndStrides( + OpBuilder &builder, Location loc, OffsetSizeAndStrideOpInterface producer, + OffsetSizeAndStrideOpInterface consumer, + const llvm::SmallBitVector &droppedProducerDims, + SmallVector<OpFoldResult> &combinedOffsets, + SmallVector<OpFoldResult> &combinedSizes, + SmallVector<OpFoldResult> &combinedStrides) { + SmallVector<OpFoldResult> consumerOffsets = consumer.getMixedOffsets(); + SmallVector<OpFoldResult> consumerSizes = consumer.getMixedSizes(); + SmallVector<OpFoldResult> consumerStrides = consumer.getMixedStrides(); + SmallVector<OpFoldResult> producerOffsets = producer.getMixedOffsets(); + SmallVector<OpFoldResult> producerSizes = producer.getMixedSizes(); + SmallVector<OpFoldResult> producerStrides = producer.getMixedStrides(); + return tensor::mergeOffsetsSizesAndStrides( + builder, loc, producerOffsets, producerSizes, producerStrides, + droppedProducerDims, consumerOffsets, consumerSizes, consumerStrides, + combinedOffsets, combinedSizes, combinedStrides); } namespace { @@ -53,24 +92,15 @@ struct MergeConsecutiveExtractSlice : public OpRewritePattern<ExtractSliceOp> { if (!prevOp) return failure(); - if (!prevOp.hasUnitStride() || !nextOp.hasUnitStride()) + SmallVector<OpFoldResult> newOffsets, newSizes, newStrides; + if (failed(mergeOffsetsSizesAndStrides(rewriter, nextOp.getLoc(), prevOp, + nextOp, prevOp.getDroppedDims(), + newOffsets, newSizes, newStrides))) return failure(); - auto prevResultType = prevOp.getType().cast<ShapedType>(); - if (prevOp.getSourceType().getRank() != prevResultType.getRank()) - return rewriter.notifyMatchFailure( - prevOp, "rank-reducing producder case unimplemented"); - - Location loc = nextOp.getLoc(); - - SmallVector<OpFoldResult> prevOffsets = prevOp.getMixedOffsets(); - SmallVector<OpFoldResult> nextOffsets = nextOp.getMixedOffsets(); - SmallVector<OpFoldResult> foldedOffsets = - mergeOffsets(loc, prevOffsets, nextOffsets, rewriter); - - rewriter.replaceOpWithNewOp<ExtractSliceOp>( - nextOp, nextOp.getType(), prevOp.getSource(), foldedOffsets, - nextOp.getMixedSizes(), nextOp.getMixedStrides()); + rewriter.replaceOpWithNewOp<ExtractSliceOp>(nextOp, nextOp.getType(), + prevOp.getSource(), newOffsets, + newSizes, newStrides); return success(); } }; |
