Refactoring the distributed tree builder.
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user