简体   繁体   中英

Can't use intel mkl in JNI shared library

I am attempting to build C JNI code that uses Intel MKL for matrix multiplication

In my C file I have

#include "mkl.h"
...
cblas_dgemm (CblasRowMajor, CblasNoTrans, CblasNoTrans, numRows, numCols, numRows, 1.0, mulMatrix, numRows, first, numCols, 0.0, second, numCols);

I compile the jni file with:

m082166@mforgehn4 $ icc -mkl -openmp -O3 -fPIC -std=c99 -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux/" -o irl/libjniconverge.so -shared c_src/MyJNICode.c

I had weird issues with System.loadLibrary, so I have the following code in a static initializer:

    String      path = System.getProperty ("jni.library");
    String[]    paths = path.split (":");

    for (String libPath : paths)
        System.load (libPath);

The code fails to run:

The unsurmountable error is this:

Exception in thread "main" java.lang.UnsatisfiedLinkError: /usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/mkl/lib/intel64_lin/libmkl_avx2.so: /usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/mkl/lib/intel64_lin/libmkl_avx2.so: undefined symbol: mkl_dft_fft_fix_twiddle_table_32f

A post here claims that is provided by libmkl_core.so, but adding /usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/mkl/lib/intel64_lin/libmkl_core.so (24 MB) doesn't solve the problem

$ java -Djni.library="/usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/mkl/lib/intel64_lin/libmkl_def.so:/usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/compiler/lib/intel64_lin/libimf.so:/home/mayo/m082166/irl/libjniconverge.so" -jar MyJava-jar-with-dependencies.jar 
Exception in thread "main" java.lang.UnsatisfiedLinkError: /usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/mkl/lib/intel64_lin/libmkl_def.so: /usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/mkl/lib/intel64_lin/libmkl_def.so: undefined symbol: mkl_dft_fft_fix_twiddle_table_32f
    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 MyJava.<clinit>(MyJava.java:77)
$ java -Djni.library="/usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/compiler/lib/intel64_lin/libimf.so:/home/mayo/m082166/irl/libjniconverge.so" -jar MyJava-jar-with-dependencies.jar 
Intel MKL FATAL ERROR: Cannot load libmkl_avx2.so or libmkl_def.so.
$ export LD_LIBRARY_PATH=/usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/mkl/lib/intel64_lin
$ java -Djni.library="/usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/compiler/lib/intel64_lin/libimf.so:/home/mayo/m082166/irl/libjniconverge.so" -jar MyJava-jar-with-dependencies.jar 
Exception in thread "main" java.lang.UnsatisfiedLinkError: /usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/compiler/lib/intel64_lin/libimf.so: libintlc.so.5: 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 MyJava.<clinit>(MyJava.java:77)
$ find /usr/local/intel-2016 -name libintlc.so
/usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/compiler/lib/intel64_lin/libintlc.so
/usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/compiler/lib/ia32_lin/libintlc.so
/usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/compiler/lib/intel64_lin_mic/libintlc.so
$ export LD_LIBRARY_PATH="/usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/mkl/lib/intel64_lin:/usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/compiler/lib/intel64_lin"
$ java -Djni.library="/usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/compiler/lib/intel64_lin/libimf.so:/home/mayo/m082166/irl/libjniconverge.so" -jar MyJava-jar-with-dependencies.jar 
Intel MKL FATAL ERROR: Cannot load libmkl_avx2.so or libmkl_def.so.
$ find /usr/local/intel-2016 -name libmkl_def.so
/usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/mkl/lib/intel64_lin/libmkl_def.so
$ echo $LD_LIBRARY_PATH
/usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/mkl/lib/intel64_lin:/usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/compiler/lib/intel64_lin
$ java -Djni.library="/usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/mkl/lib/intel64_lin/libmkl_def.so:/usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/compiler/lib/intel64_lin/libimf.so:/home/mayo/m082166/irl/libjniconverge.so" -jar MyJava-jar-with-dependencies.jar 
Exception in thread "main" java.lang.UnsatisfiedLinkError: /usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/mkl/lib/intel64_lin/libmkl_def.so: /usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/mkl/lib/intel64_lin/libmkl_def.so: undefined symbol: mkl_dft_fft_fix_twiddle_table_32f
    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 MyJava.<clinit>(MyJava.java:77)

How do I get this to link and run?

Whenever you pass code to JNI , you are no longer inside JVM (in terms of java.library.path ). It means that any shared library loaded by your JNI code will load libraries using system calls.

For you, it means you have to make sure that all libraries are visible either via LD_LIBRARY_PATH or are linked using -rpath .

Make sure libmkl_core.so and libraries it depends on

ldd libmkl_core.so

are visible to your code.

The solution is

export LD_PRELOAD=[Path]/libmkl_def.so:[Path]/libmkl_avx2.so:[Path]/libmkl_core.so:[Path]/libmkl_intel_lp64.so:[Path]/libmkl_intel_thread.so:[Different Path]/libiomp5.so

Declare that before running the Java, and it works

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM