Skip to content

Instantly share code, notes, and snippets.

@denisb411
Created December 5, 2017 22:52
Show Gist options
  • Save denisb411/9da8e66fb00d578151d19c9ac5f4634c to your computer and use it in GitHub Desktop.
Save denisb411/9da8e66fb00d578151d19c9ac5f4634c to your computer and use it in GitHub Desktop.
#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
// #define N 4 /* number of rows and columns in matrix */
/*
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
// N = 4;
int numtasks,rc,taskid,numworkers,source,dest,rows,offset,i,j,k;
struct timeval start, stop;
// double** a = (double **)malloc(N * sizeof(double*));
// for(i = 0; i < N; i++) {
// a[i] = (double *)malloc(N * sizeof(double));
// }
// double** b = (double **)malloc(N * sizeof(double*));
// for(i = 0; i < N; i++) {
// b[i] = (double **)malloc(N * sizeof(double*));
// }
// double** c = (double **)malloc(N * sizeof(double*));
// for(i = 0; i < N; i++) {
// c[i] = (double **)malloc(N * sizeof(double*));
// }
int a[N][N],b[N][N],c[N][N];
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;
for(i=0;i<N;i++){
for(j=0;j<N;j++){
a[i][j] = rand(); //initialize with random values
b[i][j] = rand();
}
}
/*---------------------------- master ----------------------------*/
srand(time(NULL));
if (taskid == MASTER) {
//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;
// int rows = N/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("%d ", 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 tasks(s)----\n\n", time_spent, N, N, numtasks);
}
/*---------------------------- 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();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment