c++ - MPI_Bcast 错误

标签 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);
    }   
}

最佳答案

有两个可能的错误原因。

第一个是您有一个未完成的前一个 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/

相关文章:

c++ - OpenGL 模板测试未按预期工作

linux - 用于小规模研究的免费 Linux 集群构建

mpi - MPICH/OpenMPI 中的容错

c++ - std::vector 的 MPI_Gatherv 问题

c++ - 用于确定素数的 CUDA 内核比 OpenMP 代码慢 - 我该如何优化它?

c++ - 函数括号后的 -> 符号表示什么?

c# - 调试从C++调用的C#dll(已嵌入Mono)

c++ - 获取 int 中的位数

c++ - Eigen 与 OpenMP : No parallelisation due to false sharing and thread overhead

multithreading - 在 OpenMP 'for' 中使用 rand_r 使用 2 个线程时速度较慢