我正在進行數值模擬過程之間的大型矢量通信。一切都很好,直到某個時間步驟。我沒有收到錯誤,但輸出解決方案顯然不正確。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