Параллельное программирование: Учебное пособие, страница 125

·  datatype — тип каждого выходного элемента данных;

·  comm — коммуникатор для упаковываемого сообщения.

Выходной параметр outbuf — стартовый адрес выходного буфера.

Подпрограмма MPI_Pack_size позволяет по значению параметра size определить объем памяти в байтах, который необходим для распаковки сообщения:

int MPI_Pack_size(int incount, MPI_Datatype datatype,

MPI_Comm comm, int *size)

Входные параметры:

·  incount — аргумент count, использованный при упаковке;

·  datatype — тип упакованных данных;

·  comm — коммуникатор.

Текст 6.5. Пример использования подпрограмм упаковки

#include "mpi.h"

#include <stdio.h>

int main(int argc, char *argv[])

{

int myrank;

float a, b;

int n;

int root = 0;

char buffer[100];

int position;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

if (myrank == root)

{

printf("Enter a, b, and n\n");

scanf("%f %f %i", &a, &b, &n) ;

position = 0;

MPI_Pack(&a, 1, MPI_FLOAT, &buffer, 100,

&position, MPI_COMM_WORLD);

MPI_Pack(&b, 1, MPI_FLOAT, &buffer, 100,

&position, MPI_COMM_WORLD);

MPI_Pack(&n, 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, 1,

MPI_FLOAT, MPI_COMM_WORLD);

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

MPI_FLOAT, MPI_COMM_WORLD);

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

 MPI_INT, MPI_COMM_WORLD);

printf("Process %i received a=%f, b=%f, n=%i\n",

myrank, a, b, n);

}

MPI_Finalize();

return 0;

}

Здесь процесс 0 копирует в буфер сначала значение а, а потом дописывает туда b и n. После выполнения широковещательной рассылки главным процессом, остальные используют подпрограмму MPI_Unpack для извлечения а, bи n из буфера. Тип данных, который надо использовать при вызове MPI_BcastMPI_PACKED.

6.6.1  Типы   MPI_BYTE и MPI_PACKED

Специальный тип данных  MPI_BYTE не имеет аналога в С/С++. Этот тип определяет хранение данных в формате, имеющем одинаковое двоичное представление на стороне источника сообщения и на стороне адресата. Такой тип данных можно использовать при передаче любых сообщений в однородных вычислительных системах.

Типы MPI_BYTE и  MPI_PACKED в качестве значений при передачах содержат байт, который, однако, интерпретируется иначе, чем символ. Представление символа может различаться на разных машинах, а байт везде одинаков, поэтому тип MPI_BYTE может использоваться, если необходимо выполнить преобразование между разными представлениями в гетерогенной вычислительной системе.

6.7  Атрибуты коммуникаторов

Кэширование позволяет добавить к коммуникатору дополнительную информацию, которую называют атрибутами коммуникатора. Это дает возможность пересылать информацию, связывая ее с коммуникаторами любого типа: интра- и интер-. Коммуникатор, снабженный атрибутами, содержит группу процессов, контекст обмена и кэшированные данные (в том числе, возможно, и виртуальную топологию).

Если какая-то информация записана в качестве атрибута в одном из процессов, она автоматически становится доступной всем другим процессам из данного коммуникатора. Специальной организации пересылок сообщений при этом не требуется, система сама позаботится о передаче необходимой информации.

Атрибуты определяются только для того коммуникатора, к которому они присоединены. Они могут дублироваться только при дублировании коммуникатора, других способов их передачи от одного коммуникатора другому нет.

В языке С атрибуты имеют тип void*. Обычно это указатели на структуры, которые содержат необходимую информацию или обработчики для объекта MPI.

Идентификатором атрибута является целое число, которое назначается системой автоматически и называется ключом атрибута. Атрибуты бывают системные и пользовательские. Системные атрибуты не могут модифицироваться программистом, во всяком случае, напрямую. К их числу относятся топология, адрес обработчика ошибок и некоторые другие. Значения ключей являются глобальными и могут использоваться всеми коммуникаторами программы.