2015-04-06 61 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); 
}