C MPI pi计算中的节点计数无效
我正在尝试将以下代码并行化以计算pi 我的方法是使用散布来并行化for,然后使用reduce来计算和值,最后显示pi 我的代码如下C MPI pi计算中的节点计数无效,c,parallel-processing,openmp,openmpi,C,Parallel Processing,Openmp,Openmpi,我正在尝试将以下代码并行化以计算pi 我的方法是使用散布来并行化for,然后使用reduce来计算和值,最后显示pi 我的代码如下 #include <stdio.h> #include <mpi.h> long num_steps = 100000; double step = 1.0/100000.0; int main() { int i, myid, size; double x, pi, local_sum = 0.0, sum=0.0; double
#include <stdio.h>
#include <mpi.h>
long num_steps = 100000;
double step = 1.0/100000.0;
int main() {
int i, myid, size;
double x, pi, local_sum = 0.0, sum=0.0;
double send_vec[num_steps], recv_vect[num_steps];
// Initialize the MPI environment
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
if (myid ==0){
int i=0;
for (i=0; i<num_steps;i++){
send_vec[i]=i;
}
}
MPI_Scatter(send_vec, num_steps/size, MPI_INT, recv_vect,
num_steps, MPI_INT, 0, MPI_COMM_WORLD);
for(i = 0; i < num_steps; ++i) {
x = (recv_vect[i]-0.5)*step;
local_sum += 4.0/(1.0+x*x);
}
MPI_Reduce(&local_sum, &sum, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
if (myid == 0){
pi = step*sum;
printf("PI value = %f\n", pi);
}
// Finalize the MPI environment.
MPI_Finalize();
}
要更正对
MPI\u Scatter()
的调用:
MPI_Scatter(send_vec, num_steps/size, MPI_INT, recv_vect,
num_steps, MPI_INT, 0, MPI_COMM_WORLD);
- 要发送
,请像在double
MPI\u Reduce()中那样使用数据类型
MPI\u double
- 由于
与sendtype
类似,发送到每个进程recvtype
的项目数必须等于每个进程sendcount
接收的项目数。在本例中,它是recvcount
num\u步数/size
MPI\u Scatter()
的调用如下所示:
MPI_Scatter(send_vec, num_steps/size, MPI_DOUBLE, recv_vect,
num_steps/size, MPI_DOUBLE, 0, MPI_COMM_WORLD);
最后,可以使用动态内存分配来避免使用堆栈存储大型阵列。此外,可以减少分配的空间以减少内存占用:
num_steps=(num_steps/size)*size;
double* send_vec=NULL;
double* recv_vec=NULL;
if(rank==0){
send_vec=malloc((num_steps/size)*sizeof(double));
if(send_vec==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
}
recv_vec=malloc(num_steps*sizeof(double));
if(recv_vec==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
...
if(rank==0){
free(send_vec);
}
free(recv_vec);
我工作。非常感谢。您能解释一下为什么接收大小必须是:num_步数/大小吗?是因为我正在接收我发送的所有内容吗?如中所述,参数
sendcount
必须是“发送到每个进程的元素数”,而recvcount
必须是“接收缓冲区中的元素数”。如果将类型为double
的num\u steps/size
元素发送到每个进程,每个进程将接收类型为double
的num\u steps/size
。另请参见关于MPI\u Scatter()
:与sendcount关联的类型签名的第160页,根目录下的sendtype必须等于所有进程上与recvcount、recvtype关联的类型签名(但是,类型映射可能不同)。这意味着发送的数据量必须等于接收的数据量,在每个进程和根进程之间成对。发送方和接收方之间仍然允许使用不同类型的映射。
num_steps=(num_steps/size)*size;
double* send_vec=NULL;
double* recv_vec=NULL;
if(rank==0){
send_vec=malloc((num_steps/size)*sizeof(double));
if(send_vec==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
}
recv_vec=malloc(num_steps*sizeof(double));
if(recv_vec==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
...
if(rank==0){
free(send_vec);
}
free(recv_vec);