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} \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 \section Performance Performance
\subsection OrthogonalPerfomance Performance of the Orthogonal Search \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 with a factor 1/ (1+\f$ \epsilon\f$). Priority search supports next
neighbor search, standard search does not. 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 In order to speed-up the internal distance computations in nearest
neighbor searching in high dimensional space, the approximate neighbor searching in high dimensional space, the approximate
searching package supports orthogonal distance computation. Orthogonal distance searching package supports orthogonal distance computation. Orthogonal distance

View File

@ -18,4 +18,5 @@
\example Spatial_searching/weighted_Minkowski_distance.cpp \example Spatial_searching/weighted_Minkowski_distance.cpp
\example Spatial_searching/splitter_worst_cases.cpp \example Spatial_searching/splitter_worst_cases.cpp
\example Spatial_searching/searching_sphere_orthogonally.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" ) 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_circular_query.cpp" )
create_single_source_cgal_program( "searching_with_point_with_info.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.") message(STATUS "will not be compiled as they use CGAL::Epick_d which requires the Eigen library.")
endif() 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()); 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); Point_d query(0,0);
// Initialize the search structure, and search all N points // 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;
}