英特尔MKL和JNI:如何添加ld从中搜索符号的共享库? [英] Intel MKL and JNI : How to add a shared library that ld searches symbols from?
问题描述
我正在尝试使用自己构建的C ++共享库( libmine.so
),并使用Java通过JNI使用英特尔的MKL库.
I'm trying to use a C++ shared library which I built (libmine.so
) and uses Intel's MKL library from Java using JNI.
我还创建了 libminejni.so
,并从Java代码中加载了它,如下所示:
I also created libminejni.so
, and loaded it from Java code like this:
System.loadLibrary("minejni")
但是,它未能加载MKL库之一( libmkl_avx2.so
)
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
该符号在 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
因此,在加载有问题的库之前,我使用 System.loadLibrary
加载了库,但是错误没有得到解决.
So I loaded the library using System.loadLibrary
before loading the problematic library, but the error wasn't solved.
我用 LD_DEBUG = bindings,symbols
(LD_DEBUG =绑定,符号)执行了该程序,发现它没有在 libmkl_gnu_thread.so
中搜索该符号.
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)
如果我使用C ++创建可执行文件,该库将起作用.我想将 libmkl_gnu_thread.so
添加到ld将搜索符号的库列表中,有人知道该怎么做吗?
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?
注意:如果我将所有与MKL相关的库都添加到LD_PRELOAD中,则可以使用,但是我正在寻找更简单的方法.注意2:示例中的某些路径已修改为删除个人信息.
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.
或者,应该有可能将 minejni
与 libmkl_gnu_thread.so
链接起来,以便将其加载到同一搜索范围内.请注意,在某些发行版中,您将不得不链接 -Wl(无需人工
),以防止优化这种依赖关系,而这在目前看来是不需要的.
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.
这篇关于英特尔MKL和JNI:如何添加ld从中搜索符号的共享库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!