My problem is that when compiling with f2py, some module variables are not recognized by functions defined within the module. The errors are raised where variable types of arguments passed to the function are declared (such as a variable describing the type of real
, or dimension elements). I do not get this error when compiling with gfortran. What is the difference and how can I remedy these errors when compiling with f2py?
My example file, moddata.f90
, contains the following code:
module mod
implicit none
integer, parameter :: dp = selected_real_kind(15)
integer, parameter :: nelem = 3
real(kind=dp), dimension(nelem) :: b
parameter (b=(/3,1,2/))
contains
function foo(x,y) result(z)
! dp, nelem are defined in module above
real(kind=dp), intent(in) :: x !scalar
integer, dimension(nelem), intent(in) :: y
! local variable
real(kind=dp) :: z
z = sum(b*y*x)
end function foo
end module mod
and I compile with
f2py -c -m moddata moddata.f90
and I get these errors:
y_Dims[0]=(nelem);
^
1 warning and 1 error generated.reduce to a constant expression
if I redefine integer, parameter :: nelem=3
before integer, dimension(nelem), intent(in) :: y
and recompile, I get
real(kind=dp) foof2pywrap
1
Error: Parameter 'dp' at (1) has not been declared or is a variable, which does not reduce to a constant expression
with same errors for each of the real(kind=dp)
declarations, and
foof2pywrap = foo(x, y)
1
Warning: Possible change of value in conversion from REAL(8) to REAL(4) at (1)
So I have to redefine dp
by integer, parameter :: dp = selected_real_kind(15)
in the function. And then it works.
I don't get these errors when I compile this module with a fortran wrapper. I wonder why nelem
and dp
in the function is not properly scoped with f2py?
Perhaps I am wrong, but I don't think f2py can handle the
module
+contains
feature of Fortran 90. If you turn your code intoand compile it as before, it works:
EDIT
The answer to this question on SO says that f2py doesn't understand how to turn a Fortran function into a python function. So I changed the
function foo
tosubroutine foo2
and then compiled asf2py moddata.f90 -m moddata
and got as outputSo it does look like the double-precision was being lost, so following the suggestion to edit a file called
.f2py_f2cmap
, I did so and got no errors when it came todp
. However, it still gives an error fornelem
, so I can think of two solutions to this:3
in place ofnelem
nelem
andb
as variables to the subroutineI also found, when using the
parameter(b = (/3.d0, 1.d0, 2.d0/) )
line, that I was getting a warning that readI am not sure what to make of this. However, I do get 18 as an answer when I use
x=1.0
andy=(/ 3, 6, 2/)
(both using python and using the module in a Fortran program).In short, completely avoid functions when you are using f2py.