MLIR:Getting-started-2

文章来自微信公众号“科文路”,欢迎关注、互动。转发须注明出处。

Multi-Level Intermediate Representation(MLIR)是创建可重用、可扩展编译器基础设施的新途径。本文为第 5 期,接上期,使用 Polygeist 完成一个 C 代码的 MLIR 编译执行流程。

接上周文,现在我们已经有了几个重要的 MLIR 工具:

  • mlir-opt
    • MLIR 机器无关优化
  • mlir-translate
    • 不同 MLIR 间转换
  • llc
    • LLVM 编译器
  • clang/clang++
    • LLVM C/C++前端
  • cgeist
    • MLIR C/C++前端

上文介绍了如何使用 Polygeist 完成 C 代码的 MLIR 转换。同时,polygeist-opt 工具可以在该过程的基础上完成更多的事情。更多细节请查看手册,本文不再赘述。

本文讲接下来这个转换的到的 mlir 文件的后续可能的处理之一:编译、链接、执行

主程序

编写一个 main.cpp 用以调用之前编写的函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/**
* @file main.cpp
* @brief A test for MLIR and Polygeist on matrix dot product. The correct
* result should be ([[13774, 12558, 14915], [ 6850, 6724, 5412]])
* @version 0.1
* @date 2022-09-07
*
* @license GPLv3
*
*/

#define N 200
#define M 300
#define K 400

#include <cstdlib>
#include <iostream>

extern "C" {
void matmul(long A[N][K], long B[K][M], long C[N][M]);
}

int main() {
long A[N][K], B[K][M], C[N][M];

srand(42);
for (auto n = 0; n < N; ++n) {
for (auto k = 0; k < K; ++k) {
A[n][k] = rand() % 100;
std::cout << A[n][k] << ", ";
}
std::cout << std::endl;
}
std::cout << std::endl;

for (auto k = 0; k < K; ++k) {
for (auto m = 0; m < M; ++m) {
B[k][m] = rand() % 100;
std::cout << B[k][m] << ", ";
}
std::cout << std::endl;
}
std::cout << std::endl;

for (auto n = 0; n < N; ++n) {
for (auto m = 0; m < M; ++m) {
C[n][m] = 0;
}
}

// uint st_cycles = 0, ed_cycles = 0;
// asm volatile("rdcycle %0" : "=r"(st_cycles) : : "memory");
matmul(A, B, C);
// asm volatile("rdcycle %0" : "=r"(ed_cycles) : : "memory");
// std::cout << ed_cycles - st_cycles << std::endl;

for (auto n = 0; n < N; ++n) {
for (auto m = 0; m < M; ++m) {
std::cout << C[n][m] << ", ";
}
std::cout << std::endl;
}
return 0;
}

编译

1
$MLIR_OPT matmul.affine.mlir -lower-affine -convert-scf-to-cf -convert-vector-to-llvm -convert-memref-to-llvm -llvm-request-c-wrappers -convert-func-to-llvm -reconcile-unrealized-casts |  $MLIR_TRANSLATE --mlir-to-llvmir | $MLIR_BIN/llc --filetype=obj -o matmul.o

可以看出该过程分为了三步

  1. 优化、转换原始 mlir 到 LLVM mlir
  2. 转换 LLVM mlir 到 LLVM IR
  3. 编译 LLVM IR 为 .o

于是,就得到了通用的 LLVM IR,也就回到了经典的编译流程。

链接

1
$LLVM_RV/bin/clang++ -o matmul_mlir matmul.o main_mlir.cpp

利用已经得到的 matmul.omain.cpp 可以编译、链接出最终的程序。

执行

1
2
3
4
5
6
7
8
9
10
11
./matmul_mlir
start ...
66, 40, 81, 41,
12, 58, 21, 40,

35, 43, 74,
43, 17, 4,
96, 62, 92,
48, 98, 59,

13774, 12558, 14915, 6850, 6724, 5412, #

结语

OK,本期内容就到此为止。本期粗略的介绍了如何使用 MLIR 系列工具完成编译过程,很多细节没有展开讲。下周咱们再继续。

都看到这儿了,不如关注每日推送的“科文路”、互动起来~

至少点个赞再走吧~

Author

xlindo

Posted on

2022-09-22

Updated on

2023-05-10

Licensed under

Comments