如何在MPI中创建新类型 [英] How to create new Type in MPI
问题描述
我是MPI新手,我想为 Residence
struct
创建一个新的数据类型。我只想看看是否可以创建新的类型正确的方法。
struct Residence
{
double x;
double y;
};
I am new to MPI and I want to create a new datatype for Residence
struct
. I just want to see if I can create the new type right way.
struct Residence
{
double x;
double 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);
}
推荐答案
ve几乎是正确的,除了 indices
应该给出从结构的开始的每个结构字段的偏移量(以字节为单位)。构造这种类型的正确方法是使用 stddef.h
中定义的 offsetof
p>
You've almost got it right except that indices
is supposed to give the offset of each structure field in bytes from the beginning of the structure. The correct way to construct such a type would be to use the offsetof
operator, defined in 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类型:
While this would suffice for that particular structure, in general one has to adjust the structured type length in order to account for any trailing padding that the compiler might insert at the end of the structure. This is only necessary if one wants to send multiple items of that structured type, i.e. an array of structure elements. The old way to do that was to add a third member to the structure of type MPI_UB
(UB comes from Upper Bound) and set the offset of that member to be equal to sizeof(struct Residence)
(padding is accounted in the structure size as returned by sizeof
). The modern way is to use MPI_Type_create_resized
, which creates a new MPI type with the same type signature as the original one but with a different extent:
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
已创建后释放。
Only the relevant code lines are shown. The code above assumes that indices[0]
gives the offset of the first structure element. One could instead use MPI_Type_get_extent
to get the true lower bound and that would work for structure types with negative offsets. It is not necessary to commit new_type
as it is only used to construct the resized type. It is also not necessary to keep it around and that's why it is freed after resized_new_type
has been created.
这篇关于如何在MPI中创建新类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!