-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[mlir][Affine] Generalize the linearize(delinearize()) simplifications #117637
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 |
---|---|---|
|
@@ -1083,6 +1083,9 @@ def AffineDelinearizeIndexOp : Affine_Op<"delinearize_index", [Pure]> { | |
%indices_2 = affine.apply #map2()[%linear_index] | ||
``` | ||
|
||
In other words, `%0:3 = affine.delinearize_index %x into (B, C)` produces | ||
`%0 = {%x / (B * C), (%x mod (B * C)) / C, %x mod C}`. | ||
|
||
The basis may either contain `N` or `N-1` elements, where `N` is the number of results. | ||
If there are N basis elements, the first one will not be used during computations, | ||
but may be used during analysis and canonicalization to eliminate terms from | ||
|
@@ -1098,7 +1101,12 @@ def AffineDelinearizeIndexOp : Affine_Op<"delinearize_index", [Pure]> { | |
%0:3 = affine.delinearize_index %linear_index into (244, 244) : index, index | ||
``` | ||
|
||
Note that, due to the constraints of affine maps, all the basis elements must | ||
Note that, for symmetry with `getPaddedBasis()`, if `hasOuterBound` is `true` | ||
when one of the `OpFoldResult` builders is called but the first element of the | ||
basis is `nullptr`, that first element is ignored and the builder proceeds as if | ||
there was no outer bound. | ||
|
||
Due to the constraints of affine maps, all the basis elements must | ||
be strictly positive. A dynamic basis element being 0 or negative causes | ||
undefined behavior. | ||
}]; | ||
|
@@ -1136,6 +1144,11 @@ def AffineDelinearizeIndexOp : Affine_Op<"delinearize_index", [Pure]> { | |
/// Return a vector that contains the basis of the operation, removing | ||
/// the outer bound if one is present. | ||
SmallVector<OpFoldResult> getEffectiveBasis(); | ||
|
||
/// Return the vector with one basis element per result of the operation. If | ||
/// there is no outer bound specified, the leading entry of this result will be | ||
/// nullptr. | ||
SmallVector<OpFoldResult> getPaddedBasis(); | ||
}]; | ||
|
||
let hasVerifier = 1; | ||
|
@@ -1160,6 +1173,9 @@ def AffineLinearizeIndexOp : Affine_Op<"linearize_index", | |
sum(i = 0 to N-1) %idx_i * product(j = i + 1 to N-1) B_j | ||
``` | ||
|
||
In other words, `%0 = affine.linearize_index [%z, %y, %x] by (Z, Y, X)` | ||
gives `%0 = %x + %y * X + %z * X * Y`, or `%0 = %x + X * (%y + Y * (%z))`. | ||
|
||
The basis may either have `N` or `N-1` elements, where `N` is the number of | ||
inputs to linearize_index. If `N` inputs are provided, the first one is not used | ||
in computation, but may be used during analysis or canonicalization as a bound | ||
|
@@ -1168,6 +1184,10 @@ def AffineLinearizeIndexOp : Affine_Op<"linearize_index", | |
If all `N` basis elements are provided, the linearize_index operation is said to | ||
"have an outer bound". | ||
|
||
As a convenience, and for symmetry with `getPaddedBasis()`, ifg the first | ||
element of a set of `OpFoldResult`s passed to the builders of this operation is | ||
`nullptr`, that element is ignored. | ||
|
||
If the `disjoint` property is present, this is an optimization hint that, | ||
for all `i`, `0 <= %idx_i < B_i` - that is, no index affects any other index, | ||
except that `%idx_0` may be negative to make the index as a whole negative. | ||
|
@@ -1224,6 +1244,11 @@ def AffineLinearizeIndexOp : Affine_Op<"linearize_index", | |
/// Return a vector that contains the basis of the operation, removing | ||
/// the outer bound if one is present. | ||
SmallVector<OpFoldResult> getEffectiveBasis(); | ||
|
||
/// Return the vector with one basis element per index operand of the operation. | ||
/// If there is no outer bound specified, the leading entry of this basis will be | ||
/// nullptr. | ||
SmallVector<OpFoldResult> getPaddedBasis(); | ||
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. Would 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. It might, and ... yeah, I'm not strongly attached to the name 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. But also it's a bit wordier - let me know if you have strong thoughts here 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. Sure, no worries - but I'd still prefer making the doc comment simpler : |
||
}]; | ||
|
||
let hasVerifier = 1; | ||
|
Uh oh!
There was an error while loading. Please reload this page.