2014-04-17 110 views
1

我有下面的代碼現在可以使用,但我不認爲隨着進程和發送數據的數量增長將會擴展。MPI發送和接收(多對多)

這裏是我要去:

首先我有一個發送迴路,每個處理器將消息發送到所有其他。 每個進程發送的消息長度將不同,但不是類型。

for (int i = 0; i < n_proc; ++i){ 
    if (i != my_rank){ 
      int N = Xcoord_top[my_rank].size(); 
      MPI_Send(&Xcoord_top[my_rank][0], N, MPI_DOUBLE, i, 1000, MPI_COMM_WORLD); 
    } 
} 
MPI_Barrier(MPI_COMM_WORLD); 

我發送的消息後,我收到他們使用類似的循環

for (int i = 0; i < n_proc; ++i){ 
    if (i != my_rank){ 
     std::vector<double> temp(max_n); 
     MPI_Recv(&temp[0], points_per_proc[i], MPI_DOUBLE, 
        MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); 
     ... 
    } 
} 

在第二循環中我也有把信息在正確的地方基於標籤幾行,消息來源

這隻有當我把環路之間的障礙,否則崩潰。

根據我的理解,消息的MPI內部存儲可能會溢出(我不確定是否使用正確的術語)。所以在這種情況下,程序會在第一個循環中掛起。

任何想法我應該怎麼做呢?

回答

2

有點過分代碼以適應評論:

我建議只是在做這個作爲一個單一的MPI_Allgatherv()

std::vector<int> disps(n_proc); 

disps[0] = 0; 
for (int i=1; i<n_proc; i++) 
    disps[i] = disps[i-1] + points_per_proc[i-1]; 

int totdata = disps[n_proc-1] + points_per_proc[n_proc-1]; 
std::vector<double> temp(totdata); 

MPI_Allgatherv(&Xcoord_top[my_rank][0], Xcoord_top[my_rank].size(), 
       MPI_Double, temp, points_per_proc, disps, MPI_DOUBLE, 
       MPI_COMM_WORLD); 

現在的數據PROC itemp[disps[i]]...temp[disps[i+1]-1]

有至少三個問題最初發布的代碼:

  • 它很可能死鎖(發送允許阻塞,直到收到) - 這可能是固定使用異步發送,例如MPI_Isend()具有以下MPI_Waitall()而不是MPI_Send();
  • 它幾乎肯定會處理收到的亂序(不能保證它在從第i個處理器接收到的第i次迭代中),所以消息長度可能是錯誤的,從而導致錯誤,從而中止程序 - 可以通過修復來源爲i而不是MPI_ANY_SOURCE來修復;和
  • 這是效率低下,使用線性點對點發送和接收,而不是像廣播或聚集優化的集體 - 可以通過使用集合,如allgather,如上所述修復。
+0

感謝它就這麼簡單! 只用於記錄disps應該被計算爲 disps [i] = disps [i-1] + points_per_proc [i-1];'和proc'i'的數據應該在'temp [disps [i ]] ... temp [disps [i + 1] -1]' – giorgk

+0

非常正確,我會相應地更正答案。 –