Beginner and do not know how to start

Hi I’m new to mlir and my team using mlir c++ framework to transfer from ast to m

As a beginner I do not know what is the mechanism of this.

From toy example, it seems that:

1, I need to define a dialect,
2, I need to register it
3, I need to analyze the ast, create blocks, set insertion point and call build method to add stuff in.

But what is the logic of all of these, most of the build functions are created from tablegen, what are the parameters mean??

Actually so many questions in my head and I do not know how to organize them, can anyone make a simple example to illustrate the mechanism of this??

Thanks a lot!!

Hi,

This all can seem fairly confusing at first, don’t worry it’s normal :slight_smile:

You mention Toy, have you gone through the tutorial entirely? There is a video and slides also if that helps (links are on the first page).

Each chapter of the tutorial has matching code in the repository: llvm-project/mlir/examples/toy at main · llvm/llvm-project · GitHub ; the example compiles and execute ; feel free to try to modify them and play with them to get a feel of how everything fits together.

Hi, thanks a lot, I’m trying to read and understand as much as I can.

I kind of figured out the following:

  1. Operations are defined based on dialect

  2. Dialect usually ODS format with mlir-tblgen tool to create

  3. During tut2, it created an ModuleOp as the top instance and adding different operations into it

  4. It use push_back and setInsertionPointToStart method to adjust the point of insertion

  5. It use builder.create(parameters) to create operations in the related insertion place

  6. builder.create will direct to one of opertation::build function

  7. The main content of the build function are addOperands, addTypes and addAttributes.

Thus based on the previous understanding, I would have the following questions

  1. Is there a method to view the content of ModuleOp while debugging? So that I can real time monitoring what is added, what is removed

  2. Is there a documentation on different objects, since what I’m facing is tons of method and template and class that I do not know what they do

  3. Would there be an illustration of what is Operand, Type and Attribute of a operation, and what is the link between them and the definitions within .td files.

Really thanks for your time and patients spent on this!!

Hey,

The dump method on Operation is quite useful for that.

mlir.dev has the doxygen output of all the MLIR classes

I think most of the presentations introducing MLIR has a slide or so on these. The .td file is TableGen format input for ODS (the idea behind and it’s documentation is Operation Definition Specification (ODS) - MLIR). Basically it is a convenience method to define operations (the preferred way, but it is possible to do by hand). Those C++ classes correspond to some of the compile time uses, while in ODS you’d use similar terms to define what the op has. For example, you’d say in the .td that the op has an integer attribute foo, this will result in generating a named accessor foo() whose return type is Attribute.

– Jacques

Jacques mentioned dump, indeed many classes in MLIR (Operation, Type, Attributes at least) have a dump() method that will print it to stderr.
You can also stream theses to llvm::err():

llvm::errs() << "This is the current op: " << *op << "\n";
llvm::errs() << "This is the current block this op is in: " << *op->getParent() << "\n";
llvm::errs() << "This is the current operation holding the region this op is in: " << *op->getParentOp() << "\n";

Other debugging tips: Debugging - MLIR

That is tough, and quickly overwhelming indeed. I use to confuse myself all the time between “class Operation” and the templated “class Op<>” that registered operation derived from. It seems like some unfortunate naming sometimes. There are also many idioms that are very specific to the project, like our value type (these registered op, or attributes and types) that are just wrapping pointers and really have reference semantics.

Maybe this doc can help to get started: Understanding the IR Structure - MLIR
I should write another one about the core classes maybe.

Hi thanks a lot. I know the dump method, but it is a little bit not that way since we can only dump after the program is finished. What I would like to ask is a method that I can view the content of it while debugging. In such a way, I can better follow the code and understanding what they actually do.

And thanks for pointing out the documentation, I’ll have a close look again try to find the relevant information…

Hi, thanks again for your time.

The debugging method is helpful but may I ask for more that say if I’m debugging using IDE and can debug it step by step. Would there be a way of monitoring ModuleOp’s content and seeing what operation is being added, what is being manipulated.

I’ll have a close look to the doc listed, thanks a lot for pointing that out ~~

You should be able to invoke dump() on each operation as you build them.

Hi, I actually tried, it actually break into exemption while debugging…

Are you using custom op printers? You can pass the option to print using the generic format too. If that still fails then that’s probably a bug and filing a repro would help debug & fix.