Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- L4 - difuzia 1 la toti pe hupercub
- #include<stdio.h>
- #include<string.h>
- #include"mpi.h"
- int mylogaritm(int nr) {
- int count = 0;
- while ((nr & 0x1) != 1) {
- nr = nr >> 1;
- count++;
- }
- if (nr == 1) {
- return count;
- } else {
- return -1;
- }
- }
- int main(int argc, char ** argv) {
- int myrank, count;
- char M[10] = "mesaj";
- int d;
- int id;
- int s = 0;
- int id_virtual;
- int masca;
- int i;
- int destinatie_virtuala, sursa_virtuala;
- char primit[10];
- MPI_Status status;
- MPI_Init(&argc, &argv);
- MPI_Comm_size(MPI_COMM_WORLD, &count);
- MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
- d = mylogaritm(count);
- if (d == -1) {
- MPI_Finalize();
- return 0;
- }
- id = myrank;
- id_virtual = id ^ s;
- masca = (1 << d) - 1;
- for (i = d - 1; i >= 0; i--) {
- masca = masca ^ (1 << i);
- if ((id_virtual & masca) == 0) {
- if ((id_virtual & (1 << i)) == 0) {
- destinatie_virtuala = id_virtual ^ (1 << i);
- //printf("%d trimit catre %d\n", myrank, destinatie_virtuala ^ s);
- MPI_Send(M, strlen(M), MPI_CHAR, destinatie_virtuala ^ s, 1,
- MPI_COMM_WORLD);
- } else {
- sursa_virtuala = id_virtual ^ (1 << i);
- MPI_Recv(M, 20, MPI_CHAR, sursa_virtuala ^ s, 1, MPI_COMM_WORLD,
- &status);
- printf("eu sunt %d si am primit de la %d\n", id_virtual,
- sursa_virtuala);
- }
- }
- }
- MPI_Finalize();
- return 0;
- }
- L5 - Difuzia 1 la toti pe un arbore
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <mpi/mpi.h>
- #define ROOT 4 // nodul radacina
- int main(int argc, char* argv[])
- {
- int rank; // rank-ul procesului curent
- int p; // numarul de procese
- int sursa; // rank-ul procesului sender
- int destinatie; // rank-ul procesului reciever
- int eticheta = 99; // eticheta pentru mesaje
- char M[100] = "Hello world!"; // sirul de caractere ce alcatuiesc mesajul
- MPI_Status status; // starea de return pentru operatia de recieve
- MPI_Comm graph; // comunicatorul pentru topologia de tip graf
- int index[] = {1, 2, 5, 7, 10, 11, 14, 15, 16}; // index[0] = grad[0]; index[i] = index[i - 1] + grad[i]
- int nrOfNodes = 9;
- /*
- Listele de adiacenta:
- 0 -> 4
- 1 -> 6
- 2 -> 4, 7, 8
- 3 -> 4, 6
- 4 -> 0, 2, 3
- 5 -> 6
- 6 -> 1, 3, 5
- 7 -> 2
- 8 -> 2
- */
- int edges[] = {4, 6, 4, 7, 8, 4, 6, 0, 2, 3, 6, 1, 3, 5, 2, 2}; // vecinii incep din stanga si se termina in dreapta - 1
- MPI_Init(&argc, &argv);
- MPI_Comm_rank(MPI_COMM_WORLD, &rank);
- MPI_Comm_size(MPI_COMM_WORLD, &p);
- MPI_Graph_create(MPI_COMM_WORLD, nrOfNodes, index, edges, 0, &graph);
- int ncount;
- MPI_Graph_neighbors_count(graph, rank, &ncount);
- int* neighbors = (int*) malloc(ncount * sizeof(int));
- if (!neighbors)
- {
- fprintf(stderr, "Eroare la alocare!\n");
- MPI_Comm_free(&graph);
- MPI_Finalize();
- exit(EXIT_FAILURE);
- }
- MPI_Graph_neighbors(graph, rank, ncount, neighbors);
- if (rank == ROOT) // pentru nodul radacina
- {
- int i;
- // trimitem mesajul catre copii
- for (i = 0; i < ncount; ++i) // parcurgem lista de vecini a nodului radacina
- {
- destinatie = neighbors[i];
- MPI_Send(M, (int)(strlen(M) + 1), MPI_CHAR, destinatie, eticheta, graph);
- printf("[Radacina %d] Am trimis mesajul \"%s\" catre destinatia %d.\n", rank, M, destinatie);
- }
- }
- else
- {
- MPI_Recv(M, 100, MPI_CHAR, MPI_ANY_SOURCE, eticheta, graph, &status);
- if (ncount > 1) // daca nodul nu este frunza (este intermediar)
- {
- int i;
- // trimitem mesajul catre copii
- for (i = 0; i < ncount; ++i)
- {
- destinatie = neighbors[i];
- if (destinatie != status.MPI_SOURCE) // ne asiguram ca nu trimitem nodului parinte
- {
- MPI_Send(M, (int)(strlen(M) + 1), MPI_CHAR, destinatie, eticheta, graph);
- printf("[Nod %d] Am trimis mesajul \"%s\" catre destinatia %d.\n", rank, M, destinatie);
- }
- }
- }
- }
- // dealocam vectorul de vecini
- if (neighbors)
- {
- free(neighbors);
- }
- // free la topologia de tip graf
- MPI_Comm_free(&graph);
- // oprim MPI
- MPI_Finalize();
- return 0;
- }
- L5 - Difuzia toti la 1 pe un arbore
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <mpi/mpi.h>
- #define ROOT 4 // nodul radacina
- int main(int argc, char* argv[])
- {
- int rank; // rank-ul procesului curent
- int p; // numarul de procese
- int sursa; // rank-ul procesului sender
- int destinatie; // rank-ul procesului reciever
- int eticheta = 99; // eticheta pentru mesaje
- int M; // sirul de caractere ce alcatuiesc mesajul
- int calculMesaj; // calculul facut de nodul care primeste mesaje de la copii
- int sumaVecini; // suma rank-urilor tuturor vecinilor nodului curent
- MPI_Status status; // starea de return pentru operatia de recieve
- MPI_Comm graph; // comunicatorul pentru topologia de tip graf
- int index[] = {1, 2, 5, 7, 10, 11, 14, 15, 16}; // index[0] = grad[0]; index[i] = index[i - 1] + grad[i]
- int nrOfNodes = 9;
- /*
- Listele de adiacenta:
- 0 -> 4
- 1 -> 6
- 2 -> 4, 7, 8
- 3 -> 4, 6
- 4 -> 0, 2, 3
- 5 -> 6
- 6 -> 1, 3, 5
- 7 -> 2
- 8 -> 2
- */
- int edges[] = {4, 6, 4, 7, 8, 4, 6, 0, 2, 3, 6, 1, 3, 5, 2, 2}; // vecinii incep din stanga si se termina in dreapta - 1
- // lista de muchii este rezultatul concatenarii listelor de adiacenta
- // pornire MPI
- MPI_Init(&argc, &argv);
- // aflam rank-ul pentru procesul curent
- MPI_Comm_rank(MPI_COMM_WORLD, &rank);
- // aflam numarul de procese
- MPI_Comm_size(MPI_COMM_WORLD, &p);
- // cream topologia de tip graf
- MPI_Graph_create(MPI_COMM_WORLD, nrOfNodes, index, edges, 0, &graph);
- // numarul de vecini
- int ncount;
- MPI_Graph_neighbors_count(graph, rank, &ncount);
- // preluam vecinii
- int* neighbors = (int*) malloc(ncount * sizeof(int));
- if (!neighbors)
- {
- fprintf(stderr, "Eroare la alocare!\n");
- MPI_Comm_free(&graph);
- MPI_Finalize();
- exit(EXIT_FAILURE);
- }
- MPI_Graph_neighbors(graph, rank, ncount, neighbors);
- // calculam suma rank-urilor vecinilor
- int i;
- sumaVecini = 0;
- for (i = 0; i < ncount; ++i)
- {
- sumaVecini += neighbors[i];
- }
- if (rank == ROOT) // pentru nodul radacina
- {
- // algoritmul 5
- // asteptam primirea tuturor mesajelor de la copii
- calculMesaj = 0;
- for (i = 0; i < ncount; ++i)
- {
- sursa = neighbors[i];
- MPI_Recv(&M, 1, MPI_INT, sursa, eticheta, graph, &status);
- printf("[Radacina %d] Am primit mesajul \"%d\" de la sursa %d.\n", rank, M, sursa);
- // adunam ID-ul primit in mesaj la suma curenta
- calculMesaj += M;
- }
- printf("[Radacina %d] Suma de ID-uri calculata: %d.\n", rank, calculMesaj);
- }
- else
- {
- if (ncount == 1) // daca nodul este frunza
- {
- // trimitem mesajul catre parinte
- destinatie = neighbors[0]; // parintele este singurul vecin al frunzei
- MPI_Send(&rank, 1, MPI_INT, destinatie, eticheta, graph);
- printf("[Nod %d] Am trimis mesajul \"%d\" catre destinatia %d.\n", rank, rank, destinatie);
- }
- else // daca nodul este intermediar
- {
- // algoritmul 4
- // asteptam primirea tuturor mesajelor de la copii
- calculMesaj = 0;
- for (i = 0; i < ncount - 1; ++i)
- {
- sursa = neighbors[i];
- MPI_Recv(&M, 1, MPI_INT, MPI_ANY_SOURCE, eticheta, graph, &status);
- printf("[Nod %d] Am primit mesajul \"%d\" de la sursa %d.\n", rank, M, sursa);
- sumaVecini -= status.MPI_SOURCE; // scadem rank-ul nodului de la care am primit
- // adunam ID-ul primit in mesaj la suma curenta
- calculMesaj += M;
- }
- // aici, in variabila "sumaVecini" va ramane rank-ul nodului parinte
- destinatie = sumaVecini;
- // trimitem calculul facut (suma rank-urilor nodurilor de la care am primit) catre nodul parinte
- // plus rank-ul propriu
- calculMesaj += rank;
- MPI_Send(&calculMesaj, 1, MPI_INT, destinatie, eticheta, graph);
- printf("[Nod %d] Am trimis mesajul \"%d\" catre destinatia %d.\n", rank, calculMesaj, destinatie);
- }
- }
- // dealocam vectorul de vecini
- if (neighbors)
- {
- free(neighbors);
- }
- // free la topologia de tip graf
- MPI_Comm_free(&graph);
- // oprim MPI
- MPI_Finalize();
- return 0;
- }
- L6 - Coprimare prefixe - OMP
- #include <omp.h>
- #include <stdio.h>
- #include <stdlib.h>
- void comprimare(int A[], int m)
- {
- int k, j;
- int k1;
- int k2;
- for (k = m - 1; k >= 0; --k)
- {
- k1 = 1 << k;
- k2 = 1 << (k + 1);
- #pragma omp parallel for private(j) num_threads(k1)
- for (j = k1; j <= k2 - 1; ++j)
- {
- A[j] = A[2 * j] + A[2 * j + 1];
- }
- }
- }
- void calculPrefixe(int A[], int B[], int m)
- {
- B[1] = A[1];
- int k,j;
- int k1;
- int k2;
- for (k = 1; k <= m; ++k)
- {
- k1 = 1 << k;
- k2 = 1 << (k + 1);
- #pragma omp parallel for private(j) num_threads(k1)
- for (j = k1; j <= k2 - 1; ++j)
- {
- if (j % 2 == 1)
- {
- B[j] = B[(j - 1) / 2];
- }
- else
- {
- B[j] = B[j / 2] - A[j + 1];
- }
- }
- }
- }
- int main() {
- int m = 3;
- int i;
- int dim = 16;
- int A[16]= {0,0,0,0,0,0,0,0,3,2,1,6,5,4,2,9};
- int B[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
- comprimare(A,m);
- printf("A = ");
- for (i = 0; i < dim; ++i)
- {
- printf("%d ", A[i]);
- }
- calculPrefixe(A, B,m);
- printf("\nB = ");
- for (i = 0; i < dim; ++i)
- {
- printf("%d ", B[i]);
- }
- return 0;
- }
- L6 Comprimare_prefixe MPI
- #include <stdio.h>
- #include <stdlib.h>
- #include "mpi.h"
- #define NP 16 // numarul de procese este 2 * n
- #define ROOT 1 // nodul radacina
- int main(int argc, char *argv[]) {
- int A[16] = { 0,0,0,0,0,0,0,0,3,2,1,6,5,4,2,9 };
- int B[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
- int rank; // rank-ul procesului curent
- int np; // numarul de procese = dimensiunea tabloului A
- MPI_Status status; // starea operatiei de recieve
- int sursaStanga, sursaDreapta; // rank-urile proceselor sender (copiii)
- int destinatieStanga, destinatieDreapta; // rank-urile proceselor reciever (copiii)
- int sursa; // rank-ul procesului sender
- int destinatie; // rank-ul procesului reciever
- int eticheta = 99; // eticheta pentru mesaje
- int valoarePrimita; // ce am primit de la procesul parinte
- int valoarePrimitaStanga, valoarePrimitaDreapta; // ce am primit de la procesele fiu
- int rezultatCalcul; // rezultatul calculului efectuat de nodul curent
- int val; // valoarea corespunzatoare procesului cu rank-ul curent
- MPI_Init(&argc, &argv);
- MPI_Comm_rank(MPI_COMM_WORLD, &rank);
- MPI_Comm_size(MPI_COMM_WORLD, &np);
- MPI_Scatter(A, 1, MPI_INT, &val, 1, MPI_INT, ROOT, MPI_COMM_WORLD);
- if (rank >= np / 2) // pentru frunze
- {
- destinatie = rank / 2;
- MPI_Send(&val, 1, MPI_INT, destinatie, eticheta, MPI_COMM_WORLD);
- printf("[Frunza %d] Am trimis mesajul \"%d\" catre nodul parinte %d.\n", rank, val, destinatie);
- }
- else if (rank != 0) // pentru nodurile intermediare (fara procesul 0, care nu este folosit!)
- {
- sursaStanga = 2 * rank; // copilul stang
- sursaDreapta = 2 * rank + 1; // copilul drept
- MPI_Recv(&valoarePrimitaStanga, 1, MPI_INT, sursaStanga, eticheta, MPI_COMM_WORLD, &status);
- printf("[Nod %d] Am primit mesajul \"%d\" de la copilul stang %d.\n", rank, valoarePrimitaStanga, sursaStanga);
- MPI_Recv(&valoarePrimitaDreapta, 1, MPI_INT, sursaDreapta, eticheta, MPI_COMM_WORLD, &status);
- printf("[Nod %d] Am primit mesajul \"%d\" de la copilul drept %d.\n", rank, valoarePrimitaDreapta, sursaDreapta);
- rezultatCalcul = valoarePrimitaStanga + valoarePrimitaDreapta;
- printf("[Nod %d] Am calculat valoarea \"%d\".\n", rank, rezultatCalcul);
- val = rezultatCalcul;
- if (rank != ROOT) // in afara de nodul radacina
- {
- destinatie = rank / 2;
- MPI_Send(&val, 1, MPI_INT, destinatie, eticheta, MPI_COMM_WORLD);
- printf("[Nod %d] Am trimis mesajul \"%d\" catre nodul parinte %d.\n", rank, val, destinatie);
- }
- }
- MPI_Gather(&val, 1, MPI_INT, A, 1, MPI_INT, ROOT, MPI_COMM_WORLD);
- if (rank == ROOT) // procesul ROOT face afisarea
- {
- printf("\nTabloul, dupa comprimare:\n");
- for (int i = 0; i < np; i++)
- {
- printf("%d ", A[i]);
- }
- printf("\n\n");
- }
- if (rank == ROOT)
- {
- destinatieStanga = 2 * rank;
- destinatieDreapta = 2 * rank + 1;
- MPI_Send(&val, 1, MPI_INT, destinatieStanga, eticheta, MPI_COMM_WORLD);
- printf("[Radacina %d] Am trimis mesajul \"%d\" catre nodul fiu %d.\n", rank, val, destinatieStanga);
- MPI_Send(&val, 1, MPI_INT, destinatieDreapta, eticheta, MPI_COMM_WORLD);
- printf("[Radacina %d] Am trimis mesajul \"%d\" catre nodul fiu %d.\n", rank, val, destinatieDreapta);
- }
- else if (rank != 0) // procesul cu rank-ul 0 nu este folosit!
- {
- sursa = rank / 2;
- MPI_Recv(&valoarePrimita, 1, MPI_INT, sursa, eticheta, MPI_COMM_WORLD, &status);
- printf("[Nod %d] Am primit mesajul \"%d\" de la nodul parinte %d.\n", rank, valoarePrimita, sursa);
- if (rank % 2 == 0)
- {
- sursaDreapta = rank + 1;
- MPI_Recv(&valoarePrimitaDreapta, 1, MPI_INT, sursaDreapta, eticheta, MPI_COMM_WORLD, &status);
- printf("[Nod %d] Am primit mesajul \"%d\" de la nodul vecin %d.\n", rank, valoarePrimitaDreapta, sursaDreapta);
- val = valoarePrimita - valoarePrimitaDreapta;
- }
- else
- {
- destinatieStanga = rank - 1;
- MPI_Send(&val, 1, MPI_INT, destinatieStanga, eticheta, MPI_COMM_WORLD);
- printf("[Nod %d] Am trimis mesajul \"%d\" catre nodul vecin %d.\n", rank, val, destinatieStanga);
- val = valoarePrimita;
- }
- if (rank < np / 2)
- {
- destinatieStanga = 2 * rank;
- destinatieDreapta = 2 * rank + 1;
- MPI_Send(&val, 1, MPI_INT, destinatieStanga, eticheta, MPI_COMM_WORLD);
- printf("[Nod %d] Am trimis mesajul \"%d\" catre nodul fiu %d.\n", rank, val, destinatieStanga);
- MPI_Send(&val, 1, MPI_INT, destinatieDreapta, eticheta, MPI_COMM_WORLD);
- printf("[Nod %d] Am trimis mesajul \"%d\" catre nodul fiu %d.\n", rank, val, destinatieDreapta);
- }
- }
- MPI_Gather(&val, 1, MPI_INT, B, 1, MPI_INT, ROOT, MPI_COMM_WORLD);
- if (rank == ROOT) // procesul ROOT face afisarea, respectiv dealocarea
- {
- printf("\nTabloul, dupa calculul prefixelor:\n");
- for (int i = 0; i < np; i++)
- {
- printf("%d ", B[i]);
- }
- printf("\n\n");
- }
- MPI_Finalize();
- return 0;
- }
- L7 - Memoria partajata OMP
- #include <omp.h>
- #include <stdio.h>
- #include <stdlib.h>
- int main (int argc, char *argv[]) {
- int A[4]={ 2, 3, 6, 8};
- //int A1[4];
- int R[8][4];
- int P[4];
- int n=4;
- int i,j;
- #pragma omp parallel for private(i,j) num_threads(n)
- for (i = 0; i < n; i++)
- {
- for (j = 0; j < n; j++)
- {
- if (A[i] < A[j])
- {
- R[i + n - 1][j] = 1;
- }
- else
- {
- R[i + n - 1][j] = 0;
- }
- }
- }
- #pragma omp parallel for private(i,j) num_threads(n)
- for (j = 0; j < n; j++)
- {
- for (i = n-2; i >=0; i--)
- {
- R[i][j] = R[2*i+1][j] + R[2*i+2][j];
- }
- P[j] = R[0][j];
- }
- #pragma omp parallel for private(j) num_threads(n)
- for (j = 0; j < n; j++) {
- A[P[j]] = A[j];
- }
- for (i = 0; i < n; i++) {
- printf("%d ", A[i]);
- }
- return 0;
- }
- L7 - Memoria partajata MPI
- #include <stdio.h>
- #include <string.h>
- #include "mpi.h"
- int main(int argc, char *argv[]) {
- int my_rank;
- int p;
- int tag=0;
- int faza;
- int n = 8;
- int r, v;
- int A[8] = { 3, 2, 3, 8, 5, 6, 4, 1 };
- MPI_Status status;
- MPI_Init(&argc, &argv);
- MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
- MPI_Comm_size(MPI_COMM_WORLD, &p);
- for (faza = 1; faza <= n; faza++)
- {
- if (faza % 2 == 1 && (my_rank <=2*n/2-1))
- {
- if (my_rank % 2 == 0)
- {
- r = A[my_rank];
- MPI_Send(&r, 1, MPI_INT, my_rank + 1, tag, MPI_COMM_WORLD);
- MPI_Recv(&v, 1, MPI_INT, my_rank + 1, tag, MPI_COMM_WORLD, &status);
- if (v < r)
- {
- A[my_rank] = v;
- }
- }
- else
- {
- r = A[my_rank];
- MPI_Send(&r, 1, MPI_INT, my_rank - 1, tag, MPI_COMM_WORLD);
- MPI_Recv(&v, 1, MPI_INT, my_rank - 1, tag, MPI_COMM_WORLD, &status);
- if (v > r)
- {
- A[my_rank] = v;
- }
- }
- }
- if (faza % 2 == 0 && (my_rank <=(2*n-1)/2))
- {
- if (my_rank % 2 == 1)
- {
- if (my_rank + 1 < n)
- {
- r = A[my_rank];
- MPI_Send(&r, 1, MPI_INT, my_rank + 1, tag, MPI_COMM_WORLD);
- MPI_Recv(&v, 1, MPI_INT, my_rank + 1, tag, MPI_COMM_WORLD,&status);
- if (v < r)
- {
- A[my_rank] = v;
- }
- }
- }
- else
- {
- if (my_rank > 0)
- {
- r = A[my_rank];
- MPI_Send(&r, 1, MPI_INT, my_rank - 1, tag,MPI_COMM_WORLD);
- MPI_Recv(&v, 1, MPI_INT, my_rank - 1, tag,MPI_COMM_WORLD, &status);
- if (v > r)
- {
- A[my_rank] = v;
- }
- }
- }
- }
- }
- printf(" A[%d]=%d \n",my_rank,A[my_rank]);
- MPI_Finalize();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement