Salome HOME
cleaning useless part of algo
[modules/yacs.git] / src / engine / PlayGround.cxx
1 // Copyright (C) 2006-2017  CEA/DEN, EDF R&D
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 <algorithm>
29
30 using namespace YACS::ENGINE;
31
32 std::string PlayGround::printSelf() const
33 {
34   std::ostringstream oss;
35   std::size_t sz(0);
36   for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
37     sz=std::max(sz,(*it).first.length());
38   for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
39     {
40       oss << " - " << std::setw(10) << (*it).first << " : " << (*it).second << std::endl;
41     }
42   return oss.str();
43 }
44
45 void PlayGround::loadFromKernelCatalog()
46 {
47   Runtime *r(getRuntime());
48   if(!r)
49     throw Exception("PlayGround::loadFromKernelCatalog : no runtime  !");
50   std::vector< std::pair<std::string,int> > data(r->getCatalogOfComputeNodes());
51   setData(data);
52 }
53
54 void PlayGround::setData(const std::vector< std::pair<std::string,int> >& defOfRes)
55 {
56   _data=defOfRes;
57   checkCoherentInfo();
58 }
59
60 int PlayGround::getNumberOfCoresAvailable() const
61 {
62   int ret(0);
63   for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
64     ret+=(*it).second;
65   return ret;
66 }
67
68 int PlayGround::getMaxNumberOfContainersCanBeHostedWithoutOverlap(int nbCoresPerCont) const
69 {
70   if(nbCoresPerCont<1)
71     throw Exception("PlayGround::getMaxNumberOfContainersCanBeHostedWithoutOverlap : invalid nbCoresPerCont. Must be >=1 !");
72   int ret(0);
73   for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
74     ret+=(*it).second/nbCoresPerCont;
75   return ret;
76 }
77
78 std::vector<int> PlayGround::computeOffsets() const
79 {
80   std::size_t sz(_data.size()),i(0);
81   std::vector<int> ret(sz+1); ret[0]=0;
82   for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++,i++)
83     ret[i+1]=ret[i]+(*it).second;
84   return ret;
85 }
86
87 void PlayGround::checkCoherentInfo() const
88 {
89   std::set<std::string> s;
90   for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
91     {
92       s.insert((*it).first);
93       if((*it).second<0)
94         throw Exception("Presence of negative int value !");
95     }
96   if(s.size()!=_data.size())
97     throw Exception("host names entries must be different each other !");
98 }
99
100 std::vector<int> PlayGround::GetIdsMatching(const std::vector<bool>& bigArr, const std::vector<bool>& pat)
101 {
102   std::vector<int> ret;
103   std::size_t szp(pat.size());
104   std::size_t sz(bigArr.size()/szp);
105   for(std::size_t i=0;i<sz;i++)
106     {
107       std::vector<bool> t(bigArr.begin()+i*szp,bigArr.begin()+(i+1)*szp);
108       if(t==pat)
109         ret.push_back(i);
110     }
111   return ret;
112 }
113
114 std::vector<int> PlayGround::BuildVectOfIdsFromVecBool(const std::vector<bool>& v)
115 {
116   std::size_t sz(std::count(v.begin(),v.end(),true)),i(0);
117   std::vector<int> ret(sz);
118   std::vector<bool>::const_iterator it(v.begin());
119   while(i<sz)
120     {
121       it=std::find(it,v.end(),true);
122       ret[i++]=std::distance(v.begin(),it);
123       it++;
124     }
125   return ret;
126 }
127
128 void PlayGround::highlightOnIds(const std::vector<int>& coreIds, std::vector<bool>& v) const
129 {
130   if(v.size()!=getNumberOfCoresAvailable())
131     throw Exception("PlayGround::highlightOnIds : oops ! invalid size !");
132   for(std::vector<int>::const_iterator it=coreIds.begin();it!=coreIds.end();it++)
133     v[*it]=true;
134 }
135
136 /*! 
137  * you must garantee coherence between PlayGround::deduceMachineFrom, PlayGround::getNumberOfWorkers, and PartDefinition::computeWorkerIdsCovered
138  */
139 std::vector<bool> PlayGround::getFetchedCores(int nbCoresPerWorker) const
140 {
141   int nbCores(getNumberOfCoresAvailable());
142   std::vector<bool> ret(nbCores,false);
143   if(nbCoresPerWorker==1)
144     std::fill(ret.begin(),ret.end(),true);
145   else
146     {
147       std::size_t posBg(0);
148       for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
149         {
150           int nbElemsToPutOn(((*it).second/nbCoresPerWorker)*nbCoresPerWorker);
151           std::fill(ret.begin()+posBg,ret.begin()+posBg+nbElemsToPutOn,true);
152           posBg+=(*it).second;
153         }
154     }
155   return ret;
156 }
157 /*!
158  * follow getMaxNumberOfContainersCanBeHostedWithoutOverlap method
159  */
160 std::vector<std::size_t> PlayGround::getWorkerIdsFullyFetchedBy(int nbCoresPerComp, const std::vector<bool>& coreFlags) const
161 {
162   std::size_t posBg(0),posWorker(0);
163   std::vector<std::size_t> ret;
164   for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
165     {
166       int nbWorker((*it).second/nbCoresPerComp);
167       for(int j=0;j<nbWorker;j++,posWorker++)
168         {
169           std::vector<bool>::const_iterator it2(std::find(coreFlags.begin()+posBg+j*nbCoresPerComp,coreFlags.begin()+posBg+(j+1)*nbCoresPerComp,false));
170           if(it2==coreFlags.begin()+posBg+(j+1)*nbCoresPerComp)
171             ret.push_back(posWorker);
172         }
173       posBg+=(*it).second;
174     }
175   return ret;
176 }
177
178 std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > PlayGround::partition(const std::vector< std::pair<const PartDefinition *,double> >& parts) const
179 {
180   std::size_t sz(parts.size()),szs(getNumberOfCoresAvailable());
181   if(sz==0)
182     return std::vector< YACS::BASES::AutoRefCnt<PartDefinition> >();
183   if(sz==1)
184     {
185       const PartDefinition *pd(parts[0].first);
186       if(!pd)
187         throw Exception("Presence of null pointer as part def  0 !");
188       YACS::BASES::AutoRefCnt<PartDefinition> ret(pd->copy());
189       std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > ret2(1,ret);
190       return ret2;
191     }
192   if(sz>31)
193     throw Exception("PlayGround::partition : not implemented yet for more than 31 ! You need to pay for it :)");
194   std::vector<bool> zeArr(szs*sz,false);
195   std::size_t i(0);
196   for(std::vector< std::pair<const PartDefinition *,double> >::const_iterator it=parts.begin();it!=parts.end();it++,i++)
197     {
198       const PartDefinition *pd((*it).first);
199       if(!pd)
200         throw Exception("Presence of null pointer as part def !");
201       if(pd->getPlayGround()!=this)
202         throw Exception("Presence of non homogeneous playground !");
203       if((*it).second<=0.)
204         throw Exception("Invalid weight !");
205       std::vector<bool> bs(pd->getCoresOn());
206       for(std::size_t j=0;j<szs;j++)
207         zeArr[j*sz+i]=bs[j];
208     }
209   std::vector< std::vector<int> > retIds(sz);
210   for(std::size_t i=0;i<szs;i++)
211     {
212       std::vector<bool> code(zeArr.begin()+i*sz,zeArr.begin()+(i+1)*sz);
213       std::vector<int> locIds(GetIdsMatching(zeArr,code));
214       std::vector<int> partsIds(BuildVectOfIdsFromVecBool(code));
215       if(partsIds.empty())
216         continue;
217       std::vector<double> wg;
218       std::vector<int> nbCores2;
219       for(std::vector<int>::const_iterator it=partsIds.begin();it!=partsIds.end();it++)
220         {
221           wg.push_back(parts[*it].second);
222           nbCores2.push_back(parts[*it].first->getNbCoresPerCompo());
223         }
224       std::vector< std::vector<int> > ress(splitIntoParts(locIds,nbCores2,wg));
225       std::size_t k(0);
226       for(std::vector<int>::const_iterator it=partsIds.begin();it!=partsIds.end();it++,k++)
227         {
228           retIds[*it].insert(retIds[*it].end(),ress[k].begin(),ress[k].end());
229         }
230     }
231   //
232   std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > ret(sz);
233   for(std::size_t i=0;i<sz;i++)
234     {
235       std::set<int> s(retIds[i].begin(),retIds[i].end());
236       std::vector<int> v(s.begin(),s.end());
237       ret[i]=PartDefinition::BuildFrom(this,(parts[i].first)->getNbCoresPerCompo(),v);
238     }
239   return ret;
240 }
241
242 std::vector<int> sortArr(const std::vector<int>& v)
243 {
244   std::multimap<int,int> m;
245   int i(v.size()-1);
246   for(std::vector<int>::const_reverse_iterator it=v.rbegin();it!=v.rend();it++)
247     m.insert(std::pair<int,int>(*it,i--));
248   std::vector<int> ret(m.size());
249   i=0;
250   for(std::multimap<int,int>::const_reverse_iterator it=m.rbegin();it!=m.rend();it++)// reverse -> sort from biggest to the finest
251     ret[i++]=(*it).second;
252   return ret;
253 }
254
255 std::vector< std::vector<int> > PlayGround::splitIntoParts(const std::vector<int>& coreIds, const std::vector<int>& nbCoresConso, const std::vector<double>& weights) const
256 {
257   double wgs(std::accumulate(weights.begin(),weights.end(),0.));
258   std::size_t sz(nbCoresConso.size());
259   if(sz!=weights.size())
260     throw Exception("PlayGround::splitIntoParts : internal error !");
261   if(sz==0)
262     return std::vector< std::vector<int> >();
263   int totalSpace(coreIds.size());
264   std::vector< std::vector<int> > ret(sz);
265   std::vector<int> fromBigToTiny(sortArr(nbCoresConso));// start to treat the coarse grain to finish with fine grain
266   std::vector<bool> zeArr(getNumberOfCoresAvailable(),false);
267   highlightOnIds(coreIds,zeArr);
268   int nbOfCoresToSplit(coreIds.size());
269   std::size_t ii(fromBigToTiny.size());
270   for(std::vector<int>::const_iterator it=fromBigToTiny.begin();it!=fromBigToTiny.end();it++,ii--)
271     {
272       int maxNbOfCores((int)(totalSpace*weights[*it]/wgs));// now try to find in zeArr at most maxNbOfCores cores
273       ret[*it]=takePlace(maxNbOfCores,nbCoresConso[*it],zeArr,ii==1);
274     }
275   return ret;
276 }
277
278 std::vector<int> PlayGround::takePlace(int maxNbOfCoresToAlloc, int nbCoresPerShot, std::vector<bool>& distributionOfCores, bool lastOne) const
279 {
280   if(maxNbOfCoresToAlloc<1)
281     throw Exception("PlayGround::takePlace : internal error ! no space to alloc !");
282   int tmpMaxNbOfCoresToAlloc(maxNbOfCoresToAlloc);
283   if(lastOne)
284     tmpMaxNbOfCoresToAlloc=std::max(tmpMaxNbOfCoresToAlloc,(int)std::count(distributionOfCores.begin(),distributionOfCores.end(),true));
285   std::vector<int> ret;
286   std::vector<int> offsets(computeOffsets());
287   int nbFullItem(0);
288   std::size_t sz(offsets.size()-1);
289   for(std::size_t i=0;i<sz && tmpMaxNbOfCoresToAlloc>=nbCoresPerShot;i++)
290     {
291       int d(offsets[i+1]-offsets[i]);
292       if(nbCoresPerShot>d)
293         continue;
294       std::vector<bool> target(nbCoresPerShot,true);
295       for(int j=0;j<=d-nbCoresPerShot && tmpMaxNbOfCoresToAlloc>=nbCoresPerShot;)
296         {
297           std::vector<bool> t(distributionOfCores.begin()+offsets[i]+j,distributionOfCores.begin()+offsets[i]+j+nbCoresPerShot);
298           if(t==target)
299             {
300               nbFullItem++;
301               tmpMaxNbOfCoresToAlloc-=nbCoresPerShot;
302               std::fill(distributionOfCores.begin()+offsets[i]+j,distributionOfCores.begin()+offsets[i]+j+nbCoresPerShot,false);
303               for(int k=offsets[i]+j;k<offsets[i]+j+nbCoresPerShot;k++)
304                 ret.push_back(k);
305               j+=nbCoresPerShot;
306             }
307           else
308             j++;
309         }
310     }
311   if(nbFullItem>0)
312     return ret;
313   if(nbCoresPerShot<=1)
314     throw Exception("PlayGround::takePlace : internal error !");
315   // not enough contiguous place. Find the first wider contiguous place
316   for(int kk=std::min(nbCoresPerShot-1,tmpMaxNbOfCoresToAlloc);kk>=1;kk--)
317     {
318       for(std::size_t i=0;i<sz && tmpMaxNbOfCoresToAlloc>=kk;i++)
319         {
320           int d(offsets[i+1]-offsets[i]);
321           if(kk>d)
322             continue;
323           std::vector<bool> target(kk,true);
324           for(int j=0;j<=d-kk && tmpMaxNbOfCoresToAlloc>=kk;)
325             {
326               std::vector<bool> t(distributionOfCores.begin()+offsets[i]+j,distributionOfCores.begin()+offsets[i]+j+kk);
327               if(t==target)
328                 {
329                   nbFullItem++;
330                   tmpMaxNbOfCoresToAlloc-=kk;
331                   std::fill(distributionOfCores.begin()+offsets[i]+j,distributionOfCores.begin()+offsets[i]+j+kk,false);
332                   for(int k=offsets[i]+j;k<offsets[i]+j+kk;k++)
333                     ret.push_back(k);
334                   return ret;
335                 }
336               else
337                 j++;
338             }
339         }
340     }
341   throw Exception("PlayGround::takePlace : internal error ! All cores are occupied !");
342 }
343
344 int PlayGround::fromWorkerIdToResId(int workerId, int nbProcPerNode) const
345 {
346   std::size_t sz2(_data.size());
347   std::vector<int> deltas(sz2+1); deltas[0]=0;
348   for(std::size_t i=0;i<sz2;i++)
349     deltas[i+1]=deltas[i]+(_data[i].second)/nbProcPerNode;
350   int zePos(0);
351   while(zePos<sz2 && (workerId<deltas[zePos] || workerId>=deltas[zePos+1]))
352     zePos++;
353   if(zePos==sz2)
354     zePos=workerId%sz2;
355   return zePos;
356 }
357
358 /*! 
359  * you must garantee coherence between PlayGround::deduceMachineFrom, PlayGround::getNumberOfWorkers, and PartDefinition::computeWorkerIdsCovered
360  */
361 std::string PlayGround::deduceMachineFrom(int workerId, int nbProcPerNode) const
362 {
363   int zePos(fromWorkerIdToResId(workerId,nbProcPerNode));
364   return _data[zePos].first;
365 }
366
367 /*! 
368  * you must garantee coherence between PlayGround::deduceMachineFrom, PlayGround::getNumberOfWorkers, PlayGround::getFetchedCores and PartDefinition::computeWorkerIdsCovered
369  */
370 int PlayGround::getNumberOfWorkers(int nbCoresPerWorker) const
371 {
372   return getMaxNumberOfContainersCanBeHostedWithoutOverlap(nbCoresPerWorker);
373 }
374
375 PlayGround::~PlayGround()
376 {
377 }
378
379 //////////////////////
380
381 PartDefinition::PartDefinition(const PlayGround *pg, int nbOfCoresPerComp):_nbOfCoresPerComp(nbOfCoresPerComp)
382 {
383   _pg.takeRef(pg);
384 }
385
386 PartDefinition::PartDefinition(const PartDefinition& other):_pg(other._pg),_nbOfCoresPerComp(other._nbOfCoresPerComp)
387 {
388 }
389
390 PartDefinition::~PartDefinition()
391 {
392 }
393
394 std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > PartDefinition::partition(const std::vector< double >& wgs) const
395 {
396   std::size_t sz(wgs.size());
397   std::vector< std::pair<const PartDefinition *,double> > elts(sz);
398   for(std::size_t i=0;i<sz;i++)
399     elts[i]=std::pair<const PartDefinition *,double>(this,wgs[i]);
400   return getPlayGround()->partition(elts);
401 }
402
403 YACS::BASES::AutoRefCnt<PartDefinition> PartDefinition::BuildFrom(const PlayGround *pg, int nbOfCoresPerComp, const std::vector<int>& coreIds)
404 {
405   int spaceSz(pg->getNumberOfCoresAvailable()),sz(coreIds.size());
406   if(sz>spaceSz)
407     throw Exception("PartDefinition::BuildFrom : error 1 !");
408   if(sz==0)
409     throw Exception("PartDefinition::BuildFrom : error 2 !");
410   int zeStart(coreIds.front()),zeEnd(coreIds.back());
411   if(zeStart<0 || zeEnd<zeStart)
412     throw Exception("PartDefinition::BuildFrom : error ! The content of core Ids is not OK !");
413   for(std::size_t i=0;i<sz-1;i++)
414     if(coreIds[i+1]<coreIds[i])
415       throw Exception("PartDefinition::BuildFrom : error ! The content of core Ids is not OK 2 !");
416   if(zeEnd-zeStart+1!=sz)
417     {
418       YACS::BASES::AutoRefCnt<PartDefinition> pd(new NonContigPartDefinition(pg,nbOfCoresPerComp,coreIds));
419       return pd;
420     }
421   if(sz==spaceSz)
422     {
423       YACS::BASES::AutoRefCnt<PartDefinition> pd(new AllPartDefinition(pg,nbOfCoresPerComp));
424       return pd;
425     }
426   YACS::BASES::AutoRefCnt<PartDefinition> pd(new ContigPartDefinition(pg,nbOfCoresPerComp,zeStart,zeEnd+1));
427   return pd;
428 }
429
430 void PartDefinition::stashPart(int nbCoresStashed, double weightOfRemain, YACS::BASES::AutoRefCnt<PartDefinition>& pdStashed, YACS::BASES::AutoRefCnt<PartDefinition>& pdRemain) const
431 {
432   if(nbCoresStashed<=0)
433     throw Exception("stashPart : Invalid nbCoresStashed value !");
434   if(weightOfRemain<=0.)
435     throw Exception("stashPart : Invalid weight !");
436   std::vector<bool> coresOn(getCoresOn());
437   int nbCoresAvailable(std::count(coresOn.begin(),coresOn.end(),true));
438   std::vector<int> ids(PlayGround::BuildVectOfIdsFromVecBool(coresOn));
439   if(nbCoresAvailable==0)
440     throw Exception("PartDefinition::stashPart : no available cores !");
441   if(nbCoresAvailable<=nbCoresStashed)
442     {
443       int n0((int)(1./(1.+weightOfRemain)*nbCoresAvailable)); n0=std::max(n0,1);
444       int n1(nbCoresAvailable-n0);
445       if(n1<=0)
446         {
447           pdStashed=PartDefinition::BuildFrom(getPlayGround(),1,ids);
448           pdRemain=PartDefinition::BuildFrom(getPlayGround(),1,ids);
449         }
450       else
451         {
452           std::vector<int> ids0(ids.begin(),ids.begin()+n0),ids1(ids.begin()+n0,ids.end());
453           pdStashed=PartDefinition::BuildFrom(getPlayGround(),1,ids0);
454           pdRemain=PartDefinition::BuildFrom(getPlayGround(),1,ids1);
455         }
456     }
457   else
458     {
459       std::vector<int> ids0(ids.begin(),ids.begin()+nbCoresStashed),ids1(ids.begin()+nbCoresStashed,ids.end());
460       pdStashed=PartDefinition::BuildFrom(getPlayGround(),1,ids0);
461       pdRemain=PartDefinition::BuildFrom(getPlayGround(),1,ids1);
462     }
463 }
464
465 /*! 
466  * you must garantee coherence between PlayGround::deduceMachineFrom, PlayGround::getNumberOfWorkers, and PartDefinition::computeWorkerIdsCovered
467  */
468 std::vector<std::size_t> PartDefinition::computeWorkerIdsCovered(int nbCoresPerComp) const
469 {
470   std::vector<bool> coresOn(getCoresOn());
471   return _pg->getWorkerIdsFullyFetchedBy(nbCoresPerComp,coresOn);
472 }
473
474 //////////////////////
475
476 ContigPartDefinition::ContigPartDefinition(const PlayGround *pg, int nbOfCoresPerComp, int zeStart, int zeStop):PartDefinition(pg,nbOfCoresPerComp),_start(zeStart),_stop(zeStop)
477 {
478   if(_start<0 || _stop<_start || _stop>getSpaceSize())
479     throw Exception("ContigPartDefinition constructor : Invalid input values");
480 }
481
482 ContigPartDefinition::ContigPartDefinition(const ContigPartDefinition& other):PartDefinition(other),_start(other._start),_stop(other._stop)
483 {
484 }
485
486 std::string ContigPartDefinition::printSelf() const
487 {
488   std::ostringstream oss;
489   oss << "Contiguous : start=" << _start << " stop=" << _stop;
490   return oss.str();
491 }
492
493 std::vector<bool> ContigPartDefinition::getCoresOn() const
494 {
495   std::vector<bool> ret(getSpaceSize(),false);
496   for(int i=_start;i<_stop;i++)
497     ret[i]=true;
498   return ret;
499 }
500
501 ContigPartDefinition *ContigPartDefinition::copy() const
502 {
503   return new ContigPartDefinition(*this);
504 }
505
506 int ContigPartDefinition::getNumberOfCoresConsumed() const
507 {
508   return _stop-_start;
509 }
510
511 //////////////////////
512
513 NonContigPartDefinition::NonContigPartDefinition(const PlayGround *pg, int nbOfCoresPerComp, const std::vector<int>& ids):PartDefinition(pg,nbOfCoresPerComp),_ids(ids)
514 {
515   checkOKIds();
516 }
517
518 NonContigPartDefinition::NonContigPartDefinition(const ContigPartDefinition& other):PartDefinition(other)
519 {
520 }
521
522 std::string NonContigPartDefinition::printSelf() const
523 {
524   std::ostringstream oss;
525   oss << "Non contiguous : ";
526   for(std::vector<int>::const_iterator it=_ids.begin();it!=_ids.end();it++)
527     oss << *it << ", ";
528   return oss.str();
529 }
530
531 std::vector<bool> NonContigPartDefinition::getCoresOn() const
532 {
533   std::vector<bool> ret(getSpaceSize(),false);
534   for(std::vector<int>::const_iterator it=_ids.begin();it!=_ids.end();it++)
535     ret[*it]=true;
536   return ret;
537 }
538
539 NonContigPartDefinition *NonContigPartDefinition::copy() const
540 {
541   return new NonContigPartDefinition(*this);
542 }
543
544 int NonContigPartDefinition::getNumberOfCoresConsumed() const
545 {
546   return _ids.size();
547 }
548
549 void NonContigPartDefinition::checkOKIds() const
550 {
551   int maxVal(getSpaceSize());
552   if(_ids.empty())
553     return;
554   int val(_ids.front());
555   if(val<0 || val>=maxVal)
556     throw Exception("checkOKIds : error 2 !");
557   std::size_t sz(_ids.size());
558   for(std::size_t i=0;i<sz-1;i++)
559     {
560       if(_ids[i+1]<=_ids[i])
561         throw Exception("checkOKIds : error 1 !");
562       if(_ids[i+1]>=maxVal)
563         throw Exception("checkOKIds : error 3 !");
564     }
565 }
566
567 //////////////////////
568
569 AllPartDefinition::AllPartDefinition(const AllPartDefinition& other):PartDefinition(other)
570 {
571 }
572
573 std::string AllPartDefinition::printSelf() const
574 {
575   std::ostringstream oss;
576   oss << "All";
577   return oss.str();
578 }
579
580 std::vector<bool> AllPartDefinition::getCoresOn() const
581 {
582   std::vector<bool> ret(getSpaceSize(),true);
583   return ret;
584 }
585
586 AllPartDefinition *AllPartDefinition::copy() const
587 {
588   return new AllPartDefinition(*this);
589 }
590
591 int AllPartDefinition::getNumberOfCoresConsumed() const
592 {
593   return getSpaceSize();
594 }
595
596 //////////////////////
597  
598  std::vector<int> ForTestOmlyHPContCls::getIDS() const
599  {
600    std::size_t sz(_ids.size());
601    std::vector<int> ret(sz);
602    for(std::size_t i=0;i<sz;i++)
603      ret[i]=_ids[i];
604    return ret;
605  }