如何使用fortranMKL将静态库中的函数打包到.so文件中

问题描述

我正在尝试使用Fortran中MKL的blas实现来加速优化例程。我需要将结果保存在共享库中,以便可以从较大的脚本访问它。我可以编译和链接我的代码而没有任何警告,但是生成的.so文件对我要调用的blas例程有未定义的引用,即dgemm

fortran代码的相关部分:

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

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

和相应的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

正如我所说,我可以在没有任何警告的情况下运行make,但是当我运行nm sumsquares.so | grep dgemm时会看到U dgemm_,并且在尝试加载.so文件时,我因段错误而崩溃(在调用不相关的子例程时,因此我认为它与此代码无关)。如何获得链接器以将相关功能放入so文件中?

更新

我通过在R中调用so来在R脚本中加载dyn.load文件,如下所示:

变化1:

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

变化2:

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

两种变化都会导致相同的结果,但存在段错误。

更新#2

我应该指出,英特尔MKL静态库 是使用-fPIC标志(至少为according to the documentation)编译的。我显然不知道我在做什么,但是据我所知,这样的事情应该是可能的。

由于blas在科学计算中得到广泛使用,因此我担心与不同版本的冲突。如果我要在so文件中进行静态链接,并将该so文件加载到使用其他blas实现的程序中,会导致冲突,或者我的库会播放好吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)