Table-driven Declarative Rewrite Rule (DRR)

Table-driven Declarative Rewrite Rule (DRR

  • 好处
  • 规则定义
  • 原模式
  • 基于位置的匹配
  • 操作的匹配有向无环图(DAG)
    • (AOp (BOp), $attr):
  • 绑定操作的结果

好处

模式创建者只需要声明性地指定重写模式,而不必担心调用具体的C++方法。
消除样板代码,展示重写的核心:mlir::RewritePattern已经能够很好地隐藏定义重写规则的样板代码。但是我们仍然需要编写C++编程语言所需的类和函数结构,检查操作符以进行匹配,并调用操作符的build()方法进行构建。这些语句通常非常简单且相似,因此可以进一步通过自动生成来简化。由于我们将样板代码减少到最低限度,声明性的重写规则将只包含重写的核心要素。这使得模式非常容易理解。

规则定义

重写规则的核心构造是在[PatternBase.td][PatternBase]中定义的:

class Pattern<
    dag sourcePattern, list<dag> resultPatterns,
    list<dag> additionalConstraints = [],
    list<dag> supplementalPatterns = [],
    dag benefitsAdded = (addBenefit 0)>;

一个声明式的重写规则包含两个主要组件:

  • 源模式,用于匹配操作的DAG。
  • 一个或多个结果模式,用于生成操作的DAG以替换匹配到的DAG。

我们允许多个结果模式以支持多结果操作和辅助操作,但通常我们只是想将一个操作的DAG转换为另一个操作的DAG。有一个方便的Pattern包装器,Pat,它接受一个单一的结果模式:

class Pat<
    dag sourcePattern, dag resultPattern,
    list<dag> additionalConstraints = [],
    dag benefitsAdded = (addBenefit 0)> :
  Pattern<sourcePattern, [resultPattern], additionalConstraints, benefitsAdded>;

每个模式被指定为一个TableGen的DAG对象,语法为(operator arg0, arg1, …)。

  • operator 通常是一个MLIR操作,但它也可以是其他指令。
  • argN 用于匹配(如果在源模式中使用)或生成(如果在结果模式中使用)operator的第N个参数。如果操作是某个MLIR操作,这意味着第N个参数如操作定义的参数列表中所指定。因此,我们说模式中的操作参数规范是基于位置的:它们出现的位置很重要。

argN 本身可以是一个DAG对象,因此我们可以有嵌套的DAG树来建模操作之间的定义-使用关系。

比如加法重写为乘法

def : Pat<
    (AddI32 $x, $y),
    (MulI32 $x, $y)
>;

假设我们有一个32位整数加法操作 AddI32,我们希望将其转换为一个乘法操作 MulI32 和一个减法操作 SubI32。以下是一个声明式重写规则的例子:

def : Pattern<
    (AddI32 $x, $y), 
    [(MulI32 $x, $y), (SubI32 $x, $y)]
>;
  • def : Pat:用于定义简单的匹配和替换规则,适用于简单的操作模式。
  • def : Pattern:用于定义更复杂的匹配和替换规则,可以包含更多的属性和逻辑,适用于复杂的操作模式。

原模式

源模式用于匹配操作的有向无环图(DAG)。DAG对象中的参数旨在捕获操作的参数。它们还可以用于进一步限制匹配条件。捕获是通过指定以 $ 符号开头的符号来完成的,而进一步的约束是通过指定 TypeConstraint(对于操作数)或 AttrConstraint(对于属性)来引入的。

在这个上下文中,我们可以将操作的参数捕获下来。捕获的方式是通过使用 $ 符号开头的标识符,例如 $a_input 和 $a_attr。我们还可以通过 TypeConstraint(类型约束)和 AttrConstraint(属性约束)来进一步限制这些参数。

def AOp : Op<"a_op"> {
    let arguments = (ins
      AnyType:$a_input,
      AnyAttr:$a_attr
    );

    let results = (outs
      AnyType:$a_output
    );
}

在这个例子中,我们定义了一个操作 AOp,它有两个参数:

  • $a_input,可以是任何类型(AnyType)。
  • $a_attr,可以是任何属性(AnyAttr)。

操作的结果定义为一个输出($a_output),它也是任意类型。

接下来,我们定义一个模式:

def : Pat<(AOp $input, F32Attr:$attr), ...>;

这个模式匹配一个 AOp 操作,其中:

  • $input 可以是任何有效的输入。
  • $attr 必须是一个浮点属性(F32Attr)。

如果这个模式匹配成功,我们会将 $input 绑定到操作的输入 $a_input,并将 $attr 绑定到操作的属性 $a_attr。之后,我们可以在其他模式和约束中使用这些绑定。

位置匹配和符号使用

在定义模式(pattern)的时候,你不需要严格遵循操作(operation)定义中使用的符号名称。换句话说,你可以使用不同的符号名称来匹配操作定义中的参数,只要它们的位置对应即可。让我们通过一个具体的例子来说明这一点

假设我们有一个操作定义如下:

def AOp : Op<"a_op"> {
    let arguments = (ins
      AnyType:$a_input,
      AnyAttr:$a_attr
    );

    let results = (outs
      AnyType:$a_output
    );
}

基于位置的匹配

当我们定义一个模式来匹配这个操作时,位置(顺序)比符号名称更重要。也就是说,你可以在模式中使用不同的符号名称来引用这些参数,只要它们的位置正确。例如:

def : Pat<(AOp $input, F32Attr:$attr), ...>;

在这个模式中:

  • $input 对应于 AOp 操作的第一个参数 $a_input。
  • $attr 对应于 AOp 操作的第二个参数 $a_attr,并且施加了浮点属性(F32Attr)的约束。

尽管符号名称不同),但因为它们的位置与 AOp 操作定义中的参数位置一致,所以匹配依然有效。

