gpt4 book ai didi

c - 使用 MPI_Reduce 的等级 ID 错误

转载 作者:太空宇宙 更新时间:2023-11-04 03:56:43 25 4
gpt4 key购买 nike

好吧,我正在使用 MPI + C 做一些作业。事实上,我只是写了 Peter Pacheco 的书中的编程作业 3.2 的一小段代码,称为并行编程简介。该代码似乎适用于 3 或 5 个进程...但是当我尝试超过 6 个进程时,程序就会中断。

我正在使用一种非常“糟糕”的调试方法,即放置一些 printfs 来跟踪问题发生的位置。使用这种“方法”,我发现在 MPI_Reduce 之后,出现了一些奇怪的行为,并且我的程序对等级 ID 感到困惑,特别是等级 0 消失了,并且出现了一个非常大(且错误)的等级。

我的代码在下面,在它之后,我发布了 3 和 9 个进程的输出......我正在运行

mpiexec -n X ./name_of_program

其中 X 是进程数。

我的代码:

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

int main(void)
{
MPI_Init(NULL,NULL);

long long int local_toss=0, local_num_tosses=-1, local_tosses_in_circle=0, global_tosses_in_circle=0;

double local_x=0.0,local_y=0.0,pi_estimate=0.0;

int comm_sz, my_rank;

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

if (my_rank == 0) {
printf("\nEnter the number of dart tosses: ");
fflush(stdout);
scanf("%lld",&local_num_tosses);
fflush(stdout);
}

//
MPI_Barrier(MPI_COMM_WORLD);

MPI_Bcast( &local_num_tosses, 1, MPI_LONG_LONG_INT, 0, MPI_COMM_WORLD);

MPI_Barrier(MPI_COMM_WORLD);

srand( rand() ); //tried to improve randomness here!

for (local_toss=0;local_toss<local_num_tosses;local_toss++) {
local_x = (-1) + (double)rand() / (RAND_MAX / 2);
local_y = (-1) + (double)rand() / (RAND_MAX / 2);

if ( (local_x*local_x + local_y*local_y) <= 1 ) {local_tosses_in_circle++;}
}


MPI_Barrier(MPI_COMM_WORLD);

MPI_Reduce
(
&local_tosses_in_circle,
&global_tosses_in_circle,
comm_sz,
MPI_LONG_LONG_INT,
MPI_SUM,
0,
MPI_COMM_WORLD
);

printf("\n\nDEBUG: myrank = %d, comm_size = %d",my_rank,comm_sz);
fflush(stdout);

MPI_Barrier(MPI_COMM_WORLD);

if (my_rank == 0) {
pi_estimate = ( (double)(4*global_tosses_in_circle) )/( (double) comm_sz*local_num_tosses );
printf("\nPi estimate = %1.5lf \n",pi_estimate);
fflush(stdout);
}

MPI_Finalize();
return 0;
}

现在,2 个输出:

(i) 对于 3 个进程:

Enter the number of dart tosses: 1000000

DEBUG: myrank = 0, comm_size = 3

DEBUG: myrank = 1, comm_size = 3

DEBUG: myrank = 2, comm_size = 3
Pi estimate = 3.14296

(ii) 对于 9 个进程:(注意\n 输出很奇怪,有时它不起作用)

        Enter the number of dart tosses: 10000000


DEBUG: myrank = 1, comm_size = 9
DEBUG: myrank = 7, comm_size = 9


DEBUG: myrank = 3, comm_size = 9
DEBUG: myrank = 2, comm_size = 9DEBUG: myrank = 5, comm_size = 9
DEBUG: myrank = 8, comm_size = 9



DEBUG: myrank = 6, comm_size = 9

DEBUG: myrank = 4, comm_size = 9DEBUG: myrank = -3532887, comm_size = 141598939[PC:06511] *** Process received signal ***
[PC:06511] Signal: Segmentation fault (11)
[PC:06511] Signal code: (128)
[PC:06511] Failing at address: (nil)
--------------------------------------------------------------------------
mpiexec noticed that process rank 0 with PID 6511 on node PC exited on signal 11 (Segmentation fault).
--------------------------------------------------------------------------

最佳答案

MPI_Reduce 的第三个参数时对我有用是1,不是comm_size(因为每个缓冲区的元素个数是1):

MPI_Reduce
(
&local_tosses_in_circle,
&global_tosses_in_circle,
1, //instead of comm_size
MPI_LONG_LONG_INT,
MPI_SUM,
0,
MPI_COMM_WORLD
);

当您增加进程数时,MPI_Reduce 会覆盖函数堆栈中的其他内容,例如my_rankcomm_sz,并破坏了数据。

此外,我认为您不需要任何 MPI_Barrier 语句。 MPI_ReduceMPI_Bcast 无论如何都是阻塞的。

我不会担心换行符。它们并没有丢失,但在输出的其他地方,可能是因为许多进程同时写入标准输出。

顺便说一句:使用 printf 进行调试非常普遍。

关于c - 使用 MPI_Reduce 的等级 ID 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15884547/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com