Version: 9.15.0
Bloc.cxx
Go to the documentation of this file.
1 // Copyright (C) 2006-2025 CEA, EDF
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 
20 #include "Bloc.hxx"
21 #include "LinkInfo.hxx"
22 #include "InputPort.hxx"
23 #include "InputDataStreamPort.hxx"
24 #include "OutputPort.hxx"
25 #include "OutputDataStreamPort.hxx"
26 #include "ElementaryNode.hxx"
27 #include "Visitor.hxx"
28 #include "ForkBlocPoint.hxx"
29 #include "SetOfPoints.hxx"
30 #include "PlayGround.hxx"
31 
32 #include <queue>
33 #include <iostream>
34 #include <numeric>
35 
36 //#define _DEVDEBUG_
37 #include "YacsTrace.hxx"
38 
39 using namespace YACS::ENGINE;
40 using namespace std;
41 
48 Bloc::Bloc(const Bloc& other, ComposedNode *father, bool editionOnly):StaticDefinedComposedNode(other,father),_fwLinks(0),_bwLinks(0)
49 {
50  for(list<Node *>::const_iterator iter=other._setOfNode.begin();iter!=other._setOfNode.end();iter++)
51  _setOfNode.push_back((*iter)->simpleClone(this,editionOnly));
52 
53  //CF Linking
54  vector< pair<OutGate *, InGate *> > cfLinksToReproduce=other.getSetOfInternalCFLinks();
55  vector< pair<OutGate *, InGate *> >::iterator iter1=cfLinksToReproduce.begin();
56  for(;iter1!=cfLinksToReproduce.end();iter1++)
57  edAddCFLink(getChildByName(other.getChildName((*iter1).first->getNode())),getChildByName(other.getChildName((*iter1).second->getNode())));
58 
59  //Data + DataStream linking
60  vector< pair<OutPort *, InPort *> > linksToReproduce=other.getSetOfInternalLinks();
61  vector< pair<OutPort *, InPort *> >::iterator iter2=linksToReproduce.begin();
62  for(;iter2!=linksToReproduce.end();iter2++)
63  {
64  OutPort* pout = iter2->first;
65  InPort* pin = iter2->second;
66  if(&other == getLowestCommonAncestor(pout->getNode(), pin->getNode()))
67  {
68  edAddLink(getOutPort(other.getPortName(pout)),getInPort(other.getPortName(pin)));
69  }
70  }
71 }
72 
74 
77 Bloc::Bloc(const std::string& name):StaticDefinedComposedNode(name),_fwLinks(0),_bwLinks(0)
78 {
79 }
80 
82 {
83  for(list<Node *>::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
84  delete *iter;
85  delete _fwLinks;
86  delete _bwLinks;
87 }
88 
90 
95 void Bloc::init(bool start)
96 {
97  Node::init(start);
98  for(list<Node *>::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
99  (*iter)->init(start);
100 }
101 
103 
108 {
109  if(_state==YACS::DONE)return true;
110  if(_state==YACS::ERROR)return true;
111  if(_state==YACS::FAILED)return true;
112  if(_state==YACS::DISABLED)return true;
113  return false;
114 }
115 
117 {
118  int ret=0;
119  for(list<Node *>::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
120  ret+=(*iter)->getOutGate()->getNbOfInGatesConnected();
121  return ret;
122 }
123 
124 Node *Bloc::simpleClone(ComposedNode *father, bool editionOnly) const
125 {
126  return new Bloc(*this,father,editionOnly);
127 }
128 
130 
133 void Bloc::getReadyTasks(std::vector<Task *>& tasks)
134 {
135  /*
136  * ComposedNode state goes to ACTIVATED when one of its child has been ACTIVATED
137  * To change this uncomment the following line
138  * Then the father node will go to ACTIVATED state before its child node
139  */
142  for(list<Node *>::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
143  (*iter)->getReadyTasks(tasks);
144 }
145 
147 
154 {
155  if(_state == YACS::DISABLED)return;
156  if(_state == YACS::DONE)return;
157  if(_inGate.exIsReady())
158  {
160  for(list<Node *>::iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
161  if((*iter)->exIsControlReady())
162  (*iter)->exUpdateState();
163  }
164 }
165 
167 
177 {
178  if(isNodeAlreadyAggregated(node))
179  {
180  if(node->_father==this)
181  return false;
182  else
183  {
184  string what = "Bloc::edAddChild : node "; what += node->getName();
185  what += " is already grand children of node";
186  throw Exception(what);
187  }
188  }
189 
190  if(node->_father)
191  {
192  string what = "Bloc::edAddChild: node is not orphan: "; what += node->getName();
193  throw Exception(what);
194  }
195 
197 
198  if(isNameAlreadyUsed(node->getName()))
199  {
200  string what("Bloc::edAddChild : name "); what+=node->getName();
201  what+=" already exists in the scope of "; what+=_name;
202  throw Exception(what);
203  }
204 
205  node->_father=this;
206  _setOfNode.push_back(node);
207  //should we also set _modified flag for node ??
208  ComposedNode *iter=node->_father;
209  //set the _modified flag so that latter on edUpdateState (eventually called by isValid) refresh state
210  //better call it at end
211  modified();
212  return true;
213 }
214 
221 {
223  list<Node *>::iterator iter=find(_setOfNode.begin(),_setOfNode.end(),node);
224  if(iter!=_setOfNode.end())
225  {
226  _setOfNode.erase(iter);
227  modified();
228  }
229 }
230 
231 std::vector< std::list<Node *> > Bloc::splitIntoIndependantGraph() const
232 {
233  std::size_t sz(_setOfNode.size());
234  list<Node *>::const_iterator it=_setOfNode.begin();
235  for(;it!=_setOfNode.end();it++)
236  (*it)->_colour=White;
237  it=_setOfNode.begin();
238  std::vector< list<Node *> > ret;
239  while(it!=_setOfNode.end())
240  {
241  Node *start(*it); start->_colour=Grey;
242  ret.push_back(list<Node *>());
243  list<Node *>& ll(ret.back());
244  std::queue<Node *> fifo; fifo.push(start);
245  while(!fifo.empty())
246  {
247  Node *cur(fifo.front()); fifo.pop();
248  ll.push_back(cur);
249  //
250  OutGate *og(cur->getOutGate());
251  list<InGate *> og2(og->edSetInGate());
252  for(list<InGate *>::const_iterator it2=og2.begin();it2!=og2.end();it2++)
253  {
254  Node *cur2((*it2)->getNode());
255  if(cur2->_colour==White)
256  {
257  cur2->_colour=Grey;
258  fifo.push(cur2);
259  }
260  }
261  //
262  InGate *ig(cur->getInGate());
263  list<OutGate *> bl(ig->getBackLinks());
264  for(list<OutGate *>::const_iterator it3=bl.begin();it3!=bl.end();it3++)
265  {
266  Node *cur3((*it3)->getNode());
267  if(cur3->_colour==White)
268  {
269  cur3->_colour=Grey;
270  fifo.push(cur3);
271  }
272  }
273  }
274  for(it=_setOfNode.begin();it!=_setOfNode.end() && (*it)->_colour!=White;it++);
275  }
276  return ret;
277 }
278 
279 Node *Bloc::getChildByShortName(const std::string& name) const
280 {
281  for (list<Node *>::const_iterator iter = _setOfNode.begin(); iter != _setOfNode.end(); iter++)
282  if ((*iter)->getName() == name)
283  return (*iter);
284  string what("node "); what+= name ; what+=" is not a child of Bloc "; what += getName();
285  throw Exception(what);
286 }
287 
289 {
290  for(list<Node *>::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
291  {
292  if((*iter)->_state == YACS::DONE)continue;
293  if((*iter)->_state == YACS::DISABLED)continue;
294  return false;
295  }
296  return true;
297 }
298 
300 {
301  for(list<Node *>::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
302  {
303  if((*iter)->_state == YACS::DONE)continue;
304  if((*iter)->_state == YACS::FAILED)continue;
305  if((*iter)->_state == YACS::DISABLED)continue;
306  if((*iter)->_state == YACS::ERROR)continue;
307  if((*iter)->_state == YACS::INTERNALERR)continue;
308  return false;
309  }
310  return true;
311 }
312 
313 bool Bloc::isNameAlreadyUsed(const std::string& name) const
314 {
315  for(list<Node *>::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
316  if((*iter)->getName()==name)
317  return true;
318  return false;
319 }
320 
321 bool insertNodeChildrenInSet(Node *node, std::set<Node *>& nodeSet)
322 {
323  bool verdict=true;
324  list<Node *> outNodes=node->getOutNodes();
325  for (list<Node *>::iterator iter=outNodes.begin();iter!=outNodes.end(); iter++)
326  {
327  verdict=(nodeSet.insert(*iter)).second;
328  if (verdict) verdict = insertNodeChildrenInSet((*iter),nodeSet);
329  }
330  return verdict;
331 }
332 
339 {
340  set<Node *> currentNodesToTest;
341  //don't insert node to test in set.
342  //If it is present after insertion of connected nodes we have a loop
343  //collect all connected nodes
344  insertNodeChildrenInSet(node,currentNodesToTest);
345  //try to insert node
346  if(!(currentNodesToTest.insert(node)).second)
347  throw Exception("Cycle has been detected",1);
348 }
349 
350 std::vector< std::pair<OutGate *, InGate *> > Bloc::getSetOfInternalCFLinks() const
351 {
352  vector< pair<OutGate *, InGate *> > ret;
353  for(list<Node *>::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
354  {
355  list<InGate *> outCFLinksOfCurNode=(*iter)->_outGate.edSetInGate();
356  for(list<InGate *>::iterator iter2=outCFLinksOfCurNode.begin();iter2!=outCFLinksOfCurNode.end();iter2++)
357  ret.push_back(pair<OutGate *, InGate *>(&(*iter)->_outGate,*iter2));
358  }
359  return ret;
360 }
361 
371 {
372  DEBTRACE("Bloc::updateStateOnFinishedEventFrom: " << node->getName());
373  //ASSERT(node->_father==this)
375  {
377  if(!areAllSubNodesDone())
378  {
380  return YACS::ABORT;
381  }
382  return YACS::FINISH;//notify to father node that 'this' has becomed finished.
383  }
384  //more job to do in 'this' bloc
385  //Conversion exceptions can be thrown so catch them to control errors
386  try
387  {
388  //notify the finished node to propagate to its following nodes
389  node->exForwardFinished();
390  }
391  catch(YACS::Exception& ex)
392  {
393  //The node has failed to propagate. It must be put in error
394  DEBTRACE("Bloc::updateStateOnFinishedEventFrom: " << ex.what());
395  // notify the node it has failed
396  node->exForwardFailed();
398  return YACS::ABORT;
399  }
400  return YACS::NOEVENT;//no notification to father needed because from father point of view nothing happened.
401 }
402 
404 
409 {
410  node->exForwardFailed();
412  {
414  if(!areAllSubNodesDone()){
416  return YACS::ABORT;
417  }
418  return YACS::FINISH;//notify to father node that 'this' has becomed finished.
419  }
420  return YACS::NOEVENT;
421 }
422 
423 void Bloc::writeDot(std::ostream &os) const
424 {
425  os << " subgraph cluster_" << getId() << " {\n" ;
426  list<Node *>nodes=getChildren();
427  for(list<Node *>::const_iterator iter=nodes.begin();iter!=nodes.end();iter++)
428  {
429  (*iter)->writeDot(os);
430  string p=(*iter)->getId();
431  //not connected node
432  if((*iter)->_inGate._backLinks.size() == 0) os << getId() << " -> " << p << ";\n";
433  list<Node *>outnodes = (*iter)->getOutNodes();
434  for(list<Node *>::const_iterator itout=outnodes.begin();itout!=outnodes.end();itout++)
435  {
436  os << p << " -> " << (*itout)->getId() << ";\n";
437  }
438  }
439  os << "}\n" ;
440  os << getId() << "[fillcolor=\"" ;
442  os << getColorState(state);
443  os << "\" label=\"" << "Bloc:" ;
444  os << getQualifiedName() <<"\"];\n";
445 }
446 
447 void Bloc::accept(Visitor* visitor)
448 {
449  visitor->visitBloc(this);
450 }
451 
457 {
458  std::list< AbstractPoint * > pts(analyzeParallelism());
459  ForkBlocPoint fbp(pts,NULL);
460  return fbp.getMaxLevelOfParallelism();
461 }
462 
463 std::list< AbstractPoint * > Bloc::analyzeParallelism() const
464 {
465  std::vector< std::list<Node *> > r(splitIntoIndependantGraph());
466  std::list< AbstractPoint * > pts;
467  for(std::vector< std::list<Node *> >::const_iterator it=r.begin();it!=r.end();it++)
468  {
469  SetOfPoints sop(*it);
470  sop.simplify();
471  pts.push_back(sop.getUniqueAndReleaseIt());
472  }
473  return pts;
474 }
475 
477 {
478  std::list< AbstractPoint * > pts(analyzeParallelism());
479  ForkBlocPoint fbp(pts,NULL);
480  fbp.getWeightRegardingDPL(weight);
481 }
482 
484 {
486  LinkInfo info(I_CF_USELESS);
487  initComputation();
489  std::set< std::pair<Node *, Node *> > linksToKill(info.getInfoUselessLinks());
490  for(std::set< std::pair<Node *, Node *> >::const_iterator it=linksToKill.begin();it!=linksToKill.end();it++)
491  edRemoveCFLink((*it).first,(*it).second);
493 }
494 
496 {
497  if(!pd)
498  throw Exception("Bloc::partitionRegardingDPL : NULL pointer !");
499  std::list< AbstractPoint * > pts(analyzeParallelism());
500  ForkBlocPoint fbp(pts,NULL);
501  fbp.partitionRegardingDPL(pd,zeMap);
502 }
503 
505 {
506  delete _fwLinks;//Normally useless
507  delete _bwLinks;//Normally useless
508  _fwLinks=new map<Node *,set<Node *> >;
509  _bwLinks=new map<Node *,set<Node *> >;
510 
511  //a set to store all CF links : used to find fastly if two nodes are connected
512  std::set< std::pair< Node*, Node* > > links;
513 
514  for(list<Node *>::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
515  {
516  Node* n1=*iter;
517  std::list<InGate *> ingates=n1->getOutGate()->edSetInGate();
518  for(std::list<InGate *>::const_iterator it2=ingates.begin();it2!=ingates.end();it2++)
519  {
520  //CF link : n1 -> (*it2)->getNode()
521  Node* n2=(*it2)->getNode();
522  links.insert(std::pair< Node*, Node* >(n1,n2));
523  std::set<Node *> bwn1=(*_bwLinks)[n1];
524  std::set<Node *> fwn1=(*_fwLinks)[n1];
525  std::set<Node *> fwn2=(*_fwLinks)[n2];
526  std::set<Node *> bwn2=(*_bwLinks)[n2];
527  std::pair<std::set<Node*>::iterator,bool> ret;
528  for(std::set<Node *>::const_iterator iter2=bwn1.begin();iter2!=bwn1.end();iter2++)
529  {
530  for(std::set<Node *>::const_iterator it3=fwn2.begin();it3!=fwn2.end();it3++)
531  {
532  ret=(*_fwLinks)[*iter2].insert(*it3);
533  if(ret.second==false)
534  {
535  //dependency already exists (*iter2) -> (*it3) : if a direct link exists it's a useless one
536  if(links.find(std::pair< Node*, Node* >(*iter2,*it3)) != links.end())
537  info.pushUselessCFLink(*iter2,*it3);
538  }
539  }
540  ret=(*_fwLinks)[*iter2].insert(n2);
541  if(ret.second==false)
542  {
543  //dependency already exists (*iter2) -> n2 : if a direct link exists it's a useless one
544  if(links.find(std::pair< Node*, Node* >(*iter2,n2)) != links.end())
545  info.pushUselessCFLink(*iter2,n2);
546  }
547  }
548  for(std::set<Node *>::const_iterator it3=fwn2.begin();it3!=fwn2.end();it3++)
549  {
550  ret=(*_fwLinks)[n1].insert(*it3);
551  if(ret.second==false)
552  {
553  //dependency already exists n1 -> *it3 : if a direct link exists it's a useless one
554  if(links.find(std::pair< Node*, Node* >(n1,*it3)) != links.end())
555  info.pushUselessCFLink(n1,*it3);
556  }
557  }
558  ret=(*_fwLinks)[n1].insert(n2);
559  if(ret.second==false)
560  {
561  //dependency already exists n1 -> n2 : it's a useless link
562  info.pushUselessCFLink(n1,n2);
563  }
564 
565  for(std::set<Node *>::const_iterator iter2=fwn2.begin();iter2!=fwn2.end();iter2++)
566  {
567  (*_bwLinks)[*iter2].insert(bwn1.begin(),bwn1.end());
568  (*_bwLinks)[*iter2].insert(n1);
569  }
570  (*_bwLinks)[n2].insert(bwn1.begin(),bwn1.end());
571  (*_bwLinks)[n2].insert(n1);
572  }
573  }
574 }
575 
589 {
592 }
593 
595 {
597  delete _fwLinks; _fwLinks=0;
598  delete _bwLinks; _bwLinks=0;
599 }
600 
614 void Bloc::checkControlDependancy(OutPort *start, InPort *end, bool cross,
615  std::map < ComposedNode *, std::list < OutPort * >, SortHierarc >& fw,
616  std::vector<OutPort *>& fwCross,
617  std::map< ComposedNode *, std::list < OutPort *>, SortHierarc >& bw,
618  LinkInfo& info) const
619 {
620  if(!cross)
621  {
622  Node *startN=isInMyDescendance(start->getNode());
623  Node *endN=isInMyDescendance(end->getNode());
624  if(startN==endN)
625  bw[(ComposedNode *)this].push_back(start);
626  else if(areLinked(startN,endN,true))
627  fw[(ComposedNode *)this].push_back(start);
628  else
629  if(areLinked(startN,endN,false))
630  bw[(ComposedNode *)this].push_back(start);
631  else
632  info.pushErrLink(start,end,E_UNPREDICTABLE_FED);
633  }
634  else//DFDS detected
636  fwCross.push_back(start);
637  else
638  info.pushErrLink(start,end,E_DS_LINK_UNESTABLISHABLE);
639 }
640 
642 
650 bool Bloc::areLinked(Node *start, Node *end, bool fw) const
651 {
652  set<Node *>& nexts=fw ? (*_fwLinks)[start] : (*_bwLinks)[start];
653  return nexts.find(end)!=nexts.end();
654 }
655 
657 
665 {
666  set<Node *>& nexts=(*_fwLinks)[start];
667  set<Node *>& preds=(*_bwLinks)[start];
668  return nexts.find(end)==nexts.end() && preds.find(end)==preds.end();
669 }
670 
672 
679 void Bloc::checkCFLinks(const std::list<OutPort *>& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const
680 {
681  if(alreadyFed==FREE_ST || alreadyFed==FED_ST)
682  {
683  map<Node *,list <OutPort *> > classPerNodes;
684  for(list< OutPort *>::const_iterator iter1=starts.begin();iter1!=starts.end();iter1++)
685  classPerNodes[isInMyDescendance((*iter1)->getNode())].push_back(*iter1);
686  set<Node *> allNodes;
687  for(map<Node *,list <OutPort *> >::iterator iter2=classPerNodes.begin();iter2!=classPerNodes.end();iter2++)
688  allNodes.insert((*iter2).first);
689  vector<Node *> okAndUseless1,useless2;
690  seekOkAndUseless1(okAndUseless1,allNodes);
691  seekUseless2(useless2,allNodes);//after this point allNodes contains collapses
692  verdictForOkAndUseless1(classPerNodes,end,okAndUseless1,alreadyFed,direction,info);
693  verdictForCollapses(classPerNodes,end,allNodes,alreadyFed,direction,info);
694  verdictForOkAndUseless1(classPerNodes,end,useless2,alreadyFed,direction,info);
695  }
696  else if(alreadyFed==FED_DS_ST)
697  for(list< OutPort *>::const_iterator iter1=starts.begin();iter1!=starts.end();iter1++)
698  info.pushErrLink(*iter1,end,E_COLLAPSE_DFDS);
699 }
700 
702 {
703  for(list<Node *>::const_iterator iter=_setOfNode.begin();iter!=_setOfNode.end();iter++)
704  {
705  (*iter)->_colour=White;
706  (*iter)->getInGate()->exReset();
707  (*iter)->getOutGate()->exReset();
708  }
709 }
710 
720 void Bloc::verdictForOkAndUseless1(const std::map<Node *,std::list <OutPort *> >& pool, InputPort *end,
721  const std::vector<Node *>& candidates, unsigned char& alreadyFed,
722  bool direction, LinkInfo& info)
723 {
724  for(vector<Node *>::const_iterator iter=candidates.begin();iter!=candidates.end();iter++)
725  {
726  const list<OutPort *>& mySet=(*pool.find(*iter)).second;
727  if(mySet.size()==1)
728  {
729  if(alreadyFed==FREE_ST)
730  {
731  alreadyFed=FED_ST;//This the final choice. General case !
732  if(!direction)
733  info.pushInfoLink(*(mySet.begin()),end,I_BACK);
734  }
735  else if(alreadyFed==FED_ST)
736  info.pushInfoLink(*(mySet.begin()),end,direction ? I_USELESS : I_BACK_USELESS);//Second or more turn in case of alreadyFed==FREE_ST before call of this method
737  }
738  else
739  {
740  if(dynamic_cast<ElementaryNode *>(*iter))
741  {
742  WarnReason reason;
743  if(alreadyFed==FREE_ST)
744  reason=direction ? W_COLLAPSE_EL : W_BACK_COLLAPSE_EL;
745  else if(alreadyFed==FED_ST)
747  for(list<OutPort *>::const_iterator iter2=mySet.begin();iter2!=mySet.end();iter2++)
748  info.pushWarnLink(*iter2,end,reason);
749  }
750  else
751  ((ComposedNode *)(*iter))->checkCFLinks(mySet,end,alreadyFed,direction,info);//Thanks to recursive model!
752  }
753  }
754 }
755 
765 void Bloc::verdictForCollapses(const std::map<Node *,std::list <OutPort *> >& pool, InputPort *end,
766  const std::set<Node *>& candidates, unsigned char& alreadyFed,
767  bool direction, LinkInfo& info)
768 {
769  info.startCollapseTransac();
770  for(set<Node *>::const_iterator iter=candidates.begin();iter!=candidates.end();iter++)
771  {
772  const list<OutPort *>& mySet=(*pool.find(*iter)).second;
773  if(mySet.size()==1)
774  {
775  if(alreadyFed==FREE_ST)
776  info.pushWarnLink(*(mySet.begin()),end,direction ? W_COLLAPSE : W_BACK_COLLAPSE);
777  else if(alreadyFed==FED_ST)
778  info.pushWarnLink(*(mySet.begin()),end,direction ? W_COLLAPSE_AND_USELESS : W_BACK_COLLAPSE_EL_AND_USELESS);
779  }
780  else
781  {
782  if(dynamic_cast<ElementaryNode *>(*iter))
783  {
784  WarnReason reason;
785  if(alreadyFed==FREE_ST)
786  reason=direction ? W_COLLAPSE_EL : W_BACK_COLLAPSE_EL;
787  else if(alreadyFed==FED_ST)
789  for(list<OutPort *>::const_iterator iter2=mySet.begin();iter2!=mySet.end();iter2++)
790  info.pushWarnLink(*iter2,end,reason);
791  }
792  else
793  {
794  ((ComposedNode *)(*iter))->checkCFLinks(mySet,end,alreadyFed,direction,info);//Thanks to recursive model!
795  WarnReason reason;
796  if(alreadyFed==FREE_ST)
797  reason=direction ? W_COLLAPSE : W_BACK_COLLAPSE;
798  else if(alreadyFed==FED_ST)
800  for(list<OutPort *>::const_iterator iter2=mySet.begin();iter2!=mySet.end();iter2++)
801  info.pushWarnLink(*iter2,end,reason);
802  }
803  }
804  }
805  if(!candidates.empty())
806  if(alreadyFed==FREE_ST)
807  alreadyFed=FED_ST;
808  info.endCollapseTransac();
809 }
810 
816 void Bloc::seekOkAndUseless1(std::vector<Node *>& okAndUseless1, std::set<Node *>& allNodes) const
817 {
818  set<Node *>::iterator iter=allNodes.begin();
819  while(iter!=allNodes.end())
820  {
821  set<Node *>& whereToFind=(*_bwLinks)[*iter];
822  std::set<Node *>::iterator iter2;
823  for(iter2=allNodes.begin();iter2!=allNodes.end();iter2++)
824  if((*iter)!=(*iter2))
825  if(whereToFind.find(*iter2)==whereToFind.end())
826  break;
827  if(iter2!=allNodes.end())
828  iter++;
829  else
830  {
831  okAndUseless1.push_back((*iter));
832  allNodes.erase(iter);
833  iter=allNodes.begin();
834  }
835  }
836 }
837 
842 void Bloc::seekUseless2(std::vector<Node *>& useless2, std::set<Node *>& allNodes) const
843 {
844  set<Node *>::iterator iter=allNodes.begin();
845  while(iter!=allNodes.end())
846  {
847  set<Node *>& whereToFind=(*_fwLinks)[*iter];
848  std::set<Node *>::iterator iter2;
849  for(iter2=allNodes.begin();iter2!=allNodes.end();iter2++)
850  if((*iter)!=(*iter2))
851  if(whereToFind.find(*iter2)==whereToFind.end())
852  break;
853  if(iter2!=allNodes.end())
854  {
855  iter++;
856  }
857  else
858  {
859  useless2.push_back((*iter));
860  allNodes.erase(iter);
861  iter=allNodes.begin();
862  }
863  }
864 }
865 
869 void Bloc::updateWithNewFind(const std::vector<Node *>& path, std::map<Node *, std::set<Node *> >& fastFinder)
870 {
871  if(path.size()>=3)
872  {
873  vector<Node *>::const_iterator iter=path.begin(); iter++;
874  vector<Node *>::const_iterator iter2=path.end(); iter2-=1;
875  for(;iter!=iter2;iter++)
876  fastFinder[*iter].insert(*(iter+1));
877  }
878 }
879 
883 void Bloc::findUselessLinksIn(const std::list< std::vector<Node *> >& res , LinkInfo& info)
884 {
885  unsigned maxSize=0;
886  list< vector<Node *> >::const_iterator whereToPeerAt;
887  for(list< vector<Node *> >::const_iterator iter=res.begin();iter!=res.end();iter++)
888  if((*iter).size()>maxSize)
889  {
890  maxSize=(*iter).size();
891  whereToPeerAt=iter;
892  }
893  //
894  if(maxSize>1)
895  {
896  vector<Node *>::const_iterator iter2=(*whereToPeerAt).begin();
897  map<Node *,bool>::iterator iter4;
898  set<Node *> searcher(iter2+1,(*whereToPeerAt).end());//to boost research
899  for(;iter2!=((*whereToPeerAt).end()-2);iter2++)
900  {
901  list< pair<InGate *,bool> >& nexts=(*iter2)->getOutGate()->edMapInGate();
902  for(list< pair<InGate *,bool> >::iterator iter4=nexts.begin();iter4!=nexts.end();iter4++)
903  if((*iter4).first->getNode()!=*(iter2+1))
904  if(searcher.find((*iter4).first->getNode())!=searcher.end())
905  info.pushUselessCFLink(*iter2,(*iter4).first->getNode());
906  searcher.erase(*iter2);
907  }
908  }
909 }
bool insertNodeChildrenInSet(Node *node, std::set< Node * > &nodeSet)
Definition: Bloc.cxx:321
#define DEBTRACE(msg)
Definition: YacsTrace.hxx:31
Composed node to group elementary and composed nodes.
Definition: Bloc.hxx:36
void removeRecursivelyRedundantCL()
Definition: Bloc.cxx:483
Node * getChildByShortName(const std::string &name) const
Definition: Bloc.cxx:279
void checkCFLinks(const std::list< OutPort * > &starts, InputPort *end, unsigned char &alreadyFed, bool direction, LinkInfo &info) const
Check control flow links.
Definition: Bloc.cxx:679
std::list< Node * > _setOfNode
Definition: Bloc.hxx:38
int getNumberOfCFLinks() const
Definition: Bloc.cxx:116
void checkControlDependancy(OutPort *start, InPort *end, bool cross, std::map< ComposedNode *, std::list< OutPort * >, SortHierarc > &fw, std::vector< OutPort * > &fwCross, std::map< ComposedNode *, std::list< OutPort * >, SortHierarc > &bw, LinkInfo &info) const
Definition: Bloc.cxx:614
virtual ~Bloc()
Definition: Bloc.cxx:81
bool areLinked(Node *start, Node *end, bool fw) const
Check if two nodes are linked.
Definition: Bloc.cxx:650
void checkNoCyclePassingThrough(Node *node)
Definition: Bloc.cxx:338
bool isNameAlreadyUsed(const std::string &name) const
Definition: Bloc.cxx:313
void accept(Visitor *visitor)
Definition: Bloc.cxx:447
std::vector< std::list< Node * > > splitIntoIndependantGraph() const
Definition: Bloc.cxx:231
std::list< AbstractPoint * > analyzeParallelism() const
Definition: Bloc.cxx:463
Node * simpleClone(ComposedNode *father, bool editionOnly=true) const
Definition: Bloc.cxx:124
bool isFinished()
Indicate if the bloc execution is finished.
Definition: Bloc.cxx:107
std::vector< std::pair< OutGate *, InGate * > > getSetOfInternalCFLinks() const
Definition: Bloc.cxx:350
bool areAllSubNodesFinished() const
Definition: Bloc.cxx:299
void seekOkAndUseless1(std::vector< Node * > &okAndUseless1, std::set< Node * > &allNodes) const
Definition: Bloc.cxx:816
void performCFComputationsOnlyOneLevel(LinkInfo &info) const
Definition: Bloc.cxx:504
static void updateWithNewFind(const std::vector< Node * > &path, std::map< Node *, std::set< Node * > > &fastFinder)
Definition: Bloc.cxx:869
void partitionRegardingDPL(const PartDefinition *pd, std::map< ComposedNode *, YACS::BASES::AutoRefCnt< PartDefinition > > &zeMap)
Definition: Bloc.cxx:495
static void verdictForOkAndUseless1(const std::map< Node *, std::list< OutPort * > > &pool, InputPort *end, const std::vector< Node * > &candidates, unsigned char &alreadyFed, bool direction, LinkInfo &info)
Definition: Bloc.cxx:720
static void verdictForCollapses(const std::map< Node *, std::list< OutPort * > > &pool, InputPort *end, const std::set< Node * > &candidates, unsigned char &alreadyFed, bool direction, LinkInfo &info)
Definition: Bloc.cxx:765
YACS::Event updateStateOnFinishedEventFrom(Node *node)
Definition: Bloc.cxx:370
std::map< Node *, std::set< Node * > > * _bwLinks
For internal calculations.
Definition: Bloc.hxx:42
bool areAllSubNodesDone() const
Definition: Bloc.cxx:288
int getMaxLevelOfParallelism() const
Definition: Bloc.cxx:456
bool arePossiblyRunnableAtSameTime(Node *start, Node *end) const
Check if two nodes can run in parallel.
Definition: Bloc.cxx:664
void getWeightRegardingDPL(ComplexWeight *weight)
Definition: Bloc.cxx:476
void init(bool start=true)
Initialize the bloc.
Definition: Bloc.cxx:95
YACS::Event updateStateOnFailedEventFrom(Node *node, const Executor *execInst)
Notify this bloc that a node has failed.
Definition: Bloc.cxx:408
std::map< Node *, std::set< Node * > > * _fwLinks
For internal calculations.
Definition: Bloc.hxx:40
bool edAddChild(Node *DISOWNnode)
Add a child node to the bloc.
Definition: Bloc.cxx:176
static void findUselessLinksIn(const std::list< std::vector< Node * > > &res, LinkInfo &info)
Definition: Bloc.cxx:883
void performCFComputations(LinkInfo &info) const
Definition: Bloc.cxx:588
void seekUseless2(std::vector< Node * > &useless2, std::set< Node * > &allNodes) const
Definition: Bloc.cxx:842
void initComputation() const
Definition: Bloc.cxx:701
std::list< Node * > getChildren() const
Definition: Bloc.hxx:57
void exUpdateState()
Update the bloc state.
Definition: Bloc.cxx:153
void getReadyTasks(std::vector< Task * > &tasks)
Collect all nodes that are ready to execute.
Definition: Bloc.cxx:133
void edRemoveChild(Node *node)
Definition: Bloc.cxx:220
virtual void writeDot(std::ostream &os) const
Dump to the input stream a dot representation of the node.
Definition: Bloc.cxx:423
void destructCFComputations(LinkInfo &info) const
destroy recursively all results of initial computations.
Definition: Bloc.cxx:594
Base class for all composed nodes.
std::string getChildName(const Node *node) const
Node * getChildByName(const std::string &name) const
static const unsigned char FREE_ST
OutPort * getOutPort(const std::string &name) const
std::vector< std::pair< OutPort *, InPort * > > getSetOfInternalLinks() const
void checkNoCrossHierachyWith(Node *node) const
std::string getName() const
void edRemoveCFLink(Node *nodeS, Node *nodeE)
Remove a controlflow link.
virtual void edRemoveChild(Node *node)
Remove a child node.
bool isNodeAlreadyAggregated(const Node *node) const
Check that Node 'node' is already a direct son of this.
std::string getPortName(const PORT *port) const
virtual void removeRecursivelyRedundantCL()
virtual void performCFComputations(LinkInfo &info) const
perform recursively all CF computations.
static const unsigned char FED_ST
static const unsigned char FED_DS_ST
bool edAddCFLink(Node *nodeS, Node *nodeE)
Add a controlflow link between two nodes.
bool edAddLink(OutPort *start, InPort *end)
Add a dataflow link between two data ports.
virtual void destructCFComputations(LinkInfo &info) const
destroy recursively all results of initial computations.
Node * isInMyDescendance(Node *nodeToTest) const
Returns the parent of a node that is the direct child of this node.
static ComposedNode * getLowestCommonAncestor(Node *node1, Node *node2)
Retrieves the lowest common ancestor of 2 nodes.
Base class for all calculation nodes.
Threaded Executor.
Definition: Executor.hxx:63
void getWeightRegardingDPL(ComplexWeight *weight)
void partitionRegardingDPL(const PartDefinition *pd, std::map< ComposedNode *, YACS::BASES::AutoRefCnt< PartDefinition > > &zeMap) const
std::list< OutGate * > getBackLinks()
Definition: InGate.cxx:134
bool exIsReady() const
Definition: InGate.cxx:126
Base class for Input Ports.
Definition: InputPort.hxx:44
Class that deal with list of semantics links for high level analysis.
Definition: LinkInfo.hxx:83
void pushErrLink(OutPort *semStart, InPort *end, ErrReason reason)
Definition: LinkInfo.cxx:86
void pushInfoLink(OutPort *semStart, InPort *end, InfoReason reason)
Definition: LinkInfo.cxx:71
void pushUselessCFLink(Node *start, Node *end)
Definition: LinkInfo.cxx:107
std::set< std::pair< Node *, Node * > > getInfoUselessLinks() const
Definition: LinkInfo.cxx:266
void pushWarnLink(OutPort *semStart, InPort *end, WarnReason reason)
Definition: LinkInfo.cxx:76
Base class for all nodes.
Definition: Node.hxx:70
std::string _name
Definition: Node.hxx:89
virtual void exForwardFinished()
Definition: Node.cxx:386
ComposedNode * _father
Definition: Node.hxx:90
std::string getColorState(YACS::StatesForNode state) const
Return the color associated to a state.
Definition: Node.cxx:578
InGate _inGate
Definition: Node.hxx:86
OutGate * getOutGate()
Definition: Node.hxx:124
virtual void modified()
Sets Node in modified state and its father if it exists.
Definition: Node.cxx:805
std::string getQualifiedName() const
same as Node::getName() in most cases, but differs for children of switch
Definition: Node.cxx:632
std::list< Node * > getOutNodes() const
Definition: Node.cxx:185
const std::string getId() const
Definition: Node.cxx:478
YACS::Colour _colour
Definition: Node.hxx:84
virtual void init(bool start=true)
Definition: Node.cxx:102
void setState(YACS::StatesForNode theState)
Sets the given state for node.
Definition: Node.cxx:652
InGate * getInGate()
Definition: Node.hxx:123
InPort * getInPort(const std::string &name) const
Definition: Node.cxx:239
const std::string & getName() const
Definition: Node.hxx:125
virtual void exForwardFailed()
Definition: Node.cxx:378
virtual YACS::StatesForNode getEffectiveState() const
Return the node state in the context of its father.
Definition: Node.cxx:538
YACS::StatesForNode _state
Definition: Node.hxx:91
std::list< InGate * > edSetInGate() const
Definition: OutGate.cxx:112
Node * getNode() const
Definition: Port.hxx:46
AbstractPoint * getUniqueAndReleaseIt() const
virtual void visitBloc(Bloc *node)=0
Proc * p
Definition: driver.cxx:216
@ E_UNPREDICTABLE_FED
Definition: LinkInfo.hxx:74
@ E_DS_LINK_UNESTABLISHABLE
Definition: LinkInfo.hxx:71
@ W_COLLAPSE_EL_AND_USELESS
Definition: LinkInfo.hxx:59
@ W_BACK_COLLAPSE_AND_USELESS
Definition: LinkInfo.hxx:61
@ W_BACK_COLLAPSE_EL
Definition: LinkInfo.hxx:62
@ W_BACK_COLLAPSE_EL_AND_USELESS
Definition: LinkInfo.hxx:63
@ W_COLLAPSE_AND_USELESS
Definition: LinkInfo.hxx:57
Event
Definition: define.hxx:56
@ ABORT
Definition: define.hxx:60
@ NOEVENT
Definition: define.hxx:57
@ FINISH
Definition: define.hxx:59
@ White
Definition: define.hxx:28
@ Grey
Definition: define.hxx:29
StatesForNode
Definition: define.hxx:34
@ FAILED
Definition: define.hxx:51
@ ACTIVATED
Definition: define.hxx:41
@ INTERNALERR
Definition: define.hxx:49
@ DONE
Definition: define.hxx:43
@ TOACTIVATE
Definition: define.hxx:40
@ DISABLED
Definition: define.hxx:50
@ ERROR
Definition: define.hxx:52