WRITE C CODE USING MPI LIBRARY Matrix Multiplication USING the following test ma
ID: 3918360 • Letter: W
Question
WRITE C CODE USING MPI LIBRARY
Matrix Multiplication USING the following test matrix :
A Matrix multiplication can be written as AB C Matrix A is copied to every processor. Matrix B is divided into blocks, along the rows, and distributed among processors, i.e. the data for matrix B should be distributed among the ranks who perform the actual multiplication. They then send back their results to the rank o for output. Think about how matrix B should be laid out in memory for efficient distribution. Use whatever type of MPI parallelism that you see fit. Use the following text matrix: B(i,j)i+3j Confirm that your algorithm works correctly for small matrices first, then increase the size (and turn off the printing) to get the timingsExplanation / Answer
#include<stdio.h>
#include<mpi.h>
#define NUM_ROWS_A 12
#define NUM_COLUMNS_A 12
#define NUM_ROWS_B 12
#define NUM_COLUMNS_B 12
#define MASTER_TO_SLAVE_TAG 1
#define SLAVE_TO_MASTER_TAG 4
void makeAB();
void printArray();
int rank;
int size;
int i, j, k;
double mat_a[NUM_ROWS_A][NUM_COLUMNS_A];
double mat_b[NUM_ROWS_B][NUM_COLUMNS_B];
double mat_result[NUM_ROWS_A][NUM_COLUMNS_B];
double start_time;
double end_time;
int low_bound;
int upper_bound;
int portion;
MPI_Status status;
MPI_Request request;
int main(int argc, char *argv[])
{
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (rank == 0) {
makeAB();
start_time = MPI_Wtime();
for (i = 1; i < size; i++) {
portion = (NUM_ROWS_A / (size - 1));
low_bound = (i - 1) * portion;
if (((i + 1) == size) && ((NUM_ROWS_A % (size - 1)) != 0)) {
upper_bound = NUM_ROWS_A; //
} else {
upper_bound = low_bound + portion;
}
MPI_Isend(&low_bound, 1, MPI_INT, i, MASTER_TO_SLAVE_TAG, MPI_COMM_WORLD, &request);
MPI_Isend(&upper_bound, 1, MPI_INT, i, MASTER_TO_SLAVE_TAG + 1, MPI_COMM_WORLD, &request);
MPI_Isend(&mat_a[low_bound][0], (upper_bound - low_bound) * NUM_COLUMNS_A, MPI_DOUBLE, i, MASTER_TO_SLAVE_TAG + 2, MPI_COMM_WORLD, &request);
}
}
MPI_Bcast(&mat_b, NUM_ROWS_B*NUM_COLUMNS_B, MPI_DOUBLE, 0, MPI_COMM_WORLD);
if (rank > 0) {
MPI_Recv(&low_bound, 1, MPI_INT, 0, MASTER_TO_SLAVE_TAG, MPI_COMM_WORLD, &status);
MPI_Recv(&upper_bound, 1, MPI_INT, 0, MASTER_TO_SLAVE_TAG + 1, MPI_COMM_WORLD, &status);
MPI_Recv(&mat_a[low_bound][0], (upper_bound - low_bound) * NUM_COLUMNS_A, MPI_DOUBLE, 0, MASTER_TO_SLAVE_TAG + 2, MPI_COMM_WORLD, &status);
for (i = low_bound; i < upper_bound; i++) {
for (j = 0; j < NUM_COLUMNS_B; j++) {
for (k = 0; k < NUM_ROWS_B; k++) {
mat_result[i][j] += (mat_a[i][k] * mat_b[k][j]);
}
}
}
MPI_Isend(&low_bound, 1, MPI_INT, 0, SLAVE_TO_MASTER_TAG, MPI_COMM_WORLD, &request);
MPI_Isend(&upper_bound, 1, MPI_INT, 0, SLAVE_TO_MASTER_TAG + 1, MPI_COMM_WORLD, &request);
MPI_Isend(&mat_result[low_bound][0], (upper_bound - low_bound) * NUM_COLUMNS_B, MPI_DOUBLE, 0, SLAVE_TO_MASTER_TAG + 2, MPI_COMM_WORLD, &request);
}
if (rank == 0) {
for (i = 1; i < size; i++) {
MPI_Recv(&low_bound, 1, MPI_INT, i, SLAVE_TO_MASTER_TAG, MPI_COMM_WORLD, &status);
MPI_Recv(&upper_bound, 1, MPI_INT, i, SLAVE_TO_MASTER_TAG + 1, MPI_COMM_WORLD, &status);
MPI_Recv(&mat_result[low_bound][0], (upper_bound - low_bound) * NUM_COLUMNS_B, MPI_DOUBLE, i, SLAVE_TO_MASTER_TAG + 2, MPI_COMM_WORLD, &status);
}
end_time = MPI_Wtime();
printf(" Running Time = %f ", end_time - start_time);
printArray();
}
MPI_Finalize(); //finalize MPI operations
return 0;
}
void makeAB()
{
for (i = 0; i < NUM_ROWS_A; i++) {
for (j = 0; j < NUM_COLUMNS_A; j++) {
mat_a[i][j] = i + j;
}
}
for (i = 0; i < NUM_ROWS_B; i++) {
for (j = 0; j < NUM_COLUMNS_B; j++) {
mat_b[i][j] = i*j;
}
}
}
void printArray()
{
for (i = 0; i < NUM_ROWS_A; i++) {
printf(" ");
for (j = 0; j < NUM_COLUMNS_A; j++)
printf("%8.2f ", mat_a[i][j]);
}
printf(" ");
for (i = 0; i < NUM_ROWS_B; i++) {
printf(" ");
for (j = 0; j < NUM_COLUMNS_B; j++)
printf("%8.2f ", mat_b[i][j]);
}
printf(" ");
for (i = 0; i < NUM_ROWS_A; i++) {
printf(" ");
for (j = 0; j < NUM_COLUMNS_B; j++)
printf("%8.2f ", mat_result[i][j]);
}
printf(" ");
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.