无法在 JNI 共享库中使用 intel mkl
Can't use intel mkl in JNI shared library
我正在尝试构建使用 Intel MKL 进行矩阵乘法的 C JNI 代码
在我的 C 文件中我有
#include "mkl.h"
...
cblas_dgemm (CblasRowMajor, CblasNoTrans, CblasNoTrans, numRows, numCols, numRows, 1.0, mulMatrix, numRows, first, numCols, 0.0, second, numCols);
我用以下代码编译 jni 文件:
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
我在使用 System.loadLibrary 时遇到了奇怪的问题,所以我在静态初始化程序中有以下代码:
String path = System.getProperty ("jni.library");
String[] paths = path.split (":");
for (String libPath : paths)
System.load (libPath);
代码无法运行:
不可逾越的错误是:
线程 "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 : 未定义符号: mkl_dft_fft_fix_twiddle_table_32f
post here 声明由 libmkl_core.so 提供,但添加 /usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/mkl/lib/intel64_lin/libmkl_core.so (24 MB) 不会解决不了问题
$ 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)
如何将此内容发送到 link 和 运行?
无论何时将代码传递给 JNI
,您都不再处于 JVM 中(就 java.library.path
而言)。这意味着您的 JNI
代码加载的任何共享库都将使用系统调用加载库。
对您来说,这意味着您必须确保所有库都可以通过 LD_LIBRARY_PATH
看到或使用 -rpath
链接。
确保 libmkl_core.so
及其依赖的库
ldd libmkl_core.so
您的代码可见。
解决方案是
导出LD_PRELOAD=[路径]/libmkl_def.so:[路径]/libmkl_avx2.so:[路径]/libmkl_core.so:[路径]/libmkl_intel_lp64.so:[路径]/libmkl_intel_thread.so:[不同路径]/libiomp5.so
在 运行 之前声明 Java,并且有效
我正在尝试构建使用 Intel MKL 进行矩阵乘法的 C JNI 代码
在我的 C 文件中我有
#include "mkl.h"
...
cblas_dgemm (CblasRowMajor, CblasNoTrans, CblasNoTrans, numRows, numCols, numRows, 1.0, mulMatrix, numRows, first, numCols, 0.0, second, numCols);
我用以下代码编译 jni 文件:
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
我在使用 System.loadLibrary 时遇到了奇怪的问题,所以我在静态初始化程序中有以下代码:
String path = System.getProperty ("jni.library");
String[] paths = path.split (":");
for (String libPath : paths)
System.load (libPath);
代码无法运行:
不可逾越的错误是:
线程 "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 : 未定义符号: mkl_dft_fft_fix_twiddle_table_32f
post here 声明由 libmkl_core.so 提供,但添加 /usr/local/intel-2016/compilers_and_libraries_2016.0.109/linux/mkl/lib/intel64_lin/libmkl_core.so (24 MB) 不会解决不了问题
$ 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)
如何将此内容发送到 link 和 运行?
无论何时将代码传递给 JNI
,您都不再处于 JVM 中(就 java.library.path
而言)。这意味着您的 JNI
代码加载的任何共享库都将使用系统调用加载库。
对您来说,这意味着您必须确保所有库都可以通过 LD_LIBRARY_PATH
看到或使用 -rpath
链接。
确保 libmkl_core.so
及其依赖的库
ldd libmkl_core.so
您的代码可见。
解决方案是
导出LD_PRELOAD=[路径]/libmkl_def.so:[路径]/libmkl_avx2.so:[路径]/libmkl_core.so:[路径]/libmkl_intel_lp64.so:[路径]/libmkl_intel_thread.so:[不同路径]/libiomp5.so
在 运行 之前声明 Java,并且有效