LehreWiki

Python as a glue

Python is often considered as a glue to combine different programming languages under one hood. Why should one combine different languages? There are some good reasons if there are existing libraries that should be combined or to increase the performance. Python is relatively fast if compared to Matlab or IDL but Fortran code can be much faster. However, before spending time in optimization one should think if it is really necessary.

The normal Python interpreter, or sometimes called cPython, is build in the C programming language. Python can be extended with C-routines and Python objects can be called from C. See http://docs.python.org/c-api/ for more information. The Jython interpreter is a Java version of Python which allows interactive and dynamic Java programming.

Using Fortran Subroutines in Python

The Fortran programming language is more than 50 years old. The first version was developed during the years 1954-1957. At this time it was a revolutionary product. Since then many new ideas have been introduced in programming languages such as the object oriented concept. Fortran has inherited some of these new concepts and allows also object orientation approaches in its newest version. However, not all compilers support such features and the standardization is not finished yet. Moreover, existing code with its origins based on Fortran 77 or Fortran 90 is not using these features. Thus, is difficult to maintain very complex applications in Fortran such as climate models. Therefore, Python can be used for refactoring some components, for example the Community Climate System Model (CCSM) Coupler.

There are different reasons why one should combine Python and Fortran

F2PY: Fortran to Python interface generator

Calling Fortran code from python is easy! Create a file hello.f:

C File hello.f
      subroutine foo (a)
      integer a
      print*, "Hello from Fortran!"
      print*, "a=",a
      end

Run f2py -c -m hello hello.f

Now in IPython try:

In [1]: import hello
In [2]: hello.foo(4)
 Hello from Fortran!
 a=           4

Example taken from

More examples

Scalar function

sub1.f95

REAL function sub1(x,y)
REAL :: x,y

sub1=0.5*(x+y)

return
end

sub1.py

   1 import os
   2 os.system('rm sub1.o')
   3 os.system('f2py --fcompiler=gnu95 -m sub1 -c ./sub1.f95')
   4 
   5 from sub1 import sub1
   6 
   7 x,y,z=3.0,2.0,0.0
   8 z=sub1(x,y)
   9 print x,y,z

run sub1
3.0 2.0 2.5

The parameters x,y are not changed. The result (sub1) is returned.

In/Out

subroutine sub2(x,y)

REAL, intent(in) :: x
REAL, intent(out)  :: y

y=x+1

return
end

   1 import os
   2 os.system('rm sub2.o')
   3 os.system('f2py --fcompiler=gnu95 -m sub2 -c ./sub2.f95')
   4 
   5 from sub2 import sub2
   6 
   7 
   8 x,y=1,0
   9 y=sub2(x)
  10 print x,y

Arrays

The following example shows how to pass an array of arbitrary size to a Fortran subroutine.

subroutine sub6(x,n)

IMPLICIT NONE


INTEGER :: i
INTEGER, intent(in) :: n
REAL*8, intent(inout) :: x(0:n-1,0:1)

do i=0,n-1 
   x(i,0)=REAL(i)
   x(i,1)=n-REAL(i)
        
enddo

return
end

   1 import os
   2 os.system('rm sub6.so') # Comment out for rebuilding Fortran module
   3 
   4 if not(os.path.exists('sub6.so')):
   5     os.system('f2py --fcompiler=gnu95  -m sub6 -c ./sub6.f95 ')
   6 
   7 
   8 from sub6 import sub6
   9 from pylab import *
  10 
  11 n=10
  12 x=zeros((n,2),dtype=float,order='Fortran')
  13 sub6(x,n)
  14 
  15 print x

LehreWiki: OpenSource2010/Lesson7 (last edited 2009-11-30 13:02:52 by anonymous)