I am a beginner in MPI programing and I am trying to do a matrix-vector multiplication (Ax=b).
I divided A matrix into two matrix A1 and A2.
I need to calculate Ax=b such a way that the process number 1 does the A1 * x multiplication and gives C1 and process number 2 does the A2 * x multiplication and gives C2 and at the end the sum of C1 and C2 will be wrapped up in C. when I run the code through cmd it stops working and I don't know what is the problem. I would be really grateful if you could help me to find out what is the problem in code, here is my code,
What I have tried:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<fstream>
#include<vector>
#include<iterator>
#include<sstream>
#include<string>
#include<cstdlib>
#include<cmath>
#include<stdio.h>
#include<conio.h>
#include<algorithm>
#include<ctime>
#include<iomanip>
#include<mpi.h>
#include<time.h>
#include<assert.h>
using namespace std;
void Initialise(int **res, int rows, int cols);
void Multiply(int **res, int **A, int **B, int aRows, int aCols, int bRows, int bCols);
void timestamp();
int main(int argc,char **argv)
{
int id, p;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &id);
MPI_Comm_size(MPI_COMM_WORLD, &p);
cout << p << endl;
char processor_name[MPI_MAX_PROCESSOR_NAME];
int name_len;
MPI_Get_processor_name(processor_name, &name_len);
if (id == 0)
{
wtime = MPI_Wtime();
int aRows = 3;
int aCols = 3;
int bRows = 3;
int bCols = 1;
int** A = new int*[aRows];
for (int i = 0; i < aRows; i++)
{
A[i] = new int[aCols];
}
int** A1 = new int*[aRows];
for (int i = 0; i < aRows; i++)
{
A1[i] = new int[aCols];
}
int** A2 = new int*[aRows];
for (int i = 0; i < aRows; i++)
{
A2[i] = new int[aCols];
}
int** B = new int*[bRows];
for (int i = 0; i < bRows; i++)
{
B[i] = new int[bCols];
}
A[0][0] = 3;
A[0][1] = 2;
A[0][2] = 5;
A[1][0] = 4;
A[1][1] = 3;
A[1][2] = 1;
A[2][0] = 2;
A[2][1] = 4;
A[2][2] = 2;
B[0][0] = 2;
B[1][0] = 1;
B[2][0] = 3;
A1[0][0] = 1;
A1[0][1] = 2;
A1[0][2] = 3;
A1[1][0] = 3;
A1[1][1] = 2;
A1[1][2] = 1;
A1[2][0] = 1;
A1[2][1] = 2;
A1[2][2] = 0;
A2[0][0] = 2;
A2[0][1] = 0;
A2[0][2] = 2;
A2[1][0] = 1;
A2[1][1] = 1;
A2[1][2] = 0;
A2[2][0] = 1;
A2[2][1] = 2;
A2[2][2] = 2;
B[0][0] = 2;
B[1][0] = 1;
B[2][0] = 3;
int** C;
C = new int*[aRows];
for (int i = 0; i < aRows; i++)
{
C[i] = new int[bCols];
}
int** C1;
C1 = new int*[aRows];
for (int i = 0; i < aRows; i++)
{
C1[i] = new int[bCols];
}
int** C2;
C2 = new int*[aRows];
for (int i = 0; i < aRows; i++)
{
C2[i] = new int[bCols];
}
Multiply(C, A, B, aRows, aCols, bRows, bCols);
for (int i = 0; i < aRows; i++)
{
for (int j = 0; j < bCols; j++)
{
std::cout << C[i][j] << ' ';
}
std::cout << '\n';
}
MPI_Send(&aRows, 1, MPI_INT, 1, 1, MPI_COMM_WORLD);
MPI_Send(&aCols, 1, MPI_INT, 1, 2, MPI_COMM_WORLD);
MPI_Send(&bRows, 1, MPI_INT, 1, 3, MPI_COMM_WORLD);
MPI_Send(&bCols, 1, MPI_INT, 1, 4, MPI_COMM_WORLD);
MPI_Send(&aRows, 1, MPI_INT, 2, 5, MPI_COMM_WORLD);
MPI_Send(&aCols, 1, MPI_INT, 2, 6, MPI_COMM_WORLD);
MPI_Send(&bRows, 1, MPI_INT, 2, 7, MPI_COMM_WORLD);
MPI_Send(&bCols, 1, MPI_INT, 2, 8, MPI_COMM_WORLD);
MPI_Send(&A1, aRows*aCols, MPI_INT, 1, 9, MPI_COMM_WORLD);
MPI_Send(&B , bRows*bCols, MPI_INT, 1, 10, MPI_COMM_WORLD);
MPI_Send(&A2, aRows*aCols, MPI_INT, 2, 11, MPI_COMM_WORLD);
MPI_Send(&B, bRows*bCols, MPI_INT, 2, 12, MPI_COMM_WORLD);
}
for (id=1;id<3;id++)
{
if (id == 1)
{
int aRows, aCols, bRows, bCols;
MPI_Recv(&aRows, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
printf("receive data:%d", aRows);
MPI_Recv(&aCols, 1, MPI_INT, 0, 2, MPI_COMM_WORLD, &status);
printf("receive data:%d", aCols);
MPI_Recv(&bRows, 1, MPI_INT, 0, 3, MPI_COMM_WORLD, &status);
printf("receive data:%d", bRows);
MPI_Recv(&bCols, 1, MPI_INT, 0, 4, MPI_COMM_WORLD, &status);
printf("receive data:%d", bCols);
int** A1 = new int*[aRows];
for (int i = 0; i < aRows; i++)
{
A1[i] = new int[aCols];
}
int** B = new int*[bRows];
for (int i = 0; i < bRows; i++)
{
B[i] = new int[bCols];
}
int** C1 = new int*[bRows];
for (int i = 0; i < bRows; i++)
{
C1[i] = new int[bCols];
}
MPI_Recv(&A1, aRows*aCols, MPI_INT, 0, 9, MPI_COMM_WORLD, &status);
printf("receive data:%d", A1);
MPI_Recv(&B , aRows*aCols, MPI_INT, 0, 10, MPI_COMM_WORLD, &status);
printf("receive data:%d", B);
Multiply(C1, A1, B, aRows, aCols, bRows, bCols);
for (int i = 0; i < aRows; i++)
{
for (int j = 0; j < bCols; j++)
{
cout << C1[i][j] << endl;
}
}
}
else
{
int aRows, aCols, bRows, bCols;
MPI_Recv(&aRows, 1, MPI_INT, 0, 5, MPI_COMM_WORLD, &status);
MPI_Recv(&aCols, 1, MPI_INT, 0, 6, MPI_COMM_WORLD, &status);
MPI_Recv(&bRows, 1, MPI_INT, 0, 7, MPI_COMM_WORLD, &status);
MPI_Recv(&bCols, 1, MPI_INT, 0, 8, MPI_COMM_WORLD, &status);
int** A2 = new int*[aRows];
for (int i = 0; i < aRows; i++)
{
A2[i] = new int[aCols];
}
int** B = new int*[bRows];
for (int i = 0; i < bRows; i++)
{
B[i] = new int[bCols];
}
int** C2 = new int*[bRows];
for (int i = 0; i < bRows; i++)
{
C2[i] = new int[bCols];
}
MPI_Recv(&A2, aRows*aCols, MPI_INT, 0, 11, MPI_COMM_WORLD, &status);
printf("receive data:%d", A2);
MPI_Recv(&B , aRows*aCols, MPI_INT, 0, 12, MPI_COMM_WORLD, &status);
printf("receive data:%d", B);
MPI_Status status;
Multiply(C2, A2, B, aRows, aCols, bRows, bCols);
for (int i = 0; i < aRows; i++)
{
for (int j = 0; j < bCols; j++)
{
cout << C2[i][j] << endl;
}
}
}
}
MPI_Finalize();
return 0;
}
void Multiply(int **res, int **A, int **B, int aRows, int aCols, int bRows, int bCols)
{
if (aCols != bRows)
return;
for (int i = 0; i < aRows; i++)
{
for (int j = 0; j < bCols; j++)
{
res[i][j] = 0;
for (int k = 0; k < aCols; k++)
{
res[i][j] += A[i][k] * B[k][j];
}
}
}
}
void Initialise(int **res, int rows, int cols)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
res[i][j] = 0;
}
}
}