Allow to change topology during the algorithme
This commit is contained in:
parent
48695863b2
commit
bae0e8da8b
2 changed files with 53 additions and 16 deletions
|
|
@ -27,49 +27,65 @@ ParadisEO WebSite : http://paradiseo.gforge.inria.fr
|
||||||
Contact: paradiseo-help@lists.gforge.inria.fr
|
Contact: paradiseo-help@lists.gforge.inria.fr
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
template<class EOT>
|
template<class EOT>
|
||||||
paradiseo::smp::IslandModel<EOT>::IslandModel(AbstractTopology& _topo) :
|
paradiseo::smp::IslandModel<EOT>::IslandModel(AbstractTopology& _topo) :
|
||||||
topo(_topo)
|
topo(_topo),
|
||||||
|
running(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template<class EOT>
|
template<class EOT>
|
||||||
void paradiseo::smp::IslandModel<EOT>::add(AIsland<EOT>& _island)
|
void paradiseo::smp::IslandModel<EOT>::add(AIsland<EOT>& _island)
|
||||||
{
|
{
|
||||||
islands.push_back(&_island);
|
islands.push_back(std::pair<AIsland<EOT>*, bool>(&_island, false));
|
||||||
islands.back()->setModel(this);
|
islands.back().first->setModel(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class EOT>
|
template<class EOT>
|
||||||
void paradiseo::smp::IslandModel<EOT>::operator()()
|
void paradiseo::smp::IslandModel<EOT>::operator()()
|
||||||
{
|
{
|
||||||
|
running = true;
|
||||||
|
|
||||||
std::vector<std::thread> threads(islands.size());
|
std::vector<std::thread> threads(islands.size());
|
||||||
|
|
||||||
|
// Preparing islands
|
||||||
|
for(auto it : islands)
|
||||||
|
it.second = true;
|
||||||
|
|
||||||
// Construct topology according to the number of islands
|
// Construct topology according to the number of islands
|
||||||
topo.construct(islands.size());
|
topo.construct(islands.size());
|
||||||
|
|
||||||
// Create table
|
// Create table
|
||||||
table = createTable(topo, islands);
|
table = createTable();
|
||||||
|
|
||||||
// Launching threads
|
// Launching threads
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
for(auto it : islands)
|
for(auto it : islands)
|
||||||
{
|
{
|
||||||
threads[i] = std::thread(&AIsland<EOT>::operator(), it);
|
threads[i] = std::thread(&AIsland<EOT>::operator(), it.first);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned workingThread = islands.size();
|
//
|
||||||
while(workingThread > 0)
|
std::function<int()> workingIslands = [this]() -> int
|
||||||
|
{
|
||||||
|
return (int)std::count_if(std::begin(islands), std::end(islands),
|
||||||
|
[](std::pair<AIsland<EOT>*, bool>& i) -> bool
|
||||||
|
{ return i.second; } );
|
||||||
|
};
|
||||||
|
|
||||||
|
while(workingIslands() > 0)
|
||||||
{
|
{
|
||||||
// Count working islands
|
// Count working islands
|
||||||
workingThread = islands.size();
|
|
||||||
for(auto& it : islands)
|
for(auto& it : islands)
|
||||||
{
|
{
|
||||||
// If an island is stopped we need to isolate its node in the topology
|
// If an island is stopped we need to isolate its node in the topology
|
||||||
if(it->isStopped())
|
if(it.second && it.first->isStopped())
|
||||||
{
|
{
|
||||||
workingThread--;
|
it.second = false;
|
||||||
topo.isolateNode(table.getLeft()[it]);
|
topo.isolateNode(table.getLeft()[it.first]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check sending
|
// Check sending
|
||||||
|
|
@ -82,7 +98,9 @@ void paradiseo::smp::IslandModel<EOT>::operator()()
|
||||||
thread.join();
|
thread.join();
|
||||||
|
|
||||||
for(auto& message : sentMessages)
|
for(auto& message : sentMessages)
|
||||||
message.join();
|
message.join();
|
||||||
|
|
||||||
|
running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class EOT>
|
template<class EOT>
|
||||||
|
|
@ -95,7 +113,18 @@ void paradiseo::smp::IslandModel<EOT>::update(eoPop<EOT> _data, AIsland<EOT>* _i
|
||||||
template<class EOT>
|
template<class EOT>
|
||||||
void paradiseo::smp::IslandModel<EOT>::setTopology(AbstractTopology& _topo)
|
void paradiseo::smp::IslandModel<EOT>::setTopology(AbstractTopology& _topo)
|
||||||
{
|
{
|
||||||
|
// If we change topo, we need to protect it
|
||||||
|
std::lock_guard<std::mutex> lock(m);
|
||||||
topo = _topo;
|
topo = _topo;
|
||||||
|
// If we change when the algorithm is running, we need to recontruct the topo
|
||||||
|
if(running)
|
||||||
|
{
|
||||||
|
topo.construct(islands.size());
|
||||||
|
// If we change the topology during the algorithm, we need to isolate stopped islands
|
||||||
|
for(auto it : islands)
|
||||||
|
if(!it.second)
|
||||||
|
topo.isolateNode(table.getLeft()[it.first]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class EOT>
|
template<class EOT>
|
||||||
|
|
@ -118,16 +147,21 @@ void paradiseo::smp::IslandModel<EOT>::send(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class EOT>
|
template<class EOT>
|
||||||
Bimap<unsigned, AIsland<EOT>*> paradiseo::smp::IslandModel<EOT>::createTable(AbstractTopology& _topo, std::vector<AIsland<EOT>*>& _islands)
|
Bimap<unsigned, AIsland<EOT>*> paradiseo::smp::IslandModel<EOT>::createTable()
|
||||||
{
|
{
|
||||||
Bimap<unsigned, AIsland<EOT>*> table;
|
Bimap<unsigned, AIsland<EOT>*> table;
|
||||||
unsigned islandId = 0;
|
unsigned islandId = 0;
|
||||||
for(auto it : islands)
|
for(auto it : islands)
|
||||||
{
|
{
|
||||||
table.add(islandId, it);
|
table.add(islandId, it.first);
|
||||||
islandId++;
|
islandId++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class EOT>
|
||||||
|
bool paradiseo::smp::IslandModel<EOT>::isRunning() const
|
||||||
|
{
|
||||||
|
return (bool)running;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,8 @@ public:
|
||||||
*/
|
*/
|
||||||
void setTopology(AbstractTopology& _topo);
|
void setTopology(AbstractTopology& _topo);
|
||||||
|
|
||||||
|
bool isRunning() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -87,14 +89,15 @@ protected:
|
||||||
*/
|
*/
|
||||||
void send(void);
|
void send(void);
|
||||||
|
|
||||||
Bimap<unsigned, AIsland<EOT>*> createTable(AbstractTopology& _topo, std::vector<AIsland<EOT>*>& _islands);
|
Bimap<unsigned, AIsland<EOT>*> createTable();
|
||||||
|
|
||||||
std::queue<std::pair<eoPop<EOT>,AIsland<EOT>*>> listEmigrants;
|
std::queue<std::pair<eoPop<EOT>,AIsland<EOT>*>> listEmigrants;
|
||||||
Bimap<unsigned, AIsland<EOT>*> table;
|
Bimap<unsigned, AIsland<EOT>*> table;
|
||||||
std::vector<AIsland<EOT>*> islands;
|
std::vector<std::pair<AIsland<EOT>*, bool>> islands;
|
||||||
AbstractTopology& topo;
|
AbstractTopology& topo;
|
||||||
std::vector<std::thread> sentMessages;
|
std::vector<std::thread> sentMessages;
|
||||||
std::mutex m;
|
std::mutex m;
|
||||||
|
std::atomic<bool> running;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include <islandModel.cpp>
|
#include <islandModel.cpp>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue