【问题标题】:how to create MPI custom type properly如何正确创建 MPI 自定义类型
【发布时间】:2021-02-05 14:04:24
【问题描述】:

我有结构(复矩阵的单个元素):

typedef struct  s_complex_number {
    int real;
    int img;
}               ComplexNumber;

这就是我将复杂矩阵描述为自定义 MPI 数据类型的方式

#define SIZE_COL 10
MPI_Datatype  matrix;
MPI_Datatype  types[2] = {MPI_INT, MPI_INT};
MPI_Datatype  row;
MPI_Datatype  complexNumber;
MPI_Aint      disp[2];
ComplexNumber ***recvData;
ComplexNumber ***sendData;
ComplexNumber example;

int blockLength[] = {1, 1};

disp[0] = (uintptr_t)&example.real - (uintptr_t)&example;
disp[1] = (uintptr_t)&example.img - (uintptr_t)&example;

/***********************Initialize custom types************************/
MPI_Type_create_struct(2, blockLength, disp, types, &complexNumber);
MPI_Type_commit(&complexNumber);

MPI_Type_vector(1, SIZE_COL, 1, complexNumber, &row);
MPI_Type_commit(&row);

MPI_Type_vector(1, SIZE_COL, 1, row, &matrix);
MPI_Type_commit(&matrix);
/**********************************************************************/

每次我尝试发送数据时,都会出现分段错误。

如何正确描述 MPI 中的 ComplexNumber** 类型?

【问题讨论】:

  • 您可以使用预定义的MPI_2INT 数据类型。 MPI 需要连续内存中的数据(例如,没有锯齿状数组),您可以确保这一点。

标签: c types segmentation-fault mpi


【解决方案1】:

使用 MPI 发送/接收ComplexNumber ***mat 非常麻烦。你需要创建一个结构数据类型,其字段与mat中的行一样多,然后将每个字段的偏移量设置为相应行开头的绝对地址,最后使用MPI_BOTTOM作为缓冲区发送/接收调用中的地址:

MPI_Datatype theMatrix;
MPI_Datatype types[SIZE_COL];
MPI_Aint disps[SIZE_COL];
int blocklengts[SIZE_COL];

for (int i = 0; i < SIZE_COL; i++)
{
   types[i] = row;
   disps[i] = (MPI_Aint) (*mat)[i];
   blocklents[i] = 1;     
}

MPI_Type_create_struct(SIZE_COL, blocklengths, disps, types, &theMatrix);
MPI_Type_commit(&theMatrix);

MPI_Send(MPI_BOTTOM, 1, theMatrix, ...);

MPI_Type_free(&theMatrix);

注意事项:

  • theMatrix 可用于发送 mat 并且仅用于发送 mat - 没有其他指向指针数组的指针对象的每一行都可能位于内存中的相同地址。这就是为什么theMatrix 在调用MPI_Send 之后立即被释放,因为它没有用,除非矩阵空间将被重复使用并一次又一次地发送。
  • 结构字段的偏移量是行的地址。可以使用(char *)(*mat)[i] - (char *)mat,但这样更麻烦。
  • 由于偏移量是绝对地址,MPI_BOTTOM 被指定为缓冲区地址。这本质上是0——地址空间的底部。如果使用(char *)(*mat)[i] - (char *)mat 代替偏移量,那么您必须提供mat 而不是MPI_BOTTOM

另一方面,发送/接收平面矩阵,即,

ComplexNumber *mat = malloc(SIZE_COL * SIZE_COL * sizeof(ComplexNumber));

归结为:

MPI_Send(mat, 1, matrix, ...);

这就是根据您的代码创建的数据类型所描述的内存布局。

【讨论】:

    猜你喜欢
    • 2014-04-16
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    • 2013-01-22
    • 2020-04-03
    • 1970-01-01
    相关资源
    最近更新 更多