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

mlir learn

https://github.com/j2kun/mlir-tutorial
学习这个项目
https://www.jeremykun.com/2023/08/10/mlir-getting-started/
get start
用我的mac编译一下试试看
然后遇到架构不对的问题
因为他的提交默认是x86
https://github.com/j2kun/mlir-tutorial/pull/1/commits/5a267e269d579da0b4ee90f3c7452017fea1ec28#diff-5493ff8e9397811510e780de47c57abb70137f1afe85d1519130dc3679d60ce5
而我的是AARCH64,在这个链接可以看到所有的_LLVM_TARGETS
https://forums.gentoo.org/viewtopic-p-8776988.html?sid=12f4b13276660e37d4bfafa765d54ef3

然后就可以编译成功了

命令是

https://github.com/j2kun/mlir-tutorial.git
git reset --hard 60cfbe01804aa5c157d56a9fb9370521d18f5578

然后修改bazel/setup_llvm.bzl
里面的_LLVM_TARGETS改成AARCH64

bazel build @llvm-project//mlir:IR
bazel build @llvm-project//mlir/...:all
bazel run @llvm-project//mlir:mlir-opt -- --help

第二篇

// 定义一个函数 main,接收一个 i32 类型的参数 arg0,并返回一个 i32 类型的值
func.func @main(%arg0: i32) -> i32 {
  // 调用函数 my_ctlz,传递参数 arg0,返回值存储在 %0 中
  %0 = func.call @my_ctlz(%arg0) : (i32) -> i32
  // 返回 %0 作为结果
  func.return %0 : i32
}

// 定义函数 my_ctlz,计算前导零的数量,接收一个 i32 类型的参数 arg0,并返回一个 i32 类型的值
func.func @my_ctlz(%arg0: i32) -> i32 {
  // 定义常量 32 和 0,都是 i32 类型
  %c32_i32 = arith.constant 32 : i32
  %c0_i32 = arith.constant 0 : i32
  
  // 比较 arg0 是否等于 0,结果存储在 %0 中
  %0 = arith.cmpi eq, %arg0, %c0_i32 : i32
  
  // 如果 arg0 等于 0,返回常量 32,表示 32 个前导零
  %1 = scf.if %0 -> (i32) {
    scf.yield %c32_i32 : i32
  } else {
    // 否则,进入循环逻辑
    // 定义一些常量:1 (index类型),1 (i32类型),32 (index类型),0 (i32类型)
    %c1 = arith.constant 1 : index
    %c1_i32 = arith.constant 1 : i32
    %c32 = arith.constant 32 : index
    %c0_i32_0 = arith.constant 0 : i32

    // 使用 for 循环,从 1 到 32,每次步进 1
    // 迭代参数为 %arg2 (初始值为 arg0),%arg3 (初始值为 0),返回 i32 和 i32 类型的结果
    %2:2 = scf.for %arg1 = %c1 to %c32 step %c1 iter_args(%arg2 = %arg0, %arg3 = %c0_i32_0) -> (i32, i32) {
      
      // 比较 arg2 是否为负数(即左移后是否变为负数)
      %3 = arith.cmpi slt, %arg2, %c0_i32 : i32
      
      // 如果 %arg2 为负数,终止循环并返回当前 %arg2 和 %arg3
      %4:2 = scf.if %3 -> (i32, i32) {
        scf.yield %arg2, %arg3 : i32, i32
      } else {
        // 否则,更新 %arg3(即前导零的数量加 1)
        %5 = arith.addi %arg3, %c1_i32 : i32
        // 同时将 %arg2 左移 1 位
        %6 = arith.shli %arg2, %c1_i32 : i32
        // 返回更新后的 %arg2 和 %arg3
        scf.yield %6, %5 : i32, i32
      }

      // 循环结束时,返回当前的 %arg2 和 %arg3
      scf.yield %4#0, %4#1 : i32, i32
    }

    // 返回前导零的计数,即循环中 %2#1 的值
    scf.yield %2#1 : i32
  }
  // 返回结果 %1
  func.return %1 : i32
}

这是ctlz的一个实现,是mlir-opt自动生成的,从

module {
  func.func @main(%arg0: i32) -> i32 {
    %0 = math.ctlz %arg0 : i32
    return %0 : i32
  }
}

生成的

git reset --hard 1b4cf45ca0f095c66fc22fd3adc8feaf2da67af2

