c - 如何通过 MPI_Send 发送整数数组?

标签 c arrays mpi

我正在尝试用常规 C 创建一个程序,在任意数量的进程之间平均划分整数数组。出于调试目的,我使用具有 12 个数字和只有 2 个进程的整数数组,以便主进程将具有 [1,2,3,4,5,6],从属进程将具有 [7,8,9,10 ,11,12]。但是我收到一条错误消息:MPI_ERR_BUFFER:无效的缓冲区指针

经过一番研究,我发现有一个函数可以做到这一点(MPI_Scatter)。不幸的是,由于我正在学习 MPI,因此实现仅限于 MPI_SendMPI_Recv 。无论如何,MPI_SendMPI_Recv 都使用 void*,并且我正在发送 int*,所以它应该可以工作。谁能指出我做错了什么?谢谢。

int* create_sub_vec(int begin, int end, int* origin);
void print(int my_rank, int comm_sz, int n_over_p, int* sub_vec);

int main(void){

    int comm_sz;
    int my_rank;

    int vec[12] = {1,2,3,4,5,6,7,8,9,10,11,12};
    int* sub_vec = NULL;
    int n_over_p;

    MPI_Init(NULL, NULL);
    MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);    

    n_over_p = 12/comm_sz;
    printf("Process %d calcula n_over_p = %d\n", my_rank, n_over_p);

    if (my_rank != 0) {
        MPI_Recv(sub_vec, n_over_p, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        print(my_rank, comm_sz, n_over_p, sub_vec);

    } else {

        printf("Distribuindo dados\n");
        for (int i = 1; i < comm_sz; i++) {
            sub_vec = create_sub_vec(i*n_over_p, (i*n_over_p)+n_over_p, vec);
            MPI_Send(sub_vec, n_over_p, MPI_INT, i, 0, MPI_COMM_WORLD);
        }
        printf("Fim da distribuicao de dados\n");

        sub_vec = create_sub_vec(0, n_over_p, vec);

        print(my_rank, comm_sz, n_over_p, sub_vec);
    }

    MPI_Finalize();
    return 0;

}

int* create_sub_vec(int begin, int end, int* origin){
    int* sub_vec;
    int size;
    int aux = 0;
    size = end - begin;
    sub_vec = (int*)malloc(size * sizeof(int));
    for (int i = begin; i < end; ++i) {
        *(sub_vec+aux) = *(origin+i);
        aux += 1;
    }
    return  sub_vec;
}

void print(int my_rank, int comm_sz, int n_over_p, int* sub_vec){
    printf("Process %d out of %d received sub_vecotr: [ ", my_rank, comm_sz);
    for (int i = 0; i < n_over_p; ++i)
    {
        printf("%d, ", *(sub_vec+i));
    }
    printf("]\n");
}

最佳答案

问题是 sub_vec 未分配在非零等级上。 这由您决定(例如 MPI 不分配接收缓冲区)。

接收部分应该看起来像

if (my_rank != 0) {
    sub_vec = (int *)malloc(n_over_p * sizeof(int));    
    MPI_Recv(sub_vec, n_over_p, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}

正如您所写,自然的方法是通过MPI_Scatter()(并且再次由您决定在开始分散之前分配接收缓冲区。

关于c - 如何通过 MPI_Send 发送整数数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46437458/

相关文章:

mpi - 非阻塞发送和阻塞接收是否仍然需要等待

c - 将 CSV 文件中的数据添加到结构中

ios - UIScrollView添加图片-使用数组滑动切换效果

javascript - 使用 JavaScript 从数组中触发命名函数?

MPI - 跨进程共享队列

c++ - 使用 Boost.MPI 库的目的是什么?

c - 为什么以下程序退出失败?

当我使用 A* 获取 void * 值并打印它时命令终止

c++ - 在 C/C++ 中去除二进制数中的前导零

java - 使用 for 循环将英语翻译为莫尔斯电码