Sunteți pe pagina 1din 16

Tema: Arhitecturi paralele de calculatoare Spnu Alexandru C411

1.Enuntul Problemei In nxn regiuni patratice identice (asezate sub forma de matrice) traiesc nxn colonisti. In intreg tinutul se comercializeaza doua tipuri de resurse, A si B. Fiecare colonist este specializat in producerea unui tip de resursa (A sau B), pe care o vinde anual (specializarea se poate modifica). Fiecare colonist are propriul pret pe unitatea de resursa, pe care il modifica anual, in functie de niste indicatori, insa exista limite legale pentru pretul minim si maxim(limite egale pentru cele doua resurse). Limitele stabilite de legea tinutului nu se modifica de la un an la altul. Resursele A si B sunt complementare, asa ca cei care produc A vor trebui sa cumpere anual B si viceversa. Fiecare colonist cumpara resursa complementara cu cel mai mic cost, cost care depinde de pretul de vanzare al resursei complementare si de distanta pana la regiunea unde e produsa. Fiecare colonist are un buget (pe care-l poate depasi) pe care-l ajusteaza anual, in functie de cheltuielile din anul precedent. Fie Colij colonistul care locuieste in regiunea cu coordonatele (i,j) din tinut, cu 0<=i<n, 0<=j<n Rij tipul de resursa pentru Colij intr-un anumit an; Rij poate fi 0 sau 1. 1-Rij resursa complementara, pe care Colij trebuie s-o cumpere intr-un anumit an Pij pretul de vanzare al resursei Rij in anul curent Pmin, Pmax limita minima, respectiv maxima pentru pretul de vanzare al unei resurse (de orice tip) Costij - costul cu care Colij cumpara resursa complementara in anul curent Costij = mini1,j1 (Pi1,j1 + dist(Colij ,Coli1,j1)), cu Ri1,j1 = 1 - Rij ; e clar ca (i,j) si (i1, j1) nu se pot referi la acelasi colonist CostResij - costul minim al unei resurse de tipul Rij, vazut din perspectiva lui Colij CostResij = mini1,j1 (Pi1,j1 + dist(Colij ,Coli1,j1)), cu Ri1,j1 = Rij ; in acest caz, (i,j) si (i1, j1) se pot referi la acelasi colonist dist(Coli,j ,Coli1,j1)) = |i - i1| + |j j1| (Distanta Manhattan) Bij bugetul colonistului Colij in anul curent Anual, au loc urmatoarele activitati:

Tema: Arhitecturi paralele de calculatoare Spnu Alexandru C411

1. Fiecare colonist cumpara cea mai ieftina resursa complementara (luand in calcul pretul resursei si lungimea drumului pana acolo) 2. Daca costul resursei complementare(Costij) depaseste bugetul alocat in acel an, pentru anul viitor va creste bugetul, dar si pretul resursei proprii, astfel: Bij (an + 1) = Costij (an) Pij (an + 1) = Pij (an) + Costij (an) - Bij (an ) 3. Daca costul resursei complementare(Costij) este sub bugetul alocat in acel an, pentru anul viitor va scadea bugetul, dar si pretul resursei proprii, astfel: Bij (an + 1) = Costij (an) Pij (an + 1) = Pij (an) + (Costij (an) - Bij (an )) / 2 Aici / este impartire intreaga; rezultatul e partea intreaga a catului. 4. Daca costul resursei complementare(Costij) este egal cu bugetul alocat in acel an, pentru anul viitor se va modifica numai pretul resursei proprii, bugetul va ramane la fel: Bij (an + 1) = Costij (an) Pij (an + 1) = CostResij (an) + 1 5. Daca in urma actualizarilor de la punctul 3, pretul devine mai mic decat pretul minim admis de legea tinutului, pretul se actualizeaza astfel: Pij (an + 1) = max ( Pij (an + 1) , Pmin) 6. Daca in urma actualizarilor de la punctele 2 sau 4, pretul devine mai mare decat pretul maxim admis de legea tinutului, colonistul se re-specializeaza (produce resursa complementara), iar pretul si bugetul se actualizeaza astfel: Rij (an + 1) = 1 - Rij (an) (pentru punctele 2-5, Rij (an + 1) = Rij (an)) Bij (an + 1) = Pmax Pij (an + 1) = (Pmin + Pmax) / 2;

