4

我正在尝试使用 boost::mpi::send () 调用发送一个名为 ABC 的用户定义结构。

给定的结构包含一个向量“数据”,其大小在运行时确定。结构 ABC 的对象由 master 发送到 slave。但是从站需要知道向量“数据”的大小,以便从站上有足够的缓冲区来接收这些数据。我可以通过先发送大小并在接收结构 ABC 的对象之前在从属设备上初始化足够的缓冲区来解决它。但这违背了使用 STL 容器的全部目的。

有谁知道更好的方法来处理这个问题?非常感谢任何建议。

这是描述我的程序意图的示例代码。由于上述原因,此代码在运行时失败。

struct ABC
{
 double cur_stock_price;
 double strike_price;
 double risk_free_rate;
 double option_price;
 std::vector <char> data;
};

namespace boost
{
 namespace serialization
 {
   template<class Archive>
   void serialize (Archive &ar,
                   struct ABC &abc,
                   unsigned int version)
   {
     ar & abc.cur_stock_price;
     ar & abc.strike_price;
     ar & abc.risk_free_rate;
     ar & abc.option_price;
     ar & bopr.data;
   }
 }
}

BOOST_IS_MPI_DATATYPE (ABC);

int main(int argc, char* argv[])
{
 mpi::environment env (argc, argv);
 mpi::communicator world;

 if (world.rank () == 0)
 {
   ABC abc_obj;
  abc.cur_stock_price = 1.0;
  abc.strike_price = 5.0;
  abc.risk_free_rate = 2.5;
  abc.option_price = 3.0;
  abc_obj.data.push_back ('a');
  abc_obj.data.push_back ('b');

   world.send ( 1, ANY_TAG, abc_obj;);
   std::cout << "Rank 0 OK!" << std::endl;
 }

else if (world.rank () == 1)
{
   ABC abc_obj;

  // Fails here because abc_obj is not big enough
   world.recv (0,ANY_TAG, abc_obj;);
   std::cout << "Rank 1 OK!" << std::endl;

   for (int i = 0; i < abc_obj;.data.size(); i++)
     std::cout << i << "=" << abc_obj.data[i] << std::endl;
 }

 MPI_Finalize();
 return 0;
}
4

2 回答 2

3

您不应该vector在消息中发送对象本身,因为接收者只需要它的内容,并且vector无论如何接收后的内部状态可能都会变得混乱(在发送端有效的内存地址可能不会是在接收端有效)。

相反,这是您需要做的:

  1. 用四个双精度和一个简单的字符数组定义一个单独的结构。
  2. 每当您需要发送时,为这个新结构创建一个临时变量,并用vector您要发送的内容填充 char 数组。
  3. 定义与此特定结构对象的大小匹配的临时 MPI 数据类型。
  4. 将临时结构作为此临时数据类型的实例发送。
  5. 在适当大的接收缓冲区中接收它(或提前发送大小)
  6. 根据 char 数组的内容重构 ABC 结构。

至少,这就是你需要用 vanilla C++ 和 MPI 做的事情。我不熟悉 boost,所以我不知道它是否会使这些步骤中的任何一个变得更容易。

于 2010-04-21T18:23:05.647 回答
0

BOOST_IS_MPI_DATATYPE仅用于固定长度数据。您的数组不是固定长度的,这就是它失败的原因。

于 2010-04-30T18:54:14.157 回答