00001 #ifndef CPM_SGV_TRAFF_TREE_BUILDER_HPP_
00002 #define CPM_SGV_TRAFF_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
00012 class Traff_builder {
00013 private:
00014 CPM_predictor* predictor;
00015
00016 public:
00017 Traff_builder(CPM_predictor* _predictor): predictor(_predictor) {}
00018
00033 void build(int size, int root, int rank, int* counts,
00034 Graph& g, Vertex& r, Vertex& u, Vertex& v)
00035 {
00036
00037 r = add_vertex(g);
00038 put(vertex_index, g, r, root);
00039 if (rank == root)
00040 v = r;
00041
00042 deque<pair<int, double> > ranks;
00043 for (int i = 0; i < size; i++)
00044 if (i != root)
00045 ranks.push_back(make_pair(i, predictor->predict_p2p(predictor, root, i, counts[i])));
00046 sort(ranks.begin(), ranks.end(), second_greater());
00047
00048 deque<pair<Vertex, deque<int> > > sets;
00049 double sum = 0;
00050 double weight = 0;
00051 for (deque<pair<int, double> >::iterator i = ranks.begin(); i != ranks.end(); i++) {
00052 if (weight == 0) {
00053 sets.push_back(make_pair(r, deque<int>()));
00054
00055 if ((mpib_coll_verbose == 1) && (rank == root)) {
00056 printf("DEBUG: ===\n");
00057 }
00058
00059 }
00060 sets.back().second.push_back(i->first);
00061
00062 if ((mpib_coll_verbose == 1) && (rank == root)) {
00063 printf("DEBUG: add element %d , potential link (%d-%d), prediction: %lf\n", i->first, root, i->first, i->second);
00064 }
00065
00066 weight += i->second;
00067 if (weight >= sum) {
00068 sum += weight;
00069 weight = 0;
00070 }
00071 }
00072 if ((mpib_coll_verbose == 1) && (rank == root)) {
00073 printf("DEBUG: ===\n");
00074 }
00075
00076 while (!sets.empty()) {
00077
00078 Vertex s = sets.front().first;
00079 int source = get(vertex_index, g, s);
00080 deque<int>& targets = sets.front().second;
00081 int count = 0;
00082 for (deque<int>::iterator i = targets.begin(); i != targets.end(); i++)
00083 count += counts[*i];
00084
00085 deque<pair<int, double> > ranks;
00086 for (deque<int>::iterator i = targets.begin(); i != targets.end(); i++) {
00087 int target = *i;
00088 ranks.push_back(make_pair(target, predictor->predict_p2p(predictor, source, target, count)));
00089
00090 if ((mpib_coll_verbose == 1) && (rank == root)) {
00091 printf("DEBUG: add element %d , potential link (%d-%d), prediction: %lf\n", target, source, target, ranks.back().second);
00092 }
00093
00094 }
00095 deque<pair<int, double> >::iterator i = min_element(ranks.begin(), ranks.end(), second_less());
00096 int target = i->first;
00097 if ((mpib_coll_verbose == 1) && (rank == root)) {
00098 printf("DEBUG: create link (%d-%d) with prediction %lf\n", source, target, i->second);
00099 }
00100 ranks.erase(i);
00101 Vertex t = add_vertex(g);
00102 put(vertex_index, g, t, target);
00103 add_edge(s, t, g);
00104 if (rank == target) {
00105 u = s;
00106 v = t;
00107 }
00108
00109 for (deque<pair<int, double> >::iterator i = ranks.begin(); i != ranks.end(); i++) {
00110 int child = i->first;
00111 i->second = predictor->predict_p2p(predictor, target, child, counts[child]);
00112 }
00113 sort(ranks.begin(), ranks.end(), second_greater());
00114 double sum = 0;
00115 double weight = 0;
00116 for (deque<pair<int, double> >::iterator i = ranks.begin(); i != ranks.end(); i++) {
00117 if (weight == 0) {
00118 if ((mpib_coll_verbose == 1) && (rank == root)) {
00119 printf("DEBUG: ===\n");
00120 }
00121 sets.push_back(make_pair(t, deque<int>()));
00122 }
00123 sets.back().second.push_back(i->first);
00124 if ((mpib_coll_verbose == 1) && (rank == root)) {
00125 printf("DEBUG: add element %d , potential link (%d-%d), prediction: %lf\n", i->first, target, i->first, i->second);
00126 }
00127 weight += i->second;
00128 if (weight >= sum) {
00129 sum += weight;
00130 weight = 0;
00131 }
00132 }
00133 sets.pop_front();
00134
00135 if ((mpib_coll_verbose == 1) && (rank == root)) {
00136 printf("DEBUG: ===\n");
00137 }
00138 }
00139 }
00140 };
00141 }
00142 }
00143 #endif //CPM_SGV_TRAFF_TREE_BUILDER_HPP_