30
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 [email protected] L. Risser CNRS / Institut de Mathématiques de Toulouse

Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

  • Upload
    others

  • View
    17

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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

[email protected]

L. Risser CNRS / Institut de Mathématiques de Toulouse

Page 2: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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.

Page 3: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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

Page 4: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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

Page 5: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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

Page 6: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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

Page 7: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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).

Page 8: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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

Page 9: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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

Page 10: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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︎

Page 11: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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 ︎

Page 12: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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 ︎

Page 13: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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

Page 14: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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︎

Page 15: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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

Page 16: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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

Page 17: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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

Page 18: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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

Page 19: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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) ︎

Page 20: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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

Page 21: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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; ︎%}︎

Page 22: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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

Page 23: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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/

Page 24: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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 ︎

Page 25: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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

Page 26: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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

Page 27: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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 ︎︎

Page 28: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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 !

Page 29: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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

Page 30: Python intermédiaire pour les scientifiqueslaurent.risser.free.fr/TEACHING/CoursPython_session2.pdfL. Risser CNRS / Institut de Mathématiques de Toulouse Python intermédiaire pour

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