Hello everyone,
I’m a MLIR freshman, I’m learning PDLL. Now I want to use the pdl to match pattern and rewrite it. How can I use the RewriteAdd.pdll to apply to original payload IR and get the desired result IR? What’s the workflow of this or it there a related simple example?
# Original payload IR
module {
func.func @test_pdl(%input0 : f32, %input1 : f32) {
%neg_out = arith.negf %input1 : f32
%sub_out = arith.subf %input0, %neg_out : f32
}
}
# RewriteAdd.pdll
Pattern RewriteAdd with benefit(1) {
let neg = op<arith.negf>(input1 : Value);
let add = op<arith.subf>(input0 : Value, neg.0);
replace add with op<arith.addf>(input1, input0);
}
# Desired result IR
module {
func.func @test_pdl(%input0 : f32, %input1 : f32) {
%add_out = arith.addf %input0, %input1 :f32
}
}
I believe the expected way to achieve what you want is to generate a C++ definition of your pattern using mlir-pdll -x=cpp
then link it to your MLIR compiler. So in other words, set-up an MLIR project and have a build script that generates the C++ for your PDLL pattern, that you can then register from your project using the generated populateGeneratedPDLLPatterns
function.
I think another way to use PDL patterns is via the transform dialect, for which I think a runtime interpreter exists.
Using mlir-pdll -x mlir -I <include dir> RewriteAdd.pdll
can generate .mlir file. And u can use that file in your # Original payload IR like this :
module {
func.func @test_pdl(%input0 : f32, %input1 : f32) {
%neg_out = arith.negf %input1 : f32
%sub_out = arith.subf %input0, %neg_out : f32
func.return
}
}
module attributes {transform.with_named_sequence} {
transform.named_sequence @__transform_main(%root: !transform.any_op) {
transform.with_pdl_patterns %root : !transform.any_op {
^bb0(%arg0: !transform.any_op):
pdl.pattern @RewriteAdd : benefit(1) {
%0 = operand
%1 = types
%2 = operation "arith.negf"(%0 : !pdl.value) -> (%1 : !pdl.range<type>)
%3 = operand
%4 = result 0 of %2
%5 = types
%6 = operation "arith.subf"(%3, %4 : !pdl.value, !pdl.value) -> (%5 : !pdl.range<type>)
rewrite %6 {
%7 = operation "arith.addf"(%0, %3 : !pdl.value, !pdl.value)
replace %6 with %7
}
}
transform.sequence %arg0 : !transform.any_op failures(propagate) {
^bb1(%arg1: !transform.any_op):
%f = pdl_match @RewriteAdd in %arg1 : (!transform.any_op) -> !transform.any_op
}
}
transform.yield
}
}
mlir-opt --transform-interpreter --allow-unregistered-dialect <file>
will do the rewrite. CSE Pass may be needed.
1 Like
Also take a look at the StableHLO to TOSA conversion patterns inside StableHLO repo. These shows a bit larger and rather self contained example too.
@Moxinilian @chenghuaWang @jpienaar , thank you for your replies.
- @Moxinilian ,it’s a little hard for me to try your proposal now, I believe I’ll try it later.
- @chenghuaWang , I have tried your proposal, it works for me. But I have another question, there are loc, loc1, loc2 and so on as following, when .mlir generated by
mlir-pdll -x mlir -I <include dir> RewriteAdd.pdll
, I don’t want to see these, how can I do?
- @jpienaar , I’ll take a look at StableHLO repo
module {
pdl.pattern @RewriteAdd : benefit(1) {
%0 = operand loc(#loc1)
%1 = types loc(#loc2)
%2 = operation "arith.negf"(%0 : !pdl.value) -> (%1 : !pdl.range<type>) loc(#loc2)
%3 = operand loc(#loc3)
%4 = result 0 of %2 loc(#loc4)
%5 = types loc(#loc5)
%6 = operation "arith.subf"(%3, %4 : !pdl.value, !pdl.value) -> (%5 : !pdl.range<type>) loc(#loc5)
rewrite %6 {
%7 = operation "arith.addf"(%0, %3 : !pdl.value, !pdl.value) loc(#loc7)
replace %6 with %7 loc(#loc6)
} loc(#loc6)
} loc(#loc)
} loc(#loc)
#loc = loc("/home/zongwu/wksp/x/examples/pdl/test_rewrite.pdll":1:1)
#loc1 = loc("/home/zongwu/wksp/x/examples/pdl/test_rewrite.pdll":2:28)
#loc2 = loc("/home/zongwu/wksp/x/examples/pdl/test_rewrite.pdll":2:13)
#loc3 = loc("/home/zongwu/wksp/x/examples/pdl/test_rewrite.pdll":3:28)
#loc4 = loc("/home/zongwu/wksp/x/examples/pdl/test_rewrite.pdll":3:44)
#loc5 = loc("/home/zongwu/wksp/x/examples/pdl/test_rewrite.pdll":3:13)
#loc6 = loc("/home/zongwu/wksp/x/examples/pdl/test_rewrite.pdll":5:3)
#loc7 = loc("/home/zongwu/wksp/x/examples/pdl/test_rewrite.pdll":5:20)
To be frank, I don’t know of any tools in mlir that can remove location information. If you really need to eliminate the location information, you can write a Pass and use mlir-opt. Of course, you can also write a regex script to manipulate the source code directly.
Understood, thanks for your reply.