如何在MPI中创建新类型 [英] How to create new Type in MPI

查看:241
本文介绍了如何在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