【问题标题】:How process knows when to stop listening for receive?进程如何知道何时停止收听接收?
【发布时间】:2017-01-27 13:45:37
【问题描述】:

考虑一个网格,其 bin 在进程之间分解。图中的数字是进程的等级。

在每个时间步,一些点会发生位移,因此需要将它们发送到新的目的地。该点发送由具有位移点的所有进程完成。图中仅以左下角 bin 的点为例。

我不知道一个进程应该持续监听接收消息多长时间?问题是接收者甚至不知道消息是否会到达,因为没有点可能传递到它的区域。

另请注意,点的来源和目的地可能与蓝点相同。

编辑:下面是表达问题的不完整代码。

void transfer_points()
{
    world.isend(dest, ...);
    while (true)
    {
        mpi::status msg = world.iprobe(any_source, any_tag);
        if (msg.count() != 0)
        {
            world.irecv(any_source, ...);
        }

        // but how long keep probing?
        if (???) {break;}            
    }
}

【问题讨论】:

  • 你基本上必须发送一个特殊的停止消息。
  • 首先使用MPI_Alltoall() 来判断每个进程要发送多少条消息?
  • 我建议始终向所有邻居发送消息,即使没有要转移的点,这意味着每次接收都将始终完成。要表明这是一条空消息,您可以使用特殊标记,或者使用 MPI_Get_count 找出传入消息的长度。

标签: c++ mpi boost-mpl


【解决方案1】:

您是否熟悉通过 MPI_Win_* 操作的单面 MPI 或 RMA(远程内存访问)?我理解你的问题的方式,它应该可以很好地解决:

  • 发送一些积分的排名将其放入另一个排名的内存(窗口)。
  • 屏障
  • 接收者已直接前往屏障,现在拥有数据

这是一个使用 RMA 的环发送示例(在 c++ 语法中!)。在您的情况下,它应该只需要一些小的修改,即。 e.仅在必要时调用 MPI_Put 以及一些关于写入缓冲区的偏移量的数学运算。

#include <iostream>
#include "mpi.h"

int main(int argc, char* argv[]) {

  MPI::Init(argc,argv);    
  int rank = MPI::COMM_WORLD.Get_rank();
  int comm_size = MPI::COMM_WORLD.Get_size();    
  int neighbor_left = rank - 1;
  int neighbor_right = rank + 1; 

  //Left and right most are neighbors.
  if(neighbor_right >= comm_size) { neighbor_right = 0;}
  if(neighbor_left < 0) {neighbor_left = comm_size - 1;}

  int postbox[2];
  MPI::Win window = MPI::Win::Create(postbox,2,sizeof(int),MPI_INFO_NULL,MPI::COMM_WORLD);

  window.Fence(0);     
  // Put my rank in the second entry of my left neighbor (I'm his right neighbor)
  window.Put(&rank,1,MPI_INT,neighbor_left,1,1,MPI_INT);
  window.Fence(0);    
  // Put my rank in the first entry of my right neighbor (I'm his left neighbor)
  window.Put(&rank,1,MPI_INT,neighbor_right,0,1,MPI_INT);
  window.Fence(0);

  std::cout << "I'm rank = " << rank << " my Neighbors (l-r) are " << postbox[0] << " " << postbox[1] << std::endl;

  MPI::Finalize();  
  return 0;
}

【讨论】:

  • 看起来 RMA 可以解决问题。完成此操作后,我会报告。谢谢。
猜你喜欢
  • 2013-10-13
  • 2011-12-03
  • 1970-01-01
  • 2018-12-04
  • 2020-03-01
  • 2021-03-03
  • 1970-01-01
  • 1970-01-01
  • 2017-11-23
相关资源
最近更新 更多