操作的匹配有向无环图(DAG)

要匹配一个操作的有向无环图(DAG),使用嵌套的DAG对象:

def BOp : Op<"b_op"> {
    let arguments = (ins);

    let results = (outs
      AnyType:$b_output
    );
}

def : Pat<(AOp (BOp), $attr), ...>;

(AOp (BOp), $attr):

这部分表示我们想要匹配的操作图结构。

  • AOp 是我们想要匹配的主要操作(Op)。
  • (BOp) 表示 AOp 的输入必须由 BOp 生成。换句话说,AOp 的唯一输入必须是 BOp 的输出。
  • $attr 是一个占位符,表示 AOp 操作可能有某些属性,我们用 $attr 来匹配这些属性。
    所以,我们可能会匹配到这样的两行IR
%0 = "b_op"() : () -> f32
%1 = "a_op"(%0) {attr = "example"} : (f32) -> i32

绑定操作的结果

在编写某种模式匹配的代码时,有时候我们需要将一个符号(变量)与某个操作的结果进行绑定,以便在后续的代码中可以引用这个结果。通过在操作定义中附加这个符号,我们就可以实现这种绑定。

举个MLIR(多级中间表示)的例子:
假设我们有两个操作AOp和BOp,并且BOp有一个结果需要在AOp中使用。我们可以这样定义一个模式(pattern):

def : Pat<(AOp (BOp:$b_result), $attr), /* 替换规则 */>;

在这个例子中,$b_result 就被绑定到 BOp 的结果上,这样我们在后续的模式或替换规则中可以引用 $b_result。

func @example_func() -> i32 {
  %0 = "BOp"() : () -> i32
  %1 = "AOp"(%0) : (i32) -> i32
  return %1 : i32
}

在这个示例中,BOp的结果(%0)被绑定到变量$b_result,并在AOp中作为输入使用。这种绑定方式在模式匹配和转换中非常有用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/774782.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

关于ORACLE单例数据库中的logfile的切换、删除以及添加

一、有关logfile的状态解释 UNUSED&#xff1a; 尚未记录change的空白group&#xff08;一般会出现在loggroup刚刚被添加&#xff0c;或者刚刚使用了reset logs打开数据库&#xff0c;或者使用clear logfile后&#xff09; CURRENT: 当前正在被LGWR使用的gro…

