Improve doc from review with new example for parallel KD tree

This commit is contained in:
Simon Giraudot 2020-03-12 12:21:21 +01:00
parent fe90d1ca1f
commit 35c838d26c
5 changed files with 83 additions and 15 deletions

View File

@ -407,6 +407,23 @@ higher dimensions.
\cgalExample{Spatial_searching/splitter_worst_cases.cpp}
\subsection Spatial_searchingExampleParallel Example for Parallel Neighbor Search
In order to speed-up the construction of the `kd` tree, the child
branches of each internal node can be computed in parallel, by calling
`Kd_tree::build<CGAL::Parallel_tag>()`. On a quad-core processor, the
parallel construction is experimentally 2 to 3 times faster than the
sequential version, depending on the point cloud. The parallel version
requires the executable to be linked against the <a href="https://www.threadingbuildingblocks.org">Intel TBB library</a>.
One query on the `kd` tree is purely sequential, but several queries
can be done in parallel.
The following example shows how to build the `kd` tree in parallel and
how to perform parallel queries:
\cgalExample{Spatial_searching/parallel_kdtree.cpp}
\section Performance Performance
\subsection OrthogonalPerfomance Performance of the Orthogonal Search
@ -480,13 +497,6 @@ to the nearest nodes exceeds the distance to the nearest point found
with a factor 1/ (1+\f$ \epsilon\f$). Priority search supports next
neighbor search, standard search does not.
In order to speed-up the construction of the `kd` tree, the child
branches of each internal node can be computed in parallel, by calling
`Kd_tree::build<CGAL::Parallel_tag>()`. On a quad-core processor, the
parallel construction is experimentally 2 to 3 times faster than the
sequential version, depending on the point cloud. The parallel version
requires the executable to be linked against the <a href="https://www.threadingbuildingblocks.org">Intel TBB library</a>.
In order to speed-up the internal distance computations in nearest
neighbor searching in high dimensional space, the approximate
searching package supports orthogonal distance computation. Orthogonal distance

View File

@ -18,4 +18,5 @@
\example Spatial_searching/weighted_Minkowski_distance.cpp
\example Spatial_searching/splitter_worst_cases.cpp
\example Spatial_searching/searching_sphere_orthogonally.cpp
\example Spatial_searching/parallel_kdtree.cpp
*/

View File

@ -43,11 +43,6 @@ create_single_source_cgal_program( "iso_rectangle_2_query.cpp" )
create_single_source_cgal_program( "nearest_neighbor_searching.cpp" )
find_package( TBB QUIET )
if(TBB_FOUND)
cgal_target_use_TBB(nearest_neighbor_searching)
endif()
create_single_source_cgal_program( "searching_with_circular_query.cpp" )
create_single_source_cgal_program( "searching_with_point_with_info.cpp" )
@ -82,3 +77,12 @@ else()
message(STATUS "will not be compiled as they use CGAL::Epick_d which requires the Eigen library.")
endif()
find_package( TBB QUIET )
if(TBB_FOUND)
create_single_source_cgal_program( "parallel_kdtree.cpp" )
cgal_target_use_TBB(parallel_kdtree)
else()
message(STATUS "parallel_kdtree.cpp requires TBB and will not be compiled")
endif()

View File

@ -20,9 +20,6 @@ int main() {
Tree tree(points.begin(), points.end());
// The tree can be built in parallel
tree.build<CGAL::Parallel_if_available_tag>();
Point_d query(0,0);
// Initialize the search structure, and search all N points

View File

@ -0,0 +1,56 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/point_generators_3.h>
#include <CGAL/Orthogonal_k_neighbor_search.h>
#include <CGAL/Search_traits_3.h>
#include <tbb/blocked_range.h>
#include <tbb/parallel_for.h>
using Kernel = CGAL::Simple_cartesian<double>;
using Point_3 = Kernel::Point_3;
using Traits = CGAL::Search_traits_3<Kernel>;
using Neighbor_search = CGAL::Orthogonal_k_neighbor_search<Traits>;
using Tree = Neighbor_search::Tree;
using Point_with_distance = Neighbor_search::Point_with_transformed_distance;
using Generator = CGAL::Random_points_in_sphere_3<Point_3>;
int main()
{
const unsigned int N = 1000;
const unsigned int k = 6;
// Generate N points in a sphere
std::vector<Point_3> points;
points.reserve (N);
Generator generator;
for (unsigned int i = 0; i < N; ++ i)
points.push_back (*(generator++));
// Build tree in parallel
Tree tree(points.begin(), points.end());
tree.build<CGAL::Parallel_tag>();
// Query tree in parallel
std::vector<std::vector<Point_3> > neighbors (points.size());
tbb::parallel_for (tbb::blocked_range<std::size_t> (0, points.size()),
[&](const tbb::blocked_range<std::size_t>& r)
{
for (std::size_t s = r.begin(); s != r.end(); ++ s)
{
// Neighbor search can be instantiated from
// several threads at the same time
Neighbor_search search (tree, points[s], k);
neighbors[s].reserve(k);
// neighbor search returns a set of pair of
// point and distance <Point_3,FT>, here we
// keep the points only
for (const Point_with_distance& pwd : search)
neighbors[s].push_back (pwd.first);
}
});
return 0;
}