当前位置: 首页 > news >正文

全文 - MLIR Toy Tutorial Chapter 1: Toy Language and AST

Toy 语言

   本教程,将会借助一个玩具语言来讲解,这个语言我们称其为 Toy。Toy 是一个基于张量的语言,它允许你定义函数,执行一些数学计算,并且打印结果。做这样的设定,是因为我们希望让教程保持简明;codegen 部分将会限制张量的维度小于等于2,而且Toy中的数据类型都是 64bit 浮点型的,也就是C语言中的double类型。于是,所有的值都隐式定义为double精度的,而且,所有的值都是不变的常量,也就是说,每一个操作的返回值都会是新分配的变量,再就是,重新分配变量是自动化管理的。上述说明已经足够了,没有什么比通读一个示例更有助于理解 MLIR 的目的和方法了。

def main() {
  # Define a variable `a` with shape <2, 3>, initialized with the literal value.
  # The shape is inferred from the supplied literal.
  #定义一个形状为2行3列的变量a,如下字面逐元素初始化。变量的形状通过提供的初始化来推导。
  var a = [[1, 2, 3], [4, 5, 6]];

  # b is identical to a, the literal tensor is implicitly reshaped: defining new
  # variables is the way to reshape tensors (element count must match).
  #变量b与a是一样的,这个初始化的方式是隐式地变形了:变形张量是通过定义新的变量的方式实现的,但是元素个数必须能对上。
  var b<2, 3> = [1, 2, 3, 4, 5, 6];

  # transpose() and print() are the only builtin, the following will transpose
  # a and b and perform an element-wise multiplication before printing the result.
  #transpose() 和 print() 函数是唯一内置的函数,接下来将会转置a 和 b,并且逐元素做乘法运算,然后打印结果。
  print(transpose(a) * transpose(b));
}

类型检查是通过类型推导静态执行的;Toy 语言仅仅要求在必要的时候指定张量的类型。函数是通用的:它们的参数未指定阶数,也就是说,我们知道函数的每个参数是一个张量,但是我们不知道它们的维度。为每一个新发现的调用点的签名,都被特化处理。让我们看一遍之前的示例代码,这次我们增加了一个 用户自定义的函数:

# User defined generic function that operates on unknown shaped arguments.
# 用户自定义的通用函数,它作用在未知形状的参数上
def multiply_transpose(a, b) {
  return transpose(a) * transpose(b);
}

def main() {
  # Define a variable `a` with shape <2, 3>, initialized with the literal value.
  var a = [[1, 2, 3], [4, 5, 6]];
  var b<2, 3> = [1, 2, 3, 4, 5, 6];

  # This call will specialize `multiply_transpose` with <2, 3> for both
  # arguments and deduce a return type of <3, 2> in initialization of `c`.
  # 这个调用将会给函数 multiply_transpose 指定两个形状为2行3列的张量作为参数,并且推导出返回值c的形状为3行2列,按此做初始化。
  var c = multiply_transpose(a, b);

  # A second call to `multiply_transpose` with <2, 3> for both arguments will
  # reuse the previously specialized and inferred version and return <3, 2>.
  #基本同上
  var d = multiply_transpose(b, a);

  # A new call with <3, 2> (instead of <2, 3>) for both dimensions will
  # trigger another specialization of `multiply_transpose`.
  # 这里是一个新的调用,入参的形状变为3行2列,而不再是2行3列,这将会触发特化另一新的 multiply_transpose函数的实现。
  var e = multiply_transpose(c, d);

  # Finally, calling into `multiply_transpose` with incompatible shapes
  # (<2, 3> and <3, 2>) will trigger a shape inference error.
  # 最后,调用对函数 multiply_transpose 做一次参数形状不兼容的调用,这将会触发一个形状推导错误。
  var f = multiply_transpose(a, c);
}

dump AST

从上边的代码生成的 AST 是相当简单的。这里对它做了转储:

