1 // Copyright (C) 2006-2016 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "YACSlibEngineExport.hxx"
24 #include "StaticDefinedComposedNode.hxx"
25 #include "AutoRefCnt.hxx"
35 class YACSLIBENGINE_EXPORT Bloc : public StaticDefinedComposedNode
38 std::list<Node *> _setOfNode;//OWNERSHIP OF ALL NODES
39 //! For internal calculations
40 mutable std::map<Node *,std::set<Node *> > *_fwLinks;
41 //! For internal calculations
42 mutable std::map<Node *,std::set<Node *> > *_bwLinks;
44 Node *simpleClone(ComposedNode *father, bool editionOnly=true) const;
46 Bloc(const Bloc& other, ComposedNode *father, bool editionOnly);
47 Bloc(const std::string& name);
50 int getNumberOfCFLinks() const;
51 void init(bool start=true);
52 void getReadyTasks(std::vector<Task *>& tasks);
54 //Node* DISOWNnode is a SWIG notation to indicate that the ownership of the node is transfered to C++
55 bool edAddChild(Node *DISOWNnode) throw(Exception);
56 void edRemoveChild(Node *node) throw(Exception);
57 std::list<Node *> getChildren() const { return _setOfNode; }
58 std::list<Node *> edGetDirectDescendants() const { return _setOfNode; }
59 std::vector< std::list<Node *> > splitIntoIndependantGraph() const;
60 Node *getChildByShortName(const std::string& name) const throw(Exception);
61 virtual void writeDot(std::ostream &os) const;
62 void accept(Visitor *visitor);
63 template<bool direction>
64 void findAllPathsStartingFrom(Node *start, std::list< std::vector<Node *> >& vec, std::map<Node *, std::set<Node *> >& accelStr) const;
65 template<bool direction>
66 void findAllNodesStartingFrom(Node *start, std::set<Node *>& result, std::map<Node *, std::set<Node *> >& accelStr, LinkInfo& info) const;
67 virtual std::string typeName() { return "YACS__ENGINE__Bloc"; }
68 int getMaxLevelOfParallelism() const;
69 void getWeightRegardingDPL(ComplexWeight *weight);
70 void removeRecursivelyRedundantCL();
71 void partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap);
72 void fitToPlayGround(const PlayGround *pg);
74 bool areAllSubNodesFinished() const;
75 bool areAllSubNodesDone() const;
76 bool isNameAlreadyUsed(const std::string& name) const;
77 void checkNoCyclePassingThrough(Node *node) throw(Exception);
78 std::vector< std::pair<OutGate *, InGate *> > getSetOfInternalCFLinks() const;
79 YACS::Event updateStateOnFinishedEventFrom(Node *node);
80 YACS::Event updateStateOnFailedEventFrom(Node *node, const Executor *execInst);
81 void initComputation() const;
82 void performCFComputationsOnlyOneLevel(LinkInfo& info) const;
83 void performCFComputations(LinkInfo& info) const;
84 void destructCFComputations(LinkInfo& info) const;
85 void checkControlDependancy(OutPort *start, InPort *end, bool cross,
86 std::map < ComposedNode *, std::list < OutPort * >, SortHierarc >& fw,
87 std::vector<OutPort *>& fwCross,
88 std::map< ComposedNode *, std::list < OutPort *>, SortHierarc >& bw,
89 LinkInfo& info) const;
90 bool areLinked(Node *start, Node *end, bool fw) const;
91 bool arePossiblyRunnableAtSameTime(Node *start, Node *end) const;
92 void checkCFLinks(const std::list<OutPort *>& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const;
93 static void verdictForOkAndUseless1(const std::map<Node *,std::list <OutPort *> >& pool, InputPort *end, const std::vector<Node *>& candidates,
94 unsigned char& alreadyFed, bool direction, LinkInfo& info);
95 static void verdictForCollapses(const std::map<Node *,std::list <OutPort *> >& pool, InputPort *end, const std::set<Node *>& candidates,
96 unsigned char& alreadyFed, bool direction, LinkInfo& info);
97 void seekOkAndUseless1(std::vector<Node *>& okAndUseless1, std::set<Node *>& allNodes) const;
98 void seekUseless2(std::vector<Node *>& useless2, std::set<Node *>& allNodes) const;
100 std::list< AbstractPoint * > analyzeParallelism() const;
101 static void findUselessLinksIn(const std::list< std::vector<Node *> >& res , LinkInfo& info);
102 template<bool direction>
103 static unsigned appendIfAlreadyFound(std::list< std::vector<Node *> >& res, const std::vector<Node *>& startRes, Node *node, std::map<Node *, std::set<Node *> >& fastFinder);
104 static void updateWithNewFind(const std::vector<Node *>& path, std::map<Node *, std::set<Node *> >& fastFinder);
107 template<bool direction>
108 struct CFDirectionVisTraits
113 struct CFDirectionVisTraits<true>
115 typedef std::list< std::pair<InGate *,bool> >::iterator Iterator;
116 typedef std::list< std::pair<InGate *,bool> >& Nexts;
117 static Nexts getNexts(Node *node) { return node->getOutGate()->edMapInGate(); }
122 struct CFDirectionVisTraits<false>
124 typedef std::list< std::pair<OutGate *,bool> >::iterator Iterator;
125 typedef std::list< std::pair<OutGate *,bool> >& Nexts;
126 static Nexts getNexts(Node *node) { return node->getInGate()->edMapOutGate(); }
130 * Internal method for CF computation. Given 'fastFinder' it searched 'node' to see if an already found path in 'res' go through 'node'.
131 * If true all paths are deduced and append to res and 'fastFinder' is updated for next turn.
133 template<bool direction>
134 unsigned Bloc::appendIfAlreadyFound(std::list< std::vector<Node *> >& res, const std::vector<Node *>& startRes, Node *node, std::map<Node *, std::set<Node *> >& fastFinder)
136 std::map<Node *, std::set<Node *> >::iterator iter=fastFinder.find(node);
137 if(iter==fastFinder.end())
140 std::vector<std::pair<std::set<Node *>::iterator, std::set<Node *>::iterator > > li;
141 std::pair<std::set<Node *>::iterator, std::set<Node *>::iterator> ipr(((*iter).second).begin(),((*iter).second).end());
143 std::vector<Node *> work(startRes);
144 std::list< std::vector<Node *> >::iterator where=res.end(); where--;
145 std::list< std::vector<Node *> >::iterator updates=where;
148 if(li.back().first!=li.back().second)
150 work.push_back(*(li.back().first));
151 if(CFDirectionVisTraits<direction>::getNexts(work.back()).empty())
153 where=res.insert(where,work);
160 std::set<Node *>& s=fastFinder[*(li.back().first)];
161 std::pair<std::set<Node *>::iterator, std::set<Node *>::iterator> pr(s.begin(),s.end());
174 for(unsigned i=0;i<ret;i++,updates--)
175 updateWithNewFind(*updates,fastFinder);
179 template<bool direction>
180 void Bloc::findAllNodesStartingFrom(Node *start, std::set<Node *>& result,
181 std::map<Node *, std::set<Node *> >& accelStr, LinkInfo& info) const
183 std::list< std::vector<Node *> > li;
184 findAllPathsStartingFrom<direction>(start,li,accelStr);
185 for(std::list< std::vector<Node *> >::const_iterator iter=li.begin();iter!=li.end();iter++)
186 for(std::vector<Node *>::const_iterator iter2=(*iter).begin()+1;iter2!=(*iter).end();iter2++)
187 result.insert(*iter2);
189 findUselessLinksIn(li,info);
193 * Method for CF computation.DFS visitor is used.
194 * if direction is true forward visiting is performed, if false backward is performed.
195 * \param start \b must be a direct descendant of 'this'.
199 template<bool direction>
200 void Bloc::findAllPathsStartingFrom(Node *start, std::list< std::vector<Node *> >& vec,
201 std::map<Node *, std::set<Node *> >& accelStr) const
207 vec.push_back(std::vector<Node *>());
208 typename CFDirectionVisTraits<direction>::Iterator iter;
209 std::list< std::vector<Node *> >::iterator curLine=vec.begin();
210 while(start->_colour!=YACS::Black)
212 (*curLine).push_back(current);
215 if(CFDirectionVisTraits<direction>::getNexts(current).empty())
218 vec.push_back(std::vector<Node *>((*curLine)));
219 updateWithNewFind(*curLine,accelStr);
220 current->_colour=YACS::Black;
225 current=(*curLine)[idInCase];
226 (*curLine).pop_back();
227 (*curLine).pop_back();
231 if(current->_colour==YACS::Black)
233 appendIfAlreadyFound<direction>(vec,(*curLine),current,accelStr);
234 curLine=vec.end(); curLine--;
235 current->_colour=YACS::Black;
239 current=(*curLine)[idInCase];
240 (*curLine).pop_back();
241 (*curLine).pop_back();
245 for(iter=CFDirectionVisTraits<direction>::getNexts(current).begin();iter!=CFDirectionVisTraits<direction>::getNexts(current).end();iter++)
248 if(iter==CFDirectionVisTraits<direction>::getNexts(current).end())
249 {//Fail this branch should be forgotten go rev
250 current->_colour=YACS::Black;
251 (*curLine).pop_back();
255 current=(*curLine)[idInCase];
256 (*curLine).pop_back();
261 //Nothing to signal continuing in this direction hoping to find
262 current=(*iter).first->getNode();