如何正确创建MPI自定义类型

问题描述

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

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,row,&matrix);
MPI_Type_commit(&matrix);
/**********************************************************************/

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

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

解决方法

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

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));

这是按照代码描述创建的数据类型的内存布局。