Version: 9.16.0
PlayGround.cxx
Go to the documentation of this file.
1// Copyright (C) 2006-2026 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
31using namespace YACS::ENGINE;
32
33std::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
49std::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
72void 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
85std::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
90void 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
102std::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
124void 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
148std::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
170std::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
184std::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
194std::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
210void 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
234std::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
248void 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//}
280std::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
298std::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
360std::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
427std::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
451std::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
462int 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
487std::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
553int 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
570std::string PlayGround::deduceMachineFrom(int workerId, int nbProcPerNode) const
571{
572 int zePos(fromWorkerIdToResId(workerId,nbProcPerNode));
573 return _data[zePos].name();
574}
575
579int PlayGround::getNumberOfWorkers(int nbCoresPerWorker) const
580{
582}
583
585{
586}
587
589
591{
592 _pg.takeRef(pg);
593}
594
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
639void 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 {
658 }
659 else
660 {
661 std::vector<int> ids0(ids.begin(),ids.begin()+n0),ids1(ids.begin()+n0,ids.end());
664 }
665 }
666 else
667 {
668 std::vector<int> ids0(ids.begin(),ids.begin()+nbCoresStashed),ids1(ids.begin()+nbCoresStashed,ids.end());
671 }
672}
673
677std::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
685ContigPartDefinition::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
691ContigPartDefinition::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
702std::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
722NonContigPartDefinition::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
740std::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
783{
784 std::ostringstream oss;
785 oss << "All";
786 return oss.str();
787}
788
789std::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
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
virtual PartDefinition * copy() const =0
YACS::BASES::AutoConstRefCnt< PlayGround > _pg
Definition: PlayGround.hxx:136
const PlayGround * getPlayGround() const
Definition: PlayGround.hxx:127
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 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