简体   繁体   English

MPI_Send和MPI_Recv不匹配C

[英]MPI_Send and MPI_Recv not matching C

I am trying to implement a workpool here. 我正在尝试在这里实现工作池。 I am supposed to send 100 differnt to numbers in total to slave processes. 我应该向从属进程发送总计100个差异数字。 Each slave process then returns something to master process and another different number is sent to the slave by the master. 然后,每个从属进程都将一些内容返回给主进程,并且主控将另一个不同的编号发送给从属进程。 This continues until all the 100 iterations are over. 这一直持续到所有100次迭代都结束为止。

My program gets kind of stuck in an infinite loop which I think is due to incorrect mapping of MPI_Send and MPI_Recv. 我的程序陷入了无限循环,我认为这是由于MPI_Send和MPI_Recv的映射不正确造成的。 I can't figure out what I am doing wrong. 我不知道自己在做什么错。 I have spent quite a few hours looking into this but to no avail. 我花了好几个小时研究这个问题,但无济于事。 I am new to MPI and programming in general. 我是MPI和程序设计的新手。 The code is given below: 代码如下:

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);
    }
}

You need to loop within your slave ranks as well. 您还需要在从属级别内循环。 As it stands now, you send iteration and a from the master to the slave, send count back from the slave to the master, and then the master tries to send iteration and a from within a while loop, while the slaves have happily exited the else block and continued on their merry way. 现在,您将iterationa从主机发送到从属设备,将count从从属设备发送回给主机,然后主机尝试在while循环内发送iterationa ,而从属设备则很高兴地退出了else封锁并继续他们的快乐之路。 Either get rid of the while loop in the master process so that it doesn't send things the slaves will never receive, or add one in the slave processes so that they will properly receive that data. 要么摆脱主进程中的while循环,以使其不发送从属将永远不会收到的内容,要么在从属进程中添加一个,以便它们可以正确接收该数据。

One of the most important things in MPI is to understand, that in general every single process executes the same programm. MPI中最重要的事情之一是要了解,通常每个进程都执行相同的程序。 This makes mpi_rank to one of your best friends, since you need it to distinguish the different tasks each process has to accomplish. 这使mpi_rank成为您最好的朋友之一,因为您需要它来区分每个进程必须完成的不同任务。

Another important point to understand is how blocking/non-blocking communication in MPI works. 要理解的另一个重要点是MPI中的阻塞/非阻塞通信如何工作。 Here we're using blocking communication ( MPI_Send() and MPI_Recv() ). 在这里,我们使用阻塞通信( MPI_Send()MPI_Recv() )。 This means a process will stop at a function call like MPI_Recv() and wait until the communication partner will reach it's "counterpart" (the MPI_Send() , to send something to me). 这意味着进程将在MPI_Recv()类的函数调用处停止,并等待直到通信伙伴到达它的“对方”( MPI_Send() ,才能向我发送消息)。

The fact that your program gets stuck is a good indication for not having the same amount of MPI_Send() and MPI_Recv() calls: somewhere a process is still waiting to receive a message/be able to send a message. 您的程序被卡住的事实很好地表明了没有相同数量的MPI_Send()MPI_Recv()调用:某个进程仍在等待接收消息/能够发送消息。

For your example, I'd try to do something like this: 对于您的示例,我将尝试执行以下操作:

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++;
}

Your task sounded like: Master sends int to slave #1, #2, #3....., then he receives from #1, #2, #3...., then he sends another int to #1, #2, #3. 您的任务听起来像:主机将int发送给从机#1,#2,#3 .....,然后他从#1,#2,#3 ....接收,然后将另一个int发送给#1, #2,#3。 You'll probably recognize that you have to loop over all the slave ranks for three times. 您可能会意识到,您必须遍历所有从属级别3次。

This solution is different (the result is the same though), but shorter: Master sends int to slave #1, then receives int from slave #1, then sends another int to slave #1. 这个解决方案是不同的(虽然结果是一样的),但是更短:主节点将int发送到从节点#1,然后从从节点#1接收int,然后再将另一个int发送到从节点#1。 Afterwards, repeat the same thing for slave #2, #3, #4.... This way we just have to loop over all the slave ranks for just one time. 然后,对从站#2,#3,#4重复相同的操作。...这样,我们只需要遍历所有从站等级一次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM