由 R 调用时,Fortran 子例程不计算

Posted

技术标签:

【中文标题】由 R 调用时,Fortran 子例程不计算【英文标题】:Fortran subroutine is not calculating when called by R 【发布时间】:2020-07-16 08:05:40 【问题描述】:

我有大量数据,在一个 3D 数组中,所以我试图通过使用 Fortran 例程来加速 R 中的计算。下面的子程序由两个命令完美编译:

    gfortran -c -ffree-form file_name.f
    R CMD SHLIB file_name.f

这是我的子程序:

    subroutine saturation_vapour_pressure_from_temperature(temp,m,n,o,saturation_vapour_pressure)
    implicit none
    integer :: m,n,o
    integer :: x,y,t
    real, intent(in) ::temp(m,n,o)
    real, intent(out) :: saturation_vapour_pressure(m,n,o)
    real :: lvRv,To,eo
    saturation_vapour_pressure(m,n,o) = temp(m,n,o)
    LvRv= 5234.0
    To= 273.15
    eo= 0.6113
    do 15, t=1,o
        do 10, y=1,n
          do 5, x=1,m
          saturation_vapour_pressure(x,y,t) = eo * exp(LvRv*1/To - LvRv*1/temp(x,y,t))
 5          end do 
10         end do 
15       end do
     end subroutine saturation_vapour_pressure_from_temperature

我为输入分配了与输出相同的值,然后通过循环执行计算。但是它不起作用,尽管我有其他具有相同原理的子例程并且它们正在工作!这是 R 中的调用。

 temperature<-array(runif(12,273.15,300),dim = c(2,3,2))
 DIMn<-dim(temperature)
 #DIMn is the dimension of array
 dyn.load("saturation_vapour_pressure_from_temperature.so")      
result<- array(.Fortran("saturation_vapour_pressure_from_temperature",temp=as.numeric(temperature),
                      m=as.integer(DIMn[1]),
                      n=as.integer(DIMn[2]),
                      o=as.numeric(DIMn[3]),saturation_vapour_pressure=as.numeric(temperature))$saturation_vapour_pressure,
             dim = DIMn)

当我检查值时

   $ all(temperature==result)
     [1] TRUE

【问题讨论】:

“它不工作”是什么意思?它是否崩溃,是否给出错误的输出,是否抛出异常(我假设 R 有异常)? 完全没有错误,只是没有计算。它不会改变输出数组值@chw21 您是否尝试过将saturation_vapour_pressure 声明为real, intent(out) :: saturation_vapour_pressure(m, n, o) 我已经试过了!还是不计算,也许是数学表达式?我对 FORTRAN 不太熟悉 请在 R 中显示完整的minimal reproducible example,我们可以看到不正确的输出。并显示您正在编译的 Fortran 代码的准确副本。您现在显示的代码无法编译,因为未声明 s 【参考方案1】:

很遗憾,我不太熟悉 R,但我可以给你一些想法:

    那里的代码不应该编译,因为你没有声明变量s。我怀疑第一个 do 循环应该使用 t,而不是 s 作为迭代器,但你会更清楚这一点。 有没有可能是编译失败而你使用的是旧版本?

    您不需要使用标签。只需输入

    do t = 1, o
        do y = 1, n
            do x = 1, m
                saturation_vapour_pressure(x,y,t) = eo * exp(LvRv*1/To - LvRv*1/temp(x,y,t))
            end do
        end do
    end do
    

【讨论】:

以上是关于由 R 调用时,Fortran 子例程不计算的主要内容,如果未能解决你的问题,请参考以下文章

如何在由 MPI 并行化的 fortran 中调用子例程?

C++ 从 dll 调用 FORTRAN 子例程

从 C++ 调用带有可选参数的 Fortran 子例程

从 C++ 调用带有可选参数的 Fortran 子例程

从 c++ 调用 FORTRAN 子例程会产生非法参数值

fortran 模块的子例程名称冲突