Дипломы, курсовые, рефераты, контрольные...
Срочная помощь в учёбе

Производные типы и упаковка/распаковка данных

РефератПомощь в написанииУзнать стоимостьмоей работы

Int MPI_Pack (void* inbuf, int incount, MPI Datatype datatype, void *outbuf, int outsize, int *position, MPI Comm comm); — функция MPI_Pack упаковывает incount элементов типа datatype из области памяти с начальным адресом inbuf. Результат упаковки помещается в выходной буфер с начальным адресом outbuf и размером outsize байт. Параметр position указывает текущую позицию в байтах, начиная с которой… Читать ещё >

Производные типы и упаковка/распаковка данных (реферат, курсовая, диплом, контрольная)

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

Для эффективной пересылки данных в таких случаях MPI предоставляет два механизма:

  • — возможность создания производных типов данных для использования в коммуникационных операциях вместо предопределенных типов MPI;
  • — пересылку упакованных данных (процесс-отправитель упаковывает пересылаемые данные перед их отправкой, а процесс-получатель распаковывает их после получения).

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

  • — последовательность базовых типов;
  • — последовательность их смещений.

Упорядоченный набор этих пар называется отображением (картой) типа:

Производные типы и упаковка/распаковка данных.

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

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

  • — Производный тип строится из предопределенных типов MPI и ранее определенных производных типов с помощью функций-конструкторов.
  • — Новый производный тип регистрируется вызовом функции МР1_ Туре_с от т i t.
  • — После регистрации новый производный тип можно использовать в коммуникационных операциях и при конструировании других типов. Предопределенные типы MPI считаются зарегистрированными.
  • — С производными типами можно выполнять некоторые дополнительные операции (в частности, узнавать их размер, протяженность и некоторые другие характеристики).
  • — Когда производный тип становится ненужным, он уничтожается функцией MPlJTypeJree.

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

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

int MPI Type_contiguous (int count, MPIDatatype oldtype,

MPI Datatype *newtype);

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

int MPI_Type_vector (int count, int blocklength, int stride, MPI Datatype oldtype, MPIDatatype * new type); - эта функция создает тип newtype, элемент которого состоит из count блоков, каждый из которых содержит одинаковое число blocklength элементов типа oldtype. Шаг stride между началом блока и началом следующего блока всюду одинаков и кратен протяженности представления базового типа.

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

int MPI_Type_create_hvector (int count, int blocklength, MPI_Aint stride, MPI Datatype oldtype, MPI Datatype *newtype);

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

int MPI Type_create indexed (int count, int *array_of_blocklengths, int *array of displacements, MPI_Datatype oldtype, MPIJDatatype * new type); - эта функция создает тип newtype, каждый элемент которого состоит из count блоков, где /-й блок содержит array of_blocklengths[i] элементов базового типа и смещен от начала размещения элемента нового типа на array of displacements[i] элементов базового типа.

Конструктор типа МР1 _Туре _createJnndexed идентичен конструктору MPI Type indexed за исключением того, что смещения измеряются в байтах:

int MPI_create_hindexed (int count, int *array_of_blocklengths, MPIAint *array_of_displacements, MPI Datatype oldtype, MPI Datatype *newtype); — элемент нового типа состоит из count блоков, где /-й блок содержит array_of_bIocklengths[i] элементов старого типа и смещен от начала размещения элемента нового типа на array of displacements[i] байт.

Конструктор типа MPI_Туре create indexed block похож на конструктор MPlJTypeindexed за исключением того, что все блоки одинаковы:

int MPI Type create indexed_block (int count, int blocklength, MPI_Aint *array_of_displacements, MPI_Datatype oldtype, MPI_Datatype biewtype);

Конструктор типа MPI Type create struct — самый универсальный из всех конструкторов. Создаваемый им тип является структурой, состоящей из произвольного числа блоков, каждый из которых может содержать произвольное число элементов одного из базовых типов и может быть смещен на произвольное число байтов от начала размещения структуры:

int MPI_Type_create_struct (int count, int *array_of_blocklengths, MPI_Aint *array of displacements, MPI Datatype *array_of_types, MPI Datatype *newtype); - эта функция создает тип newtype, элемент которого состоит из count блоков, где i-й блок содержит array_of_blocklengths[i] элементов типа array of types[i]. Смещение /-го блока от начала размещения элемента нового типа измеряется в байтах и задается в array_of_displacements[i.

Конструктор типа данных «субмассив»:

int MPI_Туре createsubarray (int ndirns, int* array of sizes, int* array of subsizes, int* array of starts, int order, MPI Datatype oldtype,

MPIDatatype *newtype); — конструктор типа для субмассива создает тип данных MPI, описывающий «-мерный субмассив «-мерного масива. Субмассив может находиться в любом месте полного массива и может быть любого ненулевого размера вплоть до размера полного массива. Этот конструктор позволяет создавать типы файлов для доступа к массивам, разбитым между процессами по блокам через один файл, содержащий глобальный массив.

И, наконец, конструктор распределенного массива поддерживает распределения данных, сходные с HPF (High Performance Fortran). Кроме этого в отличие от HPF порядок хранения может быть задан как для массивов Си, так и для ФОРТРАНА:

int MPI_Туре create_darray (int size, int rank, int ndims, int array of gsizesf], int array of distribs[], int array_of_dargs [], int array _of_ps izes[], int order, MPI Datatype oldtype, MPI Datatype* new type);

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

