35 std::size_t ret(0),pos(0);
38 bool isChunckFree(
true);
40 for( ; ( posInChunck < nbCoresPerCont ) && ( pos <
_occupied.size() ) ; ++posInChunck, ++pos)
43 if( isChunckFree && (posInChunck == nbCoresPerCont) )
51 std::vector<std::size_t> ret;
52 std::size_t pos(0),curWorkerId(0);
53 while( ( pos <
_occupied.size() ) && ( nbOfPlacesToTake > 0 ) )
55 bool isChunckFree(
true);
57 for( ; ( posInChunck < nbCoresPerCont ) && ( pos <
_occupied.size() ) ; ++posInChunck, ++pos)
60 if( isChunckFree && (posInChunck == nbCoresPerCont) )
62 for(
int i = 0 ;
i < nbCoresPerCont ; ++
i)
64 ret.push_back(curWorkerId);
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)
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;
87 return static_cast<std::size_t
>(this->
nbCores())/
static_cast<std::size_t
>(nbCoresPerCont);
92 oss << this->
name() <<
" (" << this->
nbCores() <<
") : ";
104 std::ostringstream oss;
107 sz=std::max(sz,it.name().length());
110 oss <<
" - " << std::setw(10) << it.name() <<
" : " << it.nbCores() << std::endl;
119 throw Exception(
"PlayGround::loadFromKernelCatalog : no runtime !");
120 std::vector< std::pair<std::string,int> > data(
r->getCatalogOfComputeNodes());
126 _data=std::vector<Resource>(defOfRes.begin(),defOfRes.end());
141 throw Exception(
"PlayGround::getMaxNumberOfContainersCanBeHostedWithoutOverlap : invalid nbCoresPerCont. Must be >=1 !");
144 ret+=it.nbCores()/nbCoresPerCont;
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();
159 std::set<std::string> s;
164 throw Exception(
"Presence of negative int value !");
166 if(s.size()!=
_data.size())
167 throw Exception(
"host names entries must be different each other !");
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++)
177 std::vector<bool>
t(bigArr.begin()+
i*szp,bigArr.begin()+(
i+1)*szp);
187 for(
auto res :
_data)
189 ret += res.getNumberOfFreePlace(nbCoresPerCont);
196 std::vector<std::size_t> ret;
197 std::size_t nbOfPlacesToTakeCpy(nbOfPlacesToTake),offset(0);
198 for(
const auto& res :
_data)
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);
205 if( ( nbOfPlacesToTakeCpy!=0 ) || ( ret.size()!=nbOfPlacesToTake ) )
206 throw Exception(
"PlayGround::allocateFor : internal error ! Promised place is not existing !");
212 std::size_t offset(0);
213 for(
const auto& res :
_data)
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)
219 res.release(workerId-minId,nbCoresPerCont);
229 it.printSelf(std::cout);
230 std::cout << std::endl;
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());
241 it=std::find(it,v.end(),
true);
251 throw Exception(
"PlayGround::highlightOnIds : oops ! invalid size !");
252 for(std::vector<int>::const_iterator it=coreIds.begin();it!=coreIds.end();it++)
282 std::size_t posBg(0),posWorker(0);
283 std::vector<std::size_t> ret;
286 int nbWorker(it.nbCores()/nbCoresPerComp);
287 for(
int j=0;j<nbWorker;j++,posWorker++)
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);
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
301 if (sz!=nbCoresPerShot.size())
302 throw Exception(
"PlayGround::partition : incoherent vector size !");
304 return std::vector< YACS::BASES::AutoRefCnt<PartDefinition> >();
309 throw Exception(
"Presence of null pointer as part def 0 !");
311 std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > ret2(1,ret);
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);
318 for(std::vector< std::pair<const PartDefinition *, const ComplexWeight *> >::const_iterator it=parts.begin();it!=parts.end();it++,
i++)
322 throw Exception(
"Presence of null pointer as part def !");
324 throw Exception(
"Presence of non homogeneous playground !");
326 for(std::size_t j=0;j<szs;j++)
329 std::vector< std::vector<int> > retIds(sz);
330 for(std::size_t
i=0;
i<szs;
i++)
332 std::vector<bool> code(zeArr.begin()+
i*sz,zeArr.begin()+(
i+1)*sz);
337 std::vector<std::pair <const ComplexWeight *, int> > wg;
338 for(std::vector<int>::const_iterator it=partsIds.begin();it!=partsIds.end();it++)
340 wg.push_back(std::pair <const ComplexWeight *, int> (parts[*it].second, nbCoresPerShot[*it]));
344 for(std::vector<int>::const_iterator it=partsIds.begin();it!=partsIds.end();it++,k++)
346 retIds[*it].insert(retIds[*it].end(),ress[k].begin(),ress[k].end());
350 std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > ret(sz);
351 for(std::size_t
i=0;
i<sz;
i++)
353 std::set<int> s(retIds[
i].begin(),retIds[
i].end());
354 std::vector<int> v(s.begin(),s.end());
360 std::vector< std::vector<int> >
PlayGround::splitIntoParts(
const std::vector<int>& coreIds,
const std::vector< std::pair <const ComplexWeight *, int> >& weights)
const
362 std::size_t sz(weights.size());
364 return std::vector< std::vector<int> >();
365 std::vector< std::vector<int> > ret;
366 std::vector< std::vector<int> > disorderRet(sz);
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);
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++)
381 nbCoresPerShot[
i]=(*it).second;
382 if ((*it).first->isUnsetLoopWeight())
384 nbOfCoresAllocated[
i]=nbCoresPerShot[
i];
386 else if (!(*it).first->hasValidLoopWeight())
388 nbOfCoresAllocated[
i]=std::max((
int)((
double)totalSpace/(
double)(sz)), nbCoresPerShot[
i]);
392 nbOfCoresAllocated[
i]=nbCoresPerShot[
i];
395 remainingSpace-=std::accumulate(nbOfCoresAllocated.begin(), nbOfCoresAllocated.end(), 0);
397 int criticalPathRank=
getCriticalPath(sortedWeights, nbOfCoresAllocated);
398 if (criticalPathRank!=-1)
401 while (remainingSpace >= nbCoresPerShot[criticalPathRank])
403 nbOfCoresAllocated[criticalPathRank]+=nbCoresPerShot[criticalPathRank];
404 remainingSpace-=nbCoresPerShot[criticalPathRank];
411 for(std::vector<int>::iterator it=nbOfCoresAllocated.begin();it!=nbOfCoresAllocated.end();it++,j++)
413 coresToAdd=((int)(remainingSpace/nbCoresPerShot[j]))*nbCoresPerShot[j];
415 remainingSpace-=coresToAdd;
419 for(std::vector<int>::iterator it=nbOfCoresAllocated.begin();it!=nbOfCoresAllocated.end();it++,k++)
421 disorderRet[k]=
takePlace(*it,nbCoresPerShot[k],zeArr,k==(sz-1));
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
429 int maxCoresPerShot(0), rankMax(0);
431 std::vector< std::pair <const ComplexWeight *, int> > ret;
432 std::size_t sz(weights.size());
433 while (ret.size()<sz)
435 for(std::vector<std::pair <const ComplexWeight *, int> >::const_iterator it=weights.begin();it!=weights.end();it++,
i++)
437 if ((maxCoresPerShot<(*it).second) && (saveOrder.find(
i)==saveOrder.end()))
439 maxCoresPerShot=(*it).second;
443 ret.push_back(std::pair <const ComplexWeight *, int>(weights[rankMax].first,weights[rankMax].second));
444 saveOrder[rankMax]=ret.size()-1;
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)]);
462 int PlayGround::getCriticalPath(
const std::vector<std::pair <const ComplexWeight *, int > >& weights,
const std::vector<int>& nbOfCoresAllocated)
const
464 double maxWeight(0.);
465 double pathWeight(0.);
467 if ((weights.size()!=nbOfCoresAllocated.size()) || (weights.size()==0))
468 throw Exception(
"PlayGround::getCriticalPath : internal error !");
470 for(std::vector<std::pair <const ComplexWeight *, int> >::const_iterator it=weights.begin();it!=weights.end();it++,
i++)
472 if (nbOfCoresAllocated[
i]==0)
473 throw Exception(
"PlayGround::getCriticalPath : nbOfCoresAllocated is null! error !");
474 if (!(*it).first->isDefaultValue())
476 pathWeight=(*it).first->calculateTotalLength(nbOfCoresAllocated[
i]);
477 if (pathWeight > maxWeight)
479 maxWeight=pathWeight;
487 std::vector<int>
PlayGround::takePlace(
int maxNbOfCoresToAlloc,
int nbCoresPerShot, std::vector<bool>& distributionOfCores,
bool lastOne)
const
489 if(maxNbOfCoresToAlloc<1)
490 throw Exception(
"PlayGround::takePlace : internal error ! no space to alloc !");
491 int tmpMaxNbOfCoresToAlloc(maxNbOfCoresToAlloc);
493 tmpMaxNbOfCoresToAlloc=std::max(tmpMaxNbOfCoresToAlloc,(
int)std::count(distributionOfCores.begin(),distributionOfCores.end(),
true));
494 std::vector<int> ret;
497 std::size_t sz(offsets.size()-1);
498 for(std::size_t
i=0;i<sz && tmpMaxNbOfCoresToAlloc>=nbCoresPerShot;
i++)
500 int d(offsets[
i+1]-offsets[
i]);
503 std::vector<bool> target(nbCoresPerShot,
true);
504 for(
int j=0;j<=d-nbCoresPerShot && tmpMaxNbOfCoresToAlloc>=nbCoresPerShot;)
506 std::vector<bool>
t(distributionOfCores.begin()+offsets[
i]+j,distributionOfCores.begin()+offsets[
i]+j+nbCoresPerShot);
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++)
522 if(nbCoresPerShot<=1)
523 throw Exception(
"PlayGround::takePlace : internal error !");
525 for(
int kk=std::min(nbCoresPerShot-1,tmpMaxNbOfCoresToAlloc);kk>=1;kk--)
527 for(std::size_t
i=0;i<sz && tmpMaxNbOfCoresToAlloc>=kk;
i++)
529 int d(offsets[
i+1]-offsets[
i]);
532 std::vector<bool> target(kk,
true);
533 for(
int j=0;j<=d-kk && tmpMaxNbOfCoresToAlloc>=kk;)
535 std::vector<bool>
t(distributionOfCores.begin()+offsets[
i]+j,distributionOfCores.begin()+offsets[
i]+j+kk);
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++)
550 throw Exception(
"PlayGround::takePlace : internal error ! All cores are occupied !");
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;
560 while(zePos<sz2 && (workerId<deltas[zePos] || workerId>=deltas[zePos+1]))
573 return _data[zePos].name();
616 throw Exception(
"PartDefinition::BuildFrom : error 1 !");
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)
641 if(nbCoresStashed<=0)
642 throw Exception(
"stashPart : Invalid nbCoresStashed value !");
643 if(weightOfRemain<=0.)
644 throw Exception(
"stashPart : Invalid weight !");
646 int nbCoresAvailable(std::count(coresOn.begin(),coresOn.end(),
true));
648 if(nbCoresAvailable==0)
649 throw Exception(
"PartDefinition::stashPart : no available cores !");
650 if(nbCoresAvailable<=nbCoresStashed)
652 int n0((
int)(1./(1.+weightOfRemain)*nbCoresAvailable)); n0=std::max(n0,1);
653 int n1(nbCoresAvailable-n0);
661 std::vector<int> ids0(ids.begin(),ids.begin()+n0),ids1(ids.begin()+n0,ids.end());
668 std::vector<int> ids0(ids.begin(),ids.begin()+nbCoresStashed),ids1(ids.begin()+nbCoresStashed,ids.end());
680 return _pg->getWorkerIdsFullyFetchedBy(nbCoresPerComp,coresOn);
688 throw Exception(
"ContigPartDefinition constructor : Invalid input values");
697 std::ostringstream oss;
698 oss <<
"Contiguous : start=" <<
_start <<
" stop=" <<
_stop;
733 std::ostringstream oss;
734 oss <<
"Non contiguous : ";
735 for(std::vector<int>::const_iterator it=
_ids.begin();it!=
_ids.end();it++)
743 for(std::vector<int>::const_iterator it=
_ids.begin();it!=
_ids.end();it++)
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++)
770 throw Exception(
"checkOKIds : error 1 !");
771 if(
_ids[
i+1]>=maxVal)
772 throw Exception(
"checkOKIds : error 3 !");
784 std::ostringstream oss;
809 std::size_t sz(
_ids.size());
810 std::vector<int> ret(sz);
811 for(std::size_t
i=0;
i<sz;
i++)
AllPartDefinition(const PlayGround *pg)
int getNumberOfCoresConsumed() const
std::vector< bool > getCoresOn() const
AllPartDefinition * copy() const
std::string printSelf() const
int getNumberOfCoresConsumed() const
std::string printSelf() const
ContigPartDefinition * copy() const
std::vector< bool > getCoresOn() const
ContigPartDefinition(const PlayGround *pg, int zeStart, int zeStop)
std::vector< int > getIDS() const
std::vector< std::size_t > _ids
std::vector< bool > getCoresOn() const
std::string printSelf() const
NonContigPartDefinition * copy() const
int getNumberOfCoresConsumed() const
NonContigPartDefinition(const PlayGround *pg, const std::vector< int > &ids)
virtual std::vector< bool > getCoresOn() const =0
const PlayGround * getPlayGround() const
virtual PartDefinition * copy() const =0
virtual ~PartDefinition()
static YACS::BASES::AutoRefCnt< PartDefinition > BuildFrom(const PlayGround *pg, const std::vector< int > &coreIds)
std::vector< std::size_t > computeWorkerIdsCovered(int nbCoresPerComp) const
PartDefinition(const PlayGround *pg)
YACS::BASES::AutoConstRefCnt< PlayGround > _pg
void stashPart(int nbCoresStashed, double weightOfRemain, YACS::BASES::AutoRefCnt< PartDefinition > &pdStashed, YACS::BASES::AutoRefCnt< PartDefinition > &pdRemain) const
int getNumberOfCoresAvailable() const
void checkCoherentInfo() const
std::vector< Resource > _data
std::vector< std::size_t > allocateFor(std::size_t nbOfPlacesToTake, int nbCoresPerCont) const
int getCriticalPath(const std::vector< std::pair< const ComplexWeight *, int > > &weights, const std::vector< int > &maxNbOfCores) const
int getNumberOfWorkers(int nbCoresPerWorker) const
std::string deduceMachineFrom(int workerId, int nbProcPerNode) const
void loadFromKernelCatalog()
int getMaxNumberOfContainersCanBeHostedWithoutOverlap(int nbCoresPerCont) const
std::vector< std::pair< const ComplexWeight *, int > > bigToTiny(const std::vector< std::pair< const ComplexWeight *, int > > &weights, std::map< int, int > &saveOrder) const
void highlightOnIds(const std::vector< int > &coreIds, std::vector< bool > &v) const
static std::vector< int > GetIdsMatching(const std::vector< bool > &bigArr, const std::vector< bool > &pat)
void setData(const std::vector< std::pair< std::string, int > > &defOfRes)
void release(std::size_t workerId, int nbCoresPerCont) const
std::vector< YACS::BASES::AutoRefCnt< PartDefinition > > partition(const std::vector< std::pair< const PartDefinition *, const ComplexWeight * > > &parts, const std::vector< int > &nbCoresPerShot) const
static std::vector< int > BuildVectOfIdsFromVecBool(const std::vector< bool > &v)
std::vector< std::size_t > getWorkerIdsFullyFetchedBy(int nbCoresPerComp, const std::vector< bool > &coreFlags) const
int fromWorkerIdToResId(int workerId, int nbProcPerNode) const
std::string printSelf() const
std::vector< int > takePlace(int maxNbOfCoresToAlloc, int nbCoresPerShot, std::vector< bool > &distributionOfCores, bool lastOne=false) const
std::vector< std::vector< int > > backToOriginalOrder(const std::vector< std::vector< int > > &disorderVec, const std::map< int, int > &saveOrder) const
std::vector< std::vector< int > > splitIntoParts(const std::vector< int > &coreIds, const std::vector< std::pair< const ComplexWeight *, int > > &weights) const
std::vector< int > computeOffsets() const
std::size_t getNumberOfFreePlace(int nbCoresPerCont) const
std::vector< bool > _occupied
void printSelf(std::ostream &oss) const
void release(std::size_t workerId, int nbCoresPerCont) const
std::size_t getNumberOfFreePlace(int nbCoresPerCont) const
std::size_t getNumberOfWorkers(int nbCoresPerCont) const
std::vector< std::size_t > allocateFor(std::size_t &nbOfPlacesToTake, int nbCoresPerCont) const
YACSLIBENGINE_EXPORT Runtime * getRuntime()
def distance(node, new_node)