Использование векторов в MPI (C++)

Я новичок в программировании MPI, все еще учусь, мне удавалось создавать производные типы данных, определяя структуры. Теперь я хочу включить вектор в свою структуру и отправить данные через процесс. например:

struct Structure{

//Constructor 
Structure(): X(nodes),mass(nodes),ac(nodes) {

//code to calculate the mass and accelerations
}
//Destructor
Structure() {}

//Variables
double radius;
double volume;
vector<double> mass;
vector<double> area;

//and some other variables

//Methods to calculate some physical properties

Теперь, используя MPI, я хочу отправить данные в структуре через процессы. Могу ли я создать векторы MPI_type_struct и отправить данные?

Я пытался читать форумы, но я не могу получить четкую картину из ответов, данных там. Надеюсь, я смогу получить четкое представление или подход к отправке данных

PS: я могу отправлять данные по отдельности, но это накладные расходы на отправку данных с использованием MPI_Send/Recieve, если мы считаем домен очень большим (скажем, 10000 * 10000)


person lsk1985    schedule 30.03.2010    source источник


Ответы (5)


Определение структур в MPI — это боль. Я думаю, что более простым подходом было бы использование того факта, что векторы STL гарантированно имеют непрерывно выделенную память. То есть вы можете обращаться с ними как с массивами C, получая указатель на первый элемент.

std::vector<float> data;
// ... add elements to your vector ...
MPI_Send(&data.front(), data.size(), MPI_FLOAT, 0, 1, MPI_COMM_WORLD);
person E.M.    schedule 30.03.2010
comment
Спасибо за быстрый ответ, проблема в том, что я хочу отправить всю структуру за один раз вместо отправки одной переменной вектора и других типов данных, тем самым уменьшая накладные расходы на связь между процессами... и у меня есть 10 векторов для отправки через для связи .... следовательно, это приводит к замедлению времени вычислений и снижению эффективности - person lsk1985; 30.03.2010
comment
@ lsk1985, хорошо, у меня недостаточно опыта работы с MPI, чтобы чем-то помочь. Прости. Я бы просто старался избегать отправки указателей между процессами (вместо данных, на которые они указывают). - person E.M.; 30.03.2010
comment
Если у вас есть массив указателей, создайте MPI_Type_hindexed, представляющий собой строку блоков со смещением, выраженным в байтах. Требуется только небольшая адресная арифметика. - person Victor Eijkhout; 12.12.2013

Я описываю свое решение аналогичной проблемы здесь:

Сообщения, передающие графы произвольных объектов?

Помните, что вы можете создавать пользовательские типы данных MPI из ранее определенных пользовательских типов данных MPI. Например, вы можете определить Struct, который описывает макет и содержимое одного экземпляра Structure, а затем вектор из этих типов данных Struct для всего вектора объектов. Черт возьми, если у вас есть несколько таких векторов, вы можете создать третий уровень абстракции, создав тип данных HIndexed из векторов структур, а затем отправить их все одним сообщением.

В сообщении, на которое я ссылался выше, вы найдете ссылки на описания различных пользовательских типов данных MPI, которые должны помочь вам выбрать правильный подход.

person suszterpatt    schedule 02.04.2010
comment
Спасибо за ссылку и вашу идею, как подойти к проблеме - person lsk1985; 09.04.2010

Я делаю то же, что и вы, и знаю, что архитектура моего процессора однородна. Я избегаю большого количества подстановок байтов и большого количества упаковки и распаковки MPI, используя Увеличить сериализацию.

Отправка:

  ostringstream oss;
  {
    binary_oarchive oa(oss);
    oa << BOOST_SERIALIZATION_NVP(myStruct);
  }

  MPI::COMM_WORLD.Send(oss.str().c_str(),
                       oss.str().size(),
                       MPI::Datatype(MPI_BYTE),
                       MpiLibWrapper::DEST_PROC_RANK,
                       MpiLibWrapper::MY_STRUCT_TAG);

Получение:

    vector<char> incomingBuffer(MAX_BUFFER_SIZE);

    MPI::COMM_WORLD.Recv(&incomingBuffer[0], incomingBuffer.size(),
                         MPI::Datatype(MPI_BYTE),
                         MpiLibWrapper::SRC_PROC_RANK,
                         MpiLibWrapper::MY_STRUCT_TAG,
                         msgStatus);
    if (MpiLibWrapper::ErrorOccurred(msgStatus.Get_error(),
                                     info.logging)) {
      break;
    }
    incomingBuffer.resize(msgStatus.Get_count(MPI::Datatype(MPI_BYTE)));

    if (incomingBuffer.size() > 0) {
      // Shockingly, this does not result in a memory allocation.
      istringstream iss(string(&incomingBuffer[0], incomingBuffer.size()));

      binary_iarchive ia(iss);

      ia >> BOOST_SERIALIZATION_NVP(myStruct);
    }
person Jim Hunziker    schedule 05.04.2010
comment
Я понятия не имею о сериализации Boost, может быть, мне нужно потратить некоторое время на ее понимание и посмотреть, решит ли это проблему, с которой я столкнулся. Спасибо за ваше предложение. - person lsk1985; 09.04.2010

Хм... Отправка структуры C/C++ в виде потока данных работает только тогда, когда вы гарантируете, что расположение данных на всех участвующих машинах точно такое же. В общем, так не получится. Кроме того, есть люди, которые утверждают, что отправка структуры, упакованной как тип данных, производный от MPI, +1 для ясности кода и демонстрации намерения.

person devendra rai    schedule 05.01.2012

Я, конечно, не специалист по структурам данных MPI, но не думаю, что это можно сделать. Причина в том, что в основном у вас есть структура с указателями на отправляемые данные. Все функции типов данных MPI предполагают, что данные, которые вы хотите послать, находятся в непрерывной области памяти. Если векторы имеют фиксированный максимальный размер, и вы можете сделать

double radius;
double volume;
int mass_size;
int area_size;
double mass[MASS_MAXLEN];
double area[AREA_MAXLEN];

а затем отправлять только те элементы, которые заполнены.

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

person KeithB    schedule 30.03.2010
comment
да, мне нужно попробовать и посмотреть, будет ли отправка отдельных векторов проще, спасибо за предложение - person lsk1985; 09.04.2010
comment
Все функции типов данных MPI предполагают, что данные, которые вы хотите послать, находятся в непрерывной области памяти. - хотя это правда, вы можете определить пользовательские типы данных MPI, которые представляют произвольную структуру памяти (см. мой ответ). Таким образом, вы можете определить тип данных из ваших указателей, а затем отправить сообщение как один экземпляр этого типа данных, достигнув тем самым требуемого результата. - person suszterpatt; 11.04.2010