MPI_Bcast出错

时间:2012-12-02 10:04:59

标签: c++ mpi openmp

我收到MPI_Bcast的错误(我认为这是一个旧错误)我不知道为什么会这样。错误如下:

An error occurred in MPI_Bcast    
on communicator MPI_COMM_WORLD  
MPI_ERR_TRUNCATE: message truncated      
MPI_ERRORS_ARE_FATAL: your MPI job will now abort

发生的代码是:

for (int i = 0; i < nbProcs; i++){
    for (int j = firstLocalGrainRegion; j < lastLocalGrainRegion; j++){
        GrainRegion * grainRegion = microstructure->getGrainRegionAt(j);
        int grainSize = grainRegion->getBoxSize(nb);
        double * newValues;
        if (myId == i)
            newValues = grainRegion->getNewValues();
        else
            newValues = new double[grainSize]; 
        MPI_Bcast(newValues, grainSize, MPI_DOUBLE, i, MPI_COMM_WORLD);
        MPI_Barrier(MPI_COMM_WORLD);

        if (myId != i)
            grainRegion->setNewValues(newValues);
    }   
}

1 个答案:

答案 0 :(得分:2)

错误有两个可能的原因。

第一个是你有一个待处理的先前MPI_Bcast,在外环之前的某个地方开始,但没有完成,例如以类似this question中的方式。

第二个是可能的缓冲区大小不匹配,因为grainRegion->getBoxSize(nb)在不同的进程中返回不同的值。您可以使用并行调试器检查代码,或者只在广播之前放置一个print语句,例如:

int grainSize = grainRegion->getBoxSize(nb);
printf("i=%d j=%d rank=%02d grainSize=%d\n", i, j, myId, grainSize);

使用此特定输出格式,您应该能够通过sort简单地运行输出,然后快速找到不匹配的值。由于障碍总是同步(广播可能不一定如此),因此MPI_Bcast的不同呼叫几乎不可能像第一种情况那样相互干扰。

如果发生这种情况,以便分发您的数据结构,并且确实grainSize的正确值仅在广播根进程中可用,那么您应该首先通知其他正确大小的行。最简单(但不是最有效)的解决方案是广播grainSize。一个更好的解决方案是首先在每个进程中执行一个MPI_Allgather包含粒度区域的数量(仅在必要时),然后执行具有每个区域大小的MPI_Allgatherv