如果我想通过MPI发送消息并同时接收消息,我该怎么办? [英] What should I do if I want to send message by MPI and receive messages at the same time?
问题描述
Backgroup:排名0发送消息到排名1,在排名1完成其工作后它将消息返回到排名0
Backgroup: rank 0 send message to rank 1, after rank 1 completes its work it returns messages to rank 0
实际上我运行一个线程来发送消息和另一个用于接收排名0 的人:
actually I run a thread for sending message and the other one for receiving in rank 0 like this:
int tag = 1;
void* thread_send(void* argc)
{
...;
while(1)
{
if(tag == 1)
{
MPI_Send(...,1,TAG_SEND,...);//send something to slave
tag = 0;
}
}
...
}
void* thread_receive(void* argc)
{
while(1)
{
MPI_Recv(...,0,TAG_RECV,...); //ready for receiving from slave
tag = 1;
}
}
排名1 I运行这样一个线程:
in rank 1 I run a thread like this:
void* slave(void* argc)
{
...;
while(1)
{
MPI_Probe(0,MPI_ANY_TAG,MPI_COMM_WORLD,&status);
switch(status.MPI_TAG){
case TAG_SEND:
MPI_Recv(..,0,TAG_SEND,..);
break;
}
MPI_Send(...,0,MPI_RECV,...); //notify rank 0 slave has done his work
}
}
然后我收到如下错误:
[comp01-mpi.gpu01.cis.k.hosei.ac.jp][[54135,1],0]
[btl_tcp_endpoint.c:486:mca_btl_tcp_endpoint_recv_connect_ack]
received unexpected process identifier [[16641,0],301989888]
事实上,一台机器有几个接口,我知道这可能是个问题,所以我分配参数
--mca btl_tcp_if_include eth0 - -mca oob_tcp_if_include eth0
以避免网络流量。
In fact there are several interfaces for one machine, I know it might to be a problem, so I assign the parameter --mca btl_tcp_if_include eth0 --mca oob_tcp_if_include eth0 to avoid network traffic.
我做错了什么?我将非常感谢你给我的任何建议,谢谢。
Have I done something wrong? I will appreciate any suggestion you give me, thanks.
感谢@HristoIliev,我检查了这个Open MPI:
Thanks to @HristoIliev, I checked the Open MPI like this:
MPI_Init_thread(&argc,&argv,MPI_THREAD_MULTIPLE,&provide_level);
if(provide_level < MPI_THREAD_MULTIPLE){
printf("Error: the MPI library doesn't provide the required thread level\n");
MPI_Abort(MPI_COMM_WORLD,0);
}
我收到错误:
Error: the MPI library doesn't provide the required thread level
这意味着我不能使用多个线程,那么我还能做什么?
that means I CAN NOT use multiple threads, so what else can I do?
现在我正在使用非blocing发送(Isend)和收到(Irecv),代码是这样的:
发送帖子:
Now I am using the non-blocing sends(Isend) and receives(Irecv), the code is like this: send thread:
int tag = 1;
void* thread_send(void* argc)
{
...;
while(1)
{
while(1)
{
MPI_Irecv(&tag,MPI_INT,1,MSG_TAG,MPI_COMM_WORLD,&request);
if(tag == 1) break;
printf("tag is %d\n",tag);
MPI_Wait(&request,&status);
}
MPI_Send(...,1,MSG_SEND,...);//send something to slave
tag = 0;
}
...
}
接收主题
void* slave(void* argc)
{
...;
while(1)
{
MPI_Probe(0,MPI_ANY_TAG,MPI_COMM_WORLD,&status);
switch(status.MPI_TAG){
case TAG_SEND:
MPI_Recv(..,0,MSG_Send,..);
break;
}
int tag = 1;
MPI_Isend(&tag,1,MPI_INT,0,MSG_TAG,MPI_COMM_WORLD,&request); //notify rank 0 slave has done his work
MPI_Wait(&request,&status);
printf("slave is idle now \n");
}
}
并打印如下:
tag is 0
slave is idle now
并挂在这里
推荐答案
我通过更改Irecv()函数的位置解决了这个问题,如下所示:
I have solved the problem by changing the Irecv() funciton's location, like following:
发送主题
int tag = 1;
void* thread_send(void* argc)
{
...;
while(1)
{
while(1)
{
if(tag == 1) break;
printf("tag is %d\n",tag);
MPI_Irecv(&tag,MPI_INT,1,MSG_TAG,MPI_COMM_WORLD,&request);
MPI_Wait(&request,&status);
}
MPI_Send(...,1,MSG_SEND,...);//send something to slave
tag = 0;
}
...
}.
总之,要同时发送和接收消息,如果你的MPI你可以使用多个线程支持多线程模式,你可以在启动你的MPI程序时检查它:
In conclusion, to send and receive messages at the same time, you can use multiple thread if your MPI supports multiple-thread mode, you can check it when you init your MPI program like this:
MPI_Init_thread(&argc,&argv,MPI_THREAD_MULTIPLE,&provide_level);
if(provide_level < MPI_THREAD_MULTIPLE){
printf("Error: the MPI library doesn't provide the required thread level\n");
MPI_Abort(MPI_COMM_WORLD,0);
}
或者如果你的MPI不支持多线程模式,你可以使用非阻止沟通。
Or if your MPI doesn't support multiple thread mode, you may use non-blocking communication.
这篇关于如果我想通过MPI发送消息并同时接收消息,我该怎么办?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!