将gsl c++程序与"英特尔MKL"链接

Linking gsl c++ program with Intel MKL

本文关键字:quot 英特尔 MKL 链接 gsl c++ 程序      更新时间:2023-10-16

我编写了这个测试程序。

#include <gsl/gsl_matrix.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_cblas.h>
#include <gsl/gsl_blas.h>
int main () {
gsl_vector* v = gsl_vector_calloc(5);
gsl_matrix* m = gsl_matrix_calloc(5, 5);
gsl_blas_dgemv(CblasNoTrans, 1.0, m, v, 0.0, v);
}

我使用以下命令编译并链接它。

g++ -g -DMKL_ILP64 mkl_example.cpp -L$HOME/intel/mkl/lib/intel64/ -lgsl -lmkl_intel_ilp64 -lmkl_sequential -lmkl_core -lm

我在执行gsl_blas_dgemv的行出现分段错误。堆栈跟踪如下所示:

#0  0x00007fffeeb5db0a in mkl_blas_mc3_xdgemv () from $HOME/intel/mkl/lib/intel64/libmkl_mc3.so
#1  0x00007ffff5b190be in mkl_blas_dgemv () from $HOME/intel/mkl/lib/intel64/libmkl_sequential.so
#2  0x00007ffff70e0b51 in mkl_blas__dgemv () from $HOME/intel/mkl/lib/intel64/libmkl_intel_ilp64.so
#3  0x00007ffff7108054 in cblas_dgemv () from $HOME/intel/mkl/lib/intel64/libmkl_intel_ilp64.so
#4  0x00007ffff7a0cfa4 in gsl_blas_dgemv () from /usr/lib64/libgsl.so.0
#5  0x000000000040086e in main () at mkl.cpp:10

另一方面,当与openblas链接时,相同的程序也能工作。我是不是遗漏了什么?如何将英特尔MKL与gsl一起正确使用?

请确认您可以按如下方式运行程序:

g++ -g mkl_example.cpp -L$HOME/intel/mkl/lib/intel64/ -lgsl -lmkl_intel -lmkl_sequential -lmkl_core -lm

看起来就像是在用不同的接口层链接"英特尔MKL"库。

下一步将尝试以下操作:

g++ -g -DMKL_ILP64 mkl_example.cpp -L$HOME/intel/mkl/lib/intel64/ -Wl, --no-as-needed -lgsl -lmkl_intel_ilp64 -lmkl_sequential -lmkl_core -lm

后者修改您的编译命令以包含-Wl, --no-as-needed,这保证了所有指定的库都将在运行时根据需要编写。

几天前我遇到了这个确切的问题(GCC 8.2、IMKL 2019.2、GSL 1.15(,并通过从MKL 64位接口(ILP(切换到32位接口(LP(来修复segfault。我怀疑在使用64位接口时,从libgsl调用到libmkl调用时存在某种参数大小不匹配的情况。从本质上讲,您将从这个更改您的编译/链接命令

g++ -g -DMKL_ILP64 mkl_example.cpp -L$HOME/intel/mkl/lib/intel64/ -lgsl -lmkl_intel_ilp64 -lmkl_sequential -lmkl_core -lm

到这个

g++ -g mkl_example.cpp -L$HOME/intel/mkl/lib/intel64/ -lgsl -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lm

我要补充的是,如果你没有显式地静态链接MKL,那么可能也需要包括Kaveh答案中的-Wl,--no-as-needed。(当在结果二进制文件上运行ldd时,我必须包含它才能获得所有所需的MKL.so文件。(然而,如果这是唯一的问题,我希望您在运行时会得到"未找到符号"错误,而不是分段错误。

libgsl接受32位整数,但当您使用-DMKL_ILP64选项进行编译并链接时-lmkl_intel_ilp64库,在这种情况下传递64位整数。这就是问题的原因。