I am unfortunately adding up to the long list of the UnsatisfiedLinkError… I spent a long time trying many of the suggestions that have been posted so far and I still could not get the JCudaRuntimeTest minimalistic java program to run, always getting the same message error when launching it:
Error while loading native library with base name “JCudaRuntime”
Operating system name: Windows XP
Architecture : amd64
Architecture bit size: 64
Exception in thread “main” java.lang.UnsatisfiedLinkError: Could not load native library
at jcuda.LibUtils.loadLibrary(LibUtils.java:79)
at jcuda.runtime.JCuda.assertInit(JCuda.java:225)
at jcuda.runtime.JCuda.cudaMalloc(JCuda.java:1775)
at JCudaRuntimeTest.main(JCudaRuntimeTest.java:8)
I am using the amd64 version 4.1 of the JCuda libraries, my NVIDIA computing toolkit match this version (cudart64_41_21 matches the dll dependence of JcudaRuntime.dll). My JDK is 1.7.0_02-b13 - windows 64 bit version. My %path% environment variable is pointing to the folder where the JCuda libraries are stored as well as to C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.1\bin. I tried to copy all the JCuda dlls (as well as all the dlls I could find in the NVidia SDK) to the calling java program with no success. It is difficult to guess what is going wrong in the dll loading… anybody managed to use JCuda with this same configuration? Any hint?
You obviously ruled out most of the “usual” reasons for this error. According to your description, I can’t see (or even imagine) a possible reason for the error. Two rather helpless guesses:
Could you run the examples from the SDK?
Are you sure that there is no other, older CUDA DLL installed (maybe from an old toolkit) ?
I’ll try to run another test on a Win64 machine tomorrow, with the JDK 1.7. I think until now I tested it only with 1.6, but that should not make a difference, but it’s in fact the only difference that I can see between your configuration and the one where I’m actually compiling and testing the Win64 libs… -_-
Could you run the examples from the SDK? --> yes, all the examples I tried compiled and runned (except the DirectX ones because I do not have the DirectX SDK)
Are you sure that there is no other, older CUDA DLL installed (maybe from an old toolkit)? --> 100% sure, it is the first CUDA SDK I am installing on this machine.
I’ll try to run another test on a Win64 machine tomorrow, with the JDK 1.7. I think until now I tested it only with 1.6 --> I use 1.7 because I tried to upgrade it to solve the issue (from previous comments). I had 1.6 before and the result was the same.
It’s in fact the only difference that I can see between your configuration and the one where I’m actually compiling and testing the Win64 libs… -_- --> bad news for me, JCuda looks like a jewel to me since I want to do CUDA dev with simple binding to ImageJ.
If I cannot get it to work I could just try to setup a simple JNI bridged C program that calls a standard Nvidia CUDA file compiled with MSVC++ 2008 and Nvidia rules. Is there much more to JCuda? Is there a way to have a more verbose tracing of the dll loading failure?
I just tested it again, with the current files from the website, on Windows 7 (64bit), and here it works. But I noticed that the error message that you posted said that you are using Windows XP. I can not test it on an WinXP 64bit machine at the moment. I think that the DLLs should work on all Win64 versions, but since this is a difference that at least might have an influence, I can not be 100% sure…
Maybe more importantly:
Did you use the „ImageJ Quick Start package“ from the website? Note that this package (as mentioned on the website) is slightly out-dated and unversioned for the sake of simplicity (I’ll update it as soon as possible). In any case, you should also use the JARs from the latest download package. This also refers to your question
Is there a way to have a more verbose tracing of the dll loading failure?
The latest version should print a little bit more info. For example, I just removed one DLL and thus provoked an error, and it should print something like
Error while loading native library "JCudaRuntime-windows-x86_64" with base name "JCudaRuntime"
Operating system name: Windows 7
Architecture : amd64
Architecture bit size: 64
Stack trace from the attempt to load the library as a resource:
java.lang.NullPointerException: No resource found with name '/lib/JCudaRuntime-windows-x86_64.dll'
at jcuda.LibUtils.loadLibraryResource(LibUtils.java:151)
at jcuda.LibUtils.loadLibrary(LibUtils.java:83)
at jcuda.runtime.JCuda.initialize(JCuda.java:303)
at jcuda.runtime.JCuda.<clinit>(JCuda.java:290)
at JCusparseSample.main(JCusparseSample.java:31)
Stack trace from the attempt to load the library as a file:
java.lang.UnsatisfiedLinkError: no JCudaRuntime-windows-x86_64 in java.library.path
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
at jcuda.LibUtils.loadLibrary(LibUtils.java:94)
at jcuda.runtime.JCuda.initialize(JCuda.java:303)
at jcuda.runtime.JCuda.<clinit>(JCuda.java:290)
at JCusparseSample.main(JCusparseSample.java:31)
Exception in thread "main" java.lang.UnsatisfiedLinkError: Could not load the native library
at jcuda.LibUtils.loadLibrary(LibUtils.java:129)
at jcuda.runtime.JCuda.initialize(JCuda.java:303)
at jcuda.runtime.JCuda.<clinit>(JCuda.java:290)
at JCusparseSample.main(JCusparseSample.java:31)
The part that says „no JCudaRuntime-windows-x86_64 in java.library.path“ might contain the valuable information in this case.
So are you sure that you are also using the latest version of the JARs?
If I cannot get it to work I could just try to setup a simple JNI bridged C program that calls a standard Nvidia CUDA file compiled with MSVC++ 2008 and Nvidia rules. Is there much more to JCuda?
In fact, JCuda basically consists of the low-level bindings - a 1:1 mapping of the API. And if you only want to perform a single, complex CUDA operation, it might be justifiable to create an own JNI interface, which contains only one special-purpose native method like ‚doTheComplexComputationWithCUDA‘ - but of course the intention of JCuda is to avoid this, and to provide the original flexibility of CUDA for Java. Hopefully we’ll still get it running somehow.
I started from scratch and this time copied the dll in the CUDA toolkit directory to make sure that they were visible… and I got the minimalist example to work! Now I will try to setup an ImageJ plugin with JCuda.
Yes you are right having a direct access to the CUDA functions in JAVA is more flexible but still the hardcore development will always be in C (for the kernels) and as such a generic JNI bridge that passes an ImageJ image (or a stack) pointer and parameters to a CUDA-C function (used as a building template) might be useful too (I used something similar for Matlab in the past). I never used JNI and my JAVA knowledge is at the moment very low - would you by any chance know where to find such template? Thanks a million for the great job and for your help and sorry for erroneously adding up to the linkerror list!
Well, good to hear that - although copying any JCuda DLLs to the NVIDIA directory should NOT be necessary. If there is “only” the problem that the DLLs can not be found, this can usually be solved by simply putting the DLLs into the root directory of the project, or, alternatively, specifying the path where they are located using the “java.library.path”. But at least you can run first tests now.
Yes, the fact that the kernels always have to be developed in C (and that a C-Compiler is required) could be considered as a drawback. In contrast to that: In OpenCL, you can simply define the Kernel source code as a String, and use the built-in compiler of OpenCL. I think that one of the major assets of NVIDIA and CUDA is that they have powerful runtime libraries (CUBLAS, CUFFT, etc).
By the way: There is also a runtime library called NPP ( http://developer.nvidia.com/npp ) which contains thousands (!) of image processing routines. I’m currently preparing a VERY early alpha release of “JNpp”. JNpp again just offers the low-level access to the NPP functions as-they-are. But I intended to create a set of utility classes that offer the functionality of (J)Npp in a more Java-friendly way. This will be challenging and I’m not even 100% sure if I will get it done at all, but I’ll try. Recently, I have been asking for support (in this thread (german), maybe some google translation helps to get the message). The most challenging parts of these utility-classes may probably be independent of ImageJ, but having some background knowledge in ImageJ would certainly be helpful…
EDIT: Concerning the “template” you have been asking for: I’m not entirely sure what you mean. Since the class (ImagePlus or stack) and the parameters will be highly specific for the problem, there will hardly be a one-fits-all solution. There are several approaches for simplifying the connection between Java and DLLs (like JNA or BridJ, or maybe Swig) but I haven’t seen any of them applied to CUDA.
I could also compile and get the JCuda enabled ImageJ plugin to work but it requires to change the jcudaUtils file for the newest one (jcudaUtils-0.0.4.jar), I think you mentioned something about a future update of this package.
The main reason why the „ImageJ Quick Start Package“ requires an update is because it still contains the old (unversioned) JAR files. I hope that I can do this update soon, and maybe create one or more examples showing how JNpp may be used together with ImageJ.
Admittedly, I have not done anything with ImageJ except for creating the example a while ago (and I basically wrote down what I did to get it running - that’s the „Tutorial“ now ), but I think that CUDA, and especially NPP, may be very well suited for image processing in general, so having a closer look at this should definitely be worthwhile.
I will have a look at NPP, I am really curious to see if advanced image processing functions (advanced image segmentation for instance) have been implemented… I thought only filters and basic image processing functions were implemented so far in such libraries but the scene is moving fast… regarding the template I mentioned I would be happy to have it setup for standard 8-bit stacks - the only objects that should be passed to the C-CUDA function should be a pointer to the stack and 3 parameters (width, height and number of slices of the stack). From this most Image processing could be implemented. JNI is an option but JNA and swig both look good, thanks for pointing them out!
Good luck with your work, I will definitely keep an eye on the progress and get back to you if I start implementing advanced CUDA enabled ImageJ plugins!
The „Image Segmentation“ you mentioned may be covered with the functions that are also mentioned at the NPP main page: The „NPP graphcut primitive“. Although I’ll have to read more about this - until now, I „blindly“ created the bindings for NPP, an just started testing and experimenting further…
the only objects that should be passed to the C-CUDA function should be a pointer to the stack and 3 parameters (width, height and number of slices of the stack).
Of course, it may have the advantage of simpler usage and less method call overhead, but the disadvantage of reduced flexibility. One could consider to develop and experiment with the Java bindings, and for the „final release version“ (when only the fixed functionality is required) creating such a C function that summarizes the full (specific) functionality. However, there are several options, and certainly it’s possible to find a feasible solution.
I had a look at the NPP documentation and I have to admit it is already quite advanced. Unfortunately when it comes to really demanding advanced 3D segmentation techniques the library lags well behind specialized libraries such as VTK and ITK. Coming back to ImageJ I could get the plugin to work perfectly but I still have a problem while trying to use it in the FIJI bundle. The plugins I have compiled so far with the Java 1.6 JDK were all working fine under FIJI so I doubt it is JRE related (the JRE FIJI uses is bundled with the software and is the JRE 1.6) and do not know what exactly causes the problem… it might be that Fiji cannot find all the dll… here is the error message:
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at ij.Command.runPlugIn(Command.java:146)
at ij.Command.runCommand(Command.java:95)
at ij.Executer.run(Executer.java:64)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.UnsatisfiedLinkError: Could not load the native library
at jcuda.LibUtils.loadLibrary(LibUtils.java:129)
at jcuda.driver.JCudaDriver.(JCudaDriver.java:206)
at jcuda.utils.KernelLauncher.initialize(KernelLauncher.java:603)
at jcuda.utils.KernelLauncher.(KernelLauncher.java:586)
at jcuda.utils.KernelLauncher.load(KernelLauncher.java:445)
at Simple_JCuda_Plugin.setup(Simple_JCuda_Plugin.java:95)
at ij.plugin.filter.PlugInFilterRunner.(PlugInFilterRunner.java:47)
at ij.IJ.runUserPlugIn(IJ.java:185)
at ij.IJ.runPlugIn(IJ.java:150)
… 8 more
Ok, I’ve never heard of FIJI before. It looks interesting, but also quite complex at the first glance. Since it is shipping with its own JRE, and seems to use some … “tricky” invocation mechanisms, the first thing I did was looking into the possible options, and how to pass parameters to the JVM. The first thing I found was http://fiji.sc/wiki/index.php/JavaOptions . So it should be possible to pass “normal” arguments to the VM. So it might be possible to also specify the java library path. When passing the Argument
-Djava.library.path=C:\path o\jcuda\dlls
it should find the library. (But again: The error message caused by an UnsatisfiedLinkError should be much more verbose in the latest version, as mentioned in this post). If it does not work, maybe I can install Fiji and test it myself, but I’m not sure when I will find the time for this.
Hi Marco,
I tried the ImageJ Simple_JCuda_Plugin with my FIJI installation (RHE5 64-bit) without success. Reading your FAQ’s, seems related to the location of the JCUDA libraries, I added it to my LD_LIBRARY_PATH, also I tried adding the flag -Djava.library.path=/users/rswz/data/usr/share/Fiji.app/lib to the commandline for running fiji: /users/rswz/data/usr/share/Fiji.app/fiji-linux64. Whe I tried to run the pluging in FIJI I keep getting the same error message (see below). At compilation time for java->class and cu->cubin there is no problem. The probelm is when I try to run the Simple_JCuda_Plugin.class file from FIJI.
Any advice is appreciated. Thanks.
Rafael
Operating system name: Linux
Architecture : amd64
Architecture bit size: 64
Stack trace from the attempt to load the library as a resource:
java.lang.NullPointerException: No resource found with name ‘/lib/libJCudaDriver-linux-x86_64.so’
at jcuda.LibUtils.loadLibraryResource(LibUtils.java:151)
at jcuda.LibUtils.loadLibrary(LibUtils.java:83)
at jcuda.driver.JCudaDriver.(JCudaDriver.java:206)
at jcuda.utils.KernelLauncher.initialize(KernelLauncher.java:603)
at jcuda.utils.KernelLauncher.(KernelLauncher.java:586)
at jcuda.utils.KernelLauncher.load(KernelLauncher.java:445)
at Simple_JCuda_Plugin.setup(Simple_JCuda_Plugin.java:95)
at ij.plugin.filter.PlugInFilterRunner.(PlugInFilterRunner.java:47)
at ij.IJ.runUserPlugIn(IJ.java:185)
at ij.IJ.runPlugIn(IJ.java:150)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at ij.Command.runPlugIn(Command.java:146)
at ij.Command.runCommand(Command.java:95)
at ij.Executer.run(Executer.java:64)
at java.lang.Thread.run(Thread.java:619)
Stack trace from the attempt to load the library as a file:
java.lang.UnsatisfiedLinkError: /net/vema.xcp.chevrontexaco.net/vol/vol4/geolog_q1/geolog/fe/non_geolog/rswz/usr/share/Fiji.app/lib/libJCudaDriver-linux-x86_64.so: libcudart.so.4: 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:1803)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1728)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1028)
at jcuda.LibUtils.loadLibrary(LibUtils.java:94)
at jcuda.driver.JCudaDriver.(JCudaDriver.java:206)
at jcuda.utils.KernelLauncher.initialize(KernelLauncher.java:603)
at jcuda.utils.KernelLauncher.(KernelLauncher.java:586)
at jcuda.utils.KernelLauncher.load(KernelLauncher.java:445)
at Simple_JCuda_Plugin.setup(Simple_JCuda_Plugin.java:95)
at ij.plugin.filter.PlugInFilterRunner.(PlugInFilterRunner.java:47)
at ij.IJ.runUserPlugIn(IJ.java:185)
at ij.IJ.runPlugIn(IJ.java:150)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at ij.Command.runPlugIn(Command.java:146)
at ij.Command.runCommand(Command.java:95)
at ij.Executer.run(Executer.java:64)
at java.lang.Thread.run(Thread.java:619)
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at ij.Command.runPlugIn(Command.java:146)
at ij.Command.runCommand(Command.java:95)
at ij.Executer.run(Executer.java:64)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.UnsatisfiedLinkError: Could not load the native library
at jcuda.LibUtils.loadLibrary(LibUtils.java:129)
at jcuda.driver.JCudaDriver.(JCudaDriver.java:206)
at jcuda.utils.KernelLauncher.initialize(KernelLauncher.java:603)
at jcuda.utils.KernelLauncher.(KernelLauncher.java:586)
at jcuda.utils.KernelLauncher.load(KernelLauncher.java:445)
at Simple_JCuda_Plugin.setup(Simple_JCuda_Plugin.java:95)
at ij.plugin.filter.PlugInFilterRunner.(PlugInFilterRunner.java:47)
at ij.IJ.runUserPlugIn(IJ.java:185)
at ij.IJ.runPlugIn(IJ.java:150)
… 8 more
was occasionally reported in similar forms, for example, in this thread, maybe creating a ‚symbolic link‘ to that file helps?
BTW: Did you have the chance to to a basic test of JCuda on this system outside of Fiji, just to make sure that it works in general?
Marco,
Symbolic links are preents in both lib and lib64 directories of my CUDA istallations. I also linked on my JCuda lib directory to those, still smae error message. I am using SDK 4.1 and the latest JCuda distro and Utils file.
I tried the Test case without FIJI, and I think works. I got this on the terminal:
Pointer: Pointer[nativePointer=0x0,byteOffset=0]
Have you tried JCuda on FIJI?
thanks
Rafael
Um… the output of the test programm is really strange: After memory was allocated, the ‚nativePointer‘ should not be 0 (0x0) any more Additionally, the „minimal test“ does not use the driver API. But I assume that a standalone version of the JCudaVectorAdd also works…? I did not yet test FIJI, but maybe I can try this tomorrow or on monday. It’s not Linux, however, and the error message about a missing „libcudart.so.4“ is obviusly specific for Linux…
Copied the DLLs into the FIJI root directory (Fiji.app)
Copied the JCuda JARs (including the JCuda utils JAR) into the “jars” diretory
Copied the “Simple_JCuda_Plugin.jar” into the “plugins” directory
And after starting FIJI, I could load an image and invert it with the Simple_JCuda_Plugin.
Most likely, there is something wrong with the connection between the Linux JCuda driver library and the unterlying CUDA installation. I’m not so familiar with Linux, and can hardly tell what might be wrong there (possibly with the “symbolic links”…?). Did you have the chance to test, for example, the “JCudaVectorAdd” sample?
Hi Marco,
It is working now. Many thanks for the help.
I had several thing out of order, so I went back and and check all the steps:
I installed the Nvidia drivers (I had a driver version from 2009).
I installed Cuda Toolkit (4.1) for x86_64 in /home/raf/local/cuda.
The SDK is not necessary but very useful to test your Cuda installation. I have it install in /home/raf/local/NVIDIA_GPU_Computing_SDK, and you can test it by running “make” in the “C” directory to populate the"C/bin/linux/relase/" directory, where you can test: “deviceQuery”, “scan”, etc, and see your system cuda capabilities (I have a Quadro FX4800 capable of cuda 1.3 only with 192 cores).
I installed the Oracle Java SDK (64bit) in /home/raf/local/jdk1.6.0_25/
I installed Jcuda files (4.1RC2b 64bit): *.so files in /home/raf/local/jcuda/lib/ and *.jar files in /home/raf/local/jcuda/jars/ (including jcudaUtils.jar, I took the version numbers from the file names).
I modify my CSH shell init file adding:
set path=(/home/raf/local/jdk1.6.0_25/bin /home/raf/local/cuda/bin $path)
setenv LD_LIBRARY_PATH /home/raf/local/cuda/lib64:/home/raf/local/jcuda/lib
I compiled and ran the Jcuda test cases, JCudaRuntimeTest and JCudaVectorAddKernel:
javac -cp “.:/home/raf/local/jcuda/jars/jcuda.jar” JCudaRuntimeTest.java
java -cp “.:/home/raf/local/jcuda/jars/jcuda.jar:” JCudaRuntimeTest
output: Pointer: Pointer[nativePointer=0x210000,byteOffset=0]
nvcc -cubin -m64 -arch sm_13 JCudaVectorAddKernel.cu -o JCudaVectorAddKernel.cubin
javac -cp “.:/home/raf/local/jcuda/jars/jcuda.jar” JCudaVectorAdd.java
java -cp “.:/home/raf/local/jcuda/jars/jcuda.jar:” JCudaVectorAdd
output: Test PASSED
I installed ImageJ/Fiji (64bit) in /home/raf/local/ImageJ and /home/raf/local/Fiji.app, an created symbolic links to the Jcuda jar files:
ln -s /home/raf/local/jcuda/jars/* /home/raf/local/ImageJ/plugins/jars/
ln -s /home/raf/local/jcuda/jars/* /home/raf/local/Fiji.app/jars/
I compiled and ran the Simple_JCuda_Plugin in ImageJ and Fiji:
nvcc -cubin -m64 -arch sm_13 simpleJCudaPluginKernel.cu -o simpleJCudaPluginKernel.cubin
javac -cp “.:/home/raf/local/jcuda/jars/jcuda.jar:/home/raf/local/jcuda/jars/jcudaUtils.jar:/home/raf/local/ImageJ/ij.jar” Simple_JCuda_Plugin.java
copy Simple_JCuda_Plugin.class and simpleJCudaPluginKernel.cubin in plugin directories of ImageJ and Fiji
From its directory launch ImageJ (java -jar ij.jar) or Fiji (fiji-linux64) and run the plugins->Simple_Jcuda_Plugin. It will invert any RGB image.
OK, back in 2009, CUDA hardly existed - I should probably emphasize in the Tutorials that a recent driver should be used, although it is already mentioned in the JCuda tutorial.
But when someone runs into problems with JCuda on linux (or ImageJ, specifically) this summary may be very helpful. So thanks for the detailed description!