- 
                Notifications
    You must be signed in to change notification settings 
- Fork 15k
[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 | ||
|          | ||
| `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; | ||
|          | ||
|  | ||
| /// 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. | ||
|          | ||
| // 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.