denisb413

Untitled

Nov 23rd, 2017
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.67 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 != 3)
  26.     {
  27.         printf("PARAMETROS informe a quantidade de threads na ordem\n");
  28.         return -1;
  29.     }
  30.  
  31.     // AQUI TENHO A QTDE DE THREADS
  32.     pthread_t* thread; // thread
  33.     int qtdThread = atoi(argv[1]); // qtd de thread
  34.  
  35.     int N;
  36.     N = atoi(argv[2]); //second parameter is the matrix size
  37.  
  38.     matrixA = calloc(N, sizeof(int*));
  39.     for(i = 0; i < N; i++) {
  40.         matrixA[i] = calloc(N, sizeof(int));
  41.     }
  42.  
  43.     matrixB = calloc(N, sizeof(int*));
  44.     for(i = 0; i < N; i++) {
  45.         matrixB[i] = calloc(N, sizeof(int));
  46.     }
  47.  
  48.     matrixC = calloc(N, sizeof(int*));
  49.     for(i = 0; i < N; i++) {
  50.         matrixC[i] = calloc(N, sizeof(int));
  51.     }
  52.  
  53.     int numtasks,rc,taskid,numworkers,source,dest,rows,offset,i,j,k;
  54.     struct timeval start, stop;
  55.  
  56.     MPI_Init(&argc, &argv);
  57.     MPI_Comm_rank(MPI_COMM_WORLD, &taskid);
  58.     MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
  59.  
  60.     if (numtasks < 2 ) {
  61.         printf("Need at least two MPI tasks. Quitting...\n");
  62.         MPI_Abort(MPI_COMM_WORLD, rc);
  63.         exit(1);
  64.     }
  65.     numworkers = numtasks-1;
  66.  
  67.     /*---------------------------- master ----------------------------*/
  68.     srand(time(NULL));
  69.  
  70.     if (taskid == MASTER) {
  71.  
  72.         for(i=0;i<N;i++){
  73.             for(j=0;j<N;j++){
  74.                 matrixA[i][j] = rand(); //initialize with random values
  75.                 matrixB[i][j] = rand();
  76.             }
  77.         }
  78.  
  79.         //Initiate the timer
  80.         clock_t begin = clock();
  81.  
  82.         //  send matrix data to the worker tasks
  83.         // rows = N/numworkers;
  84.         offset = 0;
  85.  
  86.         //calculate how much rows each thread will process, rounded up
  87.        
  88.         int rows = (N + (numworkers - 1)) / numworkers;
  89.  
  90.         for (dest=1; dest<=numworkers; dest++)
  91.         {
  92.             MPI_Send(&offset, 1, MPI_INT, dest, 1, MPI_COMM_WORLD);
  93.             MPI_Send(&rows, 1, MPI_INT, dest, 1, MPI_COMM_WORLD);
  94.             MPI_Send(&a[offset][0], rows*N, MPI_INT,dest,1, MPI_COMM_WORLD);
  95.             MPI_Send(&b, N*N, MPI_INT, dest, 1, MPI_COMM_WORLD);
  96.             offset = offset + rows;
  97.         }
  98.  
  99.         /* wait for results from all worker tasks */
  100.         for (i=1; i<=numworkers; i++)
  101.         {
  102.             source = i;
  103.             MPI_Recv(&offset, 1, MPI_INT, source, 2, MPI_COMM_WORLD, &status);
  104.             MPI_Recv(&rows, 1, MPI_INT, source, 2, MPI_COMM_WORLD, &status);
  105.             MPI_Recv(&c[offset][0], rows*N, MPI_INT, source, 2, MPI_COMM_WORLD, &status);
  106.         }
  107.  
  108.         printf("Here is the result matrix:\n");
  109.         for (i=0; i<N; i++) {
  110.             for (j=0; j<N; j++)
  111.             printf("%i   ", c[i][j]);
  112.             printf ("\n");
  113.         }
  114.  
  115.         //end the timer and calculate
  116.         clock_t end = clock();
  117.         double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
  118.  
  119.         printf("\n\n----This process took %f with matrix size %ix%i and with %d thread(s)----\n\n", time_spent, N, N, qtdThread);
  120.  
  121.  
  122.     }
  123.  
  124.     /*---------------------------- worker----------------------------*/
  125.     if (taskid > MASTER) {
  126.         source = 0;
  127.         MPI_Recv(&offset, 1, MPI_INT, source, 1, MPI_COMM_WORLD, &status);
  128.         MPI_Recv(&rows, 1, MPI_INT, source, 1, MPI_COMM_WORLD, &status);
  129.         MPI_Recv(&a, rows*N, MPI_INT, source, 1, MPI_COMM_WORLD, &status);
  130.         MPI_Recv(&b, N*N, MPI_INT, source, 1, MPI_COMM_WORLD, &status);
  131.  
  132.         /* Matrix multiplication */
  133.         for (k=0; k<N; k++)
  134.             for (i=0; i<rows; i++) {
  135.                 c[i][k] = 0.0;
  136.                 for (j=0; j<N; j++)
  137.                     c[i][k] = c[i][k] + a[i][j] * b[j][k];
  138.             }
  139.  
  140.  
  141.         MPI_Send(&offset, 1, MPI_INT, 0, 2, MPI_COMM_WORLD);
  142.         MPI_Send(&rows, 1, MPI_INT, 0, 2, MPI_COMM_WORLD);
  143.         MPI_Send(&c, rows*N, MPI_INT, 0, 2, MPI_COMM_WORLD);
  144.     }
  145.  
  146.     MPI_Finalize();
  147. }
Advertisement
Add Comment
Please, Sign In to add comment