Fortran comparison Re: [SciPy-dev] scipy.weave versus simple C++.

eric eric at scipy.org
Sat Jan 12 14:20:06 CST 2002


> Iterations took  6.12530398369  seconds.
> Fortran iterations took  3.15447306633  seconds.

>
> So, using Fortran you get speed up approx. _two_ times compared to cxx!!!


Hey!  That is larger than I would have expected.  Fortran often has a slight
advantage ( a few percent), but not a factor of 2.  Several things could be
in play here.

(1) Prabhu and I have no clue how to set compiler switches in gcc for best
results. (very possible)
(2) Your using a better optimizing Fortran compiler (wonder what the Intel
or KAI compiler would do on the C++ code).  Which one are you using?  If it
is g77, then this is exhibit A for supporting (1).
(3) If comparisons are made against Prabhu's C++ code instead of my
extension module which (mis) uses blitz++ arrays for indexing, would only
show a 33% improvement.  Correct?  This is starting to be more what I'd
expect.

Anyway, I'd be surprised if the difference is this great in the final
analysis -- I'll bet less than 10% difference either way.

> If one would use optimized blas and laplack functions, the speed up could
> be even greater.

Not sure about the difference here.  Which blas functions would you use for
this?  Also, you can use optimized blas/lapack from C just as easily.  Keep
in mind that ATLAS is pretty much as fast as it gets for BLAS/LAPACK and it
is all written in C with special assembly for some CPUs (Intel/AMD/PowerPC).

Still, in the end, I would like to have a version of inline that works for
Fortran.  It's not a large project, but also not one I have time for now.
If anyone is interested, drop me a line, and I'll point out how to do it.
On the usability side of inline Fortran, the array transpose issue is
confusing to people (including me), and, for speed, you have to leave the
details of this up to the user.  We're just stuck with this.

eric

>
> Below is the testing code that I used. Here is how I used it, step by
> step, to illustrate that using Fortran from python is very simple:
>
> 1) Build fortran wrapper:
>   f2py -c flaplace.f -m flaplace          # here you need f2py from CVS
>
> As a result you'll get flaplace.so in the current directory.
>
> 2) Run tests:
> $ python laplace.py
> Iterations took  6.51088702679  seconds.
> Error:  38047.7567709
> Fortran iterations took  3.22211503983  seconds.
> Error:  21778.5117188
>
> Regards,
> Pearu
>
> --------------------
> c File flaplace.f
>       subroutine timestep(u,n,m,dx,dy,error)
>       double precision u(n,m)
>       double precision dx,dy,dx2,dy2,dnr_inv,tmp,err,diff
>       integer n,m,i,j
> cf2py intent(in) :: dx,dy
> cf2py intent(in,out) :: u
> cf2py intent(out) :: error
> cf2py intent(hide) :: n,m
>       dx2 = dx*dx
>       dy2 = dy*dy
>       dnr_inv = 0.5d0 / (dx2+dy2)
>       error = 0
>       do 200,i=2,n-1
>          do 100,j=2,m-1
>             tmp = u(i,j)
>             u(i,j) = ((u(i-1,j) + u(i+1,j))*dy2+
>      &           (u(i,j-1) + u(i,j+1))*dx2)*dnr_inv
>             diff = u(i,j) - tmp
>             error = error + diff*diff
>  100     continue
>  200  continue
>       error = sqrt(error)
>       end
>
> -------------------
> # modifications to laplace.py
>
> import flaplace
>
>     # New method to LaplaceSolver class
>     def ftimeStep(self,dt = 0.0):
>         u,err = flaplace.timestep(self.g.u,self.g.dx,self.g.dy)
>         return err
>
>     # Slightly modified solve method:
>     def solve(self, n_iter=0, eps=1e-16,fortran = 0):
>         if fortran:
>             timeStep = self.ftimeStep
>         else:
>             timeStep = self.timeStep
>         err = timeStep()
>         #print err
>         count = 1
>         while err > eps:
>             if n_iter and (count > n_iter):
>                 return err;
>             err = timeStep()
>             #print err
>             count += 1
>         return count
>
>     # Slightly modified runner:
>     t1 = time.time()
>     err = s.solve(100,fortran)
>     t2 = time.time()
>     print "Iterations took ", t2 - t1, " seconds."
>     print "Error: ", err
>     t1 = time.time()
>     err = s.solve(100,fortran=1)
>     t2 = time.time()
>     print "Fortran iterations took ", t2 - t1, " seconds."
>     print "Error: ", err
>
> ---------------
> EOF message
>
> _______________________________________________
> Scipy-dev mailing list
> Scipy-dev at scipy.net
> http://www.scipy.net/mailman/listinfo/scipy-dev





More information about the Scipy-dev mailing list