LLVM Discussion Forums

LowerToAffine for conv2d

Hello, I’m trying add conv2d operation(maybe simiplied version) in Toy dialect and lower to affine Dialect.This is Affine code I wrote handly (%arg2 and %arg3 are result index,%arg4 and %arg5 are filter index)

affine.for %arg2 = 0 to 2 {
      affine.for %arg3 = 0 to 2 {
        affine.for %arg4 = 0 to 2 {
          affine.for %arg5 = 0 to 2 {
            %3 = affine.load %1[%arg4, %arg5] 
            %4 = affine.load %2[ %arg4+%arg2, %arg5+%arg3] 
            %5 = mulf %3, %4
            %6 = affine.load  %0[%arg2, %arg3] 
            %7 = addf %5,%6
            affine.store %7, %0[%arg2, %arg3]
          }
        }
      }
    }

I have trouble in implementing %4 = affine.load %2[ %arg4+%arg2, %arg5+%arg3].Firstly,I tried get the sum of two index and use the sum as index to create AffineLoad but I get the Error message 'affine.load' op index must be a dimension or symbol identifier.Then I was told I should When you call create<AffineLoadOp>, you can pass an instance of AffineMap between the memref value and the subscript values. I am not familiar with AffineMap(doesn’t show up in Toy Tutorial) .Can someone demostrate how to code that?
Another question is when I first call %6 = affine.load %0[%arg2, %arg3] (%0 is memref value of result),%6 is 0 or not? should I initialize %0 with zero?

We cannot reasonably exercise all APIs in the tutorial, it’s a starting point for people to understand the overall structure of MLIR. From then, you can explore the codebase and tests to understand how different things work. For example, if you type AffineMap in GitHub search, and it will show you the right header. All public methods are documented, in particular you need this one https://github.com/llvm/llvm-project/blob/a87db48e6fdaf8ce9e7cc479945892b934dd9404/mlir/include/mlir/IR/AffineMap.h#L59. I’m letting you find the constructors of AffineExpr, necessary to build an AffineMap, as an exercise.

Another question is when I first call %6 = affine.load %0[%arg2, %arg3] (%0 is memref value of result),%6 is 0 or not?
It gives you the value stored in the memref. It may or may not be zero.

should I initialize %0 with zero?
Depending on your use case. Arguably, it should be initialized with something, otherwise you’d just read garbage from it. Whether it’s your code that does initialization, or the caller of your code, it’s up to you to specify.

1 Like