C语言 当 mpi 发送和接收置于循环中时,Mpirun 挂起



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

节点

0 将数据分发到节点 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 %dusn",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;
    }

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 发送一个魔术数据包来结束工作线程。

在节点 0 的末尾:

for(r = 1; r < numprocs; r++)
    MPI_Send(&dummy, 1, MPI_INT, r, STOP, COMM);

对于沃克节点:

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

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

最新更新