使用MPI_Bcast(...)广播动态分配的2d数组

时间:2018-09-16 09:44:19

标签: mpi

我必须使用malloc动态创建一个数组,由根进程执行此操作,然后应该将该数组广播到所有其他将立即打印该数组的进程,实际上要求其他进程将更改矩阵独立。我的主要问题是无法将整个阵列广播到所有进程。

#include <stdlib.h>
#include <mpi.h>

int main(int argc, char **argv)
{   
    int **array;
    int rank,size,i,j;

    MPI_Init(&argc,&argv);
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);
    MPI_Comm_size(MPI_COMM_WORLD,&size);
    MPI_Datatype data_type;

    size= 4;
    array = (int **)malloc(size*sizeof(int *));
    for(i=0;i<size;i++)
        array[i] = (int *)malloc(size*sizeof(int));
    if(rank==0)
    {
        int t= 0;
        for(i=0;i<size;i++)
        {
            for(j=0;j<size;j++){
                array[i][j]=t++;
                printf("%4d",array[i][j]);
            }
            printf("\n");
        }
        printf("size is %zu\n",sizeof(array));
    }
    MPI_Barrier(MPI_COMM_WORLD);
    MPI_Bcast(&size,1,MPI_INT,0,MPI_COMM_WORLD);
    printf("size %d proec %d\n",size,rank);

    MPI_Bcast((int **)&(array[0][0]),size*size,MPI_INT,0,MPI_COMM_WORLD);
    MPI_Barrier(MPI_COMM_WORLD);
    printf("process %d prainting matrix:\n",rank);

    for (i= 0; i <size;i++)
    {
        for(j= 0; j < size; j++)
            printf("%d [%d]\t",array[i][j],rank);
        printf("\n");
    }

    MPI_Barrier(MPI_COMM_WORLD);
    MPI_Finalize();
}

1 个答案:

答案 0 :(得分:1)

问题出在线

MPI_Bcast((int **)&(array[0][0]),size*size,MPI_INT,0,MPI_COMM_WORLD);

您应该

for(i=0;i<size;i++)
{
  MPI_Bcast((int **)&(array[i][0]),size,MPI_INT,0,MPI_COMM_WORLD);
}

我不知道您的意图是什么,但是sizeof(array)不会返回数组的大小,而是(size_t *)的大小(64位为8位)。

如果需要的话,详细解释。

MPI_Send或MPI_Bcast确实发送了很多内存。

要确定这些块,您必须给出一个开始(MPI_Bcast或MPI_Send的第一个参数),然后一个长度(第二个参数),然后是数据类型(第三个参数)。

在您的示例中,它知道它必须从&(array[0][0])发送到&(array[0][0])+(size*size-1)*sizeof(int)

现在,当您完成

int main(int argc, char **argv)
{   
    int **array, * array_un;
    int rank,size,i,j;

    int **array
    size= 4;
    array = (int **)malloc(size*sizeof(int *));
    for(i=0;i<size;i++)
    {
        array[i] = (int *)malloc(size*sizeof(int));
        printf("Ox%X\n",(size_t)array[i]);
    }
    printf("end array=Ox%X\n",(size_t) &(array[size-1][size-1]));
    printf("end pointer=Ox%X\n",(size_t) array+(size*size-1)*sizeof(int));
}

它输出

Ox13B91A0
Ox13B91C0
Ox13B91E0
Ox13B6B90
end array  = Ox13B6B9C
end pointer= Ox13BB06C

您看到end arrayend pointer是不同的。现在,如果您查看每个malloc的地址,则增量为0x20(大于4*size(int)=10),然后突然减少0x2650!

成功malloc分配内存时,不能保证该内存是彼此相邻分配的。

因此,您无法使用MPI_Bcast((int **)&(array[0][0]),size*size,MPI_INT,0,MPI_COMM_WORLD);发送数据,因为&(array[0][0])到&(array[0][0])+(size*size-1)*sizeof(int)之间的数据实际上并不包含您要发送的数据。

但是malloc分配了一块连续的内存

因此您可以发送MPI_Bcast((int **)&(array[i][0]),size,MPI_INT,0,MPI_COMM_WORLD);

要努力

设置发送和接收需要付费,而发送则需要付费。因此,调用MPI_“ something”越少,效果越好。

因此,您的矩阵实际上应该分配一个malloc

将修改后的代码与此代码进行比较

#include <mpi.h>

int main(int argc, char **argv)
{   
    int *array;
    int rank,size,i,j;

    MPI_Init(&argc,&argv);
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);
    MPI_Comm_size(MPI_COMM_WORLD,&size);
    MPI_Datatype data_type;

    size= 4;
    array = (int *)malloc(size*size*sizeof(int));

    if(rank==0)
    {
        int t= 0;
        for(i=0;i<size;i++) { for(j=0;j<size;j++){ array[i*size+j]=t++; } }
    }

    MPI_Bcast(array,size*size,MPI_INT,0,MPI_COMM_WORLD);

    MPI_Barrier(MPI_COMM_WORLD);
    printf("process %d printing matrix:\n",rank);

    for (i= 0; i <size;i++)
    {
        for(j= 0; j < size; j++)
            printf("%d [%d]\t",array[i*size+j],rank);
        printf("\n");
    }
    MPI_Finalize();
}