I am a beginner familiarizing myself with the MLIR project, and recently I’ve encountered some issues understanding its structure which can be listed below:
currently the kinds of regions contained in mlir is SSACFG and Graph , I am quite familiar with the architecture of SSA (Static Single Assignment) and can understand its structure, after I read the documentation GraphRegion, the doc says that this region is appropriate for concurrent semantics without control flow , but it doesn’t provide specific examples ,so I’m a little confused about this concept
the doc gives an example:
"test.graph_region"() ({ // A Graph region
%1 = "op1"(%1, %3) : (i32, i32) -> (i32) // OK: %1, %3 allowed here
%2 = "test.ssacfg_region"() ({
%5 = "op2"(%1, %2, %3, %4) : (i32, i32, i32, i32) -> (i32) // OK: %1, %2, %3, %4 all defined in the containing region
}) : () -> (i32)
%3 = "op2"(%1, %4) : (i32, i32) -> (i32) // OK: %4 allowed here
%4 = "op3"(%1) : (i32) -> (i32)
}) : () -> ()
The SSA region is nested within the graph region, How do these two regions combine logically? I don’t quite understand.
I would really appreciate any help you can provide.
There is no CFG control flow in the graph region in the example, but if/when the control is transferred to the nested region, these you find again the usual control flow.
It’s hard to find a concrete example that you could relate to without knowing your background, but imagine that the outer region is a ML dataflow graph, and there you could have a “custom operation” which defines a nested region implemented in LLVM dialect directly.
Thank a lot ! After reading the answer and revisiting the documentation, I have a clearer understanding of the concept of graph regions.
And another question bothers me: I think structure like LLVM using Module->Function->Block is OK, so why mlir use: operation->region->block , and the block also contains operation ,region, so what is the purpose of this design
Imagine a module, that contains a graph, this graph defines a graph region to model a ML dataflow graph, and there you could have a “custom operation” which defines a nested region implemented in LLVM dialect directly.
Now you have module>graph>custom_op>…
Another example can be the way we can model host code and device code using GPU module.