如何修复创建MPI派生数据类型期间的无效参数



我有一个structure xyz,如下struct xyz { char a; int32_t b; char c[50]; uint32_t d; uchar e[10];} 所示

我需要广播它,所以我使用了MPI_Bast(),其中我需要与结构xyz对应的MPI数据类型,因为我使用MPI_Type_creat_struct()函数创建了一个新的MPI数据数据类型作为MPI_Datatype MPI_my_new_datatype, oldtypes[4];,其中我使用了与上述结构成员数据类型对应的MPI数据类型,如下

oldtypes[4] = {MPI_CHAR, MPI_INT, MPI_UNSIGNED, MPI_UNSIGNED_CHAR};,为了创建新的数据类型,我在函数中使用了以下参数。。

MPI_Type_create_struct(4,blockcounts, offsets, oldtypes, &MPI_my_new_datatype); MPI_Type_commit(&MPI_my_new_datatype);

现在它正在编译,但给出的运行时错误如下:*通讯器MPI_COMM_WORLD MPI_ERR_ARGMPI_Type_create_struct中发生错误:其他类型的无效参数MPI_ERRORS_ARE_FATAL(再见)。

有人能找出问题出在哪里吗?

您不能将类似的类型"捆绑"在一起。每个字段都需要单独寻址,其中有5个字段,而不是4个字段。

还要注意,一般来说,实际"测量"偏移量而不是推断偏移量是个好主意。

以下工作:

#include <stdio.h>
#include <mpi.h>
#include <stdint.h>
struct xyz_t {
    char a; int32_t b; char c[50]; uint32_t d; unsigned char e[10];
};
int main(int argc, char **argv) {
    int rank, size, ierr;
    MPI_Datatype oldtypes[5] = {MPI_CHAR, MPI_INT, MPI_CHAR, MPI_UNSIGNED, MPI_UNSIGNED_CHAR};
    int blockcounts[5] = {1, 1, 50, 1, 10};
    MPI_Datatype my_mpi_struct;
    MPI_Aint offsets[5];
    struct xyz_t old, new;
    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    /* find offsets */
    offsets[0] = (char*)&(old.a) - (char*)&old;
    offsets[1] = (char*)&(old.b) - (char*)&old;
    offsets[2] = (char*)&(old.c) - (char*)&old;
    offsets[3] = (char*)&(old.d) - (char*)&old;
    offsets[4] = (char*)&(old.e) - (char*)&old;
    MPI_Type_create_struct(5, blockcounts, offsets, oldtypes, &my_mpi_struct);
    MPI_Type_commit(&my_mpi_struct);
    if (rank == 0) {
        old.a = 'a';
        old.b = (int)'b';
        strcpy(old.c,"This is field c");
        old.d = (unsigned int)'d';
        strcpy(old.e,"Field e");
        MPI_Send(&old, 1, my_mpi_struct, 1, 1, MPI_COMM_WORLD);
    } else if (rank == 1) {
        MPI_Status status;
        MPI_Recv(&new, 1, my_mpi_struct, 0, 1, MPI_COMM_WORLD, &status);
        printf("new.a = %cn", new.a);
        printf("new.b = %dn", new.b);
        printf("new.e = %sn", new.e);
    }
    MPI_Type_free(&my_mpi_struct);
    MPI_Finalize();
    return 0;
}

运行:

$ mpirun -np 2 ./struct
new.a = a
new.b = 98
new.e = Field e

更新:正如Dave Goodell在下面指出的,偏移量计算最好作为进行

#include <stddef.h>
/* ... */
offsets[0] = offsetof(struct xyz_t,a);
offsets[1] = offsetof(struct xyz_t,b);
offsets[2] = offsetof(struct xyz_t,c);
offsets[3] = offsetof(struct xyz_t,d);
offsets[4] = offsetof(struct xyz_t,e);

如果您的MPI支持它(大多数应该支持,尽管OpenMPI在某些MPI2.2类型中速度较慢),则MPI_UNSIGNED应该替换为MPI_UINT32

最新更新