在R中使用Fortran模块? [英] using a Fortran module in R?

查看:151
本文介绍了在R中使用Fortran模块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只要我没有在模块中使用它,我就可以在R中使用Fortran子例程。例如:

 <$ c 

隐式无
整数,intent(in):: darts
双精度,intent(out):: dartsscore
双精度: :x_coord,y_coord
integer ::得分,n
$ b $得分= 0
做n = 1,飞镖
随机号码(x_coord)
随机号码(y_coord)

如果((x_coord ** 2 + y_coord ** 2)<= 1.0d0)则
得分=得分+ 1
如果
结束(avepi,DARTS,ROUNDS)


dartsscore = 4.0d0 *得分/飞镖

结束子程序dboard

子程序pi隐式无
双精度,意图(out):: avepi
整数,意图(in):: DARTS,ROUNDS
整数:: MASTER,rank,i,n
整数,allocatable :: seed(:)
双精度n :: pi_est,homepi,pirecv,pisum

接口
子程序dboard(飞镖,dartsscore)
隐式无
整数,intent(in):: darts
双精度,意图(out):: dartsscore
结束子程序dboard
结束界面

!我们在连续运行中将其设置为零
等级= 0
!初始化随机数发生器
!我们确保每个任务的种子不同
调用random_seed()
调用random_seed(size = n)
allocate(seed(n))
seed = 12 + rank * 11
调用random_seed(put = seed(1:n))
解除分配(种子)

avepi = 0
do i = 0,ROUNDS-1
打电话dboard(飞镖,pi_est)
!计算pi在所有迭代中的平均值
avepi =((avepi * i)+ pi_est)/(i + 1)
end do
结束子程序pi


$ b

可以为R编译:

  R CMD SHLIB ./Fortran/Fpi.f90 

我可以在R中运行它:

  mypi < -  function(DARTS,ROUNDS){
dyn.load(./ Fortran / Fpi .so)
retvals < - .Fortran(pi,avepi = as.numeric(1),DARTS = as.integer(DARTS),ROUNDS = as.integer(ROUNDS))
返回(retvals $ avepi)
}

mypi(DARTS = 50000,ROUNDS = 10)

我想在模块中编写我的fortran子例程。我认为这是不可能的,但@roygvib和@francescalus提到它是在我以前的问题



你如何做附加绑定(c,name = ...)@roygvib提到的事情在那篇文章中?



谢谢!






 模块Fortranpi 
IMPLICIT NONE
包含
子程序dboard(飞镖,dartsscore)
隐式无
整数,意图(in)::飞镖
双精度,意图(out):: dartsscore
双精度:: x_coord,y_coord
integer ::得分,n

得分= 0
做n = 1,飞镖
来电随机号码(x_coord)
来电随机号码(y_coord)$ b $如果((x_coord ** 2 + y_coord ** 2)≤1.0d0)则b
,则
得分=得分+ 1
结束如果
结束做

dartsscore = 4.0d0 *得分/飞镖

结束子程序dboard

子程序pi(avepi,DARTS, ROUNDS)bind(C,name =pi_)
隐式none
双精度,intent(out):: avepi
整型,意图(in):: DARTS,ROUNDS
integer:MASTER,rank,i,n
整数,allocatable :: seed(:)
双精度:: pi_est,homepi,pirecv,pisum

接口
子程序dboard(飞镖,dartsscore)
隐式无
整数,意图(in)::飞镖
双精度,意图(out):: dartsscore
结束子程序dboard
结束界面

!我们在连续运行中将其设置为零
等级= 0
!初始化随机数发生器
!我们确保每个任务的种子不同
调用random_seed()
调用random_seed(size = n)
allocate(seed(n))
seed = 12 + rank * 11
调用random_seed(put = seed(1:n))
解除分配(种子)

avepi = 0
do i = 0,ROUNDS-1
打电话dboard(飞镖,pi_est)
!计算pi在所有迭代中的平均值
avepi =((avepi * i)+ pi_est)/(i + 1)
end do
结束子程序pi

结束模块Fortranpi

当我尝试使用Rstudio构建包时,出现以下错误:

  ==> R CMD INSTALL --no-multiarch --with-keep.source MyPi 

