Changeset 1bc104


Ignore:
Timestamp:
05/18/07 10:28:49 (6 years ago)
Author:
Tiago de Paula Peixoto <tiago@…>
Children:
88b86e
Parents:
929c0e
git-author:
Tiago de Paula Peixoto <tiago@…> (05/18/07 10:28:49)
git-committer:
Tiago de Paula Peixoto <tiago@…> (05/18/07 10:28:49)
Message:
* graph_community.cc: code parallelization and speed improvements
* graph/graph_distance.cc: trivial "one-liner" speed improvement



git-svn-id: https://svn.forked.de/graph-tool/trunk@98 d4600afd-f417-0410-95de-beed9576f240
Location:
src/graph
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/graph/graph_community.cc

    rcea867 r1bc104  
    5252 
    5353//============================================================================== 
    54 // ManagedUnorderedMap 
    55 //============================================================================== 
    56 template <class Key, class Value> 
    57 class ManagedUnorderedMap: public tr1::unordered_map<Key,Value> 
    58 { 
    59     typedef tr1::unordered_map<Key,Value> base_t; 
    60 public: 
    61     void erase(typename base_t::iterator pos) 
    62     { 
    63         static_cast<base_t*>(this)->erase(pos); 
    64         manage(); 
    65     } 
    66  
    67     size_t erase(const Key& k) 
    68     { 
    69         size_t n = static_cast<base_t*>(this)->erase(k); 
    70         manage(); 
    71         return n; 
    72     } 
    73  
    74     void manage() 
    75     { 
    76         if (this->bucket_count() > 2*this->size()) 
    77         { 
    78             base_t* new_map = new base_t; 
    79             for (typeof(this->begin()) iter = this->begin(); iter != this->end(); ++iter) 
    80                 (*new_map)[iter->first] = iter->second; 
    81             *static_cast<base_t*>(this) = *new_map; 
    82             delete new_map; 
    83         } 
    84     } 
    85  
    86 }; 
    87  
    88  
    89 //============================================================================== 
    9054// GetCommunityStructure() 
    9155// computes the community structure through a spin glass system with  
     
    9963    void operator()(Graph& g, WeightMap weights, CommunityMap s, double gamma, size_t n_iter, pair<double,double> Tinterval, pair<size_t,bool> Nspins, size_t seed, pair<bool,string> verbose) const 
    10064    { 
    101  
     65        size_t N = HardNumVertices()(g); 
     66                     
    10267        stringstream out_str; 
    10368        ofstream out_file; 
     
    11984            Nspins.first = HardNumVertices()(g); 
    12085 
    121         ManagedUnorderedMap<size_t, size_t> Ns; // spin histogram 
    122         ManagedUnorderedMap<size_t, map<double, unordered_set<size_t> > > global_term; // global energy term 
     86        unordered_map<size_t, size_t> Ns; // spin histogram 
     87        unordered_map<size_t, map<double, unordered_set<size_t> > > global_term; // global energy term 
    12388 
    12489        // init spins from [0,N-1] and global info 
     
    161126            unordered_map<size_t, map<long double, pair<double, bool> > > cumm_prob; 
    162127            unordered_map<size_t, unordered_map<double, long double> > energy_to_prob; 
    163             for (size_t i = 0; i < degs.size(); ++i) 
     128            int i, NK = degs.size(); 
     129#ifdef USING_OPENMP 
     130            for (i = 0; i < NK; ++i) 
     131            { 
     132                cumm_prob[degs[i]]; 
     133                energy_to_prob[degs[i]]; 
     134            } 
     135#endif //USING_OPENMP 
     136            #pragma omp parallel for default(shared) private(i) schedule(dynamic)  
     137            for (i = 0; i < NK; ++i) 
    164138            { 
    165139                long double prob = 0; 
     
    168142                    long double M = log(numeric_limits<long double>::max()/(Nspins.first*10)); 
    169143                    long double this_prob = exp((long double)(-iter->first - degs[i])/T + M)*iter->second.size(); 
     144 
    170145                    if (prob + this_prob != prob) 
    171146                    { 
     
    180155                } 
    181156                if (prob == 0.0) 
    182                     steepest_descent = true; 
     157                { 
     158                    #pragma omp critical 
     159                    { 
     160                        steepest_descent = true; 
     161                    } 
     162                } 
    183163            } 
    184164 
    185165            // list of spins which were updated 
    186166            vector<pair<typename graph_traits<Graph>::vertex_descriptor,size_t> > spin_update; 
    187             spin_update.reserve(HardNumVertices()(g)); 
     167            spin_update.reserve(N); 
    188168 
    189169            // sample a new spin for every vertex 
    190             for (tie(v,v_end) = vertices(g); v != v_end; ++v) 
    191             { 
     170            int NV = num_vertices(g); 
     171            #pragma omp parallel for default(shared) private(i) firstprivate(global_term, cumm_prob) schedule(dynamic)  
     172            for (i = 0; i < NV; ++i) 
     173            { 
     174                typename graph_traits<Graph>::vertex_descriptor v = vertex(i, g); 
     175                if (v == graph_traits<Graph>::null_vertex()) 
     176                    continue; 
     177 
    192178                unordered_map<size_t, double> ns; // number of neighbours with spin 's' (weighted) 
    193179                 
    194180                // neighborhood spins info 
    195181                typename graph_traits<Graph>::out_edge_iterator e,e_end; 
    196                 for (tie(e,e_end) = out_edges(*v,g); e != e_end; ++e) 
     182                for (tie(e,e_end) = out_edges(v,g); e != e_end; ++e) 
    197183                { 
    198184                    typename graph_traits<Graph>::vertex_descriptor t = target(*e,g); 
    199                     if (t != *v) 
     185                    if (t != v) 
    200186                        ns[s[t]] += get(weights, *e); 
    201187                } 
    202188                     
    203                 size_t k = out_degree_no_loops(*v,g); 
     189                size_t k = out_degree_no_loops(v,g); 
    204190 
    205191                map<double,unordered_set<size_t> >& global_term_k = global_term[k]; 
     
    229215                    if (global_term_k.find(*iter) != global_term_k.end()) 
    230216                    { 
    231                         long double M = log(numeric_limits<long double>::max()/(Nspins.first*10)); 
     217                        long double M = log(numeric_limits<long double>::max()/(Nspins.first*10));                         
    232218                        long double prob = exp((long double)(-*iter - k)/T + M)*global_term_k[*iter].size(); 
    233219                        if (cumm_prob_k.empty() || cumm_prob_k.rbegin()->first + prob != cumm_prob_k.rbegin()->first) 
     
    257243                    while (!accept) 
    258244                    { 
    259                         typeof(cumm_prob_k.begin()) upper = cumm_prob_k.upper_bound(prob_sample(rng)); 
     245                        typeof(cumm_prob_k.begin()) upper; 
     246 
     247                        #pragma omp critical 
     248                        { 
     249                            upper = cumm_prob_k.upper_bound(prob_sample(rng)); 
     250                        } 
     251 
    260252                        if (upper == cumm_prob_k.end()) 
    261253                            upper--; 
     
    268260                uniform_int<size_t> sample_spin(0,global_term_k[E].size()-1); 
    269261                typeof(global_term_k[E].begin()) iter = global_term_k[E].begin(); 
    270                 advance(iter, sample_spin(rng)); 
     262 
     263                size_t spin_n; 
     264                #pragma omp critical 
     265                { 
     266                    spin_n = sample_spin(rng); 
     267                } 
     268                advance(iter, spin_n); 
    271269                size_t a = *iter; 
    272270 
     
    289287                    double new_E = gamma*Nnnks(k, iter->first); 
    290288                    double old_E = new_E - ns[iter->first]; 
    291  
    292289                    global_term_k[old_E].erase(iter->first); 
    293290                    if (global_term_k[old_E].empty()) 
     
    295292                    global_term_k[new_E].insert(iter->first); 
    296293                } 
    297  
     294                 
    298295                //update global info 
    299                 if (s[*v] != a) 
    300                     spin_update.push_back(make_pair(*v, a)); 
     296                if (s[v] != a) 
     297                { 
     298                    #pragma omp critical 
     299                    { 
     300                        spin_update.push_back(make_pair(v, a)); 
     301                    } 
     302                } 
    301303            } 
    302304             
     
    307309                size_t k = out_degree_no_loops(v, g); 
    308310                size_t a = spin_update[u].second; 
    309                 for (size_t i = 0; i < degs.size(); ++i) 
     311                 
     312                int i, NK = degs.size(); 
     313                #pragma omp parallel for default(shared) private(i) schedule(dynamic)  
     314                for (i = 0; i < NK; ++i) 
    310315                { 
    311316                    size_t nk = degs[i]; 
    312317                    double old_E = gamma*Nnnks(nk,s[v]); 
    313                     global_term[nk][old_E].erase(s[v]); 
    314                     if (global_term[nk][old_E].empty()) 
    315                         global_term[nk].erase(old_E); 
    316                     old_E = gamma*Nnnks(nk,a); 
    317                     global_term[nk][old_E].erase(a); 
    318                     if (global_term[nk][old_E].empty()) 
    319                         global_term[nk].erase(old_E); 
    320                 } 
    321                      
     318                    double new_E = gamma*Nnnks(nk,a); 
     319                    map<double,unordered_set<size_t> >& global_term_k = global_term[nk]; 
     320                    unordered_set<size_t>& global_term_k_old_E = global_term_k[old_E]; 
     321                    unordered_set<size_t>& global_term_k_new_E = global_term_k[new_E]; 
     322                    global_term_k_old_E.erase(s[v]); 
     323                    if (global_term_k_old_E.empty()) 
     324                        global_term_k.erase(old_E); 
     325                    global_term_k_new_E.erase(a); 
     326                    if (global_term_k_new_E.empty()) 
     327                        global_term_k.erase(new_E); 
     328                } 
     329                 
    322330                Nnnks.Update(k,s[v],a); 
    323331                Ns[s[v]]--; 
     
    325333                    Ns.erase(s[v]); 
    326334                Ns[a]++; 
    327                  
    328                 for (size_t i = 0; i < degs.size(); ++i) 
     335 
     336                #pragma omp parallel for default(shared) private(i) schedule(dynamic)  
     337                for (i = 0; i < NK; ++i) 
    329338                { 
    330339                    size_t nk = degs[i]; 
    331                     global_term[nk][gamma*Nnnks(nk,s[v])].insert(s[v]); 
    332                     global_term[nk][gamma*Nnnks(nk,a)].insert(a); 
     340                    map<double,unordered_set<size_t> >& global_term_k = global_term[nk]; 
     341                    double old_E = gamma*Nnnks(nk,s[v]); 
     342                    double new_E = gamma*Nnnks(nk,a); 
     343                    global_term_k[old_E].insert(s[v]); 
     344                    global_term_k[new_E].insert(a); 
    333345                } 
    334346                        
     
    347359                for (typeof(global_term.begin()) iter = global_term.begin(); iter != global_term.end(); ++iter) 
    348360                    n_energy += iter->second.size(); 
    349                 out_str << setw(lexical_cast<string>(Nspins.first*degs.size()).size()) << n_energy; 
     361                out_str << setw(lexical_cast<string>(Nspins.first*degs.size()).size()) << n_energy << "  "; 
    350362                if (steepest_descent) 
    351363                    out_str << " (steepest descent)"; 
     
    368380        } 
    369381 
     382 
     383        // get final energy 
     384        double E = 0.0; 
     385        unordered_map<size_t,vector<typename graph_traits<Graph>::vertex_descriptor> > spin_groups; 
     386        for (tie(v,v_end) = vertices(g); v != v_end; ++v) 
     387        { 
     388            typename graph_traits<Graph>::out_edge_iterator e, e_end; 
     389            for (tie(e,e_end) = out_edges(*v,g); e != e_end; ++e) 
     390            { 
     391                typename graph_traits<Graph>::vertex_descriptor t = target(*e,g); 
     392                if (s[t] == s[*v]) 
     393                    E -= get(weights, *e); 
     394            } 
     395            E += gamma*Nnnks(out_degree_no_loops(*v,g), s[*v]); 
     396        } 
     397                         
    370398        if (verbose.first) 
    371             cout << endl; 
     399            cout << " total energy: " << scientific << setprecision(20) << E << endl; 
    372400 
    373401        // rename spins, starting from zero 
     
    378406                spins[s[*v]] = spins.size() - 1; 
    379407            s[*v] = spins[s[*v]]; 
    380         }         
     408        } 
    381409         
    382410    } 
     
    421449private: 
    422450    double _p; 
    423     ManagedUnorderedMap<size_t,size_t> _Ns; 
     451    unordered_map<size_t,size_t> _Ns; 
    424452}; 
    425453 
     
    459487    Graph& _g; 
    460488    size_t _K; 
    461     ManagedUnorderedMap<size_t,size_t> _Ks; 
     489    unordered_map<size_t,size_t> _Ks; 
    462490}; 
    463491 
     
    521549    void Update(size_t k, size_t old_s, size_t s) 
    522550    { 
    523         for (size_t i = 0; i < _degs.size(); ++i)  
     551        int i, NK = _degs.size(); 
     552        #pragma omp parallel for default(shared) private(i) schedule(dynamic)  
     553        for (i = 0; i < NK; ++i) 
    524554        { 
    525555            size_t k1 = _degs[i], k2 = k; 
     
    528558            if (_Pkk.find(k1)->second.find(k2) == _Pkk.find(k1)->second.end()) 
    529559                continue; 
    530             _NNks[k1][old_s] -=  k1*_Pkk[k1][k2] * _Nks[k2][old_s]/double(_Nk[k2]); 
    531             if (_NNks[k1][old_s] == 0.0) 
    532                 _NNks[k1].erase(old_s); 
    533             if (_Nks[k2].find(s) != _Nks[k2].end()) 
    534                 _NNks[k1][s] -=  k1*_Pkk[k1][k2] * _Nks[k2][s]/double(_Nk[k2]); 
    535             if (_NNks[k1][s] == 0.0) 
    536                 _NNks[k1].erase(s); 
     560            unordered_map<size_t,double>& NNks_k1 = _NNks[k1]; 
     561            double Pk1k2 = _Pkk[k1][k2]; 
     562            unordered_map<size_t,size_t>& Nksk2 = _Nks[k2]; 
     563            double Nk2 = _Nk[k2]; 
     564            NNks_k1[old_s] -=  k1*Pk1k2 * Nksk2[old_s]/Nk2; 
     565            if (NNks_k1[old_s] == 0.0) 
     566                NNks_k1.erase(old_s); 
     567            if (Nksk2.find(s) != Nksk2.end()) 
     568                NNks_k1[s] -=  k1*Pk1k2 * Nksk2[s]/Nk2; 
     569            if (NNks_k1[s] == 0.0) 
     570                NNks_k1.erase(s); 
    537571        } 
    538572 
     
    542576        _Nks[k][s]++; 
    543577 
    544         for (size_t i = 0; i < _degs.size(); ++i)  
     578        #pragma omp parallel for default(shared) private(i) schedule(dynamic)  
     579        for (i = 0; i < NK; ++i) 
    545580        { 
    546581            size_t k1 = _degs[i], k2 = k; 
     
    549584            if (_Pkk.find(k1)->second.find(k2) == _Pkk.find(k1)->second.end()) 
    550585                continue; 
    551             _NNks[k1][old_s] +=  k1*_Pkk[k1][k2] * _Nks[k2][old_s]/double(_Nk[k2]); 
    552             if (_NNks[k1][old_s] == 0.0) 
    553                 _NNks[k1].erase(old_s); 
    554             _NNks[k1][s] +=  k1*_Pkk[k1][k2] * _Nks[k2][s]/double(_Nk[k2]); 
     586            unordered_map<size_t,double>& NNks_k1 = _NNks[k1]; 
     587            double Pk1k2 = _Pkk[k1][k2]; 
     588            unordered_map<size_t,size_t>& Nksk2 = _Nks[k2]; 
     589            double Nk2 = _Nk[k2]; 
     590            NNks_k1[old_s] +=  k1*Pk1k2 * Nksk2[old_s]/Nk2; 
     591            if (NNks_k1[old_s] == 0.0) 
     592                NNks_k1.erase(old_s); 
     593            NNks_k1[s] +=  k1*Pk1k2 * Nksk2[s]/Nk2; 
    555594        } 
    556595 
     
    571610    unordered_map<size_t,size_t> _Nk; 
    572611    unordered_map<size_t,unordered_map<size_t,double> > _Pkk; 
    573     unordered_map<size_t,ManagedUnorderedMap<size_t,size_t> > _Nks; 
    574     unordered_map<size_t,ManagedUnorderedMap<size_t,double> > _NNks; 
     612    unordered_map<size_t,unordered_map<size_t,size_t> > _Nks; 
     613    unordered_map<size_t,unordered_map<size_t,double> > _NNks; 
    575614}; 
    576615 
  • src/graph/graph_distance.cc

    r929c0e r1bc104  
    7171            for (tie(v2, v_end) = vertices(g); v2 != v_end; ++v2) 
    7272                if (*v2 != v && dist_map[*v2] != numeric_limits<double>::max()) 
     73                { 
     74                    double dist = dist_map[*v2]; 
    7375                    #pragma omp atomic 
    74                     hist[dist_map[*v2]]++;             
     76                    hist[dist]++; 
     77                } 
    7578        }         
    7679    } 
Note: See TracChangeset for help on using the changeset viewer.