-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[mlir] Allow folding dynamic full size subviews #140619
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -3105,7 +3105,7 @@ FailureOr<Value> SubViewOp::rankReduceIfNeeded(OpBuilder &b, Location loc, | |||||
| /// is the case if the all offsets are zero, all strides are 1, and the source | ||||||
| /// shape is same as the size of the subview. In such cases, the subview can | ||||||
| /// be folded into its source. | ||||||
| static bool isTrivialSubViewOp(SubViewOp subViewOp) { | ||||||
| static bool isTrivialSubViewOp(OpBuilder &b, SubViewOp subViewOp) { | ||||||
| if (subViewOp.getSourceType().getRank() != subViewOp.getType().getRank()) | ||||||
| return false; | ||||||
|
|
||||||
|
|
@@ -3127,15 +3127,24 @@ static bool isTrivialSubViewOp(SubViewOp subViewOp) { | |||||
| })) | ||||||
| return false; | ||||||
|
|
||||||
| // Check all size values are static and matches the (static) source shape. | ||||||
| // Check all size values match the source shape. | ||||||
| ArrayRef<int64_t> sourceShape = subViewOp.getSourceType().getShape(); | ||||||
| for (const auto &size : llvm::enumerate(mixedSizes)) { | ||||||
| std::optional<int64_t> intValue = getConstantIntValue(size.value()); | ||||||
| if (!intValue || *intValue != sourceShape[size.index()]) | ||||||
| return false; | ||||||
| if (llvm::all_of_zip(mixedSizes, sourceShape, | ||||||
| [](OpFoldResult mixedSize, int64_t staticSize) { | ||||||
| std::optional<int64_t> constSize = | ||||||
| getConstantIntValue(mixedSize); | ||||||
| return constSize.has_value() && | ||||||
| *constSize == staticSize; | ||||||
|
Comment on lines
+3134
to
+3137
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you can use llvm-project/mlir/include/mlir/Dialect/Utils/StaticValueUtils.h Lines 112 to 113 in a0c515a
|
||||||
| })) { | ||||||
| return true; | ||||||
| } | ||||||
| // All conditions met. The `SubViewOp` is foldable as a no-op. | ||||||
| return true; | ||||||
| auto sourceOpResult = dyn_cast<OpResult>(subViewOp.getSource()); | ||||||
| if (!sourceOpResult) | ||||||
| return false; | ||||||
| ReifiedRankedShapedTypeDims resultDims; | ||||||
| if (failed(reifyResultShapes(b, sourceOpResult.getOwner(), resultDims))) | ||||||
| return false; | ||||||
| return llvm::equal(mixedSizes, resultDims[sourceOpResult.getResultNumber()]); | ||||||
| } | ||||||
|
|
||||||
| namespace { | ||||||
|
|
@@ -3206,7 +3215,7 @@ class TrivialSubViewOpFolder final : public OpRewritePattern<SubViewOp> { | |||||
|
|
||||||
| LogicalResult matchAndRewrite(SubViewOp subViewOp, | ||||||
| PatternRewriter &rewriter) const override { | ||||||
| if (!isTrivialSubViewOp(subViewOp)) | ||||||
| if (!isTrivialSubViewOp(rewriter, subViewOp)) | ||||||
| return failure(); | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is problematic:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, it is difficult to compare the dynamic sizes without doing this. The other option I considered was using the ValueBoundsOpInterface, but that seems like an expensive check to run in a canonicalization. It would be nice if there were a version of These are the ways I know of to compare the result sizes of a tensor, but if you have any better suggestions, then that would be very helpful!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After looking into it further, I do see some instances of ValueBoundsOpInterface being used in canonicalization patterns, so I suppose it is the lesser of the two evils. I will update the PR implementation to use it instead.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, this won't work because I don't think it can capture equality of fully dynamic sizes that come from the same SSA value. It is more about computing bounds. So I am back to looking for something like
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wouldn't use I don't have a good solution. Maybe we can build a new pass that folds various index computations and view-like ops based on a single
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have an interface that does what I need in downstream IREE, actually. It is like reifyResultShapes, but "read only", as in, it doesn't create new IR. I am going to close this PR and handle this downstream for the time being, since I don't see a great way to do this here in MLIR. |
||||||
| if (subViewOp.getSourceType() == subViewOp.getType()) { | ||||||
| rewriter.replaceOp(subViewOp, subViewOp.getSource()); | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also update the comment?