Advertisement
Guest User

Untitled

a guest
Nov 23rd, 2014
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.16 KB | None | 0 0
  1. #include <mpi.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <math.h>
  6. #include <iostream>
  7. using namespace std;
  8.  
  9. void ThomasAlgorithm_P(int mynode, int numnodes,
  10. int N, double *b, double *a, double *c, double *x, double *q){
  11. int i;
  12. int rows_local,local_offset;
  13. double S[2][2],T[2][2],s1tmp,s2tmp;
  14. double *l,*d,*y;
  15. MPI_Status status;
  16.  
  17. l = (double*)malloc(sizeof(double) * N);
  18. d = (double*)malloc(sizeof(double) * N);
  19. y = (double*)malloc(sizeof(double) * N);
  20.  
  21. for(i=0;i<N;i++)
  22. l[i] = d[i] = y[i] = 0.0;
  23.  
  24. S[0][0] = S[1][1] = 1.0;
  25. S[1][0] = S[0][1] = 0.0;
  26.  
  27. rows_local = (int) floor((double)N/numnodes);
  28. local_offset = mynode*rows_local;
  29.  
  30. if(mynode==0){
  31. s1tmp = a[local_offset]*S[0][0];
  32. S[1][0] = S[0][0];
  33. S[1][1] = S[0][1];
  34. S[0][1] = a[local_offset]*S[0][1];
  35. S[0][0] = s1tmp;
  36. for(i=1;i<rows_local;i++){
  37. s1tmp = a[i+local_offset]*S[0][0] - b[i+local_offset-1]*c[i+local_offset-1]*S[1][0];
  38. s2tmp = a[i+local_offset]*S[0][1] - b[i+local_offset-1]*c[i+local_offset-1]*S[1][1];
  39. S[1][0] = S[0][0];
  40. S[1][1] = S[0][1];
  41. S[0][0] = s1tmp;
  42. S[0][1] = s2tmp;
  43. }
  44. }
  45. else{
  46. for(i=0;i<rows_local;i++){
  47. s1tmp = a[i+local_offset]*S[0][0] - b[i+local_offset-1]*c[i+local_offset-1]*S[1][0];
  48. s2tmp = a[i+local_offset]*S[0][1] - b[i+local_offset-1]*c[i+local_offset-1]*S[1][1];
  49. S[1][0] = S[0][0];
  50. S[1][1] = S[0][1];
  51. S[0][0] = s1tmp;
  52. S[0][1] = s2tmp;
  53. }
  54. }
  55.  
  56. for(i=0; i<=log2(numnodes);i++){
  57. if((mynode+pow(2.0,i)) < numnodes){
  58. MPI_Send(S,4,MPI_DOUBLE,int(mynode+pow(2.0,i)),0,MPI_COMM_WORLD);
  59. }
  60. if(mynode-pow(2.0,i)>=0){
  61. MPI_Recv(T,4,MPI_DOUBLE,int(mynode-pow(2.0,i)),0,MPI_COMM_WORLD,&status);
  62. s1tmp = S[0][0]*T[0][0] + S[0][1]*T[1][0];
  63. S[0][1] = S[0][0]*T[0][1] + S[0][1]*T[1][1];
  64. S[0][0] = s1tmp;
  65. s1tmp = S[1][0]*T[0][0] + S[1][1]*T[1][0];
  66. S[1][1] = S[1][0]*T[0][1] + S[1][1]*T[1][1];
  67. S[1][0] = s1tmp;
  68. }
  69. }
  70.  
  71. d[local_offset+rows_local-1] = (S[0][0] + S[0][1])/(S[1][0] + S[1][1]);
  72.  
  73. if(mynode == 0){
  74. MPI_Send(&d[local_offset+rows_local-1],1,MPI_DOUBLE,1,0,MPI_COMM_WORLD);
  75. }
  76. else{
  77. MPI_Recv(&d[local_offset-1],1,MPI_DOUBLE,mynode-1,0,MPI_COMM_WORLD,&status);
  78. if(mynode != numnodes-1)
  79. MPI_Send(&d[local_offset+rows_local-1],1,MPI_DOUBLE,mynode+1,0,MPI_COMM_WORLD);
  80. }
  81.  
  82.  
  83. if(mynode == 0){
  84. l[0] = 0;
  85. d[0] = a[0];
  86. for(i=1;i<rows_local-1;i++){
  87. l[local_offset+i] = b[local_offset+i-1]/d[local_offset+i-1];
  88. d[local_offset+i] = a[local_offset+i] - l[local_offset+i]*c[local_offset+i-1];
  89. }
  90. l[local_offset+rows_local-1] = b[local_offset+rows_local-2]/d[local_offset+rows_local-2];
  91. }
  92. else{
  93. for(i=0;i<rows_local-1;i++){
  94. l[local_offset+i] = b[local_offset+i-1]/d[local_offset+i-1];
  95. d[local_offset+i] = a[local_offset+i] - l[local_offset+i]*c[local_offset+i-1];
  96. }
  97. l[local_offset+rows_local-1] = b[local_offset+rows_local-2]/d[local_offset+rows_local-2];
  98. }
  99.  
  100. /***********************************************************************************/
  101.  
  102. if(mynode>0)
  103. d[local_offset-1] = 0;
  104.  
  105. double * tmp = new double[N];
  106. for(i=0;i<N;i++)
  107. tmp[i] = d[i];
  108. MPI_Allreduce(tmp,d,N,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD);
  109. for(i=0;i<N;i++)
  110. tmp[i] = l[i];
  111. MPI_Allreduce(tmp,l,N,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD);
  112. delete[] tmp;
  113.  
  114. if(mynode ==0){
  115. /* Forward Substitution [L][y] = [q] */
  116. y[0] = q[0];
  117. for(i=1;i<N;i++)
  118. y[i] = q[i] - l[i]*y[i-1];
  119.  
  120. /* Backward Substitution [U][x] = [y] */
  121. x[N-1] = y[N-1]/d[N-1];
  122. for(i=N-2;i>=0;i--)
  123. x[i] = (y[i] - c[i]*x[i+1])/d[i];
  124.  
  125. }
  126.  
  127. if(mynode ==0){
  128. for(i=0;i<40;i++){
  129. cout << x[i];
  130. cout << endl;
  131. }
  132. }
  133.  
  134.  
  135. free(l);
  136. free(y);
  137. free(d);
  138. return;
  139. }
  140.  
  141. int main(int argc,char *argv[])
  142. {
  143. int numnodes, mynode, sendcount, recvcount, source;
  144. int N,i;
  145. double b[] = {0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048};
  146. double c[] = {0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048,0.048};
  147. double a[] = {-1.096,-1.096,-1.096,-1.096,-1.096,-1.096,-1.096,-1.096,-1.096,-1.096,-1.096,-1.096,-1.096,-1.096,-1.096,-1.096,-1.096,-1.096,-1.096};
  148. double q[] = {-0.206311,-0.408774,-0.603633,-0.787322,-0.95655,-1.10838,-1.2403,-1.35031,-1.43691,-1.49921,-1.53691,-1.55031,-1.5403,-1.50838,-1.45655,-1.38732,-1.30363,-1.20877,-1.15431};
  149. double x[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  150.  
  151. MPI_Init(&argc,&argv);
  152. MPI_Comm_rank(MPI_COMM_WORLD, &mynode);
  153. MPI_Comm_size(MPI_COMM_WORLD, &numnodes);
  154.  
  155. N = 19;
  156.  
  157. ThomasAlgorithm_P(mynode,numnodes,N,b,a,c,x,q);
  158.  
  159. MPI_Finalize();
  160. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement