使用f2py从Python即时分配Fortran中的向量
我有一个在Python中调用的子程序,开头是这样的:
在Python中调用它的方式是:libomp.cic(pos,mpart,boxsize,dim,npart)
subroutine cic(pos,mpart,boxsize,dim,npart,mesh)
use omp_lib
implicit none
real*8 mpart
!f2py intent(in) :: mpart
real*8 boxsize
!f2py intent(in) :: boxsize
integer dim
!f2py intent(in) :: dim
integer*8 npart
!f2py intent(in) :: npart
real*8, dimension(0:dim-1,0:dim-1,0:dim-1) :: mesh
!f2py intent(out) :: mesh
real*8, dimension(npart,3) :: pos
!f2py intent(in) :: pos
运行Python脚本时出现错误:
error: (shape(pos,0)==npart) failed for 1st keyword npart: cic:npart=47099622
WARNING: Failure executing file: <test.py>
奇怪的是,当我把npart
设置为一个整数时,它可以正常工作,但它无法从Python接收npart
,也不能动态创建数组pos
。使用dim
时,mesh
可以正常工作,但pos
却不行,为什么呢?这和它们被调用的顺序有关系吗?
1 个回答
3
pos
被声明为 intent(in)
,这意味着在进入这个程序时,pos
应该已经被分配好内存。需要注意的是,这和在 Fortran 中使用自动数组是完全不同的,因为 pos
是一个虚拟参数。问题在于,由于 pos
是 intent(in)
,所以 f2py
会检查你传入的维度(mpart
)和它声明的维度,因为 npart
也应该是 intent(in)
。由于这两个维度不匹配,所以你会遇到错误。
换句话说,你有两个 intent(in)
的变量,而你传入的值不兼容。实际的解决方案取决于这个子程序应该做什么,以及这些虚拟参数的真正意图是什么。
如果 pos
确实是 intent(in)
,那么原则上你可以把 npart
改成 intent(hide)
,这样的话,numpy 会根据 pos
的分配维度来传递 npart
给你的子程序。例如,我相信它会被调用如下:
libomp.cic(pos,mpart,boxsize,dim)