ludep.c
上传用户:hhyinxing
上传日期:2013-09-10
资源大小:833k
文件大小:5k
源码类别:

并行计算

开发平台:

Unix_Linux

  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("%sn",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.     }
  53.     /*0号进程将M广播给所有进程*/
  54.     MPI_Bcast(&M,1,MPI_INT,0,MPI_COMM_WORLD);
  55.     m=M/p;
  56.     if (M%p!=0) m++;
  57.     /*分配至各进程的子矩阵大小为m*M*/
  58.     a=(float*)malloc(floatsize*m*M);
  59.     /*各进程为主行元素建立发送和接收缓冲区*/
  60.     f=(float*)malloc(floatsize*M);
  61.     /*0号进程为l和u矩阵分配内存,以分离出经过变换后的A矩阵中的l和u矩阵*/
  62.     if (my_rank==0)
  63.     {
  64.         l=(float*)malloc(floatsize*M*M);
  65.         u=(float*)malloc(floatsize*M*M);
  66.     }
  67.     /*0号进程采用行交叉划分将矩阵A划分为大小m*M的p块子矩阵,依次发送给1至p-1号进程*/
  68.     if (a==NULL) fatal("allocate errorn");
  69.     if (my_rank==0)
  70.     {
  71.         for(i=0;i<m;i++)
  72.             for(j=0;j<M;j++)
  73.                 a(i,j)=A((i*p),j);
  74.         for(i=0;i<M;i++)
  75.             if ((i%p)!=0)
  76.         {
  77.             i1=i%p;
  78.             i2=i/p+1;
  79.             MPI_Send(&A(i,0),M,MPI_FLOAT,i1,i2,MPI_COMM_WORLD);
  80.         }
  81.     }
  82.     else
  83.     {
  84.         for(i=0;i<m;i++)
  85.             MPI_Recv(&a(i,0),M,MPI_FLOAT,0,i+1,MPI_COMM_WORLD,&status);
  86.     }
  87.     for(i=0;i<m;i++)
  88.         for(j=0;j<p;j++)
  89.     {
  90.         /*j号进程负责广播主行元素*/
  91.         if (my_rank==j)
  92.         {
  93.             v=i*p+j;
  94.             for (k=v;k<M;k++)
  95.                 f[k]=a(i,k);
  96.             MPI_Bcast(f,M,MPI_FLOAT,my_rank,MPI_COMM_WORLD);
  97.         }
  98.         else
  99.         {
  100.             v=i*p+j;
  101.             MPI_Bcast(f,M,MPI_FLOAT,j,MPI_COMM_WORLD);
  102.         }
  103.         /*编号小于my_rank的进程(包括my_rank本身)利用主行对其第i+1,…,m-1行数据做行变换*/
  104.         if (my_rank<=j)
  105.             for(k=i+1;k<m;k++)
  106.         {
  107.             a(k,v)=a(k,v)/f[v];
  108.             for(w=v+1;w<M;w++)
  109.                 a(k,w)=a(k,w)-f[w]*a(k,v);
  110.         }
  111.         /*编号大于my_rank的进程利用主行对其第i,…,m-1行数据做行变换*/
  112.         if (my_rank>j)
  113.             for(k=i;k<m;k++)
  114.         {
  115.             a(k,v)=a(k,v)/f[v];
  116.             for(w=v+1;w<M;w++)
  117.                 a(k,w)=a(k,w)-f[w]*a(k,v);
  118.         }
  119.     }
  120.     /*0号进程从其余各进程中接收子矩阵a,得到经过变换的矩阵A*/
  121.     if (my_rank==0)
  122.     {
  123.         for(i=0;i<m;i++)
  124.             for(j=0;j<M;j++)
  125.                 A(i*p,j)=a(i,j);
  126.     }
  127.     if (my_rank!=0)
  128.     {
  129.         for(i=0;i<m;i++)
  130.             MPI_Send(&a(i,0),M,MPI_FLOAT,0,i,MPI_COMM_WORLD);
  131.     }
  132.     else
  133.     {
  134.         for(i=1;i<p;i++)
  135.             for(j=0;j<m;j++)
  136.         {
  137.             MPI_Recv(&a(j,0),M,MPI_FLOAT,i,j,MPI_COMM_WORLD,&status);
  138.             for(k=0;k<M;k++)
  139.                 A((j*p+i),k)=a(j,k);
  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("%dt %dn",M, N);
  161.         for(i=0;i<M;i++)
  162.         {
  163.             for(j=0;j<N;j++)
  164.                 printf("%ft",A(i,j));
  165.             printf("n");
  166.         }
  167.         printf("nOutput of LU operationn");
  168.         printf("Matrix L:n");
  169.         for(i=0;i<M;i++)
  170.         {
  171.             for(j=0;j<M;j++)
  172.                 printf("%ft",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("%ft",u(i,j));
  180.             printf("n");
  181.         }
  182.     }
  183.     MPI_Finalize();
  184.     Environment_Finalize(a,f);
  185.     return(0);
  186. }