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

1. Конструирование типа.

2. Регистрация типа.

После завершения работы с производным типом он удаляется. Все производные от него типы остаются и могут использоваться дальше, пока и они не будут уничтожены. Производные типы данных создаются из базовых типов с помощью подпрограмм-конструкторов. Операции создания производных типов могут применяться рекурсивно, что дает программисту большую свободу в организации сложных типов данных.

Производный тип данных в MPI характеризуется последовательностью базовых типов и набором целочисленных значений смещения. Смещения отсчитываются относительно начала буфера обмена и определяют те элементы данных, которые будут участвовать в обмене. Смещения могут принимать как положительные, так и отрицательные значения. Не требуется также, чтобы они были каким-либо образом упорядочены. Кроме того, один элемент данных может появляться в новом типе многократно. Последовательный набор пар (тип, смещение) называется картой типа (табл. 6.3).

Таблица 6.3. Карта производного типа данных

1-й элемент пары

2-й элемент пары

Базовый тип 0

Смещение базового типа 0

Базовый тип 1

Смещение базового типа 1

Базовый тип 2

Смещение базового типа 2

Базовый тип  n—1

Смещение базового типа  n—1

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

6.5.1  Конструкторы производных типов

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

Конструктор MPI_Type_vector создает векторный тип:

int MPI_Type_vector(int count, int blocklen,

int stride, MPI_Datatype oldtype,

MPI_Datatype *newtype)

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

·  count — количество блоков;

·  blocklen — длина каждого блока (количество элементов);

·  stride — количество элементов, расположенных между началом предыдущего и началом следующего блока;

·  oldtype — базовый тип.

Выходным параметром является идентификатор нового типа newtype, назначаемый программистом. данные здесь. Схема расположения исходных однотипных данных в новом типе представлена на рис. 6.10.

Базовый тип

Векторный типcount=2stride=4blocklen=3

Рис. 6.10. Схема векторного типа данных

Например, если

count=2;

stride=4;

blocklen=3;

oldtype = double;

то карта нового типа  newtype  будет выглядеть так:

{(double, 0), (double, 1), (double, 2),

(double, 4), (double, 5), (double, 6)}

При вызове подпрограммы MPI_Type_hvector смещения задаются в байтах:

int MPI_Type_hvector(int count, int blocklen,

MPI_Aint stride, MPI_Datatype oldtype,

MPI_Datatype *newtype)

Смысл и назначение параметров этой подпрограммы совпадают с подпрограммой MPI_Type_vector. Различие только в том, что значение параметра stride задается в байтах.

Конструктором структурного типа является подпрограмма MPI_Type_struct. Она позволяет создать тип, содержащий элементы различных базовых типов:

intMPI_Type_struct(intcount, intblocklengths[],

MPI_Aint indices[], MPI_Datatype oldtypes[],

MPI_Datatype *newtype)

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

·  count — задает количество элементов в производном типе, а также длину массивов oldtypesindices  и  blocklengths;

·  blocklengths — количество элементов в каждом блоке (массив);