Refactoring the distributed tree builder.

This commit is contained in:
Dongryeol Lee
2011-01-05 17:01:06 +00:00
parent f24c11e09b
commit 8f4ae972c2
2 changed files with 105 additions and 0 deletions
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 2.8)
set(SOURCES
ball_bound.h
distributed_tree_builder.h
general_spacetree.h
gen_kdtree.h
gen_metric_tree.h
@@ -0,0 +1,104 @@
/** @file distributed_tree_builder.h
*
* The generic template for building a distributed tree.
*
* @author Dongryeol Lee (dongryel@cc.gatech.edu)
*/
#ifndef CORE_TREE_DISTRIBUTED_TREE_BUILDER_H
#define CORE_TREE_DISTRIBUTED_TREE_BUILDER_H
#include <algorithm>
#include <boost/mpi.hpp>
#include "core/parallel/parallel_sample_sort.h"
namespace core {
namespace tree {
template<typename DistributedTableType>
class DistributedTreeBuilder {
public:
typedef typename DistributedTableType::TableType TableType;
private:
DistributedTableType *distributed_table_;
double sampling_rate_;
private:
void SetupGatherPointers_(
TableType &sampled_table, const std::vector<int> &counts,
std::vector<double *> *gather_pointers_out) {
// Have the pointers point to the right position based on the
// prefix sum position.
gather_pointers_out->resize(counts.size());
double *pointer = sampled_table.data().ptr();
for(unsigned int i = 0; i < counts.size(); i++) {
(*gather_pointers_out)[i] = pointer;
pointer += sampled_table.n_attributes() * counts[i];
}
}
void BuildSampleTree_(boost::mpi::communicator &world) {
// Each process generates a random subset of the data points to
// send to the master. This is a MPI gather operation.
TableType sampled_table;
std::vector<int> sampled_indices;
SelectSubset_(sampling_rate_, &sampled_indices);
// Send the number of points chosen in this process to the
// master so that the master can allocate the appropriate amount
// of space to receive all the points.
std::vector<int> counts;
int local_sampled_indices_size = static_cast<int>(
sampled_indices.size());
boost::mpi::gather(
table_outbox_group_comm, local_sampled_indices_size, counts, 0);
// The master process allocates the sample table and gathers the
// chosen samples from each process.
if(world.rank() == 0) {
int total_num_samples = std::accumulate(
counts.begin(), counts.end(), 0);
sampled_table.Init(
distributed_table_->n_attributes(), total_num_samples);
std::vector<double *> gather_pointers;
SetupGatherPointers_(sampled_table, counts, gather_pointers);
}
}
void SelectSubset_(
std::vector<int> *sampled_indices_out) {
std::vector<int> indices(owned_table_->n_entries(), 0);
for(unsigned int i = 0; i < indices.size(); i++) {
indices[i] = i;
}
int num_elements =
std::max(
(int) floor(sampling_rate_ * owned_table_->n_entries()), 1);
std::random_shuffle(indices.begin(), indices.end());
for(int i = 0; i < num_elements; i++) {
sampled_indices_out->push_back(indices[i]);
}
}
public:
void Init(
DistributedTableType &distributed_table_in, double sampling_rate_in) {
distributed_table_ = &distributed_table_in;
sampling_rate_ = sampling_rate_in;
}
void BuildTree(boost::mpi::communicator &world) {
}
};
};
};
#endif