]> SALOME platform Git repositories - modules/yacs.git/commitdiff
Salome HOME
SALOMEHPContainer getNumberOfFreePlace and allocateFor
authorAnthony Geay <anthony.geay@edf.fr>
Mon, 30 Mar 2020 13:32:59 +0000 (15:32 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Mon, 30 Mar 2020 13:32:59 +0000 (15:32 +0200)
src/engine/HomogeneousPoolContainer.cxx
src/engine/HomogeneousPoolContainer.hxx
src/engine/PlayGround.cxx
src/engine/PlayGround.hxx
src/runtime/SalomeHPContainer.cxx
src/runtime/SalomeHPContainer.hxx
src/runtime/SalomeHPContainerTools.cxx
src/runtime/SalomeHPContainerTools.hxx

index 089990e0103e039783e9ba3f142069fc844e71ab..c21022fb8102083dbfd90a9399c7e10fa022569e 100644 (file)
@@ -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;
+}
index 778316bb66ba061704f6e38bb760fad74060ef2f..eded783f48bd4c4457c1b6d0e5df39d42856523c 100644 (file)
@@ -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<PlayGround> _pg;
     };
index a962358f944b1625c4c8db3095c8aaae56aa16bc..4836417efc06164ace4a52c99746a6ea772df452 100644 (file)
 
 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<std::size_t> Resource::allocateFor(std::size_t& nbOfPlacesToTake, int nbCoresPerCont) const
+{
+  std::vector<std::size_t> 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<int> PlayGround::GetIdsMatching(const std::vector<bool>& 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<std::size_t> PlayGround::allocateFor(std::size_t nbOfPlacesToTake, int nbCoresPerCont) const
+{
+  std::vector<std::size_t> ret;
+  std::size_t nbOfPlacesToTakeCpy(nbOfPlacesToTake),offset(0);
+  for(auto res : _data)
+    {
+      std::vector<std::size_t> 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<std::size_t>(res.nbCores()/nbCoresPerCont);
+    }
+  if( ( nbOfPlacesToTakeCpy!=0 ) || ( ret.size()!=nbOfPlacesToTake ) )
+    throw Exception("PlayGround::allocateFor : internal error ! Promised place is not existing !");
+  return ret;
+}
+
 std::vector<int> PlayGround::BuildVectOfIdsFromVecBool(const std::vector<bool>& v)
 {
   std::size_t sz(std::count(v.begin(),v.end(),true)),i(0);
index 07e9f081307b3de4dc6eebf60b595eaa2c2b0d63..ed3719b9a44a2ce0dfebc217b3df2bc78bfe61d6 100644 (file)
@@ -43,10 +43,12 @@ namespace YACS
       std::pair<std::string,int> 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<std::size_t> allocateFor(std::size_t& nbOfPlacesToTake, int nbCoresPerCont) const;
     private:
       std::string _name;
       int _nbCores;
-      std::vector<bool> _occupied;
+      mutable std::vector<bool> _occupied;
     };
     
     
@@ -88,6 +90,9 @@ namespace YACS
       std::vector<std::size_t> getWorkerIdsFullyFetchedBy(int nbCoresPerComp, const std::vector<bool>& coreFlags) const;
       static std::vector<int> BuildVectOfIdsFromVecBool(const std::vector<bool>& v);
       static std::vector<int> GetIdsMatching(const std::vector<bool>& bigArr, const std::vector<bool>& pat);
+    public:// critical section part
+      std::size_t getNumberOfFreePlace(int nbCoresPerCont) const;
+      std::vector<std::size_t> allocateFor(std::size_t nbOfPlacesToTake, int nbCoresPerCont) const;
     private:
       std::vector< std::pair <const ComplexWeight *, int> > bigToTiny(const std::vector< std::pair <const ComplexWeight *, int> > &weights, std::map<int,int> &saveOrder) const;
          std::vector< std::vector<int> > backToOriginalOrder(const std::vector< std::vector<int> > &disorderVec, const std::map<int,int> &saveOrder) const;
index 990ad25e340f93a767191d935501159b2b5f6d4f..2cba679bd05dfd6a570e8699b4bc8d108eb6c0c5 100644 (file)
@@ -23,6 +23,7 @@
 #include "AutoLocker.hxx"
 
 #include <algorithm>
+#include <utility>
 
 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<const Task *,std::size_t>,                    // value_type
+                        long,                        // difference_type
+                        const std::pair<const Task *,std::size_t>*,             // pointer
+                        std::pair<const Task *,std::size_t> > // reference
+{
+  const std::vector< const Task *> *_v0;
+  const std::vector<std::size_t> *_v1;
+  std::size_t _num;
+public:
+  explicit PairVecIterator(const std::vector< const Task * > *v0, const std::vector<std::size_t> *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<const Task *,std::size_t>((*_v0)[_num],(*_v1)[_num]); }
+};
+
 void SalomeHPContainer::allocateFor(const std::vector<const Task *>& nodes)
 {
-  _launchModeType.allocateFor(nodes);
+  std::vector<std::size_t> workerIdsAllocated(getPG()->allocateFor(nodes.size(),this->getNumberOfCoresPerWorker()));
+  std::vector<std::pair<const Task *,std::size_t>> nodesAndIds(PairVecIterator(&nodes,&workerIdsAllocated,0),PairVecIterator(&nodes,&workerIdsAllocated,nodes.size()));
+  _launchModeType.allocateForCrude(nodesAndIds);
 }
 
 void SalomeHPContainer::release(const Task *node)
index 63e5a783b4f36d7cfd590d06ff0fc01403d42e45..e6e4f3c8fb87ab6f2b5e2c8d75d90b9982b42a09 100644 (file)
@@ -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;
index bd73a472663f79fda116fbe3f65c7912a602f1c1..5b450396014535313281e1237251ab48a0eb68eb 100644 (file)
@@ -60,6 +60,25 @@ void SalomeHPContainerVectOfHelper::allocateFor(const std::vector<const Task *>&
     }
 }
 
+void SalomeHPContainerVectOfHelper::allocateForCrude(const std::vector<std::pair<const Task *,std::size_t>>& 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)
index bbc103ba736271c60b64ff3b414d23552817f2c9..66ac984bcd63dcc07018b4bdfe72880180214044 100644 (file)
@@ -42,6 +42,7 @@ namespace YACS
       void resize(std::size_t sz);
       std::size_t getNumberOfFreePlace() const;
       void allocateFor(const std::vector<const Task *>& nodes);
+      void allocateForCrude(const std::vector<std::pair<const Task *,std::size_t>>& 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]; }