Getting there.
This commit is contained in:
@@ -202,25 +202,40 @@ void RandomCombination(
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Implements Algorithm 1 in "Fast Construction of $k$-Nearest
|
||||
* Neighbor Graphs for Point Clouds" by Connor and Kumar, TVCG
|
||||
* 2009.
|
||||
*/
|
||||
template<typename T>
|
||||
int XorMsb(T a, T b) {
|
||||
|
||||
union {
|
||||
typedef union {
|
||||
T float_rep_;
|
||||
int int_rep_;
|
||||
} float_helper;
|
||||
|
||||
// The number of Mantissa bits.
|
||||
int num_mantissa_bits = std::numeric_limits<T>::digits();
|
||||
int a_exp, b_exp;
|
||||
union float_helper a_mantissa, b_mantissa;
|
||||
float_helper a_mantissa, b_mantissa;
|
||||
a_mantissa.float_rep_ = frexp(a, &a_exp);
|
||||
b_mantissa.float_rep_ = frexp(b, &b_exp);
|
||||
if(false) {
|
||||
a_exp -= 0;
|
||||
return a_exp;
|
||||
if(a_exp == b_exp) {
|
||||
|
||||
// Take the XOR of the two Mantissa bit representations and find
|
||||
// the most significant bit.
|
||||
int a_mantissa_xor_b_mantissa = a_mantissa.int_rep_ ^ b_mantissa.int_rep_;
|
||||
int most_significant_bit = 0;
|
||||
int shift_bit = 1;
|
||||
int num_bits_in_int = std::numeric_limits<int>::digits;
|
||||
for(int i = 0; i <= num_bits_in_int; i++) {
|
||||
if((shift_bit & a_mantissa_xor_b_mantissa) != 0) {
|
||||
most_significant_bit = shift_bit;
|
||||
}
|
||||
shift_bit = shift_bit << 1;
|
||||
}
|
||||
return a_exp - shift_bit;
|
||||
}
|
||||
if(false) {
|
||||
if(b_exp < a_exp) {
|
||||
return a_exp;
|
||||
}
|
||||
else {
|
||||
return b_exp;
|
||||
@@ -235,7 +250,7 @@ inline bool MortonOrderPoints(const PointType &a, const PointType &b) {
|
||||
int selected_dim = 0;
|
||||
|
||||
for(int d = 0; d < a.length(); d++) {
|
||||
int y = XorMsb(a[d], b[d]);
|
||||
long int y = XorMsb(a[d], b[d]);
|
||||
if(x < y) {
|
||||
x = y;
|
||||
selected_dim = d;
|
||||
|
||||
@@ -92,17 +92,27 @@ class TestDistributedTree {
|
||||
};
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(TestSuiteDistributedTree)
|
||||
BOOST_AUTO_TEST_CASE(TestCaseDistributedTree) {
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
// Initialize boost MPI.
|
||||
boost::mpi::environment env(argc, argv);
|
||||
boost::mpi::communicator world;
|
||||
|
||||
// Tree type: hard-coded for a metric tree.
|
||||
typedef core::table::Table <
|
||||
core::tree::GenMetricTree<core::tree::AbstractStatistic> > TableType;
|
||||
typedef core::tree::GenMetricTree<core::tree::AbstractStatistic> TreeSpecType;
|
||||
typedef core::table::Table <TreeSpecType> TableType;
|
||||
typedef core::table::DistributedTable<TreeSpecType> DistributedTableType;
|
||||
|
||||
DistributedTableType distributed_table;
|
||||
core::tree::DistributedTreeBuilder<DistributedTableType> builder;
|
||||
builder.Init(distributed_table, 0.2);
|
||||
core::metric_kernels::LMetric<2> l2_metric;
|
||||
builder.Build(l2_metric, world);
|
||||
|
||||
// Call the tests.
|
||||
core::tree::TestDistributedTree<TableType> tree_test;
|
||||
tree_test.StressTestMain();
|
||||
|
||||
std::cout << "All tests passed!\n";
|
||||
return 0;
|
||||
}
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
+14
-6
@@ -31,6 +31,12 @@ class DistributedTreeBuilder {
|
||||
|
||||
private:
|
||||
|
||||
static bool MortonOrderNodes_(TreeType *first_node, TreeType *second_node) {
|
||||
return
|
||||
core::math::MortonOrderPoints(
|
||||
first_node->bound().center(), second_node->bound().center());
|
||||
}
|
||||
|
||||
void AugmentNodes_(
|
||||
boost::mpi::communicator &world,
|
||||
const typename TreeType::BoundType &root_bound,
|
||||
@@ -57,7 +63,6 @@ class DistributedTreeBuilder {
|
||||
}
|
||||
tmp_point_alias = (1.0 / static_cast<double>(num_samples)) *
|
||||
tmp_point_alias;
|
||||
tmp_point_alias = 0.5 * (tmp_point_alias + random_point_on_surface);
|
||||
top_leaf_nodes.push_back(new TreeType());
|
||||
top_leaf_nodes[ top_leaf_nodes.size() - 1 ]->bound().center().Copy(
|
||||
tmp_point);
|
||||
@@ -88,7 +93,7 @@ class DistributedTreeBuilder {
|
||||
// send to the master. This is a MPI gather operation.
|
||||
TableType sampled_table;
|
||||
std::vector<int> sampled_indices;
|
||||
SelectSubset_(sampling_rate_, &sampled_indices);
|
||||
SelectSubset_(&sampled_indices);
|
||||
|
||||
// Send the number of points chosen in this process to the
|
||||
// master so that the master can allocate the appropriate amount
|
||||
@@ -123,8 +128,13 @@ class DistributedTreeBuilder {
|
||||
if(top_leaf_nodes_out->size() <
|
||||
static_cast<unsigned int>(world.size())) {
|
||||
AugmentNodes_(
|
||||
world, sampled_table.get_tree()->bound(), top_leaf_nodes_out);
|
||||
world, sampled_table.get_tree()->bound(), *top_leaf_nodes_out);
|
||||
}
|
||||
|
||||
// Sort the nodes by Z-ordering their centroids.
|
||||
std::sort(
|
||||
top_leaf_nodes_out->begin(), top_leaf_nodes_out->end(),
|
||||
MortonOrderNodes_);
|
||||
}
|
||||
boost::mpi::broadcast(world, *top_leaf_nodes_out, 0);
|
||||
}
|
||||
@@ -157,7 +167,7 @@ class DistributedTreeBuilder {
|
||||
sampling_rate_ = sampling_rate_in;
|
||||
}
|
||||
|
||||
void BuildTree(
|
||||
void Build(
|
||||
const core::metric_kernels::AbstractMetric &metric_in,
|
||||
boost::mpi::communicator &world) {
|
||||
|
||||
@@ -165,8 +175,6 @@ class DistributedTreeBuilder {
|
||||
std::vector<TreeType *> top_leaf_nodes;
|
||||
BuildSampleTree_(metric_in, world, &top_leaf_nodes);
|
||||
|
||||
// Sort the top leaf nodes by their Z-ordering.
|
||||
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user