TornadoVM’s Hybrid API lets a singleDocumentation 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 mix JIT-compiled Java kernels with calls into vendor-optimized native GPU libraries—cuBLAS, cuBLASLt, cuFFT, cuDNN, cuSPARSE, and CUTLASS—without any manual memory management or host synchronization between them. A library task is a SchedulableTask node that never passes through the JIT compiler. Instead, at execution time the TornadoVM interpreter resolves every reference argument to the raw device pointer of the associated TornadoVM buffer (past the array header), then dispatches the call through a registered TornadoLibraryProvider. Scalars are passed as boxed Java objects. Because library tasks share the same TornadoVM-managed buffers as surrounding JIT tasks, data produced on the GPU by a Java kernel is consumed by cuBLAS with no copies, and vice versa.
TaskGraph.libraryTask
The entry point for library tasks is the libraryTask method on TaskGraph, a sibling of the standard .task(...) method. It takes a string task identifier, a factory method reference that returns a LibraryTaskDescriptor, and the arguments to forward to that factory.
cuBLAS is column-major. For row-major
FloatArray inputs, either pass the transpose operation (CUBLAS_OP_T) or swap the A/B operands as shown above so that C_cm = B_cm · A_cm computes the row-major C = A · B.LibraryTaskDescriptor
LibraryTaskDescriptor is a simple builder that factory methods (e.g., CuBlas::cublasSgemm) construct and return to the TornadoVM runtime. You interact with it directly only when writing a custom provider.
Package: uk.ac.manchester.tornado.api.common
Sets the provider ID string (e.g.
"nvidia/cublas"). The runtime matches this string against the registered TornadoLibraryProvider.libraryName() values.Names the specific entry point within the library (e.g.
"cublasSgemm"). Passed verbatim to TornadoLibraryProvider.dispatch(String, LibraryInvocation).Sets the argument array. Reference arguments (off-heap arrays) are resolved to device pointers by the interpreter; scalars are passed as boxed values.
Declares the data-flow access mode for each argument using
Access.READ_ONLY, Access.WRITE_ONLY, or Access.READ_WRITE. The runtime uses these to schedule transfers and determine dependencies.Attaches library-specific tuning options (algorithm selection, workspace size, math mode, etc.) as an opaque object. Ignored by the runtime; interpreted by the matching provider at dispatch time.
Getters
Returns the provider ID.
Returns the function entry-point name.
Returns the argument array.
Returns the per-argument access declarations.
Returns the tuning object, or null.
Access enum
uk.ac.manchester.tornado.api.common.Access controls how the runtime transfers data for each buffer argument.
| Value | Bit mask | Meaning |
|---|---|---|
NONE | 0b00 | No data movement (internal use). |
READ_ONLY | 0b01 | Buffer is only read by the task; transferred to device but never back. |
WRITE_ONLY | 0b10 | Buffer is only written; allocated on device, transferred to host after the task. |
READ_WRITE | 0b11 | Buffer is both read and written; transferred both directions. |
When
beta != 0 in cuBLAS/CUTLASS GEMM calls, the output matrix is read before being updated. In those cases the runtime automatically marks the output as READ_WRITE and requires it to be included in transferToDevice.Provider catalog
TornadoVM ships six built-in library providers for NVIDIA GPUs.- cuBLAS
- cuBLASLt
- cuFFT
- cuDNN
- CUTLASS
- cuSPARSE
Provider ID:
nvidia/cublas · Module: tornado-cublasDense linear algebra in FP32 and FP16, using NVIDIA BLAS. All factories are in uk.ac.manchester.tornado.cublas.CuBlas.| Factory | Operation |
|---|---|
cublasSgemv(op, m, n, α, A, lda, x, incx, β, y, incy) | y = α·op(A)·x + β·y |
cublasSgemm(opA, opB, m, n, k, α, A, lda, B, ldb, β, C, ldc) | C = α·op(A)·op(B) + β·C |
cublasSgemmTF32(...) | SGEMM using TF32 tensor cores |
cublasGemmExFP16(...) | FP16 inputs, tensor-core GEMM |
cublasSgemmStridedBatched(...) | Batched SGEMM |
TornadoLibraryProvider SPI
The TornadoLibraryProvider interface in uk.ac.manchester.tornado.runtime.library.spi is the extension point for adding new native library bindings. Providers are discovered via java.util.ServiceLoader.
Returns the unique provider identifier (e.g.
"nvidia/cublas"). Matched against LibraryTaskDescriptor.getLibraryName().Returns
true when the provider can execute on the given device. CUDA-only providers test instanceof TornadoNativeStreamSupport.Creates a native execution context for the given device and execution plan (e.g. creates a cuBLAS handle and binds it to the device’s CUDA stream). Called once per
(library, device, plan) tuple.Optional hook invoked before CUDA graph capture starts. Providers that allocate per-shape plans or workspaces (cuFFT, cuDNN, CUTLASS, cuSPARSE) create them here so
dispatch is capture-safe. Must be idempotent—typically a plan-cache lookup.Executes the named function. Arguments are accessed via
invocation.getArg(i) (scalars) and invocation.getDevicePointer(i) (device pointer for reference args).Releases all native resources (plans, workspace, library handle) held by the context.
LibraryInvocation
A single dispatch call, with all arguments already resolved by the TornadoVM interpreter.
Total number of arguments.
The Java argument at
index—a boxed scalar or the host-side array object for reference arguments.Raw device pointer for a reference argument at
index, pointing past the TornadoVM array header to the first data element.Returns
true if argument index is a buffer reference (has a device pointer) rather than a scalar.The per-(device, plan) context created by
createContext.Library-specific tuning object from
LibraryTaskDescriptor.withTuning(...), or null.Returns
true when the call is being recorded into a CUDA graph. Device allocations and host synchronization are not capture-safe; reject them here and do the sizing work in prepare() instead.Complete cuBLAS SGEMM example
The following self-contained example adds a cuBLAS SGEMM library task to aTaskGraph between two JIT preprocessing/postprocessing steps, then executes it with a TornadoExecutionPlan.
Error handling
When a library task runs on a backend that has no matching provider (OpenCL, SPIR-V, Metal), the TornadoVM runtime reports the task asUNSUPPORTED in profiling output and silently skips the dispatch. Production code should either:
- Confirm the CUDA backend is active via
TornadoRuntimeProvider.getTornadoRuntime().getBackendType(0), or - Guard the
libraryTaskcall path withTornadoVMBackendType.CUDAchecks and provide a CPU fallback using the standard.task(...)API.