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