Матрица MPI с умножением

Я пытаюсь сделать матричное умножение с использованием MPI в C, и мы должны сделать версию, которая является последовательной и одной параллельной версией. Моя параллельная версия не дает правильных ответов, и я не знаю, почему. Я думаю, что я не отправляю правильные сообщения в процессы, но я не могу быть уверен. Профессор просто перешел на разные сообщения send / receive / gather и т. Д., Но на самом деле не стал разбираться в деталях … Я видел много разных примеров, но ни один, ни один не использовал разброс / сбор. Если кто-нибудь может взглянуть на мой код и сказать мне, если что-нибудь всплывет на них, я буду признателен. Я почти уверен, что моя проблема заключается в сообщениях разброса / сбора или фактическом вычислении матрицы c.

#define N 512 #include  #include  #include  #include  #include  #include "mpi.h" print_results(char *prompt, float a[N][N]); int main(int argc, char *argv[]) { int i, j, k, rank, size, tag = 99, blksz, sum = 0; float a[N][N], b[N][N], c[N][N]; char *usage = "Usage: %s file\n"; FILE *fd; double elapsed_time, start_time, end_time; struct timeval tv1, tv2; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (argc < 2) { fprintf (stderr, usage, argv[0]); return -1; } if ((fd = fopen (argv[1], "r")) == NULL) { fprintf (stderr, "%s: Cannot open file %s for reading.\n", argv[0], argv[1]); fprintf (stderr, usage, argv[0]); return -1; } for (i = 0; i < N; i++) for (j = 0; j < N; j++) fscanf (fd, "%f", &a[i][j]); for (i = 0; i < N; i++) for (j = 0; j < N; j++) fscanf (fd, "%f", &b[i][j]); MPI_Barrier(MPI_COMM_WORLD); gettimeofday(&tv1, NULL); MPI_Scatter(a, N*N/size, MPI_INT, a, N*N/size, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(b, N*N, MPI_INT, 0, MPI_COMM_WORLD); if (rank != 0) { for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { for (k = 0; k < N; k++) { sum = sum + a[i][k] * b[k][j]; } c[i][j] = sum; sum = 0; } } } MPI_Gather(c, N*N/size, MPI_INT, c, N*N/size, MPI_INT, 0, MPI_COMM_WORLD); MPI_Finalize(); gettimeofday(&tv2, NULL); elapsed_time = (tv2.tv_sec - tv1.tv_sec) + ((tv2.tv_usec - tv1.tv_usec)/1000000.0); printf ("elapsed_time=\t%lf (seconds)\n", elapsed_time); print_results("C = ", c); } print_results(char *prompt, float a[N][N]) { int i, j; printf ("\n\n%s\n", prompt); for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { printf(" %.2f", a[i][j]); } printf ("\n"); } printf ("\n\n"); } 

обновленная часть кода:

 for (i=0;i<size; i++) { if (rank == i) { for (i = rank*(N/size); i < (rank*(N/size)+(N/size)); i++) { for (j = rank*(N/size); j < (rank*(N/size)+(N/size)); j++) { for (k = rank*N; k < rank*N+N; k++) { sum = sum + a[i][k] * b[k][j]; } c[i][j] = sum; sum = 0; } } } } 

Первой проблемой в вашем коде является то, что size не может делить N Это означает, что пакеты size рассеяния длины N*N/size не обязательно отправляют всю матрицу. Это, наверное, самый сложный момент для правильного.

Как указывает Грег Иноземцев, вторая проблема заключается в том, что вы исключаете процесс 0 из вычисления, хотя он отвечает за часть матрицы.

И еще одна проблема заключается в том, что все операции ввода-вывода (считывание коэффициентов в начале и вывод результатов в конце) должны выполняться только процессом 0.

В другой заметке вы должны указать тип возврата (в данном случае void ) вашей функции print_result , как в декларации вперед, так и в определении.