John Luke Lusty
John Luke Lusty

Reputation: 23

External function ‘f’ at (1) has no IMPLICIT type in subroutine with f2py

I've used Fortran 90 for a while now and recently decided to wrap up some modules using f2py to simplifying prototyping by using Python as a front end.

However, I've come across an error when trying to compile a subroutine that is passed an external function (from Python). Here is code that replicates the error:

! file: callback.f90
subroutine callback(f,x,y)
  implicit none
  ! - args -
  ! in
  external :: f
  real(kind=kind(0.0d0)), intent(in) :: x
  ! out
  real(kind=kind(0.0d0)), intent(inout) :: y

  y = f(x)
end subroutine

Now, if I use f2py to generate a signature file (.pyf), here is what I obtain:

!    -*- f90 -*- 
! Note: the context of this file is case sensitive.
python module callback__user__routines 
interface callback_user_interface 
    function f(x) result (y) ! in :callback:callback.f90
        intent(inout) f
        real(kind=kind(0.0d0)) intent(in) :: x
        real(kind=kind(0.0d0)) intent(inout) :: y
    end function f
end interface callback_user_interface
end python module callback__user__routines
python module callback ! in  
    interface  ! in :callback
        subroutine callback(f,x,y) ! in :callback:callback.f90
            use callback__user__routines
            external f
            real(kind=kind(0.0d0)) intent(in) :: x
            real(kind=kind(0.0d0)) intent(inout) :: y
        end subroutine callback
    end interface 
end python module callback

! This file was auto-generated with f2py (version:2).
! See http://cens.ioc.ee/projects/f2py2e/

Which is not correct, so I alter it in the following way:

!    -*- f90 -*- 
! Note: the context of this file is case sensitive.
python module __user__routines
    interface
        function f(x) result (y) 
            real(kind=kind(0.0d0)) intent(in) :: x
            real(kind=kind(0.0d0)) :: y
        end function f
    end interface
end python module __user__routines
python module callback ! in  
    interface  ! in :callback
        subroutine callback(f,x,y)
            use __user__routines
            external f
            real(kind=kind(0.0d0)) intent(in) :: x
            real(kind=kind(0.0d0)) intent(inout) :: y
        end subroutine callback
    end interface 
end python module callback

! This file was auto-generated with f2py (version:2).
! See http://cens.ioc.ee/projects/f2py2e/

Nonetheless, both throw an error telling me that I have not defined f:

callback.f90:1:21:
subroutine callback(f,x,y)
                    1
Error: Symbol ‘f’ at (1) has no IMPLICIT type
callback.f90:10:6:

  y = f(x)
      1
Error: Can't convert UNKNOWN to REAL(8) at (1)
callback.f90:1:21:

subroutine callback(f,x,y)
                    1
Error: Symbol ‘f’ at (1) has no IMPLICIT type
callback.f90:10:6:

   y = f(x)
       1
Error: Can't convert UNKNOWN to REAL(8) at (1)

I've done as much research as I can on properly editing the .pyf signature file manually, but to no avail in this case. Has anyone encountered a similar error when trying to use f2py with external functions?

Upvotes: 2

Views: 1617

Answers (1)

The error is correct and it is a Fortran error, it will happen even without any f2py or Python

subroutine callback(f,x,y)
  implicit none
  external :: f
  real(kind=kind(0.0d0)), intent(in) :: x
  real(kind=kind(0.0d0)), intent(inout) :: y

  y = f(x)
end subroutine

f has no type declared and implicit none is enabled so that is a Fortran error.

Use

  real(kind=kind(0.0d0)), external :: f

or

  external :: f
  real(kind=kind(0.0d0)) :: f

Upvotes: 5

Related Questions