Create a new dialect in toy example in mlir

Hi, as I am new to MLIR, I am trying to create a new dialect inside toy example. My aim is to convert toy dialect to my custom dialect. Using emit=mlir I got,

module {
  toy.func @main() {
    %0 = toy.constant dense<[[2.000000e+00, 5.000000e+00, 7.000000e+00, 1.000000e+00, 5.000000e+00, 8.000000e+00]]> : tensor<1x6xf64>
    toy.print %0 : tensor<1x6xf64>
    toy.return
  }
}

But what I want after transformation it will look like

module {
  func.func @main() {
    %0 = poseidon.constant dense<[[2.000000e+00, 5.000000e+00, 7.000000e+00, 1.000000e+00, 5.000000e+00, 8.000000e+00]]> : tensor<1x6xf64>
    toy.print %0 : tensor<1x6xf64>
    return
  }
}

I am modifying toy example Ch7. My codebase tree is

Ch7
β”œβ”€β”€ CMakeLists.txt
β”œβ”€β”€ demo.toy
β”œβ”€β”€ include
β”‚   β”œβ”€β”€ CMakeLists.txt
β”‚   β”œβ”€β”€ Poseidon
β”‚   β”‚   β”œβ”€β”€ CMakeLists.txt
β”‚   β”‚   β”œβ”€β”€ Passes.h
β”‚   β”‚   β”œβ”€β”€ PoseidonDialect.h
β”‚   β”‚   β”œβ”€β”€ PoseidonDialect.td
β”‚   β”‚   β”œβ”€β”€ PoseidonOps.h
β”‚   β”‚   └── PoseidonOps.td
β”‚   └── toy
β”‚       β”œβ”€β”€ AST.h
β”‚       β”œβ”€β”€ CMakeLists.txt
β”‚       β”œβ”€β”€ Dialect.h
β”‚       β”œβ”€β”€ Lexer.h
β”‚       β”œβ”€β”€ MLIRGen.h
β”‚       β”œβ”€β”€ Ops.td
β”‚       β”œβ”€β”€ Parser.h
β”‚       β”œβ”€β”€ Passes.h
β”‚       β”œβ”€β”€ ShapeInferenceInterface.h
β”‚       └── ShapeInferenceInterface.td
β”œβ”€β”€ mlir
β”‚   β”œβ”€β”€ Dialect.cpp
β”‚   β”œβ”€β”€ LowerToAffineLoops.cpp
β”‚   β”œβ”€β”€ LowerToLLVM.cpp
β”‚   β”œβ”€β”€ LowerToPoseidon.cpp
β”‚   β”œβ”€β”€ MLIRGen.cpp
β”‚   β”œβ”€β”€ PoseidonDialect.cpp
β”‚   β”œβ”€β”€ PoseidonOps.cpp
β”‚   β”œβ”€β”€ ShapeInferencePass.cpp
β”‚   β”œβ”€β”€ ToyCombine.cpp
β”‚   └── ToyCombine.td
β”œβ”€β”€ parser
β”‚   └── AST.cpp
└── toyc.cpp

Based on LowerToAffineLoops.cpp I have created LowerToPoseidon.cpp only for ConstantOp, ReturnOP & FuncOp, But I am getting error when building:

In file included from /home/Projects/llvm-project/mlir/examples/toy/Ch7/mlir/LowerToPoseidon.cpp:16:
In file included from /home/Projects/llvm-project/mlir/examples/toy/Ch7/include/toy/Dialect.h:19:
In file included from /home/Projects/llvm-project/mlir/include/mlir/IR/FunctionInterfaces.h:17:
/home/Projects/llvm-project/mlir/include/mlir/IR/Builders.h:462:11: error: no matching member function for call to 'build'
    OpTy::build(*this, state, std::forward<Args>(args)...);
    ~~~~~~^~~~~
/home/Projects/llvm-project/mlir/include/mlir/IR/PatternMatch.h:452:18: note: in instantiation of function template specialization 'mlir::OpBuilder::create<mlir::poseidon::Constantop>' requested here
    auto newOp = create<OpTy>(op->getLoc(), std::forward<Args>(args)...);
                 ^
/home/Projects/llvm-project/mlir/examples/toy/Ch7/mlir/LowerToPoseidon.cpp:97:18: note: in instantiation of function template specialization 'mlir::RewriterBase::replaceOpWithNewOp<mlir::poseidon::Constantop>' requested here
        rewriter.replaceOpWithNewOp<poseidon::Constantop>(op);
                 ^
