00001 #ifndef _PG_OWNER_COMPUTES_GRAPH_HPP_
00002 #define _PG_OWNER_COMPUTES_GRAPH_HPP_
00003
00004 #include <map>
00005 #include <vector>
00006 #include <set>
00007 #include <list>
00008 #include <utility>
00009 #include <numeric>
00010 #include <algorithm>
00011 #include <limits>
00012 #include <assert.h>
00013
00014 #include "ParGraph.hpp"
00015
00016 namespace ParGraph
00017 {
00018 using std::pair;
00019 using std::make_pair;
00020
00021 typedef std::map< const VertexID_t, pair<size_t, size_t> > KnownVerticesMap_type;
00022 typedef std::map< const VertexID_t, pair<size_t, size_t> >::iterator known_vertex_type;
00023 typedef std::map< const VertexID_t, pair<size_t, size_t> >::const_iterator const_known_vertex_type;
00024 }
00025
00026 #include "PG_property.hpp"
00027 #include "PG_edges.hpp"
00028 #include "PG_property_map.hpp"
00029 #include "PG_vertex_sets.hpp"
00030 #include "PG_heap.hpp"
00031
00032 namespace std
00033 {
00034 inline bool operator<( const ParGraph::known_vertex_type & v1, const ParGraph::known_vertex_type & v2 )
00035 {
00036 return v1->first < v2->first;
00037 }
00038 }
00039
00040 namespace ParGraph
00041 {
00042
00043 inline VertexID_t get_id( known_vertex_type v )
00044 {
00045 return v->first;
00046 }
00047 inline VertexID_t get_id( const_known_vertex_type v )
00048 {
00049 return v->first;
00050 }
00051
00052 template< class Graph, class Iter >
00053 class LocalVertexIterator
00054 {
00055 Iter iter;
00056 Graph * g;
00057 void find_next()
00058 {
00059 while( iter != g->known_vertices.end() )
00060 {
00061 if( (*iter).second.first % (_libbase.size() + 1) == _libbase.rank() ) return;
00062 iter++;
00063 }
00064 }
00065 public:
00066 LocalVertexIterator() {}
00067 LocalVertexIterator( Graph & _g )
00068 {
00069 g = &_g;
00070 iter = g->known_vertices.begin();
00071 find_next();
00072 }
00073 void operator++(int)
00074 {
00075 if( iter != g->known_vertices.end() )
00076 {
00077 iter++;
00078 find_next();
00079 }
00080 }
00081 bool operator==( const LocalVertexIterator<Graph,Iter> & other )
00082 {
00083 return iter == other.iter;
00084 }
00085 bool operator!=( const LocalVertexIterator<Graph,Iter> & other )
00086 {
00087 return iter != other.iter;
00088 }
00089 Iter operator*()
00090 {
00091 assert(iter!= g->known_vertices.end());
00092 return iter;
00093 }
00094 void goto_end()
00095 {
00096 iter = g->known_vertices.end();
00097 }
00098 int get_index()
00099 {
00100 return (*iter).second.first / (_libbase.size() + 1);
00101 }
00102 };
00103
00104 template< class Graph >
00105 struct SimpleDistribution
00106 {
00107 Graph & g;
00108
00109 SimpleDistribution( Graph & _g ) : g(_g) {}
00110
00111 void notify_id( VertexID_t ) {}
00112 void notify_about_vertices() { g.notify_about_vertices(); }
00113 void write_proc( typename Graph::KnownVertex, AllToAllBuffer & ) {}
00114 proc_t read_proc( AllToAllBuffer & ) { return _libbase.size(); }
00115 };
00116
00117 template< class Graph >
00118 struct StandardDistribution
00119 {
00120 AllGatherBuffer notify_buffer;
00121 Graph & g;
00122
00123 StandardDistribution( Graph & _g ) : notify_buffer(), g(_g) {}
00124
00125 void notify_id( VertexID_t id ) { notify_buffer.put( id ); }
00126 void notify_about_vertices()
00127 {
00128 g.notify_about_vertices( notify_buffer );
00129 }
00130 void write_proc( typename Graph::KnownVertex id , AllToAllBuffer & buf ) { buf.put( g.owning_processor(id) ); }
00131 proc_t read_proc( AllToAllBuffer & buf )
00132 {
00133 proc_t id;
00134 buf.get( &id );
00135 return id;
00136 }
00137 };
00138
00139 template < class VProperty >
00140 class OwnerComputesGraph
00141 {
00142 public:
00143 typedef OwnerComputesGraph< VProperty > self_type;
00144 typedef ParGraph::known_vertex_type KnownVertex;
00145 typedef typename ParGraph::KnownVerticesMap_type::const_iterator const_KnownVertex;
00146 typedef ParGraph::KnownVerticesMap_type KnownVerticesMap_type;
00147 typedef LocalVertexIterator<
00148 self_type, KnownVertex > VertexIterator;
00149 typedef LocalVertexIterator<
00150 const self_type,
00151 const_KnownVertex > const_VertexIterator;
00152 typedef VProperty VertexProperty;
00153
00154 typedef SetWrapper< self_type > VertexSet;
00155 typedef std::list< VertexSet > VertexSets;
00156 typedef typename VertexSets::iterator VertexSetHandle;
00157
00158 private:
00159 VertexID_t lower_free_ID;
00160 EdgeID_t lower_free_edge_ID;
00161 PG_heap< VProperty > local_vertices;
00162 KnownVerticesMap_type known_vertices;
00163 VertexSets registered_vertex_sets;
00164 SimpleDistribution< self_type > simple_helper;
00165 StandardDistribution< self_type > standard_helper;
00166
00167 public:
00168 OwnerComputesGraph();
00169
00170 void set_user_vertex_id_range( VertexID_t id ) { lower_free_ID = id + _libbase.rank(); }
00171 void set_user_edge_id_range( EdgeID_t id ) { lower_free_edge_ID = id + _libbase.rank(); }
00172 EdgeID_t get_free_edge_id() { EdgeID_t tmp = lower_free_edge_ID;
00173 lower_free_edge_ID += _libbase.size(); return tmp; }
00174
00175 pair< KnownVertex, bool > insert();
00176 pair< KnownVertex, bool > insert( const VertexProperty & );
00177 pair< KnownVertex, bool > insert( VertexID_t );
00178 pair< KnownVertex, bool > insert( VertexID_t, const VertexProperty & );
00179 void erase( KnownVertex );
00180
00181 inline VProperty & get_property_reference( VertexID_t v );
00182 inline const VProperty & get_property_reference( VertexID_t v ) const;
00183 inline VProperty & get_property_reference( KnownVertex );
00184 inline const VProperty & get_property_reference( typename KnownVerticesMap_type::const_iterator ) const;
00185 inline KnownVertex get_known_vertex( VertexID_t v );
00186 inline KnownVertex get_known_vertex( VertexID_t v ) const;
00187 inline KnownVertex get_known_vertex( KnownVertex v );
00188
00189 inline bool is_vertex_local( VertexID_t ) const;
00190 inline bool is_vertex_local( KnownVertex ) const;
00191 inline bool is_vertex_local( const_KnownVertex ) const;
00192 inline bool is_vertex_known( VertexID_t ) const;
00193 inline size_t owning_processor( VertexID_t ) const;
00194 inline size_t owning_processor( KnownVertex ) const;
00195 inline size_t owning_processor( const_KnownVertex ) const;
00196 inline KnownVertex ink_known_vertex_counter( VertexID_t );
00197 inline KnownVertex ink_known_vertex_counter_and_set_processor( VertexID_t, proc_t );
00198 inline void ink_known_vertex_counter( KnownVertex );
00199 inline void dek_known_vertex_counter( VertexID_t );
00200 inline void dek_known_vertex_counter( KnownVertex );
00201 inline KnownVertex make_vertex_known( VertexID_t, proc_t );
00202
00203 pair< VertexIterator, VertexIterator > get_local_vertices();
00204 pair< const_VertexIterator, const_VertexIterator > get_local_vertices() const;
00205
00206 template< class DistHelper >
00207 void redistribute( DistHelper & );
00208 template< class PMap, class DistHelper >
00209 void redistribute( PMap, DistHelper & );
00210
00211 template< class DistHelper >
00212 void do_distribution( std::map< KnownVertex, proc_t > &, DistHelper & );
00213 void notify_about_vertices();
00214 void notify_about_vertices_check();
00215 void notify_about_vertices(AllGatherBuffer &);
00216
00217 SimpleDistribution< self_type > & use_simple_distribution()
00218 { return simple_helper; }
00219 StandardDistribution< self_type > & use_standard_distribution()
00220 { return standard_helper; }
00221
00222 friend VertexSetHandle add_vertex_set<>( self_type & );
00223 friend void remove_vertex_set<>( self_type &, VertexSetHandle );
00224
00225 friend class LocalVertexIterator< self_type, KnownVertex >;
00226 friend class LocalVertexIterator< const self_type,
00227 typename KnownVerticesMap_type::const_iterator >;
00228
00229 friend void do_asking_for_position<>( self_type &, AllToAllBuffer & );
00230 private:
00231 KnownVertex insert_from_remote( VertexID_t );
00232 void do_distribution_on_vertex_sets( std::map< KnownVertex, proc_t > & );
00233 void compose_distribution( int *, int, int *, int * );
00234 inline size_t get_vertex_index( VertexID_t ) const;
00235 inline size_t get_vertex_index( KnownVertex ) const;
00236 inline size_t get_vertex_position( VertexID_t ) const;
00237 inline size_t get_vertex_position( KnownVertex ) const;
00238 inline void dek_known_vertex_counter_and_unmark_position( VertexID_t );
00239 inline void dek_known_vertex_counter_and_unmark_position( KnownVertex );
00240 inline void ink_known_vertex_counter_and_set_position( VertexID_t, size_t );
00241 };
00242
00243 template< class Property >
00244 OwnerComputesGraph<Property>::OwnerComputesGraph() : simple_helper(*this), standard_helper(*this)
00245 {
00246 lower_free_edge_ID = _libbase.rank();
00247 lower_free_ID = _libbase.rank();
00248 }
00249
00250 template< class Property >
00251 pair< typename OwnerComputesGraph<Property>::KnownVertex, bool >
00252 OwnerComputesGraph<Property>::insert()
00253 {
00254 VertexID_t new_ID = lower_free_ID;
00255 lower_free_ID += _libbase.size();
00256 insert( new_ID );
00257 return new_ID;
00258 }
00259
00260 template< class Property >
00261 pair< typename OwnerComputesGraph<Property>::KnownVertex, bool >
00262 OwnerComputesGraph<Property>::insert( const Property & prop )
00263 {
00264 VertexID_t new_ID = lower_free_ID;
00265 lower_free_ID += _libbase.size();
00266 insert( new_ID, prop );
00267 return new_ID;
00268 }
00269
00270 template< class Property >
00271 pair< typename OwnerComputesGraph<Property>::KnownVertex, bool >
00272 OwnerComputesGraph<Property>::insert( VertexID_t vid )
00273 {
00274 KnownVertex v = known_vertices.find(vid);
00275 if( v == known_vertices.end() )
00276 {
00277 size_t vpos = local_vertices.insert() * (_libbase.size() + 1) + _libbase.rank();
00278 return known_vertices.insert( make_pair( vid, make_pair( vpos, 1 ) ) );
00279 }
00280 else
00281 {
00282 if( is_vertex_local( v ) )
00283 {
00284 get_property_reference( v ) = Property();
00285 }
00286 }
00287 return make_pair( v, false );
00288 }
00289
00290 template< class Property >
00291 typename OwnerComputesGraph<Property>::KnownVertex
00292 OwnerComputesGraph<Property>::insert_from_remote( VertexID_t vid )
00293 {
00294 KnownVertex v = known_vertices.find(vid);
00295 if( v == known_vertices.end() )
00296 {
00297 size_t vpos = local_vertices.insert() * (_libbase.size() + 1) + _libbase.rank();
00298 pair<KnownVertex,bool> tmp = known_vertices.insert( make_pair( vid, make_pair( vpos, 1 ) ) );
00299 return tmp.first;
00300 }
00301 else
00302 {
00303 size_t vpos = local_vertices.insert() * (_libbase.size() + 1) + _libbase.rank();
00304 v->second.first = vpos;
00305 v->second.second++;
00306 }
00307 return v;
00308 }
00309
00310 template< class Property >
00311 pair< typename OwnerComputesGraph<Property>::KnownVertex, bool >
00312 OwnerComputesGraph<Property>::insert( VertexID_t vid, const Property & prop )
00313 {
00314 KnownVertex v = known_vertices.find(vid);
00315 if( v == known_vertices.end() )
00316 {
00317 size_t vpos = local_vertices.insert(prop) * (_libbase.size() + 1) + _libbase.rank();
00318 return known_vertices.insert( make_pair( vid, make_pair( vpos, 1 ) ) );
00319 }
00320 else
00321 {
00322 if( is_vertex_local( v ) )
00323 {
00324 get_property_reference( v ) = prop;
00325 }
00326 }
00327 return make_pair( v, false );
00328 }
00329
00330 template< class Property >
00331 void
00332 OwnerComputesGraph<Property>::erase( KnownVertex v )
00333 {
00334 local_vertices.erase( get_vertex_index( v ) );
00335 dek_known_vertex_counter_and_unmark_position( v );
00336 }
00337
00338 template< class VProperty >
00339 inline VProperty &
00340 OwnerComputesGraph<VProperty>::get_property_reference( VertexID_t v )
00341 {
00342 return local_vertices[ get_vertex_index(v) ];
00343 }
00344
00345 template< class VProperty >
00346 inline const VProperty &
00347 OwnerComputesGraph<VProperty>::get_property_reference( VertexID_t v ) const
00348 {
00349 return local_vertices[ get_vertex_index(v) ];
00350 }
00351
00352 template< class VProperty >
00353 inline VProperty &
00354 OwnerComputesGraph<VProperty>::get_property_reference( KnownVertex v )
00355 {
00356 return local_vertices[ v->second.first / (_libbase.size() + 1) ];
00357 }
00358
00359 template< class VProperty >
00360 inline const VProperty &
00361 OwnerComputesGraph<VProperty>::get_property_reference( typename KnownVerticesMap_type::const_iterator v ) const
00362 {
00363 return local_vertices[ v->second.first / (_libbase.size() + 1) ];
00364 }
00365
00366 template< class VProperty >
00367 inline typename OwnerComputesGraph<VProperty>::KnownVertex
00368 OwnerComputesGraph<VProperty>::get_known_vertex( VertexID_t v )
00369 {
00370 assert( known_vertices.find(v) != known_vertices.end() );
00371 return known_vertices.find(v);
00372 }
00373
00374 template< class VProperty >
00375 inline typename OwnerComputesGraph<VProperty>::KnownVertex
00376 OwnerComputesGraph<VProperty>::get_known_vertex( VertexID_t v ) const
00377 {
00378 assert( known_vertices.find(v) != known_vertices.end() );
00379 return known_vertices.find(v);
00380 }
00381
00382 template< class VProperty >
00383 inline typename OwnerComputesGraph<VProperty>::KnownVertex
00384 OwnerComputesGraph<VProperty>::get_known_vertex( KnownVertex v )
00385 {
00386 return v;
00387 }
00388
00389 template< class Property >
00390 inline bool
00391 OwnerComputesGraph<Property>::is_vertex_local( VertexID_t v ) const
00392 {
00393 const_KnownVertex it = known_vertices.find(v);
00394 if( it == known_vertices.end() ) return false;
00395 return it->second.first % (_libbase.size() + 1) == _libbase.rank();
00396 }
00397
00398 template< class Property >
00399 inline bool
00400 OwnerComputesGraph<Property>::is_vertex_local( KnownVertex v ) const
00401 {
00402
00403 return owning_processor(v) == _libbase.rank();
00404 }
00405
00406 template< class Property >
00407 inline bool
00408 OwnerComputesGraph<Property>::is_vertex_local( const_KnownVertex v ) const
00409 {
00410
00411 return owning_processor(v) == _libbase.rank();
00412 }
00413
00414 template< class Property >
00415 inline bool
00416 OwnerComputesGraph<Property>::is_vertex_known( VertexID_t v ) const
00417 {
00418 return known_vertices.find(v) != known_vertices.end();
00419 }
00420
00421 template< class Property >
00422 inline size_t
00423 OwnerComputesGraph<Property>::get_vertex_position( VertexID_t v ) const
00424 {
00425 assert( known_vertices.find(v) != known_vertices.end() );
00426 return (*known_vertices.find(v)).second.first;
00427 }
00428
00429 template< class Property >
00430 inline size_t
00431 OwnerComputesGraph<Property>::get_vertex_position( KnownVertex v ) const
00432 {
00433 return v->second.first;
00434 }
00435
00436 template< class Property >
00437 inline size_t
00438 OwnerComputesGraph<Property>::get_vertex_index( VertexID_t v ) const
00439 {
00440 return get_vertex_position(v) / (_libbase.size() + 1 );
00441 }
00442
00443 template< class Property >
00444 inline size_t
00445 OwnerComputesGraph<Property>::get_vertex_index( KnownVertex v ) const
00446 {
00447 return get_vertex_position(v) / (_libbase.size() + 1 );
00448 }
00449
00450 template< class Property >
00451 inline size_t
00452 OwnerComputesGraph<Property>::owning_processor( VertexID_t v ) const
00453 {
00454 assert( known_vertices.find(v) != known_vertices.end() );
00455 return owning_processor( known_vertices.find( v ) );
00456 }
00457
00458 template< class Property >
00459 inline size_t
00460 OwnerComputesGraph<Property>::owning_processor( KnownVertex v ) const
00461 {
00462 return v->second.first % (_libbase.size() + 1 );
00463 }
00464
00465 template< class Property >
00466 inline size_t
00467 OwnerComputesGraph<Property>::owning_processor( const_KnownVertex v ) const
00468 {
00469 return v->second.first % (_libbase.size() + 1 );
00470 }
00471
00472 template< class Property >
00473 inline typename OwnerComputesGraph<Property>::KnownVertex
00474 OwnerComputesGraph<Property>::ink_known_vertex_counter( VertexID_t v )
00475 {
00476 KnownVertex it = known_vertices.find(v);
00477 if( it == known_vertices.end() )
00478 {
00479 bool tmp;
00480 boost::tie(it,tmp) = known_vertices.insert( make_pair( v, make_pair( _libbase.size(), 1 ) ) );
00481 }
00482 else
00483 {
00484 it->second.second++;
00485 }
00486 return it;
00487 }
00488
00489 template< class Property >
00490 inline void
00491 OwnerComputesGraph<Property>::ink_known_vertex_counter( KnownVertex v )
00492 {
00493 v->second.second++;
00494 }
00495
00496 template< class Property >
00497 inline typename OwnerComputesGraph<Property>::KnownVertex
00498 OwnerComputesGraph<Property>::ink_known_vertex_counter_and_set_processor( VertexID_t v, proc_t p )
00499 {
00500 assert( p<=_libbase.size() && p != _libbase.rank() );
00501 KnownVertex it = known_vertices.find(v);
00502 if( it == known_vertices.end() )
00503 {
00504 bool tmp;
00505 boost::tie(it,tmp) = known_vertices.insert( make_pair( v, make_pair( p, 1 ) ) );
00506 }
00507 else
00508 {
00509 it->second.second++;
00510 if( it->second.first % (_libbase.size() + 1) == _libbase.size() )
00511 it->second.first = (it->second.first / (_libbase.size() + 1)) * (_libbase.size() + 1) + p;
00512 }
00513 return it;
00514 }
00515
00516 template< class Property >
00517 inline typename OwnerComputesGraph<Property>::KnownVertex
00518 OwnerComputesGraph<Property>::make_vertex_known( VertexID_t v, proc_t p )
00519 {
00520 assert( p<=_libbase.size() );
00521 KnownVertex it = known_vertices.find(v);
00522 if( it == known_vertices.end() )
00523 {
00524 bool tmp;
00525 boost::tie(it,tmp) = known_vertices.insert( make_pair( v, make_pair( p, 0 ) ) );
00526 }
00527 else
00528 {
00529 if( it->second.first % (_libbase.size() + 1) == _libbase.size() )
00530 it->second.first = (it->second.first / (_libbase.size() + 1)) * (_libbase.size() + 1) + p;
00531 }
00532 return it;
00533 }
00534
00535 template< class Property >
00536 inline void
00537 OwnerComputesGraph<Property>::ink_known_vertex_counter_and_set_position( VertexID_t v, size_t pos )
00538 {
00539 KnownVertex it = known_vertices.find(v);
00540 if( it == known_vertices.end() )
00541 {
00542 known_vertices.insert( make_pair( v, make_pair( pos, 1 ) ) );
00543 }
00544 else
00545 {
00546 it->second.second++;
00547 it->second.first = pos;
00548 }
00549 }
00550
00551 template< class Property >
00552 inline void
00553 OwnerComputesGraph<Property>::dek_known_vertex_counter( VertexID_t v )
00554 {
00555 KnownVertex it = known_vertices.find(v);
00556 if( ( --(it->second.second ) ) == 0 )
00557 known_vertices.erase(it);
00558 }
00559
00560 template< class Property >
00561 inline void
00562 OwnerComputesGraph<Property>::dek_known_vertex_counter( KnownVertex v )
00563 {
00564 if( ( --(v->second.second) ) == 0 )
00565 known_vertices.erase(v);
00566 }
00567
00568 template< class Property >
00569 inline void
00570 OwnerComputesGraph<Property>::dek_known_vertex_counter_and_unmark_position( VertexID_t v )
00571 {
00572 KnownVertex it = known_vertices.find(v);
00573 (*it).second.first = _libbase.size();
00574 if( ( --(it->second.second) ) == 0 )
00575 known_vertices.erase(it);
00576 }
00577
00578 template< class Property >
00579 inline void
00580 OwnerComputesGraph<Property>::dek_known_vertex_counter_and_unmark_position( KnownVertex v )
00581 {
00582 v->second.first = _libbase.size();
00583 if( ( --(v->second.second) ) == 0 )
00584 known_vertices.erase(v);
00585 }
00586
00587 template< class Property >
00588 pair< typename OwnerComputesGraph<Property>::VertexIterator, typename OwnerComputesGraph<Property>::VertexIterator >
00589 OwnerComputesGraph<Property>::get_local_vertices()
00590 {
00591 VertexIterator tmp(*this), tmp2(*this);
00592 tmp2.goto_end();
00593 return make_pair( tmp, tmp2 );
00594 }
00595
00596 template< class Property >
00597 pair< typename OwnerComputesGraph<Property>::const_VertexIterator, typename OwnerComputesGraph<Property>::const_VertexIterator >
00598 OwnerComputesGraph<Property>::get_local_vertices() const
00599 {
00600 const_VertexIterator tmp(*this), tmp2(*this);
00601 tmp2.goto_end();
00602 return make_pair( tmp, tmp2 );
00603 }
00604
00605 inline int pg_max( int a, int b ) { return std::max(a,b); }
00606
00607 template< class Property >
00608 void
00609 OwnerComputesGraph<Property>::compose_distribution( int *sizes, int best_size, int *send_count_buf,
00610 int *send_count )
00611 {
00612 proc_t sendproc = 0, recvproc = 0;
00613 for(; sendproc < _libbase.size() ; sendproc++ )
00614 {
00615 for(; sizes[sendproc] > best_size + 1 && recvproc < _libbase.size() ; recvproc++ )
00616 {
00617 if( best_size > sizes[recvproc] )
00618 {
00619 size_t tmp = std::min( sizes[sendproc] - best_size - 1,
00620 best_size - sizes[recvproc] );
00621 sizes[sendproc] -= tmp;
00622 sizes[recvproc] += tmp;
00623
00624 if( sendproc == _libbase.rank() )
00625 {
00626 (*send_count) += tmp; send_count_buf[recvproc] = tmp;
00627 }
00628 }
00629 }
00630 }
00631 }
00632
00633 template< class Property >
00634 template< class DistHelper >
00635 void
00636 OwnerComputesGraph<Property>::redistribute( DistHelper & dh )
00637 {
00638 int *sizes = new int[_libbase.size()];
00639 int local_size = local_vertices.size();
00640
00641 MPI_Allgather( &local_size, 1, MPI_INT, sizes, 1, MPI_INT, _libbase.comm() );
00642 int all_size = std::accumulate( sizes, sizes+_libbase.size(),0 );
00643 int max_local_size = std::accumulate( sizes, sizes+_libbase.size(),0, pg_max );
00644 int best_size = all_size/_libbase.size();
00645
00646 if( max_local_size >= best_size + best_size / 2 )
00647 {
00648 int *send_count_buf = new int[_libbase.size()], send_count;
00649 for( proc_t i = 0; i < _libbase.size() ; i++ ) send_count_buf[i] = 0;
00650
00651 compose_distribution( sizes, best_size, send_count_buf, &send_count );
00652
00653 std::map< KnownVertex, proc_t > movements;
00654 VertexIterator vit(*this);
00655
00656 for( proc_t i = 0 ; i < _libbase.size() ; i++ )
00657 {
00658 for( int j = 0 ; j < send_count_buf[i] ; j++ )
00659 {
00660 movements.insert( make_pair( *vit, i ) );
00661 vit++;
00662 }
00663 }
00664 delete[] send_count_buf;
00665 do_distribution( movements, dh );
00666 }
00667 delete[] sizes;
00668 }
00669
00670 template< class Property >
00671 template< class PropertyMap, class DistHelper >
00672 void
00673 OwnerComputesGraph<Property>::redistribute( PropertyMap procmap, DistHelper & dh )
00674 {
00675 VertexIterator vit, vend;
00676 boost::tie( vit, vend ) = get_local_vertices();
00677 std::map< KnownVertex, proc_t > movements;
00678 for(; vit != vend ; vit++ )
00679 {
00680 proc_t target = get( procmap, get_vertex_reference( vit ) );
00681 if( target != _libbase.rank() && target < _libbase.size() )
00682 {
00683 movements.insert( make_pair( *vit, target ) );
00684 }
00685 }
00686 do_distribution( movements, dh );
00687 }
00688
00689 template< class Property >
00690 template< class DistHelper >
00691 void
00692 OwnerComputesGraph<Property>::do_distribution( std::map< KnownVertex, proc_t > & movements, DistHelper & dh )
00693 {
00694 AllToAllBuffer buffer;
00695 std::map< KnownVertex, proc_t >::iterator vit = movements.begin(),
00696 vend = movements.end();
00697
00698 for(; vit != vend ; vit++ )
00699 {
00700 buffer.set_proc( vit->second );
00701 buffer.put( get_id( vit->first ) );
00702 put_property_into_buffer( *this, dh, get_property_reference( vit->first ), buffer );
00703 erase( vit->first );
00704 }
00705
00706 buffer.communicate();
00707
00708 while( ! buffer.is_empty() )
00709 {
00710 VertexID_t id;
00711 buffer.get( &id, 1 );
00712 KnownVertex v = insert_from_remote( id );
00713 get_property_from_buffer( *this, dh, get_property_reference( v ), buffer );
00714 dh.notify_id( id );
00715 }
00716
00717 do_distribution_on_vertex_sets( movements );
00718 dh.notify_about_vertices();
00719 }
00720
00721 template< class Property >
00722 void
00723 OwnerComputesGraph<Property>::notify_about_vertices( )
00724 {
00725 AllGatherBuffer notify_buffer;
00726 pair< VertexIterator, VertexIterator > lv = get_local_vertices();
00727 VertexIterator it = lv.first;
00728
00729 for(; it != lv.second ; it++ )
00730 {
00731 VertexID_t id = get_id(*it);
00732 int pos = get_vertex_position( *it );
00733 notify_buffer.put( &id, 1 );
00734 notify_buffer.put( &pos, 1 );
00735 }
00736
00737 notify_buffer.communicate();
00738
00739 while( ! notify_buffer.is_empty() )
00740 {
00741 VertexID_t id;
00742 int pos;
00743 notify_buffer.get( &id, 1 );
00744 notify_buffer.get( &pos, 1 );
00745 KnownVertex it = known_vertices.find( id );
00746 if( it != known_vertices.end() )
00747 {
00748 (*it).second.first = pos;
00749 }
00750 }
00751 }
00752
00753 template< class Property >
00754 void
00755 OwnerComputesGraph<Property>::notify_about_vertices_check( )
00756 {
00757 AllGatherBuffer notify_buffer;
00758 pair< VertexIterator, VertexIterator > lv = get_local_vertices();
00759 VertexIterator it = lv.first;
00760 if(rank()==0)std::cout<<"check"<<std::endl;
00761 for(; it != lv.second ; it++ )
00762 {
00763 VertexID_t id = get_id(*it);
00764 int pos = get_vertex_position( *it );
00765 notify_buffer.put( &id, 1 );
00766 notify_buffer.put( &pos, 1 );
00767 }
00768
00769 notify_buffer.communicate();
00770
00771 while( ! notify_buffer.is_empty() )
00772 {
00773 VertexID_t id;
00774 int pos;
00775 notify_buffer.get( &id, 1 );
00776 notify_buffer.get( &pos, 1 );
00777 KnownVertex it = known_vertices.find( id );
00778 if( it != known_vertices.end() )
00779 {
00780 if( (*it).second.first % (_libbase.size() + 1) != pos % (_libbase.size() + 1) )
00781 std::cout<<"P"<<rank()<<": v"<<id<<" hier "<< (*it).second.first % (_libbase.size() + 1)<<
00782 " soll sein "<<pos % (_libbase.size() + 1)<<std::endl;
00783 }
00784 }
00785 }
00786
00787 template< class Property >
00788 void
00789 OwnerComputesGraph<Property>::notify_about_vertices( AllGatherBuffer & notify_buffer )
00790 {
00791 notify_buffer.communicate();
00792
00793 while( ! notify_buffer.is_empty() )
00794 {
00795 VertexID_t id;
00796 proc_t p = notify_buffer.get( &id );
00797 if( p != _libbase.rank() )
00798 {
00799 KnownVertex it = known_vertices.find( id );
00800 if( it != known_vertices.end() )
00801 {
00802 size_t pos = (*it).second.first / (_libbase.size() + 1);
00803 (*it).second.first = p + pos * (_libbase.size() + 1);
00804 }
00805 }
00806 }
00807 }
00808
00809 template< class Property >
00810 void
00811 OwnerComputesGraph<Property>::do_distribution_on_vertex_sets( std::map< KnownVertex, proc_t > & movements )
00812 {
00813 AllToAllBuffer buffer;
00814 VertexID_t * tmp = new VertexID_t[ movements.size() * _libbase.size() ];
00815 int * size = new int[ _libbase.size() ];
00816
00817 typename VertexSets::iterator sets = registered_vertex_sets.begin();
00818
00819 for(; sets != registered_vertex_sets.end() ; sets++ )
00820 {
00821 for( proc_t i = 0 ; i < _libbase.size() ; i++ ) size[ i ] = 0;
00822
00823 std::map< KnownVertex, proc_t >::iterator movementsit = movements.begin();
00824 std::set< KnownVertex >::iterator setit = (*sets).begin(), tmpsetit;
00825 while( setit != (*sets).end() && movementsit != movements.end() )
00826 {
00827 if( get_id(*setit) == get_id(movementsit->first) )
00828 {
00829 tmp[ size[ (*movementsit).second ] + movements.size() * (*movementsit).second ] = get_id(*setit);
00830 size[ (*movementsit).second ]++;
00831 tmpsetit = setit;
00832 tmpsetit++;
00833 (*sets).erase( setit );
00834 setit = tmpsetit;
00835 movementsit++;
00836 }
00837 else if( get_id(*setit) < get_id(movementsit->first) )
00838 {
00839 setit++;
00840 }
00841 else
00842 {
00843 movementsit++;
00844 }
00845 }
00846 for( proc_t i = 0 ; i < _libbase.size() ; i++ )
00847 {
00848 buffer.set_proc( i );
00849 buffer.put( size[i] );
00850 if( size[i] > 0 )
00851 buffer.put( &tmp[ i * movements.size() ], size[i] );
00852 size[i] = 0;
00853 }
00854 }
00855 delete[] tmp;
00856 delete[] size;
00857 buffer.communicate();
00858
00859 for( proc_t i = 0 ; i < _libbase.size() ; i++ )
00860 {
00861 sets = registered_vertex_sets.begin();
00862 for(; sets != registered_vertex_sets.end(); sets++ )
00863 {
00864 int readsize;
00865 buffer.get( &readsize, 1 );
00866 for(; readsize > 0 ; readsize-- )
00867 {
00868 VertexID_t v;
00869 buffer.get( &v, 1 );
00870 (*sets).insert( v );
00871 }
00872 }
00873 }
00874 }
00875
00876 inline void
00877 ask_for_position( proc_t p, VertexID_t v, AllToAllBuffer & buf )
00878 {
00879 buf.set_proc( p );
00880 buf.put( v );
00881 }
00882
00883 template< class Graph >
00884 void
00885 do_asking_for_position( Graph & g, AllToAllBuffer & buf )
00886 {
00887 buf.communicate();
00888
00889 while( ! buf.is_empty() )
00890 {
00891 VertexID_t v;
00892 proc_t p = buf.get( &v, 1 );
00893 buf.set_proc( p );
00894 buf.put( v );
00895 buf.put( g.get_vertex_position( v ) );
00896 }
00897
00898 buf.communicate();
00899
00900 while( ! buf.is_empty() )
00901 {
00902 VertexID_t v;
00903 int pos;
00904 buf.get( &v, 1 );
00905 buf.get( &pos, 1 );
00906 g.ink_known_vertex_counter_and_set_position( v, pos );
00907 }
00908 }
00909
00910 }
00911
00912 #endif // _PG_OWNER_COMPUTES_GRAPH_HPP_