This is an archive of the discontinued LLVM Phabricator instance.

[mlir][TilingInterface] Enable tile and fuse using TilingInterface.
ClosedPublic

Authored by mravishankar on Jun 14 2022, 4:37 PM.

Details

Summary

This patch implements tile and fuse transformation for ops that
implement the tiling interface. To do so,

  • TilingInterface needs a new method that generates a tiled implementation of the operation based on the tile of the result needed.
  • A pattern is added that replaces a tensor.extract_slice whose source is defined by an operation that implements the TilingInterface with a tiled implementation that produces the extracted slice in-place (using the method added to TilingInterface).
  • A pattern is added that takes a sequence of operations that implement the TilingInterface (for now LinalgOps), tiles the consumer, and greedily fuses its producers iteratively.

Diff Detail

Event Timeline

mravishankar created this revision.Jun 14 2022, 4:37 PM
mravishankar requested review of this revision.Jun 14 2022, 4:37 PM

Mostly looks good except for the sub-pattern instantiation / returningMatchAndRewrite API stuff.
Just instantiate it where you need it and have the producer op be a constructor argument.
Actually in this PR, there is no need for the Swap to be a pattern, it can just be a helper function.

mlir/include/mlir/Dialect/SCF/TileUsingInterface.h
89 ↗(On Diff #436973)

typo: up to

134 ↗(On Diff #436973)

I don't see a need to instantiate those at creation time.
You can instantiate them at application time and avoid changing the returningMatchAndRewrite API.

mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp
315

Please add more // 3. 4. 5. etc doc below plz

336

If you instantiated your auxiliary pattern here, you wouldn't need an incompatible returningMatchAndRewrite API.

mravishankar added inline comments.Jun 15 2022, 3:25 PM
mlir/include/mlir/Dialect/SCF/TileUsingInterface.h
134 ↗(On Diff #436973)

Ok, I can move it to instantiate at creation time. Wondering if there is advantage to instantiating these patterns as needed within the matchAndRewrite method? Wouldnt this effectively memoize the cost of creating this pattern?

mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp
336

I still need to. Issue is I need to pass to the fusionPattern (which is the Swap...Pattern) both the tensor.extract_slice consumer and the producer. I cant really just use the getDefiningOp() on source, cause the actual operation might require traversal through the iter_args of scf.for, which is not something that should be part of the Swap...Pattern implementation. The fact that this is needed is more due to scf.for specification.
I'll convert the Swap...Pattern to a utility method. That would probably avoid the change in returningMatchAndRewrite.

mravishankar marked 2 inline comments as done.

Address comments.

mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp
336

Utility SGTM, you may also want to add it to the tiling interface directly.
Each op that tiles will also need to swap with current and future subset_extract ops to fuse.
Even better, as we discussed previously, the swap is the tiling implementation, when we implement tiling as a noop-pair + fusion.

mravishankar added inline comments.Jun 16 2022, 9:55 AM
mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp
336

Already changed the patch to make the swap a utility function. PTAL. I still put it in the tensor Dialect for now cause we cannot add a dependence from Dialects to Interfaces. I can also move it to scf dialect, but that didnt seem necessary.

W.R.T to seeing tiling as no-op pair + fusion, that only works in some cases (like we discussed). The result tile only gives you the tile sizes to use for a subset of the iteration space. You then need to translate this into the tiles of iteration space. In Linalg you can do that using indexing maps. But the way to do this would be op-specific. If you look at the implementation, finally the core tiling method used is just getTiledImplementation.

nicolasvasilache accepted this revision.Jun 17 2022, 9:05 AM
This revision is now accepted and ready to land.Jun 17 2022, 9:05 AM
ftynse added inline comments.Jun 17 2022, 9:49 AM
mlir/include/mlir/Dialect/SCF/TileUsingInterface.h
134 ↗(On Diff #436973)

Is it that expensive to initialize a pattern? If we don't list the ops it produces (which does a lookup under lock per op), there's nothing non-trivia.

mlir/include/mlir/Interfaces/TilingInterface.td
129
136
152

Non-blocking design comment: for ops with clear bijection between the iteration space and the data space of each result, we could just require them to implement a function that computes the tile of the iteration space required to compute the given tile of the data space of the op result.; then call the existing tiling function. The implementations seem to be doing exactly that...

mlir/lib/Dialect/Linalg/Transforms/TilingInterfaceImpl.cpp
150
mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp
284–289
316

operands->results?

317

ditto

mravishankar marked 4 inline comments as done.Jun 20 2022, 8:45 PM
mravishankar added inline comments.
mlir/include/mlir/Dialect/SCF/TileUsingInterface.h
134 ↗(On Diff #436973)

you probably know better what is preferable. Given that the "old" way of pattern application goes though first instantiating all the patterns, and then applying match and rewrite on it, instantiating patterns during match and rewrite seems to break that flow. Ill keep this as is, but if you feel strongly/there is a strong reason to do so, I'll remove the class object and instantiate the pattern during match and rewrite.

mlir/include/mlir/Interfaces/TilingInterface.td
152

Agreed! I wanted to not make the surface area of the interface small for now. Definitely that would be a good convenience method to have.

mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp
316

why results? It is the operands that need to be sliced?

Rebase and address comments.

This revision was landed with ongoing or failed builds.Jun 21 2022, 9:47 AM
This revision was automatically updated to reflect the committed changes.