2012-08-28 50 views
3

假設我有n進程,並且它們每個都擁有一塊本地數據,比如int爲什麼MPI_Sendrecv塊?

現在我想重新實現MPI_Allreduce()功能,即計算所有這些整數的全球總和再播相加結果返回的過程。

我想這樣做像在下面的代碼:

int temp; 
    int my_sum = temp = my_data; 
    for (int i = 1; i < size; ++i) { 
    int partner = (my_rank + 1) % size; 
    MPI_Sendrecv_replace(&temp, 1, MPI_INT, 
         partner, 0, 
         my_rank, 0, 
         MPI_COMM_WORLD, MPI_STATUS_IGNORE); 
    my_sum += temp; 
    } 

,使得過程中的環FAHION通信,但它的阻止。爲什麼?如何更改代碼以使其正常工作?

注:請,不建議選擇(更好的)解決方案的問題(明確,其中之一是使用MPI_Allreduce()功能)。我的目標是理解爲什麼這段代碼不起作用,因爲我認爲它應該。

回答

6

每個人都試圖從自己接收,但他們發送到partner;因爲partner將永遠不會收到正在發送的郵件,並且my_rank永遠不會收到來自其本身的消息,這是一個掛起。

如果你想將數據發送到parter,那麼你需要確保partner從你接受,這意味着每個人都需要從(myrank - 1 + size) % size接收:

int spartner = (my_rank + 1) % size; 
int rpartner = (my_rank - 1 + size) % size; 
MPI_Sendrecv_replace(&temp, 1, MPI_INT, 
        spartner, i, 
        rpartner, i, 
        MPI_COMM_WORLD, MPI_STATUS_IGNORE); 

這樣,等級3(說)正在發送到4,並且等級4在每次迭代中從等級3接收,並且因此sendrecv完成。 (我也冒昧給每個迭代遍歷循環自己的標籤,這在這裏並不是非常必要,但是如果存在其他不匹配的消息類型錯誤,通常會幫助找到錯誤。)