使用Mpi_散射和Mpi_聚集的矩阵乘法

使用Mpi_散射和Mpi_聚集的矩阵乘法,mpi,matrix-multiplication,Mpi,Matrix Multiplication,我是mpi编程的新手。我在写矩阵乘法。浏览了关于使用分散和聚集例程进行矩阵乘法的帖子。 我试着在上面的帖子中修改代码,如下所示 #define N 4 #include <stdio.h> #include <math.h> #include <sys/time.h> #include <stdlib.h> #include <stddef.h> #include "mpi.h" void print_results(char *p

我是mpi编程的新手。我在写矩阵乘法。浏览了关于使用分散和聚集例程进行矩阵乘法的帖子。 我试着在上面的帖子中修改代码,如下所示

#define N 4
#include <stdio.h>
#include <math.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stddef.h>
#include "mpi.h"


void print_results(char *prompt, int a[N][N]);

int main(int argc, char *argv[])
{
    int i, j, k, rank, size, tag = 99, blksz, sum = 0;
    int a[N][N]={{1,2,3,4},{5,6,7,8},{9,1,2,3},{4,5,6,7,}};
    int b[N][N]={{1,2,3,4},{5,6,7,8},{9,1,2,3},{4,5,6,7,}};
    int c[N][N];
    int aa[N],cc[N];

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    //scatter rows of first matrix to different processes     
    MPI_Scatter(a, N*N/size, MPI_INT, aa, N*N/size, MPI_INT,0,MPI_COMM_WORLD);

    //broadcast second matrix to all processes
    MPI_Bcast(b, N*N, MPI_INT, 0, MPI_COMM_WORLD);

    MPI_Barrier(MPI_COMM_WORLD);

          //perform vector multiplication by all processes
          for (i = 0; i < N; i++)
            {
                    for (j = 0; j < N; j++)
                    {
                            sum = sum + aa[j] * b[i][j];                
                    }
                    cc[i] = sum;
                    sum = 0;
            }

    MPI_Gather(cc, N*N/size, MPI_INT, c, N*N/size, MPI_INT, 0, MPI_COMM_WORLD);

    MPI_Barrier(MPI_COMM_WORLD);        
    MPI_Finalize();
    print_results("C = ", c);
}

void print_results(char *prompt, int 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(" %d", a[i][j]);
            }
            printf ("\n");
    }
    printf ("\n\n");
}
对于上述程序,我得到以下不正确的输出

C = 
 0 0 -562242168 32766
 1 0 4197933 0
 -562242176 32766 0 0
 4197856 0 4196672 0

C = 
 0 0 -1064802792 32765
 1 0 4197933 0
 -1064802800 32765 0 0
 4197856 0 4196672 0

C = 
 30 70 29 60
 70 174 89 148
 29 89 95 74
 60 148 74 126

C = 
 0 0 -1845552920 32765
 1 0 4197933 0
 -1845552928 32765 0 0
 4197856 0 4196672 0
我有以下疑问 1.为什么所有过程都会打印结果矩阵C。它是 应该只通过主流程打印。 2.为什么打印的结果不正确


这方面的更正和帮助将不胜感激。

所有进程都将打印结果矩阵
c
,因为每个进程都执行函数
void print\u results(char*prompt,int a[N][N])
。由于您是在级别为0的进程上进行收集,因此在调用
print_results(…)
函数之前添加一条语句
if(rank==0)
。此外,由于以下情况中的回路逻辑错误,结果不正确:

                for (j = 0; j < N; j++)
                {
                        sum = sum + aa[j] * b[i][j];                
                }
然后
c=

C = 
 54 37 47 57

 130 93 119 145

 44 41 56 71

 111 79 101 123 

调用mpi_finalize并不表示所有mpi进程都像OpenMP一样终止

在大多数mpi实现中,所有进程都在mpi_初始化之前和mpi_完成之后执行指令


一个好的做法是在MPI_Init之前和MPI_完成之后什么也不做。

如果您选择不广播
b
,那么您可以选择不散布
A
(并声明
int*aa
,并让它指向
A
的右行)。而且,
c
只需在等级
0
上声明/分配。
                for (j = 0; j < N; j++)
                {
                        sum = sum + aa[j] * b[j][i];                
                }
#define N 4
#include <stdio.h>
#include <math.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stddef.h>
#include "mpi.h"


void print_results(char *prompt, int a[N][N]);

int main(int argc, char *argv[])
{
    int i, j, k, rank, size, tag = 99, blksz, sum = 0;
    int a[N][N]={{1,2,3,4},{5,6,7,8},{9,1,2,3},{4,5,6,7,}};
    int b[N][N]={{1,2,3,4},{5,6,7,8},{9,1,2,3},{4,5,6,7,}};
    int c[N][N];
    int aa[N],cc[N];

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    //scatter rows of first matrix to different processes     
    MPI_Scatter(a, N*N/size, MPI_INT, aa, N*N/size, MPI_INT,0,MPI_COMM_WORLD);

    //broadcast second matrix to all processes
    MPI_Bcast(b, N*N, MPI_INT, 0, MPI_COMM_WORLD);

    MPI_Barrier(MPI_COMM_WORLD);

          //perform vector multiplication by all processes
          for (i = 0; i < N; i++)
            {
                    for (j = 0; j < N; j++)
                    {
                            sum = sum + aa[j] * b[j][i];  //MISTAKE_WAS_HERE               
                    }
                    cc[i] = sum;
                    sum = 0;
            }

    MPI_Gather(cc, N*N/size, MPI_INT, c, N*N/size, MPI_INT, 0, MPI_COMM_WORLD);

    MPI_Barrier(MPI_COMM_WORLD);        
    MPI_Finalize();
    if (rank == 0)                         //I_ADDED_THIS
        print_results("C = ", c);
}

void print_results(char *prompt, int 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(" %d", a[i][j]);
            }
            printf ("\n");
    }
    printf ("\n\n");
}
C = 
 54 37 47 57

 130 93 119 145

 44 41 56 71

 111 79 101 123