MPI_Gather在二维矩阵上只显示从主程序收集的数据[重复] 。

问题描述 投票:0回答:1

我试图使用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...

正如我自己的测试所显示的那样,收集之前的double for-loop计算出了正确的值,但是收集到了 full_matrix 只包含自己的进程,即主进程的数据,因为它后来的打印显示。

我很难理解为什么会这样,因为主进程正确地传输了数据。问题是我如何为每个进程分配内存吗?

c multidimensional-array mpi
1个回答
3
投票

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

解决办法是将Matrix存储在一整块内存中,像这样。

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];
}
© www.soinside.com 2019 - 2024. All rights reserved.