From 7df2ab0dc3a16df8c93719643ff42d9d3263d079 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Mon, 30 Mar 2020 15:32:59 +0200 Subject: [PATCH] SALOMEHPContainer getNumberOfFreePlace and allocateFor --- src/engine/HomogeneousPoolContainer.cxx | 7 +++ src/engine/HomogeneousPoolContainer.hxx | 4 +- src/engine/PlayGround.cxx | 64 +++++++++++++++++++++++++ src/engine/PlayGround.hxx | 7 ++- src/runtime/SalomeHPContainer.cxx | 32 ++++++++++++- src/runtime/SalomeHPContainer.hxx | 1 + src/runtime/SalomeHPContainerTools.cxx | 19 ++++++++ src/runtime/SalomeHPContainerTools.hxx | 1 + 8 files changed, 131 insertions(+), 4 deletions(-) diff --git a/src/engine/HomogeneousPoolContainer.cxx b/src/engine/HomogeneousPoolContainer.cxx index 089990e01..c21022fb8 100644 --- a/src/engine/HomogeneousPoolContainer.cxx +++ b/src/engine/HomogeneousPoolContainer.cxx @@ -67,3 +67,10 @@ HomogeneousPoolContainer::HomogeneousPoolContainer() HomogeneousPoolContainer::~HomogeneousPoolContainer() { } + +const PlayGround *HomogeneousPoolContainer::getPG() const +{ + if(_pg.isNull()) + throw Exception("HomogeneousPoolContainer::getPG : PlayGround is nullptr !"); + return _pg; +} diff --git a/src/engine/HomogeneousPoolContainer.hxx b/src/engine/HomogeneousPoolContainer.hxx index 778316bb6..eded783f4 100644 --- a/src/engine/HomogeneousPoolContainer.hxx +++ b/src/engine/HomogeneousPoolContainer.hxx @@ -43,7 +43,7 @@ namespace YACS void dettachOnCloning() const; bool isAttachedOnCloning() const; void setAttachOnCloningStatus(bool val) const; - void assignPG(const PlayGround *pg); + virtual void assignPG(const PlayGround *pg); // virtual void setSizeOfPool(int sz) = 0; virtual int getSizeOfPool() const = 0; @@ -58,6 +58,8 @@ namespace YACS #ifndef SWIG virtual ~HomogeneousPoolContainer(); #endif + protected: + const PlayGround *getPG() const; private: YACS::BASES::AutoConstRefCnt _pg; }; diff --git a/src/engine/PlayGround.cxx b/src/engine/PlayGround.cxx index a962358f9..4836417ef 100644 --- a/src/engine/PlayGround.cxx +++ b/src/engine/PlayGround.cxx @@ -29,6 +29,44 @@ using namespace YACS::ENGINE; +std::size_t Resource::getNumberOfFreePlace(int nbCoresPerCont) const +{ + std::size_t ret(0),pos(0); + while( pos < _occupied.size() ) + { + bool isChunckFree(true); + int posInChunck(0); + for( ; ( posInChunck < nbCoresPerCont ) && ( pos < _occupied.size() ) ; ++posInChunck, ++pos) + if(_occupied[pos]) + isChunckFree = false; + if( isChunckFree && (posInChunck == nbCoresPerCont) ) + ret++; + } + return ret; +} + +std::vector Resource::allocateFor(std::size_t& nbOfPlacesToTake, int nbCoresPerCont) const +{ + std::vector ret; + std::size_t pos(0),curWorkerId(0); + while( ( pos < _occupied.size() ) && ( nbOfPlacesToTake > 0 ) ) + { + bool isChunckFree(true); + int posInChunck(0); + for( ; ( posInChunck < nbCoresPerCont ) && ( pos < _occupied.size() ) ; ++posInChunck, ++pos) + if(_occupied[pos]) + isChunckFree = false; + if( isChunckFree && (posInChunck == nbCoresPerCont) ) + { + for(int i = 0 ; i < nbCoresPerCont ; ++i) + _occupied[pos-nbCoresPerCont+i] = true; + ret.push_back(curWorkerId); + --nbOfPlacesToTake; + } + ++curWorkerId; + } + return ret; +} std::string PlayGround::printSelf() const { @@ -112,6 +150,32 @@ std::vector PlayGround::GetIdsMatching(const std::vector& bigArr, con return ret; } +std::size_t PlayGround::getNumberOfFreePlace(int nbCoresPerCont) const +{ + std::size_t ret(0); + for(auto res : _data) + { + ret += res.getNumberOfFreePlace(nbCoresPerCont); + } + return ret; +} + +std::vector PlayGround::allocateFor(std::size_t nbOfPlacesToTake, int nbCoresPerCont) const +{ + std::vector ret; + std::size_t nbOfPlacesToTakeCpy(nbOfPlacesToTake),offset(0); + for(auto res : _data) + { + std::vector contIdsInRes(res.allocateFor(nbOfPlacesToTakeCpy,nbCoresPerCont)); + std::for_each(contIdsInRes.begin(),contIdsInRes.end(),[offset](std::size_t& val) { val += offset; }); + ret.insert(ret.end(),contIdsInRes.begin(),contIdsInRes.end()); + offset += static_cast(res.nbCores()/nbCoresPerCont); + } + if( ( nbOfPlacesToTakeCpy!=0 ) || ( ret.size()!=nbOfPlacesToTake ) ) + throw Exception("PlayGround::allocateFor : internal error ! Promised place is not existing !"); + return ret; +} + std::vector PlayGround::BuildVectOfIdsFromVecBool(const std::vector& v) { std::size_t sz(std::count(v.begin(),v.end(),true)),i(0); diff --git a/src/engine/PlayGround.hxx b/src/engine/PlayGround.hxx index 07e9f0813..ed3719b9a 100644 --- a/src/engine/PlayGround.hxx +++ b/src/engine/PlayGround.hxx @@ -43,10 +43,12 @@ namespace YACS std::pair toPair() const { return {_name,_nbCores}; } int nbCores() const { return _nbCores; } std::string name() const { return _name; } + std::size_t getNumberOfFreePlace(int nbCoresPerCont) const; + std::vector allocateFor(std::size_t& nbOfPlacesToTake, int nbCoresPerCont) const; private: std::string _name; int _nbCores; - std::vector _occupied; + mutable std::vector _occupied; }; @@ -88,6 +90,9 @@ namespace YACS std::vector getWorkerIdsFullyFetchedBy(int nbCoresPerComp, const std::vector& coreFlags) const; static std::vector BuildVectOfIdsFromVecBool(const std::vector& v); static std::vector GetIdsMatching(const std::vector& bigArr, const std::vector& pat); + public:// critical section part + std::size_t getNumberOfFreePlace(int nbCoresPerCont) const; + std::vector allocateFor(std::size_t nbOfPlacesToTake, int nbCoresPerCont) const; private: std::vector< std::pair > bigToTiny(const std::vector< std::pair > &weights, std::map &saveOrder) const; std::vector< std::vector > backToOriginalOrder(const std::vector< std::vector > &disorderVec, const std::map &saveOrder) const; diff --git a/src/runtime/SalomeHPContainer.cxx b/src/runtime/SalomeHPContainer.cxx index 990ad25e3..2cba679bd 100644 --- a/src/runtime/SalomeHPContainer.cxx +++ b/src/runtime/SalomeHPContainer.cxx @@ -23,6 +23,7 @@ #include "AutoLocker.hxx" #include +#include using namespace YACS::ENGINE; @@ -36,6 +37,13 @@ SalomeHPContainer::SalomeHPContainer(const SalomeHPContainer& other):_componentN { } +void SalomeHPContainer::assignPG(const PlayGround *pg) +{ + HomogeneousPoolContainer::assignPG(pg); + int nbOfWorkers(getPG()->getNumberOfWorkers(this->getNumberOfCoresPerWorker())); + this->setSizeOfPool(nbOfWorkers); +} + void SalomeHPContainer::setSizeOfPool(int sz) { _launchModeType.resize(sz); @@ -48,12 +56,32 @@ int SalomeHPContainer::getSizeOfPool() const std::size_t SalomeHPContainer::getNumberOfFreePlace() const { - return _launchModeType.getNumberOfFreePlace(); + return getPG()->getNumberOfFreePlace(this->getNumberOfCoresPerWorker()); } +class PairVecIterator : public std::iterator< + std::input_iterator_tag, // iterator_category + std::pair, // value_type + long, // difference_type + const std::pair*, // pointer + std::pair > // reference +{ + const std::vector< const Task *> *_v0; + const std::vector *_v1; + std::size_t _num; +public: + explicit PairVecIterator(const std::vector< const Task * > *v0, const std::vector *v1, const std::size_t num) : _v0(v0),_v1(v1),_num(num) { } + PairVecIterator& operator++() { _num++; return *this; } + bool operator==(PairVecIterator other) const { return _num == other._num; } + bool operator!=(PairVecIterator other) const { return !(*this == other); } + reference operator*() const { return std::pair((*_v0)[_num],(*_v1)[_num]); } +}; + void SalomeHPContainer::allocateFor(const std::vector& nodes) { - _launchModeType.allocateFor(nodes); + std::vector workerIdsAllocated(getPG()->allocateFor(nodes.size(),this->getNumberOfCoresPerWorker())); + std::vector> nodesAndIds(PairVecIterator(&nodes,&workerIdsAllocated,0),PairVecIterator(&nodes,&workerIdsAllocated,nodes.size())); + _launchModeType.allocateForCrude(nodesAndIds); } void SalomeHPContainer::release(const Task *node) diff --git a/src/runtime/SalomeHPContainer.hxx b/src/runtime/SalomeHPContainer.hxx index 63e5a783b..e6e4f3c8f 100644 --- a/src/runtime/SalomeHPContainer.hxx +++ b/src/runtime/SalomeHPContainer.hxx @@ -46,6 +46,7 @@ namespace YACS SalomeHPContainer(); SalomeHPContainer(const SalomeHPContainer& other); //HP specific part + void assignPG(const PlayGround *pg) override; void setSizeOfPool(int sz); int getSizeOfPool() const; std::size_t getNumberOfFreePlace() const; diff --git a/src/runtime/SalomeHPContainerTools.cxx b/src/runtime/SalomeHPContainerTools.cxx index bd73a4726..5b4503960 100644 --- a/src/runtime/SalomeHPContainerTools.cxx +++ b/src/runtime/SalomeHPContainerTools.cxx @@ -60,6 +60,25 @@ void SalomeHPContainerVectOfHelper::allocateFor(const std::vector& } } +void SalomeHPContainerVectOfHelper::allocateForCrude(const std::vector>& nodes) +{ + for(auto it : nodes) + { + std::size_t workerId(it.second); + if(workerId>=size()) + throw Exception("SalomeHPContainerVectOfHelper::allocateForCrude : Internal error ! WorkerId is greater or equal to size of HPCont !"); + if(_whichOccupied[workerId]) + throw Exception("SalomeHPContainerVectOfHelper::allocateForCrude : Mismatch between Playground info and HPContainer info !"); + } + for(auto it : nodes) + { + const Task *task(it.first); + std::size_t workerId(it.second); + _currentlyWorking[task]=workerId; + _whichOccupied[workerId]=true; + } +} + void SalomeHPContainerVectOfHelper::release(const Task *node) { if(!node) diff --git a/src/runtime/SalomeHPContainerTools.hxx b/src/runtime/SalomeHPContainerTools.hxx index bbc103ba7..66ac984bc 100644 --- a/src/runtime/SalomeHPContainerTools.hxx +++ b/src/runtime/SalomeHPContainerTools.hxx @@ -42,6 +42,7 @@ namespace YACS void resize(std::size_t sz); std::size_t getNumberOfFreePlace() const; void allocateFor(const std::vector& nodes); + void allocateForCrude(const std::vector>& nodes); void release(const Task *node); std::size_t locateTask(const Task *node) const; const SalomeContainerMonoHelper *at(std::size_t pos) const { checkPosInVec(pos); return _launchModeType[pos]; } -- 2.39.2