Module:
  Function 
    Proto 'multiply_transpose' @test/Examples/Toy/Ch1/ast.toy:4:1
    Params: [a, b]
    Block {
      Return
        BinOp: * @test/Examples/Toy/Ch1/ast.toy:5:25
          Call 'transpose' [ @test/Examples/Toy/Ch1/ast.toy:5:10
            var: a @test/Examples/Toy/Ch1/ast.toy:5:20
          ]
          Call 'transpose' [ @test/Examples/Toy/Ch1/ast.toy:5:25
            var: b @test/Examples/Toy/Ch1/ast.toy:5:35
          ]
    } // Block
  Function 
    Proto 'main' @test/Examples/Toy/Ch1/ast.toy:8:1
    Params: []
    Block {
      VarDecl a<> @test/Examples/Toy/Ch1/ast.toy:11:3
        Literal: <2, 3>[ <3>[ 1.000000e+00, 2.000000e+00, 3.000000e+00], <3>[ 4.000000e+00, 5.000000e+00, 6.000000e+00]] @test/Examples/Toy/Ch1/ast.toy:11:11
      VarDecl b<2, 3> @test/Examples/Toy/Ch1/ast.toy:15:3
        Literal: <6>[ 1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00] @test/Examples/Toy/Ch1/ast.toy:15:17
      VarDecl c<> @test/Examples/Toy/Ch1/ast.toy:19:3
        Call 'multiply_transpose' [ @test/Examples/Toy/Ch1/ast.toy:19:11
          var: a @test/Examples/Toy/Ch1/ast.toy:19:30
          var: b @test/Examples/Toy/Ch1/ast.toy:19:33
        ]
      VarDecl d<> @test/Examples/Toy/Ch1/ast.toy:22:3
        Call 'multiply_transpose' [ @test/Examples/Toy/Ch1/ast.toy:22:11
          var: b @test/Examples/Toy/Ch1/ast.toy:22:30
          var: a @test/Examples/Toy/Ch1/ast.toy:22:33
        ]
      VarDecl e<> @test/Examples/Toy/Ch1/ast.toy:25:3
        Call 'multiply_transpose' [ @test/Examples/Toy/Ch1/ast.toy:25:11
          var: c @test/Examples/Toy/Ch1/ast.toy:25:30
          var: d @test/Examples/Toy/Ch1/ast.toy:25:33
        ]
      VarDecl f<> @test/Examples/Toy/Ch1/ast.toy:28:3
        Call 'multiply_transpose' [ @test/Examples/Toy/Ch1/ast.toy:28:11
          var: a @test/Examples/Toy/Ch1/ast.toy:28:30
          var: c @test/Examples/Toy/Ch1/ast.toy:28:33
        ]
    } // Block

可以在文件夹 examples/toy/Ch1/ 中的示例代码上重新生成这个AST。请尝试运行:

path/to/BUILD/bin/toyc-ch1 test/Examples/Toy/Ch1/ast.toy -emit=ast

相关文章:

  • BM100-K系列开关量输入信号隔离器
  • 菱形虚拟继承的原理
  • WPF 浅述ToolTipService.ShowOnDisabled
  • Flask接口开发--GET接口
  • 路由选型终极对决:直连/静态/动态三大类型+华为华三思科配置差异,一张表彻底讲透!
  • Java Collection API增强功能系列之一 Arrays.asList()
  • 如何分析和解决服务器的僵尸进程问题
  • nginx服务配置练习
  • [蓝桥杯 2023 省 A] 异或和之和
  • P5356 [Ynoi Easy Round 2017] 由乃打扑克 Solution
  • Redis分布式寻址算法
  • XXL-Job 二次分片是怎么做的?有什么问题?怎么去优化的?
  • ARCGIS PRO SDK ProWindow自定义窗口DataGrid控件的应用
  • langchain-ollama的ragflow简单实现
  • 车载以太网网络测试 -23【TCPUDP通信示例】
  • 模糊规则激活方法详解(python实例对比)
  • 【Tauri2】001——安装及运行
  • shadcn如何给dialog增加关闭按钮和隐藏右上角关闭按钮
  • 重写ring3 API函数
  • 安宝特应用 | 军工级数据安全赋能保密产品数字化交付
  • 新华每日电讯:给“男性妇科病论文”开一剂复方药
  • 经彩申城!上海网络大V沙龙活动走进闵行
  • 习近平向“和平薪火 时代新章——纪念中国人民抗日战争和苏联伟大卫国战争胜利80周年中俄人文交流活动”致贺信
  • 陈雯出任外交部离退休干部局局长,此前为外交部办公厅副主任
  • 夜读丨最美的风景,在亲人的目光里
  • 五一档7.47亿收官:《水饺皇后》领跑;男观众占比增多