我收到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);
}
}
答案 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
。