Salome HOME
Optimized algo for PlayGround
authorLauffenburger Thomas <thomas.lauffenburger@edf.fr>
Tue, 1 Aug 2017 09:06:05 +0000 (11:06 +0200)
committerLauffenburger Thomas <thomas.lauffenburger@edf.fr>
Wed, 13 Sep 2017 14:37:25 +0000 (16:37 +0200)
35 files changed:
src/engine/AbstractPoint.hxx
src/engine/BagPoint.cxx
src/engine/BagPoint.hxx
src/engine/Bloc.cxx
src/engine/Bloc.hxx
src/engine/Bloc_impl.cxx
src/engine/CMakeLists.txt
src/engine/DynParaLoop.cxx
src/engine/DynParaLoop.hxx
src/engine/ElementaryNode.cxx
src/engine/ElementaryNode.hxx
src/engine/ElementaryPoint.cxx
src/engine/ElementaryPoint.hxx
src/engine/ForkBlocPoint.cxx
src/engine/ForkBlocPoint.hxx
src/engine/LinkedBlocPoint.cxx
src/engine/LinkedBlocPoint.hxx
src/engine/Loop.cxx
src/engine/Loop.hxx
src/engine/Node.hxx
src/engine/PlayGround.cxx
src/engine/PlayGround.hxx
src/engine/SetOfPoints.cxx
src/engine/SetOfPoints.hxx
src/engine/Switch.cxx
src/engine/Switch.hxx
src/engine/VisitorSaveSchema.cxx
src/engine_swig/PlayGround.i
src/engine_swig/pilot.i
src/engine_swig/testPlayGround0.py
src/yacsloader/inlineParsers.hxx
src/yacsloader/loopParsers.hxx
src/yacsloader/remoteParsers.hxx
src/yacsloader_swig/Test/testHPDecorator.py
src/yacsloader_swig/Test/testSaveLoadRun.py

index 3b4f5dc6409d388c7cb4d819a343a58f9b5fd82d..2aceabfdfd03ac02505746ab48b4693c50293dc4 100644 (file)
@@ -67,7 +67,7 @@ namespace YACS
       virtual bool contains(Node *node) = 0;
       virtual int getNumberOfNodes() const = 0;
       virtual int getMaxLevelOfParallelism() const = 0;
-      virtual double getWeightRegardingDPL() const = 0;
+      virtual void getWeightRegardingDPL(ComplexWeight *weight) = 0;
       virtual void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const = 0;
       virtual std::string getRepr() const = 0;
       virtual ~AbstractPoint();
index d7727a16dae9e651006fa4e10a08b3b93b1da6a3..2492813dfefd7c27bfbbce2256bcbc05b15b52cb 100644 (file)
@@ -79,9 +79,9 @@ int BagPoint::getMaxLevelOfParallelism() const
   return getUnique()->getMaxLevelOfParallelism();
 }
 
-double BagPoint::getWeightRegardingDPL() const
+void BagPoint::getWeightRegardingDPL(ComplexWeight *weight)
 {
-  return getUnique()->getWeightRegardingDPL();
+  getUnique()->getWeightRegardingDPL(weight);
 }
 
 void BagPoint::partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const
index 9568deb07f4377bf31372509d5581d568e5754ba..9e97acd25b72ca8c89c25da834410f75b0679317 100644 (file)
@@ -37,7 +37,7 @@ namespace YACS
       Node *getFirstNode();
       Node *getLastNode();
       int getMaxLevelOfParallelism() const;
-      double getWeightRegardingDPL() const;
+      void getWeightRegardingDPL(ComplexWeight *weight);
       void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const;
       std::string getRepr() const;
       AbstractPoint *getUniqueAndReleaseIt();
index 6fc3240abfa88716d1fb14d9d23e3654f04aaa64..9a2f4ff5089b854484086fd12ca1aa496b4c73a0 100644 (file)
@@ -473,11 +473,11 @@ std::list< AbstractPoint * > Bloc::analyzeParallelism() const
   return pts;
 }
 
-double Bloc::getWeightRegardingDPL() const
+void Bloc::getWeightRegardingDPL(ComplexWeight *weight)
 {
   std::list< AbstractPoint * > pts(analyzeParallelism());
   ForkBlocPoint fbp(pts,NULL);
-  return fbp.getWeightRegardingDPL();
+  fbp.getWeightRegardingDPL(weight);
 }
 
 void Bloc::removeRecursivelyRedundantCL()
index 3759fc0947804cfd574397f876fd8178cd6a15ed..666cb3aba6b8d449bd406465ead82a5a37595cab 100644 (file)
@@ -66,7 +66,7 @@ namespace YACS
       void findAllNodesStartingFrom(Node *start, std::set<Node *>& result, std::map<Node *, std::set<Node *> >& accelStr, LinkInfo& info) const;
       virtual std::string typeName() { return "YACS__ENGINE__Bloc"; }
       int getMaxLevelOfParallelism() const;
-      double getWeightRegardingDPL() const;
+      void getWeightRegardingDPL(ComplexWeight *weight);
       void removeRecursivelyRedundantCL();
       void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap);
       void fitToPlayGround(const PlayGround *pg);
index 038be80f6f06942ab3e935bd7724be7e1273aff3..1a5ed1f72c64e6c63ec572843fee2514e7bc60d9 100644 (file)
@@ -84,11 +84,14 @@ void Bloc::fitToPlayGround(const PlayGround *pg)
       int _lev;
       int _max_lev;
   };
-  YACS::BASES::AutoRefCnt<PartDefinition> pd(new AllPartDefinition(pg,1));
+  YACS::BASES::AutoRefCnt<PartDefinition> pd(new AllPartDefinition(pg));
   std::map<ComposedNode *,YACS::BASES::AutoRefCnt<PartDefinition> > zeMap;
+  MyVisitor vis(this);
+  this->accept(&vis);
+  for(std::list<ForEachLoop *>::const_iterator it=vis._fes.begin();it!=vis._fes.end();it++)
+    (*it)->edGetNbOfBranchesPort()->edInit(1);
   this->removeRecursivelyRedundantCL();
   this->partitionRegardingDPL(pd,zeMap);
-  MyVisitor vis(this);
   this->accept(&vis);
   for(std::list<ForEachLoop *>::const_iterator it=vis._fes.begin();it!=vis._fes.end();it++)
     {
index b1f43ff38dbd73d31643641fb72d9fafbb3e363f..3e8442219f01d40121d2dbcff687cb2408940214 100644 (file)
@@ -44,6 +44,7 @@ SET(YACSlibEngine_HEADERS
   AnyInputPort.hxx
   Bloc.hxx
   Catalog.hxx
+  ComplexWeight.hxx
   ComponentDefinition.hxx
   ComponentInstance.hxx
   ComposedNode.hxx
@@ -181,6 +182,7 @@ SET(YACSlibEngine_SOURCES
   ElementaryPoint.cxx
   SetOfPoints.cxx
   PlayGround.cxx
+  ComplexWeight.cxx
   )
 SET(YACSlibEngine_HEADERS ${YACSlibEngine_HEADERS} PARENT_SCOPE)  # Make it visible to src/engine_swig to handle dependencies
 
index 632f72478c50835cdd4f4188feb26c10e77e8a9f..5197c49e19cba920b47931f553bbc28614e4cf3e 100644 (file)
@@ -44,8 +44,9 @@ const char DynParaLoop::NAME_OF_NUMBER_OF_BRANCHES[]="nbBranches";
 DynParaLoop::DynParaLoop(const std::string& name, TypeCode *typeOfDataSplitted)
   : ComposedNode(name),_node(0),_initNode(0),_finalizeNode(0),_nbOfEltConsumed(0),
     _nbOfBranches(NAME_OF_NUMBER_OF_BRANCHES,this,Runtime::_tc_int),
-    _splittedPort(NAME_OF_SPLITTED_SEQ_OUT,this,typeOfDataSplitted),_initializingCounter(0),_unfinishedCounter(0),_failedCounter(0),_weight(1.)
+    _splittedPort(NAME_OF_SPLITTED_SEQ_OUT,this,typeOfDataSplitted),_initializingCounter(0),_unfinishedCounter(0),_failedCounter(0),_weight(), _loopWeight(0)
 {
+  _weight.setDefaultLoop();
 }
 
 DynParaLoop::~DynParaLoop()
@@ -58,7 +59,7 @@ DynParaLoop::~DynParaLoop()
 DynParaLoop::DynParaLoop(const DynParaLoop& other, ComposedNode *father, bool editionOnly)
   : ComposedNode(other,father), _nbOfBranches(other._nbOfBranches,this),
     _splittedPort(other._splittedPort,this), _node(0), _initNode(0), _finalizeNode(0),
-    _nbOfEltConsumed(0),_initializingCounter(0),_unfinishedCounter(0),_failedCounter(0),_weight(1.)
+    _nbOfEltConsumed(0),_initializingCounter(0),_unfinishedCounter(0),_failedCounter(0),_weight(other._weight), _loopWeight(other._loopWeight)
 {
   if(other._node)
     _node=other._node->clone(this,editionOnly);
@@ -423,11 +424,18 @@ DynParaLoop::TypeOfNode DynParaLoop::getIdentityOfNotifyerNode(const Node *node,
       return FINALIZE_NODE;
 }
 
-void DynParaLoop::setWeight(double newVal)
+void DynParaLoop::setWeight(double loopWeight)
 {
-  if(newVal<=0.)
+  if(loopWeight<=0.)
     throw Exception("DynParaLoop::setWeight : invalid input value !");
-  _weight=newVal;
+  _loopWeight=loopWeight;
+}
+
+ComplexWeight* DynParaLoop::getWeight()
+{
+  if (_loopWeight>0.)
+    _weight.setLoopWeight(_loopWeight, _node->getMaxLevelOfParallelism()); // not done in setWeight because _node can be null at that time
+  return &_weight;     
 }
 
 bool DynParaLoop::isMultiplicitySpecified(unsigned& value) const
index 723b27e2ec43aeab81b29ccf62131d5512e9a11f..93bffd55dac59e5fac63c406e4f27a7208d03162 100644 (file)
@@ -57,7 +57,8 @@ namespace YACS
       int _initializingCounter;
       int _unfinishedCounter;
       int _failedCounter;
-      double _weight;
+      ComplexWeight _weight;
+      double _loopWeight;
     protected:
       static const char NAME_OF_SPLITTED_SEQ_OUT[];
       static const char OLD_NAME_OF_SPLITTED_SEQ_OUT[];
@@ -98,9 +99,9 @@ namespace YACS
       Node *getChildByShortName(const std::string& name) const throw(Exception);
       Node *getChildByNameExec(const std::string& name, unsigned id) const throw(Exception);
       std::vector<Node *> getNodes() const { return _execNodes; } // need to use in GUI part for adding observers for clone nodes
-      double getWeight() const { return _weight; }
-      void setWeight(double newVal);
-      double getWeightRegardingDPL() const { return getWeight(); }
+      ComplexWeight * getWeight();
+      void setWeight(double loopWeight);
+      void getWeightRegardingDPL(ComplexWeight *weight) {weight->addWeight(getWeight());}
       bool isMultiplicitySpecified(unsigned& value) const;
       void forceMultiplicity(unsigned value);
       virtual void checkBasicConsistency() const throw(Exception);
index 129deaa1d701bbbc0466d8e007ea257854cb7697..dff7963cca3a7bb5817652d10cb22db12938ab42 100644 (file)
@@ -47,11 +47,13 @@ using namespace std;
 ElementaryNode::ElementaryNode(const std::string& name):
   Node(name),
   _createDatastreamPorts(false),
-  _multi_port_node(false)
+  _multi_port_node(false),
+  _weight()
 {
+  _weight.setDefaultElementary();
 }
 
-ElementaryNode::ElementaryNode(const ElementaryNode& other, ComposedNode *father):Node(other,father)
+ElementaryNode::ElementaryNode(const ElementaryNode& other, ComposedNode *father):Node(other,father), _weight(other._weight)
 {
   _createDatastreamPorts = other._createDatastreamPorts;
   _multi_port_node = other._multi_port_node;
@@ -892,3 +894,10 @@ void ElementaryNode::getCoupledNodes(std::set<Task*>& coupledSet)
     }
 }
 
+void ElementaryNode::setWeight(double elementaryWeight)
+{
+  if(elementaryWeight<=0.)
+    throw Exception("ElementaryNode::setWeight : invalid input value !");
+  _weight.setElementaryWeight(elementaryWeight);
+}
+
index d2561e804f9335d7c5fa6a7ff8302b73f0f7e47e..e0c90889421840c6a50c21aeb0f9e93bdc9094cc 100644 (file)
@@ -48,6 +48,7 @@ namespace YACS
       std::list<OutputPort *> _setOfOutputPort;
       std::list<InputDataStreamPort *> _setOfInputDataStreamPort;
       std::list<OutputDataStreamPort *> _setOfOutputDataStreamPort;
+      ComplexWeight _weight;
 
       // Management of multi property
       bool _createDatastreamPorts;
@@ -107,7 +108,9 @@ namespace YACS
       virtual void ensureLoading();
 
       int getMaxLevelOfParallelism() const { return 1; }
-      double getWeightRegardingDPL() const { return 0.; }
+      ComplexWeight *getWeight() { return &_weight; }
+      void setWeight(double elementaryWeight);     
+      void getWeightRegardingDPL(ComplexWeight *weight) { weight->addWeight(getWeight()); }
       void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) { }
       
       //run part
index aeef403b426173094037f4619f71196877483d75..7d161b9c2952cf7ec2a2813a8049d944a56409a3 100644 (file)
@@ -59,9 +59,9 @@ int ElementaryPoint::getMaxLevelOfParallelism() const
   return _node->getMaxLevelOfParallelism();
 }
 
-double ElementaryPoint::getWeightRegardingDPL() const
+void ElementaryPoint::getWeightRegardingDPL(ComplexWeight *weight)
 {
-  return _node->getWeightRegardingDPL();
+  _node->getWeightRegardingDPL(weight);
 }
 
 void ElementaryPoint::partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const
index 08897e80afcdee7b98e6a0ba89a01ac09f6ad0da..f5ac56538e2d397ee3bb1b13fc18da4b492859b6 100644 (file)
@@ -43,7 +43,7 @@ namespace YACS
       Node *getLastNode();
       int getNumberOfNodes() const;
       int getMaxLevelOfParallelism() const;
-      double getWeightRegardingDPL() const;
+      void getWeightRegardingDPL(ComplexWeight *weight);
       void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const;
       std::string getRepr() const;
       virtual ~ElementaryPoint();
index 79d30fe6587729443d8034aab193ff925f5de3ac..8b8768f1c3813308fd7424a86e096a3b2bac9dd7 100644 (file)
@@ -54,50 +54,41 @@ int ForkBlocPoint::getMaxLevelOfParallelism() const
   return ret;
 }
 
-double ForkBlocPoint::getWeightRegardingDPL() const
+void ForkBlocPoint::getWeightRegardingDPL(ComplexWeight *weight)
 {
-  double ret(0.);
+  ComplexWeight localWeight;
   for(std::list<AbstractPoint *>::const_iterator it=_nodes.begin();it!=_nodes.end();it++)
-    ret+=(*it)->getWeightRegardingDPL();
-  return ret;
+  {
+    (*it)->getWeightRegardingDPL(&localWeight);
+    weight->addWeight(&localWeight);
+    localWeight.setToZero();
+  }
 }
 
 void ForkBlocPoint::partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const
 {
-  std::vector< std::pair<const PartDefinition *,double> > parts,parts2;
-  std::vector<std::size_t> v,v2;
+  std::vector< std::pair<const PartDefinition *, const ComplexWeight *> > parts;
+  std::vector< int> nbCoresPerShot;
+  std::vector<std::size_t> v;
+  std::vector<ComplexWeight> nodesWeight(_nodes.size());
   std::size_t ii(0);
   for(std::list<AbstractPoint *>::const_iterator it=_nodes.begin();it!=_nodes.end();it++,ii++)
     {
-      double w((*it)->getWeightRegardingDPL());
-      if(w!=0.)
-        {
-          parts.push_back(std::pair<const PartDefinition *,double >(pd,w));
-          v.push_back(ii);
-        }
-      else
-        {
-          parts2.push_back(std::pair<const PartDefinition *,double >(pd,1.));
-          v2.push_back(ii);
-        }
+      ComplexWeight *w=&nodesWeight[ii];
+      (*it)->getWeightRegardingDPL(w);
+      parts.push_back(std::pair<const PartDefinition *, const ComplexWeight *>(pd,w));
+      nbCoresPerShot.push_back((*it)->getMaxLevelOfParallelism());
+      v.push_back(ii);
     }
   std::vector<AbstractPoint *> nodes2(_nodes.begin(),_nodes.end());
   if(!parts.empty())
     {
       const PlayGround *pg(pd->getPlayGround());
-      std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > pds(pg->partition(parts));
+      std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > pds(pg->partition(parts,nbCoresPerShot));
       ii=0;
       for(std::vector<std::size_t>::const_iterator iter=v.begin();iter!=v.end();iter++,ii++)
         nodes2[*iter]->partitionRegardingDPL(pds[ii],zeMap);
     }
-  if(!parts2.empty())
-    {
-      const PlayGround *pg(pd->getPlayGround());
-      std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > pds(pg->partition(parts2));
-      ii=0;
-      for(std::vector<std::size_t>::const_iterator iter=v2.begin();iter!=v2.end();iter++,ii++)
-        nodes2[*iter]->partitionRegardingDPL(pds[ii],zeMap);
-    }
 }
 
 std::string ForkBlocPoint::getRepr() const
index 0aa3fbf178b05c31cf0f5dfd94ec132a77e6cd3d..2c347caf21aebb1620b028247fd926ef89f418e3 100644 (file)
@@ -34,7 +34,7 @@ namespace YACS
       Node *getFirstNode();
       Node *getLastNode();
       int getMaxLevelOfParallelism() const;
-      double getWeightRegardingDPL() const;
+      void getWeightRegardingDPL(ComplexWeight *weight);
       void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const;
       std::string getRepr() const;
       virtual ~ForkBlocPoint();
index 666f757e5bbdbd809662c9b1e4ef7a829f2ce4b5..b4d2e7f2f116193d763a731d33de19a433b20565 100644 (file)
@@ -48,12 +48,15 @@ int LinkedBlocPoint::getMaxLevelOfParallelism() const
   return ret;
 }
 
-double LinkedBlocPoint::getWeightRegardingDPL() const
+void LinkedBlocPoint::getWeightRegardingDPL(ComplexWeight *weight)
 {
-  double ret(0.);
+  ComplexWeight localWeight;
   for(std::list<AbstractPoint *>::const_iterator it=_nodes.begin();it!=_nodes.end();it++)
-    ret=std::max(ret,(*it)->getWeightRegardingDPL());
-  return ret;
+  {
+    (*it)->getWeightRegardingDPL(&localWeight);
+    weight->addWeight(&localWeight);
+    localWeight.setToZero();
+  }
 }
 
 void LinkedBlocPoint::partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const
index 963ca24e02fb4515792ea9baf6d932de65bee3cd..3491ed40712fdf281faef1d4299b50f27bf015a3 100644 (file)
@@ -36,7 +36,7 @@ namespace YACS
       Node *getFirstNode();
       Node *getLastNode();
       int getMaxLevelOfParallelism() const;
-      double getWeightRegardingDPL() const;
+      void getWeightRegardingDPL(ComplexWeight *weight);
       void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const;
       std::string getRepr() const;
       virtual ~LinkedBlocPoint();
index cc4f089f96cb4f26f298f8d3ec891b39feedca7b..66d52d28d56f844b5214980dda21e69ad3bb3a7c 100644 (file)
@@ -419,11 +419,10 @@ int Loop::getMaxLevelOfParallelism() const
   return _node->getMaxLevelOfParallelism();
 }
 
-double Loop::getWeightRegardingDPL() const
+void Loop::getWeightRegardingDPL(ComplexWeight *weight)
 {
-  if(!_node)
-    return 0.;
-  return _node->getWeightRegardingDPL();
+  if(_node)
+    _node->getWeightRegardingDPL(weight);
 }
 
 void Loop::partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap)
index a1f533af060104aa9bb84297bc7052cc9fd0a2b8..cd691346a72167f3e95849d655f619118e06feea 100644 (file)
@@ -173,7 +173,7 @@ namespace YACS
       std::list<InputPort *> getSetOfInputPort() const;
       int getNumberOfInputPorts() const;
       int getMaxLevelOfParallelism() const;
-      double getWeightRegardingDPL() const;
+      void getWeightRegardingDPL(ComplexWeight *weight);
       void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap);
       Node *getChildByShortName(const std::string& name) const throw(Exception);
       static TypeCode* MappingDF2DS(TypeCode* type) throw(Exception);
