gpt4 book ai didi

c - 当 mpi 发送和接收置于循环中时,Mpirun 挂起

转载 作者:行者123 更新时间:2023-11-30 17:39:24 25 4
gpt4 key购买 nike

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

最佳答案

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发送一个magic packet来结束worker。

在节点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

顺便说一句,您可能想看看阻塞和不阻塞发送/接收。

关于c - 当 mpi 发送和接收置于循环中时,Mpirun 挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21822420/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com