我正在使用f2py进行尝试。我对NumPy内置类型和Fortran 90类型有些困惑。当与Python交互时,似乎我只能在Fortran 90中使用单精度实数。让我用一个例子来说明:
假设我有这个Fortran 90模块test.f90,希望使用f2py编译并在Python中导入:
module test
implicit none
integer, parameter :: sp = selected_real_kind(6,37) ! single precision
integer, parameter :: dp = selected_real_kind(15,307) ! double precision
real(sp) :: r_sp = 1.0
real(dp) :: r_dp = 1.0_dp
end module
我这样编译:
f2py -c -m test test.f90
然后在Python中使用:
>>> import test
>>> test.test.r_sp
array(1.0, dtype=float32)
>>> test.test.r_dp
array(1.0)
换句话说,看起来f2py不接受双精度。当从Python传递输入到Fortran 90子例程时,这变得更加棘手。假设我将我的模块扩展为:
module test
implicit none
integer, parameter :: sp = selected_real_kind(6,37) ! single precision
integer, parameter :: dp = selected_real_kind(15,307) ! double precision
real(sp) :: r_sp = 1.0
real(dp) :: r_dp = 1.0_dp
contains
subroutine input_sp(val)
real(sp), intent(in) :: val
real(sp) :: x
x = val
write(*,*) x
end subroutine
subroutine input_dp(val)
real(dp), intent(in) :: val
real(dp) :: x
x = val
write(*,*) x
end subroutine
end module
f2py -c -m test test.f90
Python
>>> import test
>>> test.test.input_sp(array(1.0,dtype=float32))
1.0000000
>>> test.test.input_sp(array(1.0,dtype=float64))
1.0000000
>>> test.test.input_dp(array(1.0,dtype=float32))
-1.15948430791165406E+155
>>> test.test.input_dp(array(1.0,dtype=float64))
-1.15948430791165406E+155
看起来好像从Python发送的任何输入变量都必须声明为单精度。这是f2py已知的问题吗?
另外,作为后续问题:从sp转换为dp可以按以下方式完成:
subroutine input_sp_to_dp(val)
real(sp), intent(in) :: val(2)
real(dp) :: x(2)
x = val
write(*,*) x
end subroutine
但我想知道这是否与编译器有关?我能否期望上面的子程序在任何架构上的任何编译器上都能正常运行?在测试时,我使用gfortran进行了所有上述示例。