I'm trying to use a C++ shared library which I built (libmine.so
) and uses Intel's MKL library from Java using JNI.
I also created libminejni.so
, and loaded it from Java code like this:
System.loadLibrary("minejni")
However it failed to load one of the MKL library (libmkl_avx2.so
)
<path_to_lib>/libmkl_avx2.so: <path_to_lib>/libmkl_avx2.so:
undefined symbol: mkl_sparse_optimize_bsr_trsm_i8
The symbol is defined in libmkl_gnu_thread.so
>nm <path_to_lib>/libmkl_gnu_thread.so | grep mkl_sparse_optimize_bsr_trsm_i8
00000000004fe240 T mkl_sparse_optimize_bsr_trsm_i8
So I loaded the library using System.loadLibrary
before loading the problematic library, but the error wasn't solved.
I executed it with LD_DEBUG=bindings,symbols
, and found that it didn't search libmkl_gnu_thread.so
for the symbol.
[java] 11275: symbol=mkl_sparse_optimize_bsr_trsm_i8; lookup in file=/local/workspaces/JDK8-1.0/runtime/jdk1.8/bin/java [0]
[java] 11275: symbol=mkl_sparse_optimize_bsr_trsm_i8; lookup in file=/lib64/libpthread.so.0 [0]
[java] 11275: symbol=mkl_sparse_optimize_bsr_trsm_i8; lookup in file=/lib/amd64/jli/libjli.so [0]
[java] 11275: symbol=mkl_sparse_optimize_bsr_trsm_i8; lookup in file=/lib64/libdl.so.2 [0]
[java] 11275: symbol=mkl_sparse_optimize_bsr_trsm_i8; lookup in file=/lib64/libc.so.6 [0]
[java] 11275: symbol=mkl_sparse_optimize_bsr_trsm_i8; lookup in file=/lib64/ld-linux-x86-64.so.2 [0]
[java] 11275: symbol=mkl_sparse_optimize_bsr_trsm_i8; lookup in file=/jdk1.8/jre/lib/amd64/server/libjvm.so [0]
[java] 11275: symbol=mkl_sparse_optimize_bsr_trsm_i8; lookup in file=/lib64/libm.so.6 [0]
[java] 11275: symbol=mkl_sparse_optimize_bsr_trsm_i8; lookup in file=/lib/libmkl_avx2.so [0]
[java] 11275: symbol=mkl_sparse_optimize_bsr_trsm_i8; lookup in file=/lib64/libdl.so.2 [0]
[java] 11275: symbol=mkl_sparse_optimize_bsr_trsm_i8; lookup in file=/lib64/libc.so.6 [0]
[java] 11275: symbol=mkl_sparse_optimize_bsr_trsm_i8; lookup in file=/lib64/ld-linux-x86-64.so.2 [0]
[java] 11275: /lib/libmkl_avx2.so: error: symbol lookup error: undefined symbol: mkl_sparse_optimize_bsr_trsm_i8 (fatal)
The library works if I create an executable using C++. I wanted to add libmkl_gnu_thread.so
to the list of libraries that ld will search symbols, does anybody know how to do that?
NOTE: If I add all MKL related library to LD_PRELOAD, it works but I'm looking for less hacky way. NOTE2: some paths in the example are modified to remove personal info.
The JNI library loads objects using by calling dlopen
with RTLD_LOCAL
(i.e., the default). This means that the library's symbols do not become available for other dlopen
calls. If you call dlopen
for libmkl_gnu_thread.so
with RTLD_GLOBAL
just once inside the same process, it will get injected into the global scope, where other libraries (including those which are loaded using with RTLD_LOCAL
) can find its symbols.
Alternatively, it should be possible to link minejni
against libmkl_gnu_thread.so
, so that it is loaded into the same search scope. Note that on some distributions, you will have to link with -Wl,--no-as-neeeded
, to prevent optimizing away this dependency, which appears to be unneeded at this point.