Я плохо знаком с программированием 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),
Определение структур в 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);
Я, конечно, не эксперт по структуре данных MPI, но я не думаю, что это можно сделать. Причина в том, что в основном у вас есть структура с указателями на отправляемые данные. Все функции типов данных MPI предполагают, что данные, которые вы хотите отправить, находятся в непрерывной области памяти. Если векторы имеют фиксированный максимальный размер, и вы можете сделать
double radius;
double volume;
int mass_size;
int area_size;
double mass[MASS_MAXLEN];
double area[AREA_MAXLEN];
, а затем отправить только те элементы, которые заполнены.
В качестве альтернативы, вы можете сами упаковать данные в один массив перед отправкой и отправить массив . Вам придется провести некоторое профилирование, чтобы увидеть, быстрее ли это, чем при раздельной отправке.
Я описываю свое решение аналогичной проблемы здесь:
Сообщение, передающее графы произвольных объектов?
Помните, что вы можете создавать пользовательские типы данных MPI из предварительно определенных пользовательских типов данных MPI. Например, вы можете определить структуру, которая описывает макет и содержимое одного экземпляра структуры, а затем вектор из этих типов данных структуры для всего вектора объектов. Черт возьми, если у вас есть несколько таких векторов, вы можете создать третий уровень абстракции, создав HIndexed тип данных из векторов структур, а затем отправить их все с одним сообщением.
В сообщении, на которое я указал выше, вы найдете ссылки на описания различных пользовательских типов данных MPI, которые должны помочь вам выбрать правильный подход.
Я делаю то же самое, что и вы, и знаю, что архитектура моего процессора однородна. Я избегаю частой перестановки байтов и большого количества упаковки и распаковки 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);
}