MPI_Send和MPI_Recv不匹配C.

时间:2015-03-12 08:21:23

标签: c mpi

我正在尝试在这里实现一个工作池。我应该向奴隶进程发送总数为100的数字。然后,每个从属进程向主进程返回一些内容,主进程将另一个不同的数字发送给从属进程。这一直持续到所有100次迭代结束。

我的程序陷入无限循环,我认为是由于MPI_Send和MPI_Recv的映射不正确。我无法弄清楚我做错了什么。我花了好几个小时研究这个,但无济于事。我是MPI和编程的新手。代码如下:

if(rank == 0) {
        int i,iteration = 0, a=0,inside=0,temp=0;
        for(i = 1; i < slaves; i++) {
        MPI_Send(&iteration,1,MPI_INT,i,0,MPI_COMM_WORLD);
        MPI_Send(&a,1,MPI_INT,i,1,MPI_COMM_WORLD);
        iteration++;
    }
    while(iteration < 100+slaves){
        MPI_Recv(&temp,1,MPI_INT,MPI_ANY_SOURCE,0, MPI_COMM_WORLD, &status);
        if(iteration < 100) {
            MPI_Send(&iteration,1,MPI_INT,status.MPI_SOURCE,0,MPI_COMM_WORLD);
            MPI_Send(&a,1,MPI_INT,status.MPI_SOURCE,1,MPI_COMM_WORLD);
        }
        iteration++;
        inside = inside + temp;
    }
}
else {
    int iteration=0,count=0;
    if(iteration < 100) {
        MPI_Recv(&iteration,1,MPI_INT,0,0,MPI_COMM_WORLD,&status);
        MPI_Recv(&count,1,MPI_INT,0,1,MPI_COMM_WORLD,&status);
        MPI_Send(&count,1,MPI_INT,0,0,MPI_COMM_WORLD);
    }
}

2 个答案:

答案 0 :(得分:3)

你也需要在你的奴隶队伍中循环。现在,您将iterationa从主服务器发送到从服务器,将count从服务器发送回主服务器,然后主服务器尝试发送iteration来自a循环内的whileelse,而奴隶们已经愉快地退出while区块并继续他们的快乐方式。要么摆脱主进程中的{{1}}循环,以便它不发送从站永远不会收到的东西,或者在从进程中添加一个循环,以便它们能够正确地接收该数据。

答案 1 :(得分:2)

MPI中最重要的事情之一是理解,通常每个进程都执行相同的程序。这使得mpi_rank成为您最好的朋友之一,因为您需要它来区分每个流程必须完成的不同任务。

另一个要理解的重点是MPI中的阻塞/非阻塞通信是如何工作的。在这里,我们使用阻止通信(MPI_Send()MPI_Recv())。这意味着一个过程将停留在MPI_Recv()之类的函数调用中,并等到通信伙伴将达到它的对应关键字&#34; (MPI_Send(),向我发送信息)。

您的程序卡住的事实很好地表明没有相同数量的MPI_Send()MPI_Recv()调用:某个进程仍在等待接收消息/能够发送消息消息。

对于你的例子,我尝试做这样的事情:

while( iterations < 100 ){
  // in general every process has to do something for 100 times,
  // but we have to have to distinguish between master and slaves.

  if( mpi_rank == 0 ){
    // The master process...
    for( int slave_rank = 1; slave_rank < mpi_size; slave_rank++ ){
      // ... has to send, receive and send once again something to/from every(!) slave, ...
      MPI_Send( [one int to slave_rank] );
      MPI_Recv( [one int from slave_rank] );
      MPI_Send( [another int to slave_rank] );
    }
  }
  else{
    //... while the slaves just have to receive, send and receive again from/to one process (the master)
    MPI_Recv( [one int from master] );
    MPI_Send( [one int to master] );
    MPI_Recv( [another int from master] );
  }
  iterations++;
}

你的任务听起来像:Master发送int到slave#1,#2,#3 .....,然后他从#1,#2,#3 ....收到,然后他发送另一个int到#1,#2,#3。你可能会认识到你必须循环遍历所有奴隶等级三次。

这个解决方案是不同的(虽然结果是相同的),但更短:Master将int发送到slave#1,然后从slave#1接收int,然后将另一个int发送到slave#1。之后,为奴隶#2,#3,#4重复同样的事情....这样我们只需要循环所有奴隶等级一次。