Работа со сложным посылкой recv-сообщения в цикле for

Я пытаюсь распараллелить биологическую модель в 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

0

Решение

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

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

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

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

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]