f2py error when declaring array size - ValueError: 3-th dimension must be 3 but got 0 (not defined)

57 Views Asked by At

I am using f2py for a function. I call it in python with

def minline(box, line):
    return my_funcs_f.minline(box, line)

where my_funcs_f is my f2py library of functions. The start of the fortran subroutine I call is

subroutine minline(box, line, myout)
  ! Inputs
  real(8), intent(in) :: line(:,:)
  real(8), intent(in) :: box(:,:,:,:)
  
  integer :: i, j, k
  real(8) :: dist(size(line,1),3)

  ! Outputs
  real(8), intent(out) :: myout(size(box,1),size(box,2),size(box,3))

  ! do a bunch of stuff here...

My variables box and line will always have their last dimension with size 3. I tried defining the box and line sizes in the python part of the code, then inputting it as inputs to the fortran subroutine. For example:

def minline(box, line):
    l, m, n = box.shape[:-1]
    p = line.shape[0]
    return my_funcs_f.minline(l, m, n, p, box, line)

and

subroutine minline(l, m, n, p, box, line, myout)
  ! Inputs
  integer :: l, m, n, p
  real(8), intent(in) :: line(p,3)
  real(8), intent(in) :: box(l,m,n,3)
  
  integer :: i, j, k
  real(8) :: dist(p,3)

  ! Outputs
  real(8), intent(out) :: myout(l,m,n)

  ! do a bunch of stuff here...

If I do this I get the error

File "/path/to/functions/file.py", line 1933, in func_calling_minline
    minlineOutput = minline(box_cart, field_line)
  File "/path/to/functions/file.py", line 1946, in minline
    return my_funcs_f.minline(l, m, n, p, box, line)
ValueError: 3-th dimension must be 3 but got 0 (not defined).

The same error persists if I try altering my code to only adjust box, where as the error if I adjust line only is

File "/path/to/functions/file.py", line 1933, in func_calling_minline
    minelineOutput = minline(box_cart, field_line)
  File "/path/to/functions/file.py", line 1947, in minline
    return my_funcs_f.minline(p, box, line)
ValueError: too many axes: 4 (effrank=4), expected rank=2

Presumably, I can't define array sizes with the inputs to a function (subroutine), is that right? If so, is there a way I should do this? Is it even neccessary? I don't work with fortran much, and it feels like I should define the array sizes, but does it not matter? I know I can't use real(8), intent(in) :: line(:,3), for example.

I'm also calling this in multiprocessing.pool with the starmap method, if that makes things more complicated (although I don't think it should).

Thanks

0

There are 0 best solutions below