1

我收到 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);
    }   
}
4

1 回答 1

2

错误有两个可能的原因。

第一个是你有一个未决的 previous MPI_Bcast,在外循环之前的某个地方开始,它没有完成,例如以类似于这个问题中的方式。

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

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使用每个区域的大小执行。

于 2012-12-02T15:36:48.787 回答