I am trying to set up JCuda and execute a Sample addition kernel. When I try to execute JCudaVectorAdd after compiling JCudaVectorAdd.java, I am getting the following error:
Exception in thread "main" java.lang.NoClassDefFoundError: jcuda/driver/JCudaDriver
at JCudaVectorAdd.main(JCudaVectorAdd.java:38)
Caused by: java.lang.ClassNotFoundException: jcuda.driver.JCudaDriver
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more
I have created a bash file with the steps I have performed to get to where I am:
#!/bin/bash
# This system has multiple Cuda instances, so we need to load the correct one
module load cuda-9.2
# Try to remove any jcuda zip files that may have been created previously
rm $HOME/jcuda.zip
# Get jcuda zip file from online, storing into $HOME directory
wget http://www.jcuda.org/downloads/JCuda-All-0.9.2.zip -O $HOME/jcuda.zip
# Remove the 0.9.2 directory in case it exists to get ready for a clean install
rm -rf $HOME/jcuda/JCuda-All-0.9.2
# Unzip the file and store within jcuda directory. NOTE: The version number will be maintained as jcuda/JCuda-ALL-0.9.2.zip, so multiple versions of jcuda can be installed using this script
unzip $HOME/jcuda.zip -d $HOME/jcuda
# Remove the zipped file now that it is no longer needed
rm $HOME/jcuda.zip
# Move into the newly create jcuda directory
cd $HOME/jcuda/JCuda-All-0.9.2/
# Get the example Main program for Vector addition from Jcuda site
wget http://www.jcuda.org/samples/JCudaVectorAdd.java
# Create a sample kernel
echo 'extern "C"' > JCudaVectorAddKernel.cu
echo '__global__ void add(int n, float *a, float *b, float *sum)' >> JCudaVectorAddKernel.cu
echo '{' >> JCudaVectorAddKernel.cu
echo ' int i = blockIdx.x * blockDim.x + threadIdx.x;' >> JCudaVectorAddKernel.cu
echo ' if (i<n)' >> JCudaVectorAddKernel.cu
echo ' {' >> JCudaVectorAddKernel.cu
echo ' sum[i] = a[i] + b[i];' >> JCudaVectorAddKernel.cu
echo ' }' >> JCudaVectorAddKernel.cu
echo '}' >> JCudaVectorAddKernel.cu
# Create a .ptx file from the cuda kernel to be consumed by the Main java program later
# The sample Main program also performs this action, but we have it here as well
nvcc -ptx JCudaVectorAddKernel.cu -o JCudaVectorAddKernel.ptx
# Try to generate a class file from the example Main .java file
javac -cp ".:jcuda-0.9.2.jar:jcuda-natives-0.9.2-linux-x86_64.jar" JCudaVectorAdd.java
# Run the compiled executable
java JCudaVectorAdd
It appears that I am missing a step somewhere, although I am not familiar enough with java or cuda/jcuda to identify what I am missing. Can anyone point me in the direction of how to resolve this issue, whether it be additional steps are modifying the steps I have performed?
EDIT: It appears that I still need to reference the other .jar files in my execution (like they do in http://www.jcuda.org/tutorial/TutorialIndex.html basic test), so my last command may have been wrong. Changing it to the following has shown slightly different results:
java JCudaVectorAdd -> java -cp ".:jcuda-0.9.2.jar:jcuda-natives-0.9.2-linux-x86_64.jar" JCudaVectorAdd
Exception in thread "main" java.lang.UnsatisfiedLinkError: Error while loading native library "JCudaDriver-0.9.2-linux-x86_64"
Operating system name: Linux
Architecture : amd64
Architecture bit size: 64
---(start of nested stack traces)---
Stack trace from the attempt to load the library as a file:
java.lang.UnsatisfiedLinkError: no JCudaDriver-0.9.2-linux-x86_64 in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
at jcuda.LibUtils.loadLibrary(LibUtils.java:143)
at jcuda.driver.JCudaDriver.<clinit>(JCudaDriver.java:296)
at JCudaVectorAdd.main(JCudaVectorAdd.java:38)
Stack trace from the attempt to load the library as a resource:
java.lang.UnsatisfiedLinkError: /tmp/libJCudaDriver-0.9.2-linux-x86_64.so: libcuda.so.1: cannot open shared object file: No such file or directory
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1824)
at java.lang.Runtime.load0(Runtime.java:809)
at java.lang.System.load(System.java:1086)
at jcuda.LibUtils.loadLibraryResource(LibUtils.java:260)
at jcuda.LibUtils.loadLibrary(LibUtils.java:158)
at jcuda.driver.JCudaDriver.<clinit>(JCudaDriver.java:296)
at JCudaVectorAdd.main(JCudaVectorAdd.java:38)
---(end of nested stack traces)---
at jcuda.LibUtils.loadLibrary(LibUtils.java:193)
at jcuda.driver.JCudaDriver.<clinit>(JCudaDriver.java:296)
at JCudaVectorAdd.main(JCudaVectorAdd.java:38)
It seems you need to tell the JRE where to find the corresponding OS library to run cuda. If you look at the output, it's stating it cannot find libcuda.so.1
.
Find where in your filesystem these libraries are, and set your java.library.path
property to point there.
java -Djava.library.path=/path/to/cudalibdir/ <rest of commandline>
If your system does not have the library, you might need to install it or compile it locally.
Disclaimer: I do not have experience with cuda specifically but have worked with other jars that require OS level libraries to function.