Я пытаюсь выполнить матричное умножение с использованием MPI, и у меня возникают проблемы с получением правильного ответа. Я должен регулярно выполнять матричное умножение с использованием MPI, а затем сравнивать ответы. Если ответы совпадают, то программа вернет The matrices are the same
, в противном случае возвращает сумму матриц и процент между ними. Я полагаю, что проблема связана со смесью того, что я прохожу через MPI, а также с умножением матриц в рабочих процессах.
Это мой код
int main(int argc, char *argv[])
{
int nrows, ncols;
double *aa; /* the A matrix */
double *bb; /* the B matrix */
double *cc1; /* A x B computed using the omp-mpi code you write */
double *cc2; /* A x B computed using the conventional algorithm */
double *AA; //* A matrix read from file*//
double *BB; // B matrix read from file*//
int myid, numprocs, dest, numworker, offset, row, i, j, k;
double starttime, endtime;
MPI_Status status;
/* insert other global variables here */
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
if (argc > 1)
{
char *logFile = argv[3];
FILE *fp = fopen(logFile, "a");
char *f_mat_a = argv[1];
char *f_mat_b = argv[2];
cc2 = malloc(sizeof(double) * nrows * nrows);
numworker = numprocs - 1; // sets up the amount that need to be received from
aa = read_matrix(f_mat_a, &nrows);
bb = read_matrix(f_mat_b, &nrows);
if (myid == 0)
{
//nrows = 0;
// Master Code goes here
//aa = read_matrix(f_mat_a, &nrows);
//bb = read_matrix(f_mat_b, &nrows);
ncols = nrows;
printf("CUR DIMS [%d]\n", nrows);
row = nrows / numworker;
offset = 0;
cc1 = malloc(sizeof(double) * nrows * nrows);
starttime = MPI_Wtime();
/* Insert your master code here to store the product into cc1 */
mmult_slow(cc1, aa, nrows, ncols, bb, ncols, nrows);
endtime = MPI_Wtime();
fprintf(fp, "SLOW %d %f\n", nrows * ncols, (endtime - starttime));
//cc2 = malloc(sizeof(double) * nrows * nrows);
starttime = MPI_Wtime();
for (dest = 1; dest <= numworker; dest++)
{
MPI_Send(&offset, 1, MPI_INT, dest, 2, MPI_COMM_WORLD);
MPI_Send(&row, 1, MPI_INT, dest, 2, MPI_COMM_WORLD);
MPI_Send(aa, row * nrows, MPI_DOUBLE, dest, 3, MPI_COMM_WORLD);
MPI_Send(bb, nrows * nrows, MPI_DOUBLE, dest, 3, MPI_COMM_WORLD);
offset += row;
}
puts("Receiving from workers");
for (dest = 1; dest <= numworker; dest++)
{
MPI_Recv(&offset, 1, MPI_INT, dest, 2, MPI_COMM_WORLD, &status);
MPI_Recv(&row, 1, MPI_INT, dest, 2, MPI_COMM_WORLD, &status);
MPI_Recv(cc2, row * nrows, MPI_DOUBLE, dest, 3, MPI_COMM_WORLD, &status);
}
endtime = MPI_Wtime();
fprintf(fp, "FAST %d %f\n", nrows * ncols, (endtime - starttime));
printf("DEBUGGING MPI CALLS RECV in master: %d %d\n", row, offset);
compare_matrices(cc2, cc1, nrows, nrows);
fclose(fp);
}
else
{
// Slave Code goes here
/*
recv from dest for loop set dest to 0
do matrix multiplication
send the multiplied matrix back
*/
puts("receiving from master");
MPI_Recv(&offset, 1, MPI_INT, 0, 2, MPI_COMM_WORLD, &status);
MPI_Recv(&row, 1, MPI_INT, 0, 2, MPI_COMM_WORLD, &status);
MPI_Recv(aa, row * nrows, MPI_DOUBLE, 0, 3, MPI_COMM_WORLD, &status);
MPI_Recv(bb, nrows * nrows, MPI_DOUBLE, 0, 3, MPI_COMM_WORLD, &status);
int row_inc = row;
for (int i = 0; i < nrows; i++)
{
for (int j = 0; j < row; j++)
{
cc2[row_inc * ncols + j] = 0.0;
for (int k = 0; k < nrows; k++)
{
cc2[i * ncols + j] += aa[i * ncols + k] + bb[k * ncols + j];
}
}
}
mmult_slow(cc2, aa, row, ncols, bb, nrows, ncols);
printf("DEBUGGING MPI CALLS RECV in worker: %d %d\n", row, offset);
MPI_Send(&offset, 1, MPI_INT, 0, 2, MPI_COMM_WORLD);
MPI_Send(&row, 1, MPI_INT, 0, 2, MPI_COMM_WORLD);
MPI_Send(cc2, row * nrows, MPI_DOUBLE, 0, 3, MPI_COMM_WORLD);
}
}
else
{
fprintf(stderr, "Usage matrix_times_vector <size>\n");
}
MPI_Finalize();
return 0;
}
Этоалгоритм для умножения матриц
for (int i = 0; i < nrows; i++)
{
for (int j = 0; j < row; j++)
{
cc2[row_inc * ncols + j] = 0.0;
for (int k = 0; k < nrows; k++)
{
cc2[i * ncols + j] += aa[i * ncols + k] + bb[k * ncols + j];
}
}
}
это вывод, который я получаю
a[0][0] == 176.549932
b[0][0] == 33.2567570659
delta == 143.293174934
relerr == 0.811629737326
a
- это матрица, выполненная через MPI, b
- обычное матричное умножение, delta
разница, relerr
процентная разница