英特尔MKL和JNI:如何添加可从中搜索符号的共享库?

时间:2019-02-14 16:23:57

标签: java c++ java-native-interface ld intel-mkl

我正在尝试使用自己构建的(libmine.so)C ++共享库,并使用JNI通过Java使用英特尔的MKL库。

我还创建了libminejni.so,并从Java代码中加载了它,如下所示:

System.loadLibrary("minejni")

但是它无法加载MKL库之一(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加载了库,但是错误没有得到解决。

我用LD_DEBUG=bindings,symbols执行了该程序,发现它没有在libmkl_gnu_thread.so中搜索该符号。

     [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将搜索符号的库列表中,有人知道该怎么做吗?

注意:如果我将所有与MKL相关的库都添加到LD_PRELOAD中,则可以使用,但是我正在寻找更简单的方法。 注意2:示例中的某些路径已修改为删除个人信息。

1 个答案:

答案 0 :(得分:1)

JNI库通过调用dlopen with RTLD_LOCAL(即默认值)来加载对象。这意味着该库的符号不可用于其他dlopen调用。如果您在同一进程中一次用dlopen调用libmkl_gnu_thread.so的{​​{1}},它将注入到全局范围中,在该范围内,其他库(包括与{{1 }})可以找到其符号。

或者,应该可以将RTLD_GLOBALRTLD_LOCAL链接起来,以便将其装入相同的搜索范围。请注意,在某些发行版中,您将必须与minejni链接,以防止优化这种依赖关系,而这在目前看来似乎是不必要的。