The Gaudi Framework  v28r3 (cc1cf868)
PRGraphVisitors.cpp
Go to the documentation of this file.
1 #include "PRGraphVisitors.h"
2 #include "AlgsExecutionStates.h"
3 
4 namespace concurrency {
5 
7 
8  //--------------------------------------------------------------------------
10 
11  bool result = true; // return true if an algorithm has no data inputs
12 
13  for ( auto dataNode : node.getInputDataNodes() ) {
14 
15  result = visit(*dataNode);
16 
17  if (!result) break; // skip checking other inputs if this input was not produced yet
18  }
19 
20  if (result)
21  m_slot->algsStates.updateState( node.getAlgoIndex(), State::DATAREADY ).ignore();
22 
23  // return true only if an algorithm is promoted to DR
24  return result;
25  }
26 
27  //--------------------------------------------------------------------------
29  return true;
30  }
31 
32  //--------------------------------------------------------------------------
34 
35  bool result = false; // return false if the input has no producers at all
36 
37  for ( auto algoNode : node.getProducers() ) {
38  const auto& state = m_slot->algsStates[algoNode->getAlgoIndex()];
39  if ( State::EVTACCEPTED == state || State::EVTREJECTED == state ) {
40  result = true;
41  break; // skip checking other producers if one was found to be executed
42  }
43  }
44 
45  // return true only if this DataNode is produced
46  return result;
47  }
48 
49  //--------------------------------------------------------------------------
51 
52  auto& states = m_slot->algsStates;
53  const State& state = states[node.getAlgoIndex()];
54  int decision = -1;
55 
56  if ( true == node.isOptimist() )
57  decision = 1;
58  else if ( State::EVTACCEPTED == state )
59  decision = !node.isLiar();
60  else if ( State::EVTREJECTED == state )
61  decision = node.isLiar();
62 
63  if ( -1 != decision ) {
64 
65  m_slot->controlFlowState[node.getNodeIndex()] = decision;
66 
67  auto promoter = DataReadyPromoter(*m_slot);
68  for ( auto output : node.getOutputDataNodes() )
69  for ( auto consumer : output->getConsumers() )
70  if (State::CONTROLREADY == states[consumer->getAlgoIndex()])
71  consumer->accept(promoter);
72 
73  auto vis = concurrency::Supervisor( *m_slot );
74  for ( auto p : node.getParentDecisionHubs() )
75  p->accept(vis);
76 
77  return true; // return true only if the algorithm produced a decision
78  }
79 
80  return false;
81  }
82 
83  //---------------------------------------------------------------------------
85 
86  if (m_slot->controlFlowState[node.getNodeIndex()] != -1)
87  return false;
88  return true;
89  }
90 
91  //---------------------------------------------------------------------------
93 
94  bool foundNonResolvedChild = false;
95  bool foundNegativeChild = false;
96  bool foundPositiveChild = false;
97  int decision = -1;
98 
99  for (auto child : node.getDaughters()) {
100  int& childDecision = m_slot->controlFlowState[child->getNodeIndex()];
101 
102  if (childDecision == -1)
103  foundNonResolvedChild = true;
104  else if (childDecision == 1)
105  foundPositiveChild = true;
106  else
107  foundNegativeChild = true;
108 
109  if (node.m_modePromptDecision) {
110  if (node.m_modeOR && foundPositiveChild) {
111  decision = 1;
112  break;
113  } else if (!node.m_modeOR && foundNegativeChild) {
114  decision = 0;
115  break;
116  }
117  } else {
118  if (foundNonResolvedChild)
119  break;
120  }
121  } // end monitoring children
122 
123  if (!foundNonResolvedChild && decision == -1) {
124  if (node.m_modeOR) { // OR
125  if (foundPositiveChild) decision = 1;
126  else decision = 0;
127  } else { // AND
128  if (foundNegativeChild) decision = 0;
129  else decision = 1;
130  }
131  }
132 
133  if (node.m_allPass && !foundNonResolvedChild)
134  decision = 1;
135 
136  if (decision != -1) {
137  m_slot->controlFlowState[node.getNodeIndex()] = decision;
138  return true;
139  }
140  return false;
141  }
142 
143  //---------------------------------------------------------------------------
145 
146  if (m_slot->controlFlowState[node.getNodeIndex()] != -1)
147  return false;
148  return true;
149  }
150 
151  //--------------------------------------------------------------------------
153 
154  bool result = false;
155 
156  auto& states = m_slot->algsStates;
157  auto& state = states[node.getAlgoIndex()];
158 
159  // Promote with INITIAL->CR
160  if ( State::INITIAL == state )
161  states.updateState( node.getAlgoIndex(), State::CONTROLREADY ).ignore();
162 
163  // Try to promote with CR->DR
164  if ( State::CONTROLREADY == state ) {
165  auto promoter = DataReadyPromoter(*m_slot);
166  result = promoter.visit(node);
167  } else {
168  result = true;
169  }
170 
171  // return true only when an algorithm is not lower than DR in its FSM
172  // i.e., the visitor has done everything it could with this algorithm
173  return result;
174  }
175 
176  //--------------------------------------------------------------------------
178 
179  auto& products = node.getOutputDataNodes();
180  float rank = 0;
181 
182  for (auto p : products)
183  rank += p->getConsumers().size();
184 
185  node.setRank(rank);
186  /*std::stringstream s;
187  s << node.getNodeName() << ", " << rank << "\n";
188  std::ofstream myfile;
189  myfile.open("AlgoRank.csv", std::ios::app);
190  myfile << s.str();
191  myfile.close();*/
192 
193  return true;
194  }
195 
196  //--------------------------------------------------------------------------
198 
199  std::ifstream myfile;
200  myfile.open("InputExecutionPlan.graphml", std::ios::in);
201 
202  boost::ExecPlan execPlan;
203 
204  boost::dynamic_properties dp;
205  dp.property("name", boost::get(&boost::AlgoNodeStruct::m_name, execPlan));
206  dp.property("index", boost::get(&boost::AlgoNodeStruct::m_index, execPlan));
207  dp.property("dataRank", boost::get(&boost::AlgoNodeStruct::m_rank, execPlan));
208  dp.property("runtime", boost::get(&boost::AlgoNodeStruct::m_runtime, execPlan));
209 
210  boost::read_graphml(myfile, execPlan, dp);
211 
212  typedef boost::graph_traits<boost::ExecPlan>::vertex_iterator itV;
214  typedef boost::graph_traits<boost::ExecPlan>::vertex_descriptor AlgoVertex;
215 
216  for (vp = boost::vertices(execPlan); vp.first != vp.second; ++vp.first) {
217  AlgoVertex v = *vp.first;
218  auto index = boost::get(&boost::AlgoNodeStruct::m_name, execPlan);
219  if (index[v] == node.getNodeName()) {
220  runThroughAdjacents(v,execPlan);
221  float rank = m_nodesSucceeded;
222  node.setRank(rank);
223  reset();
224  //std::cout << "Rank of " << index[v] << " is " << rank << std::endl;
225  }
226  }
227 
228  return true;
229  }
230 
231  //--------------------------------------------------------------------------
232  void RankerByCummulativeOutDegree::runThroughAdjacents(boost::graph_traits<boost::ExecPlan>::vertex_descriptor vertex,
234  typename boost::graph_traits<boost::ExecPlan>::adjacency_iterator itVB;
235  typename boost::graph_traits<boost::ExecPlan>::adjacency_iterator itVE;
236 
237  for (boost::tie(itVB, itVE) = adjacent_vertices(vertex, graph); itVB != itVE; ++itVB) {
238  m_nodesSucceeded += 1;
239  runThroughAdjacents(*itVB, graph);
240  }
241 
242  }
243 
244  //--------------------------------------------------------------------------
246 
247  std::ifstream myfile;
248  myfile.open("InputExecutionPlan.graphml", std::ios::in);
249 
250  boost::ExecPlan execPlan;
251 
252  boost::dynamic_properties dp;
253  dp.property("name", boost::get(&boost::AlgoNodeStruct::m_name, execPlan));
254  dp.property("index", boost::get(&boost::AlgoNodeStruct::m_index, execPlan));
255  dp.property("dataRank", boost::get(&boost::AlgoNodeStruct::m_rank, execPlan));
256  dp.property("runtime", boost::get(&boost::AlgoNodeStruct::m_runtime, execPlan));
257 
258  boost::read_graphml(myfile, execPlan, dp);
259 
260  typedef boost::graph_traits<boost::ExecPlan>::vertex_iterator itV;
262  typedef boost::graph_traits<boost::ExecPlan>::vertex_descriptor AlgoVertex;
263 
264  for (vp = boost::vertices(execPlan); vp.first != vp.second; ++vp.first) {
265  AlgoVertex v = *vp.first;
266  auto index = boost::get(&boost::AlgoNodeStruct::m_name, execPlan);
267  if (index[v] == node.getNodeName()) {
268  auto index_runtime = boost::get(&boost::AlgoNodeStruct::m_runtime, execPlan);
269  float rank = index_runtime[v];
270  node.setRank(rank);
271  //std::cout << "Rank of " << index[v] << " is " << rank << std::endl;
272  }
273  }
274  return true;
275  }
276 
277  //--------------------------------------------------------------------------
279 
280  std::ifstream myfile;
281  myfile.open("Eccentricity.graphml", std::ios::in);
282 
283  boost::ExecPlan execPlan;
284 
285  boost::dynamic_properties dp;
286  dp.property("name", boost::get(&boost::AlgoNodeStruct::m_name, execPlan));
287  dp.property("Eccentricity", boost::get(&boost::AlgoNodeStruct::m_eccentricity, execPlan));
288 
289  boost::read_graphml(myfile, execPlan, dp);
290 
291  typedef boost::graph_traits<boost::ExecPlan>::vertex_iterator itV;
293  typedef boost::graph_traits<boost::ExecPlan>::vertex_descriptor AlgoVertex;
294 
295  for (vp = boost::vertices(execPlan); vp.first != vp.second; ++vp.first) {
296  AlgoVertex v = *vp.first;
297  auto index = boost::get(&boost::AlgoNodeStruct::m_name, execPlan);
298  if (index[v] == node.getNodeName()) {
299  auto index_eccentricity = boost::get(&boost::AlgoNodeStruct::m_eccentricity, execPlan);
300  float rank = index_eccentricity[v];
301  node.setRank(rank);
302  //std::cout << "Rank of " << index[v] << " is " << rank << std::endl;
303  }
304  }
305  return true;
306  }
307 
308  //--------------------------------------------------------------------------
310 
311  // Find eccentricity of the node (only within the data realm of the execution flow graph)
312  recursiveVisit(node);
313 
314  float rank = m_maxKnownDepth;
315  node.setRank(rank);
316 
317  // Reset visitor for next nodes, if any
318  reset();
319 
320  return true;
321  }
322 
323  //--------------------------------------------------------------------------
325 
326  m_currentDepth += 1;
327 
328  auto& products = node.getOutputDataNodes();
329 
330  if (products.empty())
331  if ( (m_currentDepth - 1) > m_maxKnownDepth)
332  m_maxKnownDepth = m_currentDepth - 1;
333 
334  for (auto p : products)
335  for ( auto algoNode : p->getConsumers())
336  recursiveVisit(*algoNode);
337 
338  m_currentDepth -= 1;
339 
340  }
341 
342  //---------------------------------------------------------------------------
344 
345  if (m_slot->controlFlowState[node.getNodeIndex()] != 1)
346  return true;
347  return false;
348  }
349 
350  //---------------------------------------------------------------------------
352 
353  //std::cout << "1-st level Decision: " << node.getNodeName() << std::endl;
354  bool allChildDecisionsResolved = true;
355  for (auto child : node.getDaughters()) {
356  int& childDecision = m_slot->controlFlowState[child->getNodeIndex()];
357 
358  if (childDecision == 1 && node.m_modeOR && node.m_modePromptDecision) {
359  m_slot->controlFlowState[node.getNodeIndex()] = 1;
360  return true;
361  }
362 
363  if (childDecision == -1) {
364  allChildDecisionsResolved = false;
365  }
366  }
367 
368  if (allChildDecisionsResolved)
369  m_slot->controlFlowState[node.getNodeIndex()] = 1;
370 
371  return allChildDecisionsResolved;
372  }
373 
374  //---------------------------------------------------------------------------
376 
377  if (m_slot->controlFlowState[node.getNodeIndex()] != 1)
378  return true;
379  return false;
380  }
381 
382  //--------------------------------------------------------------------------
384 
385  auto& states = m_slot->algsStates;
386  int& decision = m_slot->controlFlowState[node.getNodeIndex()];
387 
388  auto dataPromoter = DataReadyPromoter(*m_slot);
389 
390  if (State::INITIAL == states[node.getAlgoIndex()]) {
391  states.updateState(node.getAlgoIndex(), State::CONTROLREADY);
392  if (dataPromoter.visit(node)) {
393  states.updateState(node.getAlgoIndex(), State::SCHEDULED);
394  states.updateState(node.getAlgoIndex(), State::EVTACCEPTED);
395  decision = 1;
397  //std::cout << "Algorithm decided: " << node.getNodeName() << std::endl;
398  return true;
399  }
400  } else if (State::CONTROLREADY == states[node.getAlgoIndex()] && dataPromoter.visit(node)) {
401  states.updateState(node.getAlgoIndex(), State::SCHEDULED);
402  states.updateState(node.getAlgoIndex(), State::EVTACCEPTED);
403  decision = 1;
405  //std::cout << "Algorithm decided: " << node.getNodeName() << std::endl;
406  return true;
407  }
408 
409  return false;
410  }
411 }
const unsigned int & getAlgoIndex() const
XXX: CF tests.
bool visit(AlgorithmNode &node) override
T open(T...args)
bool visit(AlgorithmNode &node) override
boost::adjacency_list< boost::vecS, boost::vecS, boost::bidirectionalS, AlgoNodeStruct > ExecPlan
const std::vector< DataNode * > & getInputDataNodes() const
Get all consumer nodes.
bool isOptimist() const
Check if positive control flow decision is enforced.
AlgsExecutionStates algsStates
Vector of algorithms states.
Definition: EventSlot.h:37
void setRank(float &rank)
Set Algorithm rank.
void recursiveVisit(AlgorithmNode &node)
Depth-first node parser to calculate node eccentricity (only within the data realm of the precedence ...
const std::vector< DataNode * > & getOutputDataNodes() const
Get all supplier nodes.
bool visit(AlgorithmNode &node) override
bool m_allPass
Whether always passing regardless of daughter results.
const std::vector< DecisionNode * > & getParentDecisionHubs() const
Get all parent decision hubs.
bool visit(DecisionNode &node) override
bool m_modeOR
Whether acting as "and" (false) or "or" node (true)
bool visitEnter(DecisionNode &node) const override
std::vector< int > controlFlowState
State of the control flow.
Definition: EventSlot.h:43
const std::vector< ControlFlowNode * > & getDaughters() const
graph_traits< ExecPlan >::vertex_descriptor AlgoVertex
bool visit(AlgorithmNode &node) override
bool visit(AlgorithmNode &node) override
bool m_modePromptDecision
Whether to evaluate the hub decision ASA its child decisions allow to do that.
void runThroughAdjacents(boost::graph_traits< boost::ExecPlan >::vertex_descriptor vertex, boost::ExecPlan graph)
bool visitEnter(DecisionNode &node) const override
bool isLiar() const
Check if control flow logic is always inverted.
const std::string & getNodeName() const
const unsigned int & getNodeIndex() const
XXX: CF tests.
DataReadyPromoter(EventSlot &slot)
Constructor.
State
Execution states of the algorithms.
bool visit(AlgorithmNode &node) override
bool visit(AlgorithmNode &node) override
STL class.
bool visitEnter(DataNode &node) const override
const std::vector< AlgorithmNode * > & getProducers() const
Get all data object producers.
bool visit(DecisionNode &node) override
AlgsExecutionStates::State State
StatusCode updateState(unsigned int iAlgo, State newState)