Tema: Arhitecturi paralele de calculatoare Spnu Alexandru C411

Aici / este impartire intreaga; rezultatul e partea intreaga a catului.

2. Cerintele temei Se va studia evolutia pietei din tinut, pe un numar de ani. Mai exact, pentru fiecare an se vor calcula (in paralel pentru punctele 3 si 5 de mai jos): - numarul de colonisti care produc resursa A (codificata cu 0) - numarul de colonisti care produc resursa B (codificata cu 1) - pretul maxim al resursei A - pretul maxim al resursei B Valorile cerute mai sus se vor tine in structuri uni sau multi-dimensionale (vectori sau matrici), cu lungimea egala cu numarul de ani. Abia dupa sfarsitul regiunii paralele se vor afisa. In plus, se vor retine si afisa in fisierul de iesire, variantele finale (dupa ultimul an) al matricilor de tipuri de resurse, de preturi si de bugete. Detaliere cerinte/punctaj Va trebui sa aveti un fisier Readme(cu explicatii pentru surse explicatii detaliate in cazul surselor optimizate, si cerintele de la punctul 4), precum si Makefile cu reguli de compilare si clean. Pentru variantele paralele, va trebui sa aveti un exemplu de script cu care ati rulat in cluster. Temele vor fi testate in clusterul facultatii. Lipsa makefile si script rulare (functionale), arhivarea cu alta extensie(in afara de zip), nerespectarea formatului de intrare/iesire (sau nume fisiere hardcodate in surse) ingreuneaza corectarea temei si duc la scaderea punctajului cu pana la 2 puncte (din 10). Implementarea paralela utilizand OpenMP. Trebuie sa calculati in paralel si cele 4 valori agregate mentionate la inceputul sectiunii Cerintele temei. Implementarile paralele trebuie sa fie corecte si din punct de vedere al concurentei/sincronizarii (daca e cazul) si al scope-ului variabilelor (private, shared, reduction...). (4p daca e corect + 1p daca scaleaza - performanta creste o data cu cresterea numarului de threaduri si varianta paralela cu 2 threaduri e mai rapida decat varianta seriala de la punctul 2)) Scalarea se puncteaza numai in cazul obtinerii punctajului total la corectitudine.

Tema: Arhitecturi paralele de calculatoare Spnu Alexandru C411

3. Formatul datelor de intrare/ieire. Rulare. Verificare Exemplu de executie: ./serial T fisin fisout ./paralel T fisin fisout ./optims T fisin fisout ./optimp T fisin fisout Unde T este numarul de iteratii(ani). In cazul versiunilor paralele, numarul de threaduri nu e un parametru la rulare, dar se va specifica intr-o variabila de mediu, la fel ca scheduling-ul(eventual). Numarul de threaduri va fi identificat de variabila de mediu OMP_NUM_THREADS (nu setati in codul sursa numarul de threaduri). Tipul de scheduling poate fi setat in interiorul programului la static, dynamic, guided sau runtime. Daca il setati runtime, el va fi specificat (impreuna cu chunk-ul) de variabila de mediu OMP_SCHEDULE. Folosire: export OMP_SCHEDULE="tip[,chunk_size]" unde tip se refera la tipul de schedule, chunk_size la dimensiunea chunk-ului(care e optionala; nu puneti paranteze drepte) Exemple de fisiere de intrare si iesire gasiti in directorul resurse_t1. Formatul fisierului de intrare este: pe prima linie, 3 numere intregi strict pozitive: Pmin, Pmax, n (vezi explicatii in prima parte a enuntului) o linie goala o matrice nxn, cu valori 1 si 0: n linii cu cate n elemente fiecare (matricea de tipuri de resurse) o linie goala

Tema: Arhitecturi paralele de calculatoare Spnu Alexandru C411

