使用 MPI 发送二维数组

Posted

技术标签:

【中文标题】使用 MPI 发送二维数组【英文标题】:Send 2d array using MPI 【发布时间】:2019-08-12 04:48:24 【问题描述】:

我一直在努力实现使用 MPI 和 C++ 并行化 Burger 方程离散域的计算。

我一直在关注此页面中提出的其他问题,但没有获得预期的结果。目前,我通过使用 2 个处理器简化了问题,并且我只发送和接收到右侧和左侧的等级。

为了初始化二维数组,我使用了这个函数:

double **alloc_2d_int(int rows, int cols) 
    double *data = (double *)malloc(rows*cols*sizeof(double));
    double **array= (double **)malloc(rows*sizeof(double*));
    for (int i=0; i<rows; i++)
        array[i] = &(data[cols*i]);

    return array;

这里一个时间向量被初始化为零。将大小增加 2 以获得 ghost shell,我可以在其中放置从其他等级接收的列和行,并使用它们来计算位于边缘的值的中心差异。

temp = alloc_2d_int(Ny_P+2,Nx_P+2);
           for (unsigned i=0; i < Ny_P+2; i++)
        
            for (unsigned j=0; j < Nx_P+2; j++)
            
               temp[i][j]=0;               
            
         

我简化了仅用 1 填充域的问题。

 for (unsigned i=1; i < Ny_P+1; i++)
        
            for (unsigned j=1; j < Nx_P+1; j++)
            
               temp[i][j]=1;
            
        

然后在每个时间步我将接收和发送。我现在只是通过左右发送和接收来工作。

            MPI_Issend(&(temp[Ny_P][1]), Nx_P, MPI_DOUBLE, rankright, 2, MPI_COMM_WORLD, &request5);
            MPI_Irecv(&(temp[0][1]), Nx_P, MPI_DOUBLE, rankleft, 2, MPI_COMM_WORLD, &request6);
            MPI_Issend(&(temp[1][1]), Nx_P, MPI_DOUBLE, rankleft, 3, MPI_COMM_WORLD, &request7);
            MPI_Irecv(&(temp[Ny_P+1][1]), Nx_P, MPI_DOUBLE, rankright, 3, MPI_COMM_WORLD, &request8);

理论上,在这种情况下,我想水平发送列,但它是放置一行,我得到这个结果:enter image description here

我知道问题出在内存布局的结构上,但我尝试了几种方法来指向数据,但都无法获得结果。

非常感谢您的帮助。

干杯!:)

【问题讨论】:

【参考方案1】:

这里有简单的建议。如果你在做 MPI,那通常意味着 HPC,所以你想改用一维数组并使用二维函数/宏来访问它。

这也将导致一次 MPI 调用,而不是每行或每列一次,因此完全没有理由使用指向数组的指针数组。

【讨论】:

Hi Matthieu,我尝试使用形状为 [i*Nx+j] 的一维数组,但我无法正确发送和接收,所以我切换到这种类型的数组进行排序出来吧。 形状可能不是[i*Nx+j]!您通常发送到另一个等级的完整行或完整列,因此形状应该是 Nx 的倍数。

以上是关于使用 MPI 发送二维数组的主要内容,如果未能解决你的问题,请参考以下文章

使用 MPI_Gather 在 Fortran 中发送二维数组

通过 MPI 发送和接收二维数组

在 MPI C++ 中传递大型二维数组

MPI_Bcast 动态二维数组

MPI_GATHERV (Fortran) 从二维子矩阵创建一个新的二维矩阵

如何确保二维数组在内存中连续分配