Я новичок в MPI и хочу создать новый тип данных для Residence
struct
, Я просто хочу посмотреть, смогу ли я создать новый тип правильно.
структура резиденция
{
двойной х;
двойной у;
};
Мой новый тип MPI
MPI_Datatype createRecType()
{
// Set-up the arguments for the type constructor
MPI_Datatype new_type;
int count = 2;
int blocklens[] = { 1,1 };
MPI_Aint indices[2];
//indices[0]=0;
MPI_Type_extent( MPI_DOUBLE, &indices[0] );
MPI_Type_extent( MPI_DOUBLE, &indices[1] );
MPI_Datatype old_types[] = {MPI_DOUBLE,MPI_DOUBLE};
MPI_Type_struct(count,blocklens,indices,old_types,&new_type);
MPI_Type_commit(&new_type);
}
Вы почти правильно поняли, за исключением того, что indices
должен дать смещение каждого поля структуры в байтах от начало структуры. Правильный способ создания такого типа будет использовать offsetof
оператор, определенный в stddef.h
:
#include <stddef.h> // or <cstddef> for C++
struct Residence
{
double x;
double y;
};
MPI_Datatype createRecType()
{
// Set-up the arguments for the type constructor
MPI_Datatype new_type;
int count = 2;
int blocklens[] = { 1,1 };
MPI_Aint indices[2];
indices[0] = (MPI_Aint)offsetof(struct Residence, x);
indices[1] = (MPI_Aint)offsetof(struct Residence, y);
MPI_Datatype old_types[] = {MPI_DOUBLE,MPI_DOUBLE};
MPI_Type_struct(count,blocklens,indices,old_types,&new_type);
MPI_Type_commit(&new_type);
return new_type;
}
Хотя этого будет достаточно для этой конкретной структуры, в общем случае необходимо настроить длину структурированного типа, чтобы учесть любые конечные отступы, которые компилятор может вставить в конец структуры. Это необходимо только в том случае, если требуется отправить несколько элементов этого структурированного типа, то есть массив элементов структуры. Старый способ сделать это — добавить третий элемент в структуру типа MPI_UB
(UB происходит от Upper Bound) и установите смещение этого элемента равным sizeof(struct Residence)
(Заполнение учитывается в размере структуры, как sizeof
). Современный способ заключается в использовании MPI_Type_create_resized
, который создает новый тип MPI с той же сигнатурой типа, что и исходная, но с другим экстентом:
MPI_Type_struct(count,blocklens,indices,old_types,&new_type);
// Create a resized type
MPI_Type resized_new_type;
MPI_Type_create_resized(new_type,
// lower bound == min(indices) == indices[0]
indices[0],
(MPI_Aint)sizeof(struct Residence),
&resized_new_type);
MPI_Type_commit(&resized_new_type);
// Free new_type as it is no longer needed
MPI_Type_free(&new_type);
return resized_new_type;
Отображаются только соответствующие строки кода. Код выше предполагает, что indices[0]
дает смещение первого элемента структуры. Можно вместо этого использовать MPI_Type_get_extent
чтобы получить истинную нижнюю границу, и это будет работать для структурных типов с отрицательными смещениями. Не нужно совершать new_type
так как он используется только для создания измененного типа. Также не нужно держать это вокруг, и поэтому оно освобождается после resized_new_type
был создан.
Других решений пока нет …