【问题标题】:Passing variables to Fortran from python causes wrong values从 python 将变量传递给 Fortran 会导致错误的值
【发布时间】:2018-11-05 09:35:42
【问题描述】:

基于此minimal example,我想使用 Python 和 Fortran 子例程操作 Fortran 模块的变量。请看下面的例子:

vars.f90

module vars
implicit none
real(kind=selected_real_kind(p=15))      :: fk(10)
end module vars

sub.f90

subroutine sub
    use vars
    print *, "sub: fk(1) = ", fk(1)
    print *, "adding 1 to fk(1)"
    fk(1) = fk(1) + 1
    print *, "fk(1) = ", fk(1)
end

mytest.f90

include "vars.f90"
include "sub.f90"

使用以下命令和 gfortran 完成编译:

f2py -c -m mytest mytest.f90

最后,这是在 Python 3.6.5 控制台中重现问题的测试用例:

>>> import mytest
>>> mytest.vars.fk[1]
0.0
>>> mytest.vars.fk[1]=1.5000
>>> mytest.vars.fk[1]
1.5
>>> mytest.sub()
 sub: fk(1) =   0.12500000000000000     
 adding 1 to fk(1)
 fk(1) =    1.1250000000000000     
>>> mytest.vars.fk[1]
1.890625
>>> 

在我看来,fk(1) 最终应该是 2.5。但不幸的是,尽管通过 python 控制台直接访问变量显示了正确的值,但 Fortran 错误地读取了子例程中的变量。修改变量后,python控制台也会显示错误的数字。

有任何建议或建议来解决/解释这种行为吗?我很感激任何帮助!谢谢!

P.S.:首先我认为这取决于 Python 和 Fortran 处理数组的方式不同(Python 从索引 0 开始,Fortran 从索引 1 开始),但这不是错误。 mytest.vars.fk[0] 在调用子程序后不被修改(初始值为 0.0)。

【问题讨论】:

标签: python fortran f2py


【解决方案1】:

代码有两个问题:

  1. 您已注意到的索引问题。您仍然需要在 Python 中访问 fk[0] 以获得所需的行为。

  2. 使用selected_real_kind(p=15) 表示种类规范。请参阅FAQ of F2PY 和相关的SO answer

目前,f2py 将您的变量视为默认实变量(此处为 32 位)而不是双精度。你可以通过创建一个文件.f2py_f2cmap(在当前工作目录中)来修复它,内容如下:

{'real':{'selected_real_kind(p=15)': 'double'}}

这将为您的参数选择“double”作为相应的 C 类型。不幸的是,F2PY 无法检测现代 Fortran 类型。

我将此标记为与f2py: Specifying real precision in fortran when interfacing with python? 重复,但这里也存在索引问题。让我们看看其他人的想法。

【讨论】:

  • 感谢@Pierre 的提示!不幸的是,他们没有解决我的问题。我用 .f2py_f2cmap 重新编译了 mytest,并在 python 控制台中使用了 [0] 索引。 >>> mytest.vars.fk[0]=1.2 >>> mytest.vars.fk[0] 1.2 >>> mytest.sub2() sub2: fk(1) = 5.2718332951556110E-315 adding 1 to fk(1) fk = 1.0000000000000000 >>> mytest.vars.fk[0] 0.0 行为还是一样。
  • 你重启控制台了吗?
  • 另外,“硬编码”类型违背了使用selected_real_kind 的想法 :-) 你能提供更多关于你的平台的信息吗? (编译器版本、Python、NumPy)。我测试了我发布的解决方案顺便说一句,它按你的预期工作,这就是我要求更多细节的原因。
  • 是的,我重新启动了控制台。好吧,我不知道。我不是本地 Fortran 程序员,我尝试包装一个巨大的 Fortran 程序来处理它。 GNU Fortran (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0、Python 3.6.5 (Anaconda Distro) 与 GCC 7.2.0 和 Numpy '1.14.3'
  • 这里一个可能的问题是 Anaconda 的编译器和您的系统编译器不匹配。你安装过 Anaconda 的 gcc 和 gfortran 吗? conda install gcc.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-26
  • 1970-01-01
  • 2017-11-02
  • 2020-10-10
相关资源
最近更新 更多