I'm trying to glue together a scripting language and MKL. The mode of operations is: scripting language dynamically loads my .so (via dlopen -- critically, with RTLD_LOCAL), and exposes my routines to the language. My glue code gets called, transforms scripting structures to MKL arguments, calls MKL, transforms results into scripting structures and returns.
Unfortunately, when the library is is first invoked, it bombs out with
*** libmkl_mc3.so *** failed with error : /usr/local/mkl/10.1.3.027/lib/em64t/libmkl_mc3.so: undefined symbol: mkl_dft_commit_descriptor_s_c2c_md_omp
*** libmkl_def.so *** failed with error : /usr/local/mkl/10.1.3.027/lib/em64t/libmkl_def.so: undefined symbol: mkl_dft_commit_descriptor_s_c2c_md_omp
MKL FATAL ERROR: Cannot load neither libmkl_mc3.so nor libmkl_def.so
After futzing around for several hours, this seems to be the situation:
(for reference, I am running linux 2.6 x86_64 with g++)
I have a small test library libtest.so that is linked as follows
"g++" -L"/usr/local/mkl/10.1.3.027/lib/em64t" -o "bin/gcc-4.3.3/debug/threading-multi/libtest.so" -Wl,-h -Wl,libtest.so -shared -Wl,--start-group "bin/gcc-4.3.3/debug/threading-multi/test.o" -Wl,-Bstatic -Wl,-Bdynamic -lmkl_gf_lp64 -lmkl_gnu_thread -lmkl_lapack -lmkl_core -liomp5 -lrt -Wl,--end-group -g -pthread
I think these are the correct dependencies, though I'm by no means confident.
1. If I write a test binary that directly links against my test function (which calls into lapack), it works just fine.
2. If I write a test binary that at run-time calls dlopen(RTLD_GLOBAL) on libtest.so (not linked in as an execution dependency), it works just fine.
3. If I write a test binary that at run-time calls dlopen(RTLD_LOCAL), I get the error above.
I think what's going on is that MKL is internally calling dlopen to intialize stuff. However, in the third case above, the symbols from libtest.so aren't added to the executables space, so it can't resolve them. I don't have the option of changing the way the scripting executable loads shared objects, even if that were the preferred solution.
For reference, this works:
4. if I invoke my binary #3 with LD_PRELOAD of libtest.so, the symbols get added to the global space, and it works. This also works with the scripting language. But it is a terrible solution for a lot of obvious reasons.
Anyone have any better approaches?