gtsam_points
Loading...
Searching...
No Matches
sort_omp.hpp
1// SPDX-FileCopyrightText: Copyright 2024 Kenji Koide
2// SPDX-License-Identifier: MIT
3#pragma once
4
5#include <algorithm>
6
7#ifdef _MSC_VER
8#pragma message("warning: Task-based OpenMP parallelism is not well supported on windows.")
9#pragma message("warning: Thus, OpenMP-based downsampling is only partially parallelized on windows.")
10#endif
11
12namespace gtsam_points {
13
18template <typename RandomAccessIterator, typename Compare>
19void quick_sort_omp_impl(RandomAccessIterator first, RandomAccessIterator last, const Compare& comp) {
20 const std::ptrdiff_t n = std::distance(first, last);
21 if (n < 1024) {
22 std::sort(first, last, comp);
23 return;
24 }
25
26 const auto median3 = [&](const auto& a, const auto& b, const auto& c, const Compare& comp) {
27 return comp(a, b) ? (comp(b, c) ? b : (comp(a, c) ? c : a)) : (comp(a, c) ? a : (comp(b, c) ? c : b));
28 };
29
30 const int offset = n / 8;
31 const auto m1 = median3(*first, *(first + offset), *(first + offset * 2), comp);
32 const auto m2 = median3(*(first + offset * 3), *(first + offset * 4), *(first + offset * 5), comp);
33 const auto m3 = median3(*(first + offset * 6), *(first + offset * 7), *(last - 1), comp);
34
35 auto pivot = median3(m1, m2, m3, comp);
36 auto middle1 = std::partition(first, last, [&](const auto& val) { return comp(val, pivot); });
37 auto middle2 = std::partition(middle1, last, [&](const auto& val) { return !comp(pivot, val); });
38
39#pragma omp task
40 quick_sort_omp_impl(first, middle1, comp);
41
42#pragma omp task
43 quick_sort_omp_impl(middle2, last, comp);
44}
45
51template <typename RandomAccessIterator, typename Compare>
52void quick_sort_omp(RandomAccessIterator first, RandomAccessIterator last, const Compare& comp, int num_threads) {
53#ifndef _MSC_VER
54#pragma omp parallel num_threads(num_threads)
55 {
56#pragma omp single nowait
57 { quick_sort_omp_impl(first, last, comp); }
58 }
59#else
60 std::sort(first, last, comp);
61#endif
62}
63
64} // namespace gtsam_points