diff --git a/fastlib/trunk/contrib/dongryel/thesis_research/core/tree/CMakeLists.txt b/fastlib/trunk/contrib/dongryel/thesis_research/core/tree/CMakeLists.txt index 403cb87950..19982dd6d7 100644 --- a/fastlib/trunk/contrib/dongryel/thesis_research/core/tree/CMakeLists.txt +++ b/fastlib/trunk/contrib/dongryel/thesis_research/core/tree/CMakeLists.txt @@ -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 diff --git a/fastlib/trunk/contrib/dongryel/thesis_research/core/tree/distributed_tree_builder.h b/fastlib/trunk/contrib/dongryel/thesis_research/core/tree/distributed_tree_builder.h new file mode 100644 index 0000000000..f7ec65851e --- /dev/null +++ b/fastlib/trunk/contrib/dongryel/thesis_research/core/tree/distributed_tree_builder.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 +#include +#include "core/parallel/parallel_sample_sort.h" + +namespace core { +namespace tree { +template +class DistributedTreeBuilder { + public: + typedef typename DistributedTableType::TableType TableType; + + private: + DistributedTableType *distributed_table_; + + double sampling_rate_; + + private: + + void SetupGatherPointers_( + TableType &sampled_table, const std::vector &counts, + std::vector *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 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 counts; + int local_sampled_indices_size = static_cast( + 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 gather_pointers; + SetupGatherPointers_(sampled_table, counts, gather_pointers); + + + } + } + + void SelectSubset_( + std::vector *sampled_indices_out) { + + std::vector 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