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:]]+")
See Question&Answers more detail:
os