UnsatisfiedLinkError : The specified procedure could not be found

I cant launch kernel with jcuda, i have jcuda 10.1 and program throws an „UnsatisfiedLinkError : C:…\JCudaDriver-10.1.0-windows-x86_64.dll : The specified procedure could not be found“. I tried jcuda 10.1 and 10.2 and always this exception was thrown. How can i solve it?

It could help if you

  1. posted the complete stack trace (it might even contain information about which procedure wasn’t found…)
  2. said more about your setup. E.g. which CUDA version do you have installed? (When you say that you tried JCuda 10.1.0 and JCuda 10.2.0, I wonder whether you really installed CUDA 10.1 and CUDA 10.2 for that…

Im already changed jcuda to jocl, sry

I think…
The dll-path isn’t in java-library-path. The java library path is build up from the %PATH%-system variable by default and has to be expanded via -djava-library-path= parameter. So if the path to the dll isn’t in %PATH% or there’s no given parameter, the library can’t be found by the JVM, even if it is in the right place.

@usruchi Yes, OpenCL fortunately is more vendor-independent, and has some mechanisms to handle dependencies more transparently (namely, the ICD - „Installable Client Driver“).

@Spacerat Oh, that’s cute :wink: I went the extra mile in JCuda and JOCL to free people (users) from the burden of having to fiddle with environment variables. The natives (DLL or SO files) have to be packed into JARs for proper Maven deployment anyhow. In fact, I’ve seen the LibUitls class being copied-and-pasted to other projects, so I even considered wrapping it into a library…

@Marco13 Then your work can’t be the solution for all usecases. The UnsatisfiedLinkError shows up, that a dll can not be found.
To your LibUtils… I do not see any passage, where loadLibrary() falls back to the original mechanism, if someone doesn’t like to put a dll or a so into every deployed Jar, because this is not in the spirit of the inventors of a library, if every application, which uses it, brings it’s own file. So you’ll have to wrap LibUtils and the binaries into a library. But this is brings up another problem… Since you have to unpack an install the dlls, you have to gain userrights to write them into a dir in the libpath or rights to create such a dir and add it to the path per program code. Anyway - if a user doesn’t grant you such rights during runtime, the execution will fail, because of an improper installation. In this case, you have to permit the user, to install the libs on his own and therefore he needs to use the original loadLibrary-Method which can’ be found in your Method.
In some of my Apps, I use

try {
  loadlibrary(LIB_NAME);
} catch (UnsatisfiedLinkError ule) {
  loadLibFromJar(LIB_NAME);
}

…and now I consider, to put this into a similar class, like your LibUtils.

The „fallback“ of using the standard mechanism is, in fact, tried first, at https://github.com/gpu/JOCL/blob/master/src/main/java/org/jocl/LibUtils.java#L144 . Only if this does not work, it goes through the (somewhat pain-in-the-back) of loading it from the JAR. So the overall structure matches your code snippet.

The reason for that is simple: During development, it is useful to „override“ the DLL from the JAR with one that has just been compiled and placed into the project directory. It should first try to pick up that one, because it may contain bugfixes that are supposed to be tested.

More generally:

The UnsatisfiedLinkError is the arch enemy (pun intended) of JNI developers. And it comes in several flavors. I’ve listed most (all?) that I encountered until now in JCuda FAQ - Please read before posting .

Fortunately, thanks to the load-from-JAR mechanism from the LibUtils, it basically never occurs any more. (Something like https://github.com/scijava/native-lib-loader could be an alternative, but there are caveats…Never change a running system…)

Iff a user still encounters an UnsatisfiedLinkError, then it’s basically always the one that says „The specified procedure could not be found“ (as in this case). This means that the DLL from the JAR was properly loaded (!), but it tries to call a function from the actual, underlying library that does not exist. For example, one will encounter this when trying to call a CUDA 10-function (through JCuda 10.0), but only having CUDA 9 installed.

(Again: In contrast to OpenCL, CUDA isn’t „version agnostic“ in any way…)

(The version problem could theoretically be alleviated by also packing the actual CUDA DLLs into the JAR. But there are two problems: 1. This might cause some licensing issues. And 2.: The DLLs for CUDA are HUGE. The DLL for CUFFT alone has 150 MB, and the total size of all DLLs is nearly 1 Gigabyte. And that’s only one of 3 operating systems. I don’t want to throw 3 GB JAR files into Maven Central :wink: )