Работа со сложным посылкой recv-сообщения в цикле for - PullRequest
0 голосов
/ 10 октября 2018

Я пытаюсь распараллелить биологическую модель в C ++ с boost::mpi.Это моя первая попытка, и я совершенно не знаком с библиотекой Boost (я начал с книги Boost C ++ Libraries от Schaling).Модель состоит из ячеек сетки и когорт индивидуумов, живущих в каждой ячейке сетки.Классы являются вложенными, так что вектор Cohorts* принадлежит GridCell.Модель работает в течение 1000 лет, и на каждом временном шаге наблюдается такой разброс, что когорты индивидуумов случайно перемещаются между ячейками сетки.Я хочу распараллелить содержимое цикла for, но не сам цикл, поскольку каждый временной шаг зависит от состояния предыдущего времени.

Я использую world.send() и world.recv() для отправки необходимой информации изодно звание к другому.Потому что иногда нечего отправлять между рангами, которые я использую с mpi::status и world.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

1 Ответ

0 голосов
/ 10 октября 2018

Тот факт, что вам нечего отправить, является важной частью вашего сценария.Вы не можете вывести этот факт только из отсутствия сообщения.Отсутствие сообщения означает только ничего не было отправлено пока .

Просто отправка вектора нулевого размера и пропуск поиска - самый простой выход.

В противном случае вам, вероятно, придется радикально изменить свой подход или реализовать очень сложный спекулятивный механизм выполнения / отката.

Также обратите внимание, что в связанном учебном пособии зонд используется совершенно по-другому.

...