00001 #ifndef CPM_SGV_UCS_TREE_BULDER_HPP_
00002 #define CPM_SGV_UCS_TREE_BULDER_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
00017 class UCS_binomial_builder {
00018 private:
00020 CPM_predictor* predictor;
00022 CPM_next_node_strategy next_node;
00023
00024 public:
00025 UCS_binomial_builder(CPM_predictor* _predictor, CPM_next_node_strategy _next_node): predictor(_predictor), next_node(_next_node) {}
00026
00027 void build(int size, int root, int rank, int* counts,
00028 Graph& g, Vertex& r, Vertex& u, Vertex& v)
00029 {
00030
00031 r = add_vertex(g);
00032 put(vertex_index, g, r, root);
00033 if (rank == root)
00034 v = r;
00035
00036 deque<pair<int, double> > ranks;
00037 for (int i = 0; i < size; i++)
00038 if (i != root)
00039 ranks.push_back(make_pair(i, 0));
00040
00041 multimap<int, Vertex> blocks;
00042
00043 int tmp, bin;
00044 for (tmp = size - 1, bin = 1; tmp > 0; tmp /= 2, bin *= 2)
00045 if (tmp % 2)
00046 blocks.insert(map<int, Vertex>::value_type(bin, r));
00047 bin /= 2;
00048
00049 while (!blocks.empty()) {
00050
00051 pair<map<int, Vertex>::iterator, map<int, Vertex>::iterator> range =
00052 blocks.equal_range(bin);
00053 for (map<int, Vertex>::iterator b = range.first; b != range.second; b++) {
00054
00055 Vertex s = b->second;
00056 int source = get(vertex_index, g, s);
00057 for (deque<pair<int, double> >::iterator i = ranks.begin(); i != ranks.end(); i++){
00058 int target = i->first;
00059 i->second = predictor->predict_p2p(predictor, source, target, counts[target]);
00060 }
00061 deque<pair<int, double> >::iterator i = (next_node == MAX) ?
00062 max_element(ranks.begin(), ranks.end(), second_less()):
00063 min_element(ranks.begin(), ranks.end(), second_less());
00064 int target = i->first;
00065
00066 if ( (rank == root) && (mpib_coll_verbose ==1) ){
00067 printf("DEBUG: source(fixed)= %d, target(selected)=%d, prediction=%lf\n", source, target, i->second);
00068 for (deque<pair<int, double> >::iterator i = ranks.begin(); i != ranks.end(); i++) {
00069 printf("DEBUG: alternative link prediction: (%d-%d) = %lf\n", source, i->first, i->second);
00070 }
00071 printf("DEBUG: ===\n");
00072 }
00073
00074 ranks.erase(i);
00075 Vertex t = add_vertex(g);
00076 put(vertex_index, g, t, target);
00077 add_edge(s, t, g);
00078 if (rank == target) {
00079 u = s;
00080 v = t;
00081 }
00082
00083 for (int bin = b->first / 2; bin > 0; bin /= 2)
00084 blocks.insert(map<int, Vertex>::value_type(bin, t));
00085 }
00086 blocks.erase(range.first, range.second);
00087 bin /= 2;
00088 }
00089 }
00090 };
00091 }
00092 }
00093 #endif //CPM_SGV_UCS_TREE_BULDER_HPP_