Main Page   Class Hierarchy   Compound List   File List   Compound Members  

PG_algorithm.hpp

00001 #ifndef _PG_ALGORITHM_HPP_
00002 #define _PG_ALGORITHM_HPP_
00003 
00004 #include "boost/tuple/tuple.hpp"
00005 #include <limits>
00006 
00007 namespace ParGraph
00008 {
00009 
00010 template< class Graph, class Functor >
00011 void for_each_vertex( Graph & g, Functor & f )
00012 {
00013   typedef typename Graph::VertexIterator Iter;
00014   Iter iter, end;
00015 
00016   boost::tie( iter, end ) = g.get_local_vertices();
00017   for(; iter != end ; iter++ )
00018   {
00019     f( *iter );
00020   }
00021 }
00022 
00023 template< class Graph, class Iterator, class Functor >
00024 void for_each_vertex( Graph & g, Iterator begin, Iterator end, Functor & f )
00025 {
00026   for( Iterator iter = begin ; iter != end ; iter++ )
00027   {
00028      f( g.get_known_vertex( *iter ) );
00029   }
00030 }
00031 
00032 template< class Graph, class EdgeMap, class Functor >
00033 void for_each_out_edge( Graph & g, EdgeMap m, Functor & f )
00034 {
00035   typedef typename Graph::VertexIterator VIter;
00036   typedef typename EdgeMap::out_iterator EIter;
00037   VIter viter, vend;
00038 
00039   boost::tie( viter, vend ) = g.get_local_vertices();
00040   for(; viter != vend ; viter++ )
00041   {
00042     EIter eiter, eend;
00043     boost::tie( eiter, eend ) = out_edges( g, *viter, m );
00044     for(; eiter != eend ; eiter++ )
00045     {
00046       f( *eiter );
00047     }
00048   }
00049 }
00050 
00051 template< class Graph, class Iterator, class EdgeMap, class Functor >
00052 void
00053 for_each_adjacent_vertex( Graph &g, Iterator vset_begin, Iterator vset_end, EdgeMap emap, Functor &f )
00054 {
00055   AllToAllBuffer forward_buffer;
00056 
00057   for( Iterator vset_it = vset_begin ; vset_it != vset_end ; vset_it++ )
00058   {
00059     typename EdgeMap::out_iterator e_it, e_end, e_next;
00060     typename Graph::KnownVertex v1 = *vset_it;
00061 
00062     boost::tie( e_it, e_end ) = out_edges( g, v1, emap );
00063     for( ; e_it != e_end ; e_it = e_next )
00064     {
00065       e_next = e_it; e_next++; // with this, the user is able to erase e_it without problems
00066       typename Graph::KnownVertex v2 = target( *e_it, g );
00067       if( g.is_vertex_local( v2 ) )
00068       {
00069         f.local_computation( v1, *e_it, v2 );
00070       }
00071       else
00072       {
00073         forward_buffer.set_proc( g.owning_processor( v2 ) );
00074         VertexID_t v = get_id(v1);
00075         forward_buffer.put( &v, 1 );
00076         EdgeID_t e = get_edge_id(*e_it);
00077         forward_buffer.put( &e, 1 );
00078         v = get_id(v2);
00079         forward_buffer.put( &v, 1 );
00080         typename Functor::first_property_type tmp_prop = 
00081             f.first_computation_on_v1( v1, *e_it, v2 );
00082         put_property_into_buffer( tmp_prop, forward_buffer );
00083       }
00084     }
00085   }
00086 
00087   forward_buffer.communicate();
00088 
00089   while( !forward_buffer.is_empty() )
00090   {
00091     VertexID_t v1id, v2id;
00092     EdgeID_t e;
00093     proc_t p = forward_buffer.get( &v1id, 1 );
00094     forward_buffer.get( &e, 1 );
00095     forward_buffer.get( &v2id, 1 );
00096     typename Functor::first_property_type tmp_prop;
00097     get_property_from_buffer( tmp_prop, forward_buffer );
00098     typename Functor::second_property_type tmp_prop2 =
00099         f.first_computation_on_v2( v1id, e, v2id, tmp_prop );
00100     forward_buffer.set_proc( p );
00101     forward_buffer.put( &v1id, 1 );
00102     forward_buffer.put( &e, 1 );
00103     forward_buffer.put( &v2id, 1 );
00104     put_property_into_buffer( tmp_prop2, forward_buffer );
00105   }
00106 
00107   forward_buffer.communicate();
00108 
00109   while( !forward_buffer.is_empty() )
00110   {
00111     VertexID_t v1id, v2id;
00112     EdgeID_t e;
00113     forward_buffer.get( &v1id, 1 );
00114     forward_buffer.get( &e, 1 );
00115     forward_buffer.get( &v2id, 1 );
00116     typename Functor::second_property_type tmp_prop2;
00117     get_property_from_buffer( tmp_prop2, forward_buffer );
00118     f.second_computation_on_v1( v1id, e, v2id, tmp_prop2 );
00119   }
00120 }
00121 
00122 template< class Set, class Type >
00123 inline void insert( Set & s, Type v )
00124 {
00125   s.insert( v );
00126 }
00127 
00128 template< class Type >
00129 inline void insert( std::vector<Type> & s, Type v )
00130 {
00131   s.push_back( v );
00132 }
00133 
00134 template< class Type >
00135 inline void insert( std::list<Type> & s, Type v )
00136 {
00137   s.push_back( v );
00138 }
00139 
00140 struct bfs_level_tag {};
00141 
00142 template< class Graph, class LevelMap, class Set, class Visitors >
00143 struct bfs_inner_part
00144 {
00145   typedef typename Visitors::first_property_type first_property_type;
00146   typedef typename Visitors::second_property_type second_property_user_type; 
00147   typedef property< bfs_level_tag, typename LevelMap::value_type, second_property_user_type > second_property_type;
00148 
00149   Graph & g;
00150   LevelMap lmap;
00151   typename LevelMap::value_type current_level;
00152   Visitors & vis;
00153   Set * grayset;
00154 
00155   bfs_inner_part( Graph & _g, LevelMap _l, Visitors & _vis ) : 
00156       g(_g), lmap(_l), current_level(0), vis(_vis) { }
00157 
00158   template< class Edge >
00159   void local_computation( typename Graph::KnownVertex v1, Edge e, typename Graph::KnownVertex v2 )
00160   {
00161     vis.examine_edge( v1, e, v2 );
00162     typename LevelMap::value_type l;
00163     if( (l = get( lmap, v2, g )) == std::numeric_limits< typename LevelMap::value_type >::max() )
00164     {
00165       put( lmap, v2, g, current_level + 1 );
00166       insert( *grayset, v2 );
00167       vis.discover_vertex( v2 );
00168       vis.target_new_vertex( v1, e, v2 );
00169     }
00170     else if( l > current_level )
00171     {
00172       vis.target_next_level( v1, e, v2 );
00173     }
00174     else if( l == current_level )
00175     {
00176       vis.target_same_level( v1, e, v2 );
00177     }
00178     else
00179     {
00180       vis.target_prev_level( v1, e, v2 );
00181     }
00182   }
00183 
00184   template< class Edge >
00185   first_property_type first_computation_on_v1( typename Graph::KnownVertex v1, Edge e, typename Graph::KnownVertex v2 )
00186   {
00187     first_property_type p;
00188     vis.examine_edge( v1, e, v2, p );
00189     return p;
00190   }
00191   second_property_type first_computation_on_v2( VertexID_t v1, EdgeID_t e, VertexID_t v2id, first_property_type & first_prop )
00192   {
00193     typename Graph::KnownVertex v2 = g.get_known_vertex(v2id);
00194     second_property_user_type second_prop;
00195     typename LevelMap::value_type l;
00196     if( (l = get( lmap, v2, g )) == std::numeric_limits< typename LevelMap::value_type >::max() )
00197     {
00198       put( lmap, v2, g, current_level + 1 );
00199       insert( *grayset, v2 );
00200       vis.discover_vertex( v2 );
00201       vis.target_new_vertex( v1, e, v2id, first_prop, second_prop );
00202     }
00203     else if( l > current_level )
00204     {
00205       vis.target_next_level( v1, e, v2id, first_prop, second_prop );
00206     }
00207     else if( l == current_level )
00208     {
00209       vis.target_same_level( v1, e, v2id, first_prop, second_prop );
00210     }
00211     else vis.target_prev_level( v1, e, v2id, first_prop, second_prop );
00212     return second_property_type( l, second_prop );
00213   }
00214   void second_computation_on_v1( VertexID_t v1, EdgeID_t e, VertexID_t v2, second_property_type & second_prop )
00215   {
00216     typename LevelMap::value_type l = get_property_value( second_prop, bfs_level_tag() );
00217     if( l == std::numeric_limits< typename LevelMap::value_type >::max() )
00218     {
00219       vis.back_from_target_new_vertex( v1, e, v2, (second_property_user_type &) second_prop );
00220     }
00221     else if( l > current_level )
00222     {
00223       vis.back_from_target_next_level( v1, e, v2, (second_property_user_type &) second_prop );
00224     }
00225     else if( l == current_level )
00226     {
00227       vis.back_from_target_same_level( v1, e, v2, (second_property_user_type &) second_prop );
00228     }
00229     else
00230     {
00231       vis.back_from_target_prev_level( v1, e, v2, (second_property_user_type &) second_prop );
00232     }
00233   }
00234 };
00235 
00236 template< class Graph, class PMap >
00237 struct set_each_vertex_property
00238 {
00239   Graph &g;
00240   PMap pmap;
00241   typename PMap::value_type val;
00242 
00243   set_each_vertex_property(  Graph & _g, PMap map, typename PMap::value_type _val ) :
00244       g(_g), pmap(map), val(_val) {}
00245   void operator() ( typename Graph::KnownVertex v )
00246   {
00247     put( pmap, g.get_property_reference(v), val );
00248   }
00249 };
00250 
00251 template< class Visitor >
00252 struct bfs_finish_vertex_type
00253 {
00254   Visitor & vis;
00255 
00256   bfs_finish_vertex_type( Visitor & _v ) : vis(_v) {}
00257 
00258   template< class TYPE >
00259   void operator() ( TYPE v ) 
00260   {
00261     vis.finish_vertex( v );
00262   }
00263 };
00264 
00265 template< class Visitor >
00266 struct bfs_examine_vertex_type
00267 {
00268   Visitor & vis;
00269 
00270   bfs_examine_vertex_type( Visitor & _v ) : vis(_v) {}
00271 
00272   template< class TYPE >
00273   void operator() ( TYPE v ) 
00274   {
00275     vis.examine_vertex( v );
00276   }
00277 };
00278 
00279 template< class Graph, class Set, class LevelMap, class EdgeMap, class Visitors >
00280 void breadth_first_search( Graph & g, Set &grayset, Set &next_grayset, bool * user_found,
00281                           LevelMap lmap, EdgeMap emap, Visitors vis )
00282 {
00283   *user_found = false;
00284   pair< typename Graph::VertexIterator, typename Graph::VertexIterator > range =
00285       g.get_local_vertices();
00286   typename Graph::VertexIterator v_iter = range.first;
00287   for(; v_iter != range.second ; v_iter++ )
00288   {
00289     put( lmap, *v_iter, g, std::numeric_limits< typename LevelMap::value_type >::max() );
00290   }
00291   bfs_finish_vertex_type< Visitors >
00292       bfs_finish_vertex( vis );
00293   bfs_examine_vertex_type< Visitors >
00294       bfs_examine_vertex( vis );
00295   typename Set::iterator s_iter = grayset.begin();
00296   for(; s_iter != grayset.end() ; s_iter++ )
00297   {
00298     put( lmap, *s_iter, g, 0 );
00299     vis.discover_vertex( *s_iter );
00300   }
00301   next_grayset.clear();
00302 
00303   bfs_inner_part< Graph, LevelMap, Set, Visitors > ip( g, lmap, vis );
00304 
00305   vis.search_finished( user_found );
00306   bool found = PG_ReduceOr( *user_found );
00307   while( !found )
00308   {
00309     std::for_each( grayset.begin(), grayset.end(), bfs_examine_vertex );
00310 
00311     ip.grayset = &next_grayset;
00312 
00313     for_each_adjacent_vertex( g, grayset.begin(), grayset.end(), emap, ip );
00314     ip.current_level++;
00315 
00316     std::for_each( grayset.begin(), grayset.end(), bfs_finish_vertex );
00317 
00318     grayset.clear();
00319     grayset.swap( next_grayset );
00320 
00321     found = PG_ReduceAnd( grayset.empty() );
00322     
00323     vis.search_finished( user_found );
00324     found |= PG_ReduceOr( *user_found );
00325   }
00326 }
00327 
00328 struct true_tag {};
00329 struct false_tag {};
00330 
00331 template< class A, class B >
00332 struct IsSame
00333 {
00334   typedef false_tag type;
00335 };
00336 
00337 template< class A >
00338 struct IsSame< A, A >
00339 {
00340   typedef true_tag type;
00341 };
00342 
00343 template< class Visitor, class TYPE1, class TYPE2 >
00344 void visitor_dispatch( false_tag, Visitor & vis, VertexID_t v1, EdgeID_t e, VertexID_t v2, TYPE1 & type1, TYPE2 & type2 )
00345 {
00346 }
00347 
00348 template< class Visitor, class TYPE1, class TYPE2 >
00349 void visitor_dispatch( true_tag, Visitor & vis, VertexID_t v1, EdgeID_t e, VertexID_t v2, TYPE1 & type1, TYPE2 & type2 )
00350 {
00351   vis( v1, e, v2, type1, type2 );
00352 }
00353 
00354 template< class Visitor, class V, class E, class TYPE1 >
00355 void visitor_dispatch( false_tag, Visitor & vis, V v1, E & e, V v2, TYPE1 & type1 )
00356 {
00357 }
00358 
00359 template< class Visitor, class V, class E, class TYPE1 >
00360 void visitor_dispatch( true_tag, Visitor & vis, V v1, E & e, V v2, TYPE1 & type1 )
00361 {
00362   vis( v1, e, v2, type1 );
00363 }
00364 
00365 template< class Visitor, class TYPE1 >
00366 void visitor_dispatch( false_tag, Visitor & vis, VertexID_t v1, EdgeID_t e, VertexID_t v2, TYPE1 & type1 )
00367 {
00368 }
00369 
00370 template< class Visitor, class TYPE1 >
00371 void visitor_dispatch( true_tag, Visitor & vis, VertexID_t v1, EdgeID_t e, VertexID_t v2, TYPE1 & type1 )
00372 {
00373   vis( v1, e, v2, type1 );
00374 }
00375 
00376 template< class Visitor, class V, class E >
00377 void visitor_dispatch( false_tag, Visitor & vis, V v1, E e, V v2 )
00378 {
00379 }
00380 
00381 template< class Visitor, class V, class E >
00382 void visitor_dispatch( true_tag, Visitor & vis, V v1, E e, V v2 )
00383 {
00384   vis( v1, e, v2 );
00385 }
00386 
00387 template< class Visitor, class TYPE1 >
00388 void visitor_dispatch( false_tag, Visitor & vis, TYPE1 type1 )
00389 {
00390 }
00391 
00392 template< class Visitor, class TYPE1 >
00393 void visitor_dispatch( true_tag, Visitor & vis, TYPE1 type1 )
00394 {
00395   vis( type1 );
00396 }
00397 
00398 template< class VISITOR, class TAG, class V, class E, class TYPE1 >
00399 void invoke_visitor( VISITOR & vis, TAG tag, V v1, E & e, V v2, TYPE1 & type1 )
00400 {
00401   typedef typename VISITOR::Category Cat;
00402   typedef typename IsSame< Cat, TAG >::type DispatchFlag;
00403   visitor_dispatch( DispatchFlag(), vis, v1, e, v2, type1 );
00404 }
00405 
00406 template< class VISITOR, class TAG, class TYPE1 >
00407 void invoke_visitor( VISITOR & vis, TAG tag, VertexID_t v1, EdgeID_t e, VertexID_t v2, TYPE1 & type1 )
00408 {
00409   typedef typename VISITOR::Category Cat;
00410   typedef typename IsSame< Cat, TAG >::type DispatchFlag;
00411   visitor_dispatch( DispatchFlag(), vis, v1, e, v2, type1 );
00412 }
00413 
00414 template< class REST1, class REST2, class TAG, class V, class E, class TYPE1 >
00415 void invoke_visitor( pair< REST1, REST2 > & vlist, TAG tag, V v1, E & e, V v2, TYPE1 & type1 )
00416 {
00417   invoke_visitor( vlist.first, tag, v1, e, v2, type1 );
00418   invoke_visitor( vlist.second, tag, v1, e, v2, type1 );
00419 }
00420 
00421 template< class REST1, class REST2, class TAG, class TYPE1 >
00422 void invoke_visitor( pair< REST1, REST2 > & vlist, TAG tag, VertexID_t v1, EdgeID_t e, VertexID_t v2, TYPE1 & type1 )
00423 {
00424   invoke_visitor( vlist.first, tag, v1, e, v2, type1 );
00425   invoke_visitor( vlist.second, tag, v1, e, v2, type1 );
00426 }
00427 
00428 template< class VISITOR, class TAG, class TYPE1, class TYPE2 >
00429 void invoke_visitor( VISITOR & vis, TAG tag, VertexID_t v1, EdgeID_t e, VertexID_t v2, TYPE1 & type1, TYPE2 & type2 )
00430 {
00431   typedef typename VISITOR::Category Cat;
00432   typedef typename IsSame< Cat, TAG >::type DispatchFlag;
00433   visitor_dispatch( DispatchFlag(), vis, v1, e, v2, type1, type2 );
00434 }
00435 
00436 template< class REST1, class REST2, class TAG, class TYPE1, class TYPE2 >
00437 void invoke_visitor( pair< REST1, REST2 > & vlist, TAG tag, VertexID_t v1, EdgeID_t e, VertexID_t v2, TYPE1 & type1, TYPE2 & type2 )
00438 {
00439   invoke_visitor( vlist.first, tag, v1, e, v2, type1, type2 );
00440   invoke_visitor( vlist.second, tag, v1, e, v2, type1, type2 );
00441 }
00442 
00443 template< class VISITOR, class TAG, class V, class E >
00444 void invoke_visitor( VISITOR & vis, TAG tag, V v1, E e, V v2 )
00445 {
00446   typedef typename VISITOR::Category Cat;
00447   typedef typename IsSame< Cat, TAG >::type DispatchFlag;
00448   visitor_dispatch( DispatchFlag(), vis, v1, e, v2 );
00449 }
00450 
00451 template< class REST1, class REST2, class TAG, class V, class E >
00452 void invoke_visitor( pair< REST1, REST2 > & vlist, TAG tag, V v1, E e, V v2 )
00453 {
00454   invoke_visitor( vlist.first, tag, v1, e, v2 );
00455   invoke_visitor( vlist.second, tag, v1, e, v2 );
00456 }
00457 
00458 template< class VISITOR, class TAG, class TYPE1 >
00459 void invoke_visitor( VISITOR & vis, TAG tag, TYPE1 type1 )
00460 {
00461   typedef typename VISITOR::Category Cat;
00462   typedef typename IsSame< Cat, TAG >::type DispatchFlag;
00463   visitor_dispatch( DispatchFlag(), vis, type1 );
00464 }
00465 
00466 template< class REST1, class REST2, class TAG, class TYPE1 >
00467 void invoke_visitor( pair< REST1, REST2 > & vlist, TAG tag, TYPE1 type1 )
00468 {
00469   invoke_visitor( vlist.first, tag, type1 );
00470   invoke_visitor( vlist.second, tag, type1 );
00471 }
00472 
00473 struct no_visitor {};
00474 
00475 struct on_discover_vertex {};
00476 struct on_examine_vertex {};
00477 struct on_finish_vertex {};
00478 
00479 struct on_examine_edge {};
00480 struct on_target_new_vertex {};
00481 struct on_target_next_level {};
00482 struct on_target_same_level {};
00483 struct on_target_prev_level {};
00484 struct on_back_from_target_new_vertex {};
00485 struct on_back_from_target_next_level {};
00486 struct on_back_from_target_same_level {};
00487 struct on_back_from_target_prev_level {};
00488 
00489 struct on_search_finished {};
00490 
00491 template< class DistributionTypes, class Visitors >
00492 class bfs_visitor
00493 {
00494   Visitors vis;
00495 public:
00496   bfs_visitor( Visitors & v ) : vis(v) {}
00497 
00498   typedef typename DistributionTypes::first_type first_property_type;
00499   typedef typename DistributionTypes::second_type second_property_type;
00500 
00501   template< class V >
00502   void discover_vertex( V v )
00503   {
00504     invoke_visitor( vis, on_discover_vertex(), v );
00505   }
00506   template< class V >
00507   void examine_vertex( V v )
00508   {
00509     invoke_visitor( vis, on_examine_vertex(), v );
00510   }
00511   template< class V >
00512   void finish_vertex( V v )
00513   {
00514     invoke_visitor( vis, on_finish_vertex(), v );
00515   }
00516   template< class V, class E >
00517   void examine_edge( V v1, E e, V v2 )
00518   {
00519     invoke_visitor( vis, on_examine_edge(), v1, e, v2 );
00520   }
00521   template< class V, class E >
00522   void examine_edge( V v1, E e, V v2,
00523                      first_property_type & p )
00524   {
00525     invoke_visitor( vis, on_examine_edge(), v1, e, v2, p );
00526   }
00527   template< class V, class E >
00528   void target_new_vertex( V v1, E e, V v2 )
00529   {
00530     invoke_visitor( vis, on_target_new_vertex(), v1, e, v2 );
00531   }
00532   void target_new_vertex( VertexID_t v1, EdgeID_t e, VertexID_t v2,
00533                      first_property_type & p1, second_property_type & p2 )
00534   {
00535     invoke_visitor( vis, on_target_new_vertex(), v1, e, v2, p1, p2 );
00536   }
00537   template< class V, class E >
00538   void target_next_level( V v1, E e, V v2 )
00539   {
00540     invoke_visitor( vis, on_target_next_level(), v1, e, v2 );
00541   }
00542   void target_next_level( VertexID_t v1, EdgeID_t e, VertexID_t v2,
00543                      first_property_type & p1, second_property_type & p2 )
00544   {
00545     invoke_visitor( vis, on_target_next_level(), v1, e, v2, p1, p2 );
00546   }
00547   template< class V, class E >
00548   void target_same_level( V v1, E e, V v2 )
00549   {
00550     invoke_visitor( vis, on_target_same_level(), v1, e, v2 );
00551   }
00552   void target_same_level( VertexID_t v1, EdgeID_t e, VertexID_t v2,
00553                      first_property_type & p1, second_property_type & p2 )
00554   {
00555     invoke_visitor( vis, on_target_same_level(), v1, e, v2, p1, p2 );
00556   }
00557   template< class V, class E >
00558   void target_prev_level( V v1, E e, V v2 )
00559   {
00560     invoke_visitor( vis, on_target_prev_level(), v1, e, v2 );
00561   }
00562   void target_prev_level( VertexID_t v1, EdgeID_t e, VertexID_t v2,
00563                      first_property_type & p1, second_property_type & p2 )
00564   {
00565     invoke_visitor( vis, on_target_prev_level(), v1, e, v2, p1, p2 );
00566   }
00567   void back_from_target_new_vertex( VertexID_t v1, EdgeID_t e, VertexID_t v2,
00568                                second_property_type & p2 )
00569   {
00570     invoke_visitor( vis, on_back_from_target_new_vertex(), v1, e, v2, p2 );
00571   }
00572   void back_from_target_next_level( VertexID_t v1, EdgeID_t e, VertexID_t v2,
00573                                second_property_type & p2 )
00574   {
00575     invoke_visitor( vis, on_back_from_target_next_level(), v1, e, v2, p2 );
00576   }
00577   void back_from_target_same_level( VertexID_t v1, EdgeID_t e, VertexID_t v2,
00578                               second_property_type & p2 )
00579   {
00580     invoke_visitor( vis, on_back_from_target_same_level(), v1, e, v2, p2 );
00581   }
00582   void back_from_target_prev_level( VertexID_t v1, EdgeID_t e, VertexID_t v2,
00583                                second_property_type & p2 )
00584   {
00585     invoke_visitor( vis, on_back_from_target_prev_level(), v1, e, v2, p2 );
00586   }
00587   void search_finished( bool * flag )
00588   {
00589     invoke_visitor( vis, on_search_finished(), flag );
00590   }
00591 };
00592 
00593 template< class First, class Second >
00594 struct bfs_distribution_types
00595 {
00596   typedef First first_type;
00597   typedef Second second_type;
00598 };
00599 
00600 template< class DistTypes, class Visitors >
00601 inline bfs_visitor< DistTypes, Visitors >
00602 make_bfs_visitor( DistTypes, Visitors vlist )
00603 {
00604   return bfs_visitor< DistTypes, Visitors >( vlist );
00605 }
00606 
00607 template< class Category >
00608 struct bfs_next_category_traits {};
00609 
00610 template< >
00611 struct bfs_next_category_traits< on_target_new_vertex >
00612 {
00613     typedef on_back_from_target_new_vertex Category;
00614 };
00615 
00616 template< >
00617 struct bfs_next_category_traits< on_target_next_level >
00618 {
00619     typedef on_back_from_target_next_level Category;
00620 };
00621 
00622 template< >
00623 struct bfs_next_category_traits< on_target_same_level >
00624 {
00625     typedef on_back_from_target_same_level Category;
00626 };
00627 
00628 template< >
00629 struct bfs_next_category_traits< on_target_prev_level >
00630 {
00631     typedef on_back_from_target_prev_level Category;
00632 };
00633 
00637 template< class Set >
00638 struct bfs_is_vertex_inside_targetset {
00639   typedef on_discover_vertex Category;
00640 
00641   Set & t_set;
00642   bool *t_found;
00643   bfs_is_vertex_inside_targetset( Set & s, bool * f ) : t_set(s), t_found(f) { }
00644 
00645   template< class Vertex >
00646   void operator() ( Vertex v )
00647   {
00648     if( t_set.find( v ) != t_set.end() ) *t_found = true;
00649   }
00650 };
00651 
00652 template< class Cat, class Graph, class EdgeMap, class EdgePropertyMap >
00653 struct bfs_set_edgeproperty_both_sides
00654 {
00655   typedef Cat Category;
00656 
00657   struct bfs_set_edgeproperty_other_side
00658   {
00659     typedef typename bfs_next_category_traits<Cat>::Category Category;
00660 
00661     Graph & g;
00662     const typename EdgePropertyMap::value_type value;
00663 
00664     bfs_set_edgeproperty_other_side( Graph &_g, typename EdgePropertyMap::value_type val ) : g(_g), value(val) {}
00665 
00666     void operator() ( VertexID_t v1, EdgeID_t e, VertexID_t v2,  no_property & ) const
00667     {
00668       put( EdgePropertyMap(), out_edge( g, v1, e, EdgeMap() ), value );
00669     }
00670   };
00671 
00672   bfs_set_edgeproperty_other_side f2;
00673 
00674   bfs_set_edgeproperty_both_sides( Graph &_g, typename EdgePropertyMap::value_type val ) : f2(_g, val) {}
00675 
00676   void operator() ( Vertex v1, typename EdgeMap::Edge e, Vertex v2 ) const
00677   {
00678     put( EdgePropertyMap(), e, f2.value );
00679   }
00680   void operator() ( VertexID_t v1, EdgeID_t e, VertexID_t v2, no_property &,  no_property & ) const
00681   {
00682     put( EdgePropertyMap(), in_edge( f2.g, v2, e, EdgeMap() ), f2.value );
00683   }
00684 
00685   pair< bfs_set_edgeproperty_both_sides< Cat, Graph, EdgeMap, EdgePropertyMap >, bfs_set_edgeproperty_other_side >
00686   get_functors()
00687   {
00688       return make_pair( *this, f2 );
00689   }
00690 };
00691 
00692 template< class EdgeMap >
00693 struct bfs_distribute_use_ingoing_edges
00694 {
00695   template< class Graph, class Vertex >
00696   void operator() ( Graph & g, Vertex v, size_t * incount )
00697   {
00698     for( size_t i = 0 ; i < size() ; i++ ) incount[i] = 0;
00699 
00700     typename EdgeMap::in_iterator eit, eend;
00701     boost::tie( eit, eend ) = in_edges( g, v, EdgeMap() );
00702     for(; eit != eend ; eit++ )
00703     {
00704       incount[ g.owning_processor( source(*eit,g) ) ]++;
00705     }
00706   }
00707 };
00708 
00709 template< class G, class S, class RankFunctor >
00710 struct bfs_distribute
00711 {
00712   typedef on_search_finished Category;
00713 
00714   G &g;
00715   S &m_set;
00716   bfs_distribute( G & _g, S & s ) : g(_g), m_set(s) {}
00717 
00718   void operator()( bool * )
00719   {
00720     if( size() == 1 ) return;
00721 
00722     RankFunctor f;
00723     typename S::iterator vit = m_set.begin(), vend = m_set.end();
00724     size_t * procrank = new size_t[size()], levelsize = 0;
00725     AllGatherBuffer buf;
00726 
00727     for(; vit != vend ; vit++, levelsize++ )
00728     {
00729       f( g, *vit, procrank );
00730       buf.put( get_id( *vit ) );
00731       buf.put( procrank, size() );
00732     }
00733 
00734     buf.communicate();
00735     levelsize = PG_ReduceAdd( levelsize );
00736     
00737     size_t bestsize = levelsize / size();
00738     int maxoverflow = levelsize % size();
00739     size_t * procsize = new size_t[size()];
00740     for( size_t i = 0 ; i < size() ; i++ ) procsize[i] = 0;
00741     std::map< typename G::KnownVertex, proc_t > movements;
00742 
00743     while( ! buf.is_empty() )
00744     {
00745       VertexID_t v;
00746       buf.get( &v );
00747       buf.get( procrank, size() );
00748       proc_t target_proc = 0; size_t best_procrank = 0;
00749       for( size_t i = 0 ; i < size() ; i++ )
00750       {
00751         if( procrank[i] >= best_procrank && ( procsize[i] < bestsize ||
00752                                 (procsize[i] == bestsize && maxoverflow-- > 0 ) ) )
00753         {
00754           best_procrank = procrank[i];
00755           target_proc = i;
00756         }
00757       }
00758       procsize[ target_proc ]++;
00759       if( target_proc != rank() && g.is_vertex_local( v ) )
00760           movements.insert( make_pair( g.get_known_vertex(v), target_proc ) );
00761     }
00762     //if( _libbase.rank() == 0 )
00763     //for(size_t i =0;i<_libbase.size();i++)
00764     //std::cout<<"P"<<i<<" hat "<<procsize[i]<<" Knoten"<<std::endl;
00765 
00766     delete[] procrank; delete[] procsize;
00767 
00768     g.do_distribution( movements, g.use_standard_distribution() );
00769   }
00770 };
00771 
00772 template< class Graph, class Set, class LevelMap, class EdgeMap >
00773 void bfs_do_distribution( Graph &g, Set &grayset1, Set &grayset2, LevelMap lmap, EdgeMap emap )
00774 {
00775   bool found = false;
00776   bfs_distribute< Graph, Set, 
00777       bfs_distribute_use_ingoing_edges< EdgeMap > > vis( g, grayset1 );
00778 
00779   breadth_first_search( g, grayset1, grayset2, &found, lmap, emap,
00780                         make_bfs_visitor( bfs_distribution_types< no_property, no_property >(), vis ) );
00781 }
00782 
00783 }
00784 
00785 #endif // _PG_ALGORITHM_HPP_

Generated on Sun Feb 29 05:14:24 2004 for ParGraph by doxygen1.3-rc3