产科管理系统 专科电子病历系统源码,前后端分离架构,多家医院产科广泛运用,系统稳定,功能齐全

产科管理系统 专科电子病历系统源码&#xff0c;前后端分离架构&#xff0c;多家医院产科广泛运用&#xff0c;系统稳定&#xff0c;功能齐全 产科管理系统&#xff0c;特别是产科信息管理系统&#xff08;Obstetrical Information Management System&#xff0c;简称OIMS&…

建智慧医院核心:智能导航系统的功能全析与实现效益

在数字化转型的浪潮中&#xff0c;智慧医院的建设是医疗行业数字化转型的关键步骤。随着医院规模的不断扩大和医疗设施的日益复杂&#xff0c;传统的静态不连续的导航方式已无法满足患者的需求。院内智能导航系统&#xff0c;作为医疗数字化转型的关键组成部分&#xff0c;正逐…

2024骨传导耳机品牌排行榜!盘点10款优质热门机型推荐!

骨传导耳机逐渐成为当下最受欢迎的热门机型&#xff0c;但随着耳机热度的增高&#xff0c;市面上一些不法商家仿佛看到了商机&#xff0c;纷纷投入骨传导耳机市场&#xff0c;这也导致骨传导耳机市场出现鱼龙混杂&#xff0c;劣质品牌横行的局面&#xff0c;纷纷有消费者反馈说…

android2024 gradle8 Processor和ksp两种编译时注解实现

android的编译时注解&#xff0c;老生常谈&#xff0c;外面的例子都是bindView&#xff0c;脑壳看疼了&#xff0c;自己学习和编写下。 而且现在已经进化到kotlin2.0了&#xff0c;google也逐渐放弃kapt&#xff0c;进入维护状态。所以要好好看看本贴。 参考我的工程&#xff1…

djangoGD高校信管专业就业信息管理系统-计算机毕业设计源码59343

djangoGD高校信管专业就业信息管理系统 摘 要 随着高校信管专业的快速发展&#xff0c;学生就业问题日益受到广泛关注。为了更好地服务学生&#xff0c;提高就业率&#xff0c;许多高校开始引入信息化手段来管理学生就业信息。然而&#xff0c;传统的就业信息管理方式存在很多问…

Linux关于文件的高级命令

tree命令 tree命令用于以树状图的形式显示目录结构。它可以帮助用户快速了解目录和文件的层次关系&#xff0c;非常适合用于浏览和理解大型文件系统的结构。 基础用法 显示当前目录的树状结构&#xff1a;tree 显示指定目录的树状结构&#xff1a;tree 指定目录路径 tree命…

【C++】 解决 C++ 语言报错:Segmentation Fault

文章目录 引言 段错误&#xff08;Segmentation Fault&#xff09;是 C 编程中常见且令人头疼的错误之一。段错误通常发生在程序试图访问未被允许的内存区域时&#xff0c;导致程序崩溃。本文将深入探讨段错误的产生原因、检测方法及其预防和解决方案&#xff0c;帮助开发者在…

昇思25天学习打卡营第5天 | 神经网络构建

1. 神经网络构建 神经网络模型是由神经网络层和Tensor操作构成的&#xff0c;mindspore.nn提供了常见神经网络层的实现&#xff0c;在MindSpore中&#xff0c;Cell类是构建所有网络的基类&#xff0c;也是网络的基本单元。一个神经网络模型表示为一个Cell&#xff0c;它由不同…

如何摆脱反爬虫机制?

在网站设计时&#xff0c;为了保证服务器的稳定运行&#xff0c;防止非法数据访问&#xff0c;通常会引入反爬虫机制。一般来说&#xff0c;网站的反爬虫机制包括以下几种&#xff1a; 1. CAPTCHA&#xff1a;网站可能会向用户显示CAPTCHA&#xff0c;要求他们在访问网站或执行…

Netty学习(Netty入门)

