【问题标题】:Mpirun hangs when mpi send and recieve is put in a loop当 mpi 发送和接收被置于循环中时,Mpirun 挂起
【发布时间】:2014-03-16 08:32:30
【问题描述】:

我试图使用 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;
    }

【问题讨论】:

    标签: c mpi cluster-computing powerpc


    【解决方案1】:

    rank &gt; 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会发送一个魔术包来结束worker。

    在 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

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

    【讨论】:

    • 谢谢。实际上,我必须在 4 节点单核 PowerPC 集群中运行此应用程序。当应用程序在 pc 上运行时,在工作节点中添加一个“do..while”循环解决了这个问题。但是 mpirun 在基于 PowerPC 的集群上运行时仍然挂起。代码是使用命令“mpirun --prefix /usr/local --hostfile /usr/local/etc/openmpi-default-hostfile -np 4 pgm”在集群上执行的。这可能是什么原因?
    • 我编辑了我的答案,但有一个小问题(我忘了增加 dir)。无论如何,因为它在你的电脑上工作,我假设你纠正了它。关于基于powerpc的集群上的问题,我不知道。您可能应该在每个循环中添加 printf("[%d] %d\n", rank, dir) 以查看它挂起的位置,以及 Send 没有对应的 Recv。
    猜你喜欢
    • 2015-08-16
    • 2016-07-23
    • 1970-01-01
    • 2013-04-15
    • 2013-01-28
    • 2018-03-12
    • 1970-01-01
    • 2013-11-18
    • 2013-12-20
    相关资源
    最近更新 更多