f2py:模块中常量的奇怪行为

时间:2013-06-11 16:42:51

标签: python global-variables fortran f2py

在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

这几乎是你所期待的。真实和真实* 8语句的行为方式相同。

对于我的实际项目,我需要使用编译器标志编译我的Fortran代码,指定双精度的显式用法。在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中双精度的显式处理?

2 个答案:

答案 0 :(得分:1)

你没有指定“显式使用双精度” - 我认为你指的是“隐式使用双精度”而numpy / f2py无法知道数据类型。在这种情况下,f2py可能猜测数据类型是float32,因此实际上只解释了(64位)参数的前32位。如果将双精度数传递给期望浮点函数的函数,则可以看到相同的效果:

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不支持它。

您需要将所有参数和参数声明为特定类型,并在命令行中更改它们可能会导致您在上面看到的各种错误。

答案 1 :(得分:0)

到目前为止我找到了一个解决方法。问题是,当提供适当的双精度编译器标志时,f2py无法识别它应该将fortran real映射到C类型double

解决方案是明确告诉f2py如何映射不同的数据类型。这可以通过创建文件.f2py_f2cmap来实现,该文件包含指定数据类型映射的python字典。有关详细信息,请参阅here

在我的情况下,以下条目解决了问题

{'real':{'':'double'},'integer':{'':'long'},'real*8':{'':'double'}}