Hi all,
I am trying to understand the relationship between memref.subview
, affine_map
and symbols. I have this simple MLIR test program:
module {
func @func(%arg0:memref<16x16xf32> ) -> f32{
%c0 = arith.constant 0 : index
%c8 = arith.constant 8 : index
%s2= memref.subview %arg0[%c8,%c8][8,8][1,1] : memref<16x16xf32> to memref<8x8xf32, #map0>
%2 = memref.load %s2[%c0, %c0] : memref<8x8xf32, #map0>
return %2 : f32
}
func @main(){
%0 = memref.alloc() : memref<16x16xf32>
call @func(%0) : (memref<16x16xf32>) -> f32
return
}
}
The idea of func
is to get a subview
of arg0
at [8,8] of size [8,8] and then read the element [0,0]
of the subview.
Let’s focus on func
and let’s have a look at the LLVMIR generated with this command:
mlir-opt ./test.mlir -convert-memref-to-llvm -convert-std-to-llvm -canonicalize -reconcile-unrealized-casts | mlir-translate --mlir-to-llvmir
Let’s consider different cases for the affine_map
With #map0 = affine_map<(d0, d1)[s0] -> (d0 * 16 + d1)>
define float @func(float* %0, float* %1, i64 %2, i64 %3, i64 %4, i64 %5, i64 %6) !dbg !3 {
%8 = getelementptr float, float* %1, i64 0, !dbg !7
%9 = load float, float* %8, align 4, !dbg !9
ret float %9, !dbg !10
}
This clearly is not correct. I am not moving the pointer in the right position of my input. Why is this happening? Aren’t the dimensions of the memref
known at compile time?
With #map0 = affine_map<(d0, d1)[s0] -> (d0 * 16 + d1 + s0)>
define float @func(float* %0, float* %1, i64 %2, i64 %3, i64 %4, i64 %5, i64 %6) !dbg !3 {
%8 = mul i64 8, %5, !dbg !7
%9 = add i64 %2, %8, !dbg !9
%10 = mul i64 8, %6, !dbg !10
%11 = add i64 %9, %10, !dbg !11
%12 = add i64 %11, 0, !dbg !12
%13 = add i64 %12, 0, !dbg !13
%14 = getelementptr float, float* %1, i64 %13, !dbg !14
%15 = load float, float* %14, align 4, !dbg !15
ret float %15, !dbg !16
}
This is correct. s0
is a symbol read from the input memref
and then the pointer is shifted (seemingly) in the right way.
With #map0 = affine_map<(d0, d1)[s0] -> (d0 * 16 + d1 + 234*s0)>
define float @func(float* %0, float* %1, i64 %2, i64 %3, i64 %4, i64 %5, i64 %6) !dbg !3 {
%8 = mul i64 8, %5, !dbg !7
%9 = add i64 %2, %8, !dbg !9
%10 = mul i64 8, %6, !dbg !10
%11 = add i64 %9, %10, !dbg !11
%12 = add i64 %11, 0, !dbg !12
%13 = add i64 %12, 0, !dbg !13
%14 = getelementptr float, float* %1, i64 %13, !dbg !14
%15 = load float, float* %14, align 4, !dbg !15
ret float %15, !dbg !16
}
This is exactly the same, although I am multiplying s0
by 234. Why this multiplication does not appear in the IR?
Thank you to whomever can clarify all this confusion
Giuseppe