Здавалка
Главная | Обратная связь

Производные типы данных



Производные типы MPI не являются в полном смысле типами данных, как это понимается в языках программирования. Они не могут использоваться ни в каких других операциях, кроме коммуникационных. Производные типы MPI следует понимать как описатели расположения в памяти элементов базовых типов. Производный тип MPI представляет собой скрытый (opaque) объект, который специфицирует две вещи: последовательность базовых типов и последовательность смещений. Последовательность таких пар определяется как отображение (карта) типа:

Typemap = {(type0, disp0), ... , (typen-1, dispn-1)}

Значения смещений не обязательно должны быть неотрицательными, различными и упорядоченными по возрастанию. Отображение типа вместе с базовым адресом начала расположения данных buf определяет коммуникационный буфер обмена. Этот буфер будет содержать n элементов, а i-й элемент будет иметь адрес buf+disp и иметь базовый тип type. Стандартные типы MPI имеют предопределенные отображения типов. Например, MPI_INT имеет отображение {(int,0)}.

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

Стандартный сценарий определения и использования производных типов включает следующие шаги:

  • Производный тип строится из предопределенных типов MPI и ранее определенных производных типов с помощью специальных функций-конструкторов MPI_Type_contiguous, MPI_Type_vector, MPI_Type_hvector, MPI_Type_indexed, MPI_Type_hindexed, MPI_Type_struct.
  • Новый производный тип регистрируется вызовом функции MPI_Type_commit. Только после регистрации новый производный тип можно использовать в коммуникационных подпрограммах и при конструировании других типов. Предопределенные типы MPI считаются зарегистрированными.
  • Когда производный тип становится ненужным, он уничтожается функцией MPI_Type_free.

Любой тип данных в MPI имеет две характеристики: протяженность и размер, выраженные в байтах:

  • Протяженность типа определяет, сколько байт переменная данного типа занимает в памяти. Эта величина может быть вычислена как:
    адрес последней ячейки данных - адрес первой ячейки данных + длина последней ячейки данных (опрашивается подпрограммой MPI_Type_extent).
  • Размер типа определяет количество реально передаваемых байт в коммуникационных операциях. Эта величина равна сумме длин всех базовых элементов определяемого типа (опрашивается подпрограммой MPI_Type_size).

Для простых типов протяженность и размер совпадают.

Функция MPI_Type_extent определяет протяженность элемента некоторого типа.

C:

int MPI_Type_extent(MPI_Datatype datatype, MPI_Aint *extent)

FORTRAN:

MPI_TYPE_EXTENT(DATATYPE, EXTENT, IERROR)

INTEGER DATATYPE, EXTENT, IERROR

IN datatype - тип данных;
OUT extent - протяженность элемента заданного типа.

Функция MPI_Type_size определяет "чистый" размер элемента некоторого типа (за вычетом пустых промежутков).

C:

int MPI_Type_size(MPI_Datatype datatype, int *size)

FORTRAN:

MPI_TYPE_SIZE(DATATYPE, SIZE, IERROR)

INTEGER DATATYPE, SIZE, IERROR

IN datatype - тип данных;
OUT size - размер элемента заданного типа.

Как отмечалось выше, для создания производных типов в MPI имеется набор специальных функций-конструкторов. Рассмотрим их в последовательности от простого к сложному.

Самый простой конструктор типа MPI_Type_contiguous создает новый тип, элементы которого состоят из указанного числа элементов базового типа, занимающих смежные области памяти.

C:

int MPI_Type_contiguous(int count, MPI_Datatype oldtype,

MPI_Datatype *newtype)

FORTRAN:

MPI_TYPE_CONTIGUOUS(COUNT, OLDTYPE, NEWTYPE, IERROR)

INTEGER COUNT, OLDTYPE, NEWTYPE, IERROR

IN count - число элементов базового типа;
IN oldtype - базовый тип данных;
OUT newtype - новый производный тип данных.

 

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

C:

int MPI_Type_vector(int count, int blocklength, int stride,

MPI_Datatype oldtype, MPI_Datatype *newtype)

FORTRAN:

MPI_TYPE_VECTOR(COUNT, BLOCKLENGTH, STRIDE, OLDTYPE,

NEWTYPE, IERROR)

INTEGER COUNT, BLOCKLENGTH, STRIDE, OLDTYPE, NEWTYPE, IERROR

IN count - число блоков;
IN blocklength - число элементов базового типа в каждом блоке;
IN stride - шаг между началами соседних блоков, измеренный числом элементов базового типа;
IN oldtype - базовый тип данных;
OUT newtype - новый производный тип данных.

Функция создает тип newtype, элемент которого состоит из count блоков, каждый из которых содержит одинаковое число blocklength элементов типа oldtype. Шаг stride между началом блока и началом следующего блока всюду одинаков и кратен протяженности представления базового типа.

Конструктор типа MPI_Type_hvector расширяет возможности конструктора MPI_Type_vector, позволяя задавать произвольный шаг между началами блоков в байтах.

C:

int MPI_Type_hvector(int count, int blocklength, MPI_Aint stride,

MPI_Datatype oldtype, MPI_Datatype *newtype)

FORTRAN:

MPI_TYPE_HVECTOR(COUNT, BLOCKLENGTH, STRIDE, OLDTYPE,

NEWTYPE, IERROR)

INTEGER COUNT, BLOCKLENGTH, STRIDE, OLDTYPE, NEWTYPE, IERROR

IN count - число блоков;
IN blocklength - число элементов базового типа в каждом блоке;
IN stride - шаг между началами соседних блоков в байтах;
IN oldtype - базовый тип данных;
OUT newtype - новый производный тип данных.

Графическая интерпретация работы конструктора MPI_Type_hvector приведена на рис. 14.

Рис. 14. Графическая интерпретация работы конструктора MPI_Type_hvector.

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

C:

int MPI_Type_indexed(int count, int *array_of_blocklengths,

int *array_of_displacements, MPI_Datatype oldtype,
MPI_Datatype *newtype)

FORTRAN:

MPI_TYPE_INDEXED(COUNT, ARRAY_OF_BLOCKLENGTHS,

ARRAY_OF_DISPLACEMENTS, OLDTYPE, NEWTYPE, IERROR)

INTEGER COUNT, ARRAY_OF_BLOCKLENGTHS(*), ARRAY_OF_DISPLACEMENTS(*),

OLDTYPE, NEWTYPE, IERROR

IN count - число блоков;
IN array_of_blocklengths - массив, содержащий число элементов базового типа в каждом блоке;
IN array_of_displacements - массив смещений каждого блока от начала размещения элемента нового типа, смещения измеряются числом элементов базового типа;
IN oldtype - базовый тип данных;
OUT newtype - новый производный тип данных.

Эта функция создает тип newtype, каждый элемент которого состоит из count блоков, где i-ый блок содержит array_of_blocklengths[i] элементов базового типа и смещен от начала размещения элемента нового типа на array_of_displacements[i] элементов базового типа.

Конструктор типа MPI_Type_hindexed идентичен конструктору MPI_Type_indexed за исключением того, что смещения измеряются в байтах.

C:

int MPI_Type_hindexed(int count, int *array_of_blocklengths,

MPI_Aint *array_of_displacements, MPI_Datatype oldtype,
MPI_Datatype *newtype)

FORTRAN:

MPI_TYPE_HINDEXED(COUNT, ARRAY_OF_BLOCKLENGTHS,

ARRAY_OF_DISPLACEMENTS, OLDTYPE, NEWTYPE, IERROR)

INTEGER COUNT, ARRAY_OF_BLOCKLENGTHS(*), ARRAY_OF_DISPLACEMENTS(*),

OLDTYPE, NEWTYPE, IERROR

IN count - число блоков;
IN array_of_blocklengths - массив, содержащий число элементов базового типа в каждом блоке;
IN array_of_displacements - массив смещений каждого блока от начала размещения элемента нового типа, смещения измеряются в байтах;
IN oldtype - базовый тип данных;
OUT newtype - новый производный тип данных.

Элемент нового типа состоит из count блоков, где i-ый блок содержит array_of_blocklengths[i] элементов старого типа и смещен от начала размещения элемента нового типа на array_of_displacements[i] байт.

 

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

C:

int MPI_Type_struct(int count, int *array_of_blocklengths,

MPI_Aint *array_of_displacements, MPI_Datatype *array_of_types,
MPI_Datatype *newtype)

FORTRAN:

MPI_TYPE_STRUCT(COUNT, ARRAY_OF_BLOCKLENGTHS,

ARRAY_OF_DISPLACEMENTS, ARRAY_OF_TYPES, NEWTYPE, IERROR)

INTEGER COUNT, ARRAY_OF_BLOCKLENGTHS(*), ARRAY_OF_DISPLACEMENTS(*),

ARRAY_OF_TYPES(*), NEWTYPE, IERROR

IN count - число блоков;
IN array_of_blocklength - массив, содержащий число элементов одного из базовых типов в каждом блоке;
IN array_of_displacements - массив смещений каждого блока от начала размещения структуры, смещения измеряются в байтах;
IN array_of_type - массив, содержащий тип элементов в каждом блоке;
OUT newtype - новый производный тип данных.

Функция создает тип newtype, элемент которого состоит из count блоков, где i-ый блок содержит array_of_blocklengths[i] элементов типа array_of_types[i]. Смещение i-ого блока от начала размещения элемента нового типа измеряется в байтах и задается в array_of_displacements[i].

Функция MPI_Type_commit регистрирует созданный производный тип. Только после регистрации новый тип может использоваться в коммуникационных операциях.

C:

int MPI_Type_commit(MPI_Datatype *datatype)

FORTRAN:

MPI_TYPE_COMMIT(DATATYPE, IERROR)

INTEGER DATATYPE, IERROR

INOUT datatype - новый производный тип данных.

Функция MPI_Type_free уничтожает описатель производного типа.

C:

int MPI_Type_free(MPI_Datatype *datatype)

FORTRAN:>

MPI_TYPE_FREE(DATATYPE, IERROR)

INTEGER DATATYPE, IERROR

INOUT datatype - уничтожаемый производный тип.

Функция MPI_Type_free устанавливает описатель типа в состояние MPI_DATATYPE_NULL. Это не повлияет на выполняющиеся в данный момент коммуникационные операции с этим типом данных и на производные типы, которые ранее были определены через уничтоженный тип.

Для определения длины сообщения используются две функции: MPI_Get_count и MPI_Get_elements. Для сообщений из простых типов они возвращают одинаковое число. Подпрограмма MPI_Get_count возвращает число элементов типа datatype, указанного в операции получения. Если получено не целое число элементов, то она возвратит константу MPI_UNDEFINED (функция MPI_Get_count рассматривалась в разделе 3.2, посвященном коммуникационным операциям типа точка-точка).

Функция MPI_Get_elements возвращает число элементов простых типов, содержащихся в сообщении.

C:

int MPI_Get_elements(MPI_Status *status, MPI_Datatype datatype,

int *count)

FORTRAN:

MPI_GET_ELEMENTS(STATUS, DATATYPE, COUNT, IERROR)

INTEGER STATUS(MPI_STATUS_SIZE), DATATYPE, COUNT, IERROR

IN status - статус сообщения;
IN datatype - тип элементов сообщения;
       
OUT count - число элементов простых типов, содержащихся в сообщении.
       






©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.