不要用苹果电脑,会报x86的codegen错误

bazel安装还是挺简单的

只需要看这个https://ym9omojhd5.feishu.cn/wiki/Hrw0wazfCitLGgky6pfc8pMgnbg
软件包下这个https://mirrors.huaweicloud.com/bazel/6.2.1/bazel-6.2.1-linux-x86_64
chmod一下就可以食用了
然后export一下就可以快速使用

然后在mlir-tutorial下使用

bazel test //tests:all

或者

bazel test //tests:ctlz.mlir.test    

搞了我好久才弄懂

如果把mlir-tutorial/tests/ctlz_simple.mlir
改成

// RUN: mlir-opt %s --convert-math-to-funcs=convert-ctlz | FileCheck %s

func.func @main(%arg0: i32) -> i32 {
  // CHECK: call
  // CHECK: foo
  // CHECK: return
  %0 = math.ctlz %arg0 : i32
  func.return %0 : i32
}

再执行bazel test //tests:ctlz_simple.mlir.test
就会报错

在这里插入图片描述
ctlz_runner.mlir文件是对功能进行测试

// RUN: mlir-opt %s \
// RUN:   -pass-pipeline="builtin.module( \
// RUN:      convert-math-to-funcs{convert-ctlz}, \
// RUN:      func.func(convert-scf-to-cf,convert-arith-to-llvm), \
// RUN:      convert-func-to-llvm, \
// RUN:      convert-cf-to-llvm, \
// RUN:      reconcile-unrealized-casts)" \
// RUN: | mlir-cpu-runner -e test_7i32_to_29 -entry-point-result=i32 > %t
// RUN: FileCheck %s --check-prefix=CHECK_TEST_7i32_TO_29 < %t

func.func @test_7i32_to_29() -> i32 {
  %arg = arith.constant 7 : i32
  %0 = math.ctlz %arg : i32
  func.return %0 : i32
}
// CHECK_TEST_7i32_TO_29: 29


// RUN: mlir-opt %s \
// RUN:   -pass-pipeline="builtin.module( \
// RUN:      convert-math-to-funcs{convert-ctlz}, \
// RUN:      func.func(convert-scf-to-cf,convert-arith-to-llvm), \
// RUN:      convert-func-to-llvm, \
// RUN:      convert-cf-to-llvm, \
// RUN:      reconcile-unrealized-casts)" \
// RUN: | mlir-cpu-runner -e test_7i64_to_61 -entry-point-result=i64 > %t
// RUN:  FileCheck %s --check-prefix=CHECK_TEST_7i64_TO_61 < %t
func.func @test_7i64_to_61() -> i64 {
  %arg = arith.constant 7 : i64
  %0 = math.ctlz %arg : i64
  func.return %0 : i64
}
// CHECK_TEST_7i64_TO_61: 61

这里的mlir经过了多级下降成为llvm,最后使用mlir-cpu-runner运行起来
里面测试了32位的7的ctlz的结果是29
64位的ctlz的7结果是61


http://www.kler.cn/news/361109.html

相关文章:

  • python的特殊方法
  • <a-table>行数据增加点击事件并获取点击行的数据+自定义button按事件
  • 比亚迪与《黑神话:悟空》的游戏全球战略合作。
  • 代码随想录算法训练营第十天|1. 两数之和,第454题.四数相加II
  • vue 报告标题时间来自 elementUI的 el-date-picker 有开始时间和结束时间
  • 【Vue】Vue3.0(十)toRefs()和toRef()的区别及使用示例
  • 【C++刷题】力扣-#243-最短单词距离
  • 期权懂|想交易科创板ETF期权需要开户账号吗?
  • 【C++ 算法进阶】算法提升三
  • Zookeeper面试整理-Zookeeper的基础概念
  • AWK不再难:案例驱动学习,让你成为数据处理高手!
  • Mamba学习笔记(3)—S4原理基础
  • Java学习Day50:唤醒八戒(Excel相关)
  • 算法-利用深度优先搜索求解二叉树路径问题
  • 服务器中使用wss协议连接websocket(基于netty)
  • Elasticsearch高级搜索技术-基于时间的数据处理
  • DS几大常见排序讲解和实现(中)(14)
  • 一起搭WPF框架之加载图片
  • 宝塔安装ffmpeg的方法
  • 浅谈计算机存储体系和CPU缓存命中