当mpi发送和接收进入循环时,Mpirun挂起

时间:2014-02-17 06:42:57

标签: c mpi cluster-computing powerpc

我试图使用mpirun在4节点集群上运行给定的程序。

Node0正在将数据分发到节点1,2和3。 在程序中,必须对变量'dir'的不同值进行计算, 范围从-90到90.

因此Node0正在分发数据并以循环方式收集结果(对于var'dir'的不同值)。 当给出do {*******}while(dir<=90);循环时,mpirun挂起,并且没有输出。 但是当我发表评论时,do {*******}while(dir<=90);循环输出是为变量dir的初始化值(dir=-90)获得的,并且该输出是正确的。在循环中给出时会出现问题。

有谁可以帮我解决这个问题。

    #include "mpi.h"
    int main(int argc,char *argv[])
    float dir=-90;
    int rank,numprocs;
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
    if(rank==0)
{
       do{

     /*initializing data*/
    for(dest=1;dest<numprocs;dest++)
    {

                  MPI_Send(&offset,1,MPI_INT,dest,FROM_MASTER,MPI_COMM_WORLD);              

    MPI_Send(&s_psi[offset],count,MPI_FLOAT,dest,FROM_MASTER,MPI_COMM_WORLD);

    }
    gettimeofday(&start,NULL);
    for (dest=1; dest<numprocs; dest++)
    {
        MPI_Recv(&offset,1,MPI_INT,dest,FROM_WORKER,MPI_COMM_WORLD,&status);            
            MPI_Recv(&P[offset],count,MPI_FLOAT,dest,FROM_WORKER,MPI_COMM_WORLD,&status);
    }

    gettimeofday(&end,NULL);
    timersub(&end,&start,&total);
    printf("time consumed=%ds %dus\n",total.tv_sec,total.tv_usec);
    dir++;
    }while(dir<=90);
    }


    if(rank>0)
{   
    MPI_Recv(&offset,1,MPI_INT,0,FROM_MASTER,MPI_COMM_WORLD,&status);           

    MPI_Recv(&s_psi[offset],count,MPI_FLOAT,0,FROM_MASTER,MPI_COMM_WORLD,&status);

    //Does the computation      
    }
    MPI_Send(&offset,1,MPI_INT,0,FROM_WORKER,MPI_COMM_WORLD);

        MPI_Send(&P[offset],count,MPI_FLOAT,0,FROM_WORKER,MPI_COMM_WORLD);
}   
MPI_Finalize();
return 0;
    }

1 个答案:

答案 0 :(得分:0)

rank > 0应该包含在循环中的部分。 每个MPI_Send都应该有相应的MPI_Recv。

if(rank>0) {   
     do {
         MPI_Recv(&offset,1,MPI_INT,0,FROM_MASTER,MPI_COMM_WORLD,&status);           
         MPI_Recv(&s_psi[offset],count,MPI_FLOAT,0,FROM_MASTER,MPI_COMM_WORLD,&status);
         // Computation      
         MPI_Send(&offset,1,MPI_INT,0,FROM_WORKER,MPI_COMM_WORLD);
         MPI_Send(&P[offset],count,MPI_FLOAT,0,FROM_WORKER,MPI_COMM_WORLD);
         dir++;
    } while(dir <= 90);
}

但是你可能在工作节点中不知道dir。通常,我们node0发送一个魔术包以结束工作者。

在node0的末尾:

for(r = 1; r < numprocs; r++)
    MPI_Send(&dummy, 1, MPI_INT, r, STOP, COMM);
对于woker节点

if(rank>0) {   
     while(true) {
         MPI_Recv(&offset,1,MPI_INT,0,FROM_MASTER,MPI_COMM_WORLD,&status);           
         MPI_Recv(&s_psi[offset],count,MPI_FLOAT,0,FROM_MASTER,MPI_COMM_WORLD,&status);
         // Computation      
         MPI_Send(&offset,1,MPI_INT,0,FROM_WORKER,MPI_COMM_WORLD);
         MPI_Send(&P[offset],count,MPI_FLOAT,0,FROM_WORKER,MPI_COMM_WORLD);

         if(MPI_Iprobe(ANY_SOURCE, STOP, COMM, &flag, &status)) {
             MPI_Recv(&dummy, 1, MPI_INT, ANY_SOURCE, STOP, COMM, NO_STATUS);
             break;
         }
    };
}

最后你可以MPI_finalize

顺便说一下,你可能想看看阻止而不是发送发送/接收。