Accera - 适用于计算密集型代码的优化交叉编译器
项目描述
待解决的问题
在传统编程语言中编写高度优化的计算密集型代码既费力又耗时。这不仅需要熟练掌握汇编语言等高级工程技能,还需要对计算机架构有深入的理解。即使是简单的数值算法的手动优化也需要巨大的工程努力。不用说,高度优化的数值代码往往容易出错,可读性差,可用性也很低。代码维护变成了一场噩梦,每次引入架构级别的变化时都需要重新实现相同的逻辑。
Accera:一个优化的解决方案
Accera是一个编译器,允许您在不手动编写汇编代码的情况下尝试循环优化。使用Accera,这些问题和障碍可以以优化的方式解决。它作为一个Python库提供,并支持跨编译到广泛的处理器目标。
Accera有三个主要目标
- 性能:保证任何计算密集型算法的最快实现。
- 可读性:确保算法的有效实现,同时不牺牲代码的可读性。
- 易用性:提供一个用户友好的编程模型,设计用于敏捷性和可维护性。
安装
对于Linux、macOS或Windows(需要Python 3.7-3.10)进行安装
pip install accera
有关安装预构建Python 3包以及如何从源代码构建Accera的更多详细信息,请参阅安装说明。
快速入门
在这个示例中,我们将
- 实现具有ReLU激活(matmul + ReLU)的矩阵乘法,这是机器学习算法中常用的一种。
- 生成两种实现:一种简单的算法和基于循环的转换。
- 比较两种实现的执行时间。
在浏览器中运行
无需安装。这将在云中启动一个Jupyter笔记本,其中运行快速入门示例。
在您的机器上运行
-
创建一个名为
quickstart.py
的Python 3脚本import accera as acc # define placeholder inputs/output A = acc.Array(role=acc.Role.INPUT, shape=(512, 512)) B = acc.Array(role=acc.Role.INPUT, shape=(512, 512)) C = acc.Array(role=acc.Role.INPUT_OUTPUT, shape=(512, 512)) # implement the logic for matmul and relu matmul = acc.Nest(shape=(512, 512, 512)) i1, j1, k1 = matmul.get_indices() @matmul.iteration_logic def _(): C[i1, j1] += A[i1, k1] * B[k1, j1] relu = acc.Nest(shape=(512, 512)) i2, j2 = relu.get_indices() @relu.iteration_logic def _(): C[i2, j2] = acc.max(C[i2, j2], 0.0) package = acc.Package() # fuse the i and j indices of matmul and relu, add to the package schedule = acc.fuse(matmul.create_schedule(), relu.create_schedule(), partial=2) package.add(schedule, args=(A, B, C), base_name="matmul_relu_fusion_naive") # transform the schedule, add to the package i, j, f, k = schedule.get_indices() ii, jj = schedule.tile({ i: 16, j: 16 }) # loop tiling schedule.reorder(j, i, f, k, jj, ii) # loop reordering plan = schedule.create_plan() plan.unroll(ii) # loop unrolling package.add(plan, args=(A, B, C), base_name="matmul_relu_fusion_transformed") # build a dynamically-linked package (a .dll or .so) that exports both functions print(package.build(name="hello_accera", format=acc.Package.Format.HAT_DYNAMIC))
-
确保您的PATH中有一个编译器
- Windows:安装Microsoft Visual Studio并运行
vcvars64.bat
以设置命令提示符。 - Linux/macOS:安装gcc
- Windows:安装Microsoft Visual Studio并运行
-
安装Accera
pip install accera
-
生成实现matmul + ReLU两种版本的库
python quickstart.py
-
为了使用和比较库函数,在同一位置创建一个名为
benchmark.py
的文件import hatlib as hat import numpy as np # load the package _, functions = hat.load("hello_accera.hat") # call one of the functions with test inputs A_test = np.random.rand(512, 512).astype(np.float32) B_test = np.random.rand(512, 512).astype(np.float32) C_test = np.zeros((512, 512)).astype(np.float32) C_numpy = np.maximum(C_test + A_test @ B_test, 0.0) matmul_relu = functions["matmul_relu_fusion_transformed"] matmul_relu(A_test, B_test, C_test) # check correctness np.testing.assert_allclose(C_test, C_numpy, atol=1e-3) # benchmark all functions hat.run_benchmark("hello_accera.hat", batch_size=5, min_time_in_sec=5)
-
运行基准测试以获取执行时间结果
python benchmark.py
下一步
手册是Accera Python编程模型的最佳入门资源。
特别是,调度转换描述了如何仅用几行Python代码就实验不同的循环转换。
最后,.hat格式只是一个包含元数据的C头文件。了解更多关于HAT格式和基准测试的信息。
工作原理
简单来说,Accera将定义循环调度和算法的Python代码转换为MLIR中间表示(IR)。Accera的编译器然后通过一系列MLIR管道对该IR进行转换。结果是包含C头文件的二进制库。该库实现了在Python中定义的算法,并且与目标兼容。
要窥探Accera执行的IR变换阶段,请在quickstart.py
中将format=acc.Package.Format.HAT_DYNAMIC
替换为format=acc.Package.Format.MLIR_DYNAMIC
,重新运行脚本,并在_tmp
子文件夹中搜索中间的*.mlir
文件。我们计划在未来记录这些IR结构。
文档
在文档页面上了解Accera的概念和Python结构。
教程
有关分步示例,请参阅教程页面。我们正在努力添加更多互补示例和教程。
贡献
Accera是一个正在进行中的研究平台,它当然可以受益于您的贡献。我们非常欢迎您的反馈、建议和功能请求。不用说,我们很乐意回答您的问题。让我们合作!请提交Github问题或向我们发送拉取请求。请查阅Microsoft行为准则了解更多信息。
致谢
Accera是使用几个开源库构建的,包括:LLVM、pybind11、toml++、tomlkit、vcpkg、pyyaml和HAT。对于测试,我们使用了numpy和catch2。
许可
本项目采用MIT许可证发布。
项目详情
下载文件
下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。
源代码分发
构建分发
哈希值 for accera-1.2.29-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | af4990dd901b4c3da8b1e2a0de79138409a76328e45cd6690279946760960792 |
|
MD5 | 226f645782ea8c98d16b22c3883a0432 |
|
BLAKE2b-256 | 46f9a76c3a276a4e48c7c8a3661ee27a00eecc0fbaf79970f2fe65daff867df6 |
哈希值 for accera-1.2.29-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | da0a05a4cb3bef962c431d81a3d206b6812b593fe6761927aa33837c0b9cd6f6 |
|
MD5 | 21da8604da9670b06e400db5d845bf75 |
|
BLAKE2b-256 | da06a88115f6d8ba743ef7767198ea6f9974267cbb464d5baddc381114172c7c |
哈希值 for accera-1.2.29-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | d12b54fd53bd20e8a6e00d94621dd13fa155f52925aa04728c1ba62bd9def015 |
|
MD5 | 880679ccb0e2d9bdcb70a2ea299fd077 |
|
BLAKE2b-256 | 8601414fcf080b6bf11721215b148a9bf06fe68a637d1a7f1e84c489ed85623e |
哈希值 用于 accera-1.2.29-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 34b13afc58f90196e5221d38c292bc786a0c9129738a6262eb476eb2b9eb90bb |
|
MD5 | 6963a7fc547e262b33d34a09c6a47a6f |
|
BLAKE2b-256 | f7ca24487544f9477159fee02e4cc52b189af30e17887b74cba842c13eb5543b |