我正在尝试在“使用 MPI”中实现矩阵向量 MPI 程序 便携式并行编程 消息传递接口 第二版 威廉·格罗普 尤因·拉斯克 Anthony Skjellum 的书,第 35 页此处。
这是一个自调度程序,其中 0 阶进程将向量广播给所有其他进程,并向每个进程发送一行矩阵。然后,进程计算向量和行之间的点积,并将结果发送回排名 0 的进程。书中的示例是用 Fortran 编写的,我将其移植到 C++ 中,但在第一次发送后就死锁了
#include "mpi.h"
#include <iostream>
#include <vector>
int main(){
int W_rank, W_size;
int rows = 9;
int cols = 9;
std::vector<double> b(cols);
std::vector< std::vector<double> > a(rows);
std::vector<double> c(rows);
std::vector<double> buffer(cols);
for(auto& row : a) row.resize(cols);
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &W_size);
MPI_Comm_rank(MPI_COMM_WORLD, &W_rank);
if(W_rank == 0){
std::fill(b.begin(), b.end(), 1);
for(auto& row : a){
std::fill(row.begin(), row.end(), 1);
}
int numsent = 0;
MPI_Bcast(b.data(), b.size(), MPI_DOUBLE, 0, MPI_COMM_WORLD);
for(int i=0; i<W_size; ++i){
for(int j=0; j<cols; ++j){
buffer[j] = a[i][j];
}
MPI_Send(buffer.data(), buffer.size(), MPI_DOUBLE, i, i, MPI_COMM_WORLD);///////deadlocks here///////////
++numsent;
}
double ans;
MPI_Status status;
for(int i=0; i<rows; ++i){
MPI_Recv(&ans, 1, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
int sender = status.MPI_SOURCE;
int tag = status.MPI_TAG;
c[tag] = ans;
if(numsent<rows){
for(int j=0; j<cols; ++j){
buffer[j] = a[numsent][j];
}
MPI_Send(buffer.data(), buffer.size(), MPI_DOUBLE, sender, numsent, MPI_COMM_WORLD);
++numsent;
}
else{
MPI_Send(MPI_BOTTOM, 0, MPI_DOUBLE, sender, -1, MPI_COMM_WORLD);
}
}
}
else{
MPI_Bcast(b.data(), b.size(), MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Status status;
while(1){
MPI_Recv(buffer.data(), buffer.size(), MPI_DOUBLE, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status);//////deadlocks here///////////////////
if(status.MPI_TAG == -1) break;
int row = status.MPI_TAG;
double ans = 0;
for(int i=0; i<cols; ++i){
ans += buffer[i]*b[i];
}
MPI_Send(&ans, 1, MPI_DOUBLE, 0, row, MPI_COMM_WORLD);
}
}
MPI_Finalize();
return 0;
}
您对 MPI 标签的处理是危险的或错误的。首先,标签必须是非负的,所以你的
-1
标签是非法的。如果在内部它被解释为无符号,它就会变成一个非常大的标签。其次:标签值有上限,因此使用 numsent
作为标签很聪明,但可能会出现问题。我会使用 tag=0 表示常规消息,使用 tag=1 表示终止,或类似的东西。