Advertisement
Guest User

ppr4

a guest
Nov 15th, 2019
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.00 KB | None | 0 0
  1. // newDynMatrix.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include <iostream>
  5. #include <cstdlib>
  6. #include <iomanip>
  7. #include <mpi.h>
  8.  
  9. #define MASTER 0
  10. #define FROM_MASTER 1
  11. #define FROM_WORKER 2
  12.  
  13. using namespace std;
  14.  
  15. int main(int argc, char **argv)
  16. {
  17.  
  18. int NRA=4, NCA=3, NCB=2; //przyk�adowe wymiary macierzy
  19.  
  20. int rank, size;
  21.  
  22. //Zadeklaruj następujące zmienne:
  23. //Zmienną, która przyjmie numer zadania nadawcy wiadomości (source),
  24. int source = -1;
  25. //Zmienną, która przyjmie numer zadania odbiorcy komunikatu (destination),
  26. int destination = -1;
  27. //Rodzaj wiadomości (message type)
  28. // ??????
  29.  
  30. //Zmienną, która określa ilość wierszy macierzy A wysłanych do każdego procesu/pracownika(rows),
  31. int rowsSent = -1;
  32. //Zmienną offset, służącą do wyznaczania które wiersze otrzyma dany proces,
  33. int offset = -1;
  34. //Dwie zmienne pomocnicze, które mogą służyć do uszczegółowienia liczby wierszy wysłanych do każdego pracownika,
  35. int rowsPerProcess = -1;
  36. int remainderToDistribute = 0;
  37.  
  38. MPI_Status status;
  39.  
  40. //Zainicjalizuj bibliotekę MPI,
  41. MPI_Init(&argc, &argv);
  42. MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  43. MPI_Comm_size(MPI_COMM_WORLD, &size);
  44.  
  45. double startTime;
  46.  
  47. //Rozpocznij pomiar czasu funkcją MPI_Wtime()
  48. if (rank == MASTER) {
  49. startTime = MPI_Wtime();
  50. }
  51.  
  52.  
  53. /*Zadeklaruj macierz A, B i C (macierz wynikowa) jako tablice dynamiczne,
  54. zajmij ciągłe miejsce w pamięci na wszystkie macierze,
  55. (Patrz: Pomoc, na końcu instrukcji)
  56. */
  57.  
  58. double **b = new double *[NCA];
  59. b[0] = new double[NCA*NCB];
  60. for (int i = 1; i < NCA; i++)
  61. {
  62. b[i] = &b[0][i*NCB];
  63. }
  64.  
  65. double **a = new double *[NRA];
  66. a = new double *[NRA]; //zadeklarowanie tablicy dynamicznej ci�g�ej contingous, aby mo�na j� by�o przes�a� w MPI bez problemu
  67. a[0] = new double[NRA*NCA];
  68. for (int i = 1; i < NRA; i++)
  69. {
  70. a[i] = &a[0][i*NCA];
  71. }
  72.  
  73. if (rank == MASTER) {
  74. //Wypisz komunikat mówiący o ilości procesów z jakim wystartował program,
  75. cout << "Master przystępuje do zarządzania z łączną liczbą procesów " << size << endl;
  76.  
  77. //Wypełnij macierze A i B,
  78. cout << "Master zgłasza wypełnianie tablicy A:" << endl;
  79. for (int i = 0; i < NRA; i++)
  80. {
  81. for (int j = 0; j < NCA; j++) //wpisanie wartosci do tablicy
  82. {
  83. a[i][j] = 1+i + j;
  84. cout << setw(5) << a[i][j] << " ";
  85. }
  86. cout<<endl;
  87. }
  88.  
  89. cout << "Master zgłasza wypełnianie tablicy B" << endl;
  90. for (int i = 0; i < NCA; i++)
  91. {
  92. for (int j = 0; j < NCB; j++)
  93. {
  94. b[i][j] = 1 + i*j;
  95. cout << setw(5) << b[i][j] << " ";
  96. }
  97. cout<<endl;
  98. }
  99.  
  100. cout << "###################### " << endl;
  101.  
  102. double **c = new double*[NRA];//zadeklarowanie macierzy wynikowej
  103. c[0]=new double[NRA*NCB];
  104. for (int i = 1; i < NRA; i++)
  105. {
  106. c[i] = &c[0][i*NCB];
  107. }
  108.  
  109. //Rozgłoś macierz B do wszystkich procesów stosując funkcję MPI_Bcast
  110. MPI_Bcast(&(b[0][0]), NCA*NCB, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  111. //Wyślij odpowiednie dane z macierzy A do procesów/pracowników,
  112. rowsPerProcess = NRA / (size - 1);
  113. remainderToDistribute = NRA % (size - 1);
  114. offset = 0;
  115.  
  116. for (int i = 1; i < size; i++) {
  117. //z którego kawałka macierzy dostanie
  118. MPI_Send(&offset, 1, MPI_INT, i, FROM_MASTER, MPI_COMM_WORLD);
  119.  
  120. //ile wierszy dostanie
  121. if (remainderToDistribute > 0) {
  122. rowsSent = rowsPerProcess + 1;
  123. remainderToDistribute--;
  124. } else {
  125. rowsSent = rowsPerProcess;
  126. }
  127. MPI_Send(&rowsSent, 1, MPI_INT, i, FROM_MASTER, MPI_COMM_WORLD);
  128.  
  129. //zawartość tego kawałka
  130. MPI_Send(&(a[offset][0]), rowsSent * NCA, MPI_DOUBLE, i, FROM_MASTER, MPI_COMM_WORLD);
  131.  
  132. //przesunięcie niżej w macierz
  133. offset += rowsSent;
  134. }
  135.  
  136. //oczekiwanie na wyniki od procesów
  137. for (int i = 1; i < size; i++) {
  138. cout << "Master oczekuje wyników od " << i << endl;
  139. //offsetu
  140. MPI_Recv(&offset, 1, MPI_INT, i, FROM_WORKER, MPI_COMM_WORLD, &status);
  141. cout << "Proces " << rank << " melduje otrzymanie offsetu: " << offset << endl;
  142. //l. wierszy
  143. MPI_Recv(&rowsSent, 1, MPI_INT, i, FROM_WORKER, MPI_COMM_WORLD, &status);
  144. cout << "Proces " << rank << " melduje otrzymanie l. wierszy: " << rowsSent << endl;
  145. //macierzy
  146. MPI_Recv(&(c[offset][0]), rowsSent * NCB, MPI_DOUBLE, i, FROM_WORKER, MPI_COMM_WORLD, &status);
  147. cout << "Proces " << rank << " melduje otrzymanie macierzy cc: " << endl;
  148. }
  149.  
  150. //koniec
  151. cout << "Zakończono w czasie " << MPI_Wtime() - startTime << endl;
  152. cout << "Tablica wynikowa: " << endl;
  153. for (int i = 0; i<NRA; i++)
  154. {
  155. for (int j = 0; j<NCB; j++)
  156. {
  157. cout << setw(5) << c[i][j] << " ";
  158. }
  159. cout<<endl;
  160. }
  161.  
  162. } else {
  163. double **cc = new double*[NRA];//zadeklarowanie macierzy wynikowej
  164. cc[0]=new double[NRA*NCB];
  165. for (int i = 1; i < NRA; i++)
  166. {
  167. cc[i] = &cc[0][i*NCB];
  168. }
  169.  
  170. //odbieranie zadania od Mastera
  171. //<BCAST wysłał macierz b>
  172. //offsetu
  173. MPI_Recv(&offset, 1, MPI_INT, 0, FROM_MASTER, MPI_COMM_WORLD, &status);
  174. cout << "Proces " << rank << " melduje otrzymanie swojego offsetu: " << offset << endl;
  175. //l. wierszy
  176. MPI_Recv(&rowsSent, 1, MPI_INT, 0, FROM_MASTER, MPI_COMM_WORLD, &status);
  177. cout << "Proces " << rank << " melduje otrzymanie liczby wierszy: " << rowsSent << endl;
  178. //macierzy
  179. MPI_Recv(&(a[0][0]), rowsSent * NCA, MPI_DOUBLE, 0, FROM_MASTER, MPI_COMM_WORLD, &status);
  180. cout << "Proces " << rank << " melduje otrzymanie swoich wierszy: " << endl;
  181. for (int i = 0; i < rowsSent; i++) {
  182. for (int j = 0; j < NCA; j++) {
  183. cout << setw(5) << a[i][j] << " ";
  184. }
  185. cout << endl;
  186. }
  187.  
  188. cout << "Proces " << rank << " melduje swoją B: " << endl;
  189. for (int i = 0; i < NCA; i++)
  190. {
  191. for (int j = 0; j < NCB; j++)
  192. {
  193. b[i][j] = 1 + i*j;
  194. cout << setw(5) << b[i][j] << " ";
  195. }
  196. cout<<endl;
  197. }
  198.  
  199. //obliczanie
  200. for (int k = 0; k < NCB; k++)// obliczenie iloczynu macierzy
  201. {
  202. for (int i = 0; i < rowsSent; i++)
  203. {
  204. cc[i][k] = 0.0;
  205. for (int j = 0; j < NCA; j++)
  206. {
  207. cc[i][k] = cc[i][k] + a[i][j] * b[j][k];
  208. }
  209. }
  210. }
  211.  
  212. cout << "Proces " << rank << " melduje zakończenie obliczeń i przechodzi do wysyłania wyników " << endl;
  213. //powrót do MASTERa
  214. //offsetu
  215. MPI_Send(&offset, 1, MPI_INT, MASTER, FROM_WORKER, MPI_COMM_WORLD);
  216. //l. wierszy
  217. MPI_Send(&rowsSent, 1, MPI_INT, MASTER, FROM_WORKER, MPI_COMM_WORLD);
  218. //macierzy
  219. MPI_Send(&(cc[0][0]), rowsSent * NCB, MPI_DOUBLE, MASTER, FROM_WORKER, MPI_COMM_WORLD);
  220. cout << "Proces " << rank << " melduje wysłanie wyników " << endl;
  221.  
  222. }
  223. //cout << "Macierz wynikowa: " << endl;
  224. //cout << "##### WYNIK: ################# " << endl;
  225. /*
  226. for (int k = 0; k < NCB; k++)// obliczenie iloczynu macierzy
  227. {
  228. for (int i = 0; i < NRA; i++)
  229. {
  230. c[i][k] = 0.0;
  231. for (int j = 0; j < NCA; j++)
  232. {
  233. c[i][k] = c[i][k] + a[i][j] * b[j][k];
  234. }
  235. }
  236. }
  237. */
  238.  
  239. MPI_Finalize();
  240. return 0;
  241. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement