2

I am new to Fortran and I am trying to run fortran inside python using f2py. I have had luck when the fortran function gave output as a single value. But when I modified the fortran function to give out an array, I am getting segmentation faults.
Could someone please help me out? Here is the code:

Fortran function: in file called 'fortfunc.f95':

function fut(x,n) 
implicit none
real, intent(in) :: x
integer, intent(in) :: n
real, dimension(2) :: fut

! My aim is to return an array fut which has 2 elements in it

fut(1)=x*n
fut(2)=x*n*100


end function fut

Then I use f2py to compile fortran function to be used in python:

f2py -c -m func fortfunc.f95 

here func is name of module to be imported in python

Python code: (pretty straightforward)

import func # func is the name of module which contains function fut
x=20
n=20
res=func.fut(x,n)
print('answer is ',res)

I wish to get an array with 2 elements called 'res' but instead I get 'Segmentation fault: 11'

Can someone please point out my mistake?

  • What you want is not possible. You have to create a subroutine and pass the array in. You can read here: https://stackoverflow.com/questions/17474225/f2py-python-function-that-returns-an-array-vector-valued-function – Chiel Jul 13 '18 at 10:59

1 Answers1

3

If you work with a subroutine, you could create the return array before you call the function. In that case, your Python script would be as following

import func
import numpy as np

res = np.zeros(2)
x = 20
n = 20
func.fut(res, x, n)

print("answer is", res)

And in the Fortran code, you can create a subroutine. Note that I replaced the type by double precision as a Fortran real is a single precision floating point number by default, while Python uses double precision.

subroutine fut(a,x,n) 
    implicit none
    double precision, intent(in) :: x
    integer, intent(in) :: n
    double precision, intent(inout), dimension(2) :: a 

    ! My aim is to return an array fut which has 2 elements in it
    a(1) = x*n
    a(2) = x*n*100
end subroutine fut
Chiel
  • 6,006
  • 2
  • 32
  • 57
  • Great! this works for now. Thanks @Chiel! Also wondering if there is any way Fortran functions could have array/matrix as outputs? – insane_oceanographer Jul 13 '18 at 12:02
  • 1
    The statement that " a Fortran real is a single precision floating point number by default, while Python uses double precision " does not precisely hold. `real` is simply the default kind, which depends on the compiler options and the platform, and `double precision` only gives twice the `real` size in bytes. Better to use `real32` and `real64` from `fortran_iso_env` module instead of `real` and `double precision` which are platform dependent. – Scientist Jul 16 '18 at 04:01