我收到 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);
}
}
最佳答案
有两个可能的错误原因。
第一个是您有一个未完成的前一个 MPI_Bcast
,它在外循环之前的某处开始,但没有完成,例如以类似于 this question 中的方式.
第二个可能是缓冲区大小不匹配,因为 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
。
关于c++ - MPI_Bcast 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13668257/