Cast UnrankedMemRefType to MemRefType


I noticed that I can cast UnrankedMemRef to MemRef like this:

%0 = memref_reinterpret_cast %memref to
        offset: [%offset],
        sizes: [%size0, %size1],
        strides: [%stride0, %stride1]
        : memref<*xf32> to memref<?x?xf32, offset: ?, strides: [?, ?]>

In C++ form:

static void MemRefReinterpretCastOp::build(
    ::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState,
    MemRefType resultType,  Value source,  Value offset, 
    ValueRange sizes,  ValueRange strides, 
    ArrayRef<NamedAttribute> attrs = {});

It seems that the lengths of the two ValueRange sizes and strides must be determined when I create the cast operator. How can I implement a function similar to this pseudocode:

func @myfunc(%arg0: memref<*xf32>, %indices: array<int>) {
    // the length of indices is undetermined when building the MLIR module
    %0 = load %arg0[%indices]: memref<*xf32>

Thanks in advance :grinning:

You can use memref_reshape, it takes an array of sizes. If the array has a statically-knows length, it gets expanded to memref_reinterpret_cast. If not, it will be lowered to LLVM directly.

1 Like