Advertisement
Guest User

Untitled

a guest
Oct 13th, 2012
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.03 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <mpi.h>
  4. #define AKYRO Lathos(__LINE__)
  5. void Lathos(int line);
  6.  
  7. main(int argc, char *argv[])
  8. {
  9. double b_pivot;
  10. double *computed_x;
  11. FILE *fd;
  12. int flops;
  13. int *have_x;
  14. double highest;
  15. int i;
  16. int j;
  17. int k;
  18. double multiplier;
  19. double **my_a;
  20. double *my_b;
  21. int my_rank;
  22. double num;
  23. int num_processes;
  24. int order;
  25. int *perm_vector;
  26. double *pivot_elements;
  27. int pivot_row;
  28. double *pivot_row_elements;
  29. FILE *result_file;
  30. int *rp_map;
  31. int *sent_yet;
  32. MPI_Status status;
  33. int temp;
  34. double total;
  35.  
  36. flops = 0;
  37.  
  38. /* Ekkinish MPI, pairnei arithmo epeksergastwn kai pairnei kai rank */
  39. MPI_Init(&argc, &argv);
  40. MPI_Comm_size(MPI_COMM_WORLD, &num_processes);
  41. MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
  42.  
  43. /* Anoigma tou arxeiou eisodou. Einai ths morfh matrix.txt
  44. ** Ston pinaka sthn arxh dhlwnoume to plhthos twn grammwn ths eksiswshs
  45. ** kai sthn sunexeia dhlwnoume tis times tou pinaka se morfh an eixame x0,x1,x2,x3
  46. ** prwta oles tis times tou x0, meta tou x1 kai meta tou x2 */
  47. fd = fopen("matrix.txt", "r");
  48. fscanf(fd, "%d", &order);
  49.  
  50. /* To perm_vector mas dinei thn lista periexomenwn, entos tou my_a,
  51. ** opou mia dwsmenh grammh ston pinaka einai apothikeymenh
  52. ** Arxika h grammi 0 einai sto index 0, h grammi 1 sto index 1 , ktl... */
  53. perm_vector = (int *) malloc(sizeof(int) * order);
  54. if (perm_vector == NULL) AKYRO;
  55.  
  56. for (i = 0; i < order; i++) /* Grammes */
  57. perm_vector[i] = i;
  58.  
  59. rp_map = (int *) malloc(sizeof(int) * order);
  60. if (rp_map == NULL) AKYRO;
  61.  
  62. for (i = 0; i < order; i++)
  63. rp_map[i] = i % num_processes;
  64.  
  65. /* Desmeysh xwrou tou pinaka sintelestwn kai toy dianysmatos lysewn pou ayto to process einai ypeythino gia apothikeysh. */
  66. my_a = (double **) malloc(sizeof(double *) * order);
  67. if (my_a == NULL) AKYRO;
  68.  
  69. for (i = 0; i < order; i++)
  70. {
  71. if (rp_map[i] == my_rank)
  72. {
  73. my_a[i] = (double *) malloc(sizeof(double) * order);
  74. if (my_a[i] == NULL) AKYRO;
  75. }
  76. else my_a[i] = NULL;
  77. }
  78.  
  79. my_b = (double *) malloc(sizeof(double) * order);
  80. if (my_b == NULL) AKYRO;
  81.  
  82. /* Anagnwsh tou pinaka sintelestwn. */
  83. for (i = 0; i < order; i++) /* Sthles */
  84. {
  85. for (j = 0; j < order; j++) /* Grammes */
  86. {
  87. fscanf(fd, "%lf", &num);
  88.  
  89. if (rp_map[perm_vector[j]] == my_rank)
  90. my_a[perm_vector[j]][i] = num;
  91. }
  92. }
  93.  
  94. /* Anagnwsh tou dianysmatos lysewn. */
  95. for (i = 0; i < order; i++) /* Grammes */
  96. {
  97. fscanf(fd, "%lf", &num);
  98.  
  99. if (rp_map[perm_vector[i]] == my_rank)
  100. my_b[perm_vector[i]] = num;
  101. }
  102.  
  103. /* Ektelesh Gaussian Elimination me partial pivoting. */
  104.  
  105. /* Desmeysh xwrou gia ta stoixeia pivot. */
  106. pivot_elements = (double *) malloc(sizeof(double) * order);
  107. if (pivot_elements == NULL) AKYRO;
  108.  
  109. pivot_row_elements = (double *) malloc(sizeof(double) * order);
  110. if (pivot_row_elements == NULL) AKYRO;
  111.  
  112. for (i = 0; i < order - 1; i++) /* Grammes */
  113. {
  114. /* Apostolh twn stoixeiwn pivot stous allous processors. */
  115. for (j = i; j < order; j++) /* Grammes */
  116. {
  117. if (rp_map[perm_vector[j]] == my_rank)
  118. {
  119. for (k = 0; k < num_processes; k++)
  120. {
  121. if (k != my_rank)
  122. {
  123. /* to i einai gia sthles edw. */
  124. MPI_Send(&my_a[perm_vector[j]][i], 1, MPI_DOUBLE, k,
  125. j, MPI_COMM_WORLD);
  126. }
  127. }
  128. }
  129. }
  130.  
  131. /* Symplhrwsh tou pinaka me ta stoixeia pivot. */
  132. for (j = i; j < order; j++) /* Grammes */
  133. {
  134. if (rp_map[perm_vector[j]] == my_rank)
  135. {
  136. /* to i einai gia sthles edw. */
  137. pivot_elements[j] = my_a[perm_vector[j]][i];
  138. if (pivot_elements[j] < 0.0) pivot_elements[j] *= -1.0;
  139. }
  140. else
  141. {
  142. MPI_Recv(&pivot_elements[j], 1, MPI_DOUBLE,
  143. rp_map[perm_vector[j]], j, MPI_COMM_WORLD,
  144. &status);
  145. if (pivot_elements[j] < 0.0) pivot_elements[j] *= -1.0;
  146. }
  147. }
  148.  
  149. /* Eyresh tis grammhs pivot. */
  150. highest = 0.0;
  151.  
  152. for (j = i; j < order; j++) /* Grammes */
  153. {
  154. if (pivot_elements[j] > highest)
  155. {
  156. highest = pivot_elements[j];
  157. pivot_row = j;
  158. }
  159. }
  160.  
  161. /* Allagh tis grammhs i me thn grammh pivot_row. */
  162. temp = perm_vector[i];
  163. perm_vector[i] = perm_vector[pivot_row];
  164. perm_vector[pivot_row] = temp;
  165.  
  166. if (rp_map[perm_vector[i]] == my_rank)
  167. {
  168. for (j = 0; j < num_processes; j++)
  169. {
  170. if (j != my_rank)
  171. {
  172. MPI_Send(my_a[perm_vector[i]], order, MPI_DOUBLE,
  173. j, i, MPI_COMM_WORLD);
  174. MPI_Send(&my_b[perm_vector[i]], 1, MPI_DOUBLE,
  175. j, i, MPI_COMM_WORLD);
  176. }
  177. }
  178.  
  179. /* Antigrafh ths grammhs pivot sto pivot_row_elements. */
  180. for (j = 0; j < order; j++) /* Sthles */
  181. pivot_row_elements[j] = my_a[perm_vector[i]][j];
  182.  
  183. b_pivot = my_b[perm_vector[i]];
  184. }
  185. else
  186. {
  187. MPI_Recv(pivot_row_elements, order, MPI_DOUBLE,
  188. rp_map[perm_vector[i]], i, MPI_COMM_WORLD,
  189. &status);
  190. MPI_Recv(&b_pivot, 1, MPI_DOUBLE, rp_map[perm_vector[i]],
  191. i, MPI_COMM_WORLD, &status);
  192. }
  193.  
  194. /*Diadikasia afaireshs pollaplasiou me skopo h sthlh i na ginei 0*/
  195. for (j = i + 1; j < order; j++) /* Rows */
  196. {
  197. if (rp_map[perm_vector[j]] == my_rank)
  198. {
  199. multiplier = my_a[perm_vector[j]][i] /
  200. pivot_row_elements[i];
  201.  
  202. for (k = 0; k < order; k++)
  203. {
  204. my_a[perm_vector[j]][k] -= multiplier *
  205. pivot_row_elements[k];
  206. flops += 2;
  207. }
  208.  
  209. my_b[perm_vector[j]] -= multiplier * b_pivot;
  210. flops += 2;
  211. }
  212. }
  213. }
  214.  
  215. /* Twra exoume ena anw trigwniko systhma. Mporoume na to lysoume me pros ta pisw antikatastash */
  216.  
  217. /* Desmeysh xwrou kai arxikopoihsh me false kathe stoixeio tou pinaka pou deixnei poies times x exoume. */
  218. have_x = (int *) malloc(sizeof(int) * order);
  219. if (have_x == NULL) AKYRO;
  220.  
  221. for (i = 0; i < order; i++)
  222. have_x[i] = 0;
  223.  
  224. /* Desmeysh xwrou gia th domh dedomenwn pou deixnei se poia processes steilame mia ypologismenh timh x. */
  225. sent_yet = (int *) malloc(sizeof(int) * num_processes);
  226. if (sent_yet == NULL) AKYRO;
  227.  
  228. /* Desmeysh xwrou gia ton pinaka timwn tou x. */
  229. computed_x = (double *) malloc(sizeof(double) * order);
  230. if (computed_x == NULL) AKYRO;
  231.  
  232. /* Pros ta pisw antikatastash. */
  233. for (i = order - 1; i >= 0; i--) /* Grammes */
  234. {
  235. if (rp_map[perm_vector[i]] == my_rank)
  236. {
  237. total = 0.0;
  238.  
  239. for (j = i + 1; j < order; j++) /* times X */
  240. {
  241. if (!have_x[j])
  242. {
  243. MPI_Recv(&computed_x[j], 1, MPI_DOUBLE,
  244. rp_map[perm_vector[j]], j,
  245. MPI_COMM_WORLD, &status);
  246. have_x[j] = 1;
  247. }
  248.  
  249. total += computed_x[j] * my_a[perm_vector[i]][j];
  250. flops += 2;
  251. }
  252. if(isnan((my_b[perm_vector[i]] - total) / my_a[perm_vector[i]][i]) != 1)
  253. {
  254. computed_x[i] = (my_b[perm_vector[i]] - total) / my_a[perm_vector[i]][i];
  255. flops++;
  256. have_x[i] = 1;
  257. }
  258. /* Apostolh ayths ths timhs sta alla processors. */
  259. for (j = 0; j < num_processes; j++)
  260. sent_yet[j] = 0;
  261.  
  262. for (j = i - 1; j >= 0; j--) /* Grammes */
  263. {
  264. if (rp_map[perm_vector[j]] != my_rank)
  265. {
  266. if (!sent_yet[rp_map[perm_vector[j]]])
  267. {
  268. MPI_Send(&computed_x[i], 1, MPI_DOUBLE,
  269. rp_map[perm_vector[j]], i,
  270. MPI_COMM_WORLD);
  271. sent_yet[rp_map[perm_vector[j]]] = 1;
  272. }
  273. }
  274. }
  275. }
  276. }
  277.  
  278. /* Eggrafh twn ypologismenwn timwn tou x sto disko */
  279. if (rp_map[perm_vector[0]] == my_rank)
  280. {
  281. result_file = fopen("result.txt", "w");
  282. fprintf(result_file, "Dianysma lyshs:\n\n");
  283.  
  284. for (i = 0; i < order; i++)
  285. {
  286. fprintf(result_file, "%f\n", computed_x[i]);
  287. }
  288.  
  289. fclose(result_file);
  290. }
  291.  
  292. /* Ektypwsh tou arithmou twn floating point leitoyrgiwn pou ektelese ayti i leitoyrgia. */
  293. printf("H diadikasia %d ektelese %d floating point leitourgies.\n",
  294. my_rank, flops);
  295.  
  296. /* Termatismos MPI. */
  297. MPI_Finalize();
  298. }
  299.  
  300. /* Synarthsh se periptwsh lathous kai eksodou. */
  301. void Lathos (int line)
  302. {
  303. printf("Lathos sthn grammh %d\n", line);
  304. exit(1);
  305. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement