使用MPI_Reduce时列组ID出错
嗯,我正在用MPI+C做一些家庭作业。事实上,我刚刚从彼得·帕切科的书中写了一段编程作业3.2的小代码,叫做并行编程入门。代码似乎适用于3或5个进程。。。但是当我尝试6个以上的进程时,程序就中断了 我使用了一种非常“糟糕”的调试方法,即放置一些printf来跟踪问题发生的位置。使用这种“方法”,我发现在MPI_Reduce之后,出现了一些奇怪的行为,我的程序对列组ID感到困惑,特别是列组0消失,出现了一个非常大(错误)的列组 下面是我的代码,在它之后,我将发布3和9个进程的输出。。。我和你一起跑步使用MPI_Reduce时列组ID出错,c,mpi,C,Mpi,嗯,我正在用MPI+C做一些家庭作业。事实上,我刚刚从彼得·帕切科的书中写了一段编程作业3.2的小代码,叫做并行编程入门。代码似乎适用于3或5个进程。。。但是当我尝试6个以上的进程时,程序就中断了 我使用了一种非常“糟糕”的调试方法,即放置一些printf来跟踪问题发生的位置。使用这种“方法”,我发现在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;
}
(ii)对于9个进程:(注意\n输出是奇怪的,有时它不工作)
当的第三个参数是
1
,而不是comm\u size
(因为每个缓冲区中的元素数是1)时,它对我有效:
当增加进程数时,MPI\u Reduce
会覆盖函数堆栈中的其他内容,例如my\u rank
和comm\u sz
,并损坏数据
另外,我认为您不需要任何MPI\u Barrier
语句MPI\u Reduce
和MPI\u Bcast
仍在阻塞
我不会担心新台词。它们并没有丢失,而是在输出的其他地方,可能是因为许多进程同时写入标准输出
顺便说一下:使用
printf
进行调试非常常见。的第三个参数为1
,而不是comm\u size
(因为每个缓冲区中的元素数为1)时,它对我有效:
当增加进程数时,MPI\u Reduce
会覆盖函数堆栈中的其他内容,例如my\u rank
和comm\u sz
,并损坏数据
另外,我认为您不需要任何MPI\u Barrier
语句MPI\u Reduce
和MPI\u Bcast
仍在阻塞
我不会担心新台词。它们并没有丢失,而是在输出的其他地方,可能是因为许多进程同时写入标准输出
顺便说一下:使用printf进行调试是很常见的。非常好,Rafael,非常感谢!它解决了我的问题!事实上,MPI_Reduce的第三个参数是数据的大小。如果它不是向量,正确的值是1…真的!我觉得自己很笨:-(哈哈,关于这个障碍,我想和你一样……但是看看堆栈溢出帖子……真的很混乱!我知道beer的帖子是从哪里来的。我可能会进入这个话题,有时会回答你。如果你没有像beer提到的那样在一个循环中执行MPI_Reduce,那么去掉MPI_障碍肯定是可以的。非常感谢Rafael、 感谢你为帮助我所做的努力!非常感谢!非常好的Rafael,非常感谢!它解决了我的问题!事实上,MPI_Reduce的第三个参数是数据的大小..如果它不是向量,正确的值是1…真的!我感到很愚蠢:-(哈哈,关于这个障碍,我想和你一样……但是看看堆栈溢出帖子……真的很混乱!我知道beer的帖子是从哪里来的。我可能会进入这个话题,有时会回答你。如果你没有像beer提到的那样在一个循环中执行MPI_Reduce,那么去掉MPI_障碍肯定是可以的。非常感谢Rafael、 感谢你为帮助我所做的努力!非常感谢!
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
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
(
&local_tosses_in_circle,
&global_tosses_in_circle,
1, //instead of comm_size
MPI_LONG_LONG_INT,
MPI_SUM,
0,
MPI_COMM_WORLD
);