Intel MKL and JNI : How to add a shared library that ld searches symbols from?

Isa_R :

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.

Florian Weimer :

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.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=160158&siteId=1