Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <pthread.h>
- #include <float.h>
- #include <time.h>
- #include <mpi.h>
- #define MASTER 0
- /*
- Crie um programa serial e um programa paralelo com MPI que calculem a multiplica ̧c ̃ao
- de duas matrizes.
- */
- int** a;
- int** b;
- int** c;
- MPI_Status status;
- int main(int argc, char *argv[])
- {
- if( argc != 2)
- {
- printf("PARAMETROS informe o tamanho da matriz\n");
- return -1;
- }
- int N;
- N = atoi(argv[1]); //second parameter is the matrix size
- a = calloc(N, sizeof(int*));
- for(i = 0; i < N; i++) {
- a[i] = calloc(N, sizeof(int));
- }
- b = calloc(N, sizeof(int*));
- for(i = 0; i < N; i++) {
- b[i] = calloc(N, sizeof(int));
- }
- c = calloc(N, sizeof(int*));
- for(i = 0; i < N; i++) {
- c[i] = calloc(N, sizeof(int));
- }
- int numtasks,rc,taskid,numworkers,source,dest,rows,offset,i,j,k;
- struct timeval start, stop;
- MPI_Init(&argc, &argv);
- MPI_Comm_rank(MPI_COMM_WORLD, &taskid);
- MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
- if (numtasks < 2 ) {
- printf("Need at least two MPI tasks. Quitting...\n");
- MPI_Abort(MPI_COMM_WORLD, rc);
- exit(1);
- }
- numworkers = numtasks-1;
- /*---------------------------- master ----------------------------*/
- srand(time(NULL));
- if (taskid == MASTER) {
- for(i=0;i<N;i++){
- for(j=0;j<N;j++){
- a[i][j] = rand(); //initialize with random values
- b[i][j] = rand();
- }
- }
- //Initiate the timer
- clock_t begin = clock();
- // send matrix data to the worker tasks
- // rows = N/numworkers;
- offset = 0;
- //calculate how much rows each thread will process, rounded up
- int rows = (N + (numworkers - 1)) / numworkers;
- for (dest=1; dest<=numworkers; dest++)
- {
- MPI_Send(&offset, 1, MPI_INT, dest, 1, MPI_COMM_WORLD);
- MPI_Send(&rows, 1, MPI_INT, dest, 1, MPI_COMM_WORLD);
- MPI_Send(&a[offset][0], rows*N, MPI_INT,dest,1, MPI_COMM_WORLD);
- MPI_Send(&b, N*N, MPI_INT, dest, 1, MPI_COMM_WORLD);
- offset = offset + rows;
- }
- /* wait for results from all worker tasks */
- for (i=1; i<=numworkers; i++)
- {
- source = i;
- MPI_Recv(&offset, 1, MPI_INT, source, 2, MPI_COMM_WORLD, &status);
- MPI_Recv(&rows, 1, MPI_INT, source, 2, MPI_COMM_WORLD, &status);
- MPI_Recv(&c[offset][0], rows*N, MPI_INT, source, 2, MPI_COMM_WORLD, &status);
- }
- printf("Here is the result matrix:\n");
- for (i=0; i<N; i++) {
- for (j=0; j<N; j++)
- printf("%i ", c[i][j]);
- printf ("\n");
- }
- //end the timer and calculate
- clock_t end = clock();
- double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
- printf("\n\n----This process took %f with matrix size %ix%i and with %d thread(s)----\n\n", time_spent, N, N, qtdThread);
- }
- /*---------------------------- worker----------------------------*/
- if (taskid > MASTER) {
- source = 0;
- MPI_Recv(&offset, 1, MPI_INT, source, 1, MPI_COMM_WORLD, &status);
- MPI_Recv(&rows, 1, MPI_INT, source, 1, MPI_COMM_WORLD, &status);
- MPI_Recv(&a, rows*N, MPI_INT, source, 1, MPI_COMM_WORLD, &status);
- MPI_Recv(&b, N*N, MPI_INT, source, 1, MPI_COMM_WORLD, &status);
- /* Matrix multiplication */
- for (k=0; k<N; k++)
- for (i=0; i<rows; i++) {
- c[i][k] = 0.0;
- for (j=0; j<N; j++)
- c[i][k] = c[i][k] + a[i][j] * b[j][k];
- }
- MPI_Send(&offset, 1, MPI_INT, 0, 2, MPI_COMM_WORLD);
- MPI_Send(&rows, 1, MPI_INT, 0, 2, MPI_COMM_WORLD);
- MPI_Send(&c, rows*N, MPI_INT, 0, 2, MPI_COMM_WORLD);
- }
- MPI_Finalize();
- }
Advertisement
Add Comment
Please, Sign In to add comment