笛卡尔拓扑mpi中的边界交换

笛卡尔拓扑mpi中的边界交换,mpi,openmpi,Mpi,Openmpi,我想在我的mpi程序中执行边界交换。 我有这样的结构: cell** local_petri_A; local_petri_A = calloc(p_local_petri_x_dim,sizeof(*local_petri_A)); for(int i = 0; i < p_local_petri_x_dim ; i ++){ local_petri_A[i] = calloc(p_local_petri_y_dim,sizeof(**local_petri_A));

我想在我的mpi程序中执行边界交换。 我有这样的结构:

cell** local_petri_A;

local_petri_A = calloc(p_local_petri_x_dim,sizeof(*local_petri_A));

for(int i = 0; i < p_local_petri_x_dim ; i ++){
        local_petri_A[i] = calloc(p_local_petri_y_dim,sizeof(**local_petri_A));
    }
我希望有一个类似于下图的交换方案:

因此,我将程序放在笛卡尔拓扑中,首先定义mpi类型以执行交换: void创建_类型(){

}

然后最后尝试从南方和北方进行交换:

   /*send to the north receive from the south */
   MPI_Sendrecv ( & local_petri_A[0][1] , 1 , border_row_t , p_north , TAG_EXCHANGE ,& local_petri_A [0][ p_local_petri_y_dim  -1] , 1 , border_row_t , p_south , TAG_EXCHANGE ,cart_comm , MPI_STATUS_IGNORE );
   /*send to the south receive from the north */
   MPI_Sendrecv ( & local_petri_A[0][ p_local_petri_y_dim  -2] , 1 , border_row_t , p_south , TAG_EXCHANGE ,& local_petri_A [0][0] , 1 , border_row_t , p_north , TAG_EXCHANGE ,cart_comm , MPI_STATUS_IGNORE );
注意:在本节中,x_inside和y_inside是数组的“内部”维度(无重影部分),p_local_petri_dim是整个数组的维度

那么我有一个错误:

我做错什么了吗


提前感谢您的帮助。

问题在于您分配2D阵列的方式。 您分配一个数组,因此在连续内存中不太可能有两行。因此,列的ddt与二维阵列布局不匹配

您可以参考以正确分配阵列


顺便说一句,Fortran没有这种问题,因此如果这是一个选项,那将使您的生活更轻松。

问题在于您分配2D数组的方式。 您分配一个数组,因此在连续内存中不太可能有两行。因此,列的ddt与二维阵列布局不匹配

您可以参考以正确分配阵列


顺便说一句,Fortran没有这种问题,因此如果这是一个选项,那将使您的生活更轻松。

好,因此它对列不起作用,但对行又如何?在这里,我只尝试发送一些行,但仍然有一个错误,我的分配行在memry中是连续的,不是吗?行肯定是连续的。请用a编辑您的问题,我会看一看itI注意到您发送的RECV带有
本地petri\u dim-1][p\u local\u petri\u y_dim-1]
,它应该是
本地petri\u a[p\u local\u petri\u y_dim-1][1]
吗?好吧,那么它对该列不起作用,但行呢?在这里,我只尝试发送一些行,但仍然有一个错误,我的分配行在memry中是连续的,不是吗?行肯定是连续的。请用a编辑您的问题,我会看一看。我注意到您发送的RECV带有
本地petri\u dim-1][p\u本地petri\u dim-1][p\u本地petri\u dim-1]
,它应该是
本地petri\u a[p\u本地petri\u dim-1][1]
////////////////////////////////
////////////////////////////////
// cell type
const int    nitems=2;
int          blocklengths[2] = {1,1};
MPI_Datatype types[2] = {MPI_INT, MPI_INT};
MPI_Aint     offsets[2];

offsets[0] = offsetof(cell, color);
offsets[1] = offsetof(cell, strength);

MPI_Type_create_struct(nitems, blocklengths, offsets, types, &mpi_cell_t);
MPI_Type_commit(&mpi_cell_t);
////////////////////////////////
///////////////////////////////

MPI_Type_vector ( x_inside , 1 , 1 , mpi_cell_t , & border_row_t );
MPI_Type_commit ( & border_row_t );
/*we put the stride to x_dim to get only one column*/
MPI_Type_vector ( y_inside  , 1 , p_local_petri_x_dim , MPI_DOUBLE , & border_col_t );
MPI_Type_commit ( & border_col_t );
   /*send to the north receive from the south */
   MPI_Sendrecv ( & local_petri_A[0][1] , 1 , border_row_t , p_north , TAG_EXCHANGE ,& local_petri_A [0][ p_local_petri_y_dim  -1] , 1 , border_row_t , p_south , TAG_EXCHANGE ,cart_comm , MPI_STATUS_IGNORE );
   /*send to the south receive from the north */
   MPI_Sendrecv ( & local_petri_A[0][ p_local_petri_y_dim  -2] , 1 , border_row_t , p_south , TAG_EXCHANGE ,& local_petri_A [0][0] , 1 , border_row_t , p_north , TAG_EXCHANGE ,cart_comm , MPI_STATUS_IGNORE );