无法使用 f2py 编译带有数组输出的子例程

Can't compile subroutine with array output with f2py

我有一个要用 f2py 编译的 Fortran 编写的子例程,但编译失败了。我不会在这里 post 完整的子程序,但是 MWE 是:

SUBROUTINE mwe(Vars, nxc, nyc, vCorr)
IMPLICIT NONE
real(kind=8), dimension(:,:,:,:) :: Vars
integer :: nxc, nyc
integer :: dims(4), nv, nt, nx, ny
real(kind=8), intent(out), allocatable :: vCorr(:,:,:,:)

dims = shape(Vars)
nv=dims(1)
nt=dims(2)
nx=dims(3)
ny=dims(4)
allocate(vCorr(nv, nt, 2*nxc+1, 2*nyc+1))

print*,size(vCorr)
print*,size(Vars)
END SUBROUTINE

这失败了

/tmp/tmpy43di1/src.linux-x86_64-2.7/mwe-f2pywrappers.f:30:31:

       call mwe(vars, nxc, nyc, vcorr)
                               1
Error: Actual argument for ‘vcorr’ must be ALLOCATABLE at (1)

这显然意味着 f2py 不接受可分配的输出数组。所以我试图通过将形状 Vars 作为数组传递来规避这个问题,所以 vCorr 不必分配,这让我得到了这段代码

SUBROUTINE mwe(Vars, nxc, nyc, dims, vCorr)
IMPLICIT NONE
real(kind=8), dimension(:,:,:,:) :: Vars
integer :: nxc, nyc
integer :: dims(4)
real(kind=8) :: vCorr(dims(1),dims(2),2*nxc+1,2*nyc+1)

print*,size(vCorr)
print*,size(Vars)
END SUBROUTINE

失败并出现此错误

/tmp/tmp0Y1S9x/src.linux-x86_64-2.7/mwemodule.c:296:39: error: called object ‘dims’ is not a function or function pointer
   vcorr_Dims[0]=dims(1),vcorr_Dims[1]=dims(2),vcorr_Dims[2]=2 * nxc + 1,vcorr_Dims[3]=2 * nyc + 1;

环顾四周后,我遇到了 this page 这让我相信(即使我使用的是 f2py2,而不是 3)这是一个错误。

对此有什么建议吗?

在第一个示例中,f2py 不支持可分配的数组参数。它们不适合 Python 数组。

在另一个例子中,f2py 不理解 vCorr(dims(1),dims(2) 中的 dims(1),dims(2)。它不支持那里的数组元素。这是一个错误。

解决方法是对维度使用标量变量

SUBROUTINE mwe(Vars, nxc, nyc, dim1, dim2, vCorr)
  integer, parameter :: dp = kind(1.d0)
  real(dp), dimension(:,:,:,:) :: Vars
  integer :: nxc, nyc
  integer :: dim1, dim2
  real(dp) :: vCorr(dim1,dim2,2*nxc+1,2*nyc+1)

注:kind=8丑陋且不可移植。真正的含义不是 8 字节,尽管在许多编译器中它确实对应于 8 字节实数。但不是全部。即使是旧的 double precision 也更好。