正确使用MPI探针

时间:2013-03-27 10:26:06

标签: c++ mpi

我需要在处理器之间传输可变长度的向量。更具体地说,一个处理器监听一些其他处理器的发送。这就是我的意思:

// receiving processor (rank 0):
MPI::Status status;
MPI::COMM_WORLD.Probe(MPI::ANY_SOURCE, my_tag, status);
const auto sender = status.Get_source();
const auto n_bytes = status.Get_count(MPI::BYTE);
std::cerr << n_bytes << std::endl;
auto row = std::vector<size_t>(n_bytes / sizeof(size_t));
MPI::COMM_WORLD.Recv(&row.front(), n_bytes, MPI::BYTE, sender, my_tag);

// sending processor:
const size_t n = 10; // example value
auto row = std::vector<size_t>(n, 0);
const auto n_bytes = n * sizeof(size_t);
MPI::COMM_WORLD.Send(&row.front(), n_bytes, MPI::BYTE, 0, my_tag);

然而,接收处理器报告n_bytes == 0。使用Probe / Recv是否正确?

1 个答案:

答案 0 :(得分:2)

问题中显示的代码完全没有错。然而,生产代码在一个关键方面有所不同(我愚蠢地认为这与问题无关)。

错误在以下代码中(发件人保持不变):

// receiving processor (rank 0):
MPI::Status status;
MPI::COMM_WORLD.Probe(MPI::ANY_SOURCE, my_tag, status);
const auto sender = status.Get_source();
const auto n_bytes = status.Get_count(MPI::BYTE);
if ( n_bytes == 0 )
{
   std::cerr << "nothing transmitted\n";
   return; // BAD
}
auto row = std::vector<size_t>(n_bytes / sizeof(size_t));
MPI::COMM_WORLD.Recv(&row.front(), n_bytes, MPI::BYTE, sender, my_tag);

错误是在探测到没有接收的之后从方法返回。甚至必须消耗空的传输。否则,下一次探测调用将获得完全相同传输的状态。

可以通过在返回前调用MPI::COMM_WORLD.Recv(NULL, 0, MPI::BYTE, sender, my_tag);来修复。