f2py: generic,public/private procedure
Hy all, As a test case before writing something bigger, I'm trying to write a little Fortran module to compute the average of a array in these 4 cases: avg2d_float, avg2d_double avg3d_float, avg3d_double I want this module to be callable from both Fortran and Python, using f2py. 4 Fortran functions have to be written, and a generic Fortran function 'avg' overloads its. The Fortran module 'stat.f90' (containing the functions), a Fortran program 'stat_example.f90' and a Python script 'stat_example.py' are at the end of the email. (everything works fine: the compilation, f2py, the execution in Python and in Fortran.) My questions are: - Assumed shape array are not supported by f2py. However, it is much more handy to write in Fortran 'avg(array)' than 'avg(array,n1,n2,n3)'. Would it be possible to supported it by modifying the signature files? - Is there a way to avoid to write by hand the 'avg' Python function (in example_stat.py) ? - Isn't there no way to declare private the functions: avg2d_float, avg2d_double, avg3d_float,avg3d_double? It's embarassing its are visible from stat_example.f90. Uncommenting the lines in the top of the file stat.f90: !private !public:: avg and running: f2py -m f90stat -c stat.f90 give the error: use stat, only : avg2d_float Error: Symbol 'avg2d_float' referenced at (1) not found in module 'stat' Thanks for any suggestion, David * to create the Fortran executable: gfortran -c stat.f90 gfortran -c stat_example.f90 gfortran -o stat_example.x stat.o stat_example.o * to create the Python module: f2py -m f90stat -c stat.f90 * The Fortran module is: """ !file stat.f90 module stat implicit none !private !public:: avg interface avg module procedure avg2d_float, avg2d_double, avg3d_float, avg3d_double end interface contains function avg2d_float(array,n1,n2) result(average) implicit none real(kind=4):: average integer:: n1,n2 real(kind=4),dimension(n1,n2),intent(in):: array average = sum(array) average = average / n1 average = average / n2 end function avg2d_float function avg2d_double(array,n1,n2) result(average) implicit none real(kind=8):: average integer:: n1,n2 real(kind=8),dimension(n1,n2),intent(in):: array average = sum(array) average = average / n1 average = average / n2 end function avg2d_double function avg3d_float(array,n1,n2,n3) result(average) implicit none real(kind=4):: average integer:: n1,n2,n3 real(kind=4),dimension(n1,n2,n3),intent(in):: array average = sum(array) average = average / n1 average = average / n2 average = average / n3 end function avg3d_float function avg3d_double(array,n1,n2,n3) result(average) implicit none real(kind=8):: average integer:: n1,n2,n3 real(kind=8),dimension(n1,n2,n3),intent(in):: array average = sum(array) average = average / n1 average = average / n2 average = average / n3 end function avg3d_double end module stat """ * The Fortran program is: """ !file: stat_example.f90 program stat_example use stat implicit none integer,parameter:: n1=10,n2=10,n3=10 real(kind=4),dimension(n1,n2):: array2d_float real(kind=8),dimension(n1,n2):: array2d_double real(kind=4),dimension(n1,n2,n3):: array3d_float real(kind=8),dimension(n1,n2,n3):: array3d_double array2d_float = 4. array2d_double = 4. array3d_float = 4. array3d_double = 4. write(*,*) avg(array2d_float,n1,n2) write(*,*) avg(array2d_double,n1,n2) write(*,*) avg(array3d_float,n1,n2,n3) write(*,*) avg(array3d_double,n1,n2,n3) write(*,*) avg2d_float(array2d_float,n1,n2) end program stat_example """ * The Python script is: """ #!/usr/bin/env python #file stat_example.py import numpy as np import f90stat def avg(a): if a.ndim == 2: if a.dtype == 'float32': return f90stat.stat.avg2d_float(a) elif a.dtype == 'float64' : return f90stat.stat.avg2d_double(a) else: raise ValueError, 'dtype = %r unsupported.' % (a.dtype) elif a.ndim == 3: if a.dtype == 'float32': return f90stat.stat.avg3d_float(a) elif a.dtype == 'float64' : return f90stat.stat.avg3d_double(a) else: raise ValueError, 'dtype = %r unsupported.' % (a.dtype) else: raise ValueError, 'ndim = %r unsupported.' % (a.ndim) if __name__ == '__main__': a = np.arange(6.) a = a.reshape(2,3) print avg(a) """
participants (1)
-
David Froger