denisb413

Untitled

Nov 23rd, 2017
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.49 KB | None | 0 0
  1. #include <string.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #include <pthread.h>
  6. #include <float.h>
  7. #include <time.h>
  8. #include <mpi.h>
  9. #define  MASTER   0
  10.  
  11. /*
  12. Crie um programa serial e um programa paralelo com MPI que calculem a multiplica ̧c ̃ao
  13. de duas matrizes.
  14. */
  15.  
  16. int** a;
  17. int** b;
  18. int** c;
  19.  
  20. MPI_Status status;
  21.  
  22. int main(int argc, char *argv[])
  23. {
  24.  
  25.     if( argc != 2)
  26.     {
  27.         printf("PARAMETROS informe o tamanho da matriz\n");
  28.         return -1;
  29.     }
  30.  
  31.     int N;
  32.     N = atoi(argv[1]); //second parameter is the matrix size
  33.  
  34.     a = calloc(N, sizeof(int*));
  35.     for(i = 0; i < N; i++) {
  36.         a[i] = calloc(N, sizeof(int));
  37.     }
  38.  
  39.     b = calloc(N, sizeof(int*));
  40.     for(i = 0; i < N; i++) {
  41.         b[i] = calloc(N, sizeof(int));
  42.     }
  43.  
  44.     c = calloc(N, sizeof(int*));
  45.     for(i = 0; i < N; i++) {
  46.         c[i] = calloc(N, sizeof(int));
  47.     }
  48.  
  49.     int numtasks,rc,taskid,numworkers,source,dest,rows,offset,i,j,k;
  50.     struct timeval start, stop;
  51.  
  52.     MPI_Init(&argc, &argv);
  53.     MPI_Comm_rank(MPI_COMM_WORLD, &taskid);
  54.     MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
  55.  
  56.     if (numtasks < 2 ) {
  57.         printf("Need at least two MPI tasks. Quitting...\n");
  58.         MPI_Abort(MPI_COMM_WORLD, rc);
  59.         exit(1);
  60.     }
  61.     numworkers = numtasks-1;
  62.  
  63.     /*---------------------------- master ----------------------------*/
  64.     srand(time(NULL));
  65.  
  66.     if (taskid == MASTER) {
  67.  
  68.         for(i=0;i<N;i++){
  69.             for(j=0;j<N;j++){
  70.                 a[i][j] = rand(); //initialize with random values
  71.                 b[i][j] = rand();
  72.             }
  73.         }
  74.  
  75.         //Initiate the timer
  76.         clock_t begin = clock();
  77.  
  78.         //  send matrix data to the worker tasks
  79.         // rows = N/numworkers;
  80.         offset = 0;
  81.  
  82.         //calculate how much rows each thread will process, rounded up
  83.        
  84.         int rows = (N + (numworkers - 1)) / numworkers;
  85.  
  86.         for (dest=1; dest<=numworkers; dest++)
  87.         {
  88.             MPI_Send(&offset, 1, MPI_INT, dest, 1, MPI_COMM_WORLD);
  89.             MPI_Send(&rows, 1, MPI_INT, dest, 1, MPI_COMM_WORLD);
  90.             MPI_Send(&a[offset][0], rows*N, MPI_INT,dest,1, MPI_COMM_WORLD);
  91.             MPI_Send(&b, N*N, MPI_INT, dest, 1, MPI_COMM_WORLD);
  92.             offset = offset + rows;
  93.         }
  94.  
  95.         /* wait for results from all worker tasks */
  96.         for (i=1; i<=numworkers; i++)
  97.         {
  98.             source = i;
  99.             MPI_Recv(&offset, 1, MPI_INT, source, 2, MPI_COMM_WORLD, &status);
  100.             MPI_Recv(&rows, 1, MPI_INT, source, 2, MPI_COMM_WORLD, &status);
  101.             MPI_Recv(&c[offset][0], rows*N, MPI_INT, source, 2, MPI_COMM_WORLD, &status);
  102.         }
  103.  
  104.         printf("Here is the result matrix:\n");
  105.         for (i=0; i<N; i++) {
  106.             for (j=0; j<N; j++)
  107.             printf("%i   ", c[i][j]);
  108.             printf ("\n");
  109.         }
  110.  
  111.         //end the timer and calculate
  112.         clock_t end = clock();
  113.         double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
  114.  
  115.         printf("\n\n----This process took %f with matrix size %ix%i and with %d thread(s)----\n\n", time_spent, N, N, qtdThread);
  116.  
  117.  
  118.     }
  119.  
  120.     /*---------------------------- worker----------------------------*/
  121.     if (taskid > MASTER) {
  122.         source = 0;
  123.         MPI_Recv(&offset, 1, MPI_INT, source, 1, MPI_COMM_WORLD, &status);
  124.         MPI_Recv(&rows, 1, MPI_INT, source, 1, MPI_COMM_WORLD, &status);
  125.         MPI_Recv(&a, rows*N, MPI_INT, source, 1, MPI_COMM_WORLD, &status);
  126.         MPI_Recv(&b, N*N, MPI_INT, source, 1, MPI_COMM_WORLD, &status);
  127.  
  128.         /* Matrix multiplication */
  129.         for (k=0; k<N; k++)
  130.             for (i=0; i<rows; i++) {
  131.                 c[i][k] = 0.0;
  132.                 for (j=0; j<N; j++)
  133.                     c[i][k] = c[i][k] + a[i][j] * b[j][k];
  134.             }
  135.  
  136.  
  137.         MPI_Send(&offset, 1, MPI_INT, 0, 2, MPI_COMM_WORLD);
  138.         MPI_Send(&rows, 1, MPI_INT, 0, 2, MPI_COMM_WORLD);
  139.         MPI_Send(&c, rows*N, MPI_INT, 0, 2, MPI_COMM_WORLD);
  140.     }
  141.  
  142.     MPI_Finalize();
  143. }
Advertisement
Add Comment
Please, Sign In to add comment