MPI_Gather 在二维矩阵上仅显示从主进程收集的数据

MPI_Gather on 2D matrix only showing data gather from master process

我正在尝试使用 MPI_Gather 将各个二维数组收集到主进程中,然后打印出整个矩阵的内容。我将工作负载分配给 num_processes 个进程,并让每个进程都在自己的私有矩阵上工作。 我将给出我的代码片段和一些伪代码来演示我在做什么。请注意,我在传输结构类型时创建了自己的 MPI_Datatype。

Point **matrix = malloc(sizeof(Point *) * (num_rows/ num_processes));
for (i = 0; i < num_rows/num_processes; i++)
    matrix [i] = malloc(sizeof(Point) * num_cols);

for( i = 0; i< num_rows/num_processes; i++)
    for (j = 0; j < num_cols; j++)
        matrix[i][j] = *Point type*

if (processor == 0) {
    full_matrix = malloc(sizeof(Point *) * num_rows);
    for (i = 0; i < num_rows/num_processes; i++)
        matrix [i] = malloc(sizeof(Point) * num_cols);

    MPI_Gather(matrix, num_rows/num_processes*num_cols, MPI_POINT_TYPE, full_matrix, num_rows/num_processes*num_cols, MPI_POINT_TYPE, 0, MPI_COMM_WORLD);
} else {
    MPI_Gather(matrix, num_rows/num_processes*num_cols, MPI_POINT_TYPE, NULL, 0, MPI_DATATYPE_NULL, 0, MPI_COMM_WORLD);
}
// ...print full_matrix...

收集之前的双 for 循环计算出正确的值,正如我自己的测试所示,但是 full_matrix 上的收集仅包含来自其自身进程(即主进程)的数据,因为它的打印稍后显示。

我无法弄清楚为什么主进程可以正确传输数据。问题是我如何为每个进程分配内存?

问题是 MPI_Gather 期望缓冲区的内容在内存中相邻,但是重复调用 malloc 并不能保证这一点,因为每次调用都可以 return 一个指向任意对象的指针内存位置。

解决方案是将矩阵存储在一整块内存中,如下所示:

Point *matrix = malloc(sizeof(Point) * (num_rows / num_processes) * num_cols);

使用此方法,您将必须访问 matrix[i * N + j] 形式的数据。如果要保留当前代码,可以像以前一样创建相邻内存,并使用另一个向量存储指向每一行的指针:

Point *matrixAdj = malloc(sizeof(Point) * (num_rows / num_processes) * num_cols);
Point **matrix = malloc(sizeof(Point *) * num_rows);

for (int i = 0; i < num_rows; ++i) {
    matrix[i] = &matrixAdj[i * num_rows];
}