ludep.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #include "stdio.h"
  2. #include "stdlib.h"
  3. #include "mpi.h"
  4. #define a(x,y) a[x*M+y]
  5. /*A为M*M矩阵*/
  6. #define A(x,y) A[x*M+y]
  7. #define l(x,y) l[x*M+y]
  8. #define u(x,y) u[x*M+y]
  9. #define floatsize sizeof(float)
  10. #define intsize sizeof(int)
  11. int M,N;
  12. int m;
  13. float *A;
  14. int my_rank;
  15. int p;
  16. MPI_Status status;
  17. void fatal(char *message)
  18. {
  19. printf("%s\n",message);
  20. exit(1);
  21. }
  22. void Environment_Finalize(float *a,float *f)
  23. {
  24. free(a);
  25. free(f);
  26. }
  27. int main(int argc, char **argv)
  28. {
  29. int i,j,k,my_rank,group_size;
  30. int i1,i2;
  31. int v,w;
  32. float *a,*f,*l,*u;
  33. FILE *fdA;
  34. MPI_Init(&argc,&argv);
  35. MPI_Comm_size(MPI_COMM_WORLD,&group_size);
  36. MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
  37. p=group_size;
  38. if (my_rank==0)
  39. {
  40. fdA=fopen("dataIn.txt","r");
  41. fscanf(fdA,"%d %d", &M, &N);
  42. if(M != N)
  43. {
  44. puts("The input is error!");
  45. exit(0);
  46. }
  47. A=(float *)malloc(floatsize*M*M);
  48. for(i = 0; i < M; i ++)
  49. for(j = 0; j < M; j ++)
  50. fscanf(fdA, "%f", A+i*M+j);
  51. fclose(fdA);
  52. printf("Input of file \"dataIn.txt\"\n");
  53. printf("%d\t %d\n",M, N);
  54. for(i=0;i<M;i++)
  55. {
  56. for(j=0;j<N;j++)
  57. printf("%f\t",A(i,j));
  58. printf("\n");
  59. }
  60. }
  61. /*0号进程将M广播给所有进程*/
  62. MPI_Bcast(&M,1,MPI_INT,0,MPI_COMM_WORLD);
  63. m=M/p;
  64. if (M%p!=0) m++;
  65. /*分配至各进程的子矩阵大小为m*M*/
  66. a=(float*)malloc(floatsize*m*M);
  67. /*各进程为主行元素建立发送和接收缓冲区*/
  68. f=(float*)malloc(floatsize*M);
  69. /*0号进程为l和u矩阵分配内存,以分离出经过变换后的A矩阵中的l和u矩阵*/
  70. if (my_rank==0)
  71. {
  72. l=(float*)malloc(floatsize*M*M);
  73. u=(float*)malloc(floatsize*M*M);
  74. }
  75. /*0号进程采用行连续划分将矩阵A划分为大小m*M的p块子矩阵,依次发送给1至p-1号进程*/
  76. if (a==NULL) fatal("allocate error\n");
  77. if (my_rank==0)
  78. {
  79. for(i=0;i<m;i++)
  80. for(j=0;j<M;j++)
  81. a(i,j)=A(i,j);
  82. for(i=1;i<p;i++)
  83. {
  84. MPI_Send(&A(i*m,0),m*M,MPI_FLOAT,i,i,MPI_COMM_WORLD);
  85. }
  86. }
  87. else
  88. {
  89. MPI_Recv(&a(0,0),m*M,MPI_FLOAT,0,my_rank,MPI_COMM_WORLD,&status);
  90. }
  91. for(j=0;j<p;j++)
  92. for(i=0;i<m;i++)
  93. {
  94. /*j号进程负责广播主行元素*/
  95. if (my_rank==j)
  96. {
  97. v=j*m+i;
  98. for (k=v;k<M;k++)
  99. f[k]=a(i,k);
  100. MPI_Bcast(f,M,MPI_FLOAT,my_rank,MPI_COMM_WORLD);
  101. }
  102. else
  103. {
  104. v=j*m+i;
  105. MPI_Bcast(f,M,MPI_FLOAT,j,MPI_COMM_WORLD);
  106. }
  107. /*编号等于my_rank的进程(包括my_rank本身)利用主行对其第i+1,…,m-1行数据做行变换*/
  108. if (my_rank==j)
  109. for(k=i+1;k<m;k++)
  110. {
  111. a(k,v)=a(k,v)/f[v];
  112. for(w=v+1;w<M;w++)
  113. a(k,w)=a(k,w)-f[w]*a(k,v);
  114. }
  115. /*编号大于my_rank的进程利用主行对其第0,i,…,m-1行数据做行变换*/
  116. if (my_rank>j)
  117. for(k=0;k<m;k++)
  118. {
  119. a(k,v)=a(k,v)/f[v];
  120. for(w=v+1;w<M;w++)
  121. a(k,w)=a(k,w)-f[w]*a(k,v);
  122. }
  123. }
  124. /*0号进程从其余各进程中接收子矩阵a,得到经过变换的矩阵A*/
  125. if (my_rank==0)
  126. {
  127. for(i=0;i<m;i++)
  128. for(j=0;j<M;j++)
  129. A(i,j)=a(i,j);
  130. }
  131. if (my_rank!=0)
  132. {
  133. MPI_Send(&a(0,0),m*M,MPI_FLOAT,0,my_rank,MPI_COMM_WORLD);
  134. }
  135. else
  136. {
  137. for(i=1;i<p;i++)
  138. {
  139. MPI_Recv(&A(i*m,0),m*M,MPI_FLOAT,i,i,MPI_COMM_WORLD,&status);
  140. }
  141. }
  142. if (my_rank==0)
  143. {
  144. for(i=0;i<M;i++)
  145. for(j=0;j<M;j++)
  146. u(i,j)=0.0;
  147. for(i=0;i<M;i++)
  148. for(j=0;j<M;j++)
  149. if (i==j)
  150. l(i,j)=1.0;
  151. else
  152. l(i,j)=0.0;
  153. for(i=0;i<M;i++)
  154. for(j=0;j<M;j++)
  155. if (i>j)
  156. l(i,j)=A(i,j);
  157. else
  158. u(i,j)=A(i,j);
  159. //printf("Input of file \"dataIn.txt\"\n");
  160. //printf("%d\t %d\n",M, N);
  161. //for(i=0;i<M;i++)
  162. //{
  163. // for(j=0;j<N;j++)
  164. // printf("%f\t",A(i,j));
  165. // printf("\n");
  166. //}
  167. printf("\nOutput of LU operation\n");
  168. printf("Matrix L:\n");
  169. for(i=0;i<M;i++)
  170. {
  171. for(j=0;j<M;j++)
  172. printf("%f\t",l(i,j));
  173. printf("\n");
  174. }
  175. printf("Matrix U:\n");
  176. for(i=0;i<M;i++)
  177. {
  178. for(j=0;j<M;j++)
  179. printf("%f\t",u(i,j));
  180. printf("\n");
  181. }
  182. }
  183. MPI_Finalize();
  184. Environment_Finalize(a,f);
  185. return(0);
  186. }