簡體   English   中英

MPI_Recv和超時

[英]MPI_Recv and timeout

我有個問題 。 假設我有np個進程,對於每個進程,我都會根據輸入文件計算需要發送給其他每個進程的消息數量(從0到...),我想向其發送此編號。 問題是我只能從通過直接連接的節點創建的拓撲中發送。 所以基本上我希望每個進程將一個int發送給所有其他進程,我有以下算法(將使用偽代碼):

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);
    }

}

現在進一步解釋一下。在這個小算法的結尾,我希望每個進程都知道下一步將收到多少消息。

為了將消息從每個節點發送到每個節點,我使用了我創建的上一個路由表。基本上每個節點都有一個包含所有節點的矩陣,並且topology [node] [1] =下一跳(這就是為什么我在上面輸入了nexthop的原因)代碼)。

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

我遇到的問題是,在收到np-1消息后,我無法中斷,因為我可能是其他進程的next_hop,並且該消息將不會發送。 所以我想做這樣的事情,使用MPI_TEST或另一條指令來查看我的Recv是否正在實際接收東西,或者它只是坐在那里,因為如果程序阻塞1-2秒,很明顯它不會接收任何更多(因為我沒有一個大的拓撲,最多20-30個進程)。

問題是我從來沒有使用過MPI_Test或其他語法,而且我不確定該怎么做。有人可以幫我為Recv創建超時,或者是否有其他解決方案? 謝謝你,很抱歉長文本

可能不是最高效的代碼,但是它應該可以工作(我沒有機會對其進行測試)

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
    }
}

無論如何,由於您不知道消息在拓撲中通過之前會經過多少時間,因此應謹慎選擇超時時間。 您可以嘗試實現某種其他類型的信令機制,例如廣播一條消息,告知該節點已收到發給該節點的所有消息。 可以增加發送的消息數量,但可以確保每個人都能得到所有信息。 另外,您可以嘗試打包或序列化要發送的數據,以便只有一個Send / Recv調用,這將使您的代碼更易於使用(我認為)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM