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