Saturday, February 14, 2026
GPU Programming pt 1.
Wednesday, December 31, 2025
Debugging JNI calls to the GPU
Monday, February 3, 2025
NVidia Drivers on Linux
sudo apt install linux-headers-$(uname -r)Monday, January 20, 2025
Notes on GPUs and Spark
Saturday, October 26, 2024
NVIDIA Rapids
...
at ai.rapids.cudf.NativeDepsLoader.loadDep(NativeDepsLoader.java:246)
yum -y install git
"cudaFree(0) to actually allocate the set device - no process exclusive required since we are relying on Spark to schedule it properly and not give it to multiple executors"
Saturday, October 5, 2024
Optimising GPU code
Changes in Java's memory
MemorySegment memorySegment = Arena.global().allocate(1024 * 1024 * 128, 8); System.out.println(memorySegment.address());
Sunday, September 22, 2024
GPU Notes
The organization of threads in CUDA terms:
- Thread: single unit of execution --- each thread has its own memory called registers
- Block: group of threads --- all threads in a block has access to a shared memory [Cuda Terminology].
- Grid: group of blocks --- all threads in a grid has access to [mutable] global memory and [immutable, global] constant memory.
[Penny Xu's blog]
Wednesday, January 3, 2024
GPU vs CPU vs AVX
Vector databases are all the rage. So, I looked at three different ways of multiplying vectors: CPU, GPU and Advanced Vector Extensions that leverages SIMD instructions if your hardware supports them. To access the GPU, I'm using the Tornado Java VM. For AVX, I'm using the JVM's jdk.incubator.vector module, available since JDK16.
![]() |
Wednesday, October 25, 2023
Java and the GPU
Java was always built to abstract away the hardware on which it runs but it's approach to GPU has been somewhat late to the game [Gary Frost, YouTube].
There are projects out there that promise to give Java access to the GPU. I looked at Aparapi but it appears to be moribud. So, I gravitated to TornadoVM which Frost describes as "state of the art".
The trouble is that TornadoVM runs everything in a Docker image that has all the shared objects built in. This is fine for a quick demo - this is the result of running on my Quadro T2000:
docker-tornadovm$ ./run_nvidia_openjdk.sh tornado -cp example/target/example-1.0-SNAPSHOT.jar example.MatrixMultiplication
Computing MxM of 512x512
CPU Execution: 1.17 GFlops, Total time = 230 ms
GPU Execution: 268.44 GFlops, Total Time = 1 ms
Speedup: 230x
To work this out, I opened a shell in the Docker image and saw that the TornadoVM build it uses was built from Git branch d3062accc. So, the first thing was to checkout that branch of TornadoVM and build it.
I built with:
mvn clean install -Pgraal-jdk-11-plus
using the graalvm-ee-java11-22.3.4 JDK.
Note that you'll need Graal as the TornadoVM code has dependencies on it. I built my own Graal JDK by following the instructions here but using a different branch as I couldn't find the download for the graal.version defined in the TornadoVM pom.xml. Note, you'll also need mx and a bootstrapping JDK that has the right compiler interface (JVMCI), in my case labsjdk-ce-21.0.1-jvmci-23.1-b19.
So far, so good. I ran the tornado script which is just a wrapper around a call to the java executable (don't forget to set your JAVA_HOME environment variable to point at the Graal JDK) but it complained it could not see a tornado.backend file.
Again, a sneaky look at the Docker container indicated that we have to tell it which driver to use. So, I created the file and told it tornado.backends=opencl-backend but then tornado complained it didn't have the OpenCL drivers. Oops.
You have to build the drivers you want seperately it seems. But if you try to build Tornado drivers without the native OpenCL dev library, you'll see:
TornadoVM/tornado-drivers/opencl-jni$ mvn clean install # yes, Maven cmake via cmake-maven-plugin
....
/usr/bin/ld: cannot find -lOpenCL
...
The Docker image saves you from having to install the OpenCL libraries on your machine. To get it working on bare metal, I played it safe and got an old Ubuntu box and installed them there. You'll need to install them with:
sudo apt install ocl-icd-opencl-dev
However, running tornado in the subsequent dist folder still pukes but with something like:
Now, finally, you can run on the bare metal:
Note, you'll need to also run it with the Graal JVM. Set both the PATH and JAVA_HOME environment variables to point to it.
Where now?
This is a nice introduction to running Java on the GPU but it's just the start. There are many caveats. Example: what if your Java code throws an Exception? GPUs have no equivalent of exceptions so what happens then? More to come.

