Skip to content

Commit 37cc6d2

Browse files
authored
Add OpenMP Parallelization to FarthestPointSampling (#6287)
* changed behavior to index into user indices instead of total pointcloud * made index mapping lambda take auto parameter * Added parallel implementation of farthest_point_sampling * Added `default(none)` to the omp parallel clause * Fixed first set of review comments * Fixed race condition and added separate reduction section * Renamed nr_threads_ to num_threads_ * Switched num_threads_ == 0 to num_threads != 0
1 parent 79008f4 commit 37cc6d2

File tree

2 files changed

+48
-11
lines changed

2 files changed

+48
-11
lines changed

filters/include/pcl/filters/farthest_point_sampling.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,36 @@ namespace pcl
7979
return (seed_);
8080
}
8181

82+
/** \brief Set the number of threads to use when operating in parallel
83+
* \param num_threads the number of threads to use
84+
*/
85+
inline void
86+
setNumberOfThreads (unsigned int num_threads)
87+
{
88+
#ifdef _OPENMP
89+
num_threads_ = num_threads != 0 ? num_threads : omp_get_num_procs();
90+
#else
91+
if (num_threads_ != 1)
92+
PCL_WARN("OpenMP is not available. Keeping number of threads unchanged at 1\n");
93+
#endif
94+
}
95+
96+
/** \brief Get the value of the internal \a num_threads_ parameter.
97+
*/
98+
inline unsigned int
99+
getNumberOfThreads () const
100+
{
101+
return num_threads_;
102+
}
103+
82104
protected:
83105

84106
/** \brief Number of points that will be returned. */
85107
std::size_t sample_size_;
86108
/** \brief Random number seed. */
87109
unsigned int seed_;
110+
/** \brief Number of threads */
111+
unsigned int num_threads_{1};
88112

89113
/** \brief Sample of point indices
90114
* \param indices indices of the filtered point cloud

filters/include/pcl/filters/impl/farthest_point_sampling.hpp

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,23 +51,36 @@ pcl::FarthestPointSampling<PointT>::applyFilter (Indices &indices)
5151

5252
for (std::size_t j = 1; j < sample_size_; ++j)
5353
{
54-
index_t next_max_index = 0;
55-
5654
const PointT& max_index_point = (*input_)[toCloudIndex(max_index)];
57-
//recompute distances
58-
for (std::size_t i = 0; i < size; ++i)
55+
56+
#pragma omp parallel \
57+
default(none) \
58+
shared(distances_to_selected_points, max_index, max_index_point, size, toCloudIndex) \
59+
num_threads(num_threads_)
5960
{
60-
if (distances_to_selected_points[i] == -1.0)
61-
continue;
62-
distances_to_selected_points[i] = std::min(distances_to_selected_points[i], geometry::distance((*input_)[toCloudIndex(i)], max_index_point));
63-
if (distances_to_selected_points[i] > distances_to_selected_points[next_max_index])
64-
next_max_index = i;
65-
}
61+
std::ptrdiff_t local_max_index = max_index;
62+
63+
#pragma omp for
64+
for (std::ptrdiff_t i = 0; i < static_cast<std::ptrdiff_t>(size); ++i)
65+
{
66+
if (distances_to_selected_points[i] == -1.0)
67+
continue;
68+
distances_to_selected_points[i] = std::min(distances_to_selected_points[i], geometry::distance((*input_)[toCloudIndex(i)], max_index_point));
69+
if (distances_to_selected_points[i] > distances_to_selected_points[local_max_index]) {
70+
local_max_index = i;
71+
}
72+
}
73+
74+
#pragma omp critical
75+
{
76+
if (distances_to_selected_points[local_max_index] > distances_to_selected_points[max_index])
77+
max_index = local_max_index;
78+
}
79+
} //pragma omp parallel
6680

6781
//select farthest point based on previously calculated distances
6882
//since distance is set to -1 for all selected elements,previously selected
6983
//elements are guaranteed to not be selected
70-
max_index = next_max_index;
7184
distances_to_selected_points[max_index] = -1.0;
7285
indices.push_back(toCloudIndex(max_index));
7386
//set distance to -1 to ignore during max element search

0 commit comments

Comments
 (0)