/home/Projects/llvm-project/build/tools/mlir/examples/toy/Ch7/include/Poseidon/PoseidonOps.h.inc:111:15: note: candidate function not viable: requires 3 arguments, but 2 were provided
  static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, DenseElementsAttr value);
              ^
/home/Projects/llvm-project/build/tools/mlir/examples/toy/Ch7/include/Poseidon/PoseidonOps.h.inc:112:15: note: candidate function not viable: requires 3 arguments, but 2 were provided
  static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, double value);
              ^
/home/Projects/llvm-project/build/tools/mlir/examples/toy/Ch7/include/Poseidon/PoseidonOps.h.inc:113:15: note: candidate function not viable: requires 4 arguments, but 2 were provided
  static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type resultType0, ::mlir::DenseElementsAttr value);
              ^
/home/Projects/llvm-project/build/tools/mlir/examples/toy/Ch7/include/Poseidon/PoseidonOps.h.inc:114:15: note: candidate function not viable: requires 4 arguments, but 2 were provided
  static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::DenseElementsAttr value);
              ^
/home/Projects/llvm-project/build/tools/mlir/examples/toy/Ch7/include/Poseidon/PoseidonOps.h.inc:115:15: note: candidate function not viable: requires at least 4 arguments, but 2 were provided
  static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {});
              ^
1 error generated.
ninja: build stopped: subcommand failed.

Please help me out. Thanks!

The error is pointing at this code your wrote.
The compiler does not find a suitable build method for this call, it helps you by telling about all the possible overloads:

/home/Projects/llvm-project/build/tools/mlir/examples/toy/Ch7/include/Poseidon/PoseidonOps.h.inc:111:15: note: candidate function not viable: requires 3 arguments, but 2 were provided
  static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, DenseElementsAttr value);
              ^
/home/Projects/llvm-project/build/tools/mlir/examples/toy/Ch7/include/Poseidon/PoseidonOps.h.inc:112:15: note: candidate function not viable: requires 3 arguments, but 2 were provided
  static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, double value);
              ^
/home/Projects/llvm-project/build/tools/mlir/examples/toy/Ch7/include/Poseidon/PoseidonOps.h.inc:113:15: note: candidate function not viable: requires 4 arguments, but 2 were provided
  static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type resultType0, ::mlir::DenseElementsAttr value);
              ^
/home/Projects/llvm-project/build/tools/mlir/examples/toy/Ch7/include/Poseidon/PoseidonOps.h.inc:114:15: note: candidate function not viable: requires 4 arguments, but 2 were provided
  static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::DenseElementsAttr value);
              ^
/home/Projects/llvm-project/build/tools/mlir/examples/toy/Ch7/include/Poseidon/PoseidonOps.h.inc:115:15: note: candidate function not viable: requires at least 4 arguments, but 2 were provided
  static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {});
              ^

So basically replaceOpWithNewOp wants to create a new operation and replace the old one with the new one, however you’re not providing any argument to build the new poseidon::Constantop, however to build it you need one (odsBuilder and odsState are implicit)

Thank you for your response. But,
In the LowerToPoseidon.cpp, I have written for ConstantOpLowering

struct ConstantopLowering : public OpRewritePattern<toy::ConstantOp> {
    using OpRewritePattern<toy::ConstantOp>::OpRewritePattern;
    LogicalResult matchAndRewrite(toy::ConstantOp op,
                                    PatternRewriter &rewriter) const final {
        rewriter.replaceOpWithNewOp<poseidon::Constantop>(op);
        return success();
    }
};

Inside PoseidonOps.cpp I have also mentioned

void Constantop::build(mlir::OpBuilder &builder, mlir::OperationState &state,
                       double value) {
  auto dataType = RankedTensorType::get({}, builder.getF64Type());
  auto dataAttribute = DenseElementsAttr::get(dataType, value);
  Constantop::build(builder, state, dataType, dataAttribute);
}

Also inside PoseidonDialect.td I have included builder as

let builders = [
        // Build a constant with a given constant tensor value.
        OpBuilder<(ins "DenseElementsAttr":$value), [{
        build($_builder, $_state, value.getType(), value);
        }]>,

        // Build a constant with a given constant floating-point value.
        OpBuilder<(ins "double":$value)>
    ];

According to the error during call of the build argument list & parameter list are not matching, How do I ensure that the build function I have written is invoked ?

You wrote the build method, don’t you think that there is an argument missing here to build the new poseidon::Constantop?

3 Likes

Thank you for pointing this out.