Program pracuje podobne ako transponovanie matice. Máme dané dve matice o veľkosti 4x4 a jednu maticu (vektor) o veľkosti 1x4. Prvá matica A je rozdelená na 4 riadky o veľkosti 1x4. Druhá matica B je veľkosti 4x4. Násobíme maticu A maticou B, čím vznikne matica C, tiež o veľkosti 4x4. Nenásobíme naraz všetky riadky, ale každý riadok si rozdelíme na 4 kroky. Teda násobením prvého riadku matice A (1x4) násobíme 4 stĺpce matice B, čím vznikne prvý riadok matice C (1x4). A takto pokračujeme s ostatnými riadkami. Opäť kvôli predbiehaniu procesov je potrebné vypočítané matice od jednotlivých procesov označiť číselne riadkami. Riešenie problému nie je škálovateľné, teda vyžaduje na svoje správne vyriešenie presne 5 procesov. Program obsahuje aj medzikroky, kde sa počíta doba za akú dané procesy vypočítali čiastkové úseky kódu.
Kód v cpp
#include <stdio.h>
#include <mpi.h>
void Matrix_Mult(int a1[][4], int a2[][4], int a3[][4])
{
int i = 0;
int j = 0;
int k = 0;
for(i = 0; i < 1; i++)
{
for( j = 0; j < 4; j++)
{
for( k = 0; k < 4; k++)
{
a3[i][j] += a1[i][k] * a2[k][j];
}
}
}
}
void PrintMatrix(int ar[][4])
{
int i = 0;
int j = 0;
for(i = 0; i < 1; i++)
{
for( j = 0; j < 4; j++)
{
printf("%4d", ar[i][j]);
}
putchar('\n');
}
}
void PrintMatrix_N(int ar[][4])
{
int i = 0;
int j = 0;
for(i = 0; i < 4; i++)
{
for( j = 0; j < 4; j++)
{
printf("%4d", ar[i][j]);
}
putchar('\n');
}
}
int main(int argc, char *argv[])
{
int size, rank;
double t1, t2;
int A1[1][4] = {
{5, 7, 8, 9}
},
A2[1][4] = {
{1, 2, 3, 4}
},
A3[1][4] = {
{9, 8, 8, 7}
},
A4[1][4] = {
{1, 1, 2, 1}
},
B[4][4] = {
{1, 1, 1, 2},
{2, 3, 4, 5},
{7, 7, 8, 1},
{0, 4, 5, 0}
},
C[1][4] = {
{0, 0, 0, 0}
},
C_vzor[4][4] = {
{75, 118, 142, 53},
{26, 44, 53, 15},
{81, 117, 140, 66},
{17, 22, 26, 9}
};
MPI_Status status;
MPI_Request request;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if(size == 5)
{
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Bcast(B, 16, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(C, 4, MPI_INT, 0, MPI_COMM_WORLD);
if(rank == 0)
{
t1 = MPI_Wtime();
printf("\n\nMatica A:\n");
PrintMatrix(A1);PrintMatrix(A2);PrintMatrix(A3);PrintMatrix(A4);
printf("\n\nMatica B:\n");
PrintMatrix_N(B);
printf("\n\nMatica C - vzorova:\n");
PrintMatrix_N(C_vzor);
printf("\n\n\nVysledok:\n");
MPI_Send(A1, 4, MPI_INT, 1, 01, MPI_COMM_WORLD);
MPI_Send(A2, 4, MPI_INT, 2, 02, MPI_COMM_WORLD);
MPI_Send(A3, 4, MPI_INT, 3, 03, MPI_COMM_WORLD);
MPI_Send(A4, 4, MPI_INT, 4, 04, MPI_COMM_WORLD);
t2 = MPI_Wtime();
printf("\nvypocet casu (rank 0): %f\n", t2-t1);
fflush(stdout);
}
else if(rank == 1)
{
t1 = MPI_Wtime();
MPI_Recv(A1, 4, MPI_INT, 0, 01, MPI_COMM_WORLD, &status);
Matrix_Mult(A1, B, C);
printf("\n\n1.riadok:\n");
PrintMatrix(C);
t2 = MPI_Wtime();
printf("\nvypocet casu (rank 1): %f\n", t2-t1);
fflush(stdout);
}
else if(rank == 2)
{
t1 = MPI_Wtime();
MPI_Recv(A2, 4, MPI_INT, 0, 02, MPI_COMM_WORLD, &status);
Matrix_Mult(A2, B, C);
printf("\n\n2.riadok:\n");
PrintMatrix(C);
t2 = MPI_Wtime();
printf("\nvypocet casu (rank 2): %f\n", t2-t1);
fflush(stdout);
}
else if(rank == 3)
{
t1 = MPI_Wtime();
MPI_Recv(A3, 4, MPI_INT, 0, 03, MPI_COMM_WORLD, &status);
Matrix_Mult(A3, B, C);
printf("\n\n3.riadok:\n");
PrintMatrix(C);
t2 = MPI_Wtime();
printf("\nvypocet casu (rank 3): %f\n", t2-t1);
fflush(stdout);
}
else if(rank == 4)
{
t1 = MPI_Wtime();
MPI_Recv(A4, 4, MPI_INT, 0, 04, MPI_COMM_WORLD, &status);
Matrix_Mult(A4, B, C);
printf("\n\n4.riadok:\n");
PrintMatrix(C);
t2 = MPI_Wtime();
printf("\nvypocet casu (rank 4): %f\n", t2-t1);
fflush(stdout);
}
}
MPI_Finalize();
return(0);
}