*安装到库'/home/ignacio/R/x86_64-pc-linux-gnu-library/3.2'
make:全部无法完成。
*安装*源*包'MyPi'...
** libs
安装到/home/ignacio/R/x86_64-pc-linux-gnu-library/3.2/MyPi/ libs
** R
**为延迟加载准备软件包
**帮助
***安装帮助索引
**构建软件包索引
* *测试是否可以加载已安装的软件包
library.dynam中的错误(lib,package,package.lib):
共享对象'Fortranpi.so'找不到
错误:加载失败
执行暂停
错误:加载失败
*删除'/home/ignacio/R/x86_64-pc-linux-gnu-library/3.2/MyPi'
*恢复以前的'/ home /ignacio/R/x86_64-pc-linux-gnu-library/3.2/MyPi'

退出状态1.

我相信问题可能是NAMESPACE

  useDynLib(Fpi)
exportPattern(^ [[:alpha:]] +)


解决方案

感谢@roygvib和@francescalus这是我的工作模块:

 模块Fortranpi 
IMPLICIT NONE
包含
子程序dboard(飞镖,dartsscore)
整数,意图(in) :: darts
double precision,intent(out):: dartsscore
double precision :: x_coord,y_coord
integer :: score,n

score = 0 $ ((x_coord ** 2 + y_coord ** 2))b $ b do n = 1,darts
call random_number(x_coord)
call random_number(y_coord)

= 1.0d0)然后
得分=得分+ 1
如果
结束

dartsscore = 4.0d0 *得分/飞镖

(c,name =pi_)
use,intrinsic :: iso_c_binding,只有:c_double,c_int
real(c_double),intent(out):: avepi
integer(c_int),intent(in):: DARTS,ROUNDS
integer :: MASTER,rank,i,n
int eger,allocatable :: seed(:)
双精度:: pi_est,homepi,pirecv,pisum

!我们在连续运行中将其设置为零
等级= 0
!初始化随机数发生器
!我们确保每个任务的种子不同
调用random_seed()
调用random_seed(size = n)
allocate(seed(n))
seed = 12 + rank * 11
调用random_seed(put = seed(1:n))
解除分配(种子)

avepi = 0
do i = 0,ROUNDS-1
打电话dboard(飞镖,pi_est)
!计算pi在所有迭代中的平均值
avepi =((avepi * i)+ pi_est)/(i + 1)
end do
结束子程序pi

结束模块Fortranpi


I am able to use a fortran subroutine in R as long as I don't have it inside a module.For example:

subroutine dboard(darts, dartsscore)
  implicit none
  integer, intent(in)           :: darts
  double precision, intent(out) :: dartsscore
  double precision              :: x_coord, y_coord
  integer                       :: score, n

score = 0
do n = 1, darts
  call random_number(x_coord)
  call random_number(y_coord)

  if ((x_coord**2 + y_coord**2) <= 1.0d0) then
  score = score + 1
  end if
end do

dartsscore = 4.0d0*score/darts

end subroutine dboard

subroutine pi(avepi, DARTS, ROUNDS)
  implicit none
  double precision, intent(out)   ::  avepi
  integer, intent(in)             ::  DARTS, ROUNDS
  integer                         ::  MASTER, rank, i, n
  integer, allocatable            ::  seed(:)
  double precision                ::  pi_est, homepi, pirecv, pisum

interface 
   subroutine dboard(darts, dartsscore)
      implicit none
      integer, intent(in)           :: darts
      double precision, intent(out) :: dartsscore
   end subroutine dboard
end interface

! we set it to zero in the sequential run
rank = 0
! initialize the random number generator
! we make sure the seed is different for each task
call random_seed()
call random_seed(size = n)
allocate(seed(n))
seed = 12 + rank*11
call random_seed(put=seed(1:n))
deallocate(seed)

avepi = 0
do i = 0, ROUNDS-1
  call dboard(darts, pi_est)
  ! calculate the average value of pi over all iterations
  avepi = ((avepi*i) + pi_est)/(i + 1)
end do
end subroutine pi    

Can be compiled for R with:

R CMD SHLIB ./Fortran/Fpi.f90

and I can run it in R with:

mypi <- function(DARTS, ROUNDS) {
  dyn.load("./Fortran/Fpi.so")
  retvals <- .Fortran("pi", avepi = as.numeric(1), DARTS =  as.integer(DARTS), ROUNDS =  as.integer(ROUNDS))
  return(retvals$avepi)
}

mypi(DARTS = 50000, ROUNDS = 10)

I would like to write my fortran subroutines inside a module. I thought this was not possible, but @roygvib and @francescalus mentioned it is in one of my previous questions

