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

并行计算

开发平台:

Unix_Linux

  1. #include "stdio.h"
  2. #include "stdlib.h"
  3. #include "mpi.h"
  4. #include "math.h"
  5. /* somethings convinient for programming use */
  6. #define a(x,y) a[x*M+y]
  7. #define b(x) b[x]
  8. #define A(x,y) A[x*M+y]
  9. #define B(x) B[x]
  10. #define floatsize sizeof(float)
  11. #define intsize sizeof(int)
  12. /* M*M matrix */
  13. int M;
  14. /* dimision for per node */
  15. int m;
  16. /* A, B array pointer */
  17. float *A;
  18. float *B;
  19. /* time starting to compute, and other virable for time use */
  20. double starttime;
  21. double time1;
  22. double time2;
  23. /* node rank */
  24. int my_rank;
  25. /* size of nodes */
  26. int p;
  27. int l;
  28. MPI_Status status;
  29. /*
  30.  *Function: fatal()
  31.  *Desc:     output some message for user to know, and exit
  32.  *Param:    message-char pointer to msg going to print on the screen
  33.  */
  34. void
  35. fatal(char *message)
  36. {
  37.     printf("%sn",message);
  38.     exit(1);
  39. }
  40. /*
  41.  *Function: Environment_Finalize()
  42.  *Desc:     release some pointer before all be finished
  43.  *Param:    a,b,x,f - float pointer
  44.  *
  45.  */
  46. void
  47. Environment_Finalize(float *a,float *b,float *x,float *f)
  48. {
  49.     free(a);
  50.     free(b);
  51.     free(x);
  52.     free(f);
  53. }
  54. /*
  55.  *Function:  main()
  56.  *Desc:      program entry
  57.  *Param:
  58.  */
  59. int
  60. main(int argc, char **argv)
  61. {
  62.     int i,j,t,k,my_rank,group_size;
  63.     int i1,i2;
  64.     int v,w;
  65.     float s;
  66.     float temp;
  67.     int tem;
  68.     float *f;
  69.     float lmax;
  70.     float *a;
  71.     float *b;
  72.     float *x;
  73.     int *shift;
  74.     FILE *fdA,*fdB;
  75.     /* initialize MPI , group_size, my_rank */
  76.     MPI_Init(&argc,&argv);
  77.     MPI_Comm_size(MPI_COMM_WORLD,&group_size);
  78.     MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
  79.     if(my_rank==0)
  80.         printf("group size: %dn",group_size);
  81.     /* node number */
  82.     p=group_size;
  83.     /*
  84.      for the node which my_rank==0, set starttime
  85.      and read A,B elements from file"dataIn.txt",
  86.      p.s. M=N-1
  87.     */
  88.     if (my_rank==0)
  89.     {
  90.         starttime=MPI_Wtime();
  91.         fdA=fopen("dataIn.txt","r");
  92.         fscanf(fdA,"%d",&M);
  93.         /* allocate memory for matrix A an B */
  94.         A=(float *)malloc(floatsize*M*M);
  95.         B=(float *)malloc(floatsize*M);
  96.         /* read A&B elements(M*(M+1)) from the file */
  97.         for(i = 0; i < M; i++)
  98.         {
  99.             /* the 0 to M-1 th element of each row is the element of A */
  100.             for(j = 0; j < M; j++)
  101.             {
  102.                 fscanf(fdA,"%f", A+i*M+j);
  103.             }
  104.             /* the last one of each row  is the element of B */
  105.             fscanf(fdA,"%f", B+i);
  106.         }
  107.         fclose(fdA);
  108.     }
  109.     /* broadcast the value of M */
  110.     MPI_Bcast(&M,1,MPI_INT,0,MPI_COMM_WORLD);
  111.     /* allocate area for each node */
  112.     m=M/p;
  113.     if (M%p!=0) m++;
  114.     f=(float*)malloc(sizeof(float)*(M+1));
  115.     a=(float*)malloc(sizeof(float)*m*M);
  116.     b=(float*)malloc(sizeof(float)*m);
  117.     x=(float*)malloc(sizeof(float)*M);
  118.     shift=(int*)malloc(sizeof(int)*M);
  119.     /* initialize shift value for each column */
  120.     for(i=0;i<M;i++)
  121.         shift[i]=i;
  122.     /* node which my_rank==0 appoints the a,b matrix array */
  123.     if (my_rank==0)
  124.     {
  125.         for(i=0;i<m;i++)
  126.             for(j=0;j<M;j++)
  127.                 a(i,j)=A(i*p,j);
  128.         for(i=0;i<m;i++)
  129.             b(i)=B(i*p);
  130.     }
  131.     if (my_rank==0)
  132.     {
  133.         for(i=0;i<M;i++)
  134.             if ((i%p)!=0)
  135.         {
  136.             i1=i%p;
  137.             i2=i/p+1;
  138.             /* send A, B elements to node i1(i1!=0) */
  139.             MPI_Send(&A(i,0),M,MPI_FLOAT,i1,i2,MPI_COMM_WORLD);
  140.             MPI_Send(&B(i),1,MPI_FLOAT,i1,i2,MPI_COMM_WORLD);
  141.         }
  142.     }                                             /*  my_rank==0 */
  143.     else                                          /*  my_rank !=0 */
  144.     {
  145.         /* receive A,B elements from node 0 */
  146.         for(i=0;i<m;i++)
  147.         {
  148.             MPI_Recv(&a(i,0),M,MPI_FLOAT,0,i+1,MPI_COMM_WORLD,&status);
  149.             MPI_Recv(&b(i),1,MPI_FLOAT,0,i+1,MPI_COMM_WORLD,&status);
  150.         }
  151.     }
  152.     time1=MPI_Wtime();                            /* computing start */
  153.     for(i=0;i<m;i++)
  154.         for(j=0;j<p;j++)
  155.     {
  156.         if (my_rank==j)                           /* node rank= j*/
  157.         {
  158.             /* find lmax of matrix a on this node */
  159.             v=i*p+j;
  160.             lmax=a(i,v);
  161.             l=v;
  162.             for(k=v+1;k<M;k++)
  163.                 if (fabs(a(i,k))>lmax)
  164.             {
  165.                 lmax=a(i,k);
  166.                 l=k;
  167.             }
  168.             /* exchange the with the max */
  169.             if (l!=v)
  170.             {
  171.                 for(t=0;t<m;t++)
  172.                 {
  173.                     temp=a(t,v);
  174.                     a(t,v)=a(t,l);
  175.                     a(t,l)=temp;
  176.                 }
  177.                 /* record the shift in order to output the right x */
  178.                 tem=shift[v];
  179.                 shift[v]=shift[l];
  180.                 shift[l]=tem;
  181.             }
  182.             for(k=v+1;k<M;k++)
  183.                 a(i,k)=a(i,k)/a(i,v);
  184.             b(i)=b(i)/a(i,v);
  185.             a(i,v)=1;
  186.             /* record f array for future use */
  187.             for(k=v+1;k<M;k++)
  188.                 f[k]=a(i,k);
  189.             f[M]=b(i);
  190.             /* broadcast f & l value to node which rank= my_rank */
  191.             MPI_Bcast(&f[0],M+1,MPI_FLOAT,my_rank,MPI_COMM_WORLD);
  192.             MPI_Bcast(&l,1,MPI_INT,my_rank,MPI_COMM_WORLD);
  193.         }
  194.         else /*rank!=j*/
  195.         {
  196.             v=i*p+j;
  197.             MPI_Bcast(&f[0],M+1,MPI_FLOAT,j,MPI_COMM_WORLD);
  198.             MPI_Bcast(&l,1,MPI_INT,j,MPI_COMM_WORLD);
  199.         }
  200.         if(my_rank!=j)
  201.             if (l!=v)
  202.         {
  203.             for(t=0;t<m;t++)
  204.             {
  205.                 temp=a(t,v);
  206.                 a(t,v)=a(t,l);
  207.                 a(t,l)=temp;
  208.             }
  209.             tem=shift[v];
  210.             shift[v]=shift[l];
  211.             shift[l]=tem;
  212.         }
  213.         if (my_rank!=j)
  214.             for(k=0;k<m;k++)
  215.         {
  216.             for(w=v+1;w<M;w++)
  217.                 a(k,w)=a(k,w)-f[w]*a(k,v);
  218.             b(k)=b(k)-f[M]*a(k,v);
  219.         }
  220.         if (my_rank==j)
  221.             for(k=0;k<m;k++)
  222.                 if (k!=i)
  223.                 {
  224.                     for(w=v+1;w<M;w++)
  225.                         a(k,w)=a(k,w)-f[w]*a(k,v);
  226.                     b(k)=b(k)-f[M]*a(k,v);
  227.                 }
  228.     } /* for i j */
  229.     /* caculate x value at node which rank is zero */
  230.     if (my_rank==0)
  231.         for(i=0;i<m;i++)
  232.             x[i*p]=b(i);
  233.     /* node which rank is not zero send b() value to node zero */
  234.     if (my_rank!=0)
  235.         for(i=0;i<m;i++)
  236.             MPI_Send(&b(i),1,MPI_FLOAT,0,my_rank,MPI_COMM_WORLD);
  237.     else
  238.     {
  239.         /*
  240.          node which rank is  zero recieve b() value from node i
  241.          and caculate x value
  242.         */
  243.         for(i=1;i<p;i++)
  244.             for(j=0;j<m;j++)
  245.         {
  246.             MPI_Recv(&b(j),1,MPI_FLOAT,i,i,MPI_COMM_WORLD,&status);
  247.             x[j*p+i]=b(j);
  248.         }
  249.     }
  250.     /* write the result to the screen and to file "dataOut.txt" */
  251.     fdA=fopen("dataOut.txt","w");
  252.     if (my_rank==0)
  253.     {
  254.         printf("Input of file "dataIn.txt"n");
  255.         printf("%dn", M);
  256.         for(i=0;i<M;i++)
  257.         {
  258.             for(j=0;j<M;j++) printf("%ft",A(i,j));
  259.             printf("%fn",B(i));
  260.         }
  261.         printf("nOutput of solutionn");
  262.         fprintf(fdA,"Output of solutionn");
  263.         for(k=0;k<M;k++)
  264.         {
  265.             for(i=0;i<M;i++)
  266.             {
  267.                 if (shift[i]==k)
  268.                 {
  269.                     printf("x[%d]=%fn",k,x[i]);
  270.                     fprintf(fdA,"x[%d]=%fn",k,x[i]);
  271.                 }
  272.             }
  273.         }
  274.     }
  275.     time2=MPI_Wtime();
  276.     if (my_rank==0)
  277.     {
  278.         printf("n");
  279.         printf("Whole running time    = %f secondsn",time2-starttime);
  280.         printf("Distribute data time  = %f secondsn",time1-starttime);
  281.         printf("Parallel compute time = %f secondsn",time2-time1);
  282.         fprintf(fdA,"Whole running time    = %f secondsn",time2-starttime);
  283.         fprintf(fdA,"Distribute data time  = %f secondsn",time1-starttime);
  284.         fprintf(fdA,"Parallel compute time = %f secondsn",time2-time1);
  285.     }
  286.     fclose(fdA);
  287.     /* finalize and release pointer */
  288.     MPI_Finalize();
  289.     Environment_Finalize(a,b,x,f);
  290.     return(0);
  291. }