在R中高效调用F95:使用.Fortran或.Call?

时间:2015-04-15 09:06:14

标签: c r dll fortran

我正在编写一些R模拟代码,但希望利用Fortran的swift线性代数库来替换核心迭代循环。到目前为止,我主要关注使用.Fortran调用链接的F95子例程的明显选项;我想我应该优化内存使用(我传递非常大的数组)并设置DUP=FALSE但是我在手册中读到了关于这种方法的危险性以及它在R 3.1.0中的折旧和R 3.2中的禁用的警告0.0。现在手册建议切换到.Call,但此功能本身不提供Fortran支持。

我的谷歌搜索已经产生了a stackoverflow question,它探索了一种将Fortran子程序通过C代码与使用.Call调用它的方法。在我看来,这种事情可能像魅力或诅咒一样起作用。因此,我的问题是:

  1. 旨在提高速度和稳健性,通过.Fortran.Call致电Fortran有哪些风险和好处?
  2. 使用.Call调用Fortran子例程是否有更优雅/更有效的方式?
  3. 是否还有其他选择?

2 个答案:

答案 0 :(得分:2)

以下是我对这种情况的看法:

.Call是通常首选的界面。它直接为您提供了指向底层R数据对象(SEXP)的指针,因此您决定进行所有内存管理。如果需要,您可以尊重NAMED字段并复制数据,或忽略它(如果您知道您不会修改数据,或者由于其他原因而感到很舒服)

.Fortran尝试从R SEXP对象自动提供适当的数据类型到Fortran子例程;但是,它的使用通常是不鼓励的(原因并不完全清楚,说实话)

您应该从C / C ++例程中调用编译的Fortran代码。给定名为fortran_subroutine的Fortran子例程,您应该能够在C / C ++代码中提供前向声明,例如: (注意:你需要一个领先的extern "C" C ++代码):

void fortran_subroutine_(<args>);

请注意函数名称的尾随下划线 - 这是Fortran编译器(我熟悉的,例如gfortran)默认情况下“破坏”符号名称的方式,因此可用的符号将具有尾随下划线。

此外,您需要确保选择的<args>映射到相应的C类型到相应的Fortran类型。幸运的是,R-exts提供了这样一个表格。

最后,R R CMD build会自动促进R包的编译+链接过程。因为我显然是一个贪婪的惩罚,我produced an example package应该提供足够的信息让你了解绑定在那里是如何工作的。

答案 1 :(得分:2)

3。共有其他选择吗?是

R包 dotCall64 可能是一个有趣的选择。它提供.C64(),它是外国功能接口的增强版本,即.C().Fortran()

接口.C64()可用于接口Fortran和C / C ++代码。它

  • .C().Fortran()的用法类似
  • 提供一种避免不必要的只读和只写参数副本的机制
  • 支持长向量(具有2 ^ 31-1个以上元素的向量)
  • 支持64位整数类型参数

因此,可以避免不必要的只读参数副本,同时避免将.Call()接口与C包装函数结合使用。

一些链接:

我是 dotCall64 垃圾邮件的作者之一。