How do you do the "attaching bind("c",name=...)" thing that @roygvib mentioned in that post?

Thanks!


I made the changes suggested in the comments:

Module Fortranpi
IMPLICIT NONE
contains
subroutine dboard(darts, dartsscore)
  implicit none
  integer, intent(in)           :: darts
  double precision, intent(out) :: dartsscore
  double precision              :: x_coord, y_coord
  integer                       :: score, n

score = 0
do n = 1, darts
  call random_number(x_coord)
  call random_number(y_coord)

  if ((x_coord**2 + y_coord**2) <= 1.0d0) then
  score = score + 1
  end if
end do

dartsscore = 4.0d0*score/darts

end subroutine dboard

subroutine pi(avepi, DARTS, ROUNDS) bind(C, name="pi_")
  implicit none
  double precision, intent(out)   ::  avepi
  integer, intent(in)             ::  DARTS, ROUNDS
  integer                         ::  MASTER, rank, i, n
  integer, allocatable            ::  seed(:)
  double precision                ::  pi_est, homepi, pirecv, pisum

interface
   subroutine dboard(darts, dartsscore)
      implicit none
      integer, intent(in)           :: darts
      double precision, intent(out) :: dartsscore
   end subroutine dboard
end interface

! we set it to zero in the sequential run
rank = 0
! initialize the random number generator
! we make sure the seed is different for each task
call random_seed()
call random_seed(size = n)
allocate(seed(n))
seed = 12 + rank*11
call random_seed(put=seed(1:n))
deallocate(seed)

avepi = 0
do i = 0, ROUNDS-1
  call dboard(darts, pi_est)
  ! calculate the average value of pi over all iterations
  avepi = ((avepi*i) + pi_est)/(i + 1)
end do
end subroutine pi

end module Fortranpi

When I try to build the package with Rstudio I get these errors:

==> R CMD INSTALL --no-multiarch --with-keep.source MyPi

* installing to library ‘/home/ignacio/R/x86_64-pc-linux-gnu-library/3.2’
make: Nothing to be done for 'all'.
* installing *source* package ‘MyPi’ ...
** libs
installing to /home/ignacio/R/x86_64-pc-linux-gnu-library/3.2/MyPi/libs
** R
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
Error in library.dynam(lib, package, package.lib) : 
  shared object ‘Fortranpi.so’ not found
Error: loading failed
Execution halted
ERROR: loading failed
* removing ‘/home/ignacio/R/x86_64-pc-linux-gnu-library/3.2/MyPi’
* restoring previous ‘/home/ignacio/R/x86_64-pc-linux-gnu-library/3.2/MyPi’

Exited with status 1.

I believe the problem could be the NAMESPACE

useDynLib(Fpi)
exportPattern("^[[:alpha:]]+")

解决方案

Thanks to @roygvib and @francescalus this is my working module:

Module Fortranpi
IMPLICIT NONE
contains
subroutine dboard(darts, dartsscore)
  integer, intent(in)                    :: darts
  double precision, intent(out)          :: dartsscore
  double precision                       :: x_coord, y_coord
  integer                                :: score, n

score = 0
do n = 1, darts
  call random_number(x_coord)
  call random_number(y_coord)

  if ((x_coord**2 + y_coord**2) <= 1.0d0) then
  score = score + 1
  end if
end do

dartsscore = 4.0d0*score/darts

end subroutine dboard

subroutine pi(avepi, DARTS, ROUNDS) bind(C, name="pi_")
  use, intrinsic                         :: iso_c_binding, only : c_double, c_int
  real(c_double), intent(out)            ::  avepi
  integer(c_int), intent(in)             ::  DARTS, ROUNDS
  integer                                ::  MASTER, rank, i, n
  integer, allocatable                   ::  seed(:)
  double precision                       ::  pi_est, homepi, pirecv, pisum

! we set it to zero in the sequential run
rank = 0
! initialize the random number generator
! we make sure the seed is different for each task
call random_seed()
call random_seed(size = n)
allocate(seed(n))
seed = 12 + rank*11
call random_seed(put=seed(1:n))
deallocate(seed)

avepi = 0
do i = 0, ROUNDS-1
  call dboard(darts, pi_est)
  ! calculate the average value of pi over all iterations
  avepi = ((avepi*i) + pi_est)/(i + 1)
end do
end subroutine pi

end module Fortranpi

这篇关于在R中使用Fortran模块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