Advertisement
Guest User

Untitled

a guest
Oct 31st, 2014
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.67 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include <string.h>
  5. #include <mpi.h>
  6.  
  7. #define M 700
  8.  
  9. int numtasks, rank, inext, iprev, ista, iend;
  10.  
  11. double unew[M + 2][M + 2] = {{ 0 }};
  12. double solution[M + 2][M + 2] = {{ 0 }};
  13.  
  14. double uold[M + 2][M + 2] = {{ 0 }};
  15.  
  16. double bufs1[M + 2];
  17. double bufs2[M + 2];
  18.  
  19. double bufr1[M + 2];
  20. double bufr2[M + 2];
  21.  
  22. MPI_Request ireqs1;
  23. MPI_Request ireqs2;
  24.  
  25. MPI_Request ireqr1;
  26. MPI_Request ireqr2;
  27.  
  28. MPI_Status istatus;
  29.  
  30. double compute_error(double solution[][M + 2], double u[][M + 2], const int m);
  31. int sor(double unew[][M + 2], double uold[][M + 2], double solution[][M + 2], const double omega, const double tol, const int m);
  32. void para_range(const int n1, const int n2, const int nprocs, const int irank, int * restrict ista, int * restrict iend);
  33. void shift(const int iflg);
  34. inline int min(const int a, const int b);
  35.  
  36. int main(int argc, char * argv[])
  37. {
  38. const int m = M;
  39.  
  40. int ierr = MPI_Init(&argc, &argv);
  41.  
  42. if(ierr != MPI_SUCCESS)
  43. {
  44. perror("MPI init failed. Terminating T800.n");
  45. exit(1);
  46. }
  47.  
  48. int i, j;
  49.  
  50. const double begin = MPI_Wtime();
  51.  
  52. const double pi = 4.0 * atan(1.0);
  53.  
  54. const double h = pi / (m + 1);
  55.  
  56. MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
  57. MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  58.  
  59. for(i = 0; i < m + 2; ++i)
  60. {
  61. uold[i][M + 1] = sin(i * h);
  62. }
  63.  
  64. for(i = 0; i < m + 2; ++i)
  65. {
  66. for(j = 0; j < m + 1; ++j)
  67. {
  68. uold[i][j] = j * h * uold[i][M + 1];
  69. }
  70. }
  71.  
  72. for(i = 0; i < m + 2; ++i)
  73. {
  74. for(j = 0; j < m + 2; ++j)
  75. {
  76. solution[i][j] = sinh(j * h) * sin(i * h) / sinh(pi);
  77. }
  78. }
  79.  
  80. para_range(0, m, numtasks, rank, &ista, &iend);
  81.  
  82. //printf("rank %d: from %d to %dn", rank, ista, iend);
  83.  
  84. inext = rank + 1;
  85. iprev = rank - 1;
  86.  
  87. if(inext == numtasks)
  88. {
  89. inext = MPI_PROC_NULL;
  90. }
  91.  
  92. if(iprev == -1)
  93. {
  94. iprev = MPI_PROC_NULL;
  95. }
  96.  
  97. const double omega = 2.0 / ( 1.0 + sin(pi / (m + 1)) );
  98. const double tol = 0.001;
  99.  
  100. const int iters = sor(unew, uold, solution, omega, tol, m);
  101.  
  102. const double end = MPI_Wtime();
  103.  
  104. MPI_Finalize();
  105.  
  106. if(rank == 0)
  107. {
  108. printf(" n");
  109. printf(" Omega = %fn", omega);
  110. printf(" It took %d iterations.n", iters);
  111.  
  112. printf("Total time = %fnnn", end - begin);
  113. }
  114.  
  115. return 0;
  116. }
  117.  
  118. double compute_error(double solution[][M + 2], double u[][M + 2], const int m)
  119. {
  120. double error = 0.0;
  121. int i, j;
  122.  
  123. for(i = 1; i < m + 1; ++i)
  124. {
  125. for(j = 1; j < m + 1; ++j)
  126. {
  127. const double abs_diff = fabs(solution[i][j] - u[i][j]);
  128.  
  129. if(error < abs_diff)
  130. {
  131. error = abs_diff;
  132. }
  133. }
  134. }
  135.  
  136. return error;
  137. }
  138.  
  139. int sor(double unew[][M + 2], double uold[][M + 2], double solution[][M + 2], const double omega, const double tol, const int m)
  140. {
  141. int i, j;
  142.  
  143. int iters = 0;
  144. double error = compute_error(solution, uold, m);
  145. double error2 = error;
  146. double temp;
  147.  
  148. while(error2 > tol)
  149. {
  150. shift(0);
  151.  
  152. for(i = 1; i < m + 1; ++i)
  153. {
  154. for(j = (i % 2) + 1; j < m + 1; j += 2)
  155. {
  156. temp = 0.25 * (uold[i][j - 1] + uold[i - 1][j]
  157. + uold[i + 1][j] + uold[i][j + 1]) - uold[i][j];
  158. uold[i][j] += omega * temp;
  159. }
  160. }
  161.  
  162. shift(1);
  163.  
  164. for(i = 1; i < m + 1; ++i)
  165. {
  166. for(j = ((i + 1) % 2) + 1; j < m + 1; j += 2)
  167. {
  168. temp = 0.25 * (uold[i][j - 1] + uold[i - 1][j]
  169. + uold[i + 1][j] + uold[i][j + 1]) - uold[i][j];
  170. uold[i][j] += omega * temp;
  171. }
  172. }
  173.  
  174. ++iters;
  175.  
  176. if(iters % 20 == 0)
  177. {
  178. // THIS IS NOT COOL
  179. error = compute_error(solution, uold, m);
  180. MPI_Allreduce(&error, &error2, 1, MPI_REAL, MPI_MAX, MPI_COMM_WORLD);
  181.  
  182. //printf("%d=%fn", rank, error2);
  183. }
  184. }
  185.  
  186. return iters;
  187. }
  188.  
  189. void para_range(const int n1, const int n2, const int nprocs, const int irank, int * restrict ista, int * restrict iend)
  190. {
  191. const int iwork = ((n2 - n1) / nprocs) + 1;
  192.  
  193. *ista = min(irank * iwork + n1, n2 + 1);
  194. *iend = min(*ista + iwork - 1, n2);
  195. }
  196.  
  197. void shift(const int iflg)
  198. {
  199. const int is1 = ((ista + iflg) % 2) + 1;
  200. const int is2 = ((iend + iflg) % 2) + 1;
  201.  
  202. const int ir1 = 3 - is1;
  203. const int ir2 = 3 - is2;
  204.  
  205. int i, icnt1=0, icnt2=0;
  206.  
  207. if(rank != 0)
  208. {
  209. icnt1 = 0;
  210.  
  211. for(i = is1; i < M; i += 2)
  212. {
  213. ++icnt1;
  214. bufs1[icnt1] = unew[i][ista];
  215. }
  216. }
  217.  
  218. if (rank != numtasks - 1)
  219. {
  220. icnt2 = 0;
  221.  
  222. for(i = is2; i < M; i += 2)
  223. {
  224. ++icnt2;
  225. bufs2[icnt2] = unew[i][iend];
  226. }
  227. }
  228.  
  229. MPI_Isend(bufs1, icnt1, MPI_REAL, iprev, 1, MPI_COMM_WORLD, &ireqs1);
  230. MPI_Isend(bufs2, icnt2, MPI_REAL, inext, 1, MPI_COMM_WORLD, &ireqs2);
  231.  
  232. MPI_Irecv(bufr1, M + 2, MPI_REAL, iprev, 1, MPI_COMM_WORLD, &ireqr1);
  233. MPI_Irecv(bufr2, M + 2, MPI_REAL, inext, 1, MPI_COMM_WORLD, &ireqr2);
  234.  
  235. MPI_Wait(&ireqs1, &istatus);
  236. MPI_Wait(&ireqs2, &istatus);
  237.  
  238. MPI_Wait(&ireqr1, &istatus);
  239. MPI_Wait(&ireqr2, &istatus);
  240.  
  241. int icnt;
  242.  
  243. if(rank != 0)
  244. {
  245. icnt = 0;
  246.  
  247. for(i = ir1; i < M; i += 2)
  248. {
  249. ++icnt;
  250. unew[i][ista - 1] = bufr1[icnt];
  251. }
  252. }
  253.  
  254. if(rank != numtasks - 1)
  255. {
  256. icnt = 0;
  257.  
  258. for(i = ir2; i < M; i += 2)
  259. {
  260. ++icnt;
  261. unew[i][iend + 1] = bufr2[icnt];
  262. }
  263. }
  264. }
  265.  
  266. inline int min(const int a, const int b)
  267. {
  268. if(a > b)
  269. {
  270. return b;
  271. }
  272.  
  273. return a;
  274. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement