Reputation: 4662
I wrote this test program.
#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);
}
I compile and link it using the following command.
g++ -g -DMKL_ILP64 mkl_example.cpp -L$HOME/intel/mkl/lib/intel64/ -lgsl -lmkl_intel_ilp64 -lmkl_sequential -lmkl_core -lm
I get Segmentation fault at the line where I'm doing gsl_blas_dgemv
. The stack trace looks like this:
#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
On the other hand, when linking with open blas the same program works. Am I missing something here? How to correctly use Intel's MKL with gsl?
Upvotes: 2
Views: 1620
Reputation: 581
libgsl accepts 32 bit integer but when you compile with -DMKL_ILP64 option and link against ...-lmkl_intel_ilp64 library, You pass 64 bit integer in that case. That's the reason of the problem.
Upvotes: 0
Reputation: 38
I ran into this exact issue a few days ago (GCC 8.2, IMKL 2019.2, GSL 1.15) and managed to fix the segfault by switching from the MKL 64 bit interface (ILP) to the 32 bit interface (LP). I suspect that there's some sort of parameter size mismatch when going from the libgsl call into the libmkl call when using the 64 bit interface. Essentially you would change your compile / link command from this
g++ -g -DMKL_ILP64 mkl_example.cpp -L$HOME/intel/mkl/lib/intel64/ -lgsl -lmkl_intel_ilp64 -lmkl_sequential -lmkl_core -lm
to this
g++ -g mkl_example.cpp -L$HOME/intel/mkl/lib/intel64/ -lgsl -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lm
I will add that including the -Wl,--no-as-needed
from Kaveh's answer may be required as well if you are not explicitly linking MKL statically. (I had to include it to get all of the required MKL .so files to show up when running ldd
on the result binary.) However I'd expect you to get a "symbol not found" error at runtime instead of a segmentation fault if that were the only problem.
Upvotes: 0
Reputation: 3477
Please confirm that you can run the program as follows:
g++ -g mkl_example.cpp -L$HOME/intel/mkl/lib/intel64/ -lgsl -lmkl_intel -lmkl_sequential -lmkl_core -lm
It looks as if you are linking the Intel MKL libraries with different interface layers.
The next step would be to try the following:
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
The latter, modifies your compile command to include -Wl, --no-as-needed
, which guarantees that all specified libraries will be written as required at runtime.
Upvotes: 1