2013-01-21 61 views
0

我有問題。假設我有np進程。對於每個進程,我基於輸入文件計算需要發送給其他進程的消息數量(從0到...),並且我想向他們發送這個數字。事情是我只能從我通過直接連接節點創建的拓撲發送。所以基本上我希望每個進程發送到所有其他人一個int,我有以下的算法(將使用僞代碼):MPI_Recv和超時

for(i=1,np){ 
    if(i!=rankID){ 
     MPI_Send(&nr,1,MPI_INT,topology[i][nexthop],DATA,MPI_COMM_WORLD); 
     MPI_SEND(&i,1,MPI_INT,topology[i][nexthop],DATA,MPI_COMM,WORLD); //i send the destination along with the int 
    } 
} 
while(1){ 
    MPI_Recv(&recvInt,1,MPI_INT,MPI_ANY_SOURCE,DATA,MPI_COMM,WORLD); 
    MPI_Recv(&destination,MPI_INT,MPI_ANY_SOURCE,DATA,MPI_COMM,WORLD); 
    if(destination == rankID){ 
     ireceive+=recvInt; 
     receivedFrom++; 
     //normally i would break if i received all np-1 messages but what if someone sends a message through me for another process ? 
    } 
    else{ 
     MPI_Send(&recvInt,1,MPI_INT,topology[destination][nexthop],DATA,MPI_COMM_WORLD); 
     MPI_Send(&destination,1,MPI_INT,topology[destination][nexthop],DATA,MPI_COMM_WORLD); 
    } 

} 

我們解釋這個有點more.At這個小算法我想每年年底我的流程知道他們會在下一步中收到多少條消息。

要發送這個消息從每個節點到每個節點,我使用一個以前創建的路由表。基本上每個節點都有一個包含所有節點的矩陣,topology [node] [1] = next hop(這就是爲什麼我輸入代碼中的上述代碼)。

每個節點都知道有np進程,所以每個節點都必須接收np-1消息(他是目的地)。

我遇到的問題是,在收到np-1消息後,我無法打破,因爲我可能是其他進程的next_hop,並且消息不會被髮送。 所以我想要做這樣的事情,使用MPI_TEST或其他指令來查看我的Recv是否實際上正在接收某些東西,或者它只是坐在那裏,因爲如果程序阻塞了1-2秒,則很明顯它不會去接收更多(因爲我沒有一個大的拓撲20-30進程最大)。

問題是我從來沒有使用MPI_Test或其他語法,我不知道如何做到這一點。有人可以幫我創建一個Recv超時或如果有另一種解決方案?謝謝,對不起文本

+0

你能破解你的文字嗎?我無法閱讀... – nhahtdh

+0

好的,編輯過的文本 – user1272703

回答

0

可能不是最有效的一段代碼的長牆,但它應該工作(我沒有機會測試它)

MPI_Request request; 
MPI_Status status; 
for(i=1,np){ 
    if(i!=rankID){ 
     MPI_ISend(&nr,1,MPI_INT,topology[i][nexthop],DATA,MPI_COMM_WORLD); 
     MPI_ISend(&i,1,MPI_INT,topology[i][nexthop],DATA,MPI_COMM,WORLD); //i send the destination along with the int 
    } 
} 
while(1){ 
    bool over = false; 
    if(over == true) 
     break; 
    if(recievedFrom < np){ 
     MPI_Recv(&recvInt,1,MPI_INT,MPI_ANY_SOURCE,DATA,MPI_COMM,WORLD); 
     MPI_Recv(&destination,MPI_INT,MPI_ANY_SOURCE,DATA,MPI_COMM,WORLD); 
     if(destination == rankID){ 
      ireceive+=recvInt; 
      receivedFrom++; 
      //normally i would break if i received all np-1 messages but what if someone sends a message through me for another process ? 
     } 
     else{ 
      MPI_Send(&recvInt,1,MPI_INT,topology[destination][nexthop],DATA,MPI_COMM_WORLD); 
      MPI_Send(&destination,1,MPI_INT,topology[destination][nexthop],DATA,MPI_COMM_WORLD); 
     } 
    } 
    else { 
     MPI_Irecv(&recvInt,1,MPI_INT,MPI_ANY_SOURCE,DATA,MPI_COMM,WORLD, request); // non blocking recieve call after you finished receiving everything addressed to you 
     time_t now = time(NULL); 
     while(time(NULL) < now + time_you_set_until_timeout){ 
      over = true; 
      int flag = 0; 
      MPI_Test(req, flag, status); 
      if(flag){ 
       over = false; 
       break; //exit timeout loop if something was received 
      } 
     } 
    } 
    if(!over){ 
      MPI_Recv(&destination,MPI_INT,MPI_ANY_SOURCE,DATA,MPI_COMM,WORLD); 
      //route the message and continue 
    } 
} 

無論如何,因爲你不」不知道有多少時間可以通過,直到消息在拓撲結構中運行,您應該小心所選的超時時間。您可以嘗試實現其他類型的信號機制,例如廣播一條消息,告訴節點收到了發往它的所有消息。授予它將增加發送的消息數量,但它會確保每個人都得到了一切。您也可以嘗試打包或序列化您的數據以便發送,以便您只有一個發送/接收電話,這將使您的代碼更易於使用(在我看來)。

+0

我會嘗試上面的代碼,並會提供一個反饋after.I只是想廣播一條消息,當我收到所有np-1消息,但請記住,我不能使用Bcast或任何一種形式與其他節點進行通信,而不是直接與其他節點通信。所以,只給我的鄰居發信號表示我完成了嗎?這是有道理的,因爲我只能作爲鄰居的下一步但是會發生什麼呢?我收到一些空的消息,讓我暫停?另外我正在串行我的發送/ recv,因爲它實際上更容易處理。謝謝 – user1272703

+0

我明白你只能使用某種通信模式,但是你可以使用類似這樣的方式:在每個節點中定義一個大小爲數的進程的布爾數組,然後從每個節點向你的鄰居發送finished_receiving消息,鄰居將得到消息,標記array [sender]爲true,然後將消息發送給它們的鄰居,除了源,當數組只包含真值,每個人都完成了,並且你可以安全地完成 –

+0

當你對他們的鄰居說,你的意思如下:假設節點A完成,並且發送帶有標籤DONE的消息給他的鄰居。現在讓我們把節點V看作節點A的鄰居。他收到消息,標記array [A] = true,然後將這個值發送給他的鄰居,以便他們標記數組[A] = true,這是否正確? – user1272703