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

·  order — флаг, задающий переупорядочение;

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

Новый тип newtype является выходным параметром этой подпрограммы.

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

6.5.2  Регистрация и удаление производных типов

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

intMPI_Type_commit(MPI_Datatype *datatype)

Аннулировать производный тип datatype можно с помощью вызова подпрограммы MPI_Type_free:

int MPI_Type_free(MPI_Datatype *datatype)

Предопределенные, то есть базовые типы данных не могут быть аннулированы.

6.5.3  Подпрограммы, сопутствующие производным типам

Размер (size) одного элемента типа datatype в байтах можно определить с помощью вызова подпрограммы MPI_Type_size:

int MPI_Type_size(MPI_Datatype datatype, int *size)

Количество элементов данных типа datatype в одном объекте, как значение выходной переменной (extent– объем), можно определить с помощью вызова подпрограммы MPI_Type_extent:

int MPI_Type_extent(MPI_Datatype datatype,

MPI_Aint *extent)

Смещения могут даваться относительно базового адреса, значение которого содержится в константе MPI_BOTTOM.

С помощью подпрограммы MPI_Type_get_contents можно определить фактические параметры, использованные при создании производного типа:

int MPI_Type_get_contents(MPI_Datatype datatype,

   int max_integers, int max_addresses,

int max_datatypes, int *integers,

    MPI_Aint *addresses, MPI_Datatype *datatypes)

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

·  datatype — идентификатор типа;

·  max_integers — количество элементов в массиве integers;

·  max_addresses — Количество элементов В массиве addresses;

·  max_datatypes — количество элементов в массиве datatypes.

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

·  integers — содержит целочисленные  аргументы,  использованные  при конструировании указанного типа;

·  addresses — содержит аргументы address, использованные при конструировании указанного типа;

·  datatypes — содержит аргументы datatype, использованные при конструировании указанного типа.

Подпрограмма MPI_Type_lb возвращает нижнюю границу типа данных datatype:

int MPI_Type_lb(MPI_Datatype datatype,

MPI_Aint *displacement)

Выходным параметром является смещение в байтах нижней границы относительно источника displacement.

Верхнюю границу типа возвращает подпрограмма  MPI_Type_ub:

int MPI_Type_ub(MPI_Datatype datatype,

MPI_Aint *displacement)

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

#include "mpi.h"

#include <stdio.h>

struct newtype

{

float a;

float b;

int n;

};

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

{

int myrank;

MPI_Datatype NEW_MESSAGE_TYPE;

int block_lengths[3];

MPI_Aint displacements[3];

MPI_Aint addresses[4];

MPI_Datatype typelist[3];

int blocks_number;

struct newtype indata;

int tag = 0;

MPI_Status status;

MPI_Init(&argc, &argv);

MPI_Comm_rank (MPI_COMM_WORLD, &myrank) ;

typelist[0] = MPI_FLOAT;

typelist[1] = MPI_FLOAT;

typelist[2] = MPI_INT;

block_lengths[0]=block_lengths[1]=1;

block_lengths[2]=1;

MPI_Address(&indata, &addresses[0]);

MPI_Address(&(indata.a), &addresses[1]);

MPI_Address(&(indata.b), &addresses[2]);

MPI_Address(&(indata.n), &addresses[3]);

displacements[0] = addresses[1] — addresses[0];

displacements[1] = addresses[2] - addresses[0];

displacements[2] = addresses[3] - addresses[0];

blocks_number =3;

MPI_Type_struct(blocks_number, block_lengths,

displacements, typelist, &NEW_MESSAGE_TYPE);

MPI_Type_commit(&NEW_MESSAGE_TYPE) ;

if (myrank == 0)

{

indata.a = 3.14159;

indata.b = 2.71828;

indata.n = 2002;

MPI_Send(&indata, 1,NEW_MESSAGE_TYPE, 1, tag,

MPI_COMM_WORLD);

printf("Process %i send: %f %f %i\n", myrank,

indata.a, indata.b, indata.n);

}

else

{

MPI_Recv(&indata, 1, NEW_MESSAGE_TYPE, 0, tag,

MPI_COMM_WORLD, &status);

printf("Process %i received: %f %f %i,