This is an archive of the discontinued LLVM Phabricator instance.

[mlir][linalg] Make reshape folding control more fine grain
ClosedPublic

Authored by ThomasRaoux on May 5 2021, 9:05 AM.

Details

Summary

This expose a lambda control instead of just a boolean to control unit dimension folding.
Note that it is not a completely NFC change as it modified the default behavior of populateElementwiseOpsFusionPatterns to always allow reshape folding. This however gives more control to user to pick a good heuristic.
Folding reshapes helps fusion opportunities but may generate sub-optimal generic ops.

Diff Detail

Event Timeline

ThomasRaoux created this revision.May 5 2021, 9:05 AM
ThomasRaoux requested review of this revision.May 5 2021, 9:05 AM
mravishankar requested changes to this revision.May 5 2021, 4:12 PM
mravishankar added inline comments.
mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
89

Do we need a different type? the below uses OpResult and OpOperand we could use the same signature

mlir/lib/Dialect/Linalg/Transforms/FusionOnTensors.cpp
1436

I understand why this is done (and I kind of like it too). But I would move this logic into the populate* methods below.

This revision now requires changes to proceed.May 5 2021, 4:12 PM
mravishankar added inline comments.May 5 2021, 4:35 PM
mlir/lib/Dialect/Linalg/Transforms/FusionOnTensors.cpp
1479

Restating comment from above more clearly. It would be better to keep the default behavior consistent with allowFoldingUnitDimReshapes = false. So just calling populateFoldReshapeOpsByExpansionPatterns should set the controlFoldingReshapes to a function that effectively disables fusion for cases where the expansion adds unit-dimensions. THe check to see if this expansion is adding unit-dimensions is failry involved. I'd like to keep it as a default behavior, and wrapped within this populate* method. If a client wants to override it then thats upto them...

Revert to original default behavior

ThomasRaoux marked an inline comment as done.May 5 2021, 6:18 PM
ThomasRaoux added inline comments.
mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
89

We only need OpOperand. Changed the signature.

mlir/lib/Dialect/Linalg/Transforms/FusionOnTensors.cpp
1479

Changed the default behavior back to what it was making this change NFC

mravishankar accepted this revision.May 5 2021, 9:25 PM

THanks Thomas. Just one last comment.

mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
31

I think it is better to have the signature as bool(const OpResult &producer, const OpOperand &operand). As it currently stands just OpOperand is sufficient, but for sake of consistency and future-proof ness it would be better to have the result and operand explicit (producer and consumer). Also it is consistent with ControlElementwiseOpsFusionFn` signature (I am OK if you want to rename it). Lesser cognitive overhead in API.

89

See above comment about signature.

This revision is now accepted and ready to land.May 5 2021, 9:25 PM
mravishankar requested changes to this revision.May 5 2021, 9:25 PM

(clicked accept by mistake)

This revision now requires changes to proceed.May 5 2021, 9:25 PM
ThomasRaoux added inline comments.May 5 2021, 9:40 PM
mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
31

I don't understand why we need to pass producer and consumer. OpOperand contains both the operand Value as well as the consumer op with getOwner(). What information are we missing? This let use get the ReshapeOp as well as the linalgOp consuming and the operand index.
Could you explain what other kind of information would be useful to control the folding?

ThomasRaoux requested review of this revision.May 5 2021, 9:44 PM
mravishankar added inline comments.May 5 2021, 11:11 PM
mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
31

Its more ergonomics. You are given a producer and a consumer in the call back. You dont need to have all client have to do operand.cast<OpResult>() to get the producer. OpResult and OpOperand seemed like the best choice, cause you get the result number in the former and the argument number in the latter directly.
More than anything, I dont see a reason for a separate type here. Consistency makes it easier to follow. So if you want to change this, then you should change the other one too :) . There I have a slightly stronger preference to keep it as OpResult and OpOperand. Basically callbacks become load-bearing. If you ever have to change the signature of a callback it becomes a heavy weight change. So some redundancy might be OK to avoid having to do that in future. I cant give you an example right now, but trying to have lesser "implicit assumptions" built into what a callback gets.

ThomasRaoux marked an inline comment as done.
ThomasRaoux added inline comments.
mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
31

Changed it.

mravishankar accepted this revision.May 6 2021, 9:01 AM
mravishankar added inline comments.
mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
31

Thanks! One Nit: you dont need a different using here. You could just make this ControlElementwiseOpsFusionFn . I am not holding this up for that, but would be good to just drop this typedef.

This revision is now accepted and ready to land.May 6 2021, 9:01 AM
ThomasRaoux marked an inline comment as done.
ThomasRaoux added inline comments.
mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
31

Sure, I switch to use ControlElementwiseOpsFusionFn

This revision was landed with ongoing or failed builds.May 6 2021, 10:12 AM
This revision was automatically updated to reflect the committed changes.