-
Notifications
You must be signed in to change notification settings - Fork 13.9k
[mlir][vector] Make the in_bounds attribute mandatory #97049
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
f34fadf
e29022d
fab6386
c9afe5d
e6a70d5
861a18f
e13898a
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 |
---|---|---|
|
@@ -1363,7 +1363,7 @@ def Vector_TransferReadOp : | |
AffineMapAttr:$permutation_map, | ||
AnyType:$padding, | ||
Optional<VectorOf<[I1]>>:$mask, | ||
OptionalAttr<BoolArrayAttr>:$in_bounds)>, | ||
BoolArrayAttr:$in_bounds)>, | ||
joker-eph marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Results<(outs AnyVectorOfAnyRank:$vector)> { | ||
|
||
let summary = "Reads a supervector from memory into an SSA vector value."; | ||
|
@@ -1401,16 +1401,19 @@ def Vector_TransferReadOp : | |
permutation or broadcasting. Elements whose corresponding mask element is | ||
`0` are masked out and replaced with `padding`. | ||
|
||
An optional boolean array attribute `in_bounds` specifies for every vector | ||
dimension if the transfer is guaranteed to be within the source bounds. If | ||
specified, the `in_bounds` array length has to be equal to the vector rank. | ||
If set to "false", accesses (including the starting point) may run | ||
For every vector dimension, the boolean array attribute `in_bounds` | ||
specifies if the transfer is guaranteed to be within the source bounds. If | ||
set to "false", accesses (including the starting point) may run | ||
out-of-bounds along the respective vector dimension as the index increases. | ||
Broadcast dimensions must always be in-bounds. In absence of the attribute, | ||
accesses along all vector dimensions (except for broadcasts) may run | ||
out-of-bounds. A `vector.transfer_read` can be lowered to a simple load if | ||
all dimensions are specified to be within bounds and no `mask` was | ||
specified. Note that non-vector dimensions *must* always be in-bounds. | ||
Non-vector and broadcast dimensions *must* always be in-bounds. The | ||
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. dumb question: what does 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 also don't know :) That note was introduced by @matthias-springer in https://reviews.llvm.org/D155719. Matthias, do you remember what cases that was referring to? |
||
`in_bounds` array length has to be equal to the vector rank. This attribute | ||
has a default value: `false` (i.e. "out-of-bounds"). When skipped in the | ||
textual IR, the default value is assumed. Similarly, the OP printer will | ||
omit this attribute when all dimensions are out-of-bounds (i.e. the default | ||
value is used). | ||
|
||
A `vector.transfer_read` can be lowered to a simple load if all dimensions | ||
are specified to be within bounds and no `mask` was specified. | ||
|
||
This operation is called 'read' by opposition to 'load' because the | ||
super-vector granularity is generally not representable with a single | ||
|
@@ -1607,7 +1610,7 @@ def Vector_TransferWriteOp : | |
Variadic<Index>:$indices, | ||
AffineMapAttr:$permutation_map, | ||
Optional<VectorOf<[I1]>>:$mask, | ||
OptionalAttr<BoolArrayAttr>:$in_bounds)>, | ||
BoolArrayAttr:$in_bounds)>, | ||
Results<(outs Optional<AnyRankedTensor>:$result)> { | ||
|
||
let summary = "The vector.transfer_write op writes a supervector to memory."; | ||
|
@@ -1643,15 +1646,19 @@ def Vector_TransferWriteOp : | |
any permutation. Elements whose corresponding mask element is `0` are | ||
masked out. | ||
|
||
An optional boolean array attribute `in_bounds` specifies for every vector | ||
dimension if the transfer is guaranteed to be within the source bounds. If | ||
specified, the `in_bounds` array length has to be equal to the vector rank. | ||
If set to "false", accesses (including the starting point) may run | ||
For every vector dimension, the boolean array attribute `in_bounds` | ||
specifies if the transfer is guaranteed to be within the source bounds. If | ||
set to "false", accesses (including the starting point) may run | ||
out-of-bounds along the respective vector dimension as the index increases. | ||
In absence of the attribute, accesses along all vector dimensions may run | ||
out-of-bounds. A `vector.transfer_write` can be lowered to a simple store if | ||
all dimensions are specified to be within bounds and no `mask` was | ||
specified. Note that non-vector dimensions *must* always be in-bounds. | ||
Non-vector and broadcast dimensions *must* always be in-bounds. The | ||
`in_bounds` array length has to be equal to the vector rank. This attribute | ||
has a default value: `false` (i.e. "out-of-bounds"). When skipped in the | ||
textual IR, the default value is assumed. Similarly, the OP printer will | ||
omit this attribute when all dimensions are out-of-bounds (i.e. the default | ||
value is used). | ||
|
||
A `vector.transfer_write` can be lowered to a simple store if all | ||
dimensions are specified to be within bounds and no `mask` was specified. | ||
|
||
This operation is called 'write' by opposition to 'store' because the | ||
super-vector granularity is generally not representable with a single | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -146,6 +146,14 @@ class AffineMap { | |
/// affine map (d0, ..., dn) -> (dp, ..., dn) on the most minor dimensions. | ||
bool isMinorIdentity() const; | ||
|
||
/// Returns the list of broadcast dimensions (i.e. dims indicated by value 0 | ||
/// in the result). | ||
/// Ex: | ||
/// * (d0, d1, d2) -> (0, d1) gives [0] | ||
/// * (d0, d1, d2) -> (d2, d1) gives [] | ||
/// * (d0, d1, d2, d4) -> (d0, 0, d1, 0) gives [1, 3] | ||
SmallVector<unsigned> getBroadcastDims() const; | ||
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. Have you looked at 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. Yes - that was my source of inspiration :) It's just below Note, |
||
|
||
/// Returns true if this affine map is a minor identity up to broadcasted | ||
/// dimensions which are indicated by value 0 in the result. If | ||
/// `broadcastedDims` is not null, it will be populated with the indices of | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1223,8 +1223,19 @@ static Operation *vectorizeAffineLoad(AffineLoadOp loadOp, | |
LLVM_DEBUG(dbgs() << "\n[early-vect]+++++ permutationMap: "); | ||
LLVM_DEBUG(permutationMap.print(dbgs())); | ||
|
||
// Make sure that the in_bounds attribute corresponding to a broadcast dim | ||
// is set to `true` - that's required by the xfer Op. | ||
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. Nothing for this PR but this is still a constraint that seems unnecessary and makes this complicated, as we can see 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. Agreed. Expect a PR to remove this shortly :) (~next week) |
||
// FIXME: We're not veryfying whether the corresponding access is in bounds. | ||
// TODO: Use masking instead. | ||
SmallVector<unsigned> broadcastedDims = permutationMap.getBroadcastDims(); | ||
SmallVector<bool> inBounds(vectorType.getRank(), false); | ||
|
||
for (auto idx : broadcastedDims) | ||
inBounds[idx] = true; | ||
|
||
auto transfer = state.builder.create<vector::TransferReadOp>( | ||
loadOp.getLoc(), vectorType, loadOp.getMemRef(), indices, permutationMap); | ||
loadOp.getLoc(), vectorType, loadOp.getMemRef(), indices, permutationMap, | ||
inBounds); | ||
|
||
// Register replacement for future uses in the scope. | ||
state.registerOpVectorReplacement(loadOp, transfer); | ||
|
Uh oh!
There was an error while loading. Please reload this page.