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
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.