Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce new algorithm (FDBSCAN-DenseBox) for DBSCAN #508

Merged
merged 9 commits into from
May 28, 2021
3 changes: 2 additions & 1 deletion examples/dbscan/ArborX_DBSCANVerification.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,8 @@ bool verifyDBSCAN(ExecutionSpace exec_space, Primitives const &primitives,

ArborX::BVH<MemorySpace> bvh(exec_space, primitives);

auto const predicates = buildPredicates(primitives, eps);
auto const predicates =
Details::PrimitivesWithRadius<Primitives>{primitives, eps};

Kokkos::View<int *, MemorySpace> indices("ArborX::DBSCAN::indices", 0);
Kokkos::View<int *, MemorySpace> offset("ArborX::DBSCAN::offset", 0);
Expand Down
60 changes: 57 additions & 3 deletions examples/dbscan/dbscan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,46 @@ void printClusterSizesAndCenters(ExecutionSpace const &exec_space,
}
}

namespace ArborX
{
namespace DBSCAN
{
// This function is required for Boost program_options to be able to use the
// Implementation enum.
std::istream &operator>>(std::istream &in, Implementation &implementation)
{
std::string impl_string;
in >> impl_string;

if (impl_string == "fdbscan")
implementation = ArborX::DBSCAN::Implementation::FDBSCAN;
else if (impl_string == "fdbscan-densebox")
implementation = ArborX::DBSCAN::Implementation::FDBSCAN_DenseBox;
else
in.setstate(std::ios_base::failbit);

return in;
}

// This function is required for Boost program_options to use Implementation
// enum as the default_value().
std::ostream &operator<<(std::ostream &out,
Implementation const &implementation)
dalg24 marked this conversation as resolved.
Show resolved Hide resolved
{
switch (implementation)
{
case ArborX::DBSCAN::Implementation::FDBSCAN:
out << "fdbscan";
break;
case ArborX::DBSCAN::Implementation::FDBSCAN_DenseBox:
out << "fdbscan-densebox";
break;
}
return out;
}
} // namespace DBSCAN
} // namespace ArborX

int main(int argc, char *argv[])
{
using ExecutionSpace = Kokkos::DefaultExecutionSpace;
Expand All @@ -308,6 +348,7 @@ int main(int argc, char *argv[])
std::cout << "ArborX hash : " << ArborX::gitCommitHash() << std::endl;

namespace bpo = boost::program_options;
using ArborX::DBSCAN::Implementation;

std::string filename;
bool binary;
Expand All @@ -320,6 +361,7 @@ int main(int argc, char *argv[])
int max_num_points;
int num_samples;
std::string filename_labels;
Implementation implementation;

bpo::options_description desc("Allowed options");
// clang-format off
Expand All @@ -336,6 +378,7 @@ int main(int argc, char *argv[])
( "labels", bpo::value<std::string>(&filename_labels)->default_value(""), "clutering results output" )
( "print-dbscan-timers", bpo::bool_switch(&print_dbscan_timers)->default_value(false), "print dbscan timers")
( "output-sizes-and-centers", bpo::bool_switch(&print_sizes_centers)->default_value(false), "print cluster sizes and centers")
( "impl", bpo::value<Implementation>(&implementation)->default_value(Implementation::FDBSCAN), R"(implementation ("fdbscan" or "fdbscan-densebox"))")
;
// clang-format on
bpo::variables_map vm;
Expand All @@ -348,13 +391,17 @@ int main(int argc, char *argv[])
return 1;
}

std::stringstream ss;
ss << implementation;

// Print out the runtime parameters
printf("eps : %f\n", eps);
printf("minpts : %d\n", core_min_size);
printf("cluster min size : %d\n", cluster_min_size);
printf("filename : %s [%s, max_pts = %d]\n", filename.c_str(),
(binary ? "binary" : "text"), max_num_points);
printf("filename [labels] : %s [binary]\n", filename_labels.c_str());
printf("implementation : %s\n", ss.str().c_str());
printf("samples : %d\n", num_samples);
printf("verify : %s\n", (verify ? "true" : "false"));
printf("print timers : %s\n", (print_dbscan_timers ? "true" : "false"));
Expand Down Expand Up @@ -386,9 +433,10 @@ int main(int argc, char *argv[])

timer_start(timer_total);

auto labels = ArborX::dbscan(
exec_space, primitives, eps, core_min_size,
ArborX::DBSCAN::Parameters().setPrintTimers(print_dbscan_timers));
auto labels = ArborX::dbscan(exec_space, primitives, eps, core_min_size,
ArborX::DBSCAN::Parameters()
.setPrintTimers(print_dbscan_timers)
.setImplementation(implementation));

timer_start(timer);
Kokkos::View<int *, MemorySpace> cluster_indices("Testing::cluster_indices",
Expand All @@ -402,6 +450,12 @@ int main(int argc, char *argv[])
printf("-- postprocess : %10.3f\n", elapsed["cluster"]);
printf("total time : %10.3f\n", elapsed["total"]);

int num_clusters = cluster_offset.size() - 1;
int num_cluster_points = cluster_indices.size();
printf("\n#clusters : %d\n", num_clusters);
printf("#cluster points : %d [%.2f%%]\n", num_cluster_points,
(100.f * num_cluster_points / data.size()));

if (verify)
{
auto passed = ArborX::Details::verifyDBSCAN(exec_space, primitives, eps,
Expand Down
Loading