Salome HOME
updated copyright message
[modules/yacs.git] / src / engine / PlayGround.cxx
index bc96d9b3d4df2d207695f6854a02a64cc0c6ceea..506e6603593e54961e4e1d5a5e0d1c21ab8c841d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2017  CEA/DEN, EDF R&D
+// Copyright (C) 2006-2023  CEA, EDF
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 #include <sstream>
 #include <iomanip>
 #include <numeric>
+#include <iostream>
 #include <algorithm>
 
 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;
+}
+
+void Resource::release(std::size_t workerId, int nbCoresPerCont) const
+{
+  if(workerId >= this->getNumberOfWorkers(nbCoresPerCont))
+    throw Exception("Resource::release : invalid worker id !");
+  std::size_t pos(workerId*static_cast<std::size_t>(nbCoresPerCont));
+  for(int i = 0 ; i < nbCoresPerCont ; ++i)
+    {
+      if(!_occupied[pos + static_cast<std::size_t>(i)])
+        throw Exception("Resource::release : internal error ! A core is expected to be occupied !");
+      _occupied[pos + static_cast<std::size_t>(i)] = false;
+    }
+}
+
+std::size_t Resource::getNumberOfWorkers(int nbCoresPerCont) const
+{
+  return static_cast<std::size_t>(this->nbCores())/static_cast<std::size_t>(nbCoresPerCont);
+}
+
+void Resource::printSelf(std::ostream& oss) const
+{
+  oss << this->name() << " (" << this->nbCores() << ") : ";
+  for(auto it : this->_occupied)
+    {
+      if(it)
+        oss << "1";
+      else
+        oss << "0";
+    }
+}
+
 std::string PlayGround::printSelf() const
 {
   std::ostringstream oss;
   std::size_t sz(0);
-  for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
-    sz=std::max(sz,(*it).first.length());
-  for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
+  for(auto it : _data)
+    sz=std::max(sz,it.name().length());
+  for(auto it : _data)
     {
-      oss << " - " << std::setw(10) << (*it).first << " : " << (*it).second << std::endl;
+      oss << " - " << std::setw(10) << it.name() << " : " << it.nbCores() << std::endl;
     }
   return oss.str();
 }
@@ -53,15 +123,15 @@ void PlayGround::loadFromKernelCatalog()
 
 void PlayGround::setData(const std::vector< std::pair<std::string,int> >& defOfRes)
 {
-  _data=defOfRes;
+  _data=std::vector<Resource>(defOfRes.begin(),defOfRes.end());
   checkCoherentInfo();
 }
 
 int PlayGround::getNumberOfCoresAvailable() const
 {
   int ret(0);
-  for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
-    ret+=(*it).second;
+  for(auto it : _data)
+    ret+=it.nbCores();
   return ret;
 }
 
@@ -70,8 +140,8 @@ int PlayGround::getMaxNumberOfContainersCanBeHostedWithoutOverlap(int nbCoresPer
   if(nbCoresPerCont<1)
     throw Exception("PlayGround::getMaxNumberOfContainersCanBeHostedWithoutOverlap : invalid nbCoresPerCont. Must be >=1 !");
   int ret(0);
-  for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
-    ret+=(*it).second/nbCoresPerCont;
+  for(auto it : _data)
+    ret+=it.nbCores()/nbCoresPerCont;
   return ret;
 }
 
@@ -79,62 +149,88 @@ std::vector<int> PlayGround::computeOffsets() const
 {
   std::size_t sz(_data.size()),i(0);
   std::vector<int> ret(sz+1); ret[0]=0;
-  for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++,i++)
-    ret[i+1]=ret[i]+(*it).second;
+  for(auto it=_data.begin();it!=_data.end();it++,i++)
+    ret[i+1]=ret[i]+it->nbCores();
   return ret;
 }
 
 void PlayGround::checkCoherentInfo() const
 {
   std::set<std::string> s;
-  for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
+  for(auto it : _data)
     {
-      s.insert((*it).first);
-      if((*it).second<0)
+      s.insert(it.name());
+      if(it.nbCores()<0)
         throw Exception("Presence of negative int value !");
     }
   if(s.size()!=_data.size())
     throw Exception("host names entries must be different each other !");
 }
 
-std::vector<bool> PlayGround::FromUItoVB(unsigned int sz, unsigned int v)
+std::vector<int> PlayGround::GetIdsMatching(const std::vector<bool>& bigArr, const std::vector<bool>& pat)
 {
-  std::vector<bool> ret(sz);
-  unsigned int p(1);
+  std::vector<int> ret;
+  std::size_t szp(pat.size());
+  std::size_t sz(bigArr.size()/szp);
   for(std::size_t i=0;i<sz;i++)
     {
-      ret[i]=p&v;
-      p<<=1;
+      std::vector<bool> t(bigArr.begin()+i*szp,bigArr.begin()+(i+1)*szp);
+      if(t==pat)
+        ret.push_back(i);
     }
   return ret;
 }
 
-unsigned int PlayGround::FromVBtoUI(const std::vector<bool>& v)
+std::size_t PlayGround::getNumberOfFreePlace(int nbCoresPerCont) const
 {
-  std::size_t sz(v.size());
-  unsigned int ret(0);
-  for(std::size_t i=0;i<sz;i++)
+  std::size_t ret(0);
+  for(auto res : _data)
     {
-      if(v[i])
-        ret+=1u<<i;
+      ret += res.getNumberOfFreePlace(nbCoresPerCont);
     }
   return ret;
 }
 
