
Tornadovm은 OpenJDK 및 GraalVM의 플러그인으로 프로그래머가 이종 하드웨어에서 Java 프로그램을 자동으로 실행할 수 있습니다. Tornadovm은 멀티 코어 CPU, 전용 GPU (Intel, NVIDIA, AMD), 통합 GPU (Intel HD Graphics 및 Arm Mali) 및 FPGA (Intel 및 Xilinx)를 포함한 OpenCL, PTX 및 SPIR-V 호환 장치를 대상으로합니다.
Tornadovm에는 OpenCl C, Nvidia Cuda PTX 어셈블리 및 SPIR-V 바이너리를 생성하는 3 개의 백엔드가 있습니다. 개발자는 설치 및 실행할 백엔드를 선택할 수 있습니다.
웹 사이트 : Tornadovm.org
문서 : https://tornadovm.readthedocs.io/en/latest/
빠른 소개는 다음 FAQ를 읽으십시오.
최신 릴리스 : Tornadovm 1.0.8-30/09/2024 : Changelog 참조.
Linux 및 MacOS에서 Tornadovm은 설치 스크립트와 함께 자동으로 설치할 수 있습니다. 예를 들어:
$ ./bin/tornadovm-installer
usage: tornadovm-installer [-h] [--version] [--jdk JDK] [--backend BACKEND] [--listJDKs] [--javaHome JAVAHOME]
TornadoVM Installer Tool. It will install all software dependencies except the GPU/FPGA drivers
optional arguments:
-h, --help show this help message and exit
--version Print version of TornadoVM
--jdk JDK Select one of the supported JDKs. Use --listJDKs option to see all supported ones.
--backend BACKEND Select the backend to install: { opencl, ptx, spirv }
--listJDKs List all JDK supported versions
--javaHome JAVAHOME Use a JDK from a user directory참고 원하는 백엔드를 선택하십시오.
opencl : OpenCL 백엔드 활성화 (OpenCL 드라이버 필요)ptx : PTX 백엔드 활성화 (NVIDIA CUDA 드라이버 필요)spirv : SPIRV 백엔드 활성화 (Intel Level Zero 드라이버 필요)설치의 예 :
# Install the OpenCL backend with OpenJDK 21
$ ./bin/tornadovm-installer --jdk jdk21 --backend opencl
# It is also possible to combine different backends:
$ ./bin/tornadovm-installer --jdk jdk21 --backend opencl,spirv,ptx또는 Tornadovm은 소스에서 또는 Docker를 사용하여 수동으로 설치할 수 있습니다.
GPU에서 Tornadovm과 함께 Docker를 사용할 계획이라면 다음 지침을 따라갈 수도 있습니다.
Amazon AWS CPU, GPU 및 FPGA에서 Tornadovm을 실행할 수도 있습니다.
Tornadovm은 현재 기계 학습 및 딥 러닝 애플리케이션, 컴퓨터 비전, 물리 시뮬레이션, 금융 응용 프로그램, 계산 사진 및 신호 처리를 가속화하는 데 사용되고 있습니다.
주요 사용 사례 :
또한 NBody, DFT, Kmeans 계산 및 행렬 계산을 포함한 예제 세트도 있습니다.
추가 정보
Tornadovm은 Light Application Programming Interface (API)를 통해 프로그래머 작업 수준, 데이터 레벨 및 파이프 라인 수준 병렬 처리에 노출됩니다. 또한 Tornadovm은 단일 소스 속성을 사용하여 코드가 가속화되고 호스트 코드는 동일한 Java 프로그램에서 사용됩니다.
Tornadovm의 Compute-Kernel은 두 가지 다른 접근 방식 (API)을 사용하여 프로그래밍 할 수 있습니다.
컴퓨팅 커널은 순차적 형식으로 작성됩니다 (단일 스레드 실행을 위해 프로그래밍 된 작업). 병렬 처리를 표현하기 위해 Tornadovm @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 ) {
// Create a task-graph with multiple tasks. Each task points to an exising Java method
// that can be accelerated on a GPU/FPGA
TaskGraph taskGraph = new TaskGraph ( "myCompute" )
. transferToDevice ( DataTransferMode . FIRST_EXECUTION , A , B ) // Transfer data from host to device only in the first execution
. task ( "mxm" , Compute :: mxmLoop , A , B , C , size ) // Each task points to an existing Java method
. transferToHost ( DataTransferMode . EVERY_EXECUTION , C ); // Transfer data from device to host
// Create an immutable task-graph
ImmutableTaskGraph immutableTaskGraph = taskGraph . snaphot ();
// Create an execution plan from an immutable task-graph
try ( TornadoExecutionPlan executionPlan = new TornadoExecutionPlan ( immutableTaskGraph )) {
// Run the execution plan on the default device
TorandoExecutionResult executionResult = executionPlan . execute ();
} catch ( TornadoExecutionPlanException e ) {
// handle exception
// ...
}
}
} Tornadovm에서 Compute-Kernel을 표현하는 또 다른 방법은 Kernel API를 통한 것입니다. 이를 위해 Tornadovm은 응용 프로그램이 스레드 -ID에 직접 액세스하고 로컬 메모리에 메모리 (NVIDIA 장치의 공유 메모리)에 메모리를 할당하고 장벽을 삽입 할 수있는 KernelContext 데이터 구조를 노출시킵니다. 이 모델은 Sycl, Oneapi, OpenCl 및 Cuda의 Compute Kernel을 프로그래밍하는 것과 유사합니다. 따라서이 API는 기존 CUDA/OpenCL Compute 커널을 Tornadovm으로 포트하려는 GPU/FPGA 전문가 프로그래머에게 더 적합합니다.
다음 코드-스핀펫은 커널-팔렐 API를 사용한 행렬 곱셈 예를 보여줍니다.
public class Compute {
private static void mxmKernel ( KernelContext context , Matrix2DFloat A , Matrix2DFloat B , Matrix2DFloat C , final int size ) {
int idx = context . globalIdx
int jdx = context . globalIdy ;
float sum = 0 ;
for ( int k = 0 ; k < size ; k ++) {
sum += A . get ( idx , k ) * B . get ( k , jdx );
}
C . set ( idx , jdx , sum );
}
public void run ( Matrix2DFloat A , Matrix2DFloat B , Matrix2DFloat C , final int size ) {
// When using the kernel-parallel API, we need to create a Grid and a Worker
WorkerGrid workerGrid = new WorkerGrid2D ( size , size ); // Create a 2D Worker
GridScheduler gridScheduler = new GridScheduler ( "myCompute.mxm" , workerGrid ); // Attach the worker to the Grid
KernelContext context = new KernelContext (); // Create a context
workerGrid . setLocalWork ( 16 , 16 , 1 ); // Set the local-group size
TaskGraph taskGraph = new TaskGraph ( "myCompute" )
. transferToDevice ( DataTransferMode . FIRST_EXECUTION , A , B ) // Transfer data from host to device only in the first execution
. task ( "mxm" , Compute :: mxmKernel , context , A , B , C , size ) // Each task points to an existing Java method
. transferToHost ( DataTransferMode . EVERY_EXECUTION , C ); // Transfer data from device to host
// Create an immutable task-graph
ImmutableTaskGraph immutableTaskGraph = taskGraph . snapshot ();
// Create an execution plan from an immutable task-graph
try ( TornadoExecutionPlan executionPlan = new TornadoExecutionPlan ( immutableTaskGraph )) {
// Run the execution plan on the default device
// Execute the execution plan
TorandoExecutionResult executionResult = executionPlan
. withGridScheduler ( gridScheduler )
. execute ();
} catch ( TornadoExecutionPlanException e ) {
// handle exception
// ...
}
}
}또한, 평행을 표현하는 두 가지 모드 (커널 및 루프 병렬화)를 동일한 작업 그래프 오브젝트에서 결합 할 수 있습니다.
동적 재구성은 Tornadovm이 장치 간의 실시간 작업 마이그레이션을 수행하는 능력입니다. 즉, Tornadovm은 성능을 높이기 위해 코드를 실행할 위치를 결정합니다 (가능하면). 다시 말해, Tornadovm은 특정 장치가 더 나은 성능을 산출 할 수 있음을 감지 할 수 있다면 장치를 전환합니다 (다른 장치에 비해).
태스크 마이그레이션을 사용하면 Tornadovm의 접근 방식은 C2 또는 Graal-Jit에 의해 컴파일 된 코드를 사용하여 응용 프로그램을 더 빨리 검토 할 수있는 경우 장치 만 전환하는 것입니다. 그렇지 않으면 CPU에 유지됩니다. 따라서 Tornadovm은 C2 및 Graal JIT 컴파일러를 보완하는 것으로 볼 수 있습니다. 모든 워크로드를 효율적으로 가장 잘 실행할 수있는 단일 하드웨어가 없기 때문입니다. GPU는 SIMD 애플리케이션을 활용하는 데 매우 능숙하며 FPGA는 파이프 라인 애플리케이션을 이용하는 데 매우 능숙합니다. 응용 프로그램이 해당 모델을 따르면 Tornadovm은 이질적인 하드웨어를 선택할 것입니다. 그렇지 않으면 기본 컴파일러 (C2 또는 Graal)를 사용하여 CPU에 유지됩니다.
동적 재구성을 사용하려면 Tornadovm 정책을 사용하여 실행할 수 있습니다. 예를 들어:
// TornadoVM will execute the code in the best accelerator.
executionPlan . withDynamicReconfiguration ( Policy . PERFORMANCE , DRMode . PARALLEL )
. execute ();이 기능을 활성화하는 방법에 대한 자세한 내용과 지침은 여기에서 확인할 수 있습니다.
Tornadovm을 사용하려면 두 가지 구성 요소가 필요합니다.
a) API가있는 Tornadovm jar 파일. API는 ClassPath 예외가있는 GPLV2로 라이센스가 부여됩니다. b) Tornadovm의 핵심 라이브러리와 드라이버 코드의 .so 라이브러리 (OpenCL, PTX 및/또는 Spirv/Level Zero 용 파일).
maven pom.xml 파일에서 다음의 종속성을 설정하여 Tornadovm API를 가져올 수 있습니다.
< repositories >
< repository >
< id >universityOfManchester-graal</ id >
< url >https://raw.githubusercontent.com/beehive-lab/tornado/maven-tornadovm</ url >
</ repository >
</ repositories >
< dependencies >
< dependency >
< groupId >tornado</ groupId >
< artifactId >tornado-api</ artifactId >
< version >1.0.8</ version >
</ dependency >
< dependency >
< groupId >tornado</ groupId >
< artifactId >tornado-matrices</ artifactId >
< version >1.0.8</ version >
</ dependency >
</ dependencies >Tornadovm을 실행하려면 Graalvm/OpenJDK 용 Tornadovm 확장자를 설치하거나 Docker 이미지로 실행해야합니다.
여기서는 Tornadovm을 설명하는 비디오, 프레젠테이션, 기술 아티클 및 인공물을 찾을 수 있으며 사용 방법을 찾을 수 있습니다.
Tornadovm> = 0.2 (동적 재구성, 초기 FPGA 지원 및 CPU/GPU 감소 포함)를 사용하는 경우 다음 인용을 사용하십시오.
@inproceedings { Fumero:DARHH:VEE:2019 ,
author = { Fumero, Juan and Papadimitriou, Michail and Zakkak, Foivos S. and Xekalaki, Maria and Clarkson, James and Kotselidis, Christos } ,
title = { {Dynamic Application Reconfiguration on Heterogeneous Hardware.} } ,
booktitle = { Proceedings of the 15th ACM SIGPLAN/SIGOPS International Conference on Virtual Execution Environments } ,
series = { VEE '19 } ,
year = { 2019 } ,
doi = { 10.1145/3313808.3313819 } ,
publisher = { Association for Computing Machinery }
}토네이도 0.1 (초기 릴리스)을 사용하는 경우 작업에서 다음 인용을 사용하십시오.
@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 = { {Exploiting High-performance Heterogeneous Hardware for Java Programs Using Graal} } ,
booktitle = { Proceedings of the 15th International Conference on Managed Languages & Runtimes } ,
series = { ManLang '18 } ,
year = { 2018 } ,
isbn = { 978-1-4503-6424-9 } ,
location = { Linz, Austria } ,
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 = { New York, NY, USA } ,
keywords = { Java, graal, heterogeneous hardware, openCL, virtual machine } ,
}선택된 간행물은 여기에서 찾을 수 있습니다.
이 작업은 부분적으로 인텔 코퍼레이션이 자금을 지원합니다. 또한 다음 EU & UKRI Grants (가장 최근의 첫 번째)에 의해 지원되었습니다.
또한 Tornadovm은 다음과 같은 EPSRC 보조금으로 지원되었습니다.
우리는 협업을 환영합니다! 기여 페이지에서 프로젝트에 기여하는 방법을 참조하십시오.
또한 Github 토론 페이지에서 새로운 제안을 열 수 있습니다.
또는 Google 문서를 우리와 공유 할 수 있습니다.
학업 및 산업 협력은 여기에서 문의하십시오.
팀을 만나려면 웹 사이트를 방문하십시오.
Tornadovm을 사용하려면 Tornadovm API를 Apache 2의 응용 프로그램에 연결할 수 있습니다.
각 Java Tornadovm 모듈은 다음과 같이 라이센스가 부여됩니다.
| 기준 치수 | 특허 |
|---|---|
| 토네이도-아피 | |
| 토네이도 런타임 | |
| 토네이도-조립 | |
| 토네이도 드라이버 | |
| 토네이도 드라이버-오펜자 헤더 | |
| 토네이도 스크립트 | |
| 토네이도 공석 | |
| 토네이도-유사성 | |
| 토네이도 벤치 마크 | |
| 토네이도-예입니다 | |
| 토네이도 장내 | |