This is an archive of the discontinued LLVM Phabricator instance.

[mlir][MemRef][Transform] Don't apply multibuffer on "useless" allocs
ClosedPublic

Authored by qcolombet on Feb 10 2023, 8:49 AM.

Details

Summary

allocs that have users outside of loops are guaranteed to fail in
multibuffer.

Instead of exposing ourselves to that failure in the transform dialect,
filter out the allocs that fall in this category.

To be able to do this filtering we have to change the multibuffer
transform op from TransformEachOpTrait to a plain TransformOp. This is
because TransformEachOpTrait expects that every successful applyToOne
returns a non-empty result.

Couple of notes:

  • I changed the assembly syntax to make sure we only get alloc ops as input. (And added a test case to make sure we reject invalid inputs.)
  • multibuffer can still fail pretty easily when you know its limitations. See the updated op failed to multibuffer test case for instance. Longer term, instead of leaking/coupling the actual implementation (in this case the checks normally done in memref::multiBuffer) with the transform dialect (the added check in ::apply), we may want to refactor how we structure the underlying implementation. E.g., we could imagine a canApply method for all the implementations that we want to hook up in the transform dialect. This has some implications on how not to duplicate work between canApply and the actual implementation but I thought I throw that here to have us think about it :).

Diff Detail

Event Timeline

qcolombet created this revision.Feb 10 2023, 8:49 AM
qcolombet requested review of this revision.Feb 10 2023, 8:49 AM
qcolombet added inline comments.Feb 10 2023, 8:52 AM
mlir/lib/Dialect/MemRef/TransformOps/MemRefTransformOps.cpp
15

I'm guessing I need to modify some bazel files because of this new dependency, right?

(And looks like I dropped the CMakeFiles.txt changes as well and nothing broke x))

nicolasvasilache added inline comments.
mlir/lib/Dialect/MemRef/TransformOps/MemRefTransformOps.cpp
15

It is likely.

I use this to run locally for bazel : https://github.com/nicolasvasilache/nicolas.vasilache.github.io/blob/master/.venv/mlirdev/bin/activate#L64

That catch 99% of what I usually need.

35

I haven't looked at the impl of multi-buffering but I doubt it is general enough to support arbitrary containing ops on the way to the first scf::ForOp ?

Maybe use:

auto loop = dyn_cast_or_null<scf::ForOp>(user->getParentOp());

?

This seems in line with your tests in which the scf.for is always the immediate parent.

This revision is now accepted and ready to land.Feb 12 2023, 11:14 PM
qcolombet added inline comments.Feb 13 2023, 12:08 AM
mlir/lib/Dialect/MemRef/TransformOps/MemRefTransformOps.cpp
35

Good catch, I went with the IREE filtering but the multi-buffering implementation is actually more general.
https://github.com/iree-org/iree/blob/a1c4b9313c561c9f80d6e15ef2f01742b5bddca6/compiler/src/iree/compiler/Codegen/Common/GPUMultiBuffering.cpp#L33

I'm going to match what the multi-buffering implementation does.
Longer term we should refactor the implementation of multi-buffering to not duplicate the implementation.

Use LoopLikeOpInterface instead of scf::ForOP

qcolombet marked an inline comment as done.Feb 13 2023, 12:11 AM

Add missing cmake and bazel changes

qcolombet marked an inline comment as done.Feb 13 2023, 12:52 AM
qcolombet added inline comments.
mlir/lib/Dialect/MemRef/TransformOps/MemRefTransformOps.cpp
15

Thanks!

This revision was automatically updated to reflect the committed changes.
qcolombet marked an inline comment as done.