MLIR官方Tutorials学习笔记(二)

        本章主要讲解了如何创建一个自己的Dialect并创建其中的Operations。

        我们使用ODS框架(Operation Defination Specification)来讲编写的.td文件自动转换成c++文件。下面的思路图我偷了知乎的法斯特豪斯:

        图里说的很明白,三步:定义自己的Dialect,创建自己Dialect Operation的基类,在自己的Dialect里创建各种Operations。

        下面我们就添加一个自己的Operation,作用是实现向量的自增,首先在.td里定义如下:

def SelfAddOp : Toy_Op<"selfadd"> {
  let summary = "self-add operation";

  let arguments = (ins F64Tensor:$input);
  let results = (outs F64Tensor);

  let assemblyFormat = [{
    `(` $input `:` type($input) `)` attr-dict `to` type(results)
  }];

  // Allow building a TransposeOp with from the input operand.
  let builders = [
    OpBuilder<(ins "Value":$input)>
  ];

  // Invoke a static verify method to verify this transpose operation.
  let hasVerifier = 1;
}

        之后我们可以使用mlir-tblgen工具搭配-gen-op-decls查看生成的operations C++声明。

bin/mlir-tblgen -gen-op-decls ../mlir/examples/toy/Ch2/include/toy/Ops.td -I ../mlir/include/

        使用mlir-tblgen工具搭配-gen-op-defs查看生成的operations C++定义。

bin/mlir-tblgen -gen-op-defs ../mlir/examples/toy/Ch2/include/toy/Ops.td -I ../mlir/include/

        然后我们在Dialect.cpp里添加selfadd operation的build和verify函数实现:

void SelfAddOp::build(mlir::OpBuilder &builder, mlir::OperationState &state,
                        mlir::Value value) {
  state.addTypes(UnrankedTensorType::get(builder.getF64Type()));
  state.addOperands(value);
} //配置一个新的操作状态:将操作的结果Type设置为UnrankedTensorType,元素类型为F64;设置操作数为操作输入值value。

llvm::LogicalResult SelfAddOp::verify() {
  auto inputType = llvm::dyn_cast<RankedTensorType>(getOperand().getType());
  auto resultType = llvm::dyn_cast<RankedTensorType>(getType());
  if (!inputType || !resultType)
    return mlir::success();

  auto inputShape = inputType.getShape();
  if (!std::equal(inputShape.begin(), inputShape.end(),
                  resultType.getShape().begin())) {
    return emitError()
           << "the shape does not fit";
  }
  return mlir::success();
} //verify用于验证操作的合法性。inputType是操作数的Type,resultType是结果的Type,通过检查操作数Type的shape是否和结果Type的shape相同来验证合法性。

        最后,我们在MLIRGen.cpp里的mlir::Value mlirGen(CallExprAST &call)函数里添加对selfadd调用时的操作:

if (callee == "selfadd") {
      if (call.getArgs().size() != 1) {
        emitError(location, "MLIR codegen encountered an error: toy.selfadd "
                            "does not accept multiple arguments");
        return nullptr;
      }
      return builder.create<SelfAddOp>(location, operands[0]);
    }

至此,添加自己的Operation(一个selfadd操作)完成。

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值