我是MPI的新手,我想为Residence
struct
创建一个新的数据类型。我只是想看看我是否可以正确地创建新类型。
结构住宅
{
双x;
双y;
};
我的新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);
}
答案 0 :(得分:5)
除了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来自上限)并将该成员的偏移量设置为等于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
后它被释放。