2015-04-06 64 views
4

是否有可能進行MPI_Sendrecv交換,其中一方不知道另一方的等級?如果沒有,那麼最好的辦法是什麼(我的下一個猜測只是一對發送和recv)?MPI Sendrecv與MPI_ANY_SOURCE

例如,在c。如果我想等級0和其他一些等級之間交換整數將這種類型的事情?:工作的

MPI_Status stat; 
if(rank){ 
    int someval = 0; 
    MPI_Sendrecv(&someval, 1, MPI_INT, 0, 1, &recvbuf, 1, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &stat); 
}else{ 
    int someotherval = 1; 
    MPI_Sendrecv(&someotherval, 1, MPI_INT, MPI_ANY_SOURCE, someotherval, &recvbuf, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &stat); 
} 

編輯: 看起來是不可能的。我把以下內容作爲一種包裝來添加我需要的功能。

void slave_sendrecv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, 
    int dest, int sendtag, void *recvbuf, int recvcount, 
    MPI_Datatype recvtype, int source, int recvtag, MPI_Status *status){ 

    MPI_Send(sendbuf, sendcount, sendtype, dest, sendtag, MPI_COMM_WORLD); 
    MPI_Recv(recvbuf, recvcount, recvtype, source, recvtag, MPI_COMM_WORLD, status); 
} 

void anon_sendrecv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, 
    int sendtag, void *recvbuf, int recvcount, 
    MPI_Datatype recvtype, int recvtag, MPI_Status *status){ 

    int anon_rank; 
    MPI_Recv(recvbuf, recvcount, recvtype, MPI_ANY_SOURCE, recvtag, MPI_COMM_WORLD, status); 
    anon_rank = status -> MPI_SOURCE; 
    MPI_Send(sendbuf, sendcount, sendtype, anon_rank, sendtag, MPI_COMM_WORLD); 
} 

編輯2:基於帕特里克回答它看起來像slave_sendrecv以上功能是不需要的,你可以只使用常規MPI_Sendrecv上知道誰它發送到最後。

回答

3

簡短的回答:

號標準不允許使用的MPI_ANY_SOURCE在任何發送過程目的地排名dest。這是有道理的,因爲你不知道目的地就不能發送消息。

標準然而確實允許您配對MPI_Sendrecv定期MPI_Send/MPI_Recv

通過發送 - 接收操作發送的消息可以由一個常規接收操作 接收或探測由一個探測操作;發送 - 接收操作可以通過常規發送操作接收發送的消息 。

在你的情況,過程0必須先接受,然後回答:

MPI_Status stat; 
if(rank){ 
    int someval = 0; 
    MPI_Sendrecv(&someval, 1, MPI_INT, 0, 1, &recvbuf, 1, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &stat); 
}else{ 
    int someotherval = 1; 
    MPI_Recv(&recvbuf, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &stat); 
    // answer to process `stat.MPI_SOURCE` using `someotherval` as tag 
    MPI_Send(&someotherval, 1, MPI_INT, stat.MPI_SOURCE, someotherval, MPI_COMM_WORLD); 
}