Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. /**********************************************************************
  2.  * MPI matrix multiplication AxB=C
  3.  *********************************************************************/
  4. #include <stdio.h>
  5. #include <mpi.h>
  6. #include <sys/time.h>
  7. #define N 10 /* number of rows and columns in matrix */
  8.  
  9. MPI_Status status;
  10.  
  11. double a[N][N], b[N][N], c[N][N];
  12.  
  13. main(int argc, char **argv) {
  14.  
  15.     int numtasks,taskid,numworkers,source,dest,rows,offset,i,j,k;
  16.  
  17.     printf("Matrix size= %d \n",N);
  18.  
  19.     struct timeval start, stop;
  20.  
  21.     MPI_Init(&argc, &argv);
  22.     MPI_Comm_rank(MPI_COMM_WORLD, &taskid);
  23.     MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
  24.     numworkers = numtasks;
  25.  
  26.     /*---------------------------- master ----------------------------*/
  27.     printf("Master\n");
  28.     if (taskid == 0) {
  29.         for (i=0; i<N; i++) {
  30.             for (j=0; j<N; j++) {
  31.                 a[i][j]= 1.0;
  32.                 b[i][j]= 2.0;
  33.             }
  34.         }
  35.         gettimeofday(&start, 0);
  36.  
  37.         /* send matrix data to the worker tasks */
  38.  
  39.         rows = N/numworkers;
  40.  
  41.         //master_rows=N%numworkers;
  42.         offset = 0;
  43.         for (dest=1; dest<numworkers; dest++)
  44.         {
  45.             MPI_Send(&offset, 1, MPI_INT, dest, 1, MPI_COMM_WORLD);
  46.             MPI_Send(&rows, 1, MPI_INT, dest, 1, MPI_COMM_WORLD);
  47.             MPI_Send(&a[offset][0], rows*N, MPI_DOUBLE,dest,1,
  48.                     MPI_COMM_WORLD);
  49.             MPI_Send(&b, N*N, MPI_DOUBLE, dest, 1, MPI_COMM_WORLD);
  50.             offset = offset + rows;
  51.         }
  52.        
  53.         for (k=0; k<N; k++){
  54.             for (i=offset; i<N; i++) {
  55.                 c[i][k] = 0.0;
  56.                 for (j=0; j<N; j++)
  57.                     c[i][k] = c[i][k] + a[i][j] * b[j][k];
  58.             }
  59.         }
  60.        
  61.         /* wait for results from all worker tasks */
  62.         for (i=1; i<numworkers; i++)
  63.         {
  64.             source = i;
  65.             MPI_Recv(&offset, 1, MPI_INT, source, 2, MPI_COMM_WORLD, &status);
  66.             MPI_Recv(&rows, 1, MPI_INT, source, 2, MPI_COMM_WORLD, &status);
  67.             MPI_Recv(&c[offset][0], rows*N, MPI_DOUBLE, source, 2,
  68.                     MPI_COMM_WORLD, &status);
  69.         }
  70.        
  71.         /* An alternative matrix multiplication approach
  72.  
  73.                 for (k=0; k<N; k++)
  74.          #                    for (i=offset; i<N; i++) {
  75.          #                            c[i][k] = 0.0;
  76.          #                           for (j=0; j<N; j++)
  77.          #                              c[i][k] = c[i][k] + a[i][j] *
  78.          #                              b[j][k];
  79.          #            }
  80.          */
  81.  
  82.  
  83.         gettimeofday(&stop, 0);
  84.         printf("Resulted Matrix C:\n");
  85.         for (i=0; i<N; i++) {
  86.             for (j=0; j<N; j++) {
  87.                 printf("%6.2f ", c[i][j]);
  88.             }
  89.             printf ("\n");
  90.  
  91.         }
  92.         fprintf(stdout,"Time = %.6f\n\n",
  93.                 (stop.tv_sec+stop.tv_usec*1e-6)-(start.tv_sec+start.tv_usec*1e-6));
  94.     }
  95.  
  96.     /*---------------------------- worker----------------------------*/
  97.     if (taskid > 0) {
  98.         printf("Worker=%d\n",taskid);
  99.         source = 0;
  100.         MPI_Recv(&offset, 1, MPI_INT, source, 1, MPI_COMM_WORLD, &status);
  101.         MPI_Recv(&rows, 1, MPI_INT, source, 1, MPI_COMM_WORLD, &status);
  102.         MPI_Recv(&a, rows*N, MPI_DOUBLE, source, 1, MPI_COMM_WORLD,
  103.                 &status);
  104.         MPI_Recv(&b, N*N, MPI_DOUBLE, source, 1, MPI_COMM_WORLD, &status);
  105.  
  106.         /* Matrix multiplication */
  107.         for (k=0; k<N; k++)
  108.         for (i=0; i<rows; i++) {
  109.             c[i][k] = 0.0;
  110.             for (j=0; j<N; j++)
  111.             c[i][k] = c[i][k] + a[i][j] * b[j][k];
  112.         }
  113.         MPI_Send(&offset, 1, MPI_INT, 0, 2, MPI_COMM_WORLD);
  114.         MPI_Send(&rows, 1, MPI_INT, 0, 2, MPI_COMM_WORLD);
  115.         MPI_Send(&c, rows*N, MPI_DOUBLE, 0, 2, MPI_COMM_WORLD);
  116.     }
  117.     MPI_Finalize();
  118. }