Умножение неквадратных матриц с использованием Scatter and Gather (MPI) 3 - PullRequest
0 голосов
/ 06 мая 2020

Я новичок в параллельном вычислении произведения между матрицами, которые не являются квадратными. Я думал сделать это с помощью "Scatter" и "Gather". Обычно размеры матрицы определяются путем чтения из файла, но в данном случае я установил минимальное значение, так как мне придется иметь дело с большими матрицами. К сожалению, результат оказался не таким, как я надеялся, поскольку программа не работает (ошибка сегментации). Думаю, я хорошо рассуждал с точки зрения псевдокода, но при его создании у меня возникли некоторые проблемы, и я хотел получить как можно более простое объяснение, чтобы оно работало. Еще я хотел узнать, как запустить программу, даже если матрица не делится на количество выбранных процессов. Спасибо

int main(int argc, char **argv) {

int id, nproc;


double **L, **R, **B;
int sum = 0;

int nU, nI, nF;
nU = 3;
nI = 5;
nF = 2;

MPI_Init(&argc, &argv);

MPI_Comm_size(MPI_COMM_WORLD, &nproc);
MPI_Comm_rank(MPI_COMM_WORLD, &id);

double L_Rows[nU/nproc][nF];
double B_Rows[nU/nproc][nI];

if(!id){

    L = new double*[nU]();
    for(int i=0; i<nU; i++)
        L[i] = new double[nF]();

    R = new double*[nF]();
    for(int i=0; i<nU; i++)
        R[i] = new double[nI]();

    B = new double*[nU]();
    for(int i=0; i<nU; i++)
        B[i] = new double[nI]();

    random_fill_LR(L, R, nU, nI, nF);
}

// Number of rows to send to other process
int count = (nU * nF)/nproc;

// Send row of matrix L to other process
MPI_Scatter(L, count, MPI_DOUBLE, L_Rows, count, MPI_DOUBLE, 0, MPI_COMM_WORLD);

// Send matrix R to ohter process
MPI_Bcast(R, nF*nI, MPI_DOUBLE, 0, MPI_COMM_WORLD);

MPI_Barrier(MPI_COMM_WORLD);

// Debug
for(int i=0; i<(nU/nproc); i++)
    for(int j=0; j<nF; j++)
        std::cout<<"Process "<<id<<" L_Rows ["<<i<<"]["<<j<<"] = "<<L_Rows[i][j]<<std::endl;

// Matrix product B = L * R
for(int k=0; k< nU/nproc; k++){
    for(int i=0; i<nU; i++){
        for(int j=0; j<nF; j++){
            sum += L_Rows[k][j] * R[j][i];
        }
        B_Rows[k][i] = sum;
        sum = 0;
    }
}

// Final matrix B
MPI_Gather(B_Rows, count, MPI_DOUBLE, B, count, MPI_DOUBLE, 0, MPI_COMM_WORLD);

MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();

// Print matrix B
if(!id){

    std::cout<<"Final matrix"<<std::endl;   

    for(int i=0; i<nU; i++){
        for(int j=0; j<nI; j++){
            std::cout<<B[i][j]<<" ";
        }
        std::cout<<std::endl;
    }
    std::cout<<std::endl;

}

return 0;

}

...