-std::vector<int> PlayGround::GetIdsMatching(const std::vector<bool>& bigArr, const std::vector<bool>& pat)
+std::vector<std::size_t> PlayGround::allocateFor(std::size_t nbOfPlacesToTake, int nbCoresPerCont) const
 {
-  std::vector<int> ret;
-  std::size_t szp(pat.size());
-  std::size_t sz(bigArr.size()/szp);
-  for(std::size_t i=0;i<sz;i++)
+  std::vector<std::size_t> ret;
+  std::size_t nbOfPlacesToTakeCpy(nbOfPlacesToTake),offset(0);
+  for(const auto& res : _data)
     {
-      std::vector<bool> t(bigArr.begin()+i*szp,bigArr.begin()+(i+1)*szp);
-      if(t==pat)
-        ret.push_back(i);
+      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;
 }
 
+void PlayGround::release(std::size_t workerId, int nbCoresPerCont) const
+{
+  std::size_t offset(0);
+  for(const auto& res : _data)
+    {
+      std::size_t nbOfWorker(static_cast<std::size_t>(res.nbCores()/nbCoresPerCont));
+      std::size_t minId(offset),maxId(offset+nbOfWorker);
+      if(workerId>=minId && workerId<maxId)
+        {
+          res.release(workerId-minId,nbCoresPerCont);
+          break;
+        }
+    }
+}
+
+void PlayGround::printMe() const
+{
+  for(auto it : _data)
+  {
+    it.printSelf(std::cout);
+    std::cout << std::endl;
+  }
+}
+
 std::vector<int> PlayGround::BuildVectOfIdsFromVecBool(const std::vector<bool>& v)
 {
   std::size_t sz(std::count(v.begin(),v.end(),true)),i(0);
@@ -160,24 +256,24 @@ void PlayGround::highlightOnIds(const std::vector<int>& coreIds, std::vector<boo
 /*! 
  * you must garantee coherence between PlayGround::deduceMachineFrom, PlayGround::getNumberOfWorkers, and PartDefinition::computeWorkerIdsCovered
  */
-std::vector<bool> PlayGround::getFetchedCores(int nbCoresPerWorker) const
-{
-  int nbCores(getNumberOfCoresAvailable());
-  std::vector<bool> ret(nbCores,false);
-  if(nbCoresPerWorker==1)
-    std::fill(ret.begin(),ret.end(),true);
-  else
-    {
-      std::size_t posBg(0);
-      for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
-        {
-          int nbElemsToPutOn(((*it).second/nbCoresPerWorker)*nbCoresPerWorker);
-          std::fill(ret.begin()+posBg,ret.begin()+posBg+nbElemsToPutOn,true);
-          posBg+=(*it).second;
-        }
-    }
-  return ret;
-}
+// std::vector<bool> PlayGround::getFetchedCores(int nbCoresPerWorker) const
+// {
+//   int nbCores(getNumberOfCoresAvailable());
+//   std::vector<bool> ret(nbCores,false);
+//   if(nbCoresPerWorker==1)
+//     std::fill(ret.begin(),ret.end(),true);
+//   else
+//     {
+//       std::size_t posBg(0);
+//       for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
+//         {
+//           int nbElemsToPutOn(((*it).second/nbCoresPerWorker)*nbCoresPerWorker);
+//           std::fill(ret.begin()+posBg,ret.begin()+posBg+nbElemsToPutOn,true);
+//           posBg+=(*it).second;
+//         }
+//     }
+//   return ret;
+//}
 /*!
  * follow getMaxNumberOfContainersCanBeHostedWithoutOverlap method
  */
@@ -185,23 +281,25 @@ std::vector<std::size_t> PlayGround::getWorkerIdsFullyFetchedBy(int nbCoresPerCo
 {
   std::size_t posBg(0),posWorker(0);
   std::vector<std::size_t> ret;
-  for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
+  for(auto it : _data)
     {
-      int nbWorker((*it).second/nbCoresPerComp);
+      int nbWorker(it.nbCores()/nbCoresPerComp);
       for(int j=0;j<nbWorker;j++,posWorker++)
         {
           std::vector<bool>::const_iterator it2(std::find(coreFlags.begin()+posBg+j*nbCoresPerComp,coreFlags.begin()+posBg+(j+1)*nbCoresPerComp,false));
           if(it2==coreFlags.begin()+posBg+(j+1)*nbCoresPerComp)
             ret.push_back(posWorker);
         }
-      posBg+=(*it).second;
+      posBg+=it.nbCores();
     }
   return ret;
 }
 
-std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > PlayGround::partition(const std::vector< std::pair<const PartDefinition *,double> >& parts) const
+std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > PlayGround::partition(const std::vector< std::pair<const PartDefinition *, const ComplexWeight *> >& parts, const std::vector< int>& nbCoresPerShot) const
 {
   std::size_t sz(parts.size()),szs(getNumberOfCoresAvailable());
+  if (sz!=nbCoresPerShot.size())
+    throw Exception("PlayGround::partition : incoherent vector size !");
   if(sz==0)
     return std::vector< YACS::BASES::AutoRefCnt<PartDefinition> >();
   if(sz==1)
@@ -217,41 +315,31 @@ std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > PlayGround::partition(con
     throw Exception("PlayGround::partition : not implemented yet for more than 31 ! You need to pay for it :)");
   std::vector<bool> zeArr(szs*sz,false);
   std::size_t i(0);
-  for(std::vector< std::pair<const PartDefinition *,double> >::const_iterator it=parts.begin();it!=parts.end();it++,i++)
+  for(std::vector< std::pair<const PartDefinition *, const ComplexWeight *> >::const_iterator it=parts.begin();it!=parts.end();it++,i++)
     {
       const PartDefinition *pd((*it).first);
       if(!pd)
         throw Exception("Presence of null pointer as part def !");
       if(pd->getPlayGround()!=this)
         throw Exception("Presence of non homogeneous playground !");
-      if((*it).second<=0.)
-        throw Exception("Invalid weight !");
-      std::vector<bool> bs(pd->getCoresOn());
+      std::vector<bool> bs(pd->getCoresOn()); // tab of length nbCores, with True or False for each Core
       for(std::size_t j=0;j<szs;j++)
-        zeArr[j*sz+i]=bs[j];
-    }
-  std::set<unsigned int> ss;
-  for(std::size_t i=0;i<szs;i++)
-    {
-      std::vector<bool> vb(zeArr.begin()+i*sz,zeArr.begin()+(i+1)*sz);
-      ss.insert(FromVBtoUI(vb));
+        zeArr[j*sz+i]=bs[j]; // remplis une table avec les valeurs de bs. La table est [nb part] * [nb cores]
     }
   std::vector< std::vector<int> > retIds(sz);
-  for(std::set<unsigned int>::const_iterator i=ss.begin();i!=ss.end();i++)
+  for(std::size_t i=0;i<szs;i++)
     {
-      std::vector<bool> code(FromUItoVB(sz,*i));// for this configuration which parts are considered
-      std::vector<int> locIds(GetIdsMatching(zeArr,code));
-      std::vector<int> partsIds(BuildVectOfIdsFromVecBool(code));
+      std::vector<bool> code(zeArr.begin()+i*sz,zeArr.begin()+(i+1)*sz);// vecteur contenant le true/false d'un coeur pour ttes les partitions
+      std::vector<int> locIds(GetIdsMatching(zeArr,code)); // liste des coeurs qui peuvent correspondre au pattern code
+      std::vector<int> partsIds(BuildVectOfIdsFromVecBool(code));// pour chaque partition retourne l'id de la premiere partition à true
       if(partsIds.empty())
         continue;
-      std::vector<double> wg;
-      std::vector<int> nbCores2;
+      std::vector<std::pair <const ComplexWeight *, int> > wg;
       for(std::vector<int>::const_iterator it=partsIds.begin();it!=partsIds.end();it++)
         {
-          wg.push_back(parts[*it].second);
-          nbCores2.push_back(parts[*it].first->getNbCoresPerCompo());
+          wg.push_back(std::pair <const ComplexWeight *, int> (parts[*it].second, nbCoresPerShot[*it]));
         }
-      std::vector< std::vector<int> > ress(splitIntoParts(locIds,nbCores2,wg));
+      std::vector< std::vector<int> > ress(splitIntoParts(locIds,wg));
       std::size_t k(0);
       for(std::vector<int>::const_iterator it=partsIds.begin();it!=partsIds.end();it++,k++)
         {
@@ -264,47 +352,138 @@ std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > PlayGround::partition(con
     {
       std::set<int> s(retIds[i].begin(),retIds[i].end());
       std::vector<int> v(s.begin(),s.end());
-      ret[i]=PartDefinition::BuildFrom(this,(parts[i].first)->getNbCoresPerCompo(),v);
+      ret[i]=PartDefinition::BuildFrom(this,v);
     }
   return ret;
 }
 
-std::vector<int> sortArr(const std::vector<int>& v)
+std::vector< std::vector<int> > PlayGround::splitIntoParts(const std::vector<int>& coreIds, const std::vector< std::pair <const ComplexWeight *, int> >& weights) const
 {
-  std::multimap<int,int> m;
-  int i(v.size()-1);
-  for(std::vector<int>::const_reverse_iterator it=v.rbegin();it!=v.rend();it++)
-    m.insert(std::pair<int,int>(*it,i--));
-  std::vector<int> ret(m.size());
-  i=0;
-  for(std::multimap<int,int>::const_reverse_iterator it=m.rbegin();it!=m.rend();it++)// reverse -> sort from biggest to the finest
-    ret[i++]=(*it).second;
-  return ret;
-}
-
-std::vector< std::vector<int> > PlayGround::splitIntoParts(const std::vector<int>& coreIds, const std::vector<int>& nbCoresConso, const std::vector<double>& weights) const
-{
-  double wgs(std::accumulate(weights.begin(),weights.end(),0.));
-  std::size_t sz(nbCoresConso.size());
-  if(sz!=weights.size())
-    throw Exception("PlayGround::splitIntoParts : internal error !");
+  std::size_t sz(weights.size());
   if(sz==0)
     return std::vector< std::vector<int> >();
-  int totalSpace(coreIds.size());
-  std::vector< std::vector<int> > ret(sz);
-  std::vector<int> fromBigToTiny(sortArr(nbCoresConso));// start to treat the coarse grain to finish with fine grain
+  std::vector< std::vector<int> > ret;
+  std::vector< std::vector<int> > disorderRet(sz);
   std::vector<bool> zeArr(getNumberOfCoresAvailable(),false);
   highlightOnIds(coreIds,zeArr);
   int nbOfCoresToSplit(coreIds.size());
-  std::size_t ii(fromBigToTiny.size());
-  for(std::vector<int>::const_iterator it=fromBigToTiny.begin();it!=fromBigToTiny.end();it++,ii--)
+  int totalSpace(coreIds.size());
+  int remainingSpace(totalSpace);
+  std::vector<int> nbOfCoresAllocated(sz);
+  std::vector<int> nbCoresPerShot(sz,-1);  
+  // first every other branchs take its minimal part of the cake
+  // and remove branch without valid weight
+  int i(0);
+  std::map<int,int> saveOrder;
+  const std::vector< std::pair <const ComplexWeight *, int> > sortedWeights(bigToTiny(weights, saveOrder));
+  for(std::vector<std::pair <const ComplexWeight *, int> >::const_iterator it=sortedWeights.begin();it!=sortedWeights.end();it++,i++)
+    {
+      nbCoresPerShot[i]=(*it).second;
+      if ((*it).first->isUnsetLoopWeight())
+        {
+         nbOfCoresAllocated[i]=nbCoresPerShot[i]; // branch with only elementary nodes
+        }
+      else if (!(*it).first->hasValidLoopWeight())
+        {
+          nbOfCoresAllocated[i]=std::max((int)((double)totalSpace/(double)(sz)), nbCoresPerShot[i]); // branch with undefined weight, takes his part proportionnally to the number of branchs
+        }
+      else
+        {
+          nbOfCoresAllocated[i]=nbCoresPerShot[i];
+        }
+    }
+  remainingSpace-=std::accumulate(nbOfCoresAllocated.begin(), nbOfCoresAllocated.end(), 0);
+  //get critical path (between path with loopWeight)
+  int criticalPathRank=getCriticalPath(sortedWeights, nbOfCoresAllocated);
+  if (criticalPathRank!=-1)
     {
-      int maxNbOfCores((int)(totalSpace*weights[*it]/wgs));// now try to find in zeArr at most maxNbOfCores cores
-      ret[*it]=takePlace(maxNbOfCores,nbCoresConso[*it],zeArr,ii==1);
+      // add cores to critical path while enough cores are availables
+         while (remainingSpace >= nbCoresPerShot[criticalPathRank])
+           {
+             nbOfCoresAllocated[criticalPathRank]+=nbCoresPerShot[criticalPathRank];
+             remainingSpace-=nbCoresPerShot[criticalPathRank];
+             criticalPathRank=getCriticalPath(sortedWeights, nbOfCoresAllocated);
+           }
+         //fill other paths with remaining cores (if possible) (reuse fromBigToTiny here?)
+         // and takePlace
+         int coresToAdd;
+         int j(0);
+         for(std::vector<int>::iterator it=nbOfCoresAllocated.begin();it!=nbOfCoresAllocated.end();it++,j++)
+           {
+             coresToAdd=((int)(remainingSpace/nbCoresPerShot[j]))*nbCoresPerShot[j];
+             *it+=coresToAdd;
+             remainingSpace-=coresToAdd;
+           }
+    }
+  int k(0);
+  for(std::vector<int>::iterator it=nbOfCoresAllocated.begin();it!=nbOfCoresAllocated.end();it++,k++)
+    {
+      disorderRet[k]=takePlace(*it,nbCoresPerShot[k],zeArr,k==(sz-1));
+    }   
+  ret=backToOriginalOrder(disorderRet, saveOrder);
+  return ret;
+}
+
+std::vector< std::pair <const ComplexWeight *, int> > PlayGround::bigToTiny(const std::vector< std::pair <const ComplexWeight *, int> > &weights, std::map<int,int> &saveOrder) const
+{
+  int maxCoresPerShot(0), rankMax(0);
+  int i(0);
+  std::vector< std::pair <const ComplexWeight *, int> > ret;
+  std::size_t sz(weights.size());
+  while (ret.size()<sz)
+    {
+      for(std::vector<std::pair <const ComplexWeight *, int> >::const_iterator it=weights.begin();it!=weights.end();it++,i++)
+        {
+          if ((maxCoresPerShot<(*it).second) && (saveOrder.find(i)==saveOrder.end()))
+            {
+              maxCoresPerShot=(*it).second;
+              rankMax=i;
+            }
+        }
+      ret.push_back(std::pair <const ComplexWeight *, int>(weights[rankMax].first,weights[rankMax].second));
+      saveOrder[rankMax]=ret.size()-1;
+      maxCoresPerShot=0;
+      i=0;
     }
+  return ret;  
+}
+
+std::vector< std::vector<int> > PlayGround::backToOriginalOrder(const std::vector< std::vector<int> > &disorderVec, const std::map<int,int> &saveOrder) const
+{
+  std::vector< std::vector<int> > ret;
+  std::size_t sz(disorderVec.size());
+  if (disorderVec.size()!=saveOrder.size())
+    throw Exception("PlayGround::backToOriginalOrder : incoherent vector size !");
+  for (int i=0; i<sz; i++)
+      ret.push_back(disorderVec[saveOrder.at(i)]);
   return ret;
 }
 
+int PlayGround::getCriticalPath(const std::vector<std::pair <const ComplexWeight *, int > >& weights, const std::vector<int>& nbOfCoresAllocated) const
+{
+  double maxWeight(0.);
+  double pathWeight(0.);
+  int rankMaxPath(-1);
+  if ((weights.size()!=nbOfCoresAllocated.size()) || (weights.size()==0))
+    throw Exception("PlayGround::getCriticalPath : internal error !");
+  int i=0;
+  for(std::vector<std::pair <const ComplexWeight *, int> >::const_iterator it=weights.begin();it!=weights.end();it++,i++)
+    {
+      if (nbOfCoresAllocated[i]==0)
+        throw Exception("PlayGround::getCriticalPath : nbOfCoresAllocated is null! error !");
+      if (!(*it).first->isDefaultValue())
+        {
+             pathWeight=(*it).first->calculateTotalLength(nbOfCoresAllocated[i]);
+             if (pathWeight > maxWeight)
+               {
+                 maxWeight=pathWeight;
+                 rankMaxPath=i;
+               }
+        }        
+    }
+  return rankMaxPath;
+} 
+
 std::vector<int> PlayGround::takePlace(int maxNbOfCoresToAlloc, int nbCoresPerShot, std::vector<bool>& distributionOfCores, bool lastOne) const
 {
   if(maxNbOfCoresToAlloc<1)
@@ -376,7 +555,7 @@ int PlayGround::fromWorkerIdToResId(int workerId, int nbProcPerNode) const
   std::size_t sz2(_data.size());
   std::vector<int> deltas(sz2+1); deltas[0]=0;
   for(std::size_t i=0;i<sz2;i++)
-    deltas[i+1]=deltas[i]+(_data[i].second)/nbProcPerNode;
+    deltas[i+1]=deltas[i]+(_data[i].nbCores())/nbProcPerNode;
   int zePos(0);
   while(zePos<sz2 && (workerId<deltas[zePos] || workerId>=deltas[zePos+1]))
     zePos++;
@@ -391,7 +570,7 @@ int PlayGround::fromWorkerIdToResId(int workerId, int nbProcPerNode) const
 std::string PlayGround::deduceMachineFrom(int workerId, int nbProcPerNode) const
 {
   int zePos(fromWorkerIdToResId(workerId,nbProcPerNode));
-  return _data[zePos].first;
+  return _data[zePos].name();
 }
 
 /*! 
@@ -408,12 +587,12 @@ PlayGround::~PlayGround()
 
 //////////////////////
 
-PartDefinition::PartDefinition(const PlayGround *pg, int nbOfCoresPerComp):_nbOfCoresPerComp(nbOfCoresPerComp)
+PartDefinition::PartDefinition(const PlayGround *pg)
 {
   _pg.takeRef(pg);
 }
 
-PartDefinition::PartDefinition(const PartDefinition& other):_pg(other._pg),_nbOfCoresPerComp(other._nbOfCoresPerComp)
+PartDefinition::PartDefinition(const PartDefinition& other):_pg(other._pg)
 {
 }
 
@@ -421,16 +600,16 @@ PartDefinition::~PartDefinition()
 {
 }
 
-std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > PartDefinition::partition(const std::vector< double >& wgs) const
-{
-  std::size_t sz(wgs.size());
-  std::vector< std::pair<const PartDefinition *,double> > elts(sz);
-  for(std::size_t i=0;i<sz;i++)
-    elts[i]=std::pair<const PartDefinition *,double>(this,wgs[i]);
-  return getPlayGround()->partition(elts);
-}
+// std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > PartDefinition::partition(const std::vector< const ComplexWeight *>& wgs) const
+// {
+//   std::size_t sz(wgs.size());
+//   std::vector< std::pair<const PartDefinition *, const ComplexWeight *> > elts(sz);
+//   for(std::size_t i=0;i<sz;i++)
+//     elts[i]=std::pair<const PartDefinition *, const ComplexWeight *>(this,wgs[i]);
+//   return getPlayGround()->partition(elts);
+// }
 
-YACS::BASES::AutoRefCnt<PartDefinition> PartDefinition::BuildFrom(const PlayGround *pg, int nbOfCoresPerComp, const std::vector<int>& coreIds)
+YACS::BASES::AutoRefCnt<PartDefinition> PartDefinition::BuildFrom(const PlayGround *pg, const std::vector<int>& coreIds)
 {
   int spaceSz(pg->getNumberOfCoresAvailable()),sz(coreIds.size());
   if(sz>spaceSz)
@@ -445,15 +624,15 @@ YACS::BASES::AutoRefCnt<PartDefinition> PartDefinition::BuildFrom(const PlayGrou
       throw Exception("PartDefinition::BuildFrom : error ! The content of core Ids is not OK 2 !");
   if(zeEnd-zeStart+1!=sz)
     {
-      YACS::BASES::AutoRefCnt<PartDefinition> pd(new NonContigPartDefinition(pg,nbOfCoresPerComp,coreIds));
+      YACS::BASES::AutoRefCnt<PartDefinition> pd(new NonContigPartDefinition(pg,coreIds));
       return pd;
     }
   if(sz==spaceSz)
     {
-      YACS::BASES::AutoRefCnt<PartDefinition> pd(new AllPartDefinition(pg,nbOfCoresPerComp));
+      YACS::BASES::AutoRefCnt<PartDefinition> pd(new AllPartDefinition(pg));
       return pd;
     }
-  YACS::BASES::AutoRefCnt<PartDefinition> pd(new ContigPartDefinition(pg,nbOfCoresPerComp,zeStart,zeEnd+1));
+  YACS::BASES::AutoRefCnt<PartDefinition> pd(new ContigPartDefinition(pg,zeStart,zeEnd+1));
   return pd;
 }
 
@@ -474,21 +653,21 @@ void PartDefinition::stashPart(int nbCoresStashed, double weightOfRemain, YACS::
       int n1(nbCoresAvailable-n0);
       if(n1<=0)
         {
-          pdStashed=PartDefinition::BuildFrom(getPlayGround(),1,ids);
-          pdRemain=PartDefinition::BuildFrom(getPlayGround(),1,ids);
+          pdStashed=PartDefinition::BuildFrom(getPlayGround(),ids);
+          pdRemain=PartDefinition::BuildFrom(getPlayGround(),ids);
         }
       else
         {
           std::vector<int> ids0(ids.begin(),ids.begin()+n0),ids1(ids.begin()+n0,ids.end());
-          pdStashed=PartDefinition::BuildFrom(getPlayGround(),1,ids0);
-          pdRemain=PartDefinition::BuildFrom(getPlayGround(),1,ids1);
+          pdStashed=PartDefinition::BuildFrom(getPlayGround(),ids0);
+          pdRemain=PartDefinition::BuildFrom(getPlayGround(),ids1);
         }
     }
   else
     {
       std::vector<int> ids0(ids.begin(),ids.begin()+nbCoresStashed),ids1(ids.begin()+nbCoresStashed,ids.end());
-      pdStashed=PartDefinition::BuildFrom(getPlayGround(),1,ids0);
-      pdRemain=PartDefinition::BuildFrom(getPlayGround(),1,ids1);
+      pdStashed=PartDefinition::BuildFrom(getPlayGround(),ids0);
+      pdRemain=PartDefinition::BuildFrom(getPlayGround(),ids1);
     }
 }
 
@@ -503,7 +682,7 @@ std::vector<std::size_t> PartDefinition::computeWorkerIdsCovered(int nbCoresPerC
 
 //////////////////////
 
-ContigPartDefinition::ContigPartDefinition(const PlayGround *pg, int nbOfCoresPerComp, int zeStart, int zeStop):PartDefinition(pg,nbOfCoresPerComp),_start(zeStart),_stop(zeStop)
+ContigPartDefinition::ContigPartDefinition(const PlayGround *pg, int zeStart, int zeStop):PartDefinition(pg),_start(zeStart),_stop(zeStop)
 {
   if(_start<0 || _stop<_start || _stop>getSpaceSize())
     throw Exception("ContigPartDefinition constructor : Invalid input values");
@@ -540,7 +719,7 @@ int ContigPartDefinition::getNumberOfCoresConsumed() const
 
 //////////////////////
 
-NonContigPartDefinition::NonContigPartDefinition(const PlayGround *pg, int nbOfCoresPerComp, const std::vector<int>& ids):PartDefinition(pg,nbOfCoresPerComp),_ids(ids)
+NonContigPartDefinition::NonContigPartDefinition(const PlayGround *pg, const std::vector<int>& ids):PartDefinition(pg),_ids(ids)
 {
   checkOKIds();
 }