Domanda

Assume we need to call fortran function, which returns some values, in python program. I found out that rewriting fortran code in such way:

subroutine pow2(in_x, out_x)
      implicit none
      real, intent(in)      :: in_x
!f2py real, intent(in, out) :: out_x
      real, intent(out)     :: out_x
      out_x = in_x ** 2
      return
end

and calling it in python in such way:

import modulename
a = 2.0
b = 0.0
b = modulename.pow2(a, b)

gives us working result. Can I call fortran function in other way, cause I think the first way is a bit clumsy?

È stato utile?

Soluzione

I think you just need to change your f2py function signature slightly (so that out_x is only intent(out) and in_x is only intent(in)):

subroutine pow2(in_x, out_x)
  implicit none
  real, intent(in)   :: in_x
  !f2py real, intent(in) :: in_x
  real, intent(out)     :: out_x
  !f2py real, intent(out) :: out_x
  out_x = in_x ** 2
  return
end subroutine pow2

Now compile:

f2py -m test -c test.f90

Now run:

>>> import test
>>> test.pow2(3)   #only need to pass intent(in) parameters :-)
9.0
>>>

Note that in this case, f2py is able to correctly scan the signature of the function without the special !f2py comments:

!test2.f90
subroutine pow2(in_x, out_x)
  implicit none
  real, intent(in)   :: in_x
  real, intent(out)     :: out_x
  out_x = in_x ** 2
  return
end subroutine pow2

Compile:

f2py -m test2 -c test2.f90

run:

>>> import test2
>>> test2.pow2(3)   #only need to pass intent(in) parameters :-)
9.0
>>>

Altri suggerimenti

Another benefit to avoiding intent(inout) arguments is (with a few other restrictions) the resulting function can be considered PURE. This is related to the no-side-effects approach taken by functional languages and pays off with better optimization and error detection by the Fortran compiler and is especially important for auto-parallelization.

If you're using IPython, try magic command, which makes it able to write

%%fortran
subroutine pow2(in_x, out_x)
  implicit none
  real, intent(in)   :: in_x
  real, intent(out)     :: out_x
  out_x = in_x ** 2
  return
end subroutine pow2

and then simply use this function in your code (without additional imports).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top