The TornadoVM CUDA backend is the deepest integration with the NVIDIA hardware and software ecosystem available from the JVM. It compiles Java bytecode through the Graal IR to CUDA PTX, hands the PTX to NVRTC for JIT compilation to a device-specific cubin, and then dispatches the resulting native kernel on a CUDA stream — all automatically, with no CUDA C to write. Beyond basic JIT code generation, the CUDA backend also exposes the full NVIDIA library ecosystem — cuBLAS, cuBLASLt, cuFFT, cuDNN, cuSPARSE, and CUTLASS — as first-classDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/Deepak-Sangle/TornadoVM/llms.txt
Use this file to discover all available pages before exploring further.
TaskGraph library tasks that share device buffers and a CUDA stream with your generated kernels, plus mma.sync Tensor Core intrinsics accessible directly from KernelContext.
Prerequisites
Before installing the CUDA backend, ensure the following are available on your system:NVIDIA GPU
Any CUDA-capable NVIDIA GPU. Tensor Core
mma.sync intrinsics (FP16, BF16, INT8, FP8) and FP16 GemmEx via cuBLASLt require Ampere (sm_80) or newer. FP8 MMA requires Ada/Hopper (sm_89+).CUDA Toolkit
Install the CUDA Toolkit from developer.nvidia.com/cuda-downloads. The toolkit must include
nvrtc (NVIDIA Runtime Compilation). /usr/local/cuda or $CUDA_PATH must be set.JDK 21 or JDK 25
JAVA_HOME must point to a JDK 21 or JDK 25 installation (OpenJDK or GraalVM). Graal-based JDK 21 enables additional optimisations.GCC/G++ ≥ 13
Required to build the native JNI bridges (
cuda-jni, cublas-jni, cufft-jni, cudnn-jni, cusparse-jni, cutlass-jni).For systems with multiple CUDA toolkits installed, TornadoVM resolves the toolkit from
/usr/local/cuda first, then falls back to the $CUDA_PATH environment variable. Set CUDA_PATH explicitly if your toolkit lives elsewhere.Installation
- SDKMAN!
- Installer Script
- Make
The fastest way to get started — downloads a prebuilt SDK that includes the CUDA backend, NVRTC JNI bridges, and all library-task JNI modules:After installation, activate the SDK and verify your device:
Verifying the Backend
After installation, confirm that the CUDA driver is visible and your GPU is enumerated:--printKernel:
JIT Compilation Pipeline
The CUDA backend follows a four-stage compilation chain at runtime:Java Bytecode → Graal IR
The method annotated as a TornadoVM task is parsed by GraalVM’s bytecode parser. Loops with
@Parallel annotations and KernelContext accesses are identified and lifted into GPU-parallel IR nodes.Graal IR → CUDA PTX
The CUDA-specific lowering pass (
CUDABackend, CUDALIRStmt) serialises the IR to CUDA PTX assembly — a portable virtual-ISA for NVIDIA GPUs. MMA nodes (CUDAMMAComputeNode, CUDAMMALoadANode, CUDAMMAStoreNode) are lowered to mma.sync PTX instructions.PTX → cubin via NVRTC
CUDAJIT hands the PTX string to the NVRTC runtime (nvrtcCompileProgram), which performs JIT compilation to a device-specific cubin binary specialised for the active GPU’s compute capability.CUDA-Specific Features
Library Tasks: cuBLAS, cuFFT, cuDNN, cuSPARSE, CUTLASS
Library tasks let you call tuned NVIDIA libraries from the sameTaskGraph as your JIT-compiled Java kernels. All library calls share TornadoVM-managed device buffers on a single CUDA stream — no extra copies, no host synchronisation required between a kernel and a library call.
Available library task providers
Available library task providers
| Provider | Operations |
|---|---|
| cuBLAS | SGEMV, SGEMM (single-precision) |
| cuBLASLt | TF32 and FP16 GemmEx on Tensor Cores; fused BIAS / GELU_BIAS epilogues; plan caching |
| cuFFT | C2C, R2C/C2R, Z2Z transforms (1D and 2D); FFT-filter pipelines with JIT kernels |
| cuDNN | Deep-learning primitives via the cuDNN graph API; fused scaled-dot-product (flash) attention via cudnn-frontend |
| cuSPARSE | Sparse-matrix operations |
| CUTLASS | Templated GEMM kernels with Tensor Core support |
TornadoLibraryProvider and are discovered via Java ServiceLoader — no core runtime changes required.Tensor Core MMA Intrinsics
KernelContext exposes mma.sync Tensor Core instructions directly from Java. FP16 (m16n8k16 → FP32) and INT8 (m16n8k32 → INT32) shapes are supported. Matrix tiles are staged in shared memory as int-packed fp16 pairs, and the warp-collective MMA call produces a per-lane accumulator fragment:
Tensor Core MMA intrinsics require an Ampere (sm_80) or newer GPU. The Graal lowering phase emits
CUDAMMAComputeNode, CUDAMMALoadANode, and CUDAMMAStoreNode IR nodes, which are serialised to mma.sync.aligned PTX instructions by CUDATensorCoreSupportPhase. Matrix tiles must be staged in int-packed shared-memory arrays before calling mmaLoadA/mmaLoadB.CUDA Graphs
CUDA Graphs allow the entire pipeline — JIT kernels, library tasks, and memory transfers — to be recorded once and replayed with a singlecuGraphLaunch, eliminating per-iteration kernel launch overhead:
Environment Variables and Build Flags
| Variable | Default | Purpose |
|---|---|---|
CUDA_PATH | /usr/local/cuda | Path to the CUDA Toolkit installation |
TORNADO_DEVICE_MEMORY | System default | Override device memory limit, e.g. -Dtornado.device.memory=8GB |
MACOSX_DEPLOYMENT_TARGET | Host macOS version | Not used for CUDA (Linux/Windows only) |