Version: 9.15.0
PlayGround.cxx
Go to the documentation of this file.
1 // Copyright (C) 2006-2025 CEA, EDF
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 
20 #include "PlayGround.hxx"
21 #include "Runtime.hxx"
22 
23 #include <set>
24 #include <map>
25 #include <sstream>
26 #include <iomanip>
27 #include <numeric>
28 #include <iostream>
29 #include <algorithm>
30 
31 using namespace YACS::ENGINE;
32 
33 std::size_t Resource::getNumberOfFreePlace(int nbCoresPerCont) const
34 {
35  std::size_t ret(0),pos(0);
36  while( pos < _occupied.size() )
37  {
38  bool isChunckFree(true);
39  int posInChunck(0);
40  for( ; ( posInChunck < nbCoresPerCont ) && ( pos < _occupied.size() ) ; ++posInChunck, ++pos)
41  if(_occupied[pos])
42  isChunckFree = false;
43  if( isChunckFree && (posInChunck == nbCoresPerCont) )
44  ret++;
45  }
46  return ret;
47 }
48 
49 std::vector<std::size_t> Resource::allocateFor(std::size_t& nbOfPlacesToTake, int nbCoresPerCont) const
50 {
51  std::vector<std::size_t> ret;
52  std::size_t pos(0),curWorkerId(0);
53  while( ( pos < _occupied.size() ) && ( nbOfPlacesToTake > 0 ) )
54  {
55  bool isChunckFree(true);
56  int posInChunck(0);
57  for( ; ( posInChunck < nbCoresPerCont ) && ( pos < _occupied.size() ) ; ++posInChunck, ++pos)
58  if(_occupied[pos])
59  isChunckFree = false;
60  if( isChunckFree && (posInChunck == nbCoresPerCont) )
61  {
62  for(int i = 0 ; i < nbCoresPerCont ; ++i)
63  _occupied[pos-nbCoresPerCont+i] = true;
64  ret.push_back(curWorkerId);
65  --nbOfPlacesToTake;
66  }
67  ++curWorkerId;
68  }
69  return ret;
70 }
71 
72 void Resource::release(std::size_t workerId, int nbCoresPerCont) const
73 {
74  if(workerId >= this->getNumberOfWorkers(nbCoresPerCont))
75  throw Exception("Resource::release : invalid worker id !");
76  std::size_t pos(workerId*static_cast<std::size_t>(nbCoresPerCont));
77  for(int i = 0 ; i < nbCoresPerCont ; ++i)
78  {
79  if(!_occupied[pos + static_cast<std::size_t>(i)])
80  throw Exception("Resource::release : internal error ! A core is expected to be occupied !");
81  _occupied[pos + static_cast<std::size_t>(i)] = false;
82  }
83 }
84 
85 std::size_t Resource::getNumberOfWorkers(int nbCoresPerCont) const
86 {
87  return static_cast<std::size_t>(this->nbCores())/static_cast<std::size_t>(nbCoresPerCont);
88 }
89 
90 void Resource::printSelf(std::ostream& oss) const
91 {
92  oss << this->name() << " (" << this->nbCores() << ") : ";
93  for(auto it : this->_occupied)
94  {
95  if(it)
96  oss << "1";
97  else
98  oss << "0";
99  }
100 }
101 
102 std::string PlayGround::printSelf() const
103 {
104  std::ostringstream oss;
105  std::size_t sz(0);
106  for(auto it : _data)
107  sz=std::max(sz,it.name().length());
108  for(auto it : _data)
109  {
110  oss << " - " << std::setw(10) << it.name() << " : " << it.nbCores() << std::endl;
111  }
112  return oss.str();
113 }
114 
116 {
117  Runtime *r(getRuntime());
118  if(!r)
119  throw Exception("PlayGround::loadFromKernelCatalog : no runtime !");
120  std::vector< std::pair<std::string,int> > data(r->getCatalogOfComputeNodes());
121  setData(data);
122 }
123 
124 void PlayGround::setData(const std::vector< std::pair<std::string,int> >& defOfRes)
125 {
126  _data=std::vector<Resource>(defOfRes.begin(),defOfRes.end());
128 }
129 
131 {
132  int ret(0);
133  for(auto it : _data)
134  ret+=it.nbCores();
135  return ret;
136 }
137 
139 {
140  if(nbCoresPerCont<1)
141  throw Exception("PlayGround::getMaxNumberOfContainersCanBeHostedWithoutOverlap : invalid nbCoresPerCont. Must be >=1 !");
142  int ret(0);
143  for(auto it : _data)
144  ret+=it.nbCores()/nbCoresPerCont;
145  return ret;
146 }
147 
148 std::vector<int> PlayGround::computeOffsets() const
149 {
150  std::size_t sz(_data.size()),i(0);
151  std::vector<int> ret(sz+1); ret[0]=0;
152  for(auto it=_data.begin();it!=_data.end();it++,i++)
153  ret[i+1]=ret[i]+it->nbCores();
154  return ret;
155 }
156 
158 {
159  std::set<std::string> s;
160  for(auto it : _data)
161  {
162  s.insert(it.name());
163  if(it.nbCores()<0)
164  throw Exception("Presence of negative int value !");
165  }
166  if(s.size()!=_data.size())
167  throw Exception("host names entries must be different each other !");
168 }
169 
170 std::vector<int> PlayGround::GetIdsMatching(const std::vector<bool>& bigArr, const std::vector<bool>& pat)
171 {
172  std::vector<int> ret;
173  std::size_t szp(pat.size());
174  std::size_t sz(bigArr.size()/szp);
175  for(std::size_t i=0;i<sz;i++)
176  {
177  std::vector<bool> t(bigArr.begin()+i*szp,bigArr.begin()+(i+1)*szp);
178  if(t==pat)
179  ret.push_back(i);
180  }
181  return ret;
182 }
183 
184 std::size_t PlayGround::getNumberOfFreePlace(int nbCoresPerCont) const
185 {
186  std::size_t ret(0);
187  for(auto res : _data)
188  {
189  ret += res.getNumberOfFreePlace(nbCoresPerCont);
190  }
191  return ret;
192 }
193 
194 std::vector<std::size_t> PlayGround::allocateFor(std::size_t nbOfPlacesToTake, int nbCoresPerCont) const
195 {
196  std::vector<std::size_t> ret;
197  std::size_t nbOfPlacesToTakeCpy(nbOfPlacesToTake),offset(0);
198  for(const auto& res : _data)
199  {
200  std::vector<std::size_t> contIdsInRes(res.allocateFor(nbOfPlacesToTakeCpy,nbCoresPerCont));
201  std::for_each(contIdsInRes.begin(),contIdsInRes.end(),[offset](std::size_t& val) { val += offset; });
202  ret.insert(ret.end(),contIdsInRes.begin(),contIdsInRes.end());
203  offset += static_cast<std::size_t>(res.nbCores()/nbCoresPerCont);
204  }
205  if( ( nbOfPlacesToTakeCpy!=0 ) || ( ret.size()!=nbOfPlacesToTake ) )
206  throw Exception("PlayGround::allocateFor : internal error ! Promised place is not existing !");
207  return ret;
208 }
209 
210 void PlayGround::release(std::size_t workerId, int nbCoresPerCont) const
211 {
212  std::size_t offset(0);
213  for(const auto& res : _data)
214  {
215  std::size_t nbOfWorker(static_cast<std::size_t>(res.nbCores()/nbCoresPerCont));
216  std::size_t minId(offset),maxId(offset+nbOfWorker);
217  if(workerId>=minId && workerId<maxId)
218  {
219  res.release(workerId-minId,nbCoresPerCont);
220  break;
221  }
222  }
223 }
224 
226 {
227  for(auto it : _data)
228  {
229  it.printSelf(std::cout);
230  std::cout << std::endl;
231  }
232 }
233 
234 std::vector<int> PlayGround::BuildVectOfIdsFromVecBool(const std::vector<bool>& v)
235 {
236  std::size_t sz(std::count(v.begin(),v.end(),true)),i(0);
237  std::vector<int> ret(sz);
238  std::vector<bool>::const_iterator it(v.begin());
239  while(i<sz)
240  {
241  it=std::find(it,v.end(),true);
242  ret[i++]=std::distance(v.begin(),it);
243  it++;
244  }
245  return ret;
246 }
247 
248 void PlayGround::highlightOnIds(const std::vector<int>& coreIds, std::vector<bool>& v) const
249 {
250  if(v.size()!=getNumberOfCoresAvailable())
251  throw Exception("PlayGround::highlightOnIds : oops ! invalid size !");
252  for(std::vector<int>::const_iterator it=coreIds.begin();it!=coreIds.end();it++)
253  v[*it]=true;
254 }
255 
259 // std::vector<bool> PlayGround::getFetchedCores(int nbCoresPerWorker) const
260 // {
261 // int nbCores(getNumberOfCoresAvailable());
262 // std::vector<bool> ret(nbCores,false);
263 // if(nbCoresPerWorker==1)
264 // std::fill(ret.begin(),ret.end(),true);
265 // else
266 // {
267 // std::size_t posBg(0);
268 // for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
269 // {
270 // int nbElemsToPutOn(((*it).second/nbCoresPerWorker)*nbCoresPerWorker);
271 // std::fill(ret.begin()+posBg,ret.begin()+posBg+nbElemsToPutOn,true);
272 // posBg+=(*it).second;
273 // }
274 // }
275 // return ret;
276 //}
280 std::vector<std::size_t> PlayGround::getWorkerIdsFullyFetchedBy(int nbCoresPerComp, const std::vector<bool>& coreFlags) const
281 {
282  std::size_t posBg(0),posWorker(0);
283  std::vector<std::size_t> ret;
284  for(auto it : _data)
285  {
286  int nbWorker(it.nbCores()/nbCoresPerComp);
287  for(int j=0;j<nbWorker;j++,posWorker++)
288  {
289  std::vector<bool>::const_iterator it2(std::find(coreFlags.begin()+posBg+j*nbCoresPerComp,coreFlags.begin()+posBg+(j+1)*nbCoresPerComp,false));
290  if(it2==coreFlags.begin()+posBg+(j+1)*nbCoresPerComp)
291  ret.push_back(posWorker);
292  }
293  posBg+=it.nbCores();
294  }
295  return ret;
296 }
297 
298 std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > PlayGround::partition(const std::vector< std::pair<const PartDefinition *, const ComplexWeight *> >& parts, const std::vector< int>& nbCoresPerShot) const
299 {
300  std::size_t sz(parts.size()),szs(getNumberOfCoresAvailable());
301  if (sz!=nbCoresPerShot.size())
302  throw Exception("PlayGround::partition : incoherent vector size !");
303  if(sz==0)
304  return std::vector< YACS::BASES::AutoRefCnt<PartDefinition> >();
305  if(sz==1)
306  {
307  const PartDefinition *pd(parts[0].first);
308  if(!pd)
309  throw Exception("Presence of null pointer as part def 0 !");
311  std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > ret2(1,ret);
312  return ret2;
313  }
314  if(sz>31)
315  throw Exception("PlayGround::partition : not implemented yet for more than 31 ! You need to pay for it :)");
316  std::vector<bool> zeArr(szs*sz,false);
317  std::size_t i(0);
318  for(std::vector< std::pair<const PartDefinition *, const ComplexWeight *> >::const_iterator it=parts.begin();it!=parts.end();it++,i++)
319  {
320  const PartDefinition *pd((*it).first);
321  if(!pd)
322  throw Exception("Presence of null pointer as part def !");
323  if(pd->getPlayGround()!=this)
324  throw Exception("Presence of non homogeneous playground !");
325  std::vector<bool> bs(pd->getCoresOn()); // tab of length nbCores, with True or False for each Core
326  for(std::size_t j=0;j<szs;j++)
327  zeArr[j*sz+i]=bs[j]; // remplis une table avec les valeurs de bs. La table est [nb part] * [nb cores]
328  }
329  std::vector< std::vector<int> > retIds(sz);
330  for(std::size_t i=0;i<szs;i++)
331  {
332  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
333  std::vector<int> locIds(GetIdsMatching(zeArr,code)); // liste des coeurs qui peuvent correspondre au pattern code
334  std::vector<int> partsIds(BuildVectOfIdsFromVecBool(code));// pour chaque partition retourne l'id de la premiere partition à true
335  if(partsIds.empty())
336  continue;
337  std::vector<std::pair <const ComplexWeight *, int> > wg;
338  for(std::vector<int>::const_iterator it=partsIds.begin();it!=partsIds.end();it++)
339  {
340  wg.push_back(std::pair <const ComplexWeight *, int> (parts[*it].second, nbCoresPerShot[*it]));
341  }
342  std::vector< std::vector<int> > ress(splitIntoParts(locIds,wg));
343  std::size_t k(0);
344  for(std::vector<int>::const_iterator it=partsIds.begin();it!=partsIds.end();it++,k++)
345  {
346  retIds[*it].insert(retIds[*it].end(),ress[k].begin(),ress[k].end());
347  }
348  }
349  //
350  std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > ret(sz);
351  for(std::size_t i=0;i<sz;i++)
352  {
353  std::set<int> s(retIds[i].begin(),retIds[i].end());
354  std::vector<int> v(s.begin(),s.end());
355  ret[i]=PartDefinition::BuildFrom(this,v);
356  }
357  return ret;
358 }
359 
360 std::vector< std::vector<int> > PlayGround::splitIntoParts(const std::vector<int>& coreIds, const std::vector< std::pair <const ComplexWeight *, int> >& weights) const
361 {
362  std::size_t sz(weights.size());
363  if(sz==0)
364  return std::vector< std::vector<int> >();
365  std::vector< std::vector<int> > ret;
366  std::vector< std::vector<int> > disorderRet(sz);
367  std::vector<bool> zeArr(getNumberOfCoresAvailable(),false);
368  highlightOnIds(coreIds,zeArr);
369  int nbOfCoresToSplit(coreIds.size());
370  int totalSpace(coreIds.size());
371  int remainingSpace(totalSpace);
372  std::vector<int> nbOfCoresAllocated(sz);
373  std::vector<int> nbCoresPerShot(sz,-1);
374  // first every other branchs take its minimal part of the cake
375  // and remove branch without valid weight
376  int i(0);
377  std::map<int,int> saveOrder;
378  const std::vector< std::pair <const ComplexWeight *, int> > sortedWeights(bigToTiny(weights, saveOrder));
379  for(std::vector<std::pair <const ComplexWeight *, int> >::const_iterator it=sortedWeights.begin();it!=sortedWeights.end();it++,i++)
380  {
381  nbCoresPerShot[i]=(*it).second;
382  if ((*it).first->isUnsetLoopWeight())
383  {
384  nbOfCoresAllocated[i]=nbCoresPerShot[i]; // branch with only elementary nodes
385  }
386  else if (!(*it).first->hasValidLoopWeight())
387  {
388  nbOfCoresAllocated[i]=std::max((int)((double)totalSpace/(double)(sz)), nbCoresPerShot[i]); // branch with undefined weight, takes his part proportionnally to the number of branchs
389  }
390  else
391  {
392  nbOfCoresAllocated[i]=nbCoresPerShot[i];
393  }
394  }
395  remainingSpace-=std::accumulate(nbOfCoresAllocated.begin(), nbOfCoresAllocated.end(), 0);
396  //get critical path (between path with loopWeight)
397  int criticalPathRank=getCriticalPath(sortedWeights, nbOfCoresAllocated);
398  if (criticalPathRank!=-1)
399  {
400  // add cores to critical path while enough cores are availables
401  while (remainingSpace >= nbCoresPerShot[criticalPathRank])
402  {
403  nbOfCoresAllocated[criticalPathRank]+=nbCoresPerShot[criticalPathRank];
404  remainingSpace-=nbCoresPerShot[criticalPathRank];
405  criticalPathRank=getCriticalPath(sortedWeights, nbOfCoresAllocated);
406  }
407  //fill other paths with remaining cores (if possible) (reuse fromBigToTiny here?)
408  // and takePlace
409  int coresToAdd;
410  int j(0);
411  for(std::vector<int>::iterator it=nbOfCoresAllocated.begin();it!=nbOfCoresAllocated.end();it++,j++)
412  {
413  coresToAdd=((int)(remainingSpace/nbCoresPerShot[j]))*nbCoresPerShot[j];
414  *it+=coresToAdd;
415  remainingSpace-=coresToAdd;
416  }
417  }
418  int k(0);
419  for(std::vector<int>::iterator it=nbOfCoresAllocated.begin();it!=nbOfCoresAllocated.end();it++,k++)
420  {
421  disorderRet[k]=takePlace(*it,nbCoresPerShot[k],zeArr,k==(sz-1));
422  }
423  ret=backToOriginalOrder(disorderRet, saveOrder);
424  return ret;
425 }
426 
427 std::vector< std::pair <const ComplexWeight *, int> > PlayGround::bigToTiny(const std::vector< std::pair <const ComplexWeight *, int> > &weights, std::map<int,int> &saveOrder) const
428 {
429  int maxCoresPerShot(0), rankMax(0);
430  int i(0);
431  std::vector< std::pair <const ComplexWeight *, int> > ret;
432  std::size_t sz(weights.size());
433  while (ret.size()<sz)
434  {
435  for(std::vector<std::pair <const ComplexWeight *, int> >::const_iterator it=weights.begin();it!=weights.end();it++,i++)
436  {
437  if ((maxCoresPerShot<(*it).second) && (saveOrder.find(i)==saveOrder.end()))
438  {
439  maxCoresPerShot=(*it).second;
440  rankMax=i;
441  }
442  }
443  ret.push_back(std::pair <const ComplexWeight *, int>(weights[rankMax].first,weights[rankMax].second));
444  saveOrder[rankMax]=ret.size()-1;
445  maxCoresPerShot=0;
446  i=0;
447  }
448  return ret;
449 }
450 
451 std::vector< std::vector<int> > PlayGround::backToOriginalOrder(const std::vector< std::vector<int> > &disorderVec, const std::map<int,int> &saveOrder) const
452 {
453  std::vector< std::vector<int> > ret;
454  std::size_t sz(disorderVec.size());
455  if (disorderVec.size()!=saveOrder.size())
456  throw Exception("PlayGround::backToOriginalOrder : incoherent vector size !");
457  for (int i=0; i<sz; i++)
458  ret.push_back(disorderVec[saveOrder.at(i)]);
459  return ret;
460 }
461 
462 int PlayGround::getCriticalPath(const std::vector<std::pair <const ComplexWeight *, int > >& weights, const std::vector<int>& nbOfCoresAllocated) const
463 {
464  double maxWeight(0.);
465  double pathWeight(0.);
466  int rankMaxPath(-1);
467  if ((weights.size()!=nbOfCoresAllocated.size()) || (weights.size()==0))
468  throw Exception("PlayGround::getCriticalPath : internal error !");
469  int i=0;
470  for(std::vector<std::pair <const ComplexWeight *, int> >::const_iterator it=weights.begin();it!=weights.end();it++,i++)
471  {
472  if (nbOfCoresAllocated[i]==0)
473  throw Exception("PlayGround::getCriticalPath : nbOfCoresAllocated is null! error !");
474  if (!(*it).first->isDefaultValue())
475  {
476  pathWeight=(*it).first->calculateTotalLength(nbOfCoresAllocated[i]);
477  if (pathWeight > maxWeight)
478  {
479  maxWeight=pathWeight;
480  rankMaxPath=i;
481  }
482  }
483  }
484  return rankMaxPath;
485 }
486 
487 std::vector<int> PlayGround::takePlace(int maxNbOfCoresToAlloc, int nbCoresPerShot, std::vector<bool>& distributionOfCores, bool lastOne) const
488 {
489  if(maxNbOfCoresToAlloc<1)
490  throw Exception("PlayGround::takePlace : internal error ! no space to alloc !");
491  int tmpMaxNbOfCoresToAlloc(maxNbOfCoresToAlloc);
492  if(lastOne)
493  tmpMaxNbOfCoresToAlloc=std::max(tmpMaxNbOfCoresToAlloc,(int)std::count(distributionOfCores.begin(),distributionOfCores.end(),true));
494  std::vector<int> ret;
495  std::vector<int> offsets(computeOffsets());
496  int nbFullItem(0);
497  std::size_t sz(offsets.size()-1);
498  for(std::size_t i=0;i<sz && tmpMaxNbOfCoresToAlloc>=nbCoresPerShot;i++)
499  {
500  int d(offsets[i+1]-offsets[i]);
501  if(nbCoresPerShot>d)
502  continue;
503  std::vector<bool> target(nbCoresPerShot,true);
504  for(int j=0;j<=d-nbCoresPerShot && tmpMaxNbOfCoresToAlloc>=nbCoresPerShot;)
505  {
506  std::vector<bool> t(distributionOfCores.begin()+offsets[i]+j,distributionOfCores.begin()+offsets[i]+j+nbCoresPerShot);
507  if(t==target)
508  {
509  nbFullItem++;
510  tmpMaxNbOfCoresToAlloc-=nbCoresPerShot;
511  std::fill(distributionOfCores.begin()+offsets[i]+j,distributionOfCores.begin()+offsets[i]+j+nbCoresPerShot,false);
512  for(int k=offsets[i]+j;k<offsets[i]+j+nbCoresPerShot;k++)
513  ret.push_back(k);
514  j+=nbCoresPerShot;
515  }
516  else
517  j++;
518  }
519  }
520  if(nbFullItem>0)
521  return ret;
522  if(nbCoresPerShot<=1)
523  throw Exception("PlayGround::takePlace : internal error !");
524  // not enough contiguous place. Find the first wider contiguous place
525  for(int kk=std::min(nbCoresPerShot-1,tmpMaxNbOfCoresToAlloc);kk>=1;kk--)
526  {
527  for(std::size_t i=0;i<sz && tmpMaxNbOfCoresToAlloc>=kk;i++)
528  {
529  int d(offsets[i+1]-offsets[i]);
530  if(kk>d)
531  continue;
532  std::vector<bool> target(kk,true);
533  for(int j=0;j<=d-kk && tmpMaxNbOfCoresToAlloc>=kk;)
534  {
535  std::vector<bool> t(distributionOfCores.begin()+offsets[i]+j,distributionOfCores.begin()+offsets[i]+j+kk);
536  if(t==target)
537  {
538  nbFullItem++;
539  tmpMaxNbOfCoresToAlloc-=kk;
540  std::fill(distributionOfCores.begin()+offsets[i]+j,distributionOfCores.begin()+offsets[i]+j+kk,false);
541  for(int k=offsets[i]+j;k<offsets[i]+j+kk;k++)
542  ret.push_back(k);
543  return ret;
544  }
545  else
546  j++;
547  }
548  }
549  }
550  throw Exception("PlayGround::takePlace : internal error ! All cores are occupied !");
551 }
552 
553 int PlayGround::fromWorkerIdToResId(int workerId, int nbProcPerNode) const
554 {
555  std::size_t sz2(_data.size());
556  std::vector<int> deltas(sz2+1); deltas[0]=0;
557  for(std::size_t i=0;i<sz2;i++)
558  deltas[i+1]=deltas[i]+(_data[i].nbCores())/nbProcPerNode;
559  int zePos(0);
560  while(zePos<sz2 && (workerId<deltas[zePos] || workerId>=deltas[zePos+1]))
561  zePos++;
562  if(zePos==sz2)
563  zePos=workerId%sz2;
564  return zePos;
565 }
566 
570 std::string PlayGround::deduceMachineFrom(int workerId, int nbProcPerNode) const
571 {
572  int zePos(fromWorkerIdToResId(workerId,nbProcPerNode));
573  return _data[zePos].name();
574 }
575 
579 int PlayGround::getNumberOfWorkers(int nbCoresPerWorker) const
580 {
581  return getMaxNumberOfContainersCanBeHostedWithoutOverlap(nbCoresPerWorker);
582 }
583 
585 {
586 }
587 
589 
591 {
592  _pg.takeRef(pg);
593 }
594 
595 PartDefinition::PartDefinition(const PartDefinition& other):_pg(other._pg)
596 {
597 }
598 
600 {
601 }
602 
603 // std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > PartDefinition::partition(const std::vector< const ComplexWeight *>& wgs) const
604 // {
605 // std::size_t sz(wgs.size());
606 // std::vector< std::pair<const PartDefinition *, const ComplexWeight *> > elts(sz);
607 // for(std::size_t i=0;i<sz;i++)
608 // elts[i]=std::pair<const PartDefinition *, const ComplexWeight *>(this,wgs[i]);
609 // return getPlayGround()->partition(elts);
610 // }
611 
613 {
614  int spaceSz(pg->getNumberOfCoresAvailable()),sz(coreIds.size());
615  if(sz>spaceSz)
616  throw Exception("PartDefinition::BuildFrom : error 1 !");
617  if(sz==0)
618  throw Exception("PartDefinition::BuildFrom : error 2 !");
619  int zeStart(coreIds.front()),zeEnd(coreIds.back());
620  if(zeStart<0 || zeEnd<zeStart)
621  throw Exception("PartDefinition::BuildFrom : error ! The content of core Ids is not OK !");
622  for(std::size_t i=0;i<sz-1;i++)
623  if(coreIds[i+1]<coreIds[i])
624  throw Exception("PartDefinition::BuildFrom : error ! The content of core Ids is not OK 2 !");
625  if(zeEnd-zeStart+1!=sz)
626  {
628  return pd;
629  }
630  if(sz==spaceSz)
631  {
633  return pd;
634  }
636  return pd;
637 }
638 
639 void PartDefinition::stashPart(int nbCoresStashed, double weightOfRemain, YACS::BASES::AutoRefCnt<PartDefinition>& pdStashed, YACS::BASES::AutoRefCnt<PartDefinition>& pdRemain) const
640 {
641  if(nbCoresStashed<=0)
642  throw Exception("stashPart : Invalid nbCoresStashed value !");
643  if(weightOfRemain<=0.)
644  throw Exception("stashPart : Invalid weight !");
645  std::vector<bool> coresOn(getCoresOn());
646  int nbCoresAvailable(std::count(coresOn.begin(),coresOn.end(),true));
647  std::vector<int> ids(PlayGround::BuildVectOfIdsFromVecBool(coresOn));
648  if(nbCoresAvailable==0)
649  throw Exception("PartDefinition::stashPart : no available cores !");
650  if(nbCoresAvailable<=nbCoresStashed)
651  {
652  int n0((int)(1./(1.+weightOfRemain)*nbCoresAvailable)); n0=std::max(n0,1);
653  int n1(nbCoresAvailable-n0);
654  if(n1<=0)
655  {
656  pdStashed=PartDefinition::BuildFrom(getPlayGround(),ids);
658  }
659  else
660  {
661  std::vector<int> ids0(ids.begin(),ids.begin()+n0),ids1(ids.begin()+n0,ids.end());
662  pdStashed=PartDefinition::BuildFrom(getPlayGround(),ids0);
663  pdRemain=PartDefinition::BuildFrom(getPlayGround(),ids1);
664  }
665  }
666  else
667  {
668  std::vector<int> ids0(ids.begin(),ids.begin()+nbCoresStashed),ids1(ids.begin()+nbCoresStashed,ids.end());
669  pdStashed=PartDefinition::BuildFrom(getPlayGround(),ids0);
670  pdRemain=PartDefinition::BuildFrom(getPlayGround(),ids1);
671  }
672 }
673 
677 std::vector<std::size_t> PartDefinition::computeWorkerIdsCovered(int nbCoresPerComp) const
678 {
679  std::vector<bool> coresOn(getCoresOn());
680  return _pg->getWorkerIdsFullyFetchedBy(nbCoresPerComp,coresOn);
681 }
682 
684 
685 ContigPartDefinition::ContigPartDefinition(const PlayGround *pg, int zeStart, int zeStop):PartDefinition(pg),_start(zeStart),_stop(zeStop)
686 {
687  if(_start<0 || _stop<_start || _stop>getSpaceSize())
688  throw Exception("ContigPartDefinition constructor : Invalid input values");
689 }
690 
691 ContigPartDefinition::ContigPartDefinition(const ContigPartDefinition& other):PartDefinition(other),_start(other._start),_stop(other._stop)
692 {
693 }
694 
696 {
697  std::ostringstream oss;
698  oss << "Contiguous : start=" << _start << " stop=" << _stop;
699  return oss.str();
700 }
701 
702 std::vector<bool> ContigPartDefinition::getCoresOn() const
703 {
704  std::vector<bool> ret(getSpaceSize(),false);
705  for(int i=_start;i<_stop;i++)
706  ret[i]=true;
707  return ret;
708 }
709 
711 {
712  return new ContigPartDefinition(*this);
713 }
714 
716 {
717  return _stop-_start;
718 }
719 
721 
722 NonContigPartDefinition::NonContigPartDefinition(const PlayGround *pg, const std::vector<int>& ids):PartDefinition(pg),_ids(ids)
723 {
724  checkOKIds();
725 }
726 
728 {
729 }
730 
732 {
733  std::ostringstream oss;
734  oss << "Non contiguous : ";
735  for(std::vector<int>::const_iterator it=_ids.begin();it!=_ids.end();it++)
736  oss << *it << ", ";
737  return oss.str();
738 }
739 
740 std::vector<bool> NonContigPartDefinition::getCoresOn() const
741 {
742  std::vector<bool> ret(getSpaceSize(),false);
743  for(std::vector<int>::const_iterator it=_ids.begin();it!=_ids.end();it++)
744  ret[*it]=true;
745  return ret;
746 }
747 
749 {
750  return new NonContigPartDefinition(*this);
751 }
752 
754 {
755  return _ids.size();
756 }
757 
759 {
760  int maxVal(getSpaceSize());
761  if(_ids.empty())
762  return;
763  int val(_ids.front());
764  if(val<0 || val>=maxVal)
765  throw Exception("checkOKIds : error 2 !");
766  std::size_t sz(_ids.size());
767  for(std::size_t i=0;i<sz-1;i++)
768  {
769  if(_ids[i+1]<=_ids[i])
770  throw Exception("checkOKIds : error 1 !");
771  if(_ids[i+1]>=maxVal)
772  throw Exception("checkOKIds : error 3 !");
773  }
774 }
775 
777 
779 {
780 }
781 
782 std::string AllPartDefinition::printSelf() const
783 {
784  std::ostringstream oss;
785  oss << "All";
786  return oss.str();
787 }
788 
789 std::vector<bool> AllPartDefinition::getCoresOn() const
790 {
791  std::vector<bool> ret(getSpaceSize(),true);
792  return ret;
793 }
794 
796 {
797  return new AllPartDefinition(*this);
798 }
799 
801 {
802  return getSpaceSize();
803 }
804 
806 
807  std::vector<int> ForTestOmlyHPContCls::getIDS() const
808  {
809  std::size_t sz(_ids.size());
810  std::vector<int> ret(sz);
811  for(std::size_t i=0;i<sz;i++)
812  ret[i]=_ids[i];
813  return ret;
814  }
AllPartDefinition(const PlayGround *pg)
Definition: PlayGround.hxx:177
std::vector< bool > getCoresOn() const
Definition: PlayGround.cxx:789
AllPartDefinition * copy() const
Definition: PlayGround.cxx:795
std::string printSelf() const
Definition: PlayGround.cxx:782
ContigPartDefinition * copy() const
Definition: PlayGround.cxx:710
std::vector< bool > getCoresOn() const
Definition: PlayGround.cxx:702
ContigPartDefinition(const PlayGround *pg, int zeStart, int zeStop)
Definition: PlayGround.cxx:685
std::vector< int > getIDS() const
Definition: PlayGround.cxx:807
std::vector< std::size_t > _ids
Definition: PlayGround.hxx:202
std::vector< bool > getCoresOn() const
Definition: PlayGround.cxx:740
NonContigPartDefinition * copy() const
Definition: PlayGround.cxx:748
NonContigPartDefinition(const PlayGround *pg, const std::vector< int > &ids)
Definition: PlayGround.cxx:722
virtual std::vector< bool > getCoresOn() const =0
const PlayGround * getPlayGround() const
Definition: PlayGround.hxx:127
virtual PartDefinition * copy() const =0
static YACS::BASES::AutoRefCnt< PartDefinition > BuildFrom(const PlayGround *pg, const std::vector< int > &coreIds)
Definition: PlayGround.cxx:612
std::vector< std::size_t > computeWorkerIdsCovered(int nbCoresPerComp) const
Definition: PlayGround.cxx:677
PartDefinition(const PlayGround *pg)
Definition: PlayGround.cxx:590
YACS::BASES::AutoConstRefCnt< PlayGround > _pg
Definition: PlayGround.hxx:136
void stashPart(int nbCoresStashed, double weightOfRemain, YACS::BASES::AutoRefCnt< PartDefinition > &pdStashed, YACS::BASES::AutoRefCnt< PartDefinition > &pdRemain) const
Definition: PlayGround.cxx:639
int getNumberOfCoresAvailable() const
Definition: PlayGround.cxx:130
void checkCoherentInfo() const
Definition: PlayGround.cxx:157
std::vector< Resource > _data
Definition: PlayGround.hxx:115
std::vector< std::size_t > allocateFor(std::size_t nbOfPlacesToTake, int nbCoresPerCont) const
Definition: PlayGround.cxx:194
int getCriticalPath(const std::vector< std::pair< const ComplexWeight *, int > > &weights, const std::vector< int > &maxNbOfCores) const
Definition: PlayGround.cxx:462
int getNumberOfWorkers(int nbCoresPerWorker) const
Definition: PlayGround.cxx:579
std::string deduceMachineFrom(int workerId, int nbProcPerNode) const
Definition: PlayGround.cxx:570
int getMaxNumberOfContainersCanBeHostedWithoutOverlap(int nbCoresPerCont) const
Definition: PlayGround.cxx:138
std::vector< std::pair< const ComplexWeight *, int > > bigToTiny(const std::vector< std::pair< const ComplexWeight *, int > > &weights, std::map< int, int > &saveOrder) const
Definition: PlayGround.cxx:427
void highlightOnIds(const std::vector< int > &coreIds, std::vector< bool > &v) const
Definition: PlayGround.cxx:248
static std::vector< int > GetIdsMatching(const std::vector< bool > &bigArr, const std::vector< bool > &pat)
Definition: PlayGround.cxx:170
void setData(const std::vector< std::pair< std::string, int > > &defOfRes)
Definition: PlayGround.cxx:124
void release(std::size_t workerId, int nbCoresPerCont) const
Definition: PlayGround.cxx:210
std::vector< YACS::BASES::AutoRefCnt< PartDefinition > > partition(const std::vector< std::pair< const PartDefinition *, const ComplexWeight * > > &parts, const std::vector< int > &nbCoresPerShot) const
Definition: PlayGround.cxx:298
static std::vector< int > BuildVectOfIdsFromVecBool(const std::vector< bool > &v)
Definition: PlayGround.cxx:234
std::vector< std::size_t > getWorkerIdsFullyFetchedBy(int nbCoresPerComp, const std::vector< bool > &coreFlags) const
Definition: PlayGround.cxx:280
int fromWorkerIdToResId(int workerId, int nbProcPerNode) const
Definition: PlayGround.cxx:553
std::string printSelf() const
Definition: PlayGround.cxx:102
std::vector< int > takePlace(int maxNbOfCoresToAlloc, int nbCoresPerShot, std::vector< bool > &distributionOfCores, bool lastOne=false) const
Definition: PlayGround.cxx:487
std::vector< std::vector< int > > backToOriginalOrder(const std::vector< std::vector< int > > &disorderVec, const std::map< int, int > &saveOrder) const
Definition: PlayGround.cxx:451
std::vector< std::vector< int > > splitIntoParts(const std::vector< int > &coreIds, const std::vector< std::pair< const ComplexWeight *, int > > &weights) const
Definition: PlayGround.cxx:360
std::vector< int > computeOffsets() const
Definition: PlayGround.cxx:148
std::size_t getNumberOfFreePlace(int nbCoresPerCont) const
Definition: PlayGround.cxx:184
std::vector< bool > _occupied
Definition: PlayGround.hxx:55
void printSelf(std::ostream &oss) const
Definition: PlayGround.cxx:90
std::string name() const
Definition: PlayGround.hxx:46
void release(std::size_t workerId, int nbCoresPerCont) const
Definition: PlayGround.cxx:72
std::size_t getNumberOfFreePlace(int nbCoresPerCont) const
Definition: PlayGround.cxx:33
std::size_t getNumberOfWorkers(int nbCoresPerCont) const
Definition: PlayGround.cxx:85
std::vector< std::size_t > allocateFor(std::size_t &nbOfPlacesToTake, int nbCoresPerCont) const
Definition: PlayGround.cxx:49
YACSLIBENGINE_EXPORT Runtime * getRuntime()
Definition: Runtime.cxx:61
def distance(node, new_node)
Definition: graph.py:275