This is an archive of the discontinued LLVM Phabricator instance.

[mlir][Linalg] Add support for bufferization of SubTensorOp and SubTensorInsertOp
ClosedPublic

Authored by nicolasvasilache on Nov 6 2020, 9:02 AM.

Details

Reviewers
silvas
aartbik
Summary

This revision adds support for bufferization by using a mix of tensor_load, subview, linalg.copy and tensor_to_memref.

Diff Detail

Event Timeline

nicolasvasilache requested review of this revision.Nov 6 2020, 9:02 AM
silvas added inline comments.Nov 6 2020, 2:01 PM
mlir/lib/Dialect/Linalg/Transforms/Bufferize.cpp
242

This shouldn't be needed. See below.

250

This shouldn't be needed, see below.

279

The conversion framework guarantees that operands are all legal types (which would be memref here). So you shouldn't need this if condition and can proceed assuming that sourceMemref is a memref.

283

You can use getTypeConverter()->convertType(op.getType()).

296

You should not be creating TensorLoad / TensorToMemref ops yourself. The dialect conversion framework does it automatically.

You can replace this line with rewriter.replaceOp(op, alloc) and it will automatically insert tensor_load if needed.

331

Same comment. This isn't needed. The conversion is guaranteed by the framework.

384

not needed.

mlir/test/Dialect/Linalg/bufferize.mlir
232

This is not correct. Sorry :(

Consider %t = std.get_global_memref @some_constant_memref. There's no way of getting out of a non-peephole analysis here to prove that a memref is writable and not aliased in a way that prevents this optimization.

Let's land this without attempting any tricks, and then do a "whiteboarding" session to look at ways to get the desired optimization here (I can think of many ways, but I think we will need to stare at the "inefficient but correct" versions to really make a decision on the tradeoffs here).

silvas requested changes to this revision.Nov 6 2020, 2:01 PM
This revision now requires changes to proceed.Nov 6 2020, 2:01 PM
nicolasvasilache marked 7 inline comments as done.Nov 9 2020, 3:59 AM
nicolasvasilache added subscribers: ulysseB, albertcohen.
mlir/test/Dialect/Linalg/bufferize.mlir
232

Actually, note that the TensorToMemRefOp says:

Create a memref from a tensor. This is equivalent to allocating a new memref of the appropriate (possibly dynamic) shape, and then copying the elements (as if by a tensor_store op) into the newly allocated memref.

I dropped all the copies that are unnecessary according to this semantics.
It seems it is the job of scf.for to do the right thing from tensor_load + tensor_to_memref + ops that create aliases.

Address review.

nicolasvasilache edited the summary of this revision. (Show Details)Nov 9 2020, 4:00 AM
silvas accepted this revision.Nov 9 2020, 8:35 AM
silvas added inline comments.
mlir/lib/Dialect/Linalg/Transforms/Bufferize.cpp
244

nit: remove tensor_to_memref here, as it no longer reflects the code in the pattern body.

mlir/test/Dialect/Linalg/bufferize.mlir
232

Ugh, I wrote that line, and somehow I didn't piece together the ramifications of these semantics. In practice, tensor_to_memref(tensor_load(memref)) -> memref pattern gets applied in many places without considering this semantic... which is a huge latent bug. This is partially just due to how the dialect converion framework works. It elides them "on the fly" without considering the aliasing implications of removing copies.... I'll need to think more about how to fix this..... Thanks for reminding me of this.

Example:

func @f(%arg0: memref<?xf32>) {
  %0 = tensor_to_memref(tensor_load(%arg0))
  %1 = tensor_to_memref(tensor_load(%arg0))
  // In current code, %0 and %1 will alias each other.
  // In corrected code, %0 and %1 must not alias each other unless it's provable that it doesn't matter :/
}
This revision is now accepted and ready to land.Nov 9 2020, 8:35 AM
nicolasvasilache marked 3 inline comments as done.Nov 9 2020, 9:10 AM
nicolasvasilache added inline comments.
mlir/lib/Dialect/Linalg/Transforms/Bufferize.cpp
244

Addressed: squashed into the commit but forgot to update phab.

nicolasvasilache marked an inline comment as done.

This landed