我正在进行数值模拟过程之间的大型矢量通信。一切都很好,直到某个时间步骤。我没有收到错误,但输出解决方案显然不正确。MPI全部到全部通信问题
我现在正在调试相当长的一段时间,我的假设是,有在MPI通信错误。
我的代码的通信部分看起来像这样:
MPI_Request req;
for(int j=0;j<numProcs;j++){
if(j!=myId){
tag=0;
sizeToSend=toProc[j].size();
MPI_Isend(&sizeToSend, 1, MPI_LONG_LONG, j, tag, MPI_COMM_WORLD,&req);
MPI_Request_free(&req);
}
}
for(int j=0;j<numProcs;j++){
if(j!=myId){
tag=0;
MPI_Recv(&sizeToReceive[j], 1, MPI_LONG_LONG, j, tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
}
for(int j=0;j<numProcs;j++){
if(j!=myId){
if(toProc[j].size()>0){
tag=1;
MPI_Isend(&toProc[j][0], toProc[j].size(), MPI_LONG_LONG, j, tag, MPI_COMM_WORLD,&req);
MPI_Request_free(&req);
}
}
}
for(int j=0;j<numProcs;j++){
if(j!=myId){
if(sizeToReceive[j]>0){
receiveBuffer.resize(sizeToReceive[j]);
tag=1;
MPI_Recv(&receiveBuffer[0], sizeToReceive[j], MPI_LONG_LONG, j, tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
for(int k=0;k<sizeToReceive[j];k++){
domain.field[receiveBuffer[k]]=1;
}
receiveBuffer.clear();
}
}
}
MPI_Barrier(MPI_COMM_WORLD);
for(int j=0;j<toProc.size();j++){
toProc[j].clear();
}
可变numProcs
是包含的进程数的int,myId
是包含进程的秩的int,tag
是int,domain.field
是一个vector<char>
。 其他必要的变量的定义是这样的:
vector<vector <long long> > toProc;
toProc.resize(numProcs);
long long sizeToReceive[numProcs];
long long sizeToSend=0;
vector<long long> receiveBuffer;
我试图在上面的代码做的就是发送向量toProc[j]
与id==j for j=0,...,numProcs-1, j!=myId
上的每个进程来处理。 为了达到这个目的,我在前两个for-loop中发送和接收这些向量的大小,并在第3个和第4个for循环中发送和接收实际数据。我正在使用Isend,因为我显然希望这些调用是非阻塞的。
toProc[j]
中的值是在进程j的向量domain.field(每个进程都有自己的domain.field)中必须设置为1的索引。
我的问题是: 你看到意外的行为任何潜在的在我的Isend-RECV政策的使用。
我没有看到立即的问题,除了垃圾邮件也许太多正在进行的请求,但似乎你可以大大简化并通过'MPI_Alltoall'和'MPI_Alltoallv'加快整个操作。 – Zulan
感谢您的建议,我会尝试使用'MPI_Alltoall'实现相同的行为,您会考虑多少个请求太多?如果我只使用4个进程,那么错误也会发生,可能已经太多了吗? – Jonas
似乎我忽略了一个非常明显的问题,请参阅我的答案。 – Zulan