Reputation: 1
The program have two methods to calculate the matrix product:
one using serial algorithm
//Function to multiply matrices using serial algorithm
int** multiplySerial(int** matrixA, int** matrixB, int rowsA, int colsA, int colsB) {
int** result = new int*[rowsA];
for (int i = 0; i < rowsA; i++) {
result[i] = new int[colsB];
for (int j = 0; j < colsB; j++) {
result[i][j] = 0;
for (int k = 0; k < colsA; k++) {
result[i][j] += matrixA[i][k] * matrixB[k][j];
}
}
}
return result;
}
another one using parallel version.
//Function to multiply matrices using parallel algorithm
int** multiplyParallel(int** matrixA, int** matrixB, int rowsA, int colsA, int colsB, int rank, int size) {
int** result = new int*[rowsA];
for (int i = 0; i < rowsA; i++) {
result[i] = new int[colsB];
for (int j = 0; j < colsB; j++) {
result[i][j] = 0;
}
}
int* sendbuf = new int[colsA];
int* recvbuf = new int[colsA];
MPI_Status status;
for (int k = 0; k < colsA; k++) {
for (int i = 0; i < rowsA; i++) {
sendbuf[i] = matrixA[i][k];
}
MPI_Allgather(sendbuf, rowsA, MPI_INT, recvbuf, rowsA, MPI_INT, MPI_COMM_WORLD);
for (int j = rank; j < colsB; j += size) {
for (int i = 0; i < rowsA; i++) {
result[i][j] = 0;
for (int k = 0; k < colsA; k++) {
result[i][j] += recvbuf[k] * matrixB[k][j];
}
}
}
}
delete[] sendbuf;
delete[] recvbuf;
return result;
}
Both take two same matrices and return the resulting matrix product. The methods are tested with some large randomly generated matrices here is the random matrix generator function
// Function to generate random matrices
void generateRandomMatrix(int** matrix, int rows, int columns) {
srand(time(NULL));
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
matrix[i][j] = rand() % 10;
}
}
}
and compare the results for serial and parallel versions. and lastly I Calculated the speedup and efficiency of parallel version.
here is the memory deallocation for memory management
// Function to deallocate memory for a matrix
void deallocateMatrix(int** matrix, int rows) {
for (int i = 0; i < rows; i++) {
delete[] matrix[i];
}
delete[] matrix;
}
here is the Main method
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <mpi.h>
using namespace std;
int main(int argc, char* argv[]) {
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
int rowsA = 10; // Number of rows in matrix A
int colsA = 10; // Number of columns in matrix A
int colsB = 10; // Number of columns in matrix B
// Generate random matrices A and B
int** matrixA = nullptr;
int** matrixB = nullptr;
if (rank == 0) {
matrixA = new int*[rowsA];
matrixB = new int*[colsA];
for (int i = 0; i < rowsA; i++) {
matrixA[i] = new int[colsA];
}
for (int i = 0; i < colsA; i++) {
matrixB[i] = new int[colsB];
}
generateRandomMatrix(matrixA, rowsA, colsA);
generateRandomMatrix(matrixB, colsA, colsB);
}
// Broadcast matrix B to all processes
MPI_Bcast(&matrixB[0][0], colsA * colsB, MPI_INT, 0, MPI_COMM_WORLD);
// Calculate the product using serial algorithm
double startTime = MPI_Wtime();
int** serialResult = multiplySerial(matrixA, matrixB, rowsA, colsA, colsB);
double endTime = MPI_Wtime();
double serialTime = endTime - startTime;
// Calculate the product using parallel algorithm
startTime = MPI_Wtime();
int** parallelResult = multiplyParallel(matrixA, matrixB, rowsA, colsA, colsB, rank, size);
endTime = MPI_Wtime();
double parallelTime = endTime - startTime;
// Compare the results of serial and parallel algorithms
bool isEqual = true;
if (rank == 0) {
for (int i = 0; i < rowsA; i++) {
for (int j = 0; j < colsB; j++) {
if (serialResult[i][j] != parallelResult[i][j]) {
isEqual = false;
break;
}
}
if (!isEqual) {
break;
}
}
}
// Print results
if (rank == 0) {
if (isEqual) {
cout << "Results are equal." << endl;
} else {
cout << "Results are not equal." << endl;
}
double speedup = serialTime / parallelTime;
double efficiency = speedup / size;
cout << "Serial Time: " << serialTime << " seconds" << endl;
cout << "Parallel Time: " << parallelTime << " seconds" << endl;
cout << "Speedup: " << speedup << endl;
cout << "Efficiency: " << efficiency << endl;
deallocateMatrix(matrixA, rowsA);
deallocateMatrix(matrixB, colsA);
}
deallocateMatrix(serialResult, rowsA);
deallocateMatrix(parallelResult, rowsA);
MPI_Finalize();
return 0;
}
these are the problems with the code first the result matrices are not the same result not equal here is an example second when i run the code with multiple processors it crashes when i run it with this command mpiexec -n 2 ./matrix_multiplication
Upvotes: 0
Views: 182