【问题标题】:cannot send std::vector using MPI_Send and MPI_Recv无法使用 MPI_Send 和 MPI_Recv 发送 std::vector
【发布时间】:2015-05-18 02:10:58
【问题描述】:

我正在尝试使用 MPI send 和 recv 函数发送 std:vector,但我没有到达任何地方。 我收到类似

的错误
Fatal error in MPI_Recv: Invalid buffer pointer, error stack:
MPI_Recv(186): MPI_Recv(buf=(nil), count=2, MPI_INT, src=0, tag=0, MPI_COMM_WORLD, status=0x7fff9e5e0c80) failed
MPI_Recv(124): Null buffer pointer

我尝试了多种组合

A) 就像用来发送数组的东西 ..

 std::vector<uint32_t> m_image_data2; // definition of  m_image_data2
     m_image_data2.push_back(1);
     m_image_data2.push_back(2);
     m_image_data2.push_back(3);
     m_image_data2.push_back(4);
     m_image_data2.push_back(5);

MPI_Send( &m_image_data2[0], 2, MPI_INT, 1, 0, MPI_COMM_WORLD);
MPI_Send( &m_image_data2[2], 2, MPI_INT, 1, 0, MPI_COMM_WORLD);

MPI_Recv( &m_image_data2[0], 2, MPI_INT, 0, 0, MPI_COMM_WORLD, &status );

B) 没有 []

MPI_Send( &m_image_data2, 2, MPI_INT, 1, 0, MPI_COMM_WORLD);
MPI_Send( &m_image_data2 + 2, 2, MPI_INT, 1, 0, MPI_COMM_WORLD);

MPI_Recv( &m_image_data2, 2, MPI_INT, 0, 0, MPI_COMM_WORLD, &status );

C) 使用矢量方法,例如 at()..

MPI_Send( &m_image_data2.at(0), 2, MPI_INT, 1, 0, MPI_COMM_WORLD);
MPI_Send( &m_image_data2.at(2), 2, MPI_INT, 1, 0, MPI_COMM_WORLD);

MPI_Recv( &m_image_data2.at(0), 2, MPI_INT, 0, 0, MPI_COMM_WORLD, &status );

我正在考虑在主节点将向量转换为 int[],然后在工作节点将其转换回向量,但这会产生不必要的开销。

有人知道怎么解决吗?

【问题讨论】:

  • 请发布完整的代码示例。正如您在下面评论的那样,您的错误与 MPI 无关,而与您省略显示的代码无关,但没人知道!

标签: c++ vector parallel-processing mpi hpc


【解决方案1】:

如果没有更完整的示例,我不知道发生了什么,但似乎您的发送和接收不匹配(或者您没有正确初始化接收向量)。

以下内容就足够了:

std::vector<uint32_t> m_image_data2;

if (rank==0) {
  m_image_data2.push_back(1);
  m_image_data2.push_back(2);
  m_image_data2.push_back(3);
  m_image_data2.push_back(4);
  m_image_data2.push_back(5);
  // send 5 ints at once
  MPI_Send( &m_image_data2[0], 5, MPI_INT, 1, 0, MPI_COMM_WORLD);
}
else {
  // make space for 5 ints
  m_image_data2.resize(5);
  // receive 5 ints
  MPI_Recv(&m_image_data2[0], 5, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
}

【讨论】:

  • 我会通过使用向量的 size() 来稍微改进这一点,即 MPI_Send(&m_image_data2[0],m_image_data2.size(),...);要干净利落地移动复杂的数据类型,您还可以研究 MPI 中的自定义数据类型功能。这很棘手,但您可以发送结构。此外,传输大小未知的数据也需要您发送向量的大小,以便接收方有机会分配。您可以查看 Boost MPI boost.org/doc/html/mpi.html
  • 真的!!谢谢它的工作!我错过了这一行:m_image_data2.resize(5);
  • 您不需要使用&amp;m_image_data2[0]std::vector 获取数据,有一个.data() 函数可以做到这一点;即&amp;m_image_data2[0] == m_image_data2.data()
  • @wolfPack88 std::vector.data() 是 C++11 功能,它可能不适用于 OP,但是是的,这是一种不那么冗长的方式。
  • 我认为英特尔和 GCC 早在 2010 年就已经有了它,当时它还没有成为标准的一部分。不过,这很公平。
【解决方案2】:

考虑Boost::MPI,它明确支持例如std::vector 通过 Boost::Serialization。

当然,Boost::MPI 不支持所有 MPI 3.0,而是支持 MPI 1.3(可能是 MPI 2.2 的子集,但绝对不是 RMA),因此它不是一个完美的解决方案。但是,如果你只使用 MPI-1 中引入的 MPI 的常用功能,那应该没问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-06
    • 2011-11-11
    • 2018-09-10
    • 2014-04-17
    • 2011-01-24
    • 1970-01-01
    • 2020-03-23
    • 2017-10-25
    相关资源
    最近更新 更多