【问题标题】:f2py - order of function arguments messed upf2py - 函数参数的顺序搞砸了
【发布时间】:2016-02-20 20:58:19
【问题描述】:

我编写了一个小的 Fortran 函数,并使用 f2py 在 Python 中将参数传递给它。不知何故,参数的顺序在传输过程中被弄乱了,我不知道为什么。

Fortran 函数的相关部分(位于名为 calc_density.f95 的文件中):

subroutine calc_density(position, nparticles, ncells, L, density)

implicit none

integer, intent(in) :: nparticles
integer, intent(in) :: ncells
double precision, intent(in) :: L
double precision, dimension(nparticles), intent(in) :: position
double precision, dimension(ncells), intent(out) :: density

double precision :: sumBuf, offSum
integer :: pLower, pUpper, pBuf, numBuf, last, idx
double precision, dimension(nparticles) :: sorted

 print *, 'Fortran ', 'position length ', size(position), &
  'density length ', size(density), 'nparticles ', nparticles, &
  'ncells ', ncells, 'L ', L

end subroutine calc_density

f2py 编译命令:

f2py -c --fcompiler=gnu95 -m fortran_calc_density calc_density.f95

Python代码的相关部分:

from fortran_calc_density import calc_density as densityCalc
from numpy import array, float64

def calc_density(position, ncells, L):
  arg = array(position, dtype = float64, order = 'F')
  nparticles = len(position)
  density = densityCalc(position, nparticles,  ncells, L)

  print 'Python ', 'position length ', len(position), 'density length',  len(density), 'nparticles ', nparticles, 'ncells ', ncells, 'L ', L   
  return density

显示所有传输变量不匹配的屏幕输出示例:

Fortran position length           12 density length          100 nparticles           12 ncells          100 L    20.000000000000000    
Python  position length  100 density length  100 nparticles  100 ncells  20 L  12.5663706144

Python 的打印输出显示了值,除了密度数组的长度,它应该等于 ncells,因此根据 Fortran 函数的设计,它应该等于 20。 然而,Fortran 值完全关闭,因此在传输过程中一定发生了一些事情,从而扰乱了周围的参数。

我在这里做错了什么?

【问题讨论】:

  • 为避免任何混淆:您能否仔细检查一下 Fortran 行是否在 Python 行 之后打印,即使密度计算在 Python 打印 之前 被调用声明?
  • 对不起,那是误导。实际上,首先打印的是 Fortran 打印。 Python 和 Fortran 函数实际上是在循环中调用的,因此会连续打印到屏幕上。我刚刚选择了该输出的两个后续打印来显示该问题。结果在循环之间不会改变。现在已经更正了帖子,所以它显示了正确的打印顺序。

标签: python fortran f2py


【解决方案1】:

查看 f2py 创建的文档(使用 gfortran-5.3.0 编译):

>>> print calc_density.__doc__

Wrapper for ``calc_density``.

Parameters
----------
position : input rank-1 array('d') with bounds (nparticles)
ncells : input int
l : input float


Other Parameters
----------------
nparticles : input int, optional
    Default: len(position)

Returns
-------
density : rank-1 array('d') with bounds (cells)

您可以看到nparticles 是可选的(这是由f2py 自动完成的)并且默认值为len(position)。默认情况下,可选参数被移动到参数列表的末尾。因此,在您的调用中,最后一个参数被解释为nparticles

您可以将nparticles 留在函数调用之外,也可以将其移至最后一个参数。两者:

density = densityCalc(position, ncells, L)
density = densityCalc(position, ncells, L, nparticles)

应该会产生正确的结果。如果要保持fortran子程序参数列表的顺序,也可以使用关键字:

density = densityCalc(position=position, nparticles=nparticles, ncells=ncells, l=L)

请注意,fortran 不区分大小写,因此关键字必须为小写 l = L

【讨论】:

  • 谢谢!现在谜团已解开,一切正常:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-06
  • 2018-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-03
相关资源
最近更新 更多