Currently Being Moderated

## F2Py and Static Libraries

VERSION 1
Created on: Apr 29, 2013 11:21 PM by Jules Kouatchou - Last Modified:  Apr 30, 2013 12:11 AM by Jules Kouatchou

We want to show an example how to use F2Py to link a Fortran subroutine with pre-built static libraries.

Assume that we have three methods to compute a matrice multiplication and we want to write Fortran subroutines to implement those methods (each method is contained in its own file.

Method 1: Loop

``````      subroutine matMult_loop1(A, B, C, n1, n2, n3)

INTEGER n1, n2, n3
DOUBLE PRECISION A(n1,n2)
DOUBLE PRECISION B(n2,n3)
DOUBLE PRECISION C(n1,n3)

INTEGER i, j, k

do j = 1, n3
do i = 1, n1
C(i, j) = 0.
do k = 1, n2
C(i, j) = C(i, j) + A(i, k)*B(k, j)
enddo
enddo
enddo

RETURN

end subroutine matMult_loop1
``````

Method 2: Loop

``````      subroutine matMult_loop2(A, B, C, n1, n2, n3)

INTEGER n1, n2, n3
DOUBLE PRECISION A(n1,n2)
DOUBLE PRECISION B(n2,n3)
DOUBLE PRECISION C(n1,n3)

INTEGER i, j, k

do j = 1, n3
do i = 1, n1
C(i, j) = 0
enddo
do k = 1, n2
do i = 1, n1
C(i, j) = C(i, j) + A(i, k)*B(k, j)
enddo
enddo
enddo

RETURN

end subroutine matMult_loop2
``````

Method 3: Intrinsic Fortran function (matmult)

``````      subroutine matMult_func(A, B, C, n1, n2, n3)

INTEGER n1, n2, n3
DOUBLE PRECISION A(n1,n2)
DOUBLE PRECISION B(n2,n3)
DOUBLE PRECISION C(n1,n3)

C = matmul(A,B)

RETURN

end subroutine matMult_func
``````

Creation of the Static Library

You can use the following Makefile to create (assuming that the name of the source files are  matMult_loop1.F90, matMult_loop2.F90 and matMult_func.F90) the static library:

`FC = gfortranFFLAGS = -fPICSRCS_F = \$(wildcard  matMult_*.F90)OBJS   = \$(SRCS_F:.F90=.o)all: \$(OBJS)        ar crs libmatMultiplication.a \$(OBJS)clean:        rm -f *.o *.mod *.so *.a.SUFFIXES:.SUFFIXES: .o .f .F90 .h.F90.o: \$(FSOURCE)        \$(FC) -c \$(FFLAGS) \$?`

After you create the Makefile file, you can issue the command:

``````make
``````

and you will get the static library: libmatMultiplication.a

Fortran Subroutine Relying on the Static Library

Now, let us write a Fortran subroutine (contains in a file named matrixMult.F90) that will use the library:

``````      subroutine matrixMult(A, B, C, n1, n2, n3, iCase)

INTEGER, intent(in) :: n1, n2, n3
INTEGER, intent(in) :: iCase
DOUBLE PRECISION, intent(in) :: A(n1,n2)
DOUBLE PRECISION, intent(in) :: B(n2,n3)
DOUBLE PRECISION, intent(out) :: C(n1,n3)

SELECT CASE (iCase)
CASE (1)
CALL matMult_loop1(A, B, C, n1, n2, n3)
CASE (2)
CALL matMult_loop2(A, B, C, n1, n2, n3)
CASE (3)
CALL matMult_func (A, B, C, n1, n2, n3)
END SELECT

RETURN

end subroutine matrixMult
``````

Generating the Python Module with F2Py

Here are the command lines to generate the module (to be used in a Python script) by F2Py:

``````f2py -m multMatrices -h sgnFile.pyf matrixMult.F90
f2py -c --fcompiler=gnu95 sgnFile.pyf matrixMult.F90 -L{Full_Path_to_Library} -lmatMultiplication
``````

You will obtain the file multMatrices.so.

Writing a Python Code to Test Matrix Multiplications

The following Python code (named f2py_matrixMult.py) can be used to test the the different matrix multiplication methods:

``````#!/usr/bin/env python

import numpy as np
from time import *
import sys
import multMatrices

n1 = int(sys.argv[1])
n2 = int(sys.argv[2])
n3 = int(sys.argv[3])

A = np.random.rand(n1,n2)
B = np.random.rand(n2,n3)

#-------
# Case 1
#-------
beg = time()
AB = multMatrices.matrixmult(A,B,1)
end = time()

print 'Loop1: time for','AB'+str(np.shape(AB)),'=','A'+str(np.shape(A)),'B'+str(
np.shape(B)),'is', end - beg,'s'

#-------
# Case 2
#-------
beg = time()
AB = multMatrices.matrixmult(A,B,2)
end = time()

print 'Loop2: time for','AB'+str(np.shape(AB)),'=','A'+str(np.shape(A)),'B'+str(np.shape(B)),'is', end - beg,'s'

#-------
# Case 3
#-------
beg = time()
AB = multMatrices.matrixmult(A,B,3)
end = time()

print 'matmul function: time for','AB'+str(np.shape(AB)),'=','A'+str(np.shape(A)),'B'+str(np.shape(B)),'is', end - beg,'s'

``````

To run the Python script, issue the command:

``````./f2py_matrixMult.py n1 n2 n3
``````

where n1, n2 and n3 are the dimensions of the matrices:

Timing Numbers

n1,n2,n3
Method 1
Method 2
Method 3
1000,1500,100015.259.611.33
1500,1500,150040.0921.613.32
1500,2000,150055.6228.824.49