F2PY - 从子程序访问模块参数

时间:2013-11-14 17:04:52

标签: python fortran f2py

我不能让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

2 个答案:

答案 0 :(得分:2)

很长一段时间以来,这个问题已经有了任何活动,但我想出了问题,所以我想我会把它发布给有此问题的其他人。问题是虽然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 docs所说,这是"保存参数值非常有用,以便可以在其他变量的初始化表达式中访问它们#34;。

我还没有使用您的代码对此进行测试,但我已经用类似的情况对其进行了测试。

答案 1 :(得分:1)

虽然我没有对它进行过测试,但是认为你差不多用原始代码了。我们为一些代码做了类似的事情,但是使用gfortran。

您不需要f2py testmod.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或者等价的,让你在python中import testsub然后testsub.testsub(my_arg)

相关问题