我正在尝试使用MPI运行矩阵乘法程序。数组'a'和'b'的类型为double,大小为512 * 512。数组'a'将被分散,数组'b'将被广播。矩阵乘法后的最终结果将在数组c [512] [512]中的主进程中收集 我试图使用MPI_Send()和MPI_Recv()函数实现MPI_Scatter(),但我有点陷入无限循环(可能)。 P 是进程数。
double a[512][512], b[512][512], c[512][512];
blksz = 512/P;
if(rank == 0) {
// Scatter input matrix a, implementation of MPI_Scatter()
for(j = 1 ; j < P ; j++ ) {
MPI_Send(&a + j*blksz*N*sizeof(double), blksz*N, MPI_DOUBLE, j, 0, MPI_COMM_WORLD);
}
// Broadcast the input matrix b, implementation of MPI_Bcast()
for(j = 1 ; j < P ; j++ ) {
MPI_Send(&b, N*N, MPI_DOUBLE, j, 1, MPI_COMM_WORLD);
}
}
else {
MPI_Recv(&a, blksz*N, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &status);
MPI_Recv(&b, N*N, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD, &status);
}
for(i = 0 ; i < blksz; i++) {
for(j = 0 ; j < N ; j++) {
c[i][j] = 0;
for(k = 0 ; k < N ; k++) {
c[i][j] += a[i][k] * b[k][j];
}
}
}
// Gather result, implementation of MPI_Gather()
if(rank != 0) {
MPI_Send(&c, blksz*N, MPI_DOUBLE, 0, 2, MPI_COMM_WORLD);
}
else {
for(i = 1 ; i < P ; i++) {
MPI_Recv(&c+i*blksz*N*sizeof(double), blksz*N, MPI_DOUBLE, 0, 2, MPI_COMM_WORLD, &status);
}
}
我是一名编程的初学者,但是我整晚都想弄清楚,但无济于事。如果有人能帮助我,我真的很感激。
答案 0 :(得分:0)
当你发送&a + j*blksize*N*sizeof(double)
时,你没有做你想做的事。首先,&a
是a
的地址,它是一个数组数组,不是你想要发送的,你想发送一个指针,或*a
(技术上这个是一个数组,但它将隐式地转换为指向所述数组的第一个元素的指针。接下来,在进行指针运算时,您不需要(事实上,不应该)乘以sizeof(type)
;这将由编译器为您处理。所以你的第一个MPI_Send
命令应该是
MPI_Send(*a + j*blksz*N, blksz*N, MPI_DOUBLE, j, 0, MPI_COMM_WORLD);
进行类似的更改(对于所有发送和接收),您的代码应该有效。