I have the following Fortran source code intended to be compiled with f2py
to be used by Numpy/Python.
subroutine get_value(ts, c_open)
implicit none
! INPUT PARAMETERS
integer(kind=4), intent(in) :: ts(:)
! OUTPUT PARAMETERS
integer(kind=4), intent(out) :: c_open
! SIMULATED CALCULATION
c_open = ts(1)
end subroutine
subroutine get_value_range(ts, a, b, c_open)
implicit none
! INPUT PARAMETERS
integer(kind=4), intent(in) :: ts(:)
integer(kind=4), intent(in) :: a
integer(kind=4), intent(in) :: b
! OUTPUT PARAMETERS
! - AGGREGATED VALUES TO RETURN
integer(kind=4), intent(out) :: c_open(b-a)
! INDIVIDUAL RETURN VALUES
integer(kind=4) :: c1_open
! AUXILIARY VARIABLES
integer :: i ! ITERATOR
! FILL IN OUTPUT ARRAY
do i = 1,10
call get_value( ts, c1_open)
c_open(i) = c1_open
end do
end subroutine
Basically get_value
calculates a value (in this example it just returns the value of the first item of the passed vector ts
and get_value_range
returns a vector of results using get_value
function.
When I compile with f2py
I get:
37 | call get_value( ts, c1_open)
| 1
Error: Explicit interface required for 'get_value' at (1): assumed-shape argument
Why is this error being drop by f2py
and is there any way to fix it?
EDIT:
I have been redirected here: Fortran - explicit interface and here: Procedure with assumed-shape dummy argument must have an explicit interface
Now if I understood those posts correctly the compiler requires to know the parameters of get_value
in get_value_range
. That can be done either encapsulating everything in a module
or by using an internal procedure
or by defining explicitly an interface
.
I am still pretty new to f2py
and I am not sure if in f2py
you have to encapsulate everything in modules or just write the subroutines as stand alone subroutines in the file. So far I am following the later approach as by doing that I see that they are properly exposed to Python.
Assuming that I want to try the approach of an explicit interface
I try this:
subroutine get_value(ts, c_open)
implicit none
! INPUT PARAMETERS
integer(kind=4), intent(in) :: ts(:)
! OUTPUT PARAMETERS
integer(kind=4), intent(out) :: c_open
! SIMULATED CALCULATION
c_open = ts(1)
end subroutine
subroutine get_value_range(ts, a, b, ca_open)
implicit none
! INPUT PARAMETERS
integer(kind=4), intent(in) :: ts(:)
integer(kind=4), intent(in) :: a
integer(kind=4), intent(in) :: b
! OUTPUT PARAMETERS
! - AGGREGATED VALUES TO RETURN
integer(kind=4), intent(out) :: ca_open(b-a)
! INDIVIDUAL RETURN VALUES
integer(kind=4) :: c1_open
! AUXILIARY VARIABLES
integer :: i ! ITERATOR
! INTERFACE TO get_value
interface
function get_value(ts, c_open)
integer(kind=4), intent(in) :: ts(:)
integer(kind=4), intent(out) :: c_open
end function
end interface
! FILL IN OUTPUT ARRAY
do i = 1,10
call get_value(ts, c1_open)
ca_open(i) = c1_open
end do
end subroutine
But then I get the following error:
37 | function get_value(ts, c_open)
| 1
......
45 | call get_value(ts, c1_open)
| 2
Error: 'get_value' at (1) has a type, which is not consistent with the CALL at (2)
So it seems that the compiler is now finding the definition of get_value
but for some reason that I can not understand it is detecting an inconsistency between the function definition and the call.
EDIT 2:
There is a clear error in the definition as pointed out in the comments, the interface block defines a function instead of a subroutine.
However, when I modify it I get a new error:
subroutine get_value(ts, c_open)
implicit none
! INPUT PARAMETERS
integer(kind=4), intent(in) :: ts(:)
! OUTPUT PARAMETERS
integer(kind=4), intent(out) :: c_open
! SIMULATED CALCULATION
c_open = ts(1)
end subroutine
subroutine get_value_range(ts, a, b, ca_open)
implicit none
! INTERFACE TO get_value
interface
subroutine get_value (ts, c_open)
integer(kind=4), intent(in) :: ts(:)
integer(kind=4), intent(out) :: c_open
end subroutine get_value
end interface
! INPUT PARAMETERS
integer(kind=4), intent(in) :: ts(:)
integer(kind=4), intent(in) :: a
integer(kind=4), intent(in) :: b
! OUTPUT PARAMETERS
! - AGGREGATED VALUES TO RETURN
integer(kind=4), intent(out) :: ca_open(b-a)
! INDIVIDUAL RETURN VALUES
integer(kind=4) :: c1_open
! AUXILIARY VARIABLES
integer :: i ! ITERATOR
! FILL IN OUTPUT ARRAY
do i = 1,10
call get_value(ts, c1_open)
ca_open(i) = c1_open
end do
end subroutine
These are the new errors after trying to compile it with f2py
:
86 | subroutine get_value(ts,c_open) ! in :tape_lib:./ohl
| 1
Error: Syntax error in SUBROUTINE statement at (1)
88 | integer(kind=4), intent(in),dimension(:) :: ts
| 1
Error: Unexpected data declaration statement in INTERFACE block at (1)
89 | integer(kind=4), intent(out) :: c_open
| 1
Error: Unexpected data declaration statement in INTERFACE block at (1)
90 | end subroutine get_value
| 1
Error: Expecting END INTERFACE statement at (1)