#c #matrix #vector #mpi
#c #матрица #вектор #mpi
Вопрос:
У меня есть задача для моего текущего класса MPI, где я должен умножить матрицу 2×3
1 2 3
4 5 6
на вектор 3×1 7 8 9
Мне сказали предположить, что у нас есть только 2 процессора.
У меня есть следующая реализация, но я захожу в тупик и не могу понять, почему.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <mpi.h>
int main(void)
{
int comm_sz; /* number of processes*/
int my_rank; /* my process rank */
int m, n;
double* Matrix;
double* Vector;
double* Resu<
double* localMatrix;
MPI_Comm comm;
FILE *fptr = fopen("mv-data.txt", "r");
MPI_Init(NULL, NULL);
comm = MPI_COMM_WORLD;
MPI_Comm_size(comm, amp;comm_sz);
MPI_Comm_rank(comm, amp;my_rank);
if (my_rank == 0)
{
fscanf(fptr,"%d", m);
fscanf(fptr, "%d", n);
}
MPI_Bcast(m, 1, MPI_INT, 0, comm);
MPI_Bcast(n,1,MPI_INT, 0, comm);
if (my_rank==0)
{
Matrix = malloc(m*n * sizeof(double));
for(int i = 0; i<m; i )
for(int j=0; j< n; j )
fscanf(fptr, "%lf", amp;Matrix[i*n j]);
Vector = malloc(n*sizeof(double));
for (int i = 0; i < n; i )
fscanf(fptr,"%lf", amp;Vector[i]);
Result = malloc(m * sizeof(double));
for (int row = 0; row < m; row )
{
localMatrix = malloc(m*sizeof(double));
for(int column = 0; column < n; column )
localMatrix[column] = Matrix[row*n column];
MPI_Send(localMatrix, n, MPI_DOUBLE, row % comm_sz, 0, comm);
}
}
MPI_Bcast(Vector, n, MPI_DOUBLE, 0,comm);
MPI_Recv(localMatrix, n, MPI_DOUBLE, 0, 0, comm, MPI_STATUS_IGNORE);
Result[my_rank] = 0;
for(int i = 0; i < n; i )
{
Result[my_rank] = localMatrix[i] * Vector[i];
}
if (my_rank = 0)
{
for (int i = 0; i < m; i )
printf("%d", Result[i]);
}
return 0;
}
Я не могу придумать никакого другого способа отправить этот процесс на главный процессор, не вызывая взаимоблокировки.
Любая помощь будет оценена.
Комментарии:
1. Используйте коллективные операции: разбросайте матрицу, передайте вектор и соберите результат.
if(tank == 0)
останется только в самом начале и в самом конце вашего кода.
Ответ №1:
В rank 0
, вы используете блокировку MPI_Send
. Затем другие процессы вызывают коллектив MPI_Bcast
вместо сопоставления MPI_Recv
. Это может привести к взаимоблокировке (буферизация может происходить внутри MPI_Send
, а также может избежать взаимоблокировки). Смотрите ниже:
if (my_rank==0)
{
for (int row = 0; row < m; row )
{
MPI_Send(localMatrix, n, MPI_DOUBLE, row % comm_sz, 0, comm);
}
}
MPI_Bcast(Vector, n, MPI_DOUBLE, 0,comm); // COLLECTIVE - PROCESS MAY GET STUCK HERE
MPI_Recv(localMatrix, n, MPI_DOUBLE, 0, 0, comm, MPI_STATUS_IGNORE);
Вы можете попробовать что-то вроде этого,
if (my_rank==0)
{
for (int row = 0; row < m; row )
{
MPI_Send(localMatrix, n, MPI_DOUBLE, row % comm_sz, 0, comm);
}
} else
{
MPI_Recv(localMatrix, n, MPI_DOUBLE, 0, 0, comm, MPI_STATUS_IGNORE);
}
MPI_Bcast(Vector, n, MPI_DOUBLE, 0,comm);
что определенно позволит избежать взаимоблокировки. Кроме того, в вашем коде есть проблемы. Например,
MPI_Recv(localMatrix, n, MPI_DOUBLE, 0, 0, comm, MPI_STATUS_IGNORE);
вызовет ошибку сегментации, поскольку память для localMatrix
не выделена. Доступ Result
, а также Vector
также вызывает ошибку сегментации, потому что вы не выделили для него память в других процессах (например: ранги от 1 до N-1), кроме ранга 0.