MLIR官方Tutorial学习笔记(三)

        这章主要讲解了表达式的匹配重写(pattern match rewrite),有两种方式:通过DRR在td文件中重写,或直接用C++写匹配重写函数。我们这里主要使用第二种方式。

        给了一个例子,转置的转置可以直接写成原操作数:

transpose(transpose(x)) = x;

        首先我们定义transpose简化类,继承自mlir的OpRewritePattern:

struct SimplifyRedundantTranspose : public mlir::OpRewritePattern<TransposeOp> 

        在类中定义rewrite方法:

llvm::LogicalResult
  matchAndRewrite(TransposeOp op,
                  mlir::PatternRewriter &rewriter) const override {
    // Look through the input of the current transpose.
    mlir::Value transposeInput = op.getOperand(); //获取transposeOp的操作数
    TransposeOp transposeInputOp = transposeInput.getDefiningOp<TransposeOp>();
    //获取transpose操作数的操作Op,若为不为transpose,则直接返回failure
    // Input defined by another transpose? If not, no match.
    if (!transposeInputOp)
      return failure();

    // Otherwise, we have a redundant transpose. Use the rewriter.
    rewriter.replaceOp(op, {transposeInputOp.getOperand()});//若是,则执行替换
    return success();
  }

        另外,要在Ops.td里在transposeOp的定义里启用hasCanonicalizer选项,以便使用canonicalization框架,同时添加[NoSideEffect]参数,用来清除Operation中的副作用,如下:

你问我为什么要这么干?我也不知道。

def TransposeOp : Toy_Op<"transpose", [NoSideEffect]> {
     // Enable registering canonicalization patterns with this operation.
      let hasCanonicalizer = 1;

        最后把我们编写的patterns注册成规范化pattern, 来让canonicalization framework pick up:

void TransposeOp::getCanonicalizationPatterns(RewritePatternSet &results,
                                              MLIRContext *context) {
  results.add<SimplifyRedundantTranspose>(context);
}

        这样就实现了transpose嵌套的一个匹配重写优化。

        接下来我们实现另一个优化,首先我在Ops.td里定义了两个Operation,selfaddone()和selfsubone(),也就是自增1和自减1,我们要实现的匹配重写是:

selfsubone(selfaddone(x)) = x;

        因为首先匹配的是selfaddoneOp,所以记得在selfaddoneOp的定义里把“let hasCanonicalizer = 1”加上哦。

        接着老套路,定义SimplifyRedundantAddSub 类继承自mlir::OpRewritePattern<SelfSubOneOp>:

struct SimplifyRedundantAddSub : public mlir::OpRewritePattern<SelfSubOneOp>

        其中的匹配重写函数:

lvm::LogicalResult
  matchAndRewrite(SelfSubOneOp op, mlir::PatternRewriter& rewriter) const override{
    mlir::Value selfsubInput = op.getOperand();
    SelfAddOneOp selfsubInputOp = selfsubInput.getDefiningOp<SelfAddOneOp>();
    
    if(!selfsubInputOp)
      return failure();

    rewriter.replaceOp(op, {selfsubInputOp.getOperand()});
    return success();
  }

        其中的逻辑我相信聪明的你一眼就懂了。

        最后注册一下:

void SelfSubOneOp::getCanonicalizationPatterns(RewritePatternSet& results, 
                                                MLIRContext* context)
{
  results.add<SimplifyRedundantAddSub>(context);
}

        ok了,测试一下:很完美

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值