int MPI_Type_commit (MPI_Datatype *datatype);

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

int MPI_Type_dup (MPI Datatype datatype, MPI Datatype *newtype); Любой тип данных в MPI имеет две характеристики: протяженность и размер, выраженные в байтах: протяженность типа определяет, сколько байт переменная данного типа занимает в памяти. Эта величина может быть вычислена как адрес последней ячейки данных — адрес первой ячейки данных + длина последней ячейки данных. Протяженность может быть получена с помощью функций MPI_Type_get_extent, а если к типу применялись операции изменения нижней и/или верхней границы, то MPI_Туре_getJrue_extent.

Размер типа определяет количество реально передаваемых байт в коммуникационных операциях. Эта величина равна сумме длин всех базовых элементов определяемого типа. Размер типа данных MPI может быть получен с помощью функции MPI_Type_size.

Для простых типов протяженность и размер совпадают. int MPI_Туре_get extent (MPIDatatype datatype, MPIAint *lb, MPI_Aint *extent);); - функция возвращает нижнюю границу и протяженность типа.

int MPI Type_get_true_extent (MPI Datatype datatype, MPI_Aint *lb, MPI Aint *extent); - возвращает истинные нижнюю границу и протяжснность даже в том случае, если для данного типа изменялась нижняя граница.

int MPI_Type_size (MPIDatatype datatype, ini *size); - возвращает в переменной size «чистый» размер элемента некоторого типа (за вычетом пустых промежутков), т. е. количество байт данных, которые будут фактически передаваться при коммуникациях между ветвями.

int MPI_Type_create_resized (MPI Datatype oldtype, MPIAint lb, MPIAint extent, MPI Datatype *newtype); - эта функция возвращает в newtype дескриптор нового типа данных, идентичного oldtype, за исключением того, что нижняя граница типа данных установлена в lb, а верхняя — в lb + extent. Любые предыдущие маркеры lb и ub стираются, и в позиции, указанные аргументами lb и extent, помещается новая пара маркеров. Это влияет на поведение типа данных при коммуникациях с counf> 1 и при создании новых порожденных типов данных.

int MPI_Type_set_name (MPI Datatype type, char *type_name); - присваивает символическое имя производному типу данных (удобно для отладки).

int MPI Type get name (MPl Data type type, char *type_name, int *resultlen); — возвращает имя производного типа данных.

int MPI TypeJreefMPI Datatype *datatype); - уничтожает производный тип. Эта функция устанавливает дескриптор типа в состояние MPIDATATYPENULL, что нс повлияет ни на выполняющиеся в данный момент коммуникационные операции с этим типом данных, ни на производные типы, которые ранее были определены через уничтоженный тип.

Передача/прием упакованных данных.

Функция МР1_Раск упаковывает элементы предопределенного или производного типа, помещая их побайтное представление в выходной буфер:

int MPI_Pack (void* inbuf, int incount, MPI Datatype datatype, void *outbuf, int outsize, int *position, MPI Comm comm); — функция MPI_Pack упаковывает incount элементов типа datatype из области памяти с начальным адресом inbuf. Результат упаковки помещается в выходной буфер с начальным адресом outbuf и размером outsize байт. Параметр position указывает текущую позицию в байтах, начиная с которой будут размещаться упакованные данные. После возврата из функции значение position будет увеличено на число упакованных байт, указывая на первый свободный байт в выходном буфере. Параметр

comm при последующей посылке упакованного сообщения будет использован как коммуникатор.

Функция MPIPacksize позволяет определить размер буфера, необходимый для упаковки заданного количества данных типа datatype:

int MPI_Pack_size (int incount, MPI Datatype datatype, MPI Comm comm, int *size);

Функция MPlJUnpack извлекает заданное число элементов некоторого типа из побайтного представления элементов во входном массиве:

int MPlJJnpack (void * inbuf int insize, int *position, void *outbufint outcount, MPl Datatype datatype, MPIjComm comm); — эта функция извлекает outcount элементов типа datatype из побайтного представления элементов в массиве inbuj. начиная с адреса position, и помещает их в область памяти с начальным адресом outbuf. После возврата из функции параметр position будет увеличен на размер распакованного сообщения.

Показать весь текст
Заполнить форму текущей работой