Векторное использование в 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),

8
задан KeithB 30 March 2010 в 19:26
поделиться

4 ответа

Определение структур в 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);
11
ответ дан 5 December 2019 в 18:58
поделиться

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

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

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

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

-2
ответ дан 5 December 2019 в 18:58
поделиться

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

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

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

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

0
ответ дан 5 December 2019 в 18:58
поделиться

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

Отправка:

  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);
    }
0
ответ дан 5 December 2019 в 18:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: