Main Page   Class Hierarchy   Compound List   File List   Compound Members  

PG_owner_computes_graph.hpp

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 //    assert( owning_processor(v) != _libbase.size() );
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 //    assert( owning_processor(v) != _libbase.size() );
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 } // namespace ParGraph
00911 
00912 #endif // _PG_OWNER_COMPUTES_GRAPH_HPP_

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