Unit-extent dimensions are typically used for achieving broadcasting
behavior. The pattern added (along with canonicalization patterns
added previously) removes the use of unit-extent dimensions, and
instead uses a more canonical representation of the computation. This
new pattern is not added as a canonicalization for now since it
entails adding additional reshape operations. A pass is added to
exercise these patterns, along with an API entry to populate a
patterns list with these patterns.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Generally looks good, thanks Mahesh.
I left some code laering comments.
mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp | ||
---|---|---|
74 | This does not belong here right? | |
82 | In the grander scheme, should this function be exposed? I am asking because the way it is currently used, it takes and indexMap that comes from a GenericOp. Should this be refactored so that it can also help build correct IR that is canonical by construction? No need to necessarily change, I am mostly asking form your higher-level user's perspective. | |
94 | auto zero = getAffineConstantExpr(0, context); then just: return shape[fdim] == 1 && exprs[dim] == zero;. Why can dim overflow here? | |
99 | This should assert at least one dim is not a unitExtent otherwise reassociationMaps is empty? | |
101 | trivial braces here and below. | |
104 | I find the multi-dim++ a bit tricky to follow but I can't see offhand how to make it more readable. | |
172 | typo: result | |
1142 | The layering does not seem right to me. Traditionally we either:
If you're worried that other things are not visible they should also be moved in the proper place. patterns.insert<ReplaceUnitExtentTensors>(context); GenericOp::getCanonicalizationPatterns(patterns); TensorReshapeOp::getCanonicalizationPatterns(patterns); | |
mlir/lib/Dialect/Linalg/Transforms/Fusion.cpp | ||
828 | This should be its own pass in its own file, with its own pattern it is unclear to me why it is in the Fusion pass. |
mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp | ||
---|---|---|
74 | Ah, sorry. This shouldnt be here . Removed. | |
82 | I am not sure what you mean by exposed. This is a static function that is useful only for the callsite. The issue here might be that this was added to LinalgOps.cpp. Moving all of this into a separate pass. So it is not visible to op parsing/verification, etc. So in effect it isnt exposed outside of the pass. Regarding other questions
| |
94 | Changed. Thanks! | |
99 | Turns out it is OK to have all dims being unitExtent. Added a test for that. | |
104 | Made this a while loop and made the dim++ more explicit. | |
1142 | I agree. I moved everything to a separate file and added the relevant patterns into that. |
Thanks!
Note the last minor points.
mlir/lib/Dialect/Linalg/Transforms/DropUnitDims.cpp | ||
---|---|---|
100 | It seems like this whole function could be replaced by:
? | |
142 | We have ArrayAttr::getAsRange, seems a similar ArrayAttr::getFromRange would be useful? | |
175 | I am curious why does the iterator type matter here? | |
192 | nit: for (auto attr : llvm::enumerate(iteratorTypes)) if (unitDims.count(attr.index()) == 0) newIteratorTypes.push_back(attr.value()); ? | |
215 | typo: dimension | |
243 | Thanks, much simpler to follow AFAIR ! | |
mlir/test/Dialect/Linalg/drop-unit-extent-dims.mlir | ||
166 | nit:newline |
This does not belong here right?
It also intersects with this revision: https://reviews.llvm.org/D79759
Skipping since I am not seeing it used in this revision.