I cannot get f2py to reference a parameter from a module in a separate subroutine where it is used to defined an input array dimension. I.e. the paramter is defeind in a module:
! File: testmod.f90
MODULE testmod
INTEGER, PARAMETER :: dimsize = 20
END MODULE testmod
and the parameter dimsize needs to be referenced in a subroutine (NOT contained in the module) in another file, which will be the entry point for my python module:
! File testsub.f90
SUBROUTINE testsub(arg)
USE testmod
REAL, INTENT(IN) :: arg(dimsize)
END SUBROUTINE testsub
I compile like this:
f2py -m testmod -h testmod.pyf testsub.f90
pgf90 -g -Mbounds -Mchkptr -c -fPIC testmod.f90 -o testmod.o
pgf90 -g -Mbounds -Mchkptr -c -fPIC testsub.f90 -o testsub.o
f2py -c testmod.pyf testmod.o testsub.o
but get this error:
testmodmodule.c: In function 'f2py_rout_testmod_testsub':
testmodmodule.c:180: error: 'dimsize' undeclared (first use in this function)
I have tried modifying testsub.g90 to include the following directive, as suggested ni other posts:
SUBROUTINE testsub(arg)
USE testmod
!f2py integer, parameter :: dimsize
REAL, INTENT(IN) :: arg(dimsize)
END SUBROUTINE testsub
but to no avail. I need to keep the subroutine separate from the module.
How can I get f2py to correctly resolve the variable dimsize
?
TIA
It's been a long time since this question has gotten any activity, but I figured out the problem so I thought I'd post it for anyone else who has this issue. The problem is that while the Fortran code is perfectly valid, the C wrapper generated by F2PY doesn't know what dimsize is when it checks that arrays are the correct size (within the C wrapper, it's encapsulated in some kind of module structure).
Just change this code:
SUBROUTINE testsub(arg)
USE testmod
!f2py integer, parameter :: dimsize
REAL, INTENT(IN) :: arg(dimsize)
END SUBROUTINE testsub
to this:
SUBROUTINE testsub(arg)
USE testmod
!f2py integer, intent(aux) :: dimsize
REAL, INTENT(IN) :: arg(dimsize)
END SUBROUTINE testsub
This will "Define auxiliary C variable in F2PY generated wrapper function". As the Scipy docs say, this is "Useful to save parameter values so that they can be accessed in initialization expression of other variables".
I haven't tested this with your code, but I've tested it with a similar situation I was having.
Although I've not tested it, I think you nearly have it with your original code. We do something similar for some of our code, but with gfortran.
You shouldn't need to f2py
the testmod.f90 file. You should just compile it to an object file just like you would if this were normal Fortran:
pgf90 -g -Mbounds -Mchkptr -c -fPIC testmod.f90 -o testmod.o
Then you should be able to compile your testsub.f90 into a python-usable module with:
f2py --fcompiler=pgf90 --f90flags="-g -Mbounds -Mchkptr" -c testsub.f90 -m testsub testmod.o
That should build a testsub.so, or equivalent, letting you import testsub
and then testsub.testsub(my_arg)
in python.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With