在 Fortran 模块中使用全局常量时,我发现 f2py 有一些奇怪的行为。
假设我有一个文件 test.f90,它看起来像
module test1
real, parameter :: a = 12345.
end module test1
module test2
real*8, parameter :: a = 6789.
end module test2
如果我用 f2py 包装它,使用
f2py -c -m mymod test.f90
正在运行
python -c "import mymod as m; print m.test1.a; print m.test2.a"
我明白了
12345.0
6789.0
这几乎是您所期望的。 real 和 real*8 语句的行为方式相同。
对于我的实际项目,我需要使用编译器标志编译我的 Fortran 代码,指定显式使用 double 。在 Fortran 中,这工作正常。当我将上面的代码编译为
f2py --f90flags="-fdefault-double-8 -fdefault-integer-8 -fdefault-real-8" -c -m mymod test.f90
我得到结果
python -c "import mymod as m; print m.test1.a; print m.test2.a"
0.0
6789.0
这其实很奇怪。全局变量在第一种情况下没有初始化,它的值为零。这是一个错误还是有不同的方法来指定 f2py 中 double 的显式处理?
请您参考如下方法:
您没有指定“显式使用 double ”——我认为您指定的是“隐式使用 double ”,而 numpy/f2py 无法知道数据类型。在这种情况下,f2py 很可能猜测数据类型是 float32,因此实际上只解释了(64 位)参数的前 32 位。如果将 double 字传递给需要 float 的函数,您会看到相同的效果:
program main
real*8 :: foo
foo = 12345.
call printme(foo)
end program
subroutine printme(foo)
real foo
print*, foo
end subroutine printme
编译运行:
gfortran test2.f90
./a.out #prints 0.00000
这里的要点是您希望 f2py 知道如何解释 Fortran 代码以及如何解释特定编译器的命令行参数。我们可能会争辩说,这种类型的支持对于一小部分编译器很有用——不幸的是,f2py 目前不支持它。
您需要将所有参数和参数声明为特定类型,并且在命令行上更改它们可能会导致您在上面看到的各种错误。
