I'm trying to use a Fortran90 numerical model with Python 3.5 using f2py.
f2py -c module.f90 -m mod --fcompiler=gfortran
The model is a Fortran module that contains variables, functions and subroutines. I'm posting here a code example that has all the features of the numerical model
module modul
implicit none
integer :: inte
real :: re
integer, dimension(3) :: array
CHARACTER(*), PARAMETER :: chara = "helloWorld"
contains
integer function fun()
fun = array(1) + array(2) + array(3)
end function
subroutine subrout(a,b)
real, intent(out) :: b
integer, intent(out) :: a
a = inte + fun()
b = re
write(*,*) chara
end subroutine subrout
end module modul
The conversion of the code with f2py works properly but, when I import the module in Python, I receive a segmentation fault error
>>> import mod
Segmentation fault (core dumped)
I realized that the problem depends on the unspecified dimension of the character array
CHARACTER(*), PARAMETER :: chara = "helloWorld"
as, if I remove that line of code or I assign a fixed dimension to the array (like CHARACTER(20) ), the module works properly in Python.
1. Is there a way to make it works without modifying the Fortran code (the model is long and complex and, if possible, I don't want to work on it)?
The character arrays are used to define strings in the code (like error messages) and to handle the input/output from files. One way to solve the problem (if there is no answer to question 1) could be defining a fixed maximum dimension for all the character strings (i.e. INTEGER, PARAMETER :: lenChar = 100) and then use
CHARACTER(lenChar), PARAMETER :: chara
instead of the previous declaration. In this case the module is successfully imported in Python but when I try to modify the array content it requires an input lenChar long (the same problem appears with the other types of array like INTEGER or REAL and doesn't depend by the PARAMETER attribute)
mod.modul.chara = "hello"
0-th dimension must be fixed to 100 but got 5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
SystemError: error return without exception set
This is an operation that the model needs to handle as the "chara" could be the path for the data and it needs to be initialized at run-time.
2. If there no answer to question (1) and I need to proceed in this way, how can I assign to the array an input shorter than the length of the array?
System information:
OS: Ubuntu 16.04
Python 3.5.2
f2py Version: 2
numpy Version: 1.12.1
GNU Fortran (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
Answering question 2:
Strings in fortran are treated as array of characters in f2py. So in your case mod.modul.chara
is an array of 100
characters (depending on the length specified in fortran). To feed something like 'hello'
into the handle you could do the following:
for i,j in enumerate('hello'):
mod.modul.chara[i]=j
This should let you pass the string.