00001 #ifndef CPM_BRSG_TREE_BUILDERS_HPP_
00002 #define CPM_BRSG_TREE_BUILDERS_HPP_
00003
00004 #include "MPIBlib/collectives/comm_tree.hpp"
00005 #include "cpm_model.h"
00006 #include "collectives/cpm_coll_ops_list.h"
00007 #include "cpm_functional.hpp"
00008
00009 namespace CPM {
00011 namespace BRSG {
00012 using namespace MPIB::comm_tree;
00013
00018 class UCS_binomial_builder {
00019 protected:
00020 CPM_predictor* predictor;
00021 CPM_next_node_strategy next_node;
00022 CPM_coll_op_types coll_op;
00023
00024 public:
00025 UCS_binomial_builder(CPM_predictor* _predictor, CPM_next_node_strategy _next_node, CPM_coll_op_types _coll_op): predictor(_predictor), next_node(_next_node), coll_op(_coll_op) {}
00026
00027 void build(int size, int root, int rank, int count,
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 i->second = predictor->predict_p2p(predictor, source, i->first, (coll_op == BR)? count : (count * bin));
00059 deque<pair<int, double> >::iterator i = (next_node == MAX) ?
00060 max_element(ranks.begin(), ranks.end(), second_less()):
00061 min_element(ranks.begin(), ranks.end(), second_less());
00062 int target = i->first;
00063
00064 if ( (rank == root) && (mpib_coll_verbose ==1) ){
00065 printf("DEBUG: source(fixed)= %d, target(selected)=%d, prediction=%lf, message_size=%d\n", source, target, i->second, (coll_op == BR)? count : (bin * count));
00066 for (deque<pair<int, double> >::iterator i = ranks.begin(); i != ranks.end(); i++) {
00067 printf("DEBUG: alternative link prediction: (%d-%d) = %lf\n", source, i->first, i->second);
00068 }
00069 printf("DEBUG: ===\n");
00070 }
00071
00072 ranks.erase(i);
00073 Vertex t = add_vertex(g);
00074 put(vertex_index, g, t, target);
00075 add_edge(s, t, g);
00076
00077
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
00096 class BFS_binomial_builder {
00097 private:
00098 CPM_predictor* predictor;
00099 CPM_next_node_strategy next_node;
00100 CPM_coll_op_types coll_op;
00101
00102 public:
00103 BFS_binomial_builder(CPM_predictor* _predictor, CPM_next_node_strategy _next_node, CPM_coll_op_types _coll_op): predictor(_predictor), next_node(_next_node), coll_op(_coll_op) {}
00104
00105 void build(int size, int root, int rank, int count,
00106 Graph& g, Vertex& r, Vertex& u, Vertex& v)
00107 {
00108
00109 r = add_vertex(g);
00110 put(vertex_index, g, r, root);
00111 if (rank == root)
00112 v = r;
00113
00114 deque<pair<int, double> > ranks;
00115 for (int i = 0; i < size; i++)
00116 if (i != root)
00117 ranks.push_back(make_pair(i, 0));
00118
00119 deque<pair<Vertex, int> > blocks;
00120
00121 for (int tmp = size - 1, bin = 1; tmp > 0; tmp /= 2, bin *= 2)
00122 if (tmp % 2)
00123 blocks.push_back(make_pair(r, bin));
00124
00125 while (!blocks.empty()) {
00126 Vertex s = blocks.back().first;
00127 int source = get(vertex_index, g, s);
00128 int bin = blocks.back().second;
00129 for (deque<pair<int, double> >::iterator i = ranks.begin(); i != ranks.end(); i++) {
00130 int target = i->first;
00131 i->second = predictor->predict_p2p(predictor, source, target, (coll_op == BR ) ? count : (count * bin));
00132 }
00133 deque<pair<int, double> >::iterator i = (next_node == MAX) ?
00134 max_element(ranks.begin(), ranks.end(), second_less()):
00135 min_element(ranks.begin(), ranks.end(), second_less());
00136 int target = i->first;
00137
00138 if ( (rank == root) && (mpib_coll_verbose ==1) ){
00139 printf("DEBUG: source(fixed)= %d, target(selected)=%d, prediction=%lf, message_size=%d\n", source, target, i->second, (coll_op == BR)? count : (bin * count));
00140 for (deque<pair<int, double> >::iterator i = ranks.begin(); i != ranks.end(); i++) {
00141 printf("DEBUG: alternative link prediction: (%d-%d) = %lf\n", source, i->first, i->second);
00142 }
00143 printf("DEBUG: ===\n");
00144 }
00145
00146 ranks.erase(i);
00147 Vertex t = add_vertex(g);
00148 put(vertex_index, g, t, target);
00149 if (rank == target) {
00150 u = s;
00151 v = t;
00152 }
00153 add_edge(s, t, g);
00154 blocks.pop_back();
00155 for (bin /= 2; bin > 0; bin /= 2)
00156 blocks.push_front(make_pair(t, bin));
00157 }
00158 }
00159 };
00160
00165 class DFS_binomial_builder {
00166
00167 private:
00168 CPM_predictor* predictor;
00169 CPM_next_node_strategy next_node;
00170 CPM_coll_op_types coll_op;
00171
00172 public:
00173 DFS_binomial_builder(CPM_predictor* _predictor, CPM_next_node_strategy _next_node, CPM_coll_op_types _coll_op): predictor(_predictor), next_node(_next_node), coll_op(_coll_op) {}
00174
00175 void build(int size, int root, int rank, int count,
00176 Graph& g, Vertex& r, Vertex& u, Vertex& v)
00177 {
00178
00179 r = add_vertex(g);
00180 put(vertex_index, g, r, root);
00181 if (rank == root)
00182 v = r;
00183
00184 deque<pair<int, double> > ranks;
00185 for (int i = 0; i < size; i++)
00186 if (i != root)
00187 ranks.push_back(make_pair(i, 0));
00188
00189 deque<pair<Vertex, int> > blocks;
00190 int bin;
00191
00192 for (int tmp = size - 1, bin = 1; tmp > 0; tmp /= 2, bin *= 2)
00193 if (tmp % 2)
00194 blocks.push_back(make_pair(r, bin));
00195
00196 while (!blocks.empty()) {
00197 Vertex s = blocks.front().first;
00198 bin = blocks.front().second;
00199 int source = get(vertex_index, g, s);
00200 for (deque<pair<int, double> >::iterator i = ranks.begin(); i != ranks.end(); i++) {
00201 int target = i->first;
00202 i->second = predictor->predict_p2p(predictor, source, target, (coll_op == BR ) ? count : (count * bin));
00203 }
00204 deque<pair<int, double> >::iterator i = (next_node == MAX) ?
00205 max_element(ranks.begin(), ranks.end(), second_less()):
00206 min_element(ranks.begin(), ranks.end(), second_less());
00207 int target = i->first;
00208 if ( (rank == root) && (mpib_coll_verbose ==1) ){
00209 printf("DEBUG: source(fixed)= %d, target(selected)=%d, prediction=%lf, message_size=%d\n", source, target, i->second, (coll_op == BR)? count : (bin * count));
00210 for (deque<pair<int, double> >::iterator i = ranks.begin(); i != ranks.end(); i++) {
00211 printf("DEBUG: alternative link prediction: (%d-%d) = %lf\n", source, i->first, i->second);
00212 }
00213 printf("DEBUG: ===\n");
00214 }
00215
00216 ranks.erase(i);
00217 Vertex t = add_vertex(g);
00218 put(vertex_index, g, t, target);
00219 if (rank == target) {
00220 u = s;
00221 v = t;
00222 }
00223 add_edge(s, t, g);
00224 blocks.pop_front();
00225 for (bin /= 2; bin > 0; bin /= 2)
00226 blocks.push_front(make_pair(t, bin));
00227 }
00228 }
00229 };
00230 }
00231 }
00232
00233 #endif //CPM_BRSG_TREE_BUILDERS_HPP_