使用R的包(例如LAPACK)从Fortran源构建共享对象

时间:2014-06-04 17:47:26

标签: r dll fortran lapack

我是新手从Fortran源创建R的共享对象。也许我的一些问题没有意义。但是,我已经搜索了很多关于我的问题,但仍然得不到明确的答案。所以,我想弄清楚在R中创建这些共享对象(.dll文件)的大图是什么。

根据一些教程和手册,我需要准备一个Fortran文件 mymodf.f ,它只包含子程序,类似如下:

c file mymodf.f
   subroutine initmod(odeparms)
    external odeparms
    double precision parms(3)
    common /myparms/parms

     call odeparms(3, parms)
    return
   end

   subroutine derivs (neq, t, y, ydot, yout, ip)
    ....
    return
   end

   subroutine jac (neq, t, y, ml, mu, pd, nrowpd, yout, ip)
    ....
    return
   end
c end of file mymodf.f

为了创建共享对象,它需要以下代码:

system("R CMD SHLIB mymodf.f")

我想使用LAPACK中的子程序来求解一些线性方程或逆矩阵。我该怎么办才能调用LAPACK中的子程序?我问这个问题是因为需要在R中安装软件包以调用一些额外的函数,或者需要在C中添加#include <xxxx.h>作为标头来调用xxxx.h中的一些额外函数。同样的情况。

另外,我从http://www.netlib.org/lapack下载了lapack-3.5.0.tgz。我应该把包装放在哪里?我是否需要安装此.tgz文件?

这不是编写,编译和运行Fortran程序的正常情况。我有一些Fortran代码,这不是一个完整的程序,我想把它作为R的.dll文件编译。

非常感谢您的帮助!

(仅供参考,我正在使用Windows 7 PC)

1 个答案:

答案 0 :(得分:2)

对于没有从Fortran源为R生成共享对象的经验的人来说,搜索我上面提到的问题的答案是非常耗时的,因为很少有教程提到这些。似乎有经验的人看不到这个帖子。

如果要在LAPACK或BLAS中调用子例程,则需要创建一个名为 Makevars 的文件,其中没有包含以下内容的文件类型:

PKG_LIBS=$(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)

备注:您不需要手动安装LAPACK和BLAS库,R已经包含它们。您需要做的就是通过在Fortran源文件的同一目录下创建 Makevars 文件来告诉编译器如何链接它们。对于其他Fortran库,我不知道如何链接它们。希望有人可以提供指导。

然后,你需要有一个Fortran源代码,比如将它命名为 my.f90 ,它包含如下内容:

  subroutine LIN(a,b)
     implicit none
     integer, parameter :: n=2, nrhs=1
     integer, parameter :: lda=n, ldb=n
     double precision :: a(lda,n), b(ldb,nrhs)
     integer :: info

     call DPOSV('U',n,nrhs,a,lda,b,ldb,info)

  end subroutine LIN

下一步是将Fortran代码编译为Mac中Windows / .so文件中的.dll文件(这就是所谓的为R创建共享对象)。要在Windows中编译代码,您需要安装Rtools和R.此外,R的路径应添加到系统变量的“路径”中。 (步骤:右键单击计算机图标 - &gt;属性 - >高级系统设置 - >环境变量 - &gt;在系统变量中查找并选择“路径” - >单击“编辑”并添加R的路径,例如,C:\Program Files\R\R-3.0.2\bin;)。现在,您已准备好编译代码。您需要以管理员身份打开R,切换到包含Fortran文件的目录,然后在R控制台中执行命令:

system('R CMD SHLIB my.f90')

您将看到共享对象 my.dll 是在目录下创建的。

最后一步是将共享对象加载到R中并运行它。按照我的例子,

dyn.load('my.dll') #load the shared object

a<-diag(c(1,2)) #prepare arguments *a* and *b* for the Fortran subroutine
b<-c(3,4)
.Fortran("LIN",a=as.double(a),b=as.double(b)) #call the Fortran subroutine

备注:您需要从R卸载共享对象,以便在R仍在运行时可以删除或编译它:

dyn.unload('my.dll')