Use Fortran subroutine in R? Undefined symbol -
this follow to previous question. wrapped fortran code in module , compiles when run:
r cmd shlib ./fortran/fpi.f90
this fortran code:
module fpi implicit none contains subroutine pi(avepi, darts, rounds) 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, dboard ! set 0 in sequential run rank = 0 ! initialize random number generator ! make sure seed different 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 = 0, rounds-1 pi_est = dboard(darts) ! calculate average value of pi on iterations avepi = ((avepi*i) + pi_est)/(i + 1) end end subroutine pi double precision function dboard(darts) integer, intent(in) :: darts double precision :: x_coord, y_coord integer :: score, n score = 0 n = 1, darts call random_number(x_coord) call random_number(y_coord) if ((x_coord**2 + y_coord**2) <= 1.0d0) score = score + 1 end if end dboard = 4.0d0*score/darts end function end module fpi
i'm trying run in r:
mypi <- function(darts, rounds) { dyn.load("./fortran/fpi.so") retvals <- .fortran("pi", darts = as.integer(darts) , rounds = as.integer(rounds), avepi = as.numeric(1)) return(retvals$avepi) } mypi(darts = 50000, rounds = 10)
and error:
error in dyn.load("./fortran/fpi.so") : unable load shared object '/home/ignacio/local/projects/pi/./fortran/fpi.so': /home/ignacio/local/projects/pi/./fortran/fpi.so: undefined symbol: dboard_
your problem comes down declaration of dboard
:
double precision :: pi_est, homepi, pirecv, pisum, dboard
here saying dboard
external function, rather module procedure. explains why there symbol dboard_
coming play. want remove that:
double precision :: pi_est, homepi, pirecv, pisum
and instead rely, in pi
on module procedure-ness of dboard
: pi
knows without declaration.
now, beyond that, because pi
in module there going name mangling going on subroutine itself. i'd solve problem making pi
(c) interoperable procedure.
module fpi implicit none contains subroutine pi(avepi, darts, rounds) bind(c) use, intrinsic :: iso_c_binding, : c_double, c_int real(c_double), intent(out) :: avepi integer(c_int), intent(in) :: darts, rounds ...
and using .c
rather .fortran
.
you can keep pi
, dboard
in module, , latter needn't interoperable.
Comments
Post a Comment