9

我无法让 f2py 在用于定义输入数组维度的单独子例程中引用来自模块的参数。即参数在模块中定义:

! File: testmod.f90
MODULE testmod
INTEGER, PARAMETER :: dimsize = 20
END MODULE testmod

并且参数 dimsize 需要在另一个文件的子例程(不包含在模块中)中引用,这将是我的 python 模块的入口点:

! File testsub.f90
SUBROUTINE testsub(arg)
USE testmod
REAL, INTENT(IN) :: arg(dimsize)
END SUBROUTINE testsub

我这样编译:

f2py -m testmod  -h testmod.pyf testsub.f90
pgf90 -g -Mbounds -Mchkptr -c -fPIC testmod.f90 -o testmod.o
pgf90 -g -Mbounds -Mchkptr -c -fPIC testsub.f90 -o testsub.o
f2py -c testmod.pyf testmod.o testsub.o

但得到这个错误:

testmodmodule.c: In function 'f2py_rout_testmod_testsub':
testmodmodule.c:180: error: 'dimsize' undeclared (first use in this function)

我已尝试修改 testsub.g90 以包含以下指令,正如其他帖子所建议的那样:

SUBROUTINE testsub(arg)
USE testmod
!f2py integer, parameter :: dimsize
REAL, INTENT(IN) :: arg(dimsize)
END SUBROUTINE testsub

但无济于事。我需要将子程序与模块分开。

如何让 f2py 正确解析变量dimsize

TIA

4

2 回答 2

3

这个问题已经有很长时间没有任何活动了,但我发现了这个问题,所以我想我会把它发布给其他有这个问题的人。问题是,虽然 Fortran 代码完全有效,但 F2PY 生成的 C 包装器在检查数组的大小是否正确时并不知道 dimsize 是什么(在 C 包装器中,它被封装在某种模块结构中)。

只需更改此代码:

SUBROUTINE testsub(arg)
USE testmod
!f2py integer, parameter :: dimsize
REAL, INTENT(IN) :: arg(dimsize)
END SUBROUTINE testsub

对此:

SUBROUTINE testsub(arg)
USE testmod
!f2py integer, intent(aux) :: dimsize
REAL, INTENT(IN) :: arg(dimsize)
END SUBROUTINE testsub

这将“在 F2PY 生成的包装函数中定义辅助 C 变量”。正如Scipy 文档所说,这是“用于保存参数值以便可以在其他变量的初始化表达式中访问它们”。

我没有用你的代码测试过这个,但我已经用我遇到的类似情况测试过它。

于 2016-04-06T00:50:26.167 回答
1

虽然我没有测试过它,但我认为您几乎可以使用原始代码获得它。我们对我们的一些代码做了类似的事情,但使用的是 gfortran。

您不需要f2pytestmod.f90 文件。你应该把它编译成一个目标文件,就像这是普通的 Fortran 一样:

pgf90 -g -Mbounds -Mchkptr -c -fPIC testmod.f90 -o testmod.o

然后你应该能够将你的 testsub.f90 编译成一个 python 可用的模块:

f2py --fcompiler=pgf90 --f90flags="-g -Mbounds -Mchkptr" -c testsub.f90 -m testsub testmod.o

那应该构建一个 testsub.so 或等效的,让你import testsub然后testsub.testsub(my_arg)在 python 中。

于 2013-11-21T06:15:48.927 回答