尝试使用 MPI_Recv 接收向量
Trying to receive a vector with MPI_Recv
我正在使用 MPI 和 CGM 现实并行模型实现 Chan 和 Dehne 排序算法。到目前为止,每个进程从原始向量接收 N/p 个数字,然后每个进程使用快速排序按顺序排列它们的数字,然后每个进程从它的本地向量创建一个样本(样本的大小为 p),然后每个进程发送它们采样到 P0; P0 应该接收大小为 p*p 的更大向量中的所有样本,以便它可以容纳来自所有处理器的数据。这就是我卡住的地方,它似乎在工作,但由于某种原因,在 P0 收到所有数据后,它退出并显示信号:分段错误 (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\n", my_rank);
MPI_Finalize();
有趣的是,每个进程都会到达命令 printf("P%d got here\n", 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。
问题是你在零阶上用 local_sample
(另一个指针)覆盖了 global_sample_receiver
(一个指针)。
如果您想将 global_sample_receiver
的前 comm_sz
个元素设置为 local_sample
的前 comm_sz
个元素,则必须复制数据(例如 不是指针)手动。
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 和 CGM 现实并行模型实现 Chan 和 Dehne 排序算法。到目前为止,每个进程从原始向量接收 N/p 个数字,然后每个进程使用快速排序按顺序排列它们的数字,然后每个进程从它的本地向量创建一个样本(样本的大小为 p),然后每个进程发送它们采样到 P0; P0 应该接收大小为 p*p 的更大向量中的所有样本,以便它可以容纳来自所有处理器的数据。这就是我卡住的地方,它似乎在工作,但由于某种原因,在 P0 收到所有数据后,它退出并显示信号:分段错误 (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\n", my_rank);
MPI_Finalize();
有趣的是,每个进程都会到达命令 printf("P%d got here\n", 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。
问题是你在零阶上用 local_sample
(另一个指针)覆盖了 global_sample_receiver
(一个指针)。
如果您想将 global_sample_receiver
的前 comm_sz
个元素设置为 local_sample
的前 comm_sz
个元素,则必须复制数据(例如 不是指针)手动。
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);