For memref.subview operations, when there are more than one
unit-dimensions, the strides need to be used to figure out which of
the unit-dims are actually dropped.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Sorry for delay.
How does this change the situation for subviews with dynamic strides? Dynamic strides will all have the same static value so it looks like the code will just assume all dimensions are dropped because of that.
mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp | ||
---|---|---|
693 | Nit: please document and drop trivial braces below. | |
725 | Typo: dimension | |
730 | Did you mean size rather than rank? | |
732 | Nit: spurious empty line | |
744 | ||
756–758 | If this can never happen, it should be an assertion. I see you are asserting below, but maybe let's better to assert here and put your comment as assertion message + have different messages for different that currently return None. | |
mlir/test/Dialect/MemRef/invalid.mlir | ||
365 | Nit: please add a newline |
sorry I should have commented here .. I will pick this up and rewrite some of the basics, this should make the whole thing much smaller code-wise.
Ill explain by example. Lets say you have two unit dimensions with dynamic strides, s0 and s1, if either of one is dropped, then the result will have only one dynamic stride s0 irrespective of which one is dropped. So this is handled (I also have a test for this I think).
Thats fine, as long as the tests here pass. (In any case, I think the logic here is actually quite simple, it is the simplest of all candidates I could come up with (dont think number of lines of codes correspond to simplicity :) ). I am not tied to the solution though, so please let me know when you have this approach working.
@ftynse addressed most of your comments. I am running presubmits, and will submit after they pass. Ill address any other comments you have post-submit.
mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp | ||
---|---|---|
756–758 | Well, this is used in the verifier as well, so it needs to return on error and not assert. I could have different messages, but that would just be little verbose. Finally its about type mismatch. The caller reports it as such. |
Change from using DenseMap<int64_t> to std::map<int64_t> since the dynamic stride value is same as tombstone value for DenseMap<int64_t>.
There is a bug in the implementation. It crashes with this test case:
// RUN: mlir-opt %s -canonicalize func.func @func(%arg0: tensor<?x?x?xf32>, %arg1: index) -> index { %0 = bufferization.to_memref %arg0 : memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>> %c1 = arith.constant 1 : index %subview = memref.subview %0[0, 0, 0] [1, %arg1, 1] [1, 1, 1] : memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>> to memref<1x?xf32, strided<[?, ?], offset: ?>> %dim = memref.dim %subview, %c1 : memref<1x?xf32, strided<[?, ?], offset: ?>> return %dim : index }
Crashes here:
assert(subview.isDynamicSize(sourceIndex) && "expected dynamic subview size");
It is not clear to me from the comments and the description why we consider strides at all. Couldn't we just make an arbitrary decision which dims are dropped (like tensor.extract_slice)? We could just drop the same strides. (This means that the valid result types of a memref.subview would change a bit.)
This is also not clear to me yet. When we have static strides, there is some logic to select a specific dim to be dropped. But when we have dynamic strides, we cannot look at the dynamic runtime stride value and just assume that they are all the same. So it looks like we don't really care which stride is dropped. Is this just to "make the result type verify"?
Nope. Unlike tensor.extract_slice, memref.subviews have strides. And the ordering of the strides need not match the dimensions. For example in column-major ordering the outermost strides are unit-strides....
The best fix for this is we explicitly take as arguments which dimensions are to be dropped. I think I mentioned this at the time I was working on it. Trying to "figure it out" is always going to be harder.
This is also not clear to me yet. When we have static strides, there is some logic to select a specific dim to be dropped. But when we have dynamic strides, we cannot look at the dynamic runtime stride value and just assume that they are all the same. So it looks like we don't really care which stride is dropped. Is this just to "make the result type verify"?
This part is tricky. I think for dynamic strides, you need to drop one dynamic stride value for one dimension dropped... maybe being fast and loose here. Ill look at the test case here.
Nit: please document and drop trivial braces below.