python intermédiaire pour les...
TRANSCRIPT
L. Risser CNRS / Institut de Mathématiques de Toulouse
Python intermédiaire pour les scientifiques Session 2/5 : Python pour le numérique
Laurent Risser Ingénieur de Recherche à l'Institut de Mathématiques de Toulouse
L. Risser CNRS / Institut de Mathématiques de Toulouse
L. Risser CNRS / Institut de Mathématiques de Toulouse
Résumé
En bref : 1. Correction du TP de la session précédente. 2. Présentation de Scipy. 3. TP : utilisation de Scipy pour l’optimisation et la statistique. 4. Interactions simples entre Python et un code compilé. 5. Interfaçage Python - Fortran avec f2py 6. Interfaçage Python - C/C++ avec SWIG. 7. Compilation avec Pythran.
L. Risser CNRS / Institut de Mathématiques de Toulouse
2) Scipy
Scipy est une bibliothèque pour les mathématiques, la science, et l'ingénierie → Utilise massivement la classe array de Numpy. On peut voir ce que Scipy peut faire à la page http://docs.scipy.org/doc/scipy/reference/ : • Integration (scipy.integrate) • Optimization and root finding (scipy.optimize) • Interpolation (scipy.interpolate) • Fourier Transforms (scipy.fftpack) • Signal Processing (scipy.signal) • Linear Algebra (scipy.linalg) • Sparse Eigenvalue Problems with ARPACK • Compressed Sparse Graph Routines scipy.sparse.csgraph • Spatial data structures and algorithms (scipy.spatial) • Statistics (scipy.stats) • Multi-dimensional image processing (scipy.ndimage) • Clustering package (scipy.cluster) • Orthogonal distance regression (scipy.odr) • Sparse matrices (scipy.sparse) • Sparse linear algebra (scipy.sparse.linalg) • Compressed Sparse Graph Routines (scipy.sparse.csgraph) • File inputs/outputs (scipy.io) • … et bien d’autres encore
SciPy
L. Risser CNRS / Institut de Mathématiques de Toulouse
Exemple de fonctions d'algèbre linéaire :
SciPy
import numpy as np ︎from scipy import linalg ︎︎A = np.array([[1,2],[3,4]]) ︎︎linalg.inv(A) ︎→ array([[-2. , 1. ], [ 1.5, -0.5]]) ︎︎linalg.pinv(A) #generalized inverse︎→ array([[-2. , 1. ],[ 1.5, -0.5]]) ︎︎A.dot(linalg.inv(A)) #double check ︎→ array([[1.0e+00, 0.0e+00],[4.4e-16, 1.0e+00]]) ︎︎linalg.det(A) ︎→ -2.0 ︎︎
Remarque : certaines fonctions sont aussi disponibles dans np.linalg mais sont plus simples
la,v = linalg.eig(A) ︎l1,l2 = la︎︎→ print l1, l2 #eigenvalues ︎(-0.372281323269+0j) (5.37228132327+0j) ︎︎print v[:,0] #first eigenvector ︎→ [-0.82456484 0.56576746] ︎︎print v[:,1] #second eigenvector ︎→ [-0.41597356 -0.90937671] ︎
…︎U,s,Vh = linalg.svd(A) #singular value decomp. ︎…︎linalg.expm2(A) #matrix exponential︎…︎
2) Scipy
L. Risser CNRS / Institut de Mathématiques de Toulouse
SciPy Exemple de fonction d’optimisation :
import numpy as np ︎from scipy.optimize import minimize︎︎def rosen(x): ︎
"""The Rosenbrock function"""︎return sum(100.0*(x[1:]-x[:-1]**2.0)**2.0 + (1-x[:-1])**2.0) ︎
︎x0 = np.array([1.3, 0.7, 0.8, 1.9, 1.2]) ︎rosen(x0) ︎→ 848.2200 ︎︎res = minimize(rosen, x0, method='nelder-mead',options={'xtol': 1e-8, 'disp': True}) ︎︎→ Optimization terminated successfully. Current function value: 0.000000 ︎→ Iterations: 339 Function evaluations: 571 ︎︎print(res.x) ︎→ [ 1. 1. 1. 1. 1.] ︎︎rosen(res.x) ︎→ 4.861e-17 ︎
2) Scipy
L. Risser CNRS / Institut de Mathématiques de Toulouse
SciPy Exemple de fonction en statistique :
import scipy.stats︎︎rvs1 = scipy.stats.norm.rvs(loc=5, scale=10, size=500) ︎rvs2 = scipy.stats.norm.rvs(loc=5, scale=10, size=500) ︎rvs3 = scipy.stats.norm.rvs(loc=8, scale=10, size=500) ︎︎scipy.stats.ttest_ind(rvs1, rvs2) #t-test (returns: calculated t-statistic / two-tailed p-value) ︎→ (-0.5489, 0.5831) ︎︎scipy.stats.ttest_ind(rvs1, rvs3) ︎→ (-4.533, 6.507e-6) ︎︎scipy.stats.ks_2samp(rvs1, rvs2) #Kolmogorov-Smirnov test (returns: KS statistic / two-tailed p-value) ︎→ (0.0259, 0.9954) ︎︎scipy.stats.ks_2samp(rvs1, rvs3) ︎→ (0.1139, 0.0027) ︎︎︎︎
2) Scipy
L. Risser CNRS / Institut de Mathématiques de Toulouse
4) Interactions simples entre Python et un code compilé
Interaction possible de Python avec un code compilé /programme à l’aide d’appels système
import os︎︎… ︎︎MaLigneDeCommande="./MyProgram -i data.csv -d …"︎os.system(MaLigneDeCommande) ︎︎…︎
→ Python va attendre la fin du programme MyProgram pour executer la ligne suivante (à moins qu’il ne soit lancé en tache de fond).
L. Risser CNRS / Institut de Mathématiques de Toulouse
4) Interactions simples entre Python et un code compilé
Interaction possible de Python avec un code compilé /programme à l’aide d’appels système
import os︎︎[lit ou genere des donnees] ︎︎[Sauvegarde les donnees] ︎︎MaLigneDeCommande="./MyProgram [nom des fichiers en entree] [nom des fichiers en sortie]"︎os.system(MaLigneDeCommande) ︎︎[Lecture des donnees] ︎︎[Utilisation des donnees] ︎︎
• Simple et efficace • Nécessite des accès disque dur
L. Risser CNRS / Institut de Mathématiques de Toulouse
5) Interface Python/Fortran avec f2py
Interfaçage Python/Fortran avec f2py
• F2PY (Fortran to Python interface generator) permet d’interfacer Python avec Fortran 77/90/95 ainsi que C • Fait partie de SciPy • Informations et tutoriel : https://docs.scipy.org/doc/numpy-dev/f2py/ • Note : un compilateur Fortran doit être préalablement installé Fonctionnement : • On considère un fichier exemple.f avec des fonctions Fortran • F2PY génère un fichier dit signature exemple.pyf qui contient les informations par défaut pour enrober (wrap) exemple.f sous Python • Spécification des entrées et sorties dans la signature (optionnel, tous est input sinon) • F2PY utilise exemple.pyf pour générer un fichier Fortran faisant les liens • F2PY compile finalement tous les fichiers sources exemple.so • La librairie exemple.so est appelable comme un module Python classique
L. Risser CNRS / Institut de Mathématiques de Toulouse
5) Interface Python/Fortran avec f2py
Exemple issu de https://docs.scipy.org/doc/numpy-dev/f2py/ :
fibo.f : ︎C FILE: FIBO.F SUBROUTINE FIB (A,N) C C CALCULATE FIRST N FIBONACCI NUMBERS C INTEGER N REAL*8 A(N) DO I=1,N IF (I.EQ.1) THEN A(I) = 0.0D0 ELSEIF (I.EQ.2) THEN A(I) = 1.0D0 ELSE A(I) = A(I-1) + A(I-2) ENDIF ENDDO END C END FILE FIBO.F︎
L. Risser CNRS / Institut de Mathématiques de Toulouse
5) Interface Python/Fortran avec f2py
Exemple issu de https://docs.scipy.org/doc/numpy-dev/f2py/ :
fibo.f : ︎C FILE: FIBO.F SUBROUTINE FIB (A,N) C C CALCULATE FIRST N FIBONACCI NUMBERS C INTEGER N REAL*8 A(N) DO I=1,N IF (I.EQ.1) THEN A(I) = 0.0D0 ELSEIF (I.EQ.2) THEN A(I) = 1.0D0 ELSE A(I) = A(I-1) + A(I-2) ENDIF ENDDO END C END FILE FIBO.F︎
fibo.pyf : ︎! -*- f90 -*- ︎python module fibo2 ! in
interface ! in :fibo2 subroutine fib(a,n) ! in :fibo2:fibo.f real*8 dimension(n) :: a integer optional,check(len(a)>=n),depend(a) :: n=len(a) end subroutine fib end interface
end python module fibo2︎
Génération du fichier signature fibo.f : f2py fibo.f -m fibo2 -h fibo.pyf︎où : • -m spécifie le nom du module d’extension • -h spécifie le nom du fichier signature ︎
L. Risser CNRS / Institut de Mathématiques de Toulouse
5) Interface Python/Fortran avec f2py
Exemple issu de https://docs.scipy.org/doc/numpy-dev/f2py/ :
fibo.f : ︎C FILE: FIBO.F SUBROUTINE FIB (A,N) C C CALCULATE FIRST N FIBONACCI NUMBERS C INTEGER N REAL*8 A(N) DO I=1,N IF (I.EQ.1) THEN A(I) = 0.0D0 ELSEIF (I.EQ.2) THEN A(I) = 1.0D0 ELSE A(I) = A(I-1) + A(I-2) ENDIF ENDDO END C END FILE FIBO.F︎
fibo.pyf : ︎! -*- f90 -*- ︎python module fibo2
interface subroutine fib(a,n) real*8 dimension(n),intend(out),depend(n) :: a integer intend(in):: n end subroutine fib end interface
end python module fibo2︎
Modification de fibo.pyf : • n est un argument • a doit être retourné à Python • a doit avoir la taille n ︎
L. Risser CNRS / Institut de Mathématiques de Toulouse
5) Interface Python/Fortran avec f2py
Exemple issu de https://docs.scipy.org/doc/numpy-dev/f2py/ :
fibo.f : ︎C FILE: FIBO.F SUBROUTINE FIB (A,N) C C CALCULATE FIRST N FIBONACCI NUMBERS C INTEGER N REAL*8 A(N) DO I=1,N IF (I.EQ.1) THEN A(I) = 0.0D0 ELSEIF (I.EQ.2) THEN A(I) = 1.0D0 ELSE A(I) = A(I-1) + A(I-2) ENDIF ENDDO END C END FILE FIBO.F︎
Dans Python : ︎︎import fibo2 ︎︎print fib2.fib.__doc__ ︎→ fib - Function signature: ︎→ a = fib(n) ︎→ Required arguments: ︎→ n : input int ︎→ Return objects: ︎→ a : rank-1 array('d') with bounds (n) ︎︎print fib2.fib(8) ︎→ [ 0. 1. 1. 2. 3. 5. 8. 13.] ︎
Compilation et création de fibo2.so : f2py -c fibo.pyf fibo.f ︎
où -c génère la librairie
L. Risser CNRS / Institut de Mathématiques de Toulouse
5) Interface Python/Fortran avec f2py
Exemple issu de https://docs.scipy.org/doc/numpy-dev/f2py/ :
fibo.f : ︎C FILE: FIBO.F SUBROUTINE FIB (A,N) C C CALCULATE FIRST N FIBONACCI NUMBERS C INTEGER N REAL*8 A(N) DO I=1,N IF (I.EQ.1) THEN A(I) = 0.0D0 ELSEIF (I.EQ.2) THEN A(I) = 1.0D0 ELSE A(I) = A(I-1) + A(I-2) ENDIF ENDDO END C END FILE FIBO.F︎
Tout peut aussi être fait en une commande en modifiant fibo.f et : f2py -c –m fibo3 fibo3.f︎
fibo3.f : ︎C FILE: FIBO3.F SUBROUTINE FIB (A,N) C C CALCULATE FIRST N FIBONACCI NUMBERS C INTEGER N REAL*8 A(N) Cf2py intent(in) n Cf2py intent(out) a Cf2py depend(n) a DO I=1,N IF (I.EQ.1) THEN A(I) = 0.0D0 ELSEIF (I.EQ.2) THEN A(I) = 1.0D0 ELSE A(I) = A(I-1) + A(I-2) ENDIF ENDDO END C END FILE FIBO3.F︎
L. Risser CNRS / Institut de Mathématiques de Toulouse
5) Interface Python/Fortran avec f2py
Exemple issu de https://docs.scipy.org/doc/numpy-dev/f2py/ :
fibo.f : ︎C FILE: FIBO.F SUBROUTINE FIB (A,N) C C CALCULATE FIRST N FIBONACCI NUMBERS C INTEGER N REAL*8 A(N) DO I=1,N IF (I.EQ.1) THEN A(I) = 0.0D0 ELSEIF (I.EQ.2) THEN A(I) = 1.0D0 ELSE A(I) = A(I-1) + A(I-2) ENDIF ENDDO END C END FILE FIBO.F︎
Tout peut aussi être fait en une commande en modifiant fibo.f et : f2py -c –m fibo3 fibo3.f︎
fibo3.f : ︎C FILE: FIBO3.F SUBROUTINE FIB (A,N) C C CALCULATE FIRST N FIBONACCI NUMBERS C INTEGER N REAL*8 A(N) Cf2py intent(in) n Cf2py intent(out) a Cf2py depend(n) a DO I=1,N IF (I.EQ.1) THEN A(I) = 0.0D0 ELSEIF (I.EQ.2) THEN A(I) = 1.0D0 ELSE A(I) = A(I-1) + A(I-2) ENDIF ENDDO END C END FILE FIBO3.F︎
Retour d’expérience sur ce tutoriel (sous Ubuntu) : tout fonctionne parfaitement
L. Risser CNRS / Institut de Mathématiques de Toulouse
5) Interface Python/Fortran avec f2py
Mais au fait, est-ce que ça sert vraiment à quelque chose ?
fibo.f : ︎C FILE: FIBO.F SUBROUTINE FIB (A,N) C C CALCULATE FIRST N FIBONACCI NUMBERS C INTEGER N REAL*8 A(N) DO J=1,100000000 DO I=1,N IF (I.EQ.1) THEN A(I) = 0.0D0 ELSEIF (I.EQ.2) THEN A(I) = 1.0D0 ELSE A(I) = A(I-1) + A(I-2) ENDIF ENDDO ENDDO END C END FILE FIBO.F︎
≈ 1.1 secondes sur mon PC avec n=8
fibo.py : def pyfibo(n):
A=np.zeros((n)) for j in range(100000000): for i in range(n): if i==0: A[i]=0. elif i==1: A[i]=1. else: A[i]=A[i-1]+A[i-2]
Suite calculée 108 fois
208 secondes sur mon PC avec n=8
Gain ≈ facteur 200
L. Risser CNRS / Institut de Mathématiques de Toulouse
6) Interface Python/C++ avec SWIG
Interfaçage Python/C++
L’API (Application Programmers Interface) Python contient un ensemble de fonctions, macros et variables qui permettent de compiler du code C/C++ appelable par Python comme un module. • Inclure Python.h dans le code C/C++ • Suivre les instructions de https://docs.python.org/2/extending/extending.html
L. Risser CNRS / Institut de Mathématiques de Toulouse
6) Interface Python/C++ avec SWIG
Interfaçage Python/C++
L’API (Application Programmers Interface) Python contient un ensemble de fonctions, macros et variables qui permettent de compiler du code C/C++ appelable par Python comme un module. • Inclure Python.h dans le code C/C++ • Suivre les instructions de https://docs.python.org/2/extending/extending.html Il est possible de simplifier la démarche en utilisant SWIG : → Simple Wrapper Interface Generator SWIG génère des fichiers pour interfacer C/C++ avec de nombreux langages dont Python
L. Risser CNRS / Institut de Mathématiques de Toulouse
6) Interface Python/C++ avec SWIG
Interfaçage Python/C++ avec SWIG
Site web : http://www.swig.org 1) Installation de SWIG : • Configuration de la compilation avec ./configure (sur ma machine ./configure –without-pcre) • Compilation avec make 2) Compilation d’un fichier C/C++ pour Python : • Ecriture d’un fichier C/C++ simple (ex : example.c) • Ecriture d’un fichier interface (ex : example.i) • Exécution de SWIG pour générer un fichier d’interface (ici example_warp.c)
swig -python example.i︎• Compile chaque fichier et création d’une librairie (ici example.so)
gcc -c example.c example_wrap.c -I/usr/local/include/python2.1︎ld -shared example.o example_wrap.o -o _example.so ︎
3) Appel de example.so dans Python • Comme une librairie classique, ex : import example puis example.fct(3) ︎
L. Risser CNRS / Institut de Mathématiques de Toulouse
6) Interface Python/C++ avec SWIG
Interfaçage Python/C++ avec SWIG
Site web : http://www.swig.org 1) Installation de SWIG : • Configuration de la compilation avec ./configure (sur ma machine ./configure –without-pcre) • Compilation avec make 2) Compilation d’un fichier C/C++ pour Python : • Ecriture d’un fichier C/C++ simple (ex : example.c) • Ecriture d’un fichier interface (ex : example.i) • Exécution de SWIG pour générer un fichier d’interface (ici example_warp.c)
swig -python example.i︎• Compile chaque fichier et création d’une librairie (ici example.so)
gcc -c example.c example_wrap.c \ -I/usr/local/include/python2.1︎ld -shared example.o example_wrap.o -o _example.so ︎
3) Appel de example.so dans Python • Comme une librairie classique, ex : import example puis example.fct(3) ︎
Retour d’experience (sous Mac OS) sur le tutoriel SWIG de http://www.swig.org : Un peu plus dur que prévu notamment pour l’appel de librairies !
Pour m’en sortir : • je suis allé dans [racine swig]/Examples/python/simple • J’ai exécuté le makefile de l’exemple • En l’exécutant, j’ai vu les bonnes commandes pour faire tourner SWIG sur ma machine
L. Risser CNRS / Institut de Mathématiques de Toulouse
6) Interface Python/C++ avec SWIG
Pour compiler : swig –I"./Lib/" –I"./Lib/python/" -python example.i gcc -c -I. example_wrap.c example.c -I/Users/risser/anaconda/include/python2.7 -I/Users/risser/anaconda/lib/python2.7/config cc -bundle -undefined suppress -flat_namespace example.o example_wrap.o -o _example.so
Interfaçage Python/C++ avec SWIG
example.c : ︎/* A global variable */︎double Foo = 3.0; ︎/* Compute the greatest common divisor of positive integers */︎int gcd(int x, int y) {︎ int g; ︎ g = y; ︎ while (x > 0) {︎ g = x; ︎ x = y % x; ︎ y = g; ︎ }︎ return g; ︎}︎
example.i : ︎%module example︎︎%inline %{︎extern int gcd(int x, int y); ︎extern double Foo; ︎%}︎
L. Risser CNRS / Institut de Mathématiques de Toulouse
6) Interface Python/C++ avec SWIG
Interfaçage Python/C++ avec SWIG
example.c : ︎/* A global variable */︎double Foo = 3.0; ︎/* Compute the greatest common divisor of positive integers */︎int gcd(int x, int y) {︎ int g; ︎ g = y; ︎ while (x > 0) {︎ g = x; ︎ x = y % x; ︎ y = g; ︎ }︎ return g; ︎}︎
Runme.py : ︎import example︎︎# Call our gcd() function ︎x = 42 ︎y = 105 ︎g = example.gcd(x, y) ︎print "The gcd of %d and %d is %d" % (x, y, g) ︎︎# Manipulate the Foo global variable︎print "Foo = ", example.cvar.Foo ︎example.cvar.Foo = 3.1415926 ︎print "Foo = ", example.cvar.Foo ︎
Gains en performance similaires à ceux obtenus avec f2py
L. Risser CNRS / Institut de Mathématiques de Toulouse
7) Compilation avec Pythran
Pythran : • Python vers C++ puis compilation du code C++ • Code compilé appelable en tant que module dans Python • Très orienté calcul scientifique (cblas, openmp, …) • Supporte très bien les numpy.array • Page web : https://pythonhosted.org/pythran/
L. Risser CNRS / Institut de Mathématiques de Toulouse
7) Compilation avec Pythran
Pythran : exemple 1
import numpy as np ︎def arc_distance(theta_1, phi_1, theta_2, phi_2): ︎ "””︎ Calculates the pairwise arc distance between all points in vector a and b. ︎ """ ︎ temp = (np.sin((theta_2-theta_1)/2)**2 + np.cos(theta_1)*np.cos(theta_2) * np.sin((phi_2-phi_1)/2)**2) ︎ distance_matrix = 2 * np.arctan2(np.sqrt(temp), np.sqrt(1-temp)) ︎ return distance_matrix ︎︎V1=np.random.rand(1000000) ︎V2=np.random.rand(1000000) ︎V3=np.random.rand(1000000) ︎V4=np.random.rand(1000000) ︎︎Toto=arc_distance(VA, phi_1, theta_2, phi_2) ︎ 4 secondes sur mon PC ︎
L. Risser CNRS / Institut de Mathématiques de Toulouse
7) Compilation avec Pythran
import numpy as np ︎Import Arc_distance ︎V1=np.random.rand(1000000) ︎V2=np.random.rand(1000000) ︎V3=np.random.rand(1000000) ︎V4=np.random.rand(1000000) ︎︎Toto=Arc_distance.arc_distance(VA, phi_1, theta_2, phi_2) ︎
Pythran : exemple 1
Arc_distance.py: ︎︎import numpy as np ︎︎#pythran export arc_distance(float[], float[], float[], float[]) ︎def arc_distance(theta_1, phi_1, theta_2, phi_2): ︎ "””︎ Calculates the pairwise arc distance between all points in vector a and b. ︎ """ ︎ temp = (np.sin((theta_2-theta_1)/2)**2 + np.cos(theta_1)*np.cos(theta_2) * np.sin((phi_2-phi_1)/2)**2) ︎ distance_matrix = 2 * np.arctan2(np.sqrt(temp), np.sqrt(1-temp)) ︎ return distance_matrix ︎
Compilation : pythran arc_distance.py ︎
1.7 secondes sur mon PC ︎
à rajouter avant la fonction
L. Risser CNRS / Institut de Mathématiques de Toulouse
7) Compilation avec Pythran
import numpy as np ︎Import Arc_distance ︎V1=np.random.rand(1000000) ︎V2=np.random.rand(1000000) ︎V3=np.random.rand(1000000) ︎V4=np.random.rand(1000000) ︎︎Toto=Arc_distance.arc_distance(VA, phi_1, theta_2, phi_2) ︎
Pythran : exemple 1
Arc_distance.py: ︎︎import numpy as np ︎︎#pythran export arc_distance(float[], float[], float[], float[]) ︎def arc_distance(theta_1, phi_1, theta_2, phi_2): ︎ "””︎ Calculates the pairwise arc distance between all points in vector a and b. ︎ """ ︎ temp = (np.sin((theta_2-theta_1)/2)**2 + np.cos(theta_1)*np.cos(theta_2) * np.sin((phi_2-phi_1)/2)**2) ︎ distance_matrix = 2 * np.arctan2(np.sqrt(temp), np.sqrt(1-temp)) ︎ return distance_matrix ︎
Compilation : pythran arc_distance.py ︎
1.7 secondes sur mon PC ︎
Gain = facteur 2.3 … mais : • Fonctions numpy déjà optimisées • Options openmp pas utilisées
L. Risser CNRS / Institut de Mathématiques de Toulouse
7) Compilation avec Pythran
Pythran : exemple 2
fibo4.py : import numpy as np Import time #pythran export pyfib(float) def pyfibo(n):
t_init=time.time() A=np.zeros((n)) for j in range(100000000): for i in range(n): if i==0: A[i]=0. elif i==1: A[i]=1. else: A[i]=A[i-1]+A[i-2] print str(time.time()-t_init)+’ secondes’ return A
Compilation et différentiation du code python et du code Pythranisé : pythran fibo4.py ︎ → genere fibo4.so ︎mv fibo4.py fibo5.py ︎ → permet de differencier fibo4.so et fibo5 dans Python ︎︎
L. Risser CNRS / Institut de Mathématiques de Toulouse
7) Compilation avec Pythran
Pythran : exemple 2
fibo4.py : import numpy as np Import time #pythran export pyfib(float) def pyfibo(n):
t_init=time.time() A=np.zeros((n)) for j in range(100000000): for i in range(n): if i==0: A[i]=0. elif i==1: A[i]=1. else: A[i]=A[i-1]+A[i-2] print str(time.time()-t_init)+’ secondes’ return A
Compilation et différentiation du code python et du code Pythranisé : pythran fibo4.py ︎ → genere fibo4.so ︎mv fibo4.py fibo5.py ︎ → permet de differencier fibo4.so et fibo5 dans Python ︎︎import fibo4 ︎import fibo5 ︎︎fib4.pyfib(8) ︎→ 1.108 secondes ︎→ array([0., 1., 1., 2., 3., 5., 8., 13.]) ︎fib5.pyfib(8) ︎→ 193.8 secondes ︎→ array([0., 1., 1., 2., 3., 5., 8., 13.]) ︎
• Le code Python basique a à peu près la même vitesse que tout à l’heure • Gain ≈ facteur 200 pour le code compilé avec Pythran !
L. Risser CNRS / Institut de Mathématiques de Toulouse
7) Compilation avec Pythran
Pythran : exemple 2
fibo4.py : import numpy as np Import time #pythran export pyfib(float) def pyfibo(n):
t_init=time.time() A=np.zeros((n)) for j in range(100000000): for i in range(n): if i==0: A[i]=0. elif i==1: A[i]=1. else: A[i]=A[i-1]+A[i-2] print str(time.time()-t_init)+’ secondes’ return A
Compilation et différentiation du code python et du code Pythranisé : pythran fibo4.py ︎ → genere fibo4.so ︎mv fibo4.py fibo5.py ︎ → permet de differencier fibo4.so et fibo5 dans Python ︎︎import fibo4 ︎import fibo5 ︎︎fib4.pyfib(8) ︎→ 1.108 secondes ︎→ array([0., 1., 1., 2., 3., 5., 8., 13.]) ︎fib5.pyfib(8) ︎→ 193.8 secondes ︎→ array([0., 1., 1., 2., 3., 5., 8., 13.]) ︎
• Le code Python basique a à peu près la même vitesse que tout à l’heure • Gain ≈ facteur 200 pour le code compilé avec Pythran !
Retour d’expérience (sous Ubuntu) : • Installation de Pythran un peu technique mais on s’en sort avec les explications de https://pythonhosted.org/pythran/ • Très simple une fois installé • Performances un peu décevantes par rapport au code compilé numpy mais j’aurais sans doute eu un meilleur gain en installant openmp ou cblas
• Pour les for, les if et consorts… ça dépote comme du C ou du Fortran
L. Risser CNRS / Institut de Mathématiques de Toulouse
Merci
MERCI !!!
Références :
• http://docs.scipy.org/doc/scipy/reference/ • https://docs.scipy.org/doc/numpy-dev/f2py/ • https://docs.python.org/2/extending/extending.html • http://www.swig.org • https://pythonhosted.org/pythran/ • http://scipy.org/ Remerciements :
• Etienne Gondet
• Vous