Hi,
Sent this last week but checking the archives it appears not to have got through. Hopefully this will work...
I am looking at moving some of my code to fortran to use with f2py. To get started I used this simple example:
SUBROUTINE bincount (x,c,n,m) IMPLICIT NONE INTEGER, INTENT(IN) :: n,m INTEGER, DIMENSION(n), INTENT(IN) :: x INTEGER, DIMENSION(0:m-1), INTENT(OUT) :: c INTEGER :: i
DO i = 1, n c(x(i)) = c(x(i)) + 1 END DO END
It performs well: In [1]: x = np.random.random_integers(0,1023,1000000).astype(int) In [4]: timeit test.bincount(x,1024) 1000 loops, best of 3: 1.16 ms per loop In [5]: timeit np.bincount(x) 100 loops, best of 3: 4 ms per loop
I'm guessing most of the benefit comes from less checking + not having to find the maximum value (which I pass as parameter m).
But I have some questions. It seems to work as is, but I don't set c to zeros anywhere. Can I assume arrays created by f2py are zero? Is this the recommended way to use f2py with arrays? (I initially tried using assumed arrays with DIMENSION(:) but it couldn't get it to work). Also I'm quite new to fortran - what would be the advantages, if any, of using a FORALL instead of DO in a situation like this? I guess with 1D arrays it doesn't make a copy since ordering is not a problem, but if it was 2D arrays am I right in thinking that if I passed in a C order array it would automatically make a copy to F order. What about the return - will I get a number array in F order, or will it automatically be copied to C order? (I guess I will see but I haven't got onto trying that yet). What if I wanted to keep all the array creation in numpy - ie call it as the fortran subroutine bincount(x,c) and have c modified in place? Should I be using !f2py comments? I wasn't clear if these are needed - it seems to work as is but could they give any improvement?
For comparison I tried the same thing in cython - after a couple of iterations with not typing things properly I ended up with:
import numpy as np cimport numpy as np cimport cython
@cython.boundscheck(False) def bincount(np.ndarray[np.int_t, ndim=1] x not None,int m): cdef int n = x.shape[0] cdef unsigned int i cdef np.ndarray[np.int_t, ndim=1] c = np.zeros(m,dtype=np.int)
for i from 0 <= i < n: c[<unsigned int>x[i]] += 1
return c
which now performs a bit better than np.bincount, but still significantly slower than the fortran. Is this to be expected or am I missing something in the cython?
In [14]: timeit ctest.bincount(x,1024) 100 loops, best of 3: 3.31 ms per loop
Cheers
Robin
Hi,
I have another question about distributing a Python extension which uses f2py wrapped code. Ideally I'd like to keep pure Python/Numpy alternatives and just use fortran version if available - but I think that should be OK.
I'm more worried about distributing binaries on Windows - I think on Mac/Linux it would be ok to have a fortran compiler required and build it - but on Windows I guess one should really distribute binaries.
What is the recommended (free) fortran 95 compiler for use with f2py on windows (gfortan with cygwin?) Is it possible to get f2py to build a static library on windows so I can just distribute that? Or will I need to include library files from the compiler? How many different binary versions does one need to support common recent windows setups? I guess I need a different binary for each major python version and 32/64 bits (ie 2.5 32bit, 2.6 32bit, 2.5 64bit, 2.6 64bit). Is this right, or would different binaries be required for XP, Vista, 7 etc. ?
Can anyone point me to a smallish Python package that includes fortran code in this way that I could look to for inspiration?
Cheers
Robin
On Thu, Oct 15, 2009 at 8:53 AM, Robin robince@gmail.com wrote:
Hi,
I have another question about distributing a Python extension which uses f2py wrapped code. Ideally I'd like to keep pure Python/Numpy alternatives and just use fortran version if available - but I think that should be OK.
I'm more worried about distributing binaries on Windows - I think on Mac/Linux it would be ok to have a fortran compiler required and build it - but on Windows I guess one should really distribute binaries.
What is the recommended (free) fortran 95 compiler for use with f2py on windows (gfortan with cygwin?) Is it possible to get f2py to build a static library on windows so I can just distribute that? Or will I need to include library files from the compiler? How many different binary versions does one need to support common recent windows setups? I guess I need a different binary for each major python version and 32/64 bits (ie 2.5 32bit, 2.6 32bit, 2.5 64bit, 2.6 64bit). Is this right, or would different binaries be required for XP, Vista, 7 etc. ?
The same binaries should work on both XP and Vista.
Can anyone point me to a smallish Python package that includes fortran code in this way that I could look to for inspiration?
I don't know if you can pymc smallish, but it is using a considerable amount of fortran, and distributes only win32-py2.5 binaries. http://code.google.com/p/pymc/
for the rest I have no idea. (for numpy/scipy, I'm still using g77 with the official mingw for windows xp, win32 only)
Josef
Cheers
Robin _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
-----Original Message----- From: numpy-discussion-bounces@scipy.org [mailto:numpy-discussion- bounces@scipy.org] On Behalf Of Robin Sent: 15 Oct 2009 6:54 AM To: numpy-discussion@scipy.org Subject: Re: [Numpy-discussion] extension questions: f2py and cython
Hi,
I have another question about distributing a Python extension which uses f2py wrapped code. Ideally I'd like to keep pure Python/Numpy alternatives and just use fortran version if available - but I think that should be OK.
I'm more worried about distributing binaries on Windows - I think on Mac/Linux it would be ok to have a fortran compiler required and build it - but on Windows I guess one should really distribute binaries.
What is the recommended (free) fortran 95 compiler for use with f2py
on
windows (gfortan with cygwin?) Is it possible to get f2py to build a static library on windows so I can just distribute that? Or will I
need
to include library files from the compiler?
I am using gfortran, which has a native Windows installer: http://www.scipy.org/F2PY_Windows
I have also successfully used g95 with f2py on Windows.
When f2py runs this on Windows, it produces a *.pyd file that contains the compiled code. E.g. myfoo.f --> myfoo.pyd. This is imported into python with 'import myfoo'. The recipient of the windows binary needs only the *.pyd file (and your *.py files).
Andrew
-----Original Message----- From: numpy-discussion-bounces@scipy.org [mailto:numpy-discussion- bounces@scipy.org] On Behalf Of Robin Sent: 15 Oct 2009 4:37 AM To: numpy-discussion@scipy.org Subject: [Numpy-discussion] extension questions: f2py and cython
Hi,
Sent this last week but checking the archives it appears not to have got through. Hopefully this will work...
I am looking at moving some of my code to fortran to use with f2py. To get started I used this simple example:
...
But I have some questions. It seems to work as is, but I don't set c
to
zeros anywhere. Can I assume arrays created by f2py are zero?
As I understand it, uninitialized variables in Fortran are compiler/system-dependent. Some compilers initialize values to zero, many leave the previous contents of the memory in place. It is safest to never use the value of an uninitialized variable.
Andrew
Hi,
Thanks
On Thu, Oct 15, 2009 at 4:10 PM, Andrew Hawryluk HAWRYLA@novachem.com wrote:
But I have some questions. It seems to work as is, but I don't set c
to
zeros anywhere. Can I assume arrays created by f2py are zero?
As I understand it, uninitialized variables in Fortran are compiler/system-dependent. Some compilers initialize values to zero, many leave the previous contents of the memory in place. It is safest to never use the value of an uninitialized variable.
But in this case I understood it was initialised or created by the f2py wrapper first and then passed to the fortran subroutine - so I wondered how f2py creates it (I think I traced it to array_from_pyobj() but I couldn't really understand what it was doing or whether it would always be zeros). I guess as you say though it is always safer to initialize explicitly
Cheers
Robin