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

并行计算

开发平台:

Unix_Linux

  1. #include "stdio.h"
  2. #include "stdlib.h"
  3. #include "math.h"
  4. #include "mpi.h"
  5. #define a(x,y) a[x*M+y]
  6. #define q(x,y) q[x*M+y]
  7. #define A(x,y) A[x*M+y]
  8. #define Q(x,y) Q[x*M+y]
  9. #define R(x,y) R[x*M+y]
  10. float temp;
  11. float *A;
  12. float *R;
  13. float *Q;
  14. double starttime;
  15. double time1;
  16. double time2;
  17. int p;
  18. MPI_Status status;
  19. void Environment_Finalize(float *a,float *q,float *v,float *f,float *R,
  20.                           float *Q,float *ai,float *aj,float *qi,float *qj)
  21. {
  22.     free(a);
  23.     free(q);
  24.     free(v);
  25.     free(f);
  26.     free(R);
  27.     free(Q);
  28.     free(ai);
  29.     free(aj);
  30.     free(qi);
  31.     free(qj);
  32. }
  33. int main(int argc, char **argv)
  34. {
  35.     int M,N,m;
  36.     int z;
  37.     int i,j,k,my_rank,group_size;
  38.     float *ai,*qi,*aj,*qj;
  39.     float c,s,sp;
  40.     float *f,*v;
  41.     float *a,*q;
  42.     FILE *fdA;
  43.     MPI_Init(&argc,&argv);
  44.     MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
  45.     MPI_Comm_size(MPI_COMM_WORLD,&group_size);
  46.     p=group_size;
  47.     starttime=MPI_Wtime();
  48.     if(my_rank==p-1)
  49.     {
  50.         fdA=fopen("dataIn.txt","r");
  51.         fscanf(fdA,"%d %d", &M, &N);
  52.         if(M != N)
  53.         {
  54.             puts("The input is error!");
  55.             exit(0);
  56.         }
  57.         A=(float*)malloc(sizeof(float)*M*M);
  58.         Q=(float*)malloc(sizeof(float)*M*M);
  59.         R=(float*)malloc(sizeof(float)*M*M);
  60.         for(i = 0; i < M; i ++)
  61.         {
  62.             for(j = 0; j < M; j ++) fscanf(fdA, "%f", A+i*M+j);
  63.         }
  64.         fclose(fdA);
  65.         for(i=0;i<M;i++)
  66.             for(j=0;j<M;j++)
  67.                 if (i==j)
  68.                     Q(i,j)=1.0;
  69.         else
  70.             Q(i,j)=0.0;
  71.     }
  72.     MPI_Bcast(&M,1,MPI_INT,p-1,MPI_COMM_WORLD);
  73.     m=M/p;
  74.     if (M%p!=0) m++;
  75.     qi=(float*)malloc(sizeof(float)*M);
  76.     qj=(float*)malloc(sizeof(float)*M);
  77.     aj=(float*)malloc(sizeof(float)*M);
  78.     ai=(float*)malloc(sizeof(float)*M);
  79.     v=(float*)malloc(sizeof(float)*M);
  80.     f=(float*)malloc(sizeof(float)*M);
  81.     a=(float*)malloc(sizeof(float)*m*M);
  82.     q=(float*)malloc(sizeof(float)*m*M);
  83.     if (a==NULL||q==NULL||f==NULL||v==NULL||qi==NULL||qj==NULL||ai==NULL||aj==NULL)
  84.         printf("memory allocation is wrongn");
  85.     if (my_rank==p-1)
  86.     {
  87.         for(i=0;i<m;i++)
  88.             for(j=0;j<M;j++)
  89.         {
  90.             a(i,j)=A((my_rank*m+i),j);
  91.             q(i,j)=Q((my_rank*m+i),j);
  92.         }
  93.     }
  94.     if (my_rank==p-1)
  95.     {
  96.         for(i=0;i<p-1;i++)
  97.         {
  98.             MPI_Send(&A(m*i,0),m*M,MPI_FLOAT,i,i,MPI_COMM_WORLD);
  99.             MPI_Send(&Q(m*i,0),m*M,MPI_FLOAT,i,i,MPI_COMM_WORLD);
  100.         }
  101.         free(A);
  102.     }
  103.     else
  104.     {
  105.         MPI_Recv(a,m*M,MPI_FLOAT,p-1,my_rank,MPI_COMM_WORLD,&status);
  106.         MPI_Recv(q,m*M,MPI_FLOAT,p-1,my_rank,MPI_COMM_WORLD,&status);
  107.     }
  108.     time1=MPI_Wtime();
  109.     if (p>1)
  110.     {
  111.         if (my_rank==0)
  112.         {
  113.             for(j=0;j<m-1;j++)
  114.             {
  115.                 for(i=j+1;i<m;i++)
  116.                 {
  117.                     sp=sqrt(a(j,j)*a(j,j)+a(i,j)*a(i,j));
  118.                     c=a(j,j)/sp;  s=a(i,j)/sp;
  119.                     for(k=0;k<M;k++)
  120.                     {
  121.                         aj[k]=c*a(j,k)+s*a(i,k);
  122.                         qj[k]=c*q(j,k)+s*q(i,k);
  123.                         ai[k]=-s*a(j,k)+c*a(i,k);
  124.                         qi[k]=-s*q(j,k)+c*q(i,k);
  125.                     }
  126.                     for(k=0;k<M;k++)
  127.                     {
  128.                         a(j,k)=aj[k];
  129.                         q(j,k)=qj[k];
  130.                         a(i,k)=ai[k];
  131.                         q(i,k)=qi[k];
  132.                     }
  133.                 }                                 /*  i */
  134.                 for(k=0;k<M;k++)
  135.                 {
  136.                     f[k]=a(j,k);
  137.                     v[k]=q(j,k);
  138.                 }
  139.                 MPI_Send(&f[0],M,MPI_FLOAT,1,j,MPI_COMM_WORLD);
  140.                 MPI_Send(&v[0],M,MPI_FLOAT,1,j,MPI_COMM_WORLD);
  141.             }                                     /* for j */
  142.             for(k=0;k<M;k++)
  143.             {
  144.                 f[k]=a((m-1),k);
  145.                 v[k]=q((m-1),k);
  146.             }
  147.             MPI_Send(&f[0],M,MPI_FLOAT,1,m-1,MPI_COMM_WORLD);
  148.             MPI_Send(&v[0],M,MPI_FLOAT,1,m-1,MPI_COMM_WORLD);
  149.         }                                         /* my_rank==0 */
  150.         else                                      /* my_rank!=0 */
  151.         {
  152.             if (my_rank!=(group_size-1))
  153.             {
  154.                 for(j=0;j<my_rank*m;j++)
  155.                 {
  156.                     MPI_Recv(&f[0],M,MPI_FLOAT,(my_rank-1),j,MPI_COMM_WORLD,&status);
  157.                     MPI_Recv(&v[0],M,MPI_FLOAT,(my_rank-1),j,MPI_COMM_WORLD,&status);
  158.                     for(i=0;i<m;i++)
  159.                     {
  160.                         sp=sqrt(f[j]*f[j]+a(i,j)*a(i,j));
  161.                         c=f[j]/sp;  s=a(i,j)/sp;
  162.                         for(k=0;k<M;k++)
  163.                         {
  164.                             aj[k]=c*f[k]+s*a(i,k);
  165.                             qj[k]=c*v[k]+s*q(i,k);
  166.                             ai[k]=-s*f[k]+c*a(i,k);
  167.                             qi[k]=-s*v[k]+c*q(i,k);
  168.                         }
  169.                         for(k=0;k<M;k++)
  170.                         {
  171.                             f[k]=aj[k];
  172.                             v[k]=qj[k];
  173.                             a(i,k)=ai[k];
  174.                             q(i,k)=qi[k];
  175.                         }
  176.                     }
  177.                     MPI_Send(&f[0],M,MPI_FLOAT,(my_rank+1),j,MPI_COMM_WORLD);
  178.                     MPI_Send(&v[0],M,MPI_FLOAT,(my_rank+1),j,MPI_COMM_WORLD);
  179.                 }                                 /* for j */
  180.                 for(j=0;j<m-1;j++)
  181.                 {
  182.                     for(i=j+1;i<m;i++)
  183.                     {
  184.                         sp=sqrt(a(j,(my_rank*m+j))*a(j,(my_rank*m+j))+a(i,(my_rank*m+j))*a(i,(my_rank*m+j)));
  185.                         c=a(j,(my_rank*m+j))/sp;
  186.                         s=a(i,(my_rank*m+j))/sp;
  187.                         for(k=0;k<M;k++)
  188.                         {
  189.                             aj[k]=c*a(j,k)+s*a(i,k);
  190.                             qj[k]=c*q(j,k)+s*q(i,k);
  191.                             ai[k]=-s*a(j,k)+c*a(i,k);
  192.                             qi[k]=-s*q(j,k)+c*q(i,k);
  193.                         }
  194.                         for(k=0;k<M;k++)
  195.                         {
  196.                             a(j,k)=aj[k];
  197.                             q(j,k)=qj[k];
  198.                             a(i,k)=ai[k];
  199.                             q(i,k)=qi[k];
  200.                         }
  201.                     }
  202.                     for(k=0;k<M;k++)
  203.                     {
  204.                         f[k]=a(j,k);
  205.                         v[k]=q(j,k);
  206.                     }
  207.                     MPI_Send(&f[0],M,MPI_FLOAT,my_rank+1,my_rank*m+j,MPI_COMM_WORLD);
  208.                     MPI_Send(&v[0],M,MPI_FLOAT,my_rank+1,my_rank*m+j,MPI_COMM_WORLD);
  209.                 }                                 /* for j */
  210.                 for(k=0;k<M;k++)
  211.                 {
  212.                     f[k]=a((m-1),k);
  213.                     v[k]=q((m-1),k);
  214.                 }
  215.                 MPI_Send(&f[0],M,MPI_FLOAT,my_rank+1,my_rank*m+m-1,MPI_COMM_WORLD);
  216.                 MPI_Send(&v[0],M,MPI_FLOAT,my_rank+1,my_rank*m+m-1,MPI_COMM_WORLD);
  217.             }                                     /* my_rank !=groupsize -1 */
  218.             if (my_rank==(group_size-1))
  219.             {
  220.                 for(j=0;j<my_rank*m;j++)
  221.                 {
  222.                     MPI_Recv(&f[0],M,MPI_FLOAT,(my_rank-1),j,MPI_COMM_WORLD,&status);
  223.                     MPI_Recv(&v[0],M,MPI_FLOAT,(my_rank-1),j,MPI_COMM_WORLD,&status);
  224.                     for(i=0;i<m;i++)
  225.                     {
  226.                         sp=sqrt(f[j]*f[j]+a(i,j)*a(i,j));
  227.                         c=f[j]/sp;  s=a(i,j)/sp;
  228.                         for(k=0;k<M;k++)
  229.                         {
  230.                             aj[k]=c*f[k]+s*a(i,k);
  231.                             qj[k]=c*v[k]+s*q(i,k);
  232.                             ai[k]=-s*f[k]+c*a(i,k);
  233.                             qi[k]=-s*v[k]+c*q(i,k);
  234.                         }
  235.                         for(k=0;k<M;k++)
  236.                         {
  237.                             f[k]=aj[k];
  238.                             v[k]=qj[k];
  239.                             a(i,k)=ai[k];
  240.                             q(i,k)=qi[k];
  241.                         }
  242.                     }                             /* for i */
  243.                     for(k=0;k<M;k++)
  244.                     {
  245.                         Q(j,k)=v[k];
  246.                         R(j,k)=f[k];
  247.                     }
  248.                 }                                 /* for j */
  249.                 for(j=0;j<m-1;j++)
  250.                 {
  251.                     for(i=j+1;i<m;i++)
  252.                     {
  253.                         sp=sqrt(a(j,(my_rank*m+j))*a(j,(my_rank*m+j))+a(i,(my_rank*m+j))*a(i,(my_rank*m+j)));
  254.                         c=a(j,(my_rank*m+j))/sp;
  255.                         s=a(i,(my_rank*m+j))/sp;
  256.                         for(k=0;k<M;k++)
  257.                         {
  258.                             aj[k]=c*a(j,k)+s*a(i,k);
  259.                             qj[k]=c*q(j,k)+s*q(i,k);
  260.                             ai[k]=-s*a(j,k)+c*a(i,k);
  261.                             qi[k]=-s*q(j,k)+c*q(i,k);
  262.                         }
  263.                         for(k=0;k<M;k++)
  264.                         {
  265.                             a(j,k)=aj[k];
  266.                             q(j,k)=qj[k];
  267.                             a(i,k)=ai[k];
  268.                             q(i,k)=qi[k];
  269.                         }
  270.                     }                             /*  for i */
  271.                     for(k=0;k<M;k++)
  272.                     {
  273.                         Q((my_rank*m+j),k)=q(j,k);
  274.                         R((my_rank*m+j),k)=a(j,k);
  275.                     }
  276.                 }                                 /* for j */
  277.                 for(k=0;k<M;k++)
  278.                 {
  279.                     Q((my_rank*m+m-1),k)=q((m-1),k);
  280.                     R((my_rank*m+m-1),k)=a((m-1),k);
  281.                 }
  282.             }                                     /* for my_rank==groupsize -1 */
  283.         }                                         /*    else my_rank!=0           */
  284.     }                                             /*    if p >1          */
  285.     if (p==1)
  286.     {
  287.         for (j=0;j<M;j++)
  288.             for (i=j+1;i<M;i++)
  289.         {
  290.             sp=sqrt(a(j,j)*a(j,j) + a(i,j)*a(i,j));
  291.             c=a(j,j)/sp;
  292.             s=a(i,j)/sp;
  293.             for (k=0;k<M;k++)
  294.             {
  295.                 aj[k]=c*a(j,k) + s*a(i,k);
  296.                 qj[k]=c*q(j,k) + s*q(i,k);
  297.                 ai[k]=(-s)*a(j,k) + c*a(i,k);
  298.                 qi[k]=(-s)*q(j,k) + c*q(i,k);
  299.             }
  300.             for (k=0;k<M;k++)
  301.             {
  302.                 a(j,k)=aj[k];
  303.                 q(j,k)=qj[k];
  304.                 a(i,k)=ai[k];
  305.                 q(i,k)=qi[k];
  306.             }
  307.         }                                         /* for   */
  308.         for(i=0;i<M;i++)
  309.             for(j=0;j<M;j++)
  310.                 R(i,j)=a(i,j);
  311.         for(i=0;i<M;i++)
  312.             for(j=0;j<M;j++)
  313.                 Q(i,j)=q(i,j);
  314.     }                                             /*  if   p==1 */
  315.     if (my_rank==p-1)
  316.     {
  317.         printf("Input of file "dataIn.txt"n");
  318.         printf("%dt %dn",M, N);
  319.         for(i=0;i<M;i++)
  320.         {
  321.             for(j=0;j<N;j++) printf("%ft",A(i,j));
  322.             printf("n");
  323.         }
  324.         printf("nOutput of QR operationn");
  325.         printf("Matrix R:n");
  326.         for(i=0;i<M;i++)
  327.         {
  328.             for(j=0;j<M;j++)
  329.                 printf("%ft",R(i,j));
  330.             printf("n");
  331.         }
  332.         for(i=0;i<M;i++)
  333.             for(j=i+1;j<M;j++)
  334.         {
  335.             temp=Q(i,j);
  336.             Q(i,j)=Q(j,i);
  337.             Q(j,i)=temp;
  338.         }
  339.         printf("Matrix Q:n");
  340.         for(i=0;i<M;i++)
  341.         {
  342.             for(j=0;j<M;j++)
  343.                 printf("%ft",Q(i,j));
  344.             printf("n");
  345.         }
  346.     }
  347.     time2 = MPI_Wtime();
  348.     if (my_rank==0)
  349.     {
  350.         printf("n");
  351.         printf("Whole running time    = %f secondsn",time2-starttime);
  352.         printf("Distribute data time  = %f secondsn",time1-starttime);
  353.         printf("Parallel compute time = %f secondsn",time2-time1);
  354.     }
  355.     MPI_Barrier(MPI_COMM_WORLD);
  356.     MPI_Finalize();
  357.     Environment_Finalize(a,q,v,f,R,Q,ai,aj,qi,qj);
  358.     return(0);
  359. }