00001 #ifndef TREE_BUILDERS_HPP_
00002 #define TREE_BUILDERS_HPP_
00003
00004 #include "comm_tree.hpp"
00005
00006 namespace MPIB {
00007
00023 namespace BRSG {
00024 using namespace comm_tree;
00025
00030 class Binomial_builder {
00031 public:
00032 void build(int size, int root, int rank, int count,
00033 Graph& g, Vertex& r, Vertex& u, Vertex& v)
00034 {
00035 r = add_vertex(g);
00036 put(vertex_index, g, r, root);
00037 if (rank == root) {
00038 v = r;
00039 }
00040
00041 deque<pair<Vertex, pair<int, int> > > subtrees;
00042
00043 for (int tmp = size - 1, bin = 1, index = 1; tmp > 0; tmp /= 2, bin *= 2) {
00044 if (tmp % 2) {
00045 subtrees.push_back(make_pair(r, make_pair(index, bin)));
00046 index += bin;
00047 }
00048 }
00049
00050 while (!subtrees.empty()) {
00051 pair<Vertex, pair<int, int> >& subtree = subtrees.front();
00052 Vertex s = subtree.first;
00053 Vertex t = add_vertex(g);
00054
00055 int index = subtree.second.first;
00056 int target = root + index;
00057 if (target >= size)
00058 target -= size;
00059 put(vertex_index, g, t, target);
00060 if (target == rank) {
00061 u = s;
00062 v = t;
00063 }
00064 pair<Edge, bool> e = add_edge(s, t, g);
00065 int bin = subtree.second.second;
00066 subtrees.pop_front();
00067 index += bin;
00068 for (bin /= 2; bin > 0; bin /= 2) {
00069 index -= bin;
00070 subtrees.push_front(make_pair(t, make_pair(index, bin)));
00071 }
00072 }
00073 }
00074 };
00075
00076 }
00077 }
00078
00079 #endif