The Gaudi Framework  master (ff829712)
Loading...
Searching...
No Matches
concurrency::TarjanSCCFinder Class Reference

The visitor implements the Tarjan algorithm for searching strongly connected components in the data flow realm of precedence rules graph. More...

#include </builds/gaudi/Gaudi/GaudiHive/src/PRGraph/Visitors/Validators.h>

Inheritance diagram for concurrency::TarjanSCCFinder:
Collaboration diagram for concurrency::TarjanSCCFinder:

Public Member Functions

bool visitEnter (ConditionNode &) const override
 
bool visitEnter (DecisionNode &) const override
 
bool visitEnter (AlgorithmNode &node) const override
 
bool visit (AlgorithmNode &nodeAt) override
 
bool passed () const
 
std::string reply ()
 
void reset () override
 
virtual bool visit (DecisionNode &)
 
virtual bool visit (DataNode &)
 
virtual bool visit (ConditionNode &)
 
virtual bool visitEnter (DataNode &) const
 
- Public Member Functions inherited from concurrency::IGraphVisitor
virtual ~IGraphVisitor ()=default
 

Private Member Functions

bool on_stack (const AlgorithmNode &node) const
 

Private Attributes

unsigned int m_nodes_count { 0 }
 
std::unordered_map< AlgorithmNode *, std::pair< unsigned int, unsigned int > > m_lowlinks
 
std::map< unsigned int, std::vector< AlgorithmNode * > > m_scc
 
std::vector< AlgorithmNode * > m_stack
 
std::ostringstream m_status { " No strongly connected components found in DF realm" }
 

Detailed Description

The visitor implements the Tarjan algorithm for searching strongly connected components in the data flow realm of precedence rules graph.

Definition at line 168 of file Validators.h.

Member Function Documentation

◆ on_stack()

bool concurrency::TarjanSCCFinder::on_stack ( const AlgorithmNode & node) const
inlineprivate

Definition at line 198 of file Validators.h.

198 {
199 return std::find( m_stack.begin(), m_stack.end(), &node ) != m_stack.end() ? true : false;
200 }
std::vector< AlgorithmNode * > m_stack
Definition Validators.h:206

◆ passed()

bool concurrency::TarjanSCCFinder::passed ( ) const
inline

Definition at line 182 of file Validators.h.

182 {
183 return m_scc.empty() ||
184 !std::any_of( m_scc.begin(), m_scc.end(), []( const auto& pr ) { return pr.second.size() > 1; } );
185 }
std::map< unsigned int, std::vector< AlgorithmNode * > > m_scc
Definition Validators.h:205

◆ reply()

std::string concurrency::TarjanSCCFinder::reply ( )

Definition at line 281 of file Validators.cpp.

281 {
282
283 if ( !passed() ) {
284
285 m_status << " Strongly connected components found in DF realm:";
286
287 for ( auto& pr : m_scc ) {
288 if ( pr.second.size() > 1 ) {
289 m_status << "\n o [lowlink:" << std::to_string( pr.first ) << "] |";
290
291 // rotate SCCs to get reproducible order
292 std::vector sortedSCC( pr.second.begin(), pr.second.end() );
293 std::sort( sortedSCC.begin(), sortedSCC.end(), CompareNodes<AlgorithmNode*>() );
294 std::rotate( pr.second.begin(), std::find( pr.second.begin(), pr.second.end(), sortedSCC.front() ),
295 pr.second.end() );
296
297 for ( const auto& algoPtr : pr.second ) m_status << " " << algoPtr->name() << " |";
298 }
299 }
300 }
301
302 return m_status.str();
303 }
std::ostringstream m_status
Definition Validators.h:208

◆ reset()

void concurrency::TarjanSCCFinder::reset ( )
inlineoverridevirtual

Reimplemented from concurrency::IGraphVisitor.

Definition at line 189 of file Validators.h.

189 {
190 m_nodes_count = 0;
191 m_stack.clear();
192 m_lowlinks.clear();
193 m_scc.clear();
194 m_status = std::ostringstream{ " No strongly connected components found in DF realm" };
195 }
std::unordered_map< AlgorithmNode *, std::pair< unsigned int, unsigned int > > m_lowlinks
Definition Validators.h:204

◆ visit() [1/4]

bool concurrency::TarjanSCCFinder::visit ( AlgorithmNode & nodeAt)
overridevirtual

Reimplemented from concurrency::IGraphVisitor.

Definition at line 235 of file Validators.cpp.

