Как передать определяемые пользователем структуры с помощью boost mpi - PullRequest
4 голосов
/ 21 апреля 2010

Я пытаюсь отправить пользовательскую структуру с именем ABC с помощью вызова boost :: mpi :: send ().

Данная структура содержит вектор «данных», размер которого определяется во время выполнения. Объекты struct ABC отправляются мастером подчиненным. Но ведомые устройства должны знать размер векторных «данных», чтобы на ведомом устройстве был доступен достаточный буфер для получения этих данных. Я могу обойти это, отправив сначала размер и инициализируя достаточный буфер на ведомом устройстве, прежде чем получать объекты struct 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;
}

Ответы [ 2 ]

3 голосов
/ 21 апреля 2010

Вы не должны отправлять сам объект vector в сообщении, так как получателю нужно только его содержимое, и внутреннее состояние vector, вероятно, будет все испорчено после получения в любом случае (адреса памяти были действительны на передающем конце, вероятно, не будет действительным на принимающем конце).

Вместо этого вот что вам нужно сделать:

  1. Определите отдельную структуру с четырьмя двойными числами и простым массивом символов.
  2. Всякий раз, когда вам нужно отправить, создайте временную переменную этой новой структуры и заполните массив char содержимым vector, которое вы хотите отправить.
  3. Определить временный тип данных MPI, соответствующий размеру этого конкретного объекта структуры.
  4. Отправьте временную структуру как экземпляр этого временного типа данных.
  5. Получите его в подходящем большом буфере приема (или отправьте размер заранее)
  6. Реконструировать структуру ABC на основе содержимого массива char.

По крайней мере, это то, что вам нужно делать с vanilla C ++ и MPI. Я не знаком с бустом, поэтому не знаю, облегчает ли это какой-либо из этих шагов.

0 голосов
/ 30 апреля 2010

BOOST_IS_MPI_DATATYPE только для данных фиксированной длины . Ваш массив не имеет фиксированной длины, поэтому он не работает.

...