00001 #ifndef CPM_SGV_DFS_TREE_BUILDER_HPP_
00002 #define CPM_SGV_DFS_TREE_BUILDER_HPP_
00003
00004 #include "MPIBlib/collectives/comm_tree.hpp"
00005 #include "cpm_model.h"
00006
00007 namespace CPM {
00008 namespace SGv {
00009 using namespace MPIB::comm_tree;
00010
00015 class DFS_binomial_builder {
00016 private:
00017 CPM_predictor* predictor;
00018 CPM_next_node_strategy next_node;
00019
00020 public:
00021 DFS_binomial_builder(CPM_predictor* _predictor, CPM_next_node_strategy _next_node): predictor(_predictor), next_node(_next_node) {}
00022
00023 void build(int size, int root, int rank, int* counts,
00024 Graph& g, Vertex& r, Vertex& u, Vertex& v)
00025 {
00026
00027 r = add_vertex(g);
00028 put(vertex_index, g, r, root);
00029 if (rank == root)
00030 v = r;
00031
00032 deque<pair<int, double> > ranks;
00033 for (int i = 0; i < size; i++)
00034 if (i != root)
00035 ranks.push_back(make_pair(i, 0));
00036
00037 deque<pair<Vertex, int> > blocks;
00038
00039 for (int tmp = size - 1, bin = 1; tmp > 0; tmp /= 2, bin *= 2)
00040 if (tmp % 2)
00041 blocks.push_back(make_pair(r, bin));
00042
00043 while (!blocks.empty()) {
00044 Vertex s = blocks.front().first;
00045 int source = get(vertex_index, g, s);
00046 for (deque<pair<int, double> >::iterator i = ranks.begin(); i != ranks.end(); i++) {
00047 int target = i->first;
00048 i->second = predictor->predict_p2p(predictor, source, target, counts[target]);
00049 }
00050 deque<pair<int, double> >::iterator i = (next_node == MAX) ?
00051 max_element(ranks.begin(), ranks.end(), second_less()):
00052 min_element(ranks.begin(), ranks.end(), second_less());
00053 int target = i->first;
00054
00055 if ( (rank == root) && (mpib_coll_verbose ==1) ){
00056 printf("DEBUG: source(fixed)= %d, target(selected)=%d, prediction=%lf\n", source, target, i->second);
00057 for (deque<pair<int, double> >::iterator i = ranks.begin(); i != ranks.end(); i++) {
00058 printf("DEBUG: alternative link prediction: (%d-%d) = %lf\n", source, i->first, i->second);
00059 }
00060 printf("DEBUG: ===\n");
00061 }
00062
00063 ranks.erase(i);
00064 Vertex t = add_vertex(g);
00065 put(vertex_index, g, t, target);
00066 if (rank == target) {
00067 u = s;
00068 v = t;
00069 }
00070 add_edge(s, t, g);
00071 int bin = blocks.front().second;
00072 blocks.pop_front();
00073 for (bin /= 2; bin > 0; bin /= 2)
00074 blocks.push_front(make_pair(t, bin));
00075 }
00076 }
00077 };
00078 }
00079 }
00080 #endif //CPM_SGV_DFS_TREE_BUILDER_HPP_