o matrice nxn, cu valori intregi intre Pmin si Pmax: n linii cu cate n elemente fiecare (matricea de preturi) o linie goala o matrice nxn, cu valori intregi mai mari decat Pmin: n linii cu cate n elemente fiecare (matricea de bugete) Formatul fisierului de iesire este: pe primele T linii se afiseaza cele 4 valori agregate cerute pentru anii [1..T] (in ordinea: numarul de colonisti care produc resursa A (codificata cu 0), pretul maxim al resursei A, numarul de colonisti care produc resursa B (codificata cu 1), pretul maxim al resursei B); configuratia din fisierul de intrare corespunde anului 0 o matrice nxn, cu triplete de forma (Rij,Pij,Bij): n linii cu cate n triplete fiecare, reprezentand configuratia tipurilor de resurse, a preturilor si a bugetelor in anul T; configuratia din fisierul de intrare corespunde anului 0

Corectitudinea implementarilor se va verifica, in aceasta ordine: - comanda diff (vezi exemplul din mini-tutorialul de rulare in cluster) pe fisierele de iesire (intre outputul vostru si cel de referinta) - inspectarea codului sursa Daca verificarea cu diff intoarce diferente, punctajul obtinut pe implementarile seriale va fi neglijabil In cazul implementarilor paralele, depunctarea depinde de gravitatea erorilor; atentie ca e posibil ca programul paralel sa treaca de verificarea cu diff si totusi sa nu fie corect. 4.Codul sursa #include <stdio.h> #include <stdlib.h> #include <omp.h> int maxim(int x, int y) { int m = (x > y)?x:y; return m; }

Tema: Arhitecturi paralele de calculatoare Spnu Alexandru C411

void main(int argc, char* argv[]) { FILE *fp; int nrAni = atoi(argv[1]); fp = fopen(argv[2], "r"); if (fp == NULL) { puts("Cannot open file!"); //return; } int pMin, pMax, n; fscanf(fp, "%i %i %i",&pMin, &pMax, &n); printf("pMin, pMax, n: %i, %i, %i \n", pMin, pMax, n); //Avem 3 matrici in care pastram datele necesare problemei //tip, pret, buget int r[n][n], r1[n][n], p[n][n], p1[n][n], b[n][n], b1[n][n], c[n][n]; //rezultatele le retinem intr-o matrice cu nrAni linii si 4 coloane //pe fiecare linie avem datele pentru anul corespunzator int rezultate[nrAni][4]; int i, j, k ,l; int min, max; //le folosim cand calculam resursa cu cost minim int cost, costRes; int pretMaxA = pMin, pretMaxB = pMin, nrA = 0, nrB = 0; //tip resurse for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { fscanf(fp, "%i", &r[i][j]); //printf("%i ", r[i][j]); } //puts(" "); } //puts("\n"); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { fscanf(fp, "%i", &p[i][j]); //printf("%i ", p[i][j]); } //puts(" "); } //puts("\n"); for (i = 0; i < n; i++) {

Tema: Arhitecturi paralele de calculatoare Spnu Alexandru C411

for (j = 0; j < n; j++) { fscanf(fp, "%i", &b[i][j]); //printf("%i ", b[i][j]); } //puts(" "); } //puts("\n"); fclose(fp); //Start programming //Pentru fiecare colonist int an = 0; int pret, pret1; int ok = -1; for (an = 1; an <= nrAni; an++) { ok = an % 2; nrA = 0; nrB = 0; pretMaxA = pMin; pretMaxB = pMin; #pragma omp parallel { #pragma omp for private(i,j,l,k,pret,cost,costRes) reduction(+:nrA,nrB)nowait for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { cost = 3*n + pMax; costRes = 3*n + pMax; //Determinam pretul minim cu care poate cumpara o resursa for (k = 0; k < n; k++) { for (l = 0; l < n; l++) { if (ok == 1){ pret = p[k][l] + (abs(i - k) + abs(j - l)); //pentru resursa complementara if (r[k][l] == 1 - r[i][j]) { if (pret < cost)cost = pret; } else { //pentru resursa proprie if (pret < costRes)costRes = pret; } } else {

Tema: Arhitecturi paralele de calculatoare Spnu Alexandru C411

pret = p1[k][l] + (abs(i - k) + abs(j - l)); //pentru resursa complementara if (r1[k][l] == 1 - r1[i][j]) { if (pret < cost)cost = pret; } else { //pentru resursa proprie if (pret < costRes)costRes = pret; } } } } //pentru an impar if (ok == 1) { r1[i][j] = r[i][j]; b1[i][j] = cost; if (cost > b[i][j]) { p1[i][j] = p[i][j] + cost - b[i][j]; } else { if (cost < b[i][j]) p1[i][j] = p[i][j] + (int)((cost - b[i][j])/2); else p1[i][j] = costRes + 1; } if (p1[i][j] < pMin) p1[i][j] = maxim(p1[i][j], pMin); if (p1[i][j] > pMax) { p1[i][j] = (int)((pMin + pMax)/2); r1[i][j] = 1 - r[i][j]; b1[i][j] = pMax; } //numaram colonistii de un anumit tip //si det. preturile maxime if (r1[i][j] == 0) { nrA++; #pragma omp critical if (p1[i][j] > pretMaxA) pretMaxA = p1[i][j]; } else {

Tema: Arhitecturi paralele de calculatoare Spnu Alexandru C411

nrB++; #pragma omp critical if (p1[i][j] > pretMaxB) pretMaxB = p1[i][j]; } } //daca este an par else { r[i][j] = r1[i][j]; b[i][j] = cost; if (cost > b1[i][j]) p[i][j] = p1[i][j] + cost - b1[i][j]; else { if (cost < b1[i][j]) p[i][j] = p1[i][j] + (int)((cost - b1[i][j])/2); else p[i][j] = costRes + 1; } if (p[i][j] < pMin) p[i][j] = maxim(p[i][j], pMin); if (p[i][j] > pMax) { p[i][j] = (int)((pMin + pMax)/2); r[i][j] = 1 - r1[i][j]; b[i][j] = pMax; } //numaram colonistii de un anumit tip if (r[i][j] == 0) { nrA++; #pragma omp critical if (p[i][j] > pretMaxA) pretMaxA = p[i][j]; } else { nrB++; #pragma omp critical if (p[i][j] > pretMaxB) pretMaxB = p[i][j]; } } } }

Tema: Arhitecturi paralele de calculatoare Spnu Alexandru C411

//retinem rezultatele in matrice rezultate[an-1][0] = nrA; rezultate[an-1][1] = pretMaxA; rezultate[an-1][2] = nrB; rezultate[an-1][3] = pretMaxB; } } //se afiseaza matricea finala si rezultatele pe fiecare an FILE *fp1 = fopen(argv[3], "w"); if (fp1 == NULL) { puts("Cannot open file to write!!!"); } for (i = 0; i < nrAni; i++) { fprintf(fp1,"%i %i %i %i", rezultate[i][0], rezultate[i][1], rezultate[i][2], rezultate[i][3]); fprintf(fp1,"%s", "\n"); } printf("n este: %i\n", n); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { if (nrAni % 2 == 1) fprintf(fp1,"(%i,%i,%i) ", r1[i][j], p1[i][j], b1[i][j]); else fprintf(fp1,"(%i,%i,%i) ", r[i][j], p[i][j], b[i][j]); } fprintf(fp1,"%s", "\n"); } fclose(fp1); }

II. METODA ITERATIVA JACOBI

Determinarea solutiei exacte a sistemului A * x = b cu ajutorul unor metode de tip iterativ este posibila numai dupa efectuarea unui numar nelimitat - teoretic infinit de iteratii sau pasi. Deoarece nici o metoda practica nu poate cicla la infinit, rezulta ca metodele iterative determina doar o solutie aproximativa, aproximare prin trunchiere, care se abate mai mult sau mai putin fata de solutia exacta x*, in functie de precizia de calcul dorita. Mai concret, metodele iterative apeleaza la construirea unui sir de aproximatii succesive x_0, x_1, ... , x_k care, in anumite conditii, tinde catre solutia exacta x*. In

Tema: Arhitecturi paralele de calculatoare Spnu Alexandru C411

cazul in care pentru sirul aproximatiilor succesive nu este posibila definirea unei limite, se spune ca metoda respectiva diverge. In cazul in care sirul aproximatiilor succesive are o limita, se spune ca metoda este convergenta. In acest caz se poate defini o relatie de recurenta intre doua aproximatii succesive x_k si x_(k+1). Definirea relatiei de recurenta intre aproximatiile succesive se face pornind de la desfacerea matricei A in alte doua matrice: A=N-P Folosind aceasta desfacere in expresia sistemului de ecuatii se obtine relatia: N*x=P*x+b care permite ca, pornind de la o aproximatie initiala x_0, sa se construiasca un sir de aproximatii succesive pe baza relatiei de recurenta: N * x_(k+1) = P * x_k + b In practica, alegerea desfacerii A = N - P se face astfel incat un sistem de forma N * y = C, unde y si C sunt vectori ai necunoscutelor si termenilor liberi, sa se rezolve cat mai usor. Aceasta este totuna cu o forma cat mai simpla a matricei N, diagonala sau triunghiulara. In general, toate metodele iterative de rezolvare a sistemelor de ecuatii liniare, definesc matricele N si P din desfacerea A = N - P pornind de la desfacerea standard a matricei A: A=L+D+R unde: L este matricea strict inferior triunghiulara ale carei elemente subdiagonale sunt elementele matricei A; R este matricea strict superior triunghiulara ale carei elemente supradiagonale sunt elementele matricei A; D este matricea diagonala ale carei elemente nenule sunt tocmai elementele diagonale din matricea A.

Ca si in cazul metodelor directe, toate metodele iterative folosesc impartirea la un element diagonal, numit pivot. Din acest motiv, desfacerea standard astfel definita trebuie sa se caracterizeze prin elemente nenule pe diagonala matricei D sau, ceea ce este totuna, pe diagonala matricei A. Daca exista cel putin un asemenea element nul este necesara permutarea unor linii ale matricei A (pivotarea partiala).

Metoda iterativa Jacobi

Tema: Arhitecturi paralele de calculatoare Spnu Alexandru C411

Metoda iterativa Jacobi, numita si metoda iteratiilor simultane, foloseste o desfacere A = N - P, in care matricele N si P se aleg conform relatiei: N=D P=-L-R unde D, L si R sunt matricele din desfacerea standard, iar toate elementele diagonale a_ii sunt nenule. Folosind aceasta desfacere in relatia generala de recurenta, se obtine forma matriceala a relatiei de recurenta pentru metoda Jacobi: D * x_(k+1) = - ( L + R ) * x_k + b Pentru un element x_i al vectorului necunoscutelor, la iteratia k+1, relatia de recurenta capata forma:

care reprezinta formula de iterare a metodei Jacobi. Inspectia sumara a acestei formule sugereaza imediat motivul pentru care toate elementele diagonale a_ii trebuie sa fie nenule. Metoda iterativa Jacobi este convergenta daca, pentru fiecare linie din matricea A, suma valorilor absolute ale termenilor din afara diagonalei principale nu depaseste valoarea absoluta a termenului diagonal. Matricele care satisfac aceasta proprietate se numesc diagonal dominante. O particularitate a metodei Jacobi se refera la modul cum este folosita aproximatia anterioara x_k pentru calculul noii aproximatii x_(k+1). Astfel, se constata ca noile aproximatii ale fiecarei necunoscute de aproximatiile anterioare ale tuturor celorlalte se determina n functie

necunoscute ( j <> i ). Din acest motiv, noua aproximatie nu o poate inlocui pe cea anterioara n vectorul x si, in consecinta, aplicarea metodei Jacobi necesita folosirea a cel putin doi vectori : un vector x, care memoreaza aproximatia anterioara si un vector y, care memoreaza aproximatia nou calculata. La sfarsitul fiecarei iteratii vectorul x este actualizat, prin copierea in el a elementelor vectorului y. Algoritmul 1 - Sisteme de ecuatii liniare - Metoda iterativa Jacobi 1. Definirea sistemului de ecuatii: rangul n, matricea coeficientilor A, vectorul termenilor liberi b;

Tema: Arhitecturi paralele de calculatoare Spnu Alexandru C411

2. Definirea parametrilor de iterare: abaterea relativa maxima admisa Emax si numarul maxim de iteratii Nmax; 3. Calcul iterativ: i. Stabilirea aproximatiei initiale, identica cu termenii liberi:

ii. iii. iv.

v. vi.

Initializarea procesului iterativ: It <-- 0. Initializarea abaterii relative maxime in iteratia curenta cu o valoare superioara lui Emax : Dx <-- Emax + 1. Daca s-a atins numarul maxim de iteratii (It=Nmax) sau abaterea Dx a trecut sub valoarea admisa ( Dx <= Emax ), se incheie procesul iterativ si se trece la pasul 4; Trecerea la o noua iteratie: It <-- It + 1. Calculul noii aproximatii in vectorul y:

vii.

Calculul abaterii relative maxime in iteratia curenta:

viii.

Actualizarea vectorului aproximatiilor din ultima iteratie:

ix. Se revine la pasul 3.iv. 4. Stabilirea conditiilor de iesire din bucla iterativa: o daca Dx <= Emax (metoda converge), se afiseaza solutia aproximativa
o

si numarul de iteratii efectuate It; daca Dx>Emax, dar It=Nmax (metoda nu converge), se afiseaza mesajul "Depasire numar maxim iteratii";

Tema: Arhitecturi paralele de calculatoare Spnu Alexandru C411

#include"stdafx.h" #include<omp.h> #include<math.h> #include<conio.h> #define N 3 #define EPS 0.0001 #define max_D 100 double norm_inf_omp(double x[],int n) { double norm; int i; norm=abs(x[0]); #pragma omp parallel { #pragma omp parallel for private(i) shared(x,norm) for(i=0;i<n;i++) { if(abs(x[i])>norm) norm=abs(x[i]); } } return(norm); } void jacobi_omp(double a[N][N], double g[N],int n) { double b[N][N]={0},x0[N],x1[N],x1_x0[N],norm,temp; int i,j,k; #pragma omp parallel for private(i,j) shared(g,a,b) for(i=0;i<n;i++) { g[i]=g[i]/a[i][i]; for(j=0;j<n;j++) { if(i==j) continue; b[i][j]=-a[i][j]/a[i][i]; } } #pragma omp single {

Tema: Arhitecturi paralele de calculatoare Spnu Alexandru C411

k=0; } #pragma omp single { norm=norm_inf_omp(x1_x0,n); } while ((norm>=EPS)&&(k<max_D)) { #pragma omp parallel for private(i) shared(x0,x1) for (i=0;i<n;i++) x0[i]=x1[i]; #pragma omp parallel for private(i,j,temp) shared(x0,x1,x1_x0,g,b) for (i=0;i<n;i++) { temp=0; for(j=0;j<n;j++) temp=temp+b[i][j]*x0[j]; x1[i]=temp+g[i]; x1_x0[i]=x1[i]-x0[i]; } #pragma omp single { norm=norm_inf_omp(x1_x0,n); } #pragma omp single { k++; } } for(i=0;i<n;i++) printf("x[%d]=%lf\n",i,x1[i]); printf("%d times iteration \n",k); } int _tmain(int argc, _TCHAR* argv[]) { double a[N][N]={{8,-3,2},{4,11,-1},{6,3,12}}; double g[N]={20,33,36}; //double a[N][N]={{5,2,3},{-3,9,1},{2,-1,-7}}; //double g[N]={-1,2,3}; double t1,t2; printf("matricea A:\n");

Tema: Arhitecturi paralele de calculatoare Spnu Alexandru C411

for(int i=0;i<N;i++) { for(int j=0;j<N;j++) printf("%12.2f",a[i][j]); printf("\n"); } printf("\n"); printf("\n"); printf("vectorul B:\n"); for(int i=0;i<N;i++) printf("%12.2f",g[i]); printf("\n"); printf("\n"); t1=omp_get_wtime(); jacobi_omp(a,g,N); t2=omp_get_wtime(); double dif2=t2-t1; printf("Time omp: %f\n",dif2); _getch(); return 0; }

S-ar putea să vă placă și