This commit starts a new pass and patterns for converting Linalg
named ops to generic ops. This enables us to leverage the flexbility
from generic ops during transformations. Right now only linalg.conv
is supported; others will be added when useful.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Great, thanks for starting this Lei!
It is easy to support any LinalgOp (i.e. that implements LinalgStructuredOpInterface) with one of the MatchAnyTag patterns.
See e.g. https://github.com/llvm/llvm-project/blob/master/mlir/lib/Dialect/Linalg/Transforms/Bufferize.cpp#L200.
If you just added that you could have linalg.matmul generate automatically and then all the named ops defined in the .tc file.
The remaining ops in LinalgStructuredOps.td would be for future work but ideally the .tc lang + parser evolves to support all cases automatically :)
Since you already wrote 90% of the logic in LinalgGeneralizationPattern, could I ask you to also write the pattern that matches any LinalgOp?
Thanks much!
Same comment as Nicolas. Seems like it is easily generalizable to all Named ops.
mlir/lib/Dialect/Linalg/Transforms/Generalization.cpp | ||
---|---|---|
88 | Each NamedOp seems to have a region builder that should give you this body? |
Thanks for the comment. I looked into it a bit and feel this might not be as trivial as expected. Or maybe it's just that I didn't find the proper API for it.
We have two categories of named ops right now: 1) tc generated vs 2) manually written. For 1) they have regionBuilder but not for 2). So in order to handle all 1) cases, I need to have a way to differentiate between 1) and 2). (Long-term we want to convert all 2) into 1) but I think that's a separate task on itself.) But AFAICT, there isn't an op interface or something like that to allow me to get all 1) ops in a generic way so I can access the regionBuilder. So then I'm not sure how the MatchAnyTag and then filter for 1) works. The way I can think of is actually use template for each of the 1) ops. But there is another issue. I don't have a TableGen'generated list that I can just #include to get the list of ops in 1): the TC generated TD file is included in the main TD file. This probably is just a small issue as I can separate them out or manually instantiate for all 1) ops. But I wanted to know whether this is the approach we want to choose: using template patterns for all the tc generated ops. Please let me know.
Yes I was just thinking of tackling 1) and not worry about 2).
The regionBuilder is currently auto-generated here https://github.com/llvm/llvm-project/blob/ecca7852d9d75aba859a3d8d001bfb2dda1345db/mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp#L1524 and does not yet use interfaces.
The idea would be to expose that (maybe to the NamedStructuredOpTrait (https://github.com/llvm/llvm-project/blob/73ca690df88ad5df77afe29b984720963ee37183/mlir/include/mlir/Dialect/Linalg/IR/LinalgTraits.h#L95) or otherwise create a new interface if it is better).
I actually spent some effort removing all places where we used to rely on list of ops so I'd love it if we did not reintroduce them :)
- [mlir][linalg] Start a named ops to generic ops pass
- Add another pattern to handle all tc-generated named ops
Looks good, thanks Lei!
Approving conditioned on an extra tensor test.
mlir/test/Dialect/Linalg/generalize-named-ops.mlir | ||
---|---|---|
55 | Add one test for matmul with tensors please, your code seems to handle the case. |
Each NamedOp seems to have a region builder that should give you this body?