Hi,
TL;DR I’d like to add a new op memref.construct_strided_metadata
that is the counterpart of memref.extract_strided_metadata
, I.e., it materializes a memref
based on the provided metadata.
Context
In expand-striped-metadata
we simplify “complex” memref
operations by
- Extracting the metadata of the source memref using
memref.extract_strided_metadata
- Applying the effects of this complex operation to the metadata (offset, sizes, and strides) using
affine.apply
- Rebuilding the resulting memref
E.g.,
%res = memref.subview %src, %subSizes, …
=>
%base, %offset, %sizes, %strides = memref.extract_strided_metadata(%src)
%final_sizes = %subSizes
%final_strides = <some math> %strides
%final_offset = <some math> %offset
%res = <rebuild memref descriptor> %base, %final_offset, %final_sizes, %final_strides
The problem is we currently don’t have any operation that can do #3 (<rebuild memref descriptor>
in the above snippet). The current implementation uses memref.reinterpret_cast
but it turns out this is not technically correct (see [MLIR] expand-strided-metadata's expansions are invalid · Issue #59896 · llvm/llvm-project · GitHub)
Proposed solution
To solve this issue, I’d like to introduce a new memref operation that would rebuild a memref descriptor from the given metadata:
memref.construct_strided_metadata base: %ZeroRanked, offset: [%offset], sizes: [%size0, …], strides: [%stride0, …] : memref<ty> -> memref<..x..xty, strided<[…], offset: …>>
The semantic is straight forward: given the base, offset, sizes, and strides, materialize a memref with these values.
The intend is to use this operation as the counterpart of memref.extract_strided_metadata
.
In other words:
%base, %offset, %sizes, %strides = memref.extract_strided_metadata %src
%dst = memref.construct_strided_metadata %base, %offset, %sizes, %strides
=>
%dst = memref.cast %src
Note: To limit the footgun abilities of this operation, I’d like to enforce that the base argument must be zero ranked and have an offset of 0.
What do people think?
Cheers,
-Quentin