next up previous contents
Next: Выбор используемого метода передачи Up: Группировка данных для пересылки Previous: Другие конструкторы производных типов   Contents

Упаковка и распаковка

Альтернативный подход к группировке данных реализован функциями MPI_Pack() и MPI_Unpack(). MPI_Pack() позволяет явно хранить данные, состоящие из нескольких несмежных участков, в смежных областях памяти. MPI_Unpack() может использоваться для копирования данных из смежного буфера в области памяти, состоящие из нескольких несмежных участков.

Для иллюстрации этих функций можно привести еще один вариант текста функции Get_data():

void Get_data4(int my_rank, float* a_ptr, float* b_ptr,

    int* n_ptr) {

  int root = 0; /* Аргумент для MPI_Bcast */

  char buffer[100]; /* Аргументы для MPI_Pack/Unpack */

  int position; /* и MPI_Bcast*/

  if (my_rank == 0) {

    printf(''Введите a, b, и n\n'');

    scanf(''%f %f %d'', a_ptr, b_ptr, n_ptr);

    /* Упаковка данных в буфер */

    position = 0; /* Начать с начала буфера */

    MPI_Pack(a_ptr, 1, MPI_FLOAT, buffer, 100,

      &position, MPI_COMM_WORLD);

    /* Position будет увеличена на */

    /* sizeof(float) байт */

    MPI_Pack(b_ptr, 1, MPI_FLOAT, buffer, 100,

      &position, MPI_COMM_WORLD);

    MPI_Pack(n_ptr, 1, MPI_INT, buffer, 100,

      &position, MPI_COMM_WORLD);

    /* Разослать содержимое буфера */

    MPI_Bcast(buffer, 100, MPI_PACKED, root,

       MPI_COMM_WORLD);

  } else {

    MPI_Bcast(buffer, 100, MPI_PACKED, root,

       MPI_COMM_WORLD);

    /* Распаковать содержимое буфера */

    position = 0;

    MPI_Unpack(buffer, 100, &position, a_ptr, 1,

    MPI_FLOAT, MPI_COMM_WORLD);

    /* Позиция снова увеличивается на */

    /* sizeof(float) байт */ 

    MPI_Unpack(buffer, 100, &position, b_ptr, 1,

       MPI_FLOAT, MPI_COMM_WORLD);

    MPI_Unpack(buffer, 100, &position, n_ptr, 1,

       MPI_INT, MPI_COMM_WORLD);

  }

} /* Get-data4 */

В этой версии Get_data() процесс 0 использует MPI_Pack(), чтобы скопировать в буфер a, а затем добавить к нему b и n. После широковещательной рассылки буфера остальные процессы используют MPI_Unpack(), чтобы извлечь a, b, n из буфера. Тип данных в вызове MPI_Bcast() указан как MPI_PACKED.

Синтаксис вызова MPI_Pack():

int MPI_Pack(void* pack_data, int in_count,

       MPI_Datatype datatype, void* buffer, int size,

       int* position_ptr, MPI_Comm comm)

Параметр pack_data указывает на данные, которые будут буферизованы. Они состоят из in_count элементов, каждый из которых имеет тип datatype. Параметр position_ptr является параметром ввода / вывода. При вводе данные, на которые указывает pack_data копируются в память, начинающуюся в буфере по адресу buffer + *position_ptr. При возвращении *position_ptr ссылается на первую ячейку в буфере после данных, которые были скопированы. Параметр size содержит размер в байтах памяти, на которую указывает буфер, а comm определяет коммуникатор, который будет использовать буфер.

Синтаксис MPI_Unpack():

int MPI_Unpack(void* buffer, int size,

       int* position_ptr, void* unpack_data,

       int count, MPI_Datatype datatype,

       MPI_comm comm);

Параметр buffer ссылается на данные, которые должны быть распакованы. Они содержат size байт. Параметр position_ptr является параметром ввода/вывода. При вызове MPI_Unpack() данные, начинающиеся в буфере по адресу buffer + *position_ptr, копируются в память, на которую указывает unpack_data. При возвращении *position_ptr ссылается на первую ячейку в буфере после данных, которые были только что скопированы. MPI_Unpack() копирует count элементов, имеющих тип datatype в unpack_data. Коммуникатор, связанный с буфером обозначен через comm.



2004-06-22