MPI_Type_indexed : расширение "векторного" описателя; длины массивов и расстояния между ними теперь не фиксированы, а у каждого массива свои. Соответственно, аргументы #2 и #3 здесь - не переменные, а массивы: массив длин и массив позиций.
Пример: создание шаблона для выделения верхней правой части матрицы.
#define SIZE 100
float a[ SIZE ][ SIZE ];
int pos[ SIZE ]
int len[ SIZE ];
MPI_Datatype upper;
...
for( i=0; ipos[i] = SIZE*i + i; /* .xxxxx */
len[i] = SIZE - i; /* ..xxxx */
} /* ...xxx */
MPI_Type_indexed(
SIZE, /* количество массивов в переменной нового типа */
len, /* длины этих массивов */
pos, /* их позиции от начала переменной, */
/* отсчитываемые в количестве ячеек */
MPI_FLOAT, /* тип ячейки массива */
&upper );
MPI_Type_commit( &upper );
/* Поступающий поток чисел типа 'float' будет
* размещен в верхней правой части матрицы 'a'
*/
MPI_Recv( a, 1, upper, .... );
Аналогично работает функция MPI_Type_hindexed, но позиции массивов от начала переменной задаются не в количестве ячеек базового типа, а в байтах.
MPI_Type_struct : создает описатель структуры. Наверняка будет использоваться Вами чаще всего.
MPI_Type_struct(
count, /* количество полей */
int *len, /* массив с длинами полей */
/* (на тот случай, если это массивы) */
MPI_Aint *pos, /* массив со смещениями полей */
/* от начала структуры, в байтах */
MPI_Datatype *types, /* массив с описателями типов полей */
MPI_Datatype *newtype ); /* ссылка на создаваемый тип */
Здесь используется тип MPI_Aint: это просто скалярный тип, переменная которого имеет одинаковый с указателем размер. Введен он исключительно для единообразия с Фортраном, в котором нет типа "указатель". По этой же причине имеется и функция MPI_Address: в Си она не нужна (используются оператор вычисления адреса & и основанный на нем макрос offsetof() ); а в Фортране оператора вычисления адреса нет, и используется MPI_Address.
Пример создания описателя типа "структура":
#include /* подключаем макрос 'offsetof()' */
typedef struct {
int i;
double d[3];
long l[8];
char c;
} AnyStruct;
AnyStruct st;
MPI_Datatype anyStructType;
int len[5] = { 1, 3, 8, 1, 1 };
MPI_Aint pos[5] = { offsetof(AnyStruct,i), offsetof(AnyStruct,d),
offsetof(AnyStruct,l), offsetof(AnyStruct,c),
sizeof(AnyStruct) };
MPI_Datatype typ[5] = { MPI_INT,MPI_DOUBLE,MPI_LONG,MPI_CHAR,MPI_UB };
MPI_Type_struct( 5, len, pos, typ, &anyStructType );
MPI_Type_commit( &anyStructType );
/* подготовка закончена */
MPI_Send( st, 1, anyStructType, ... );
Обратите внимание: структура в примере содержит 4 поля, а массивы для ее описания состоят из 5 элементов. Сделано это потому, что MPI должен знать не только смещения полей, но и размер всей структуры. Для этого и служит псевдотип MPI_UB ("upper bound").
Адрес начала структуры и адрес ее первого поля, как правило, совпадают, но если это не так: нулевым элементом массива typ должен быть MPI_LB.
Do'stlaringiz bilan baham: |