在您的第一个示例中,我不知道您为什么说f2py似乎不接受双精度,test.test.r_dp
而 双精度却如此。一个显示带有小数点的值且没有显式dtype的numpy数组是一个双精度数组。
第二个示例显示了F2PY用处理类型定义的局限性kind=<kind>
。请参阅常见问题解答:http ://cens.ioc.ee/projects/f2py2e/FAQ.html#q-what-if-fortran-90-code-uses-type- spec-kind-kind
要查看发生了什么,请运行f2py test.f90 -m test
。我得到这个:
Reading fortran codes...
Reading file 'test.f90' (format:free)
Post-processing...
Block: test
Block: test
Block: input_sp
Block: input_dp
Post-processing (stage 2)...
Block: test
Block: unkNown_interface
Block: test
Block: input_sp
Block: input_dp
Building modules...
Building module "test"...
Constructing F90 module support for "test"...
Variables: r_dp sp r_sp dp
Constructing wrapper function "test.input_sp"...
getctype: "real(kind=sp)" is mapped to C "float" (to override define dict(real = dict(sp="<C typespec>")) in /Users/warren/tmp/.f2py_f2cmap file).
getctype: "real(kind=sp)" is mapped to C "float" (to override define dict(real = dict(sp="<C typespec>")) in /Users/warren/tmp/.f2py_f2cmap file).
getctype: "real(kind=sp)" is mapped to C "float" (to override define dict(real = dict(sp="<C typespec>")) in /Users/warren/tmp/.f2py_f2cmap file).
input_sp(val)
Constructing wrapper function "test.input_dp"...
getctype: "real(kind=dp)" is mapped to C "float" (to override define dict(real = dict(dp="<C typespec>")) in /Users/warren/tmp/.f2py_f2cmap file).
getctype: "real(kind=dp)" is mapped to C "float" (to override define dict(real = dict(dp="<C typespec>")) in /Users/warren/tmp/.f2py_f2cmap file).
getctype: "real(kind=dp)" is mapped to C "float" (to override define dict(real = dict(dp="<C typespec>")) in /Users/warren/tmp/.f2py_f2cmap file).
input_dp(val)
Wrote C/API module "test" to file "./testmodule.c"
Fortran 90 wrappers are saved to "./test-f2pywrappers2.f90"
请注意,它会将“ real(kind = sp)”和“ real(kind = dp)”都映射到C“ float”,这是单精度的。
将类型声明分别更改为“ real(kind = 4)”和“ real(kind = 8)”(或“ real * 4”和“ real * 8”)。
当然,这违背了使用的目的selected_real_kind
,对于某些编译器,对于单精度和双精度而言,4和8不是正确的KIND值。在这种情况下,使用gfortransp
为4和dp
8,因此可以正常工作。
告诉f2py如何处理这些声明。在f2py常见问题解答中对此进行了说明,这是上面显示的f2py输出中的“ getctype:…”消息中建议的方法。
在这种情况下,您将创建一个名为.f2py_f2cmap
(在运行f2py的目录中)的文件,其中包含以下行
dict(real=dict(sp='float', dp='double'))
然后f2py将对那些real(sp)
和real(dp)
声明做正确的事情。
它还可以重新排列代码:
module types
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
module input
contains
subroutine input_sp(val)
use types
real(sp), intent(in) :: val
real(sp) :: x
x = val
write(*,*) x
end subroutine
subroutine input_dp(val)
use types
real(dp), intent(in) :: val
real(dp) :: x
x = val
write(*,*) dp, val, x
end subroutine
end module