Toy Dialect extend

Hello,I am working on extending Toy Dialect by adding some operator such as conv2d max_pool2d softmax and lowering this opearator to Affine Dialect.I wrote conv2d like this


but I don’t know how to write build method.
I want input and filter operands and strides_h strides_w padding as attribute
Is that a inappropriate way to write conv2d? How to write conv2d and build method?

You need to define this method in a source (.cpp) file as Conv2DOp::build with the signature you provided. Inside this method, you should populate the OperationState instance with operands, attributes and result types, similarly to what you would do in a parser. Look in the sources of the Toy tutorial for examples, e.g. https://github.com/llvm/llvm-project/blob/master/mlir/examples/toy/Ch2/mlir/Dialect.cpp#L170.

Note that a default ::build method will be generated from from the arguments and results provided in the op description, ::build(OpBuilder &, OperationState &, Type result, Value input, Value filter, IntegerAttr stridesh, IntegerAttr stridesw, IntegerAttr padding).

Also note that ::build methods now must take OpBuilder & rather than Builder * as the first argument. Normally, I should have updated all references.

Then I have a trouble in lowering conv2d to Affine Dialect,I write Affine handly is following:(assuming result shape is 2X2,input shape is 3X3,filter shape is 2X2,stridesh=1,stridesw=1,padding=0
%arg2 %arg3 is result Induction var,%arg4 %arg5 is filterInduction var)

 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]
          }
        }
      }
    }

Is that a correct way ?

Is [ %arg4+%arg2, %arg5+%arg3] legal?
how to write code in LowerToAffineLoops.cpp in Toy tutorial

Yes, that would be valid.

1 Like

image

How to write in LowerToAffineLoops.cpp, loopIvs.push_back(loop.getInductionVar())?

As one example, you can take a look at the code in LoopTiling.cpp. Note that calling a clear() on the loop body which is a Block will also erase its terminator and make the op invalid. The body is by default empty (with only the terminator) when you create it.

The main problem is how to implement

[ %arg4+%arg2, %arg5+%arg3]

I learn from lowerToAffineLoops.cpp in ch6 Toy Tutorial that rewriter.create<AffineLoadOp>(loc, binaryAdaptor.lhs(), loopIvs); need a SmallVector<Value, 4> loopIvs; loopIvs.push_back(loop.getInductionVar()); what does %arg4+%arg2 need ? how to add two Induction Var
by the way ,I 'm trying to understand LoopTiling.cpp,but it’s a little difficult for me(beginner in MLIR)

To get the sum of two index values or any affine function of those, you’ll have to set up the map on AffineLoadOp appropriately. The map will be (d0, d1) → (d0 + d1) in that case.

I have to bother again that how to set up the map specificly.The map now is (d0,d1)–>(d0,d1).
Is it explicit to set up or not? I don’t see any code setting up the map

When you call create<AffineLoadOp>, you can pass an instance of AffineMap between the memref value and the subscript values.

I’m not familiar with AffineMap.I’ll appreciate it if you demostrate how to code what you say.
I also tried to get sum of two index value in advance and create<AffineLoadOp> with the sum.But it says that 'affine.load' op index must be a dimension or symbol identifier

Please read carefully what I said:

you can pass an instance of AffineMap between the memref value and the subscript values

you need to get an instance of AffineMap that computes the sum,

AffineMap sumMap = ...

and pass it to the create function between the arguments I mentioned

builder.create<AffineLoadOp>(location, memref, sumMap, indices);

I pointed you to relevant APIs in another thread you started.