Ce diaporama a bien été signalé.
Le téléchargement de votre SlideShare est en cours. ×

Traitement des données massives (INF442, A4)

Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Chargement dans…3
×

Consultez-les par la suite

1 sur 77 Publicité

Plus De Contenu Connexe

Diaporamas pour vous (20)

Les utilisateurs ont également aimé (17)

Publicité

Similaire à Traitement des données massives (INF442, A4) (20)

Plus récents (20)

Publicité

Traitement des données massives (INF442, A4)

  1. 1. INF442 : Traitement des donn´ees massives A4 : Alg`ebre lin´eaire distribu´ee Frank Nielsen X2013 6 mai 2015
  2. 2. Plan ◮ un peu de MPI ◮ produit matriciel sur la topologie du tore ◮ la g´en´ericit´e avec la biblioth`eque C++ STL
  3. 3. MPI : pas de m´emoire globale ! → m´emoire locale pour chaque processus, ´echange de messages Diff´erent d’un fil de calcul (fork) avec m´emoire globale partag´ee (INF431) i n t main ( i n t argc , char ∗∗ argv ) { i n t rang , n , var ; i n t ∗ ptr=&var ; MPI Init (&argc , &argv ) ; MPI Comm size (MPI COMM WORLD, &n ) ; MPI Comm rank (MPI COMM WORLD, &rang ) ; ∗ ptr=rang ; ( ∗ ptr )++; p r i n t f ( ”P%d var=%dn” , rang , var ) ; MPI Finalize () ;} P0 var =1 P2 var =3 P1 var =2 P3 var =4
  4. 4. #i n c l u d e <s t d i o . h> #i n c l u d e <mpi . h> i n t main ( i n t argc , c har∗∗ argv ) { i n t rang , p , autre , taga =0, tagb =1; double a , b ; MPI Status s t a t u s ; MPI Request r e q u e s t ; MPI Init (&argc , &argv ) ; MPI Comm size (MPI COMM WORLD, &p ) ; MPI Comm rank ( MPI COMM WORLD, &rang ) ; i f (p==2) { // M´emoire locale de chaque processus a u t r e=1−rang ; // l’autre processus a=0; b=1; p r i n t f (” Proc . %d a u t r e=%d avant a=%f b=%f n” , rang , autre , a , b ) ; // double swap en utilisant une op´eration de communication sans variable locale tmp ! // on utilise en fait le buffer de communication pour tmp MPI Isend(&a , 1 , MPI DOUBLE, autre , taga , MPI COMM WORLD, &r e q u e s t ) ; MPI Isend(&b , 1 , MPI DOUBLE, autre , tagb , MPI COMM WORLD, &r e q u e s t ) ; p r i n t f (” Attendons avec MPI WAIT que l e s messages s o i e n t bie n p a r t i s . . . n” ) ; MPI Wait(& re que st , &s t a t u s ) ; // Re¸coit dans a le message avec tagb (donc la valeur de b) MPI Recv(&a , 1 , MPI DOUBLE, autre , tagb , MPI COMM WORLD, &s t a t u s ) ; // Re¸coit dans b le message avec taga (donc la valeur de a) MPI Recv(&b , 1 , MPI DOUBLE, autre , taga , MPI COMM WORLD, &s t a t u s ) ; p r i n t f (” Proc . %d apre s a=%f b=%f n” , rang , a , b ) ; } e l s e i f ( rang==0) p r i n t f (” Executez avec mpirun −np 2 mpiswap442 . exe ” ) ; M P I F i n a l i z e () ;}
  5. 5. taga=0; tagb=1; a=0; b=1; Isend(a,P1,taga); Isend(b,P1,tagb); MPI Wait; Recv(&a,tagb); Recv(&b,taga); P0 taga=0; tagb=1; a=0; b=1; Isend(a,P0,taga); Isend(b,P0,tagb); MPI Wait; Recv(&a,tagb); Recv(&b,taga); P1 0, taga 1, tagb1, tagb 0, taga m´emoire locale P0 m´emoire locale P1 [ france ~]$ mpirun -np 2 mpiswap442 .exe Proc . 1 autre =0 avant a =0.000000 b =1.000000 Attendons avec MPI_WAIT que les messages soient bien partis ... Proc . 0 autre =1 avant a =0.000000 b =1.000000 Attendons avec MPI_WAIT que les messages soient bien partis ... Proc . 1 apres a =1.000000 b =0.000000 Proc . 0 apres a =1.000000 b =0.000000
  6. 6. Alg`ebre lin´eaire en parall`ele : la r´egression Frank Nielsen 1.Les matrices en HPC-1.R´egression A6-6
  7. 7. La r´egression lin´eaire ◮ on veut pr´edire ˆy = f (x) avec f (x) = ˆβ0 + d i=1 ˆβi xi . ◮ les observations (xi , yi ) sont dans Rd × R. Pour des classes C0 et C1 (valeurs de y), on peut encoder y = 0 ssi. xi ∈ C0 et y = 1 ssi. xi ∈ C1 ◮ on classifie avec la r´egression en ´evaluant ˆyi = f (xi ) puis en seuillant : xi ∈ C0 ssi. ˆyi < 1 2 et xi ∈ C1 ssi. ˆyi ≥ 1 2 ◮ on peut augmenter l’espace des donn´ees en rajoutant une coordonn´ee x0 = 1. Ainsi x ← (x, 1) et f (x) = d i=0 ˆβi xi = x⊤ i β (d + 1 param`etres `a ´evaluer) ◮ l’erreur que l’on veut minimiser est les moindres carr´es ( Residual Sum of Squares , RSS) : ˆβ = min β n i=1 (yi − x⊤ i β)2 Frank Nielsen 1.Les matrices en HPC-1.R´egression A6-7
  8. 8. La r´egression lin´eaire et la classification Fronti`ere de d´ecision = hyperplan (espace affine de dimension d − 1 dans Rd ) Frank Nielsen 1.Les matrices en HPC-1.R´egression A6-8
  9. 9. La r´egression lin´eaire ordinaire Soit X la matrice des donn´ees de dimension n × (d + 1), y le vecteur colonne de dimension n et β le vecteur param`etre de dimension d + 1. On a la somme des diff´erences au carr´e : RSS(β) = n i=1 (yi − x⊤ i β)2 = (y − Xβ)⊤ (y − Xβ) En prenant le gradient ∇βRSS(β), on trouve l’´equation dite normale ( normal equation ) : X⊤ (y − Xβ) = 0 Pour X⊤X non-singuli`ere, on trouve ˆβ minimisant les moindres carr´es par la matrice pseudo-inverse (Penrose-Moore) : ˆβ = (X⊤ X)−1 X⊤ y = X† y Frank Nielsen 1.Les matrices en HPC-1.R´egression A6-9
  10. 10. La r´egression lin´eaire en Scilab rand(’seed ’,getdate(’s’)) x = -30:30; a=0.8; b=5; y=a *x+b; // on perturbe avec un bruit uniforme bruit=rand(1,61,’uniform ’) -0.5; y = y+10*bruit; // regression lin´eaire en scilab [aa , bb] = reglin(x, y); plot(x, y,’r+’ ); plot(x, a*x+b,’bo -’) Frank Nielsen 1.Les matrices en HPC-1.R´egression A6-10
  11. 11. La r´egression lin´eaire : ordinaire ou totale x y y = a × x (x1, y1) (x2, y2) (x3, y3) ordinary regression vs. total regression Frank Nielsen 1.Les matrices en HPC-1.R´egression A6-11
  12. 12. Comparaison de la classification par r´egression ou par k-PPV Classifieur sur un vecteur al´eatoire = variable al´eatoire ⇒ variance et biais Frank Nielsen 1.Les matrices en HPC-1.R´egression A6-12
  13. 13. Comparaison de la classification par r´egression vs. k-PPV ◮ r´egression = bon pour interpoler et extrapoler mais mod`ele rigide avec l’hypoth`ese globale d’une fonction lin´eaire f (x) (faible complexit´e = d + 1 param`etres). ⇒ grand biais et petite variance ◮ k-PPV : mod`ele f (x) localement constant, flexible, mais grande complexit´e = d × n “param`etres”. ⇒ petit biais mais grande variance Frank Nielsen 1.Les matrices en HPC-1.R´egression A6-13
  14. 14. Alg`ebre lin´eaire : les briques de base ◮ des vecteurs colonnes : v =    v1 ... vl    ◮ des matrices (square, skinny, ou fat) : M =    m1,1 ... m1,c ... ... ... ml,1 ... ml,c    ◮ plusieurs types de matrices avec leur stockage m´emoire : matrices denses O(lc), matrices diagonales, matrices sym´etriques, matrices triangulaires, matrices creuses O(l + c). Alg`ebre multi-lin´eaire et tenseurs. Frank Nielsen 1.Les matrices en HPC-1.R´egression A6-14
  15. 15. Les op´erations/primitives en alg`ebre lin´eaire Soit l = c = d les dimensions des matrices et vecteurs. ◮ le produit scalaire v1 · v2 = v⊤ 1 × v2 : O(d) ◮ le produit matrice-vecteur M × v : O(d2) ◮ le produit matrice-matrice M1 × M2 : O(d3) ◮ la factorisation (d´ecomposition) LU M = L × U (pour r´esoudre les syst`emes lin´eaires), QR, etc. Toutes ces primitives sont impl´ement´ees dans la biblioth`eque BLAS, Basic Linear Algebra Subroutines en plusieurs niveaux http://www.netlib.org/blas/ Frank Nielsen 1.Les matrices en HPC-1.R´egression A6-15
  16. 16. La multiplication matricielle : un d´efi = probl`eme ouvert ! ◮ mˆeme en s´equentiel, on ne connait pas d’algorithme optimal ! ◮ borne inf´erieure : Ω(d2), nombre d’entr´ees de la matrice carr´ee r´esultat. ◮ meilleur algorithme connu `a ce jour : O(d2.3728639) , analyse fine de l’algorithme de Coppersmith et Winograd. Le Gall, Fran¸cois (2014), “Powers of tensors and fast matrix multiplication,” Proceedings of the 39th International Symposium on Symbolic and Algebraic Computation (ISSAC 2014), arXiv:1401.7714 Frank Nielsen 1.Les matrices en HPC-1.R´egression A6-16
  17. 17. Diff´erents motifs pour le parall´elisme de donn´ees ◮ acc`es et transmissions des donn´ees M et v sur un cluster de machines : d´epend de la topologie du r´eseau d’interconnexion ◮ dispositions bloc-colonnes et bloc-colonne cycliques → largeur b du bloc ´el´ementaire (chaque bloc tient dans la m´emoire locale) Idem si on prend les lignes (= colonnes de la matrice transpos´ee)
  18. 18. Diff´erents motifs pour le parall´elisme des donn´ees Motif 2D bloc ligne-colonne , et 2D bloc ligne-colonne cyclique Damier, ´echiquier
  19. 19. Le produit matrice vecteur sur la topologie de l’anneau orient´e
  20. 20. Produit matrice-vecteur sur l’anneau : Bloc colonne 1D En BLAS, une op´eration de base : y ← y + Ax A(i) = Ai× n p :(i+1)× n p −1,·: sous-matrice bloc ligne de dimension n × n p y(i) ← y(i) + A(i) × x(i) = y(i) + j A[i][j] × x[j] ◮ initialement, A(i), x(i) et y(i) sont stock´es sur le processus Pi ◮ faire tourner les sous-vecteurs x(i) sur la topologie de l’anneau orient´e
  21. 21. Regardons la situation pour y(1) X1 X2 X3 X4 X1 X2 X3 X4 Y1 = A1,4 × X4 + A1,1 × X1 Y1 = A1,1 × X1P1 P2 P3 P4 A4,4A4,3 A1,1 A2,2 A3,3 A1,2 A1,3 A1,4 A2,1 A3,1 A4,1 A4,2 A3,2 A3,4 A2,4A2,3 A4,4A4,3 A1,1 A2,2 A3,3 A1,2 A1,3 A1,4 A2,1 A3,1 A4,1 A4,2 A3,2 A3,4 A2,4A2,3 En fond gris, les blocs qui servent aux produits locaux y(·) ← A(·, ·)x(·) + y(·)
  22. 22. X1 X2 X3 X4 X2 X1 X4 X3 Y1 = A1,3 × X3 + A1,4 × X4 + A1,1 × X1 Y1 = A1,2 × X2 + A1,3 × X3 + A1,4 × X4 + A1,1 × X1 A4,4A4,3 A1,1 A2,2 A3,3 A1,2 A1,3 A1,4 A2,1 A3,1 A4,1 A4,2 A3,2 A3,4 A2,4A2,3 A4,4A4,3 A1,1 A2,2 A3,3 A1,2 A1,3 A1,4 A2,1 A3,1 A4,1 A4,2 A3,2 A3,4 A2,4A2,3
  23. 23. produitMatriceVecteur (A, x , y ) { q = Comm rank () ; // rang du processus p = Comm size () ; // nombre de processus r = n/p ; // taille des blocs f o r ( step =0; step<p ; step++) { // on envoie le bloc de x sur le prochain nœud de l’anneau send ( x , r ) ; // communication non-bloquante // calcul local : produit matrice-vecteur bloc f o r ( i =0; i<r ; i++) { f o r ( j =0; j<r ; j++) { y [ i ] = y [ i ] + a [ i , (q−step mod p) r + j ] ∗ x [ j ] ; } } // on re¸coit le bloc de x du processus pr´ec´edent de l’anneau r e c e i v e (temp , r ) ; x = temp ;} }
  24. 24. Produit matriciel parall`ele Les algorithmes parall`eles vont d´ependre : ◮ des motifs des donn´ees ◮ de la topologie du r´eseau d’interconnexion des machines ◮ des types d’op´erations de communications utilis´es Coˆut d’une communication entre deux nœuds voisins : Temps Message = Latence + #longeur × temps par unit´e de longeur Temps Message = α + τl ◮ on mesure α et τ en ´equivalent FLOPS ◮ efficacit´e : temps s´equentiel/(P × temps parall`ele) ◮ speed-up optimal ⇔ efficacit´e = 1 Frank Nielsen 1.Les matrices en HPC-4.Complexit´e des communications A6-24
  25. 25. Le produit matriciel sur un cluster de machines C = A × B ◮ les ´el´ements des matrices n × n sont initialement distribu´es sur les P processus P1, ..., PP−1 ◮ on ´echange par messages des matrices blocs (rappel MPI : pas de m´emoire partag´ee globale) ◮ plusieurs motifs de d´ecompositions : ◮ blocs de lignes ◮ blocs de colonnes ◮ blocs de damiers ◮ les d´ecompositions sont en rapport avec les algorithmes et le r´eseau d’interconnexion (graphe complet, anneau, tore)
  26. 26. Le tore 2D ◮ on consid´ere √ P ∈ N le cˆot´e de la grille torique `a√ P × √ P = P processeurs (NB : anneau = tore 1D) ◮ chaque processeur Pi peut communiquer avec ses 4 voisins : Nord, Sud, Est, Ouest
  27. 27. Produit matriciel C = A × B sur le tore ◮ initialement, les matrices sont stock´es par bloc avec le motif de damier (par bloc 2D) sur le tore. ◮ le processus Pi,j pour i, j ∈ {1, ..., √ P} est responsable du calcul de C(i, j) = √ P k=1 A(i, k) × B(k, j) Plusieurs fa¸cons de transmettre les matrices blocs A(·, ·), B(·, ·) et C(·, ·). → nous allons voir trois principaux algorithmes
  28. 28. Produit matriciel : l’algorithme de Cannon Frank Nielsen 3.Produit matriciel-1.L’algorithme de Cannon A6-28
  29. 29. Algorithme de Cannon : vue g´en´erale ◮ n´ecessite des op´erations de pre-skewing des matrices avant les calculs locaux et des op´erations de post-skewing apr`es ces calculs locaux ◮ les communications des sous-matrices A et B sont des rotations horizontales (←) et des rotations verticales (↑). Frank Nielsen 3.Produit matriciel-1.L’algorithme de Cannon A6-29
  30. 30. A0,0 B0,0 A0,0 A0,1 A0,2 A1,2A1,1A1,0 A2,0 A2,1 A2,2 B0,0 B0,1 B0,2 B1,2B1,1B1,0 B2,0 B2,1 B2,2 A0,1 B0,1 A0,2 B0,2 A1,0 B1,0 A2,0 B2,0 A1,1 B1,1 A2,1 B2,1 A2,2 B2,2 A1,2 B1,2 A0,0 A0,1 A0,2 A1,2A1,1 A1,0 A2,0 A2,1A2,2 B0,0 B0,1 B0,2 B1,2 B1,1 B1,0 B2,0 B2,1 B2,2 A0,1 B1,0 A0,0A0,1 A0,2 A1,2 A1,1A1,0 A2,0 A2,1 A2,2 B0,0 B0,1 B0,2 B1,2 B1,1 B1,0 B2,0 B2,1 B2,2 A0,2 B2,1 A0,0 B0,2 A1,2 B2,0 A2,0 B0,0 A1,0 B0,1 A2,1 B1,1 A2,2 B2,2 A1,1 B1,2 Initialisation Pre-processing : Preskewing ´etape 1 : Calculs locaux Rotations ´etape 2: Calculs locaux Rotations A0,0 B0,0 A0,1 B1,1 A0,2 B2,2 A1,1 B1,0 A2,2 B2,0 A1,2 B2,1 A2,0 B0,1 A2,1 B1,2 A1,0 B0,2 Frank Nielsen 3.Produit matriciel-1.L’algorithme de Cannon A6-30
  31. 31. A0,2 B2,0 A0,0 A0,1A0,2 A1,2A1,1A1,0 A2,0A2,1 A2,2 B0,0 B0,1 B0,2 B1,2 B1,1 B1,0 B2,0 B2,1 B2,2 A0,0 B0,1 A0,1 B1,2 A1,0 B0,0 A2,0 B0,0 A1,1 B1,1 A2,1 B1,1 A2,0 B0,2 A1,2 B2,2 ´etape 3 : Calculs locaux Rotations A0,0 A0,1 A0,2 A1,2A1,1 A1,0 A2,0 A2,1A2,2 B0,0 B0,1 B0,2 B1,2 B1,1 B1,0 B2,0 B2,1 B2,2 A0,0 B0,0 A0,1 B1,1 A0,2 B2,2 A1,1 B1,0 A2,2 B2,0 A1,2 B2,1 A2,0 B0,1 A2,1 B1,2 A1,0 B0,2 A0,0 B0,0 A0,0 A0,1 A0,2 A1,2A1,1A1,0 A2,0 A2,1 A2,2 B0,0 B0,1 B0,2 B1,2B1,1B1,0 B2,0 B2,1 B2,2 A0,1 B0,1 A0,2 B0,2 A1,0 B1,0 A2,0 B2,0 A1,1 B1,1 A2,1 B2,1 A2,2 B2,2 A1,2 B1,2 Postprocessing: Post-skewing Configuration initiale ! Frank Nielsen 3.Produit matriciel-1.L’algorithme de Cannon A6-31
  32. 32. // Pr´e-traitement des matrices A et B // Preskew ← : ´el´ements diagonaux de A align´es verticalement sur la premi`ere colonne PreskewHorizontal(A); // Preskew ↑ : ´el´ements diagonaux de B align´es horizontalement sur la premi`ere ligne PreskewVertical(B); // Initialise les blocs de C `a 0 C = 0; pour k = 1 `a √ P faire C ← C+ProduitsLocaux(A,B); // d´ecalage vers la gauche ← RotationHorizontale(A); // d´ecalage vers le haut ↑ RotationVerticale(B); fin // Post-traitement des matrices A et B : op´erations inverses du pr´e-traitement // Preskew → PostskewHorizontal(A); // Preskew ↓ PostskewVertical(B); Frank Nielsen 3.Produit matriciel-1.L’algorithme de Cannon A6-32
  33. 33. Produit matriciel : algorithme de Fox Frank Nielsen 3.Produit matriciel-2.Algorithme de Fox A6-33
  34. 34. Algorithme de Fox ◮ initialement, les donn´ees ne bougent pas (= pas de pr´e-traitement) ◮ diffusions horitonzales des diagonales de A (d´ecal´ees vers la droite) ◮ rotations verticales de B, de bas en haut ... appel´e aussi algorithme broadcast-multiply-roll Frank Nielsen 3.Produit matriciel-2.Algorithme de Fox A6-34
  35. 35. A0,0 A0,0 A0,0 A1,1A1,1 A1,1 A2,2 A2,2A2,2 ´etape 1 : Diffusion A (premi`ere diagonale) Calculs locaux ´etape 1’: Rotation verticale de B A0,1 B1,0 A0,1 A0,1A0,1 A1,2A1,2A1,2 A2,0A2,0 A2,0 A0,1 B1,1 A0,1 B1,2 A1,2 B2,0 A2,0 B0,0 A1,2 B2,1 A2,0 B0,1 A2,0 B0,2 A1,2 B2,2 ´etape 2 : Diffusion A (deuxi`eme diagonale) Calcul locaux A0,0 B0,0 A0,0 B0,1 A0,0 B0,2 A1,1 B1,0 A2,2 B2,0 A1,1 B1,1 A2,2 B2,1 A2,2 B2,2 A1,1 B1,2 B0,0 B0,1 B0,2 B1,2B1,1B1,0 B2,0 B2,1 B2,2 B1,2B1,1B1,0 B2,0 B2,1 B2,2 B0,0 B0,1 B0,2 A0,0 A0,0 A0,0 A1,1A1,1 A1,1 A2,2 A2,2A2,2 B1,2B1,1B1,0 B2,0 B2,1 B2,2 B0,0 B0,1 B0,2 Frank Nielsen 3.Produit matriciel-2.Algorithme de Fox A6-35
  36. 36. A0,2 B2,0 A0,2 A0,2 A0,2 A1,0A1,0A1,0 A2,1 A2,1 A2,1 A0,2 B2,1 A0,2 B2,2 A1,0 B0,0 A2,1 B1,0 A1,0 B0,1 A2,1 B1,1 A2,1 B1,2 A1,0 B0,2 ´etape 2’: Rotation verticale de B ´etape 3: Diffusion A (troisi`eme diagonale) Calculs locaux A0,1 A0,1A0,1 A1,2A1,2A1,2 A2,0A2,0 A2,0 B2,0 B2,1 B2,2 B0,0 B0,1 B0,2 B1,2B1,1B1,0 B2,0 B2,1 B2,2 B0,0 B0,1 B0,2 B1,2B1,1B1,0 A0,0 B0,0 A0,1 B0,1 A0,2 B0,2 A1,0 B1,0 A2,0 B2,0 A1,1 B1,1 A2,1 B2,1 A2,2 B2,2 A1,2 B1,2 ´etape 3’: Rotation verticale de B → ´etat final B0,0 B0,1 B0,2 B1,2B1,1B1,0 B2,0 B2,1 B2,2 Frank Nielsen 3.Produit matriciel-2.Algorithme de Fox A6-36
  37. 37. // Initialise les blocs de C `a 0 C = 0; pour i = 1 `a √ P faire // Broadcast Diffusion de la i-i`eme diagonale de A sur les lignes de processus du tore; // Multiply C ← C+ProduitsLocaux(A,B); // Roll // Rotation verticale : d´ecalage vers le haut ↑ RotationVerticale(B); fin Frank Nielsen 3.Produit matriciel-2.Algorithme de Fox A6-37
  38. 38. Produit matriciel : algorithme de Snyder Frank Nielsen 3.Produit matriciel-3.Algorithme de Snyder A6-38
  39. 39. Produit matriciel : algorithme de Snyder ◮ initialement, on transpose B : B ← B⊤ ◮ sommes globales (reduce) sur les lignes de processeurs ◮ accumulation des r´esultats sur les diagonales principales de C (d´ecal´ees `a chaque ´etape vers la droite) ◮ rotations verticales de bas en haut A0,0 A0,1 A0,2 A1,0 A1,1 A1,2 A2,0 A2,1 A2,2 premi`ere diagonale deuxi`eme diagonale troisi`eme diagonale Frank Nielsen 3.Produit matriciel-3.Algorithme de Snyder A6-39
  40. 40. A0,0 A0,1 A0,2 A1,2A1,1A1,0 A2,0 A2,1 A2,2 B0,0 B0,1 B0,2 B1,2B1,1B1,0 B2,0 B2,1 B2,2 Initialisation Pre-processing : Transpose B → B⊤ ´etape 1: Calculs locaux et accumulation sur la premi`ere diagonale de C B0,0 B1,1 B2,2 B1,0 B2,0 B0,2 B0,1 B2,1 B1,2 C0,0 C1,1 C2,2 B⊤ A0,0 A0,1 A0,2 A1,2A1,1 A1,0 A2,0 A2,1A2,2 A0,0 A0,1 A0,2 A1,2A1,1 A1,0 A2,0 A2,1A2,2 B0,0 B1,1 B2,2 B1,0 B2,0 B0,2 B0,1 B2,1 B1,2 Frank Nielsen 3.Produit matriciel-3.Algorithme de Snyder A6-40
  41. 41. ´etape 1’: Rotation verticale de B A0,0 A0,1 A0,2 A1,2A1,1 A1,0 A2,0 A2,1A2,2 B0,0 B1,0 B2,0 B1,1B0,1 B2,1 B2,2B0,2 B1,2 ´etape 2: Calculs locaux et accumulation sur la deuxi`eme diagonale de C ´etape 2’: Rotation verticale de B A0,0 A0,1 A0,2 A1,2A1,1 A1,0 A2,0 A2,1A2,2 B0,0 B1,0 B2,0 B1,1B0,1 B2,1 B2,2B0,2 B1,2 C0,1 C1,2 C2,0 A0,0 A0,1 A0,2 A1,2A1,1 A1,0 A2,0 A2,1A2,2 B0,0 B1,0 B2,0 B1,1B0,1 B2,1 B2,2B0,2 B1,2 C0,2 C1,0 C2,1 ´etape 3: Calculs locaux et accumulation sur la troisi`eme diagonale de C Frank Nielsen 3.Produit matriciel-3.Algorithme de Snyder A6-41
  42. 42. // Preskewing Transpose B; // Phase de calcul for k = 1 to √ P do // Produit scalaire ligne par ligne sur A et B Calcule localement par bloc : C = A × B; // On calcule les matrices blocs d´efinitives de C pour la k-i`eme diagonale // Somme globale ´equivaut au produit scalaire d’une ligne de A avec une ligne de B Somme globale de C sur les processeurs lignes pour la k-i`eme diagonale de C; D´ecalage vertical de B; end // On transpose B afin de retrouver la matrice initiale Transpose B; Frank Nielsen 3.Produit matriciel-3.Algorithme de Snyder A6-42
  43. 43. En r´esum´e Le produit matriciel sur le tore : ◮ algorithme de Cannon (pr´e-processing) ◮ algorithme de Fox (broadcast-multiply-roll) ◮ algorithme de Snyder (sommes globales) Comparatif des trois algorithmes : Algorithme Cannon Fox Snyder pr´etraitement preskewing de A et B rien transposition B ← B⊤ produits matriciels en place en place sur les lignes PEs mouvements A gauche → droite diffusion horizontale rien mouvements B bas → haut bas → haut bas → haut Frank Nielsen 3.Produit matriciel-3.Algorithme de Snyder A6-43
  44. 44. La biblioth`eque C++ STL : g´en´ericit´e
  45. 45. Les classes g´en´eriques en C++ But de la g´en´ericit´e = produire du code ind´ependant des types (instanci´es lors de l’usage): // returns 0 if equal, 1 if value1 is bigger, -1 otherwise i n t compare ( const i n t &value1 , const i n t &value2 ) { i f ( value1 < value2 ) r e t u r n −1; i f ( value2 < value1 ) r e t u r n 1 ; r e t u r n 0 ; } // returns 0 if equal, 1 if value1 is bigger, -1 otherwise i n t compare ( const s t r i n g &value1 , const s t r i n g & value2 ) { i f ( value1 < value2 ) r e t u r n −1; i f ( value2 < value1 ) r e t u r n 1 ; r e t u r n 0;} ⇒ factorisation du code puis `a la compilation, code polymorphique pour les divers types requis : g´en´eration des codes sp´ecifiques pour les types demand´es.
  46. 46. #i n c l u d e <iostream > #i n c l u d e <s t r i n g > // returns 0 if equal, 1 if value1 is bigger, -1 otherwise template <c l a s s T> i n t compare ( const T &value1 , const T &value2 ) { i f ( value1 < value2 ) r e t u r n −1; i f ( value2 < value1 ) r e t u r n 1 ; r e t u r n 0 ; } // On est gentil ici pour le compilateur : // on indique explicitement les types demand´es i n t main ( i n t argc , char ∗∗ argv ) { std : : s t r i n g h (” h e l l o ” ) , w( ” world ” ) ; std : : cout << compare<std : : s t r i n g >(h , w) << std : : endl ; std : : cout << compare<int >(10 , 20) << std : : endl ; std : : cout << compare<double >(50.5 , 5 0 .6 ) << std : : endl ; r e t u r n 0;}
  47. 47. Inf´erence des types demand´es par le compilateur #i n c l u d e <iostream > #i n c l u d e <s t r i n g > // returns 0 if equal, 1 if value1 is bigger, -1 otherwise template <c l a s s T> i n t compare ( const T &value1 , const T &value2 ) { i f ( value1 < value2 ) r e t u r n −1; i f ( value2 < value1 ) r e t u r n 1 ; r e t u r n 0 ; } // Le compilateur doit trouver le type demande ici : // inf´erence de types i n t main ( i n t argc , char ∗∗ argv ) { std : : s t r i n g h (” h e l l o ” ) , w( ” world ” ) ; std : : cout << compare (h , w) << std : : endl ; std : : cout << compare (10 , 20) << std : : endl ; std : : cout << compare (5 0 .5 , 5 0 .6 ) << std : : endl ; r e t u r n 0;}
  48. 48. M´ecanisme de compilation ◮ le compilateur ne g´en´ere pas de code directement lorsqu’il rencontre une classe/fonction template parce qu’il ne connaˆıt pas encore quelles seront les types demand´es. ◮ quand le compilateur rencontre une fonction template utilis´ee, il sait quel type est demand´e : Il instancie alors le template et compile le code correspondant ⇒ les classes/fonctions templates doivent donc se trouver dans le fichier d’en-tˆete, header .h Le m´ecanisme de template ressemble donc a une macro expansion...
  49. 49. fichier compare.h : #i f n d e f COMPARE H #d e f i n e COMPARE H template <c l a s s T> i n t comp( const T& a , const T& b ) { i f ( a < b ) r e t u r n −1; i f (b < a ) r e t u r n 1 ; r e t u r n 0;} #e n d i f // COMPARE H fichier main.cpp : #i n c l u d e <iostream > #i n c l u d e ”compare . h” using namespace std ; i n t main ( i n t argc , char ∗∗ argv ) { cout << comp<int >(10 , 20) ; cout << endl ; r e t u r n 0 ; }
  50. 50. Lire un fichier dans un vector de la STL Vous avez d´ej`a utilis´e la classe vector de la STL ! (tableaux dynamiques) i f s t r e a m f i n ; f i n . open ( ” f i c h i e r . t x t ” ) ; vector <s t r i n g > t e x t e ; s t r i n g mote ; while ( f i n >> mot ) { t e x t e . push back (mot ) ;} f i n . c l o s e ( ) ; ◮ La boucle while lit jusqu’`a temps de rencontrer EOF (End Of File) ◮ Les donn´ees sont des chaˆınes de caract`eres s´epar´ees par des d´elimiteurs (espace, tab, retour `a la ligne, point virgule pour les fichiers CSV, Comma-Separated Values)
  51. 51. STL : une collection de structures de donn´ees Le concept fondamental est le containeur avec son iterator , le tout en template ! Structure de donn´ees nom STL #include tableau dynamique vector <vector> liste chaˆın´ee list <list> pile stack <stack> file queue <queue> arbre binaire set <set> table de hachage map <set> tas ordonn´e file de priorit´e <queue> Les #include sont `a faire sans le .h
  52. 52. La STL : structures de donn´ees g´en´eriques set <s t r i n g > mots ; l i s t <Eleve> PromoX2013 ; stack < vector <int > > nombres ; `A chaque container STL, on a un it´erateur (iterator) associ´e de type container<T>::iterator set <s t r i n g >:: i t e r a t o r p=mots . f i n d ( ” cours ”) ; l i s t <Eleve >:: i t e r a t o r premier=PromoX2013 . begin () ; stack < vector <int > >:: i t e r a t o r f i n=nombres . end () ; On d´eref´erence un it´erateur comme pour un pointeur : *it
  53. 53. Les containeurs stockent par valeur, pas par ref´erence ◮ quand on ins´ere un objet, le containeur va en faire une copie ◮ quand le containeur doit r´earranger les objets, il proc´ede en faisant des copies de ceux-ci. Par exemple, si on tri, ou si on ins´ere sur un containeur map, etc. ◮ si on veut ´eviter cela, il faudra donc faire des containeurs de pointeurs ! C++11 a le mot clef auto pour inf´erer directemement les types et un “foreach” (pour les curieux !) : f o r ( vector <Printer >:: i t e r a t o r i t = vec . begin () ; i t < vec . end () ; i t ++) { cout << ∗ i t << endl ; } f o r ( auto i t = vec . begin () ; i t < vec . end () ; i t ++) { cout << ∗ i t << endl ; } std : : s t r i n g s t r ( ” Bonjour INF442” ) ; f o r ( auto c : s t r ) { std : : cout << c << endl ; }
  54. 54. Fonctions membres communes `a la STL Toutes les classes containeurs ont les fonctions membres : i n t s i z e () i t e r a t o r begin () i t e r a t o r end () bool empty () Pour lister tous les ´el´ements d’un containeur, on fait : l i s t <s t r i n g >:: i t e r a t o r i t=maListe . begin () ; while ( i t != maListe . end () ) { cout << ∗ i t <<endl ; i t e r ++;} Notons que end() est un ´el´ement sentinel . On ne peut pas d´eref´erencer end().
  55. 55. Diff´erents acc`es aux ´el´ements d’un containeur ◮ pour vector, on peut acc´eder aux ´el´ements en utilisant un index [i] : vector <int > vec442<double >; vec442 [0]=280; ... mais les crochets ne peuvent pas ˆetre utilis´es pour list<int> par exemple ◮ on peut rajouter un ´el´ement `a la fin d’une liste ou d’un vecteur avec push back : monVecteur . push back (2013) ; maListe . push back (2013) ; ... mais il n’ y a pas de push_back pour les ensembles (cod´es par des arbres binaires) : set <int > monEnsemble ; monEnsemble . push back (2013) ; // Erreur !!!
  56. 56. La liste (doublement chaˆın´ee) On peut ajouter `a la tˆete ou `a la queue d’une liste en temps constant : maListe . push back (2013) ; maListe . p u s h f r on t (2015) ; On peut ins´erer ou supprimer un ´el´ement avec un it´erateur : l i s t <s t r i n g >:: i t e r a t o r p=maListe . begin () ; p=maListe . e r a s e ( p ) ; p=maListe . i n s e r t (p , ”HPC” ) ; On peut avancer ou reculer dans une liste avec les op´erateurs unaires ++ et -- : p++; p−−; // faire attention aux d´ebordements possibles Seul b´emol : on ne peut pas directement acc´eder i-i`eme ´el´ement (cela demande de parcourir la liste, pas de crochets).
  57. 57. La liste doublement chaˆın´ee en STL Voir INF311/INF411 NULL NULL C++ HPC MPI list<string>::iterator it=liste.find("HPC") q=it-- q=it++
  58. 58. Les piles et les files ◮ Piles ( stacks ) et files ( queues ) sont des sous-classes de la classe deque ◮ Une pile est une liste chaˆın´ee avec la propri´et´e Dernier Arriv´e Premier Sorti, DAPS (LIFO : Last In First Out). ◮ Une file est une liste chaˆın´ee avec la propri´et´e Premier Arriv´e Premier Sorti, PAPS (FIFO : First In First Out). ◮ On acc´ede au dernier ´el`eement au sommet de la pile ou au premier ´el´ement d’une file avec les primitives push et pop ◮ Pour les piles, on a aussi top, et pour les files front et back
  59. 59. Les piles : illustration stack <s t r i n g > S ; S . push ( ”A”) ; S . push ( ”B”) ; S . push ( ”C”) ; S . pop () ; Q. pop () ; S . push ( ”D”) ; Q. push ( ”D”) ; cout << S . top () ;
  60. 60. Les files : illustration queue<s t r i n g > Q; Q. push ( ”A”) ; Q. push ( ”B”) ; Q. push ( ”C”) ; Q. pop () ; Q. push ( ”D”) ; cout << Q. f r o n t () << Q. back () ;
  61. 61. Les files de priorit´e On doit d´efinir un operator < . La plus grande valeur est sur le haut (max-heap, top). p r i o r i t y q u e u e <int > Q; Q. push (23) ; Q. push (12) ; Q. push (71) ; Q. push (2) ; cout << Q. top () ; Q. pop () ; cout << Q. top () ; pour la plus petite valeur (min-heap), il faut donc changer le sens s´emantique de l’op´erateur < ... http://en.cppreference.com/w/cpp/language/operator_comparison
  62. 62. On peut trier facilement avec une file de priorit´e... #i n c l u d e <queue> #i n c l u d e <iostream > using namespace std ; s t r u c t comparator { bool o perato r () ( i n t i , i n t j ) { r e t u r n i < j ;} } ; i n t main ( i n t argc , char const ∗ argv [ ] ) { p r i o r i t y q u e u e <int , std : : vector <int >, comparator> minHeap ; minHeap . push (10) ; minHeap . push (5) ; minHeap . push (12) ; minHeap . push (3) ; minHeap . push (3) ; minHeap . push (4) ; while ( ! minHeap . empty () ) { cout << minHeap . top () << ” ” ; minHeap . pop () ; } r e t u r n 0;} // 12 10 5 4 3 3
  63. 63. Les ensembles : set (arbres binaires ´equilibr´es) On doit d´efinir operator <. Toutes les valeurs sont uniques (sinon, utiliser un multiset). insert(value), erase(value), erase(iterator), iterator find(value) set <s t r i n g > s ; s . i n s e r t ( ” Ecole ” ) ; s . i n s e r t ( ” Polytechnique ” ) ; s . e r a s e ( ” Ecole ” ) ; cout << ∗( s . f i n d ( ” Polytechnique ”) ) ;
  64. 64. Le hachage (map) ◮ Diff´erence entre hachage ferm´e (tableau) et hachage ouvert (tableau de pointeurs sur des listes). ◮ Templates pour la clef et le type de donn´ees map<K,T>. ◮ On doit d´efiniroperator < pour le type K. map<int , s t r i n g > monHachage ; monHachage [23121981] = ” A n n i v e r s a i r e Toto” ; monHachage [05031953] = ” A n n i v e r s a i r e T i t i ” ; . . . map<s t r i n g , int > monHachageRev ; monHachageRev [ ”Toto” ] = 23121981; monHachageRev [ ” T i t i ” ] = 05031953;
  65. 65. Le hachage (map) Les fonctions membres pour la classe STL map : erase(iterator), erase(K clef), map_name(K key) map<s t r i n g , int > M; M[ ”A” ] = 23; M[ ”B” ] = 12; M[ ”C” ] = 71; M[ ”D” ] = 5; M. e r a s e ( ”D” ) ; cout << M[ ”B” ] ;
  66. 66. La classe STL paire `a la rescousse map<s t r i n g , int > maMap; pair <s t r i n g , int > p a i r e ( ”Tutu” , 606) ; maMap. i n s e r t ( p a i r e ) ; . . . // on cr´e´e un nouvel enregistrement en faisant aussi : maMap[ ”Tata” ] = 707; ⇒ op´erateur crochet [K]
  67. 67. Les temps d’acc´es aux structures de donn´ees Pour un containeur `a n ´el´ements : vecteur list set map Ins´erer/supprimer O(n) O(1) O(log n) ˜O(1) Rechercher O(n) O(n) O(log n) ˜O(1) Voir INF311/INF411.
  68. 68. Les it´erateurs Chaque containeur est equipp´e d’un it´erateur : container <T>:: i t e r a t o r i t ; i t=C. begin () ; ◮ ++ et -- pour avancer ou reculer ◮ * pour d´eref´erencer ◮ == et =! pour les tests de comparaisons Seulement dans la classe vector, on peut bouger de p ´el´ements (arithm´etique) en faisant vector <T>:: i t e r a t o r i t ; i t=i t+p ; i t=i t −p ;
  69. 69. Les it´erateurs : premier et dernier ´el´ements Le dernier ´el´ement est une sentinelle : cout << ∗( L . begin () ) ; // oui, si pas vide ! cout << ∗( L . end () ) ; // toujours non ! l i s t <s t r i n g >:: i t e r a t o r p = L . end () ; p−−; cout << ∗p ; // ok, si pas vide !
  70. 70. La classe STL algorithm Proc´edures (pas des m´ethodes de classe) : find, remove, count, shuffle, replace, sort, for each, min element, binary search, transform, copy, swap : i t e r = f i n d (L . begin () , L . end () , ” Cours INF442” ) ; i n t x = count (L . begin () , L . end () , ” i n s c r i t en INF442” ) ; r e p l a c e (L . begin () , L . end () , ”DEP442” , ”INF442” ) ; if : prend une fonction bool´eene utilisateur : r e p l a c e i f (L . begin , L . end () , appartient442S , ” Tutorat ”) ;
  71. 71. La biblioth`eque Boost
  72. 72. Boost ◮ un ensemble de biblioth`eques qui se comportent bien avec la STL : http://www.boost.org/ ◮ liste des biblioth`eques de Boost : http://www.boost.org/doc/libs/ Graph BGL generic graph components MPI MPI interface in Boost style Rational rational number class Thread Portable multi-threading uBlas linear algebra for vector/matrix Xpressive regular expression Install´e dans le r´epertoire /usr/local/boost-1.56.0
  73. 73. Boost : la biblioth`eque uBLAS #i n c l u d e <boost / numeric / ublas / matrix . hpp> #i n c l u d e <boost / numeric / ublas / i o . hpp> using namespace std ; using namespace boost : : numeric : : ublas ; i n t main () { matrix <double> m (3 , 3) ; f o r ( unsigned i = 0; i < m. s i z e 1 () ; ++ i ) f o r ( unsigned j = 0; j < m. s i z e 2 () ; ++ j ) m ( i , j ) = i + j ∗ j ; cout << m << endl ; }
  74. 74. Boost : la biblioth`eque uBLAS alias mpiboost =’/usr/local/openmpi -1.8.3/ bin /mpic++ -I/usr/local/boost -1.56.0/ include / -L/usr/local/boost -1.56.0/ lib/ - lboost_mpi -lboost_serialization ’ mpiboost matrice442.cpp -o matrice442.exe mpirun -np 1 matrice442.exe [3 ,3]((0 ,1 ,4) ,(1,2,5) ,(2,3,6)) http://www.boost.org/doc/libs/1_58_0/libs/numeric/ublas/doc/
  75. 75. # i n c l u d e <boost / numeric / ublas / matrix . hpp> # i n c l u d e <boost / numeric / ublas / i o . hpp> # i n c l u d e <boost / numeric / ublas / matrix . hpp> using namespace boost : : numeric : : ublas ; using namespace std ; i n t main () { matrix <double > myMat (3 ,3 , 2 . 5 ) ; myMat (0 ,0)= myMat (2 ,2) =1.0; myMat (0 ,2)= −3.6; myMat (2 ,0) =5.9; cout << ”My Mat : ” << myMat << endl ; cout << ”Num Rows : ” << myMat . s i z e 1 () << endl ; cout << ”Num Cols : ” << myMat . s i z e 2 () << endl ; cout << ”My Mat Transp : ” << t r a n s (myMat) << endl ; cout << ”My Mat Real Part : ” << r e a l (myMat) << endl ; myMat . r e s i z e (4 ,4) ; cout << ”My Resized Mat : ” << myMat << endl ; r e t u r n 0;}
  76. 76. matrix <double > myMat (3 ,3 , 2. 5) ; myMat (0 ,0)= myMat (2 ,2) =1.0; myMat (0 ,2)= −3.6; myMat (2 ,0) =5.9; mpirun -np 1 matricefun442.exe My Mat :[3 ,3]((1 ,2.5 , -3.6) ,(2.5 ,2.5 ,2.5) ,(5.9 ,2.5 ,1)) Num Rows :3 Num Cols :3 My Mat Transp :[3 ,3]((1,2.5 ,5.9) ,(2.5 ,2.5 ,2.5) ,( -3.6 ,2.5 ,1)) My Mat Real Part :[3 ,3]((1 ,2.5 , -3.6) ,(2.5 ,2.5 ,2.5) ,(5.9 ,2.5 ,1)) My Resized Mat :[4 ,4]((1,2.5 , -3.6 ,3.57355e -115) ,(2.5,2.5,2.5 ,2.02567e -322) ,(5.9 ,2.5 ,1 ,0) ,(0,0,0,0))
  77. 77. R´esum´e A4 la classification par r´egression lin´eaire (et comparaison avec le classifieur k-PPV) le produit matrice-vecteur sur l’anneau orient´e produits matriciels sur le tore : algorithmes de Cannon (pre-processing), de Fox (broadcast-multiply-roll) et de Snyder (sommes globales) la g´en´ericit´e avec la biblioth`eque C++ STL la biblioth`eque Boost uBLAS Pour la prochaine fois : lire le chapitre 5 du polycopi´e

×