TornadoVM
TornadoVM 是 OpenJDK 和 GraalVM 的一个插件,允许程序员在异构硬件上自动运行 Java 程序。
TornadoVM 支持 OpenCL、PTX 和 SPIR-V 兼容设备,包括多核 CPU、专用 GPU(Intel、NVIDIA、AMD)、集成 GPU(Intel HD Graphics 和 ARM Mali)以及 FPGA(Intel 和 Xilinx)。
TornadoVM 有三个后端,分别生成 OpenCL C、NVIDIA CUDA PTX 汇编和 SPIR-V 二进制文件。
开发者可以选择安装和运行哪个后端。
网站: tornadovm.org
文档: https://tornadovm.readthedocs.io/en/latest/
想快速了解,请阅读以下 FAQ。
最新版本: TornadoVM 1.0.6 - 2024年6月27日 : 请参阅 CHANGELOG。
1. 安装
在 Linux 和 macOS 中,可以使用安装脚本自动安装 TornadoVM。例如:
$ ./bin/tornadovm-installer
usage: tornadovm-installer [-h] [--version] [--jdk JDK] [--backend BACKEND] [--listJDKs] [--javaHome JAVAHOME]
TornadoVM 安装工具。它将安装除 GPU/FPGA 驱动程序以外的所有软件依赖项。
可选参数:
-h, --help 显示帮助信息并退出
--version 打印 TornadoVM 的版本
--jdk JDK 选择支持的 JDK 之一。使用 --listJDKs 选项查看所有支持的版本。
--backend BACKEND 选择要安装的后端: { opencl, ptx, spirv }
--listJDKs 列出所有支持的 JDK 版本
--javaHome JAVAHOME 使用用户目录中的 JDK
注意 选择所需的后端:
opencl
: 启用 OpenCL 后端(需要 OpenCL 驱动程序)ptx
: 启用 PTX 后端(需要 NVIDIA CUDA 驱动程序)spirv
: 启用 SPIRV 后端(需要 Intel Level Zero 驱动程序)
安装示例:
# 使用 OpenJDK 21 安装 OpenCL 后端
$ ./bin/tornadovm-installer --jdk jdk21 --backend opencl
# 也可以组合不同的后端:
$ ./bin/tornadovm-installer --jdk jdk21 --backend opencl,spirv,ptx
或者,TornadoVM 可以通过源码手动安装或使用Docker安装。
如果你计划在 GPU 上使用 Docker 运行 TornadoVM,可以按照这些指南进行操作。
你还可以在 Amazon AWS 的 CPU、GPU 和 FPGA 上运行 TornadoVM,按照这里的说明进行操作。
2. 使用说明
TornadoVM 目前用于加速机器学习和深度学习应用、计算机视觉、物理仿真、金融应用、计算摄影和信号处理。
特色用例:
- kfusion-tornadovm: 使用 Tornado-API 加速的计算机视觉应用的 Java 应用程序,能够在独立和集成 GPU 上运行。
- Java Ray-Tracer: 使用 TornadoVM 加速的 Java 应用程序,用于实时光线追踪。
我们还有一组示例,包括 NBody、DFT、KMeans 计算和矩阵计算。
附加信息
3. 编程模型
TornadoVM 通过轻量级应用程序编程接口 (API) 向程序员公开任务级、数据级和管道级并行性。此外,TornadoVM 使用单源特性,其中加速代码和主机代码位于同一 Java 程序中。
TornadoVM 中的计算内核可以通过两种不同的方法(API)进行编程:
a) 循环并行 API
计算内核以顺序形式编写(任务为单线程执行编程)。为表达并行性,TornadoVM 提供了两个可用于循环和参数的注解:a) @Parallel
用于注解并行循环;b) @Reduce
用于注解用于化简的参数。
以下代码片段显示了使用 TornadoVM 和循环并行 API 加速矩阵乘法的完整示例:
public class Compute {
private static void mxmLoop(Matrix2DFloat A, Matrix2DFloat B, Matrix2DFloat C, final int size) {
for (@Parallel int i = 0; i < size; i++) {
for (@Parallel int j = 0; j < size; j++) {
float sum = 0.0f;
for (int k = 0; k < size; k++) {
sum += A.get(i, k) * B.get(k, j);
}
C.set(i, j, sum);
}
}
}
public void run(Matrix2DFloat A, Matrix2DFloat B, Matrix2DFloat C, final int size) {
// 创建包含多个任务的任务图。每个任务都指向一个可以在 GPU/FPGA 上加速的现有 Java 方法
TaskGraph taskGraph = new TaskGraph("myCompute")
.transferToDevice(DataTransferMode.FIRST_EXECUTION, A, B) // 数据仅在第一次执行时从主机传输到设备
.task("mxm", Compute::mxmLoop, A, B, C, size) // 每个任务都指向一个现有的 Java 方法
.transferToHost(DataTransferMode.EVERY_EXECUTION, C); // 每次执行后将数据从设备传输到主机
// 创建不可变的任务图
ImmutableTaskGraph immutableTaskGraph = taskGraph.snaphot();
// 从不可变任务图创建执行计划
try (TornadoExecutionPlan executionPlan = new TornadoExecutionPlan(immutableTaskGraph)) {
// 在默认设备上运行执行计划
TorandoExecutionResult executionResult = executionPlan.execute();
} catch (TornadoExecutionPlanException e) {
// 处理异常
// ...
}
}
}
b) 内核 API
另一种在 TornadoVM 中表达计算内核的方法是通过 内核 API。
为此,TornadoVM 提供了 KernelContext
数据结构,应用程序可以直接访问线程 ID、在本地内存中分配内存(在 NVIDIA 设备上为共享内存),并插入屏障。
此模型类似于在 SYCL、oneAPI、OpenCL 和 CUDA 中编程计算内核。因此,此 API 更适合于希望获得更多控制或希望将现有 CUDA/OpenCL 计算内核移植到 TornadoVM 的 GPU/FPGA 专家程序员。
以下代码片段显示了使用内核并行 API 进行矩阵乘法的示例:
public class Compute {
private static void mxmKernel(KernelContext context, Matrix2DFloat A, Matrix2DFloat B, Matrix2DFloat C, final int size)
```bibtex
@inproceedings{Clarkson:2018:EHH:3237009.3237016,
author = {Clarkson, James and Fumero, Juan and Papadimitriou, Michail and Zakkak, Foivos S. and Xekalaki, Maria and Kotselidis, Christos and Luj\'{a}n, Mikel},
title = {{利用Graal为Java程序开发的高性能异构硬件}},
booktitle = {第15届国际管理语言与运行时大会论文集},
series = {ManLang '18},
year = {2018},
isbn = {978-1-4503-6424-9},
location = {奥地利林茨},
pages = {4:1--4:13},
articleno = {4},
numpages = {13},
url = {http://doi.acm.org/10.1145/3237009.3237016},
doi = {10.1145/3237009.3237016},
acmid = {3237016},
publisher = {ACM},
address = {美国纽约},
keywords = {Java, graal, 异构硬件, openCL, 虚拟机},
}
精选的出版物可以在这里找到。
8. 致谢
本研究部分由英特尔公司资助。 此外,还得到了以下欧盟和英国研究与创新署(UKRI)项目的支持(按最近顺序排列):
- 欧盟地平线欧洲和英国研究与创新署 AERO 101092850。
- 欧盟地平线欧洲和英国研究与创新署 INCODE 101093069。
- 欧盟地平线欧洲和英国研究与创新署 ENCRYPT 101070670。
- 欧盟地平线欧洲和英国研究与创新署 TANGO 101070052。
- 欧盟地平线2020 ELEGANT 957286。
- 欧盟地平线2020 E2Data 780245。
- 欧盟地平线2020 ACTiCLOUD 732366。
此外,TornadoVM还得到了以下英国工程和物理科学研究委员会(EPSRC)项目的支持:
9. 贡献与合作
我们欢迎合作!请参阅贡献指南页面了解如何为项目做出贡献。
提出您的问题和建议:
此外,您可以在GitHub讨论页面上提出新建议。
或者,您也可以与我们共享Google文档。
合作:
对于学术和行业合作,请通过这里联系我们。
10. TornadoVM团队
11. 许可证
要使用TornadoVM,您可以将TornadoVM API链接到您的应用程序中,TornadoVM API使用Apache 2.0许可。
每个Java TornadoVM模块的许可证如下: