структурированная сериализация в C и передача через MPI

Я определил пользовательскую структуру и хочу отправить ее другому процессу MPI с помощью MPI_Bsend (или MPI_Send).

Вот моя структура:

struct car{ int shifts; int topSpeed; }myCar; 

Однако, помимо примитивных типов, MPI, похоже, не поддерживает прямую «передачу» сложных типов данных, таких как структура выше. Я слышал, что мне, возможно, придется использовать «сериализацию». Как мне это сделать и отправить «myCar» для обработки 5?

Иеремия прав – MPI_Type_create_struct – это путь сюда.

Важно помнить, что MPI – это библиотека, не встроенная в язык; поэтому он не может «видеть», как выглядит структура, чтобы сериализовать ее самостоятельно. Поэтому для отправки сложных типов данных вы должны явно определить его макет. На языке, который имеет встроенную поддержку для сериализации, набор оберток MPI может с успехом использовать это; mpi4py, например, использует пиренейский рассол для прозрачной отправки сложных типов данных; но в С, вам нужно засучить armва и сделать это сами.

Для вашей структуры это выглядит так:

 #include  #include  #include  #include  typedef struct car_s { int shifts; int topSpeed; } car; int main(int argc, char **argv) { const int tag = 13; int size, rank; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); if (size < 2) { fprintf(stderr,"Requires at least two processes.\n"); exit(-1); } /* create a type for struct car */ const int nitems=2; int blocklengths[2] = {1,1}; MPI_Datatype types[2] = {MPI_INT, MPI_INT}; MPI_Datatype mpi_car_type; MPI_Aint offsets[2]; offsets[0] = offsetof(car, shifts); offsets[1] = offsetof(car, topSpeed); MPI_Type_create_struct(nitems, blocklengths, offsets, types, &mpi_car_type); MPI_Type_commit(&mpi_car_type); MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (rank == 0) { car send; send.shifts = 4; send.topSpeed = 100; const int dest = 1; MPI_Send(&send, 1, mpi_car_type, dest, tag, MPI_COMM_WORLD); printf("Rank %d: sent structure car\n", rank); } if (rank == 1) { MPI_Status status; const int src=0; car recv; MPI_Recv(&recv, 1, mpi_car_type, src, tag, MPI_COMM_WORLD, &status); printf("Rank %d: Received: shifts = %d topSpeed = %d\n", rank, recv.shifts, recv.topSpeed); } MPI_Type_free(&mpi_car_type); MPI_Finalize(); return 0; } 

Хотя ответ Джонатана Дурси верен, он слишком сложный. MPI предоставляет более простые и менее общие типы конструкторов, более подходящие для вашей проблемы. MPI_Type_create_struct ТОЛЬКО нужен, если у вас разные базовые типы (например, int и float).

Для вашего примера существует несколько лучших решений:

  • Предполагая, что два целых числа выровнены в смежной области памяти (т. Е. Как массив целых чисел), вам вообще не нужен производный тип данных. Просто отправьте / получите два элемента типа MPI_INT с адресом переменной типа car который будет использоваться в качестве буфера отправки / получения:

     MPI_Send(&send, 2, MPI_INT, dest, tag, MPI_COMM_WORLD); MPI_Recv(&recv, 2, MPI_INT, src, tag, MPI_COMM_WORLD, &status); 
  • Если вы хотите использовать производный тип данных (например, для удобства чтения или удовольствия от него), вы можете использовать MPI_Type_contiguous который соответствует массивам:

     MPI_Type_contiguous(2, MPI_INT, &mpi_car_type); 
  • В случае, если два целых числа выровнены по-разному (скорее всего, это не так, но это зависит от машины и реализации MPI для множества разных платформ), вы можете использовать MPI_Type_indexed_block : он принимает массив перемещений (например, MPI_Type_create_struct ), но только один аргумент oldtype и длина блока каждого блока равны 1 по определению:

     MPI_Aint offsets[2]; offsets[0] = offsetof(car, shifts) ; //most likely going to be 0 offsets[1] = offsetof(car, topSpeed); MPI_Type_indexed_block(2, offsets, MPI_INT); 

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

Посмотрите на MPI_Type_create_struct чтобы создать собственный тип данных MPI для вашего объекта. Пример его использования – http://beige.ucs.indiana.edu/I590/node100.html .

  • Какая польза для тегов в Go?
  • Являются ли C-структуры с теми же типами членов, которые имеют одинаковый макет в памяти?
  • C: указатель на структуру в определении структуры
  • Изменить переменную Struct в словаре
  • Не уникальные значения enums
  • Почему GCC не оптимизирует структуры?
  • Почему я не могу скопировать инициализацию структуры, полученной из другой структуры?
  • Невозможно изменить ошибку возвращаемого значения c #
  • Макет в памяти структуры. структура массивов и массив структур в C / C ++
  • Какие анонимные структуры и союзы полезны для C11?
  • Есть ли недостатки для передачи структур по значению в C, а не для передачи указателя?
  • Interesting Posts

    Преобразование символа в числовое значение ASCII в java

    mod_rewrite: заменить подчеркивания тире

    Настройка Access-Control-Allow-Origin в ASP.Net MVC – простейший возможный метод

    Как добавить глобальные фильтры ASPI Web Api?

    Обновление пользовательских данных – Идентификация ASP.NET

    Как получить список всех установленных пакетов вместе с версией в композиторе?

    В чем разница между JSF, Servlet и JSP?

    Сохранение изображения в plist

    Простой и быстрый метод сравнения изображений для сходства

    Вставьте заголовок в документ LibreOffice Writer

    Любое изменение в любом файле в папке bin приводит к переработке приложения в веб-приложении ASP.NET?

    Сделать локальную среду разработки MAMP доступной извне?

    Можно ли инициализировать атрибут C # с массивом или другим переменным числом аргументов?

    размещение файла в пути к classам

    Как заставить скрипт bash ждать, а затем продолжить работу?

    Давайте будем гением компьютера.