通过MPI发送数组点对点通信

时间:2016-01-29 23:57:02

标签: c mpi

您好我正试图将2-dim数组的边缘发送到与MPI的点对点通信。

struct image {
    /* image data block */
    double **data; //2dim array

    /* boundaries */
    double *top;
    double *bot;
    double *left;
    double *right;

    /* dimensions */
    int width;
    int height;
};

每个节点都有自己的图像(相同的宽度和高度)以及应该接收交换数据的边界。每个节点都已知道发送/接收数据的位置。接收缓冲区(顶部,机器人,左,右)已经分配。 什么行不通的是我在交换过程中总是遇到分段错误。

这是我的批判方法:

void MPI_stencil_p_to_p(struct image *img, int *neighbours, MPI_Comm comm)
{
    int count = 0;

    for (int i = 0; i < 4; ++i)
    {
        if (neighbours[i] != MPI_PROC_NULL){
            count+=2;
        }
    }
    MPI_Status status[count];
    MPI_Request req[count];
    int count_tmp = count;
    for (int i = 0; i < 4; ++i)
    {
        if (neighbours[i] != MPI_PROC_NULL){
            count_tmp--;
            if (i == 0)
            {
                printf("%d: %d\n", ra, neighbours[i]);
                printf("works %d\n", ra);
                MPI_Isend(img->data[0], img->width, MPI_DOUBLE, neighbours[i], TAG, comm, &req[count_tmp]);
                count_tmp--;
                MPI_Irecv(&img->top, img->width, MPI_DOUBLE, neighbours[i], TAG, comm, &req[count_tmp]);
                continue;
            } else if (i == 2)
            {
                printf("%d: %d\n", ra, neighbours[i]);
                int len = img->height-1;
                MPI_Isend(img->data[len], img->width, MPI_DOUBLE, neighbours[i], TAG, comm, &req[count_tmp]);
                count_tmp--;
                MPI_Irecv(&img->bot, img->width, MPI_DOUBLE, neighbours[i], TAG, comm, &req[count_tmp]);
                continue;
            }

            MPI_Datatype col;
            MPI_Type_vector(img->height, 1, img->width, MPI_DOUBLE, &col);
            MPI_Type_commit(&col);

            if (i == 1)
            {
                printf("%d: %d\n", ra, neighbours[i]);
                MPI_Isend(&img->data[0][0], 1, col, neighbours[i], TAG, comm, &req[count_tmp]);
                count_tmp--;
                MPI_Irecv(&img->right, img->height, MPI_DOUBLE, neighbours[i], TAG, comm, &req[count_tmp]);
            } else
            {
                printf("%d: %d\n", ra, neighbours[i]);
                int len = img->width-1;
                MPI_Isend(&img->data[0][len], 1, col, neighbours[i], TAG, comm, &req[count_tmp]);
                count_tmp--;
                MPI_Irecv(&img->left, img->height, MPI_DOUBLE, neighbours[i], TAG, comm, &req[count_tmp]);
            }
            MPI_Type_free(&col);
        }
    }
    if (MPI_Waitall(count, req, status) != MPI_SUCCESS)
        error_exit(EXIT_FAILURE, "MPI_Waitall");
}

感谢帮助我!

1 个答案:

答案 0 :(得分:1)

在不确切知道segfault发生的位置的情况下,我只想猜错误在哪里。但是,每次有人问这样的问题时,都是因为他们使用双指针构建了一个2D数组,并且它们没有密集的矩阵。 MPI期望发送/接收连续数据,因此如果您尝试发送如下分配的矩阵的多行:

double **data;
data = malloc(sizeof(double) * n);
for (i = 0; i < n; i++) data[i] = malloc(sizeof(double) * m);

您遇到问题,因为data[0][m-1]data[1][0]不一定在内存中的连续位置。

相反,在MPI中发送矩阵时,您需要将它们分配为一维数组并进行额外的数学计算或单独发送每一行。