如何在MPI中创建新类型

4 c c++ cluster-computing mpi mpich

我是MPI的新手,我想为其创建一个新的数据类型Residence struct.我只是想看看我是否可以正确地创建新类型.struct Residence {double 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);

}
Run Code Online (Sandbox Code Playgroud)

Hri*_*iev 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;
}
Run Code Online (Sandbox Code Playgroud)

虽然这对于该特定结构就足够了,但通常必须调整结构化类型长度以便考虑编译器可能在结构的末尾插入的任何尾随填充.只有在想要发送该结构化类型的多个项目(即结构元素数组)时,才需要这样做.旧的方法是将第三个成员添加到类型的结构中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;
Run Code Online (Sandbox Code Playgroud)

仅显示相关的代码行.上面的代码假设indices[0]给出了第一个结构元素的偏移量.可以MPI_Type_get_extent用来获得真正的下界,这对于具有负偏移的结构类型是有效的.没有必要提交,new_type因为它仅用于构造调整大小的类型.它也没有必要保持它,这就是它resized_new_type被创建后释放的原因.