【问题标题】:Invalid node count in MPI pi calculationMPI pi 计算中的节点计数无效
【发布时间】:2016-10-22 11:41:35
【问题描述】:

我正在尝试并行化以下代码以计算 pi。

我的做法是用scatter把for并行化,然后用reduce计算sum值,最后显示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 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();
}

问题是当我使用选项 -np 1 和 2 运行程序时 我确实得到了想要的结果。

但当我使用 3、4 或更高版本运行时,我收到以下错误:

PIC_Send(284).........: Negative count, value is -240000
Fatal error in PMPI_Scatter: Invalid count, error stack

【问题讨论】:

    标签: c parallel-processing openmp openmpi


    【解决方案1】:

    MPI_Scatter() 的调用将更正:

    MPI_Scatter(send_vec, num_steps/size, MPI_INT, recv_vect, 
    num_steps, MPI_INT, 0, MPI_COMM_WORLD);
    
    • 要发送double,请使用数据类型MPI_DOUBLE,就像在MPI_Reduce() 中所做的一样
    • 由于sendtyperecvtype相似,发送到每个进程sendcount的项目数必须等于每个进程接收到的项目数recvcount。在本例中,它是num_steps/size

    最后,对MPI_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_steps/size?是因为我收到了我发送的所有内容吗?
    • documentation of openmpi about MPI_Scatter() 中指定的,参数sendcount 必须是“发送到每个进程的元素数”,recvcount 必须是“接收缓冲区中的元素数”。如果将double 类型的num_steps/size 元素发送到每个进程,则每个进程将收到double 类型的num_steps/size
    • 另见MPI standards 3.1的p160关于MPI_Scatter():The type signature associated with sendcount, sendtype at the root must be equal to the type signature associated with recvcount, recvtype at all processes (however, the type maps may be different). This implies that the amount of data sent must be equal to the amount of data received, pairwise between each process and the root. Distinct type maps between sender and receiver are still allowed.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    相关资源
    最近更新 更多