Advertisement
Guest User

Untitled

a guest
Nov 26th, 2014
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.77 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include "mpi.h"
  5.  
  6. #define V 4
  7.  
  8. //Zakładamy, że liczba procesów p jest równa r^2, gdzie r jest liczbą całkowitą, p <= V^2 oraz V % r = 0
  9.  
  10. float min(float a, float b)
  11. {
  12.     if(a <= b)
  13.         return a;
  14.     return b;
  15. }
  16.  
  17. int oblicz_pozycje(int i, int j, int w, int r)
  18. {
  19.     return w * w * ((i / w) * r + (j / w)) + (i % w) * w + (j % w);
  20. }
  21.  
  22. void oblicz_pozycje_odwrotna(int a, int w, int r, int *i, int *j)
  23. {
  24.     *i = (a / (w * w)) / r * w + (a % (w * w)) / w;
  25.     *j = (a / (w * w)) % r * w + (a % w);
  26. }
  27.  
  28. int main(int argc, char *argv[])
  29. {
  30.     int i, j, k;
  31.     float macierz[V][V];
  32.     float wynik[V][V];
  33.     float **macierz_lokalna;
  34.     float *macierz_tablica, *macierz_lokalna_tablica;
  35.     float *komunikat_wiersz, *komunikat_kolumna;
  36.     const float nieskonczonosc = 1.0/0.0;
  37.     int rank;
  38.     MPI_Comm comm_cart, comm_wiersz, comm_kolumna;
  39.     int dims[2];
  40.     int periods[] = {1, 1};
  41.     int nr_wiersza, nr_kolumny;
  42.     int coords[2];
  43.     int p, r, wielkosc_lokalna;
  44.  
  45.     MPI_Init(&argc, &argv);
  46.     MPI_Comm_size(MPI_COMM_WORLD, &p);
  47.  
  48.     r = (int)floor(sqrt(p));
  49.     dims[0] = dims[1] = r;
  50.     wielkosc_lokalna = V / r;
  51.     macierz_lokalna = (float **)calloc(wielkosc_lokalna, sizeof(float *));
  52.     macierz_tablica = (float *)calloc(V * V, sizeof(float));
  53.     macierz_lokalna_tablica = (float *)calloc(wielkosc_lokalna * wielkosc_lokalna, sizeof(float));
  54.     komunikat_wiersz = (float *)calloc(wielkosc_lokalna, sizeof(float));
  55.     komunikat_kolumna = (float *)calloc(wielkosc_lokalna, sizeof(float));
  56.  
  57.     for(i = 0; i < wielkosc_lokalna; ++i)
  58.     {
  59.         macierz_lokalna[i] = (float *)calloc(wielkosc_lokalna, sizeof(float));
  60.     }
  61.  
  62.     MPI_Cart_create(MPI_COMM_WORLD, 2, dims, periods, 1, &comm_cart);
  63.     MPI_Comm_rank(comm_cart, &rank);
  64.     MPI_Cart_coords(comm_cart, rank, 2, coords);
  65.     nr_wiersza = coords[0];
  66.     nr_kolumny = coords[1];
  67.     dims[0] = 0;
  68.     dims[1] = 1;
  69.     MPI_Cart_sub(comm_cart, dims, &comm_wiersz);
  70.     dims[0] = 1;
  71.     dims[1] = 0;
  72.     MPI_Cart_sub(comm_cart, dims, &comm_kolumna);
  73.     if(rank == 0)
  74.     {
  75.  
  76. /*
  77.  * Ustawienie wartości w macierzy
  78.  * dla macierz[i][i] = 0
  79.  * jeśli istnieje krawędź z i do j to macierz[i][j] = waga krawędzi
  80.  * jeśli krawędź z i do j nie istnieje to macierz[i][j] = nieskończoność
  81.  */
  82.         for(i = 0; i < V; ++i)
  83.         {
  84.             for(j = 0; j < V; ++j)
  85.             {
  86.                 if(i == j)
  87.                     macierz[i][i] = 0;
  88.                 else
  89.                     macierz[i][j] = nieskonczonosc;
  90.             }
  91.         }
  92.  
  93. macierz[0][2] = -2;
  94. macierz[1][0] = 4;
  95. macierz[1][2] = 3;
  96. macierz[2][3] = 2;
  97. macierz[3][1] = -1;
  98.  
  99. /*
  100. macierz[0][1] = 1;
  101. macierz[0][3] = 5;
  102. macierz[1][2] = 2;
  103. macierz[1][3] = 1;
  104. macierz[2][0] = 1;
  105. macierz[2][3] = 3;
  106. macierz[3][1] = 3;
  107. macierz[3][2] = 2;
  108. */
  109.  
  110. //Rozesłanie lokalnych macierzy do odpowiednich procesów
  111.         for(i = 0; i < V; ++i)
  112.         {
  113.             for(j = 0; j < V; ++j)
  114.             {
  115.                 macierz_tablica[oblicz_pozycje(i, j, wielkosc_lokalna, r)] = macierz[i][j];
  116.             }
  117.         }
  118.     }
  119.     MPI_Scatter(macierz_tablica, wielkosc_lokalna * wielkosc_lokalna, MPI_FLOAT, macierz_lokalna_tablica, wielkosc_lokalna * wielkosc_lokalna, MPI_FLOAT, 0, comm_cart);
  120.     for(i = 0; i < wielkosc_lokalna; ++i)
  121.     {
  122.         for(j = 0; j < wielkosc_lokalna; ++j)
  123.         {
  124.             macierz_lokalna[i][j] = macierz_lokalna_tablica[i * wielkosc_lokalna + j];
  125.         }
  126.     }
  127.  
  128. //Główna część równoległego algorytmu Floyda
  129.     for(k = 0; k < V; ++k)
  130.     {
  131.  
  132. //Rozesłanie fragmentów kolumn i wierszy
  133.         if(nr_wiersza == k / wielkosc_lokalna)
  134.         {
  135.             for(i = 0; i < wielkosc_lokalna; ++i)
  136.             {
  137.                 komunikat_kolumna[i] = macierz_lokalna[k % wielkosc_lokalna][i];
  138.             }
  139.         }
  140.         if(nr_kolumny == k / wielkosc_lokalna)
  141.         {
  142.             for(i = 0; i < wielkosc_lokalna; ++i)
  143.             {
  144.                 komunikat_wiersz[i] = macierz_lokalna[i][k % wielkosc_lokalna];
  145.             }
  146.         }
  147.         MPI_Bcast(komunikat_wiersz, wielkosc_lokalna, MPI_FLOAT, k / wielkosc_lokalna, comm_wiersz);
  148.         MPI_Bcast(komunikat_kolumna, wielkosc_lokalna, MPI_FLOAT, k / wielkosc_lokalna, comm_kolumna);
  149.  
  150. //Obliczenia w algorytmie
  151.         for(i = 0; i < wielkosc_lokalna; ++i)
  152.         {
  153.             for(j = 0; j < wielkosc_lokalna; ++j)
  154.             {
  155.                 macierz_lokalna[i][j] = min(macierz_lokalna[i][j], komunikat_wiersz[i] + komunikat_kolumna[j]);
  156.             }
  157.         }
  158.     }
  159.  
  160. //Łączenie wyników
  161.     for(i = 0; i < wielkosc_lokalna; ++i)
  162.     {
  163.         for(j = 0; j < wielkosc_lokalna; ++j)
  164.         {
  165.             macierz_lokalna_tablica[i * wielkosc_lokalna + j] = macierz_lokalna[i][j];
  166.         }
  167.     }
  168.     MPI_Gather(macierz_lokalna_tablica, wielkosc_lokalna * wielkosc_lokalna, MPI_FLOAT, macierz_tablica, wielkosc_lokalna * wielkosc_lokalna, MPI_FLOAT, 0, comm_cart);
  169.     if(rank == 0)
  170.     {
  171.         for(k = 0; k < V * V; ++k)
  172.         {
  173.             oblicz_pozycje_odwrotna(k, wielkosc_lokalna, r, &i, &j);
  174.             wynik[i][j] = macierz_tablica[k];
  175.         }
  176.  
  177. //Wyswietlanie wyniku
  178.         for(i = 0; i < V; ++i)
  179.         {
  180.             for(j = 0; j < V; ++j)
  181.                 printf("%.3f\t", wynik[i][j]);
  182.             printf("\n");
  183.         }
  184.     }
  185.  
  186.     MPI_Finalize();
  187.     return 0;
  188. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement