Can't compile subroutine with array output with f2py

时间:2017-04-10 02:30:54

标签: fortran f2py

I have a subroutine that I'm writing in Fortran to be compiled with f2py and the compilation is failing. I won't post the full subroutine here but a MWE is:

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

This fails with

/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)

Which apparently means that f2py doesn't accept allocatable output arrays. So I tried to circumvent this problem by passing the shape Vars as an array, so vCorr doesn't have to be allocated, which led me to this code

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

Which fails with this error

/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;

After some look around I came across this page which leads me to believe (even though I'm using f2py2, and not 3) that this is a bug.

Any suggestions around this?

1 个答案:

答案 0 :(得分:0)

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

在另一个示例中,f2py无法理解dims(1),dims(2)中的vCorr(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也更好。