2020-10-30

How do I pack a function from a static library into an .so file with fortran (MKL)

I'm trying to speed up an optimization routine using MKL's blas implementation in fortran. I need to have the result in a shared library so that it is accessible from a larger script. I can compile and link my code without any warnings, but the resulting .so file has an undefined reference to the blas routine I'm trying to call, namely dgemm.

relevant section of the fortran code:

subroutine sumsquares(params, Mx, flen, glen, numr, numcols, g, lambda, res)
 implicit none
 integer, intent(in):: flen, glen, numr, numcols
 real(8), dimension(flen, numcols) :: params
 real(8), dimension(flen, numcols) :: g
 real(8), dimension(flen, numcols) :: gc
 real(8), dimension(flen, glen) :: Mx 

 gc = -g
 call dgemm('N', 'N', flen, glen, numcols, 1, Mx, flen, params, numcols, 1, gc,flen)
 return
end subroutine sumsquares

and the corresponding makefile

FC=ifort
LD_LIBRARY_PATH=/opt/intel/composerxe-2011.1.107/compiler/lib/intel64:/opt/intel/composerxe-2011.1.107/mkl/lib/intel64
LIBRARY_PATH=/opt/intel/composerxe-2011.1.107/compiler/lib/intel64:/opt/intel/composerxe-2011.1.107/mkl/lib/intel64
INCLUDE=/opt/intel/composerxe-2011.1.107/mkl/include
FPATH=/opt/intel/composerxe-2011.1.107/mkl/include
CPATH=/opt/intel/composerxe-2011.1.107/mkl/include
FFLAGS=-i8 -I$(MKLROOT)/include/intel64/ilp64 -I$(MKLROOT)/include
LDFLAGS= -shared -nofor-main -fPIC
LINKLIBS=-fPIC -shared -L$(MKLROOT)/lib/intel64 $(MKLROOT)/lib/intel64/libmkl_blas95_ilp64.a -lmkl_rt -lpthread -lm

sumsquares: sumsquares.f90
    $(FC) $(FFLAGS) -c -fPIC /opt/intel/composerxe-2011.1.107/mkl/include/blas.f90 -o blas95.o
    $(FC) $(FFLAGS) -nofor-main -c -fPIC sumsquares.f90
    $(FC) $(LDFLAGS) sumsquares.o $(LINKLIBS) sumsquares.o

As I said, I can run make without any warnings, but when I run nm sumsquares.so | grep dgemm I see U dgemm_, and when I try to load the .so file, I crash with a segfault (while calling an unrelated subroutine, so I don't think it's related to this code). How do I get the linker to put in the relevant function into the so file?

Update

I am loading the so file in an R script by calling dyn.load in R as follows:

Variation 1:

dyn.load("/home/me/path/sumsquares.so")

Variation 2:

dyn.load("/opt/intel/composerxe-2011.1.107/mkl/lib/intel64/libmkl_rt.so")
dyn.load("/home/me/path/sumsquares.so")

Both variations lead to the same result, with a segfault.



from Recent Questions - Stack Overflow https://ift.tt/2HPNZgt
https://ift.tt/eA8V8J

No comments:

Post a Comment