This is an archive of the discontinued LLVM Phabricator instance.

[MLIR][LinAlg] Implement detensoring cost-modelling.
ClosedPublic

Authored by ergawy on Apr 6 2021, 4:37 AM.

Details

Summary

This patch introduces the neccessary infrastructure changes to implement
cost-modelling for detensoring. In particular, it introduces the
following changes:

  • An extension to the dialect conversion framework to selectively

convert sub-set of non-entry BB arguments.

  • An extension to branch conversion pattern to selectively convert

sub-set of a branche's operands.

  • An interface for detensoring cost-modelling.
  • 2 simple implementations of 2 different cost models.

This sets the stage to explose cost-modelling for detessoring in an
easier way. We still need to come up with better cost models.

Diff Detail

Event Timeline

ergawy created this revision.Apr 6 2021, 4:37 AM
ergawy requested review of this revision.Apr 6 2021, 4:37 AM
rriddle added inline comments.Apr 6 2021, 10:43 AM
mlir/include/mlir/Transforms/DialectConversion.h
507

Can you just use ArrayRef instead? The "not provided" case could just be an empty ArrayRef.

mlir/lib/Dialect/Linalg/Transforms/Detensorize.cpp
18

Is this not included transitively?

360–369

What situations apply here? This seems like it's making an assumption.

444

Why not just duplicate this into the if/else above and avoid the dynamic memory allocation?

mlir/lib/Dialect/StandardOps/Transforms/FuncConversions.cpp
86

This is a little wonky, what about using something like a callback function instead?

mlir/lib/Transforms/Utils/DialectConversion.cpp
501

typo: idnetity

ergawy updated this revision to Diff 335748.Apr 7 2021, 1:29 AM

Handle rridle's comments:

  • Use ArrayRef for argument type.
  • Use function_ref instead of DenseMap.
  • Remove unneeded includes.
  • Avoid dynamic memory allocation.
ergawy marked 4 inline comments as done.Apr 7 2021, 1:30 AM
silvas added inline comments.Apr 7 2021, 12:18 PM
mlir/include/mlir/Dialect/StandardOps/Transforms/FuncConversions.h
47

can you default this to nullptr?

mlir/lib/Dialect/Linalg/Transforms/Detensorize.cpp
241

I feel like blockArgumentDetensoring is redundant with detensorableBranchOps. I feel like you should remove detensorableBranchOps and only have detensorableBlockArguments (which can just be DenseMap<BlockArgument>).

245

document the heuristic used by this cost model.

253

I find this function very weird. There are 2 "worklists" in this function (while (chainOp && !dyn_cast<GenericOp>(chainOp))) and while (!workList.empty()), and then discoverDetensorableComponent is a recursive function which itself is a kind of worklist.

You should be able to have a single worklist traversal. I'm thinking a worklist of Value that you initially populate with the CondBranchOp condition values, and then for each Value you pop off the worklist you:

  1. Check if it is the result of a regular scalar op -- if so, put the operands of that op on the worklist
  2. If it is the result of tensor.extract, put the operand on the worklist
  3. if it is the result of a linalg.generic that should be detensored, save the linalg op in detensorableLinalgOps, and push all its operands onto the worklist
  4. If it is a BlockArgument, then save it in blockArgumentDetensoring and put all corresponding values in predecessors onto the worklist. (and fail if any predecessor's terminator doesn't implement BranchOpInterface)
mlir/test/Dialect/Linalg/detensorize_while.mlir
2

can you add test cases for:

  1. trivial one-block function
  2. diamond control flow (representative of if/else)
mlir/test/Dialect/Linalg/detensorize_while_pure_cf.mlir
48

you need CHECK lines for the rest of the stuff :)

ergawy updated this revision to Diff 336330.Apr 9 2021, 12:43 AM
ergawy marked 5 inline comments as done.

Handle Sean's comments:

  • Refactor control-flow model.
  • Dedeuce branch op detensoring from block argument detensoring.
  • Add more docs.
ergawy added inline comments.Apr 9 2021, 12:44 AM
mlir/test/Dialect/Linalg/detensorize_while_pure_cf.mlir
48

Oh boy, I don't know how I missed that. Fixed.

ergawy updated this revision to Diff 336341.Apr 9 2021, 1:25 AM
ergawy marked 2 inline comments as done.

Add more tests.

ergawy marked an inline comment as done.Apr 9 2021, 1:26 AM
ergawy added inline comments.
mlir/lib/Dialect/Linalg/Transforms/Detensorize.cpp
253

Thanks for the suggestion. That made the code much simpler to read.

324

I will handle this in a later patch if it's ok. This one is huge already.

360–369

Removed that method altogether.

ergawy added inline comments.Apr 9 2021, 1:29 AM
mlir/test/Dialect/Linalg/detensorize_if.mlir
2

I added a test for if conditions. But as you can see the current heuristic implementation doesn't look forward and therefore doesn't detensor successor blocks if they need to be detensored.

This is not difficult to add, I think it would be better to add in a follow up patch since one is quite large already. WDYT?

silvas added inline comments.Apr 9 2021, 1:08 PM
mlir/lib/Dialect/Linalg/Transforms/Detensorize.cpp
206

typo: lingal

293

nit: naming of these args isn't great.

Perhaps "opsToDetensor" and "blockArgsToDetensor"?

300

For a worklist algorithm, one typically would write it as:

SmallVector<Value> worklist;
DenseSet<Value> visited;

And visited contains the Value's that have already been visited by the traversal and is used to prune the traversal. (you may also want a DenseSet<Operation*>) The main loop is

while (!worklist.empty()) {
  Value currentItem = worklist.pop_back_val();
  if (!visited.insert(currentItem).second)
    continue;

This also guarantees a particular ordering (DFS). The way you are doing it here using only a DenseSet is sketchy because 1) the ordering is nondeterministic and 2) since you erase values from the worklist, you can end up revisiting Value's (which can lead to compile time blowups).

306
if (auto bbarg = currentItem.dyn_cast<BlockArgument>()) { ...; continue}
Operation *op = currentItem.getDefiningOp();
...
371

where/when is "later?

mlir/test/Dialect/Linalg/detensorize_if.mlir
2

makes sense! we can add it later.

ergawy updated this revision to Diff 336597.Apr 10 2021, 12:25 AM
ergawy marked 3 inline comments as done.

Handle review comments.

ergawy marked 3 inline comments as done.Apr 10 2021, 12:25 AM
ergawy added inline comments.
mlir/lib/Dialect/Linalg/Transforms/Detensorize.cpp
300

Thank you. Done.

371

Added a clarification.

ergawy marked 2 inline comments as done.Apr 11 2021, 3:05 AM
silvas accepted this revision.Apr 12 2021, 2:09 PM

Thanks! Great work!

This revision is now accepted and ready to land.Apr 12 2021, 2:09 PM
This revision was automatically updated to reflect the committed changes.
mlir/test/Dialect/Linalg/detensorize_while_pure_cf.mlir