尝试使用MPI_Recv接收矢量

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了尝试使用MPI_Recv接收矢量相关的知识,希望对你有一定的参考价值。

我正在使用MPI和CGM现实并行模型实现Chan和Dehne排序算法。到目前为止,每个过程从原始向量接收N / p数,然后每个过程使用快速排序顺序排序,每个过程然后从其本地向量(样本具有大小p)创建样本,然后每个过程发送他们的样本到P0; P0应该接收大小为p * p的较大向量中的所有样本,以便它可以容纳来自所有处理器的数据。这是我被困住的地方,它似乎工作但是由于某些原因,在P0收到所有数据之后,它出现了Signal:Segmentation fault(11)。谢谢。

以下是代码的相关部分:

// Step 2. Each process calculates it's local sample with size comm_sz
        local_sample = create_local_sample(sub_vec, n_over_p, comm_sz);

// Step 3. Each process sends it's local sample to P0
        if (my_rank == 0) {
            global_sample_receiver = (int*)malloc(pow(comm_sz,2)*sizeof(int));
            global_sample_receiver = local_sample;
            for (i = 1; i < comm_sz; i++) {
                MPI_Recv(global_sample_receiver+(i*comm_sz), comm_sz, MPI_INT,
                i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
            }   
        } else {
            MPI_Send(local_sample, comm_sz, MPI_INT, 0, 0, MPI_COMM_WORLD);
        }

        printf("P%d got here
", my_rank);

        MPI_Finalize();

有趣的是,每个进程都会到达命令printf("P%d got here ", my_rank);,因此打印到终端。此外,global_sample_receiver确实包含了最终应该包含的数据,但程序仍然完成了分段错误。

这是输出:

P2 got here
P0 got here
P3 got here
P1 got here
[Krabbe-Ubuntu:05969] *** Process received signal ***
[Krabbe-Ubuntu:05969] Signal: Segmentation fault (11)
[Krabbe-Ubuntu:05969] Signal code: Address not mapped (1)
[Krabbe-Ubuntu:05969] Failing at address: 0x18000003e7
--------------------------------------------------------------------------
mpiexec noticed that process rank 0 with PID 5969 on node Krabbe-Ubuntu 
exited on signal 11 (Segmentation fault).
--------------------------------------------------------------------------

编辑:我发现了问题,原来local_sample也需要一个malloc。

答案

问题是你在秩0上用global_sample_receiver(它是另一个指针)覆盖local_sample(这是一个指针)。

如果你想用comm_sz中的第一个global_sample_receiver元素设置comm_sz的第一个local_sample元素,那么你必须手动复制数据(例如不是指针)。

memcpy(global_sample_receiver, local_sample, comm_sz * sizeof(int));

话虽这么说,这样做的自然MPI方式是通过MPI_Gather()

以下是第3步的结果:

// Step 3. Each process sends it's local sample to P0
if (my_rank == 0) {
    global_sample_receiver = (int*)malloc(pow(comm_sz,2)*sizeof(int));
}
MPI_Gather(global_sample_receiver,comm_sz, MPI_INT, local_sample, comm_sz, MPI_INT, 0, MPI_COMM_WORLD);

以上是关于尝试使用MPI_Recv接收矢量的主要内容,如果未能解决你的问题,请参考以下文章

使用 MPI_Send 和 MPI_Recv 未正确接收矩阵

mpi_recv 只接收 mpi_send 发送的一半数据?完全糊涂

MPI_Recv:接收的大小与发送的大小不同

线程中阻塞 MPI_Recv 的 CPU 使用率

C++ 中的 MPI_Send MPI_Recv 段错误

收到的关于 MPI_Isend 的数据不一致