0

我正在尝试将 C++ 中的生物模型与boost::mpi. 这是我的第一次尝试,我对 boost 库完全陌生(我从 Schaling 的 Boost C++ Libraries 一书开始)。该模型由网格单元和居住在每个网格单元内的个人群组组成。这些类是嵌套的,这样一个向量Cohorts*属于一个GridCell。该模型运行了 1000 年,并且在每个时间步长上,存在分散,使得个体群体在网格单元之间随机移动。我想并行化 for 循环的内容,而不是循环本身,因为每个时间步都取决于前一次的状态。

我使用world.send()andworld.recv()将必要的信息从一个级别发送到另一个级别。因为有时在我使用的等级之间没有任何东西可以发送,mpi::statusworld.iprobe()确保代码不会挂起等待从未发送过的消息(我按照本教程进行操作)

我的代码的第一部分似乎工作正常,但在继续执行 for 循环的下一步之前,我无法确保已收到所有发送的消息。事实上,我注意到一些队伍在其他队伍有时间发送他们的消息之前移动到下一个时间步长(或者至少从输出中看起来像这样)

我没有发布代码,因为它由几个类组成,而且很长。如果有兴趣,代码在github 上。我这里大致写了伪代码。我希望这足以理解这个问题。

int main()
{
    // initialise the GridCells and Cohorts living in them

    //depending on the number of cores requested split the 
    //grid cells that are processed by each core evenly, and 
    //store the relevant grid cells in a vector of  GridCell*

    // start to loop through each time step
    for (int k = 0; k < (burnIn+simTime); k++) 
    {
        // calculate the survival and reproduction probabilities 
        // for each Cohort and the dispersal probability

        // the dispersing Cohorts are sorted based on the rank of
        // the destination and stored in multiple vector<Cohort*>

        // I send the vector<Cohort*> with 
        world.send(…)

        // the receiving rank gets the vector of Cohorts with: 
        mpi::status statuses[world.size()];
        for(int st = 0; st < world.size(); st++)
        {
            ....
            if( world.iprobe(st, tagrec) )    
            statuses[st] = world.recv(st, tagrec, toreceive[st]);
            //world.iprobe ensures that the code doesn't hang when there
            // are no dispersers
        }
        // do some extra calculations here

        //wait that all processes are received, and then the time step ends. 
        //This is the bit where I am stuck. 
        //I've seen examples with wait_all for the non-blocking isend/irecv,
        // but I don't think it is applicable in my case.
        //The problem is that I noticed that some ranks proceed to the next
        //time step before all the other ranks have sent their messages.
    }
}

我编译

mpic++ -I/$HOME/boost_1_61_0/boost/mpi -std=c++11  -Llibdir \-lboost_mpi -lboost_serialization -lboost_locale  -o out

并使用 执行mpirun -np 5 out,但我希望稍后能够在 HPC 集群上使用更多内核执行(该模型将在全球范围内运行,单元的数量可能取决于选择的网格单元大小用户)。安装的编译器是 g++ (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0, Open MPI: 2.1.1

4

1 回答 1

1

在您的场景中,您没有要发送的内容是一条重要信息。您不能仅从没有消息中推断出该事实。没有消息仅意味着尚未发送任何消息。

简单地发送一个大小为零的向量并跳过探测是最简单的方法。

否则,您可能不得不彻底改变您的方法或实施非常复杂的推测执行/回滚机制。

另请注意,链接教程以非常不同的方式使用探针。

于 2018-10-10T08:11:21.677 回答