235 {
236
237 // DFS ******************************************************
238
239 // put the node on stack
240 m_stack.push_back( &nodeAt );
241
242 // initialize and cache the low-link value of this node
243 m_nodes_count += 1;
244 unsigned int lowlink_init{ m_nodes_count };
245 // record initial low-link value of this node
246 m_lowlinks.insert( { &nodeAt, { lowlink_init, lowlink_init } } );
247 auto& lowlink = m_lowlinks[&nodeAt].second;
248
249 for ( const auto& output : nodeAt.getOutputDataNodes() ) {
250 for ( const auto& consumer : output->getConsumers() ) {
251 consumer->accept( *this );
252 // DFS callback ******************************************
253 // propagate the low-link value back
254 if ( on_stack( *consumer ) ) {
255 if ( lowlink > m_lowlinks[consumer].second ) lowlink = m_lowlinks[consumer].second;
256 // this allows to detect loops (i.e., a cycle consisting of a single algorithm node: A->d->A),
257 // but there is a protection against this case at Algorithm::initialize()
258 if ( consumer == &nodeAt ) m_scc.insert( { lowlink, { &nodeAt } } );
259 }
260 }
261 }
262
263 // If an SCC is found, book-keep it and take it off the stack
264 if ( lowlink_init == lowlink ) {
265 if ( m_scc.find( lowlink ) == m_scc.end() ) m_scc.insert( { lowlink, {} } );
266
267 for ( auto stackNodeRIter = m_stack.rbegin(); stackNodeRIter != m_stack.rend(); ++stackNodeRIter ) {
268
269 bool lastSCCNodeOnStack{ *stackNodeRIter == &nodeAt };
270 if ( lowlink == m_lowlinks[*stackNodeRIter].second ) m_scc[lowlink].push_back( *stackNodeRIter );
271
272 m_stack.pop_back();
273 if ( lastSCCNodeOnStack ) break;
274 }
275 }
276
277 return true;
278 }
bool on_stack(const AlgorithmNode &node) const
Definition Validators.h:198

◆ visit() [2/4]

virtual bool concurrency::IGraphVisitor::visit ( ConditionNode & )
inlinevirtual

Reimplemented from concurrency::IGraphVisitor.

Definition at line 34 of file IGraphVisitor.h.

34{ return true; }

◆ visit() [3/4]

virtual bool concurrency::IGraphVisitor::visit ( DataNode & )
inlinevirtual

Reimplemented from concurrency::IGraphVisitor.

Definition at line 31 of file IGraphVisitor.h.

31{ return true; }

◆ visit() [4/4]

virtual bool concurrency::IGraphVisitor::visit ( DecisionNode & )
inlinevirtual

Reimplemented from concurrency::IGraphVisitor.

Definition at line 25 of file IGraphVisitor.h.

25{ return true; }

◆ visitEnter() [1/4]

bool concurrency::TarjanSCCFinder::visitEnter ( AlgorithmNode & node) const
inlineoverridevirtual

Reimplemented from concurrency::IGraphVisitor.

Definition at line 175 of file Validators.h.

175 {
176 // check if the node was already visited
177 return m_lowlinks.find( &node ) != m_lowlinks.end() ? false : true;
178 }

◆ visitEnter() [2/4]

bool concurrency::TarjanSCCFinder::visitEnter ( ConditionNode & ) const
inlineoverridevirtual

Reimplemented from concurrency::IGraphVisitor.

Definition at line 173 of file Validators.h.

173{ return false; }

◆ visitEnter() [3/4]

virtual bool concurrency::IGraphVisitor::visitEnter ( DataNode & ) const
inlinevirtual

Reimplemented from concurrency::IGraphVisitor.

Definition at line 30 of file IGraphVisitor.h.

30{ return true; }

◆ visitEnter() [4/4]

bool concurrency::TarjanSCCFinder::visitEnter ( DecisionNode & ) const
inlineoverridevirtual

Reimplemented from concurrency::IGraphVisitor.

Definition at line 174 of file Validators.h.

174{ return false; }

Member Data Documentation

◆ m_lowlinks

std::unordered_map<AlgorithmNode*, std::pair<unsigned int, unsigned int> > concurrency::TarjanSCCFinder::m_lowlinks
private

Definition at line 204 of file Validators.h.

◆ m_nodes_count

unsigned int concurrency::TarjanSCCFinder::m_nodes_count { 0 }
private

Definition at line 202 of file Validators.h.

202{ 0 };

◆ m_scc

std::map<unsigned int, std::vector<AlgorithmNode*> > concurrency::TarjanSCCFinder::m_scc
private

Definition at line 205 of file Validators.h.

◆ m_stack

std::vector<AlgorithmNode*> concurrency::TarjanSCCFinder::m_stack
private

Definition at line 206 of file Validators.h.

◆ m_status

std::ostringstream concurrency::TarjanSCCFinder::m_status { " No strongly connected components found in DF realm" }
private

Definition at line 208 of file Validators.h.

208{ " No strongly connected components found in DF realm" };

The documentation for this class was generated from the following files: