MPI Sendrecv MPI_ANY_SOURCE
MPI Sendrecv with MPI_ANY_SOURCE
是否可以在一方不知道另一方排名的情况下进行 MPI_Sendrecv 交换?如果没有,最好的方法是什么(我的下一个猜测就是一对发送和接收)?
例如,在 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。
简答:否
标准不允许在任何发送过程中使用 MPI_ANY_SOURCE
作为目标等级 dest
。这是有道理的,因为您无法在不知道目的地的情况下发送消息。
然而,标准确实允许您将 MPI_Sendrecv
与常规 MPI_Send
/MPI_Recv
配对:
A message sent by a send-receive operation can be received by a regular receive operation
or probed by a probe operation; a send-receive operation can receive a message sent
by a regular send operation.
在您的情况下,进程 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);
}
是否可以在一方不知道另一方排名的情况下进行 MPI_Sendrecv 交换?如果没有,最好的方法是什么(我的下一个猜测就是一对发送和接收)?
例如,在 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。
简答:否
标准不允许在任何发送过程中使用 MPI_ANY_SOURCE
作为目标等级 dest
。这是有道理的,因为您无法在不知道目的地的情况下发送消息。
然而,标准确实允许您将 MPI_Sendrecv
与常规 MPI_Send
/MPI_Recv
配对:
A message sent by a send-receive operation can be received by a regular receive operation or probed by a probe operation; a send-receive operation can receive a message sent by a regular send operation.
在您的情况下,进程 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);
}