使用Mpi_散射和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
#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