Advertisement
elsemTim

mpi

Dec 22nd, 2018
182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.96 KB | None | 0 0
  1. /**********************************************************************                                                                                      
  2.  * MPI-based matrix multiplication AxB=C                                                                                                                    
  3.  *********************************************************************/
  4.  
  5.  
  6. #include <stdio.h>
  7. #include "mpi.h"
  8. #define N               4        /* number of rows and columns in matrix */
  9.  
  10. MPI_Status status;
  11.  
  12. double a[N][N],b[N][N],c[N][N];
  13.  
  14. main(int argc, char **argv)
  15. {
  16.   int numtasks,taskid,numworkers,source,dest,rows,offset,i,j,k;
  17.  
  18.   struct timeval start, stop;
  19.  
  20.   MPI_Init(&argc, &argv);
  21.   MPI_Comm_rank(MPI_COMM_WORLD, &taskid);
  22.   MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
  23.  
  24.   numworkers = numtasks-1;
  25.  
  26.   /*---------------------------- master ----------------------------*/
  27.   if (taskid == 0) {
  28.     for (i=0; i<N; i++) {
  29.       for (j=0; j<N; j++) {
  30.         a[i][j]= 1.0;
  31.         b[i][j]= 2.0;
  32.       }
  33.     }
  34.  
  35.     gettimeofday(&start, 0);
  36.  
  37.     /* send matrix data to the worker tasks */
  38.     rows = N/numworkers;
  39.     offset = 0;
  40.  
  41.     for (dest=1; dest<=numworkers; dest++)
  42.     {
  43.       MPI_Send(&offset, 1, MPI_INT, dest, 1, MPI_COMM_WORLD);
  44.       MPI_Send(&rows, 1, MPI_INT, dest, 1, MPI_COMM_WORLD);
  45.       MPI_Send(&a[offset][0], rows*N, MPI_DOUBLE,dest,1, MPI_COMM_WORLD);
  46.       MPI_Send(&b, N*N, MPI_DOUBLE, dest, 1, MPI_COMM_WORLD);
  47.       offset = offset + rows;
  48.     }
  49.  
  50.     /* wait for results from all worker tasks */
  51.     for (i=1; i<=numworkers; i++)
  52.     {
  53.       source = i;
  54.       MPI_Recv(&offset, 1, MPI_INT, source, 2, MPI_COMM_WORLD, &status);
  55.       MPI_Recv(&rows, 1, MPI_INT, source, 2, MPI_COMM_WORLD, &status);
  56.       MPI_Recv(&c[offset][0], rows*N, MPI_DOUBLE, source, 2, MPI_COMM_WORLD, &status);
  57.     }
  58.  
  59.     gettimeofday(&stop, 0);
  60.  
  61.     printf("Here is the result matrix:\n");
  62.     for (i=0; i<N; i++) {
  63.       for (j=0; j<N; j++)
  64.         printf("%6.2f   ", c[i][j]);
  65.       printf ("\n");
  66.     }
  67.  
  68.     fprintf(stdout,"Time = %.6f\n\n",
  69.          (stop.tv_sec+stop.tv_usec*1e-6)-(start.tv_sec+start.tv_usec*1e-6));
  70.  
  71.   }
  72.  
  73.   /*---------------------------- worker----------------------------*/
  74.   if (taskid > 0) {
  75.     source = 0;
  76.     MPI_Recv(&offset, 1, MPI_INT, source, 1, MPI_COMM_WORLD, &status);
  77.     MPI_Recv(&rows, 1, MPI_INT, source, 1, MPI_COMM_WORLD, &status);
  78.     MPI_Recv(&a, rows*N, MPI_DOUBLE, source, 1, MPI_COMM_WORLD, &status);
  79.     MPI_Recv(&b, N*N, MPI_DOUBLE, source, 1, MPI_COMM_WORLD, &status);
  80.  
  81.     /* Matrix multiplication */
  82.     for (k=0; k<N; k++)
  83.       for (i=0; i<rows; i++) {
  84.         c[i][k] = 0.0;
  85.         for (j=0; j<N; j++)
  86.           c[i][k] = c[i][k] + a[i][j] * b[j][k];
  87.       }
  88.  
  89.  
  90.     MPI_Send(&offset, 1, MPI_INT, 0, 2, MPI_COMM_WORLD);
  91.     MPI_Send(&rows, 1, MPI_INT, 0, 2, MPI_COMM_WORLD);
  92.     MPI_Send(&c, rows*N, MPI_DOUBLE, 0, 2, MPI_COMM_WORLD);
  93.   }
  94.  
  95.   MPI_Finalize();
  96. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement