MPI_Bcast hanging
MPI_Bcast hanging
我按照这里的示例添加了一些代码进行测试,但在添加新代码时出现了一些奇怪的结果。结果如下所示。它在这里挂断了,无法继续。
[0]: Before Bcast, buf is 777
[1]: Before Bcast, buf is 32767
[0]: After Bcast, buf is 777
从两个角度来看,这很奇怪:
代码为
if(rank==i) if(i==0)
时不会挂断乳清CCD_ 2在bcast前不为0。
这是代码:
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char** argv) {
int rank;
int buf;
const int root=0;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if(rank == root) {
buf = 777;
}
printf("[%d]: Before Bcast, buf is %dn", rank, buf);
// newly added
for(int i=0; i<2; i++)
{
if(rank==i)
{
if(i==1)
MPI_Bcast(&buf, 1, MPI_INT, rank, MPI_COMM_WORLD);
}
}
// end newly added
/* everyone calls bcast, data is taken from root and ends up in everyone's buf */
MPI_Bcast(&buf, 1, MPI_INT, root, MPI_COMM_WORLD);
printf("[%d]: After Bcast, buf is %dn", rank, buf);
MPI_Finalize();
return 0;
}
我真正想做的是实现以下功能:每个处理器运行部分处理,然后在获得结果后广播,其他处理器通过组合接收结果来更新自己的结果。
以下是代码的主要部分(原始代码来自libsvm)
struct decision_function
{
double *alpha;
double rho;
};
int gate_no = 2;
int p = 0;
int nr_class = 8;
for(int i=0;i<nr_class;i++)
{
for(int j=i+1;j<nr_class;j++)
{
if(((world_rank==i-2*gate_no*(i/(2*gate_no))) && (i%(2*gate_no) < gate_no))||((world_rank==2*gate_no*(i/(2*gate_no)+1)-i-1)&&(i%(2*gate_no) >= gate_no)))
{
// some process for generating f[p] here
....
MPI_Bcast(f[p].alpha, count[i]+count[j], MPI_DOUBLE, world_rank, MPI_COMM_WORLD);
}
++p;
}
}
但是这个代码不起作用,我也有一些错误。
Fatal error in PMPI_Bcast: Other MPI error, error stack:
PMPI_Bcast(1478)......................: MPI_Bcast(buf=0xcc7b40, count=2340, MPI_DOUBLE, root=1, MPI_COMM_WORLD) failed
MPIR_Bcast_impl(1321).................:
MPIR_Bcast_intra(1119)................:
MPIR_Bcast_scatter_ring_allgather(962):
MPIR_Bcast_binomial(154)..............: message sizes do not match across processes in the collective
此块
if(rank==i)
{
if(i==1)
MPI_Bcast(&buf, 1, MPI_INT, rank, MPI_COMM_WORLD);
}
意味着只有进程1对CCD_ 3进行调用。由于这是一个集体操作,通讯器中的所有进程都应该调用它(同时)。在这种情况下,进程1正在等待所有其他进程,如果我理解正确的话,这些进程将继续,直到它们到达对MPI_Bcast
的下一个调用,在那里它们等待进程1。等等。等等。
我不确定你到底想做什么,所以不能就如何解决这个问题提供任何建设性的建议。