MPI_Send 和 MPI_Recv 不匹配 C

MPI_Send and MPI_Recv not matching C

我想在这里实现一个工作池。我应该向从进程发送 100 个不同的数字。然后每个从属进程 returns 向主进程发送一些东西,另一个不同的数字由主进程发送给从属进程。这一直持续到所有 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);
    }
}

你也需要在你的奴隶队伍中循环。现在,您将 iterationa 从主机发送到从机,将 count 从从机发送回主机,然后主机尝试发送 iterationa 来自 while 循环,而奴隶们愉快地退出了 else 块并继续他们快乐的方式。要么去掉主进程中的 while 循环,这样它就不会发送从属进程永远不会收到的东西,要么在从属进程中添加一个循环,这样它们就能正确地接收数据。

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

另一个需要理解的重点是 blocking/non-blocking MPI 中的通信是如何工作的。这里我们使用阻塞通信(MPI_Send()MPI_Recv())。这意味着进程将在 MPI_Recv() 之类的函数调用处停止,并等待通信伙伴到达它的 "counterpart"(MPI_Send(),向我发送内容)。

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

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

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。您可能会认识到您必须遍历所有从属队列 3 次。

这个解决方案是不同的(虽然结果是一样的),但更短:Master 发送 int 到 slave #1,然后从 slave #1 接收 int,然后发送另一个 int 到 slave #1。之后,对 slave #2、#3、#4 重复同样的事情......这样我们只需要遍历所有 slave ranks 一次。