Can f2py be used to call Fortran code with declarations of the form real(kind=wp)
from Python? For example, calling the subroutines in the Fortran module
module foo
implicit none
private
public :: sum_absolute, twice
integer, parameter :: wp = kind(1.0d0)
contains
pure subroutine sum_absolute(n, x, sum_abs_x)
! return the sum of the absolute values of x
integer , intent(in) :: n
double precision, intent(in) :: x(n)
double precision, intent(out) :: sum_abs_x
!f2py intent(in) n
!f2py intent(in) x(n)
!f2py intent(out) sum_abs_x
sum_abs_x = sum(abs(x))
end subroutine sum_absolute
!
pure subroutine twice(n, x, twice_x)
integer , intent(in) :: n
double precision, intent(in) :: x(n)
double precision, intent(out) :: twice_x(n)
!f2py intent(in) n
!f2py intent(in) x(n)
!f2py intent(in,out) twice_x(n)
twice_x = 2*x
end subroutine twice
end module foo
with the Python script
import numpy as np
from bar import foo
x = np.array([-10, 20, -30], dtype=np.float64)
twice_x = np.zeros(len(x))
foo.twice(x, twice_x)
print("x, sum_absolute(x), twice(x) =", x, foo.sum_absolute(x), twice_x)
using the commands
f2py -c -m bar sub.f90 --compiler=mingw32
python xsub.py
works on Windows, giving output
x, sum_absolute(x), twice(x) = [-10. 20. -30.] 60.0 [-20. 40. -60.]
However, when the Fortran module has variables declared with a parameterized kind instead of using double precision
,
module foo
implicit none
private
public :: sum_absolute, twice
integer, parameter :: wp = kind(1.0d0)
contains
pure subroutine sum_absolute(n, x, sum_abs_x)
! return the sum of the absolute values of x
integer , intent(in) :: n
real(kind=wp), intent(in) :: x(n)
real(kind=wp), intent(out) :: sum_abs_x
!f2py intent(in) n
!f2py intent(in) x(n)
!f2py intent(out) sum_abs_x
sum_abs_x = sum(abs(x))
end subroutine sum_absolute
!
pure subroutine twice(n, x, twice_x)
integer , intent(in) :: n
real(kind=wp), intent(in) :: x(n)
real(kind=wp), intent(out) :: twice_x(n)
!f2py intent(in) n
!f2py intent(in) x(n)
!f2py intent(in,out) twice_x(n)
twice_x = 2*x
end subroutine twice
end module foo
The output of
x, sum_absolute(x), twice(x) = [-10. 20. -30.] -10.0 [0. 0. 0.]
is wrong.