概述 Netty是什么 Netty的地位 Netty的优势 HelloWorld public class HelloClient {public static void main(String[] args) throws InterruptedException {// 1. 启动类new Bootstrap()// 2. 添加 EventLoop.group(new NioEventLoopGroup())// 3. 选择客户端 channel 实现.…

python绘制领域矩形

问题描述&#xff1a; 使用python书写代码实现以下功能&#xff1a;给定四个点的坐标&#xff0c;调用一个函数&#xff0c;可以使原来的四个点分别向四周上下左右移动15距离&#xff0c;分别记录下移动后的坐标&#xff0c;然后画出内侧矩形和外侧矩形 代码&#xff1a; im…

配置并调试后端程序(sql)

1.环境准备 安装VS Code和Node.js插件&#xff1a;确保你已经安装了VS Code和Node.js插件。创建launch.json文件&#xff1a;在你的项目中创建一个.vscode文件夹&#xff0c;并在其中创建launch.json文件。添加以下内容&#xff1a; {"version": "0.2.0"…

【C语言】五子棋(c语言实现)

这里写目录标题 最终效果菜单打印函数棋盘的初始化和打印人人对战落子判空函数悔棋函数判胜负函数人人对战 人机对战一是将直接调用rand生成随机值&#xff0c;这就不可控二是根据棋子赢面来判断哪里落子最好 如果选择退出程序直接exit就行主函数调用逻辑源代码 最终效果 五子棋…

The Sandbox 人物化身每月奖励: 七月版来了!

人物化身的持有者可以从 The Sandbox 领取自己的队服&#xff01; 视频&#xff1a;https://youtu.be/tSo5FPL7DhE 我们又推出了人物化身所有者月度奖励&#xff01;在七月&#xff0c;我们将通过 The Sandbox 队服来弘扬体育竞技精神。穿上这些时尚的元宇宙队服&#xff0c;代…

深度报告 | 百度安全携手极越安全发布《整车安全渗透测试白皮书》

注重点&#xff0c;如何确保车辆全生命周期的安全已成为整个行业亟待解决的问题。对于车企而言&#xff0c;通过渗透测试尽量多地发现安全威胁&#xff0c;是确保车辆信息系统的稳定运行、保障用户安全驾驶至关重要的措施。然而&#xff0c;传统的渗透测试方法已无法满足智能网…

Linux miniconda 安装tensorflow-gpu遇到找不到GPU问题

背景&#xff1a; Linux Miniconda python3.9 安装步骤 1、 pip install tensorflow-gpu2.8.0 -i https://pypi.tuna.tsinghua.edu.cn/simple 2、报错如下&#xff1a; 更换镜像源&#xff0c;单独安装 pip install tf-estimator-nightly2.8.0.dev2021122109 -i https:/…

使用 docker buildx 构建跨平台镜像

buildx是Docker官方提供的一个构建工具&#xff0c;它可以帮助用户快速、高效地构建Docker镜像&#xff0c;并支持多种平台的构建。使用buildx&#xff0c;用户可以在单个命令中构建多种架构的镜像&#xff0c;例如x86和arm架构&#xff0c;而无需手工操作多个构建命令。此外bu…

【docker】容器内配置环境变量

背景&#xff1a; 我要把下面的环境变量写到bash脚本里&#xff0c;起名叫environment_start.sh。 目的&#xff1a; 用于每次进入容器dev_into.sh的时候&#xff0c;让系统获取到环境变量。 操作步骤&#xff1a; 先在容器外找个合适的位置写环境变量bash脚本&#xff0c…

bmob Harmony鸿蒙快速开发搜索功能

搜索功能是很多应用都需要的功能。在很多平台上&#xff0c;要开发一个兼容性较好的搜索功能都还是需要添加比较多的视图代码的。 为了解决这个问题&#xff0c;鸿蒙ArkUI提供了一个快速添加搜索功能的视图组件给我们&#xff0c;结合Bmob Harmony鸿蒙SDK的搜索能力&#xff0…