index f379204821a7677a3385eca4e2ad5619a28bc625..15c51ab1c5408863cea27c9df0c3d73a0cb19d2c 100644 (file)
@@ -175,7 +175,7 @@ namespace YACS
       virtual const Proc *getProc() const;
       virtual void accept(Visitor *visitor) = 0;
       virtual int getMaxLevelOfParallelism() const = 0;
-      virtual double getWeightRegardingDPL() const = 0;
+      virtual void getWeightRegardingDPL(ComplexWeight *weight) = 0;
       virtual void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) = 0;
       std::string getQualifiedName() const;
       int getNumId();
index 4ed54568e9f62091e221629d88a903bf84891088..f28047937e3d563cc4a8445909fbc500ded85041 100644 (file)
@@ -29,6 +29,7 @@
 
 using namespace YACS::ENGINE;
 
+
 std::string PlayGround::printSelf() const
 {
   std::ostringstream oss;
@@ -136,24 +137,24 @@ void PlayGround::highlightOnIds(const std::vector<int>& coreIds, std::vector<boo
 /*! 
  * you must garantee coherence between PlayGround::deduceMachineFrom, PlayGround::getNumberOfWorkers, and PartDefinition::computeWorkerIdsCovered
  */
-std::vector<bool> PlayGround::getFetchedCores(int nbCoresPerWorker) const
-{
-  int nbCores(getNumberOfCoresAvailable());
-  std::vector<bool> ret(nbCores,false);
-  if(nbCoresPerWorker==1)
-    std::fill(ret.begin(),ret.end(),true);
-  else
-    {
-      std::size_t posBg(0);
-      for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
-        {
-          int nbElemsToPutOn(((*it).second/nbCoresPerWorker)*nbCoresPerWorker);
-          std::fill(ret.begin()+posBg,ret.begin()+posBg+nbElemsToPutOn,true);
-          posBg+=(*it).second;
-        }
-    }
-  return ret;
-}
+// std::vector<bool> PlayGround::getFetchedCores(int nbCoresPerWorker) const
+// {
+//   int nbCores(getNumberOfCoresAvailable());
+//   std::vector<bool> ret(nbCores,false);
+//   if(nbCoresPerWorker==1)
+//     std::fill(ret.begin(),ret.end(),true);
+//   else
+//     {
+//       std::size_t posBg(0);
+//       for(std::vector< std::pair<std::string,int> >::const_iterator it=_data.begin();it!=_data.end();it++)
+//         {
+//           int nbElemsToPutOn(((*it).second/nbCoresPerWorker)*nbCoresPerWorker);
+//           std::fill(ret.begin()+posBg,ret.begin()+posBg+nbElemsToPutOn,true);
+//           posBg+=(*it).second;
+//         }
+//     }
+//   return ret;
+//}
 /*!
  * follow getMaxNumberOfContainersCanBeHostedWithoutOverlap method
  */
@@ -175,9 +176,11 @@ std::vector<std::size_t> PlayGround::getWorkerIdsFullyFetchedBy(int nbCoresPerCo
   return ret;
 }
 
-std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > PlayGround::partition(const std::vector< std::pair<const PartDefinition *,double> >& parts) const
+std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > PlayGround::partition(const std::vector< std::pair<const PartDefinition *, const ComplexWeight *> >& parts, const std::vector< int>& nbCoresPerShot) const
 {
   std::size_t sz(parts.size()),szs(getNumberOfCoresAvailable());
+  if (sz!=nbCoresPerShot.size())
+    throw Exception("PlayGround::partition : incoherent vector size !");
   if(sz==0)
     return std::vector< YACS::BASES::AutoRefCnt<PartDefinition> >();
   if(sz==1)
@@ -193,35 +196,31 @@ std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > PlayGround::partition(con
     throw Exception("PlayGround::partition : not implemented yet for more than 31 ! You need to pay for it :)");
   std::vector<bool> zeArr(szs*sz,false);
   std::size_t i(0);
-  for(std::vector< std::pair<const PartDefinition *,double> >::const_iterator it=parts.begin();it!=parts.end();it++,i++)
+  for(std::vector< std::pair<const PartDefinition *, const ComplexWeight *> >::const_iterator it=parts.begin();it!=parts.end();it++,i++)
     {
       const PartDefinition *pd((*it).first);
       if(!pd)
         throw Exception("Presence of null pointer as part def !");
       if(pd->getPlayGround()!=this)
         throw Exception("Presence of non homogeneous playground !");
-      if((*it).second<=0.)
-        throw Exception("Invalid weight !");
-      std::vector<bool> bs(pd->getCoresOn());
+      std::vector<bool> bs(pd->getCoresOn()); // tab of length nbCores, with True or False for each Core
       for(std::size_t j=0;j<szs;j++)
-        zeArr[j*sz+i]=bs[j];
+        zeArr[j*sz+i]=bs[j]; // remplis une table avec les valeurs de bs. La table est [nb part] * [nb cores]
     }
   std::vector< std::vector<int> > retIds(sz);
   for(std::size_t i=0;i<szs;i++)
     {
-      std::vector<bool> code(zeArr.begin()+i*sz,zeArr.begin()+(i+1)*sz);
-      std::vector<int> locIds(GetIdsMatching(zeArr,code));
-      std::vector<int> partsIds(BuildVectOfIdsFromVecBool(code));
+      std::vector<bool> code(zeArr.begin()+i*sz,zeArr.begin()+(i+1)*sz);// vecteur contenant le true/false d'un coeur pour ttes les partitions
+      std::vector<int> locIds(GetIdsMatching(zeArr,code)); // liste des coeurs qui peuvent correspondre au pattern code
+      std::vector<int> partsIds(BuildVectOfIdsFromVecBool(code));// pour chaque partition retourne l'id de la premiere partition Ã  true
       if(partsIds.empty())
         continue;
-      std::vector<double> wg;
-      std::vector<int> nbCores2;
+      std::vector<std::pair <const ComplexWeight *, int> > wg;
       for(std::vector<int>::const_iterator it=partsIds.begin();it!=partsIds.end();it++)
         {
-          wg.push_back(parts[*it].second);
-          nbCores2.push_back(parts[*it].first->getNbCoresPerCompo());
+          wg.push_back(std::pair <const ComplexWeight *, int> (parts[*it].second, nbCoresPerShot[*it]));
         }
-      std::vector< std::vector<int> > ress(splitIntoParts(locIds,nbCores2,wg));
+      std::vector< std::vector<int> > ress(splitIntoParts(locIds,wg));
       std::size_t k(0);
       for(std::vector<int>::const_iterator it=partsIds.begin();it!=partsIds.end();it++,k++)
         {
@@ -234,47 +233,138 @@ std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > PlayGround::partition(con
     {
       std::set<int> s(retIds[i].begin(),retIds[i].end());
       std::vector<int> v(s.begin(),s.end());
-      ret[i]=PartDefinition::BuildFrom(this,(parts[i].first)->getNbCoresPerCompo(),v);
+      ret[i]=PartDefinition::BuildFrom(this,v);
     }
   return ret;
 }
 
-std::vector<int> sortArr(const std::vector<int>& v)
+std::vector< std::vector<int> > PlayGround::splitIntoParts(const std::vector<int>& coreIds, const std::vector< std::pair <const ComplexWeight *, int> >& weights) const
 {
-  std::multimap<int,int> m;
-  int i(v.size()-1);
-  for(std::vector<int>::const_reverse_iterator it=v.rbegin();it!=v.rend();it++)
-    m.insert(std::pair<int,int>(*it,i--));
-  std::vector<int> ret(m.size());
-  i=0;
-  for(std::multimap<int,int>::const_reverse_iterator it=m.rbegin();it!=m.rend();it++)// reverse -> sort from biggest to the finest
-    ret[i++]=(*it).second;
-  return ret;
-}
-
-std::vector< std::vector<int> > PlayGround::splitIntoParts(const std::vector<int>& coreIds, const std::vector<int>& nbCoresConso, const std::vector<double>& weights) const
-{
-  double wgs(std::accumulate(weights.begin(),weights.end(),0.));
-  std::size_t sz(nbCoresConso.size());
-  if(sz!=weights.size())
-    throw Exception("PlayGround::splitIntoParts : internal error !");
+  std::size_t sz(weights.size());
   if(sz==0)
     return std::vector< std::vector<int> >();
-  int totalSpace(coreIds.size());
-  std::vector< std::vector<int> > ret(sz);
-  std::vector<int> fromBigToTiny(sortArr(nbCoresConso));// start to treat the coarse grain to finish with fine grain
+  std::vector< std::vector<int> > ret;
+  std::vector< std::vector<int> > disorderRet(sz);
   std::vector<bool> zeArr(getNumberOfCoresAvailable(),false);
   highlightOnIds(coreIds,zeArr);
   int nbOfCoresToSplit(coreIds.size());
-  std::size_t ii(fromBigToTiny.size());
-  for(std::vector<int>::const_iterator it=fromBigToTiny.begin();it!=fromBigToTiny.end();it++,ii--)
+  int totalSpace(coreIds.size());
+  int remainingSpace(totalSpace);
+  std::vector<int> nbOfCoresAllocated(sz);
+  std::vector<int> nbCoresPerShot(sz,-1);  
+  // first every other branchs take its minimal part of the cake
+  // and remove branch without valid weight
+  int i(0);
+  std::map<int,int> saveOrder;
+  const std::vector< std::pair <const ComplexWeight *, int> > sortedWeights(bigToTiny(weights, saveOrder));
+  for(std::vector<std::pair <const ComplexWeight *, int> >::const_iterator it=sortedWeights.begin();it!=sortedWeights.end();it++,i++)
+    {
+      nbCoresPerShot[i]=(*it).second;
+      if ((*it).first->isUnsetLoopWeight())
+        {
+         nbOfCoresAllocated[i]=nbCoresPerShot[i]; // branch with only elementary nodes
+        }
+      else if (!(*it).first->hasValidLoopWeight())
+        {
+          nbOfCoresAllocated[i]=(int)((double)totalSpace/(double)(sz)); // branch with undefined weight
+        }
+      else
+        {
+          nbOfCoresAllocated[i]=nbCoresPerShot[i];
+        }
+    }
+  remainingSpace-=std::accumulate(nbOfCoresAllocated.begin(), nbOfCoresAllocated.end(), 0);
+  //get critical path (between path with loopWeight)
+  int criticalPathRank=getCriticalPath(sortedWeights, nbOfCoresAllocated);
+  if (criticalPathRank!=-1)
     {
-      int maxNbOfCores((int)(totalSpace*weights[*it]/wgs));// now try to find in zeArr at most maxNbOfCores cores
-      ret[*it]=takePlace(maxNbOfCores,nbCoresConso[*it],zeArr,ii==1);
+      // add cores to critical path while enough cores are availables
+         while (remainingSpace >= nbCoresPerShot[criticalPathRank])
+           {
+             nbOfCoresAllocated[criticalPathRank]+=nbCoresPerShot[criticalPathRank];
+             remainingSpace-=nbCoresPerShot[criticalPathRank];
+             criticalPathRank=getCriticalPath(sortedWeights, nbOfCoresAllocated);
+           }
+         //fill other paths with remaining cores (if possible) (reuse fromBigToTiny here?)
+         // and takePlace
+         int coresToAdd;
+         int j(0);
+         for(std::vector<int>::iterator it=nbOfCoresAllocated.begin();it!=nbOfCoresAllocated.end();it++,j++)
+           {
+             coresToAdd=((int)(remainingSpace/nbCoresPerShot[j]))*nbCoresPerShot[j];
+             *it+=coresToAdd;
+             remainingSpace-=coresToAdd;
+           }
     }
+  int k(0);
+  for(std::vector<int>::iterator it=nbOfCoresAllocated.begin();it!=nbOfCoresAllocated.end();it++,k++)
+    {
+      disorderRet[k]=takePlace(*it,nbCoresPerShot[k],zeArr,k==(sz-1));
+    }   
+  ret=backToOriginalOrder(disorderRet, saveOrder);
   return ret;
 }
 
+std::vector< std::pair <const ComplexWeight *, int> > PlayGround::bigToTiny(const std::vector< std::pair <const ComplexWeight *, int> > &weights, std::map<int,int> &saveOrder) const
+{
+  int maxCoresPerShot(0), rankMax(0);
+  int i(0);
+  std::vector< std::pair <const ComplexWeight *, int> > ret;
+  std::size_t sz(weights.size());
+  while (ret.size()<sz)
+    {
+      for(std::vector<std::pair <const ComplexWeight *, int> >::const_iterator it=weights.begin();it!=weights.end();it++,i++)
+        {
+          if ((maxCoresPerShot<(*it).second) && (saveOrder.find(i)==saveOrder.end()))
+            {
+              maxCoresPerShot=(*it).second;
+              rankMax=i;
+            }
+        }
+      ret.push_back(std::pair <const ComplexWeight *, int>(weights[rankMax].first,weights[rankMax].second));
+      saveOrder[rankMax]=ret.size()-1;
+      maxCoresPerShot=0;
+      i=0;
+    }
+  return ret;  
+}
+
+std::vector< std::vector<int> > PlayGround::backToOriginalOrder(const std::vector< std::vector<int> > &disorderVec, const std::map<int,int> &saveOrder) const
+{
+  std::vector< std::vector<int> > ret;
+  std::size_t sz(disorderVec.size());
+  if (disorderVec.size()!=saveOrder.size())
+    throw Exception("PlayGround::backToOriginalOrder : incoherent vector size !");
+  for (int i=0; i<sz; i++)
+      ret.push_back(disorderVec[saveOrder.at(i)]);
+  return ret;
+}
+
+int PlayGround::getCriticalPath(const std::vector<std::pair <const ComplexWeight *, int > >& weights, const std::vector<int>& nbOfCoresAllocated) const
+{
+  double maxWeight(0.);
+  double pathWeight(0.);
+  int rankMaxPath(-1);
+  if ((weights.size()!=nbOfCoresAllocated.size()) || (weights.size()==0))
+    throw Exception("PlayGround::getCriticalPath : internal error !");
+  int i=0;
+  for(std::vector<std::pair <const ComplexWeight *, int> >::const_iterator it=weights.begin();it!=weights.end();it++,i++)
+    {
+      if (nbOfCoresAllocated[i]==0)
+        throw Exception("PlayGround::getCriticalPath : nbOfCoresAllocated is null! error !");
+      if (!(*it).first->isDefaultValue())
+        {
+             pathWeight=(*it).first->calculateTotalLength(nbOfCoresAllocated[i]);
+             if (pathWeight > maxWeight)
+               {
+                 maxWeight=pathWeight;
+                 rankMaxPath=i;
+               }
+        }        
+    }
+  return rankMaxPath;
+} 
+
 std::vector<int> PlayGround::takePlace(int maxNbOfCoresToAlloc, int nbCoresPerShot, std::vector<bool>& distributionOfCores, bool lastOne) const
 {
   if(maxNbOfCoresToAlloc<1)
@@ -378,12 +468,12 @@ PlayGround::~PlayGround()
 
 //////////////////////
 
-PartDefinition::PartDefinition(const PlayGround *pg, int nbOfCoresPerComp):_nbOfCoresPerComp(nbOfCoresPerComp)
+PartDefinition::PartDefinition(const PlayGround *pg)
 {
   _pg.takeRef(pg);
 }
 
-PartDefinition::PartDefinition(const PartDefinition& other):_pg(other._pg),_nbOfCoresPerComp(other._nbOfCoresPerComp)
+PartDefinition::PartDefinition(const PartDefinition& other):_pg(other._pg)
 {
 }
 
@@ -391,16 +481,16 @@ PartDefinition::~PartDefinition()
 {
 }
 
-std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > PartDefinition::partition(const std::vector< double >& wgs) const
-{
-  std::size_t sz(wgs.size());
-  std::vector< std::pair<const PartDefinition *,double> > elts(sz);
-  for(std::size_t i=0;i<sz;i++)
-    elts[i]=std::pair<const PartDefinition *,double>(this,wgs[i]);
-  return getPlayGround()->partition(elts);
-}
+// std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > PartDefinition::partition(const std::vector< const ComplexWeight *>& wgs) const
+// {
+//   std::size_t sz(wgs.size());
+//   std::vector< std::pair<const PartDefinition *, const ComplexWeight *> > elts(sz);
+//   for(std::size_t i=0;i<sz;i++)
+//     elts[i]=std::pair<const PartDefinition *, const ComplexWeight *>(this,wgs[i]);
+//   return getPlayGround()->partition(elts);
+// }
 
-YACS::BASES::AutoRefCnt<PartDefinition> PartDefinition::BuildFrom(const PlayGround *pg, int nbOfCoresPerComp, const std::vector<int>& coreIds)
+YACS::BASES::AutoRefCnt<PartDefinition> PartDefinition::BuildFrom(const PlayGround *pg, const std::vector<int>& coreIds)
 {
   int spaceSz(pg->getNumberOfCoresAvailable()),sz(coreIds.size());
   if(sz>spaceSz)
@@ -415,15 +505,15 @@ YACS::BASES::AutoRefCnt<PartDefinition> PartDefinition::BuildFrom(const PlayGrou
       throw Exception("PartDefinition::BuildFrom : error ! The content of core Ids is not OK 2 !");
   if(zeEnd-zeStart+1!=sz)
     {
-      YACS::BASES::AutoRefCnt<PartDefinition> pd(new NonContigPartDefinition(pg,nbOfCoresPerComp,coreIds));
+      YACS::BASES::AutoRefCnt<PartDefinition> pd(new NonContigPartDefinition(pg,coreIds));
       return pd;
     }
   if(sz==spaceSz)
     {
-      YACS::BASES::AutoRefCnt<PartDefinition> pd(new AllPartDefinition(pg,nbOfCoresPerComp));
+      YACS::BASES::AutoRefCnt<PartDefinition> pd(new AllPartDefinition(pg));
       return pd;
     }
-  YACS::BASES::AutoRefCnt<PartDefinition> pd(new ContigPartDefinition(pg,nbOfCoresPerComp,zeStart,zeEnd+1));
+  YACS::BASES::AutoRefCnt<PartDefinition> pd(new ContigPartDefinition(pg,zeStart,zeEnd+1));
   return pd;
 }
 
@@ -444,21 +534,21 @@ void PartDefinition::stashPart(int nbCoresStashed, double weightOfRemain, YACS::
       int n1(nbCoresAvailable-n0);
       if(n1<=0)
         {
-          pdStashed=PartDefinition::BuildFrom(getPlayGround(),1,ids);
-          pdRemain=PartDefinition::BuildFrom(getPlayGround(),1,ids);
+          pdStashed=PartDefinition::BuildFrom(getPlayGround(),ids);
+          pdRemain=PartDefinition::BuildFrom(getPlayGround(),ids);
         }
       else
         {
           std::vector<int> ids0(ids.begin(),ids.begin()+n0),ids1(ids.begin()+n0,ids.end());
-          pdStashed=PartDefinition::BuildFrom(getPlayGround(),1,ids0);
-          pdRemain=PartDefinition::BuildFrom(getPlayGround(),1,ids1);
+          pdStashed=PartDefinition::BuildFrom(getPlayGround(),ids0);
+          pdRemain=PartDefinition::BuildFrom(getPlayGround(),ids1);
         }
     }
   else
     {
       std::vector<int> ids0(ids.begin(),ids.begin()+nbCoresStashed),ids1(ids.begin()+nbCoresStashed,ids.end());
-      pdStashed=PartDefinition::BuildFrom(getPlayGround(),1,ids0);
-      pdRemain=PartDefinition::BuildFrom(getPlayGround(),1,ids1);
+      pdStashed=PartDefinition::BuildFrom(getPlayGround(),ids0);
+      pdRemain=PartDefinition::BuildFrom(getPlayGround(),ids1);
     }
 }
 
@@ -473,7 +563,7 @@ std::vector<std::size_t> PartDefinition::computeWorkerIdsCovered(int nbCoresPerC
 
 //////////////////////
 
-ContigPartDefinition::ContigPartDefinition(const PlayGround *pg, int nbOfCoresPerComp, int zeStart, int zeStop):PartDefinition(pg,nbOfCoresPerComp),_start(zeStart),_stop(zeStop)
+ContigPartDefinition::ContigPartDefinition(const PlayGround *pg, int zeStart, int zeStop):PartDefinition(pg),_start(zeStart),_stop(zeStop)
 {
   if(_start<0 || _stop<_start || _stop>getSpaceSize())
     throw Exception("ContigPartDefinition constructor : Invalid input values");
@@ -510,7 +600,7 @@ int ContigPartDefinition::getNumberOfCoresConsumed() const
 
 //////////////////////
 
-NonContigPartDefinition::NonContigPartDefinition(const PlayGround *pg, int nbOfCoresPerComp, const std::vector<int>& ids):PartDefinition(pg,nbOfCoresPerComp),_ids(ids)
+NonContigPartDefinition::NonContigPartDefinition(const PlayGround *pg, const std::vector<int>& ids):PartDefinition(pg),_ids(ids)
 {
   checkOKIds();
 }
index 63236663a89436907f2baecf40cef9e65678c901..cd688aff8497d3fa6a406dc7e891d58469c20233 100644 (file)
 #include "YACSlibEngineExport.hxx"
 #include "RefCounter.hxx"
 #include "AutoRefCnt.hxx"
+#include "ComplexWeight.hxx"
 
 #include <vector>
 #include <string>
+#include <map>
 
 namespace YACS
 {
   namespace ENGINE
   {
-    class PartDefinition;
+    class PartDefinition;   
     
     class YACSLIBENGINE_EXPORT PlayGround : public RefCounter
     {
@@ -45,7 +47,7 @@ namespace YACS
       int getNumberOfCoresAvailable() const;
       int getMaxNumberOfContainersCanBeHostedWithoutOverlap(int nbCoresPerCont) const;
       std::vector<int> computeOffsets() const;
-      std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > partition(const std::vector< std::pair<const PartDefinition *,double> >& parts) const;
+      std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > partition(const std::vector< std::pair<const PartDefinition *, const ComplexWeight *> >& parts, const std::vector<int> &nbCoresPerShot) const;
       int fromWorkerIdToResId(int workerId, int nbProcPerNode) const;
       std::string deduceMachineFrom(int workerId, int nbProcPerNode) const;
       int getNumberOfWorkers(int nbCoresPerWorker) const;
@@ -55,7 +57,10 @@ namespace YACS
       static std::vector<int> BuildVectOfIdsFromVecBool(const std::vector<bool>& v);
       static std::vector<int> GetIdsMatching(const std::vector<bool>& bigArr, const std::vector<bool>& pat);
     private:
-      std::vector< std::vector<int> > splitIntoParts(const std::vector<int>& coreIds, const std::vector<int>& nbCoresConso, const std::vector<double>& weights) const;
+      std::vector< std::pair <const ComplexWeight *, int> > bigToTiny(const std::vector< std::pair <const ComplexWeight *, int> > &weights, std::map<int,int> &saveOrder) const;
+         std::vector< std::vector<int> > backToOriginalOrder(const std::vector< std::vector<int> > &disorderVec, const std::map<int,int> &saveOrder) const;
+         int getCriticalPath(const std::vector<std::pair <const ComplexWeight *, int > >& weights, const std::vector<int>& maxNbOfCores) 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> takePlace(int maxNbOfCoresToAlloc, int nbCoresPerShot, std::vector<bool>& distributionOfCores, bool lastOne=false) const;
     private:
       void checkCoherentInfo() const;
@@ -68,15 +73,13 @@ namespace YACS
     class YACSLIBENGINE_EXPORT PartDefinition : public RefCounter
     {
     protected:
-      PartDefinition(const PlayGround *pg, int nbOfCoresPerComp);
+      PartDefinition(const PlayGround *pg);
       PartDefinition(const PartDefinition& other);
       virtual ~PartDefinition();
     public:
-      std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > partition(const std::vector< double >& wgs) const;
-      static YACS::BASES::AutoRefCnt<PartDefinition> BuildFrom(const PlayGround *pg, int nbOfCoresPerComp, const std::vector<int>& coreIds);
+      //std::vector< YACS::BASES::AutoRefCnt<PartDefinition> > partition(const std::vector< const ComplexWeight *>& wgs) const;
+      static YACS::BASES::AutoRefCnt<PartDefinition> BuildFrom(const PlayGround *pg, const std::vector<int>& coreIds);
       const PlayGround *getPlayGround() const { return _pg; }
-      int getNbCoresPerCompo() const { return _nbOfCoresPerComp; }
-      void setNbCoresPerCompo(int newNbCores) { _nbOfCoresPerComp=newNbCores; }
       int getSpaceSize() const { return _pg->getNumberOfCoresAvailable(); }
       void stashPart(int nbCoresStashed, double weightOfRemain, YACS::BASES::AutoRefCnt<PartDefinition>& pdStashed, YACS::BASES::AutoRefCnt<PartDefinition>& pdRemain) const;
       std::vector<std::size_t> computeWorkerIdsCovered(int nbCoresPerComp) const;
@@ -86,13 +89,12 @@ namespace YACS
       virtual int getNumberOfCoresConsumed() const = 0;
     private:
       YACS::BASES::AutoConstRefCnt<PlayGround> _pg;
-      int _nbOfCoresPerComp;
     };
 
     class YACSLIBENGINE_EXPORT ContigPartDefinition : public PartDefinition
     {
     public:
-      ContigPartDefinition(const PlayGround *pg, int nbOfCoresPerComp, int zeStart, int zeStop);
+      ContigPartDefinition(const PlayGround *pg, int zeStart, int zeStop);
       ContigPartDefinition(const ContigPartDefinition& other);
       std::string printSelf() const;
       std::vector<bool> getCoresOn() const;
@@ -110,7 +112,7 @@ namespace YACS
     class YACSLIBENGINE_EXPORT NonContigPartDefinition : public PartDefinition
     {
     public:
-      NonContigPartDefinition(const PlayGround *pg, int nbOfCoresPerComp, const std::vector<int>& ids);
+      NonContigPartDefinition(const PlayGround *pg, const std::vector<int>& ids);
       NonContigPartDefinition(const ContigPartDefinition& other);
       std::string printSelf() const;
       std::vector<bool> getCoresOn() const;
@@ -127,7 +129,7 @@ namespace YACS
     class AllPartDefinition : public PartDefinition
     {
     public:
-      AllPartDefinition(const PlayGround *pg, int nbOfCoresPerComp):PartDefinition(pg,nbOfCoresPerComp) { }
+      AllPartDefinition(const PlayGround *pg):PartDefinition(pg) { }
       AllPartDefinition(const AllPartDefinition& other);
       std::string printSelf() const;
       std::vector<bool> getCoresOn() const;
index 39d787168b8b6f4ce8914b3701415e0f57565a3c..76f892577b9db0403fa5aaf0eae719728446d1d6 100644 (file)
@@ -87,9 +87,9 @@ int SetOfPoints::getMaxLevelOfParallelism() const
   return _bp->getMaxLevelOfParallelism();
 }
 
-double SetOfPoints::getWeightRegardingDPL() const
+void SetOfPoints::getWeightRegardingDPL(ComplexWeight *weight)
 {
-  return _bp->getWeightRegardingDPL();
+  _bp->getWeightRegardingDPL(weight);
 }
 
 void SetOfPoints::partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const
index d670ff692dc0c697f5335ad7a0e6398a3fc7cfc8..bc29934b0d56dbc94af04bbcb9c9113394237854 100644 (file)
@@ -47,7 +47,7 @@ namespace YACS
       AbstractPoint *findPointWithNode(Node *node);
       const std::list<AbstractPoint *>& getListOfPoints() const;
       int getMaxLevelOfParallelism() const;
-      double getWeightRegardingDPL() const;
+      void getWeightRegardingDPL(ComplexWeight *weight);
       void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const;
       AbstractPoint *getUniqueAndReleaseIt() const;
     private:
index 5c0b7a2d85cff08f0ad5489a6b2c4ddc82deea6a..99e6ba45ae1ca271e3643a563f67b16ca646540f 100644 (file)
@@ -408,12 +408,15 @@ int Switch::getMaxLevelOfParallelism() const
   return ret;
 }
 
-double Switch::getWeightRegardingDPL() const
+void Switch::getWeightRegardingDPL(ComplexWeight *weight)
 {
-  double ret(0);
+  ComplexWeight localWeight;
   for(std::map< int , Node * >::const_iterator it=_mapOfNode.begin();it!=_mapOfNode.end();it++)
-    ret=std::max(ret,((*it).second)->getWeightRegardingDPL());
-  return ret;
+  {
+    ((*it).second)->getWeightRegardingDPL(&localWeight);
+    weight->max(localWeight);
+    localWeight.setToZero();
+  }
 }
 
 void Switch::partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap)
index be5b1c16fcb03f78102f8094d0c87ad8d4f555ed..a635bdb417337f301f85705d165ec7a1d90b3e26 100644 (file)
@@ -116,7 +116,7 @@ namespace YACS
       void writeDot(std::ostream &os) const;
       int getNumberOfInputPorts() const;
       int getMaxLevelOfParallelism() const;
-      double getWeightRegardingDPL() const;
+      void getWeightRegardingDPL(ComplexWeight *weight);
       void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap);
       void edRemoveChild(Node *node) throw(Exception);
       std::list<InputPort *> getSetOfInputPort() const;
index 4e33796b94c1ecc2d5f8da76b066c73c4a50811a..cf7abb9a1e06ebc37d571d75df35db54ca6a4a8f 100644 (file)
@@ -134,7 +134,7 @@ void VisitorSaveSchema::visitForEachLoop(ForEachLoop *node)
     _out << " state=\"disabled\"";
   if (!nbranch->isEmpty())
     _out << " nbranch=\"" << nbranch->getIntValue() << "\"";
-  _out << " weight=\"" << node->getWeight() << "\"";
+  _out << " loopWeight=\"" << node->getWeight()->getSimpleLoopWeight() << "\"";
   if (node->edGetSamplePort())
     _out << " type=\"" << node->edGetSamplePort()->edGetType()->name() << "\"";
   _out << ">" << endl;
@@ -160,7 +160,7 @@ void VisitorSaveSchema::visitOptimizerLoop(OptimizerLoop *node)
     _out << " state=\"disabled\"";
   if (!nbranch->isEmpty())
     _out << " nbranch=\"" << nbranch->getIntValue() << "\"";
-  _out << " weight=\"" << node->getWeight() << "\"";
+  _out << " loopWeight=\"" << node->getWeight()->getSimpleLoopWeight() << "\"";
   _out << " lib=\"" << node->getAlgLib() << "\"";
   _out << " entry=\"" << node->getSymbol() << "\"";
   _out << ">" << endl;
@@ -227,7 +227,10 @@ void VisitorSaveSchema::visitInlineNode(InlineNode *node)
   if(node->getExecutionMode()==InlineNode::LOCAL_STR)
     _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
   else
-    _out << indent(depth) << "<remote name=\"" << node->getName() << "\"";
+    {
+      _out << indent(depth) << "<remote name=\"" << node->getName() << "\"";
+      _out << " elementaryWeight=\"" << node->getWeight()->getElementaryWeight() << "\"";
+    }
   if (node->getState() == YACS::DISABLED)
     _out << " state=\"disabled\">" << endl;
   else
@@ -264,7 +267,10 @@ void VisitorSaveSchema::visitInlineFuncNode(InlineFuncNode *node)
   if(node->getExecutionMode()==InlineNode::LOCAL_STR)
     _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
   else
-    _out << indent(depth) << "<remote name=\"" << node->getName() << "\"";
+    {
+      _out << indent(depth) << "<remote name=\"" << node->getName() << "\"";
+      _out << " elementaryWeight=\"" << node->getWeight()->getElementaryWeight() << "\"";
+    }
   if (node->getState() == YACS::DISABLED)
     _out << " state=\"disabled\">" << endl;
   else
index 859ed1fcb5d23622ea9a89c72a437583d5b2cfb7..e0b34f2540e9041e011a2697d54feb853397b1b4 100644 (file)
@@ -16,9 +16,9 @@
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-
-%template()              std::pair< YACS::ENGINE::PartDefinition *, double>;
-%template(vecppdd)       std::vector< std::pair< YACS::ENGINE::PartDefinition *, double> >;
+%include <std_vector.i>
+%template()              std::pair< YACS::ENGINE::PartDefinition *, YACS::ENGINE::ComplexWeight *>;
+%template(vecppdd)       std::vector< std::pair< YACS::ENGINE::PartDefinition *, YACS::ENGINE::ComplexWeight *> >;
 
 %newobject YACS::ENGINE::PlayGround::copy;
 
@@ -55,7 +55,7 @@ namespace YACS
   namespace ENGINE
   {
     class PartDefinition;
-
+    
     class PlayGround : public RefCounter
     {
     public:
@@ -75,13 +75,13 @@ namespace YACS
              return self->printSelf();
            }
 
-           std::vector< YACS::BASES::AutoRefCnt<YACS::ENGINE::PartDefinition> > partition(const std::vector< std::pair< YACS::ENGINE::PartDefinition *,double> >& parts) const
+           std::vector< YACS::BASES::AutoRefCnt<YACS::ENGINE::PartDefinition> > partition(const std::vector< std::pair< YACS::ENGINE::PartDefinition *, YACS::ENGINE::ComplexWeight *> >& parts, const std::vector<int> &nbCoresPerShot) const
            {
              std::size_t sz(parts.size());
-             std::vector< std::pair< const YACS::ENGINE::PartDefinition *,double> > partsCpp(sz);
+             std::vector< std::pair< const YACS::ENGINE::PartDefinition *, const YACS::ENGINE::ComplexWeight *> > partsCpp(sz);
              for(std::size_t i=0;i<sz;i++)
-               partsCpp[i]=std::pair<const YACS::ENGINE::PartDefinition *,double >(parts[i].first,parts[i].second);
-             return self->partition(partsCpp);
+               partsCpp[i]=std::pair<const YACS::ENGINE::PartDefinition *, const YACS::ENGINE::ComplexWeight *>(parts[i].first, parts[i].second);
+             return self->partition(partsCpp, nbCoresPerShot);
            }
          }
     private:
@@ -102,7 +102,7 @@ namespace YACS
     class ContigPartDefinition : public PartDefinition
     {
     public:
-      ContigPartDefinition(const PlayGround *pg, int nbOfCoresPerComp, int zeStart, int zeStop);
+      ContigPartDefinition(const PlayGround *pg, int zeStart, int zeStop);
       int getStart() const;
       int getStop() const;
       %extend
@@ -119,7 +119,7 @@ namespace YACS
     class NonContigPartDefinition : public PartDefinition
     {
     public:
-      NonContigPartDefinition(const PlayGround *pg, int nbOfCoresPerComp, const std::vector<int>& ids);
+      NonContigPartDefinition(const PlayGround *pg, const std::vector<int>& ids);
       std::vector<int> getIDs() const;
       %extend
          {
@@ -135,7 +135,7 @@ namespace YACS
     class AllPartDefinition : public PartDefinition
     {
     public:
-      AllPartDefinition(const PlayGround *pg, int nbOfCoresPerComp);
+      AllPartDefinition(const PlayGround *pg);
       %extend
          {
            std::string __str__() const
index 98a7296db3b0330b204bd02fc2a3b40e79146ec2..f0316e5f48418f9f28d4fa4c09f2b5ced5527432 100644 (file)
@@ -320,7 +320,7 @@ EXCEPTION(YACS::ENGINE::ExecutorSwig::waitPause)
           return (long)self;
     }
 }
-
+%include <ComplexWeight.hxx>
 %include <ElementaryNode.hxx>
 %include <InlineNode.hxx>
 %include <ServiceNode.hxx>
index 3128e212627c80efb214be677b1ad6bf1c464d74..df0509c5918510ccae9cc56bea8cdc2dd96374b1 100644 (file)
@@ -23,17 +23,18 @@ import unittest
 class TestPlayGround0(unittest.TestCase):
     def test0(self):
         pg=pilot.PlayGround([("a0",28),("a1",28),("a2",28)])
-        pd=pilot.ContigPartDefinition(pg,4,0,3*28)
-        res=pg.partition([(pd,1.),(pd,1.)])
+        pd=pilot.ContigPartDefinition(pg,0,3*28)
+        cw=pilot.ComplexWeight(0.,1.,4)
+        res=pg.partition([(pd,cw),(pd,cw)],[4,4])
         assert(len(res)==2)
         assert(isinstance(res[0],pilot.ContigPartDefinition))
         assert(isinstance(res[1],pilot.ContigPartDefinition))
-        assert(res[0].getStart()==0 and res[0].getStop()==40)
-        assert(res[1].getStart()==40 and res[1].getStop()==84)
+        assert(res[0].getStart()==0 and res[0].getStop()==44)
+        assert(res[1].getStart()==44 and res[1].getStop()==84)
         assert(sum([elt.getNumberOfCoresConsumed() for elt in res])==pg.getNumberOfCoresAvailable())
-        pd2=pilot.AllPartDefinition(pg,4)
+        pd2=pilot.AllPartDefinition(pg)
         assert(pd2.getNumberOfCoresConsumed()==84)
-        res=pg.partition([(pd2,1.),(pd2,1.),(pd2,1.)])
+        res=pg.partition([(pd2,cw),(pd2,cw),(pd2,cw)],[4,4,4])
         assert(len(res)==3)
         assert(isinstance(res[0],pilot.ContigPartDefinition))
         assert(isinstance(res[1],pilot.ContigPartDefinition))
@@ -43,7 +44,8 @@ class TestPlayGround0(unittest.TestCase):
         assert(res[2].getStart()==56 and res[2].getStop()==84)
         #
         pg.setData([("a0",2),("a1",8),("a2",8)])
-        res=pg.partition([(pilot.AllPartDefinition(pg,4),1.),(pilot.AllPartDefinition(pg,1),1.)])
+        cw2=pilot.ComplexWeight(0.,4.,1)
+        res=pg.partition([(pilot.AllPartDefinition(pg),cw),(pilot.AllPartDefinition(pg),cw)],[4,1])
         assert(len(res)==2)
         assert(isinstance(res[0],pilot.ContigPartDefinition))
         assert(isinstance(res[1],pilot.NonContigPartDefinition))
@@ -54,20 +56,24 @@ class TestPlayGround0(unittest.TestCase):
     def test1(self):
         """ test focused on complicated cut due to lack of cores"""
         pg=pilot.PlayGround([("a0",13)])
-        pd=pilot.ContigPartDefinition(pg,4,0,13)
-        res=pg.partition([(pd,1.),(pd,1.)])
+        pd=pilot.ContigPartDefinition(pg,0,13)
+        cw=pilot.ComplexWeight(0.,1.,4)
+        cw2=pilot.ComplexWeight(0.,2.,4)
+        res=pg.partition([(pd,cw),(pd,cw2)],[4,4])
         assert(len(res)==2)
         assert(isinstance(res[0],pilot.ContigPartDefinition) and isinstance(res[1],pilot.ContigPartDefinition))
         assert(res[0].getStart()==0 and res[0].getStop()==4)
         assert(res[1].getStart()==4 and res[1].getStop()==12)# 1 core lost
         #
-        pg=pilot.PlayGround([("a0",2),("a1",11)])
-        pd=pilot.ContigPartDefinition(pg,4,0,13)
-        res=pg.partition([(pd,1.),(pd,1.)])
+        pg=pilot.PlayGround([("a0",2),("a1",27)])
+        cw3=pilot.ComplexWeight(0.,20,1)
+        cw4=pilot.ComplexWeight(0.,1.,8)
+        pd=pilot.ContigPartDefinition(pg,0,29)
+        res=pg.partition([(pd,cw3),(pd,cw4)],[4,8])
         assert(len(res)==2)
         assert(isinstance(res[0],pilot.ContigPartDefinition) and isinstance(res[1],pilot.ContigPartDefinition))
-        assert(res[0].getStart()==2 and res[0].getStop()==6)
-        assert(res[1].getStart()==6 and res[1].getStop()==10)# 5 cores lost
+        assert(res[0].getStart()==10 and res[0].getStop()==26)
+        assert(res[1].getStart()==2 and res[1].getStop()==10)# 5 cores lost
         pass
     
     pass
index 0a6cedb5a036756bdfef5ba77fd207368f2533d5..9fd2d7393df8786bc3face21d4a94034fc7e96cc 100644 (file)
@@ -72,6 +72,7 @@ struct inlinetypeParser:public nodetypeParser<T>
       for (int i = 0; attr[i]; i += 2) 
       {
         if(std::string(attr[i]) == "name")this->name(attr[i+1]);
+        if(std::string(attr[i]) == "elementaryWeight")this->weight(atof(attr[i+1]));
         if(std::string(attr[i]) == "state")this->state(attr[i+1]);
       }
     }
@@ -81,6 +82,12 @@ struct inlinetypeParser:public nodetypeParser<T>
       _kind="";
       this->_state="";
       this->_container="";
+      this->_weight=-1.;
+    }
+  virtual void weight (const double& x)
+    {
+      DEBTRACE("elementary_weight: " << x )
+      _weight=x;
     }
   virtual void kind (const std::string& name)
     {
@@ -154,6 +161,7 @@ struct inlinetypeParser:public nodetypeParser<T>
       return this->_node;
     }
   std::string _kind;
+  double _weight;
 };
 
 template <class T> inlinetypeParser<T> inlinetypeParser<T>::inlineParser;
@@ -164,6 +172,7 @@ void inlinetypeParser<YACS::ENGINE::InlineNode*>::script (const myfunc& f)
   DEBTRACE( "inline_script: " << f._code )             
   _node=theRuntime->createScriptNode(_kind,_name);
   _node->setScript(f._code);
+  if(_weight>0)_node->setWeight(_weight);
 }
 
 template <>
@@ -174,6 +183,7 @@ void inlinetypeParser<YACS::ENGINE::InlineNode*>::function (const myfunc& f)
   fnode=theRuntime->createFuncNode(_kind,_name);
   fnode->setScript(f._code);
   fnode->setFname(f._name);
+  if(_weight>0)fnode->setWeight(_weight);
   _node=fnode;
 }
 
index db84e6ff144094528ebf5116156741eb12139b72..83abbc33d74dcee073f3f917e9cecb30a944424d 100644 (file)
@@ -506,7 +506,7 @@ struct foreachlooptypeParser:dynparalooptypeParser<T>
           if(std::string(attr[i]) == "name")name(attr[i+1]);
           if(std::string(attr[i]) == "state")this->state(attr[i+1]);
           if(std::string(attr[i]) == "nbranch")nbranch(atoi(attr[i+1]));
-          if(std::string(attr[i]) == "weight")weight(atof(attr[i+1]));
+          if(std::string(attr[i]) == "loopWeight")weight(atof(attr[i+1]));
           if(std::string(attr[i]) == "type")datatype(attr[i+1]);
         }
       postAttr();
@@ -514,7 +514,7 @@ struct foreachlooptypeParser:dynparalooptypeParser<T>
   virtual void pre ()
     {
       _nbranch=0;
-      _weight=1;
+      _weight=-1.;
       this->looptypeParser<T>::pre();
     }
   virtual void name (const std::string& name)
@@ -559,7 +559,7 @@ struct foreachlooptypeParser:dynparalooptypeParser<T>
       this->_cnode=theRuntime->createForEachLoop(_name,currentProc->typeMap[_datatype]);
       //set number of branches
       if(_nbranch > 0)this->_cnode->edGetNbOfBranchesPort()->edInit(_nbranch);
-      this->_cnode->setWeight(_weight);
+      if(_weight > 0)this->_cnode->setWeight(_weight);
       this->_cnodes.push_back(this->_cnode);
       currentProc->names.push_back(_fullname + '.');
     }
@@ -604,7 +604,7 @@ struct optimizerlooptypeParser:dynparalooptypeParser<T>
           if(std::string(attr[i]) == "name")name(attr[i+1]);
           if(std::string(attr[i]) == "state")this->state(attr[i+1]);
           if(std::string(attr[i]) == "nbranch")nbranch(atoi(attr[i+1]));
-          if(std::string(attr[i]) == "weight")weight(atof(attr[i+1]));
+          if(std::string(attr[i]) == "loopWeight")weight(atof(attr[i+1]));
           if(std::string(attr[i]) == "lib")lib(attr[i+1]);
           if(std::string(attr[i]) == "entry")entry(attr[i+1]);
           if(std::string(attr[i]) == "kind")kind(attr[i+1]);
@@ -614,7 +614,7 @@ struct optimizerlooptypeParser:dynparalooptypeParser<T>
   virtual void pre ()
     {
       _nbranch=0;
-      _weight=1;
+      _weight=-1.;
       this->looptypeParser<T>::pre();
     }
   virtual void name (const std::string& name)
@@ -650,7 +650,7 @@ struct optimizerlooptypeParser:dynparalooptypeParser<T>
       this->_cnode=theRuntime->createOptimizerLoop(_name,_lib,_entry,true,_kind, currentProc);
       //set number of branches
       if(_nbranch > 0)this->_cnode->edGetNbOfBranchesPort()->edInit(_nbranch);
-      this->_cnode->setWeight(_weight);
+      if(_weight > 0)this->_cnode->setWeight(_weight);
       this->_cnodes.push_back(this->_cnode);
       currentProc->names.push_back(_fullname + '.');
     }
index 6db9b35867246c556b0340e85e7c157c56c2a490..47ea6897a3c84d9fe0ffa87c0b7d35e191b8a183 100644 (file)
@@ -61,6 +61,7 @@ struct remotetypeParser:public inlinetypeParser<T>
       fnode->setScript(f._code);
       fnode->setFname(f._name);
       fnode->setExecutionMode("remote");
+      if (this->_weight>0)fnode->setWeight(this->_weight);
       this->_node=fnode;
     }
 
@@ -71,6 +72,7 @@ struct remotetypeParser:public inlinetypeParser<T>
       node=theRuntime->createScriptNode(this->_kind,this->_name);
       node->setScript(f._code);
       node->setExecutionMode("remote");
+      if (this->_weight>0)node->setWeight(this->_weight);
       this->_node=node;
     }
 
index aa15b60df74a734dcf2f036da15af3aae202801f..717654e442c6007dabbf503751d8935fe929d9d7 100644 (file)
@@ -65,6 +65,7 @@ class TestHPDecortator(unittest.TestCase):
         n1_1.edAddChild(n1_1_sc)
         n1_1_sc.setExecutionMode("remote")
         n1_1_sc.setScript("""3*i1""")
+        n1_1.setWeight(4.)
         i1_1_sc=n1_1_sc.edAddInputPort("i1",td)
         p.edAddLink(n1_1.edGetSamplePort(),i1_1_sc)
         n1_1_sc.setContainer(hp1)
@@ -72,8 +73,8 @@ class TestHPDecortator(unittest.TestCase):
         hp1.setProperty("nb_proc_per_node","1")
         hp4.setProperty("nb_proc_per_node","4")
         pg.setData([("m0",8),("m1",8),("m2",8),("m3",8)]) # virtual machine with 32 cores spread over 4 nodes
-        assert(n1_0.getWeight()==1.)
-        assert(n1_1.getWeight()==1.)
+        assert(n1_0.getWeight().getSimpleLoopWeight()==-1.)
+        assert(n1_1.getWeight().getSimpleLoopWeight()==4.)
         p.fitToPlayGround(pg)########### ZE CALL
         fyto=pilot.ForTestOmlyHPContCls()
         assert(hp4.getSizeOfPool()==8)# 32/4
@@ -104,25 +105,25 @@ class TestHPDecortator(unittest.TestCase):
         #############################
         #  Change weight of ForEach #
         #############################
-        n1_0.setWeight(2)
+        n1_0.setWeight(1)
         p.fitToPlayGround(pg)########### ZE CALL
         assert(hp4.getSizeOfPool()==8)# 32/4
         n1_0_sc.getContainer().forYourTestsOnly(fyto)
         assert(fyto.getContainerType()=="HPContainerShared")
         pd=fyto.getPD()
         assert(isinstance(pd,pilot.ContigPartDefinition))
-        assert(pd.getStart()==0 and pd.getStop()==21)
-        assert(fyto.getIDS()==(0,1,2,3,4))
+        assert(pd.getStart()==0 and pd.getStop()==16)
+        assert(fyto.getIDS()==(0,1,2,3))
         assert(hp1.getSizeOfPool()==32)# 32/1
         fyto=pilot.ForTestOmlyHPContCls()
         n1_1_sc.getContainer().forYourTestsOnly(fyto)
         assert(fyto.getContainerType()=="HPContainerShared")
         pd=fyto.getPD()
         assert(isinstance(pd,pilot.ContigPartDefinition))
-        assert(pd.getStart()==21 and pd.getStop()==32)
-        assert(fyto.getIDS()==(21,22,23,24,25,26,27,28,29,30,31))
-        assert(n1_0.edGetNbOfBranchesPort().getPyObj()==6)
-        assert(n1_1.edGetNbOfBranchesPort().getPyObj()==11)
+        assert(pd.getStart()==16 and pd.getStop()==32)
+        assert(fyto.getIDS()==(16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31))
+        assert(n1_0.edGetNbOfBranchesPort().getPyObj()==4)
+        assert(n1_1.edGetNbOfBranchesPort().getPyObj()==16)
         #
         fyto=pilot.ForTestOmlyHPContCls()
         n0.getContainer().forYourTestsOnly(fyto)
@@ -156,6 +157,7 @@ class TestHPDecortator(unittest.TestCase):
         p.edAddChild(n1_0)
         p.edAddCFLink(n0,n1_0)
         p.edAddLink(out0_0,n1_0.edGetSeqOfSamplesPort())
+        n1_0.setWeight(1.)
         ##
         n1_0_sc=r.createScriptNode("Salome","n1_0_sc")
         n1_0.edAddChild(n1_0_sc)
@@ -170,6 +172,7 @@ class TestHPDecortator(unittest.TestCase):
         p.edAddChild(n1_1)
         p.edAddCFLink(n0,n1_1)
         p.edAddLink(out0_0,n1_1.edGetSeqOfSamplesPort())
+        n1_1.setWeight(4.)
         ##
         n1_1_sc=r.createScriptNode("Salome","n1_1_sc")
         n1_1.edAddChild(n1_1_sc)
@@ -188,11 +191,11 @@ class TestHPDecortator(unittest.TestCase):
         ##
         hp1.setProperty("nb_proc_per_node","1")
         hp4.setProperty("nb_proc_per_node","4")
-        pg.setData([("m0",8),("m1",8),("m2",8),("m3",8)]) # virtual machine with 32 cores spread over 4 nodes
-        assert(n1_0.getWeight()==1.)
-        assert(n1_1.getWeight()==1.)
+        pg.setData([("m0",8),("m1",8),("m2",8),("m3",8),("m4",4)]) # virtual machine with 32 cores spread over 4 nodes
+        assert(n1_0.getWeight().getSimpleLoopWeight()==1.)
+        assert(n1_1.getWeight().getSimpleLoopWeight()==4.)
         p.fitToPlayGround(pg)########### ZE CALL
-        assert(hp4.getSizeOfPool()==8)# 32/4
+        assert(hp4.getSizeOfPool()==9)# 36/4
         fyto=pilot.ForTestOmlyHPContCls()
         n1_0_sc.getContainer().forYourTestsOnly(fyto)
         assert(fyto.getContainerType()=="HPContainerShared")
@@ -201,14 +204,14 @@ class TestHPDecortator(unittest.TestCase):
         assert(pd.getStart()==0 and pd.getStop()==16)
         assert(fyto.getIDS()==(0,1,2,3))
         #
-        assert(hp1.getSizeOfPool()==32)# 32/1
+        assert(hp1.getSizeOfPool()==36)# 36/1
         fyto=pilot.ForTestOmlyHPContCls()
         n1_1_sc.getContainer().forYourTestsOnly(fyto)
         assert(fyto.getContainerType()=="HPContainerShared")
         pd=fyto.getPD()
         assert(isinstance(pd,pilot.ContigPartDefinition))
-        assert(pd.getStart()==16 and pd.getStop()==32)
-        assert(fyto.getIDS()==(16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31))
+        assert(pd.getStart()==20 and pd.getStop()==36)
+        assert(fyto.getIDS()==(20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35))
         assert(n1_0.edGetNbOfBranchesPort().getPyObj()==4)
         assert(n1_1.edGetNbOfBranchesPort().getPyObj()==16)
         #
@@ -217,13 +220,13 @@ class TestHPDecortator(unittest.TestCase):
         assert(fyto.getContainerType()=="HPContainerShared")
         pd=fyto.getPD()
         assert(isinstance(pd,pilot.AllPartDefinition))
-        assert(list(fyto.getIDS())==range(8))
+        assert(list(fyto.getIDS())==range(9))
         fyto=pilot.ForTestOmlyHPContCls()
         n1_2.getContainer().forYourTestsOnly(fyto)
         assert(fyto.getContainerType()=="HPContainerShared")
         pd=fyto.getPD()
-        assert(isinstance(pd,pilot.AllPartDefinition))
-        assert(list(fyto.getIDS())==range(8))
+        assert(isinstance(pd,pilot.ContigPartDefinition))
+        assert(list(fyto.getIDS())==[4])
         pass
 
     @unittest.skip("requires 2 machines in catalog")
@@ -357,6 +360,165 @@ class TestHPDecortator(unittest.TestCase):
         assert(len(set(hp1.getKernelContainerNames()))==3)
         pass
     
+    def test4(self):
+        """ two branch whose on with one elementary node and on foreach"""
+        SALOMERuntime.RuntimeSALOME.setRuntime()
+        r=SALOMERuntime.getSALOMERuntime()
+        pg=pilot.PlayGround()
+        pg.loadFromKernelCatalog()
+        assert(len(pg.getData())!=0)
+        p=r.createProc("p0")
+        td=p.createType("double","double")
+        tdd=p.createSequenceTc("seqdouble","seqdouble",td)
+        hp1=p.createContainer("HP1","HPSalome")        
+        #
+        ##
+        n0=r.createScriptNode("Salome","n0")
+        n0.setExecutionMode("remote")
+        out0_0=n0.edAddOutputPort("o1",tdd)
+        n0.setScript("""o1=[float(i)+0.1 for i in range(1000)]""")
+        n0.setContainer(hp1)
+        p.edAddChild(n0)
+        #
+        b0 = r.createBloc("Bloc0")
+        p.edAddChild(b0)
+        p.edAddCFLink(n0,b0)
+        ##
+        n1_0=r.createForEachLoop("n1_0",td)
+        b0.edAddChild(n1_0)
+        p.edAddLink(out0_0,n1_0.edGetSeqOfSamplesPort())
+        n1_0.setWeight(10.)
+        ##
+        n1_0_sc=r.createScriptNode("Salome","n1_0_sc")
+        n1_0.edAddChild(n1_0_sc)
+        n1_0_sc.setExecutionMode("remote")
+        n1_0_sc.setScript("""2*i1""")
+        i1_0_sc=n1_0_sc.edAddInputPort("i1",td)
+        p.edAddLink(n1_0.edGetSamplePort(),i1_0_sc)
+        n1_0_sc.setContainer(hp1)
+        ##
+        n1_0_1=r.createScriptNode("Salome","n1_0_1")
+        n1_0_1.setExecutionMode("remote")
+        n1_0_1.setScript("""a=2""")
+        b0.edAddChild(n1_0_1)
+        p.edAddCFLink(n1_0,n1_0_1)
+        n1_0_1.setContainer(hp1)  
+        n1_0_1.setWeight(20.)        
+        ##
+        #
+        n1_1=r.createForEachLoop("n1_1",td)
+        p.edAddChild(n1_1)
+        p.edAddCFLink(n0,n1_1)
+        p.edAddLink(out0_0,n1_1.edGetSeqOfSamplesPort())
+        n1_1.setWeight(100.)
+        ##
+        n1_1_sc=r.createScriptNode("Salome","n1_1_sc")
+        n1_1.edAddChild(n1_1_sc)
+        n1_1_sc.setExecutionMode("remote")
+        n1_1_sc.setScript("""3*i1""")
+        i1_1_sc=n1_1_sc.edAddInputPort("i1",td)
+        p.edAddLink(n1_1.edGetSamplePort(),i1_1_sc)
+        n1_1_sc.setContainer(hp1)
+        
+        hp1.setProperty("nb_proc_per_node","1")
+        pg.setData([("m0",12)])
+        w=pilot.ComplexWeight()
+        b0.getWeightRegardingDPL(w)
+        assert(w.getElementaryWeight()==20.)
+        assert(w.calculateTotalLength(1)==30.)
+        assert(w.calculateTotalLength(2)==25.)
+        p.fitToPlayGround(pg)########### ZE CALL
+        assert(n1_0.edGetNbOfBranchesPort().getPyObj()==7)
+        assert(n1_1.edGetNbOfBranchesPort().getPyObj()==5)
+        #
+        fyto=pilot.ForTestOmlyHPContCls()
+        n1_0_sc.getContainer().forYourTestsOnly(fyto)
+        assert(fyto.getContainerType()=="HPContainerShared")
+        pd=fyto.getPD()
+        assert(isinstance(pd,pilot.ContigPartDefinition))
+        print (pd.getStart(),pd.getStop())
+        assert(pd.getStart()==0 and pd.getStop()==7)
+        
+        #########################
+        ## change HPcontainer
+        ## very important: if you change HPcontainer you have to reload the graph
+        #########################
+        p=r.createProc("p0")
+        n0=r.createScriptNode("Salome","n0")
+        n0.setExecutionMode("remote")
+        out0_0=n0.edAddOutputPort("o1",tdd)
+        n0.setScript("""o1=[float(i)+0.1 for i in range(1000)]""")
+        n0.setContainer(hp1)
+        p.edAddChild(n0)
+        #
+        b0 = r.createBloc("Bloc0")
+        p.edAddChild(b0)
+        p.edAddCFLink(n0,b0)
+        ##
+        n1_0=r.createForEachLoop("n1_0",td)
+        b0.edAddChild(n1_0)
+        p.edAddLink(out0_0,n1_0.edGetSeqOfSamplesPort())
+        ##
+        n1_0_sc=r.createScriptNode("Salome","n1_0_sc")
+        n1_0.edAddChild(n1_0_sc)
+        n1_0_sc.setExecutionMode("remote")
+        n1_0_sc.setScript("""2*i1""")
+        i1_0_sc=n1_0_sc.edAddInputPort("i1",td)
+        p.edAddLink(n1_0.edGetSamplePort(),i1_0_sc)
+        n1_0_sc.setContainer(hp1)
+        ##
+        n1_0_1=r.createForEachLoop("n1_0_1",td)
+        b0.edAddChild(n1_0_1)
+        p.edAddLink(out0_0,n1_0_1.edGetSeqOfSamplesPort())
+        p.edAddCFLink(n1_0,n1_0_1)
+        ##
+        n1_0_1sc=r.createScriptNode("Salome","n1_0_1sc")
+        n1_0_1.edAddChild(n1_0_1sc)
+        n1_0_1sc.setExecutionMode("remote")
+        n1_0_1sc.setScript("""a=2""")
+        i1_0_1sc=n1_0_1sc.edAddInputPort("i1",td)
+        p.edAddLink(n1_0_1.edGetSamplePort(),i1_0_1sc)
+        ##
+        #
+        n1_1=r.createForEachLoop("n1_1",td)
+        p.edAddChild(n1_1)
+        p.edAddCFLink(n0,n1_1)
+        p.edAddLink(out0_0,n1_1.edGetSeqOfSamplesPort())
+        ##
+        n1_1_sc=r.createScriptNode("Salome","n1_1_sc")
+        n1_1.edAddChild(n1_1_sc)
+        n1_1_sc.setExecutionMode("remote")
+        n1_1_sc.setScript("""3*i1""")
+        i1_1_sc=n1_1_sc.edAddInputPort("i1",td)
+        p.edAddLink(n1_1.edGetSamplePort(),i1_1_sc)
+        n1_1_sc.setContainer(hp1)
+        ##
+        ##
+        hp4=p.createContainer("HP4","HPSalome")
+        hp4.setProperty("nb_proc_per_node","4")
+        n1_0.setWeight(40.)
+        n1_0_1.setWeight(20)
+        n1_1.setWeight(100.)
+        n1_0_1sc.setContainer(hp4)
+        w=pilot.ComplexWeight()
+        b0.getWeightRegardingDPL(w)
+        assert(w.getElementaryWeight()==0.)
+        assert(w.calculateTotalLength(4)==30.)
+        assert(w.calculateTotalLength(8)==15.)
+        pg.setData([("m0",120)])
+        p.fitToPlayGround(pg)########### ZE CALL
+        assert(n1_0.edGetNbOfBranchesPort().getPyObj()==64)
+        assert(n1_0_1.edGetNbOfBranchesPort().getPyObj()==16)
+        assert(n1_1.edGetNbOfBranchesPort().getPyObj()==56)
+        #
+        fyto=pilot.ForTestOmlyHPContCls()
+        n1_0_sc.getContainer().forYourTestsOnly(fyto)
+        assert(fyto.getContainerType()=="HPContainerShared")
+        pd=fyto.getPD()
+        assert(isinstance(pd,pilot.ContigPartDefinition))
+        assert(pd.getStart()==0 and pd.getStop()==64)
+        pass
+
     pass
 
 if __name__ == '__main__':
index 6a35686d27828304e587f468ddf54d25a52dba5e..caf0271db3d4db25efc3d82ad030b1cf549fe47a 100755 (executable)
@@ -1609,6 +1609,7 @@ import time
 time.sleep(2)
 o2=2*i1
 """)
+    n10.setWeight(4.)
     i1=n10.edAddInputPort("i1",ti)
     o2=n10.edAddOutputPort("o2",ti)
     p.edAddChild(n1)
@@ -1628,7 +1629,8 @@ o2=2*i1
     #
     l=loader.YACSLoader()
     p=l.load(fname)
-    self.assertEqual(p.getChildByName("n1").getWeight(),3.0)
+    self.assertEqual(p.getChildByName("n1").getWeight().getSimpleLoopWeight(),3.0)
+    self.assertEqual(p.getChildByName("n1").getChildByName("n10").getWeight().getElementaryWeight(),4.0)
     pass
 
   pass