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++;
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
00763
00764
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_