Contiguous. Простейшим типом конструктора типа данных является конструктор MPI_TYPE_CONTIGUOUS, который позволяет копировать тип данных в смежные области.
Синтаксис функции MPI_TYPE_CONTIGUOUS представлен ниже.
MPI_TYPE_CONTIGUOUS (count, oldtype, newtype)
IN | count | число повторений (неотрицательное целое) | |
IN | oldtype | старый тип данных (дескриптор) | |
OUT | newtype | новый тип данных (дескриптор) |
int MPI_Type_contiguous(int count, MPI_Datatype oldtype,
MPI_Datatype *newtype)
MPI_TYPE_CONTIGUOUS(COUNT, OLDTYPE, NEWTYPE, IERROR)
INTEGER COUNT, OLDTYPE, NEWTYPE, IERROR
MPI::Datatype MPI::Datatype::Create_contiguous (int count) const
Новый тип newtype есть тип, полученный конкатенацией (сцеплением) count копий старого типа oldtype.
Пример 3.20 Пусть oldtype имеет карту type map { ( double, 0), (char, 8) } с длиной 16 и пусть count = 3. Карта нового типа будет:
{ (double, 0), (char, 8), (double, 16), (char, 24), (double, 32), (char, 40) } ;
то есть содержать меняющиеся удвоенные значения и символьные элементы со смещением 0, 8, 16, 24, 32, 40.
В общем предположим, что карта типа для oldtype есть
{ (type,disp), ..., (type, disp)} ,
с длиной ex, Тогда newtype имеет карту с count n элементами, определяемыми:
{ (type, disp), ..., (type, disp), (type, disp+ex), ... ,(type, disp+ ex) , ...
(type, disp+ex ( count-1)), ... , (type, disp+ ex (count-1)) }.
Vector. Функция MPI_TYPE_VECTOR является более универсальным конструктором, который позволяет реплицировать типы данных в области, состоящие из блоков равного объема. Каждый блок получается конкатенацией некоторого количества копий старого типа. Пространство между блоками кратно размеру old datatype.
Синтаксис функции MPI_TYPE_VECTOR представлен ниже.
MPI_TYPE_VECTOR(count, blocklength, stride, oldtype, newtype)
IN | count | число блоков (неотрицательное целое) | |
IN | blocklength | число элементов в каждом блоке (неотрицательное целое) | |
IN | stride | число элементов между началами каждого блока (целое) | |
IN | oldtype | старый тип данных (дескриптор) | |
OUT | newtype | новый тип данных (дескриптор) |
int MPI_Type_vector(int count, int blocklength, int stride,
MPI_Datatype oldtype, MPI_Datatype *newtype)
MPI_TYPE_VECTOR(COUNT, BLOCKLENGTH, STRIDE, OLDTYPE, NEWTYPE, IERROR)
INTEGER COUNT, BLOCKLENGTH, STRIDE, OLDTYPE, NEWTYPE, IERROR
MPI::Datatype MPI::Datatype::Create_vector(int count,
int blocklength, int stride) const
Пример 3.21 Предположим снова, что oldtype имеет карту type map {(double, 0), (char, 8)}, с размером 16. Обращение MPI_TYPE_VECTOR(2, 3, 4, oldtype, newtype) будет создавать тип с картой:
type map, { (double, 0), (char, 8), (double, 16), (char, 24), ( double, 32), (char, 40),
(double, 64), (char, 72), (double, 80), (char, 88), (double, 96), (char, 104) } .
Это означает, что в новой карте есть два блока, каждый с тремя копиями старого типа, со страйдом (stride) 4 элемента (416 байтов) между блоками.
Пример 3.22 Обращение MPI_TYPE_VECTOR(3, 1, -2, oldtype, newtype) будет создавать тип:
{ (double, 0), (char, 8), (double, -32), (char, -24), (double, -64), (char, -56) } .
В общем случае предположим, что oldtype имеет карту:
{ (type, disp), ..., (type, disp) },
с экстентом ex. Пусть bl - длина блока. Вновь созданный
тип данных будет иметь карту с
элементами:
{ (type, disp), ... , (type, disp),
(type,disp+ ex) , ... , (type, disp+ ex), ...,
(type, disp+ (bl -1) ex) , ... , (type, disp+ (bl -1) ex) ,
(type,disp+ stride ex) , ... , (type, disp+ stride ex), ... ,
(type, disp+ (stride + bl -1) ex) , ... , (type_n-1, disp_n-1+ (stride + bl -1) ex) , ....,
(type,disp+ stride (count-1) ex), ... ,
(type, disp+ stride (count -1) ex) , ... ,
(type, disp+ (stride (count -1) + bl -1) ex) , ... ,
(type, disp+ ( stride (count -1) + bl -1) ex) } .
Обращение к MPI_TYPE_CONTIGUOUS (count, oldtype, newtype)
эквивалентно обращению
MPI_TYPE_VECTOR(count, 1, 1,
oldtype, newtype) или обращению MPI_TYPE_VECTOR (1, count, n,
oldtype, newtype), где n - произвольное.
Hvector. Функция MPI_TYPE_HVECTOR идентична MPI_TYPE_VECTOR за исключением того, что страйд задается в байтах, а не в элементах. Использование обоих типов векторных конструкторов иллюстрируется в разделе 3.12.7. (H обозначает heterogeneous - неоднородный).
Синтаксис функции MPI_TYPE_HVECTOR представлен ниже.
MPI_TYPE_HVECTOR(count, blocklength, stride, oldtype, newtype)
IN | count | число блоков (неотрицательное целое) | |
IN | blocklength | число элементов в каждом блоке (неотрицательное целое) | |
IN | stride | число байтов между стартом каждого блока (целое) | |
IN | oldtype | старый тип данных (дескриптор) | |
OUT | newtype | новый тип данных (дескриптор) |
int MPI_Type_hvector(int count, int blocklength, MPI_Aint stride,
MPI_Datatype oldtype, MPI_Datatype *newtype)
MPI_TYPE_HVECTOR(COUNT, BLOCKLENGTH, STRIDE, OLDTYPE, NEWTYPE, IERROR)
INTEGER COUNT, BLOCKLENGTH, STRIDE, OLDTYPE, NEWTYPE, IERROR
MPI::Datatype MPI::Datatype::Create_hvector(int count,
int blocklength, MPI::Aint stride) const
Предположим, что oldtype имеет карту
{ (type, disp), ..., (type, disp) } ,
с расширением ex. Пусть bl - длина блока. Вновь созданный тип данных будет иметь карту с элементами:
{ (type, disp), ... , (type, disp),
(type,disp+ ex) , ... , (type, disp+ ex), ...,
(type, disp+ (bl -1) ex) , ... , (type, disp+ (bl -1) ex) ,
(type,disp+ stride) , ... , (type, disp+ stride) , ... ,
(type, disp+ stride + ( bl -1) ex) , ... ,
(type, disp+ stride + (bl -1) ex) , ....,
(type,disp+ stride (count-1)) , ... , (type, disp+ stride (count -1)) , ... ,
(type, disp+ stride (count -1) + (bl -1) ex) , ... ,
(type, disp+ stride (count -1) + (bl -1) ex) } .
Indexed. Функция MPI_TYPE_INDEXED позволяет реплицировать старый тип old datatype в последовательность блоков (каждый блок есть конкатенация old datatype), где каждый блок может содержать различное число копий и иметь различное смещение. Все смещения блоков кратны длине старого блока old type.
Синтаксис функции MPI_TYPE_INDEXED представлен ниже.
MPI_TYPE_INDEXED(count, array_of_blocklengths,
array_of_displacements, oldtype, newtype)
IN | count | число блоков | |
IN | array_of_blocklengths | число элементов в каждом блоке (массив неотрицательных целых) | |
IN | array_of_displacements | смещение для каждого блока (массив целых) | |
IN | oldtype | старый тип данных (дескриптор) | |
OUT | newtype | новый тип данных (дескриптор) |
int MPI_Type_indexed(int count, int *array_of_blocklengths,
int *array_of_displacements, MPI_Datatype oldtype, MPI_Datatype *newtype)
MPI_TYPE_INDEXED(COUNT, ARRAY_OF_BLOCKLENGTHS,
ARRAY_OF_DISPLACEMENTS, OLDTYPE, NEWTYPE, IERROR)
INTEGER COUNT, ARRAY_OF_BLOCKLENGTHS(*), ARRAY_OF_DISPLACEMENTS(*),
OLDTYPE, NEWTYPE, IERROR
MPI::Datatype MPI::Datatype::Create_indexed(int count,
const int array_of_blocklengths[],
const int array_of_displacements[]) const
Пример 3.23 Пусть oldtype имеет карту type map { ( double, 0), (char, 8) } с экстентом16. Пусть B = (3, 1) и D = (4, 0). Обращение MPI_TYPE_INDEXED (2, B, D, oldtype, newtype) возвращает тип данных с картой:
{ (double, 64), (char, 72), (double, 80), (char, 88), (double, 96), (char, 104),
(double, 0), (char, 8) } .
Это означает, что в новом типе имеется три копии старого типа old type, начиная со смещения 64 и одна копия стартует со смещения 0.
В общем случае предположим, что oldtype имеет карту
{ (type, disp), ..., (type, disp) } ,
с экстентом ex. Пусть В является аргументом массива длин и D - аргументом массива смещений. Тогда вновь созданный тип данных имеет элементов:
{(type, disp+ D[0] ex),..., (type, disp + D[0]ex)
(type, disp+ D[0] +B[0] -1)ex),..., (type, disp + (D[0] + В[0] -1)ex),...,
(type, disp+ D[count - 1]ex),..., (type, disp + D[count - 1]ex)... ,
(type, disp+ (D[count - 1] + B[count -1)ex),...,
(type, disp+D[count - 1] + B[count -1)ex).
Обращение к MPI_TYPE_VECTOR (count, blocklength, stride, oldtype, newtype) будет эквивалентно обращению к MPI_TYPE_INDEXED(count, B, D, oldtype, newtype), где
D[j] = j strade, j = 0,..., count - 1,
и
B[j] = blocklength, j = 0,..., count - 1
Hindexed. Функция MPI_TYPE_HINDEXED идентична MPI_TYPE_INDEXED, за исключением того, что смещения блоков в массиве array_of_displacements задаются в байтах, а не в кратностях величины старого типа oldtype.
Синтаксис функции MPI_TYPE_HINDEXED представлен ниже.
MPI_TYPE_HVECTOR(count, blocklength, stride, oldtype, newtype)
IN | count | число блоков (неотрицательное целое) | |
IN | blocklength | число элементов в каждом блоке (неотрицательное целое) | |
IN | stride | число байтов между стартом каждого блока (целое) | |
IN | oldtype | старый тип данных (дескриптор) | |
OUT | newtype | новый тип данных (дескриптор) |
int MPI_Type_hvector(int count, int blocklength, MPI_Aint stride,
MPI_Datatype oldtype, MPI_Datatype *newtype)
MPI_TYPE_HVECTOR(COUNT, BLOCKLENGTH, STRIDE, OLDTYPE, NEWTYPE, IERROR)
INTEGER COUNT, BLOCKLENGTH, STRIDE, OLDTYPE, NEWTYPE, IERROR
MPI::Datatype MPI::Datatype::Create_hvector(int count,
int blocklength, MPI::Aint stride) const
Предположим, что oldtype имеет карту
{ (type0, disp0), ..., (typen-1, dispn-1) }
с расширением ex. Пусть В - это аргумент
array_of_blocklength, а D - аргумент
array_of_displacements. Вновь созданный тип данных имеет
карту с
элементов:
{(type,disp+ D[0]),..., (type, disp+ D[0]),...,
(type, disp+ D[0] + (B[0] -1)ex),...,
(typedisp+ D[0] + (B[0] -1)ex),...,
(type, disp+ D[count - 1]),..., (typedisp+ D[count - 1]), ...,
(type, disp+ D[count - 1]) + (B[count - 1] - 1)ex),...,
(typedisp+ D[count - 1]) + (B[count - 1] - 1)ex)}
Struct. MPI_TYPE_STRUCT является наиболее общим типом конструктора. Он отличается от предыдущего тем, что позволяет каждому блоку состоять из репликаций различного типа.
Синтаксис функции MPI_TYPE_STRUCT представлен ниже.
=1cm
MPI_TYPE_STRUCT(count, array_of_blocklengths,
array_of_displacements, array_of_types, newtype)
IN | count | число блоков (целое) | |
IN | array_of_blocklength | число элементов в каждом блоке (массив целых) | |
IN | array_of_displacements | смещение каждого блока в байтах (массив целых) | |
IN | array_of_types | тип элементов в каждом блоке (массив дескрипторов объектов типов данных) | |
OUT | newtype | новый тип данных (дескриптор) |
=1cm
int MPI_Type_struct(int count, int *array_of_blocklengths,
MPI_Aint *array_of_displacements, MPI_Datatype *array_of_types,
MPI_Datatype *newtype)
=1cm
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
Пример 3.24 Пусть type1 имеет карту типа
{ (double, 0), (char, 8) } ,
с шириной 16. Пусть B = (2, 1, 3), D = (0, 16, 26), и T = (MPI_FLOAT, type1, MPI_CHAR). Тогда обращение MPI_TYPE_STRUCT(3, B, D, T, newtype) возвращает тип с картой:
{ (float, 0), (float, 4), (double, 16), (char, 24), (char, 26), (char, 27), (char, 28) },
то есть две копии MPI_FLOAT, начиная с 0, с последующей одной копией type1, начиная с 16, с последующими тремя копиями MPI_CHAR, начиная с 26. (Предполагается, что число с плавающей точкой занимает четыре байта).
Обращение к MPI_TYPE_HINDEXED(count, B, D, oldtype, newtype) эквивалентно обращению к MPI_TYPE_STRUCT(count, B, D, T, newtype), где каждый вход T равен oldtype.