Умножение матриц с использованием MPI - PullRequest
0 голосов
/ 29 октября 2019

Я пытаюсь выполнить матричное умножение с использованием 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 процентная разница

...