从子程序访问模块参数
我不能让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
这个问题已经有很长时间了,但我发现了这个问题,所以我想我会将它发布给有此问题的其他人。 问题是,虽然Fortran代码是完全有效的,但由F2PY生成的C封装器在检查数组是否正确(在C封装器中,封装在某种模块结构中)时不知道dimsize是什么。
只需更改此代码:
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文档所说,这是“对于保存参数值很有用,以便可以在其他变量的初始化表达式中访问它们”。
我没有用你的代码测试过这个,但是我测试过它和我有类似的情况。
虽然我还没有测试过,但我想你几乎已经把它与你的原始代码一起使用了。 我们为我们的一些代码做了类似的事情,但使用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或等价的,让你import testsub
,然后在python中testsub.testsub(my_arg)
。