f2py 没有按预期输出 inout

问题描述 投票:0回答:2

为什么 f2py 在处理 inout 参数时没有生成正确的包装器?

这是我的函数调用的示例:

io = 7.5
io, out1, out2, out3 = fortran_file.func(5, 2.5, False, io)

这在 Fortran 中可能是这样的(example.f):

subroutine func(inputA, inputB, inputC, ioD, outE, outF, outG)

integer inputA
real inputB
logical inputC

real ioD, outE, outF, outG
real localH

if(.not.inputC) then
   localH= ioD
else
   localH= inputB
endif

ioD= ioD + localH
outE= inputA + 10.5
outF= inputA + 5.5
outG= inputA + 1.5
return
end

默认情况下,f2py 将此处的所有内容标记为输入,即使这是一个基本示例。所以我使用以下方法创建文件签名:

python.exe -m numpy.f2py -m fortran_file -h sig_example.pyf example.f

我编辑 pyf 文件以添加正确的意图信息。然后我编译使用:

python.exe -m numpy.f2py -c sig_example.pyf example.f

但它一直抱怨 f2py func 只返回 3 个项目。

即使 io 显式使用

intent(inout)
,f2py 也不会返回它。

我使用 f2py 中的

--build-dir
选项来查看为包装器生成的 C 代码。 该文件在参数下列出了 io,但它说 in/outputrank-0 array(float,'f) 这告诉我它知道它应该是 inout,但我不明白为什么它把它标记为数组? 它也没有在“返回”下列出 io,这让我更加困惑。 关联的
Py_BuildValue
调用也不将 io 包含在参数列表中。

为什么看起来 inout 不应该被返回? 这就是 inout 的全部意义,对于某些文件来说这是必需的。

我意识到这整个问题是小众的,但我真的可以在这里使用一些帮助。有没有办法在Python内部指定参数意图?因为我的文件太多了,无法手动编辑签名。

python fortran f2py
2个回答
1
投票

intent(inout)
参数的工作方式与 Fortran 中类似。然而,在Python中,Python环境中的变量值是不可变的。 Fortran 函数将收到一个副本,它将修改其副本,然后 Python 将丢弃修改后的副本。

但是可变值可以放入容器中,例如 NumPy 数组。这意味着

import numpy as np
io = np.asarray([7.5])
out, out, out = fortran_file.func(5, 2.5, False, io)
print(io)

将打印

[15.]

使用函数修改的新值。


0
投票

@Vladimir F Героям слава 的帖子解决了我的问题。但是,它发布了如下警告:

DeprecationWarning:不推荐将 ndim > 0 的数组转换为标量,并且将来会出错。确保在执行此操作之前从数组中提取单个元素。 (已弃用 NumPy 1.25。)

还没有找到解决避免此警告的方法。

© www.soinside.com 2019 - 2024. All rights reserved.