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

并行计算

开发平台:

Unix_Linux

  1. #include "stdio.h"
  2. #include "stdlib.h"
  3. #include "mpi.h"
  4. #include "math.h"
  5. #define E 0.0001
  6. #define intsize sizeof(int)
  7. #define floatsize sizeof(float)
  8. #define a(x,y) a[x*M+y]
  9. #define q(x,y) q[x*M+y]
  10. #define b(x,y) b[x*m+y]
  11. #define t(l,x,y) t[x*M+y+l*m]
  12. #define buffer(x,y) buffer[x*m+y]
  13. #define A(x,y) A[x*M+y]
  14. #define Q(x,y) Q[x*M+y]
  15. #define R(x,y) R[x*M+y]
  16. float temp;
  17. float *A;
  18. float *R;
  19. float *Q;
  20. double starttime;
  21. double time1;
  22. double time2;
  23. int p;
  24. MPI_Status status;
  25. void Environment_Finalize(float *a,float *q,float *v,float *f,
  26.     float *R,float *Q,float *ai,float *aj,
  27.     float *qi,float *qj,float *b,float *t,float *buffer)
  28. {
  29.     free(a);
  30.     free(q);
  31.     free(v);
  32.     free(f);
  33.     free(R);
  34.     free(Q);
  35.     free(ai);
  36.     free(aj);
  37.     free(qi);
  38.     free(qj);
  39.     free(b);
  40.     free(t);
  41.     free(buffer);
  42. }
  43. int main(int argc, char **argv)
  44. {
  45.     int M,N,m;
  46.     int mm1,mp1;
  47.     int count,tag;
  48.     int n;
  49.     int i,j,k,l,my_rank,group_size;
  50.     float *ai,*qi,*aj,*qj;
  51.     float c,s,sp;
  52.     float *f,*v;
  53.     float *a,*q,*b,*t,*buffer;
  54.     FILE *fdA;
  55.     count=0;
  56.     MPI_Init(&argc,&argv);
  57.     MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
  58.     MPI_Comm_size(MPI_COMM_WORLD,&group_size);
  59.     p=group_size;
  60.     starttime=MPI_Wtime();
  61.     if(my_rank==p-1)
  62.     {
  63.         fdA=fopen("dataIn.txt","r");
  64.         fscanf(fdA,"%d %d", &M, &N);
  65.         if(M != N)
  66.         {
  67.             puts("The input is error!");
  68.             exit(0);
  69.         }
  70.         A=(float*)malloc(sizeof(float)*M*M);
  71.         Q=(float*)malloc(sizeof(float)*M*M);
  72.         R=(float*)malloc(sizeof(float)*M*M);
  73.         for(i = 0; i < M; i ++)
  74.         {
  75.             for(j = 0; j < M; j ++) fscanf(fdA, "%f", A+i*M+j);
  76.         }
  77.         fclose(fdA);
  78.         printf("Input of file "dataIn.txt"n");
  79.         printf("%dt %dn",M, N);
  80.         for(i=0;i<M;i++)
  81.         {
  82.             for(j=0;j<N;j++) printf("%ft",A(i,j));
  83.             printf("n");
  84.         }
  85.         for(i=0;i<M;i++)
  86.             for(j=0;j<M;j++)
  87.                 if (i==j)
  88.                     Q(i,j)=1.0;
  89.         else
  90.             Q(i,j)=0.0;
  91.     }
  92.     MPI_Bcast(&M,1,MPI_INT,p-1,MPI_COMM_WORLD);
  93.     m=M/p;
  94.     if (M%p!=0) m++;
  95.     qi=(float*)malloc(sizeof(float)*M);
  96.     qj=(float*)malloc(sizeof(float)*M);
  97.     aj=(float*)malloc(sizeof(float)*M);
  98.     ai=(float*)malloc(sizeof(float)*M);
  99.     v=(float*)malloc(sizeof(float)*M);
  100.     f=(float*)malloc(sizeof(float)*M);
  101.     a=(float*)malloc(sizeof(float)*m*M);
  102.     q=(float*)malloc(sizeof(float)*m*M);
  103.     b=(float*)malloc(sizeof(float)*m*M);
  104.     t=(float *)malloc(floatsize*m*M);
  105.     if (my_rank%2!=0)
  106.         buffer=(float *)malloc(M*m*floatsize);
  107.     if (a==NULL||q==NULL||f==NULL||v==NULL||qi==NULL||qj==NULL||ai==NULL||aj==NULL||b==NULL||t==NULL||buffer==NULL)
  108.         printf("memory allocation is wrongn");
  109.     if (my_rank==p-1)
  110.     {
  111.         for(i=0;i<m;i++)
  112.             for(j=0;j<M;j++)
  113.         {
  114.             a(i,j)=A((my_rank*m+i),j);
  115.             q(i,j)=Q((my_rank*m+i),j);
  116.         }
  117.     }
  118.     if (my_rank==p-1)
  119.     {
  120.         for(i=0;i<p-1;i++)
  121.         {
  122.             MPI_Send(&A(m*i,0),m*M,MPI_FLOAT,i,i,MPI_COMM_WORLD);
  123.             MPI_Send(&Q(m*i,0),m*M,MPI_FLOAT,i,i,MPI_COMM_WORLD);
  124.         }
  125.     }
  126.     else
  127.     {
  128.         MPI_Recv(a,m*M,MPI_FLOAT,p-1,my_rank,MPI_COMM_WORLD,&status);
  129.         MPI_Recv(q,m*M,MPI_FLOAT,p-1,my_rank,MPI_COMM_WORLD,&status);
  130.     }
  131.     time1=MPI_Wtime();
  132.     do
  133.     {
  134.         if (p>1)
  135.         {
  136.             if (my_rank==0)
  137.             {
  138.                 for(j=0;j<m-1;j++)
  139.                 {
  140.                     for(i=j+1;i<m;i++)
  141.                     {
  142.                         sp=sqrt(a(j,j)*a(j,j)+a(i,j)*a(i,j));
  143.                         c=a(j,j)/sp;  s=a(i,j)/sp;
  144.                         for(k=0;k<M;k++)
  145.                         {
  146.                             aj[k]=c*a(j,k)+s*a(i,k);
  147.                             qj[k]=c*q(j,k)+s*q(i,k);
  148.                             ai[k]=-s*a(j,k)+c*a(i,k);
  149.                             qi[k]=-s*q(j,k)+c*q(i,k);
  150.                         }
  151.                         for(k=0;k<M;k++)
  152.                         {
  153.                             a(j,k)=aj[k];
  154.                             q(j,k)=qj[k];
  155.                             a(i,k)=ai[k];
  156.                             q(i,k)=qi[k];
  157.                         }
  158.                     }                             /*  i */
  159.                     for(k=0;k<M;k++)
  160.                     {
  161.                         f[k]=a(j,k);
  162.                         v[k]=q(j,k);
  163.                     }
  164.                     MPI_Send(&f[0],M,MPI_FLOAT,1,j,MPI_COMM_WORLD);
  165.                     MPI_Send(&v[0],M,MPI_FLOAT,1,j,MPI_COMM_WORLD);
  166.                 }                                 /* for j */
  167.                 for(k=0;k<M;k++)
  168.                 {
  169.                     f[k]=a((m-1),k);
  170.                     v[k]=q((m-1),k);
  171.                 }
  172.                 MPI_Send(&f[0],M,MPI_FLOAT,1,m-1,MPI_COMM_WORLD);
  173.                 MPI_Send(&v[0],M,MPI_FLOAT,1,m-1,MPI_COMM_WORLD);
  174.             }                                     /* my_rank==0 */
  175.             else                                  /* my_rank!=0 */
  176.             {
  177.                 if (my_rank!=group_size-1)
  178.                 {
  179.                     for(j=0;j<my_rank*m;j++)
  180.                     {
  181.                         MPI_Recv(&f[0],M,MPI_FLOAT,(my_rank-1),j,MPI_COMM_WORLD,&status);
  182.                         MPI_Recv(&v[0],M,MPI_FLOAT,(my_rank-1),j,MPI_COMM_WORLD,&status);
  183.                         for(i=0;i<m;i++)
  184.                         {
  185.                             sp=sqrt(f[j]*f[j]+a(i,j)*a(i,j));
  186.                             c=f[j]/sp;  s=a(i,j)/sp;
  187.                             for(k=0;k<M;k++)
  188.                             {
  189.                                 aj[k]=c*f[k]+s*a(i,k);
  190.                                 qj[k]=c*v[k]+s*q(i,k);
  191.                                 ai[k]=-s*f[k]+c*a(i,k);
  192.                                 qi[k]=-s*v[k]+c*q(i,k);
  193.                             }
  194.                             for(k=0;k<M;k++)
  195.                             {
  196.                                 f[k]=aj[k];
  197.                                 v[k]=qj[k];
  198.                                 a(i,k)=ai[k];
  199.                                 q(i,k)=qi[k];
  200.                             }
  201.                         }
  202.                         MPI_Send(&f[0],M,MPI_FLOAT,(my_rank+1),j,MPI_COMM_WORLD);
  203.                         MPI_Send(&v[0],M,MPI_FLOAT,(my_rank+1),j,MPI_COMM_WORLD);
  204.                     }                             /* for j */
  205.                     for(j=0;j<m-1;j++)
  206.                     {
  207.                         for(i=j+1;i<m;i++)
  208.                         {
  209.                             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));
  210.                             c=a(j,my_rank*m+j)/sp;
  211.                             s=a(i,my_rank*m+j)/sp;
  212.                             for(k=0;k<M;k++)
  213.                             {
  214.                                 aj[k]=c*a(j,k)+s*a(i,k);
  215.                                 qj[k]=c*q(j,k)+s*q(i,k);
  216.                                 ai[k]=-s*a(j,k)+c*a(i,k);
  217.                                 qi[k]=-s*q(j,k)+c*q(i,k);
  218.                             }
  219.                             for(k=0;k<M;k++)
  220.                             {
  221.                                 a(j,k)=aj[k];
  222.                                 q(j,k)=qj[k];
  223.                                 a(i,k)=ai[k];
  224.                                 q(i,k)=qi[k];
  225.                             }
  226.                         }
  227.                         for(k=0;k<M;k++)
  228.                         {
  229.                             f[k]=a(j,k);
  230.                             v[k]=q(j,k);
  231.                         }
  232.                         MPI_Send(&f[0],M,MPI_FLOAT,my_rank+1,my_rank*m+j,MPI_COMM_WORLD);
  233.                         MPI_Send(&v[0],M,MPI_FLOAT,my_rank+1,my_rank*m+j,MPI_COMM_WORLD);
  234.                     }                             /* for j */
  235.                     for(k=0;k<M;k++)
  236.                     {
  237.                         f[k]=a((m-1),k);
  238.                         v[k]=q((m-1),k);
  239.                     }
  240.                     MPI_Send(&f[0],M,MPI_FLOAT,my_rank+1,my_rank*m+m-1,MPI_COMM_WORLD);
  241.                     MPI_Send(&v[0],M,MPI_FLOAT,my_rank+1,my_rank*m+m-1,MPI_COMM_WORLD);
  242.                 }                                 /* my_rank !=groupsize -1 */
  243.                 if (my_rank==group_size-1)
  244.                 {
  245.                     for(j=0;j<my_rank*m;j++)
  246.                     {
  247.                         MPI_Recv(&f[0],M,MPI_FLOAT,(my_rank-1),j,MPI_COMM_WORLD,&status);
  248.                         MPI_Recv(&v[0],M,MPI_FLOAT,(my_rank-1),j,MPI_COMM_WORLD,&status);
  249.                         for(i=0;i<m;i++)
  250.                         {
  251.                             sp=sqrt(f[j]*f[j]+a(i,j)*a(i,j));
  252.                             c=f[j]/sp;  s=a(i,j)/sp;
  253.                             for(k=0;k<M;k++)
  254.                             {
  255.                                 aj[k]=c*f[k]+s*a(i,k);
  256.                                 qj[k]=c*v[k]+s*q(i,k);
  257.                                 ai[k]=-s*f[k]+c*a(i,k);
  258.                                 qi[k]=-s*v[k]+c*q(i,k);
  259.                             }
  260.                             for(k=0;k<M;k++)
  261.                             {
  262.                                 f[k]=aj[k];
  263.                                 v[k]=qj[k];
  264.                                 a(i,k)=ai[k];
  265.                                 q(i,k)=qi[k];
  266.                             }
  267.                         }                         /* for i */
  268.                         for(k=0;k<M;k++)
  269.                         {
  270.                             Q(j,k)=v[k];
  271.                             R(j,k)=f[k];
  272.                         }
  273.                     }                             /* for j */
  274.                     for(j=0;j<m-1;j++)
  275.                     {
  276.                         for(i=j+1;i<m;i++)
  277.                         {
  278.                             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));
  279.                             c=a(j,my_rank*m+j)/sp;
  280.                             s=a(i,my_rank*m+j)/sp;
  281.                             for(k=0;k<M;k++)
  282.                             {
  283.                                 aj[k]=c*a(j,k)+s*a(i,k);
  284.                                 qj[k]=c*q(j,k)+s*q(i,k);
  285.                                 ai[k]=-s*a(j,k)+c*a(i,k);
  286.                                 qi[k]=-s*q(j,k)+c*q(i,k);
  287.                             }
  288.                             for(k=0;k<M;k++)
  289.                             {
  290.                                 a(j,k)=aj[k];
  291.                                 q(j,k)=qj[k];
  292.                                 a(i,k)=ai[k];
  293.                                 q(i,k)=qi[k];
  294.                             }
  295.                         }                         /*  for i */
  296.                         for(k=0;k<M;k++)
  297.                         {
  298.                             Q((my_rank*m+j),k)=q(j,k);
  299.                             R((my_rank*m+j),k)=a(j,k);
  300.                         }
  301.                     }                             /* for j */
  302.                     for(k=0;k<M;k++)
  303.                     {
  304.                         Q((my_rank*m+m-1),k)=q((m-1),k);
  305.                         R((my_rank*m+m-1),k)=a((m-1),k);
  306.                     }
  307.                 }                                 /* for my_rank==groupsize -1 */
  308.             }                                     /*    else my_rank!=0           */
  309.         }                                         /*    if p >1          */
  310.         if (p==1)
  311.         {
  312.             for (j=0;j<M;j++)
  313.                 for (i=j+1;i<M;i++)
  314.             {
  315.                 sp=sqrt(a(j,j)*a(j,j) + a(i,j)*a(i,j));
  316.                 c=a(j,j)/sp;
  317.                 s=a(i,j)/sp;
  318.                 for (k=0;k<M;k++)
  319.                 {
  320.                     aj[k]=c*a(j,k) + s*a(i,k);
  321.                     qj[k]=c*q(j,k) + s*q(i,k);
  322.                     ai[k]=(-s)*a(j,k) + c*a(i,k);
  323.                     qi[k]=(-s)*q(j,k) + c*q(i,k);
  324.                 }
  325.                 for (k=0;k<M;k++)
  326.                 {
  327.                     a(j,k)=aj[k];
  328.                     q(j,k)=qj[k];
  329.                     a(i,k)=ai[k];
  330.                     q(i,k)=qi[k];
  331.                 }
  332.             }                                     /* for   */
  333.             for(i=0;i<M;i++)
  334.                 for(j=0;j<M;j++)
  335.                     R(i,j)=a(i,j);
  336.             for(i=0;i<M;i++)
  337.                 for(j=0;j<M;j++)
  338.                     Q(i,j)=q(i,j);
  339.         }                                         /*  if   p==1 */
  340.         if (my_rank==p-1)
  341.         {
  342.             for(i=0;i<M;i++)
  343.                 for(j=i+1;j<M;j++)
  344.             {
  345.                 temp=Q(i,j);
  346.                 Q(i,j)=Q(j,i);
  347.                 Q(j,i)=temp;
  348.             }
  349.         }
  350.         if (my_rank==p-1)
  351.         {
  352.             for(i=0;i<m;i++)
  353.                 for(j=0;j<M;j++)
  354.                     a(i,j)=R((my_rank*m+i),j);
  355.             for (i=0;i<M;i++)
  356.                 for (j=0;j<m;j++)
  357.                     b(i,j)=Q(i,(my_rank*m+j));
  358.         }
  359.         if (my_rank==p-1)
  360.         {
  361.             for(i=0;i<p-1;i++)
  362.             {
  363.                 MPI_Send(&R(m*i,0),m*M,MPI_FLOAT,i,i,MPI_COMM_WORLD);
  364.                 for (j=0;j<M;j++)
  365.                     MPI_Send(&Q(j,m*i),m,MPI_FLOAT,i,i,MPI_COMM_WORLD);
  366.             }
  367.         }
  368.         else
  369.         {
  370.             MPI_Recv(a,m*M,MPI_FLOAT,p-1,my_rank,MPI_COMM_WORLD,&status);
  371.             for (j=0;j<M;j++)
  372.                 MPI_Recv(&b(j,0),m,MPI_FLOAT,p-1,my_rank,MPI_COMM_WORLD,&status);
  373.         }
  374.         for (i=0;i<p;i++)
  375.         {
  376.             l=(i+my_rank)%p;
  377.             for (k=0;k<m;k++)
  378.                 for (j=0;j<m;j++)
  379.                     for (t(l,k,j)=0,n=0;n<M;n++)
  380.                         t(l,k,j)=t(l,k,j)+a(k,n)*b(n,j);
  381.             mm1=(p+my_rank-1)%p;
  382.             mp1=(my_rank+1)%p;
  383.             if (i!=p-1)
  384.             {
  385.                 if(my_rank%2==0)
  386.                 {
  387.                     MPI_Send(b,M*m,MPI_FLOAT,mm1,mm1,MPI_COMM_WORLD);
  388.                     MPI_Recv(b,M*m,MPI_FLOAT,mp1,my_rank,MPI_COMM_WORLD,&status);
  389.                 }
  390.                 else
  391.                 {
  392.                     for(k=0;k<M;k++)
  393.                         for(j=0;j<m;j++)
  394.                             buffer(k,j)=b(k,j);
  395.                     MPI_Recv(b,M*m,MPI_FLOAT,mp1,my_rank,MPI_COMM_WORLD,&status);
  396.                     MPI_Send(buffer,M*m,MPI_FLOAT,mm1,mm1,MPI_COMM_WORLD);
  397.                 }
  398.             }
  399.         }                                         /*  for */
  400.         if (my_rank==p-1)
  401.             for(i=0;i<m;i++)
  402.                 for(j=0;j<M;j++)
  403.                     A((my_rank*m+i),j)=*(t+i*M+j);
  404.         if (my_rank!=p-1)
  405.             MPI_Send(t,m*M,MPI_FLOAT,p-1,my_rank,MPI_COMM_WORLD);
  406.         else
  407.         {
  408.             for(k=0;k<p-1;k++)
  409.             {
  410.                 MPI_Recv(t,m*M,MPI_FLOAT,k,k,MPI_COMM_WORLD,&status);
  411.                 for(i=0;i<m;i++)
  412.                     for(j=0;j<M;j++)
  413.                         A((k*m+i),j)=*(t+i*M+j);
  414.             }
  415.         }
  416.         count++;
  417.         tag=0;
  418.         if (my_rank==p-1)
  419.         {
  420.             for(i=1;i<M;i++)
  421.                 for(j=0;j<i;j++)
  422.                     if (fabs(A(i,j))>E)
  423.                         tag=1;
  424.         }
  425.         MPI_Bcast(&tag,1,MPI_INT,p-1,MPI_COMM_WORLD);
  426.         if (my_rank==p-1)
  427.         {
  428.             for(i=0;i<M;i++)
  429.                 for(j=0;j<M;j++)
  430.                     if (i==j)
  431.                         Q(i,j)=1.0;
  432.             else
  433.                 Q(i,j)=0.0;
  434.         }
  435.         if (my_rank==p-1)
  436.         {
  437.             for(i=0;i<m;i++)
  438.                 for(j=0;j<M;j++)
  439.             {
  440.                 a(i,j)=A((my_rank*m+i),j);
  441.                 q(i,j)=Q((my_rank*m+i),j);
  442.             }
  443.         }
  444.         if (my_rank==p-1)
  445.         {
  446.             for(i=0;i<p-1;i++)
  447.             {
  448.                 MPI_Send(&A(m*i,0),m*M,MPI_FLOAT,i,i,MPI_COMM_WORLD);
  449.                 MPI_Send(&Q(m*i,0),m*M,MPI_FLOAT,i,i,MPI_COMM_WORLD);
  450.             }
  451.         }
  452.         else
  453.         {
  454.             MPI_Recv(a,m*M,MPI_FLOAT,p-1,my_rank,MPI_COMM_WORLD,&status);
  455.             MPI_Recv(q,m*M,MPI_FLOAT,p-1,my_rank,MPI_COMM_WORLD,&status);
  456.         }
  457.     }
  458.     while ((tag==1)&&(count<1000));
  459.     if(my_rank==p-1)
  460.     {
  461.         if (count>=1000)
  462.         {
  463.             printf("n can not converage to a triangular matrixn");
  464.             printf("this is the matrix:n");
  465.             for(i=0;i<M;i++)
  466.             {
  467.                 for(j=0;j<M;j++)
  468.                     printf("%ft",A(i,j));
  469.                 printf("n");
  470.             }
  471.         }
  472.         else
  473.         {
  474.             printf("nthe envalue isn");
  475.             for(i=0;i<M;i++) printf("%ft",A(i,i));
  476.             printf("n");
  477.         }
  478.     }
  479.     time2 = MPI_Wtime();
  480.     if (my_rank==0)
  481.     {
  482.         printf("n");
  483.         printf("Iteration num = %dn",count);
  484.         printf("Whole running time    = %f secondsn",time2-starttime);
  485.         printf("Distribute data time  = %f secondsn",time1-starttime);
  486.         printf("Parallel compute time = %f secondsn",time2-time1);
  487.     }
  488.     MPI_Barrier(MPI_COMM_WORLD);
  489.     MPI_Finalize();
  490.     Environment_Finalize(a,q,v,f,R,Q,ai,aj,qi,qj,b,t,buffer);
  491.     return(0);
  492. }