Skip to content

Commit 22236ea

Browse files
Integrate v0.3
1 parent b27e2b2 commit 22236ea

22 files changed

+748
-187
lines changed

common/CMakeLists.txt

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,11 @@ set(executor_incs
175175
include/pcl/experimental/executor/executor.h
176176
include/pcl/experimental/executor/property.h
177177
include/pcl/experimental/executor/type_trait.h
178-
)
179-
180-
set(executor_default_incs_impl
181-
include/pcl/experimental/executor/default/cuda_executor.hpp
182-
include/pcl/experimental/executor/default/omp_executor.hpp
183-
include/pcl/experimental/executor/default/inline_executor.hpp
184-
include/pcl/experimental/executor/default/sse_executor.hpp
178+
include/pcl/experimental/executor/cuda_executor.hpp
179+
include/pcl/experimental/executor/omp_executor.hpp
180+
include/pcl/experimental/executor/inline_executor.hpp
181+
include/pcl/experimental/executor/sse_executor.hpp
182+
include/pcl/experimental/executor/best_fit.hpp
185183
)
186184

187185
set(executor_property_incs_impl
@@ -230,6 +228,5 @@ PCL_ADD_INCLUDES("${SUBSYS_NAME}" console ${tools_incs})
230228
PCL_ADD_INCLUDES("${SUBSYS_NAME}" range_image ${range_image_incs})
231229
PCL_ADD_INCLUDES("${SUBSYS_NAME}" range_image/impl ${range_image_incs_impl})
232230
PCL_ADD_INCLUDES("${SUBSYS_NAME}" experimental/executor ${executor_incs})
233-
PCL_ADD_INCLUDES("${SUBSYS_NAME}" experimental/executor/default ${executor_default_incs_impl})
234231
PCL_ADD_INCLUDES("${SUBSYS_NAME}" experimental/executor/property ${executor_property_incs_impl})
235232
PCL_ADD_INCLUDES("${SUBSYS_NAME}" experimental/executor/trait ${executor_trait_incs_impl})
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/*
2+
* SPDX-License-Identifier: BSD-3-Clause
3+
*
4+
* Point Cloud Library (PCL) - www.pointclouds.org
5+
* Copyright (c) 2020-, Open Perception, Inc.
6+
* Author(s): Shrijit Singh <[email protected]>
7+
*
8+
*/
9+
10+
#pragma once
11+
12+
#include <pcl/experimental/executor/type_trait.h>
13+
14+
#include <pcl/experimental/executor//cuda_executor.hpp>
15+
#include <pcl/experimental/executor//inline_executor.hpp>
16+
#include <pcl/experimental/executor//omp_executor.hpp>
17+
#include <pcl/experimental/executor//sse_executor.hpp>
18+
#include <thread>
19+
20+
#include <cstring>
21+
22+
namespace executor {
23+
24+
static const auto best_fit_executors =
25+
std::make_tuple(executor::omp_executor<>{}, executor::sse_executor<>{},
26+
executor::inline_executor<>{});
27+
28+
struct executor_runtime_checks {
29+
template <typename Executor, typename executor::InstanceOf<
30+
Executor, executor::inline_executor> = 0>
31+
static bool check(Executor& exec) {
32+
pcl::utils::ignore(exec);
33+
return true;
34+
}
35+
36+
template <typename Executor,
37+
typename executor::InstanceOf<Executor, executor::sse_executor> = 0>
38+
static bool check(Executor& exec) {
39+
pcl::utils::ignore(exec);
40+
if (const char* env_p = std::getenv("PCL_ENABLE_SSE_EXEC"))
41+
return strcasecmp(env_p, "ON") == 0;
42+
return true;
43+
}
44+
45+
template <typename Executor,
46+
typename executor::InstanceOf<Executor, executor::omp_executor> = 0>
47+
static bool check(Executor& exec) {
48+
if (const char* env_p = std::getenv("PCL_ENABLE_OMP_EXEC"))
49+
return strcasecmp(env_p, "OFF") == 0;
50+
51+
// If hardware_concurrency() fails to get the number of threads than set max
52+
// threads to 2 as a fallback to prevent unwanted scaling in machines with
53+
// large number of available threads
54+
auto max_threads =
55+
std::max(std::min(std::thread::hardware_concurrency(), 8u), 2u);
56+
exec.set_max_threads(max_threads);
57+
58+
return true;
59+
}
60+
61+
template <typename Executor, typename executor::InstanceOf<
62+
Executor, executor::cuda_executor> = 0>
63+
static bool check(Executor& exec) {
64+
pcl::utils::ignore(exec);
65+
if (const char* env_p = std::getenv("PCL_ENABLE_CUDA_EXEC"))
66+
return strcasecmp(env_p, "ON") == 0;
67+
return true;
68+
}
69+
};
70+
71+
namespace detail {
72+
73+
template <typename Function, typename Executor, typename = void>
74+
bool execute(Function&& f, Executor& exec) {
75+
pcl::utils::ignore(f, exec);
76+
return false;
77+
}
78+
79+
template <typename Function, template <typename...> class Executor,
80+
typename... Properties,
81+
typename std::enable_if<executor::is_executor_available_v<Executor>,
82+
int>::type = 0>
83+
bool execute(Function&& f, Executor<Properties...>& exec) {
84+
f(exec);
85+
return true;
86+
}
87+
88+
template <typename Supported>
89+
struct executor_predicate {
90+
template <typename T, typename = void>
91+
struct condition : std::false_type {};
92+
93+
template <typename T>
94+
struct condition<T,
95+
std::enable_if_t<is_executor_instance_available<T>::value &&
96+
tuple_contains_type<T, Supported>::value>>
97+
: std::true_type {};
98+
};
99+
100+
} // namespace detail
101+
102+
template <typename RuntimeChecks = executor_runtime_checks, typename Function,
103+
typename... SupportedExecutors>
104+
void enable_exec_with_priority(
105+
Function&& f, std::tuple<SupportedExecutors...> supported_execs) {
106+
static_assert(std::is_base_of<executor_runtime_checks, RuntimeChecks>::value,
107+
"Runtime checks should inherit from executor_runtime_checks");
108+
bool executor_selected = false;
109+
executor::for_each_until_true(supported_execs, [&](auto& exec) {
110+
if (RuntimeChecks::check(exec)) {
111+
executor_selected = detail::execute(f, exec);
112+
return executor_selected;
113+
}
114+
return false;
115+
});
116+
117+
// This should not happen, at least one executor should always be selected. So
118+
// either all runtime checks failed which is incorrect behaviour or no
119+
// supported executors were passed which should not be done
120+
if (!executor_selected)
121+
std::cerr << "No executor selected. All runtime checks returned false or "
122+
"no executors were passed."
123+
<< std::endl;
124+
}
125+
126+
template <typename RuntimeChecks = executor_runtime_checks, typename Function,
127+
typename... SupportedExecutors>
128+
void enable_exec_with_priority(Function&& f, SupportedExecutors&&... execs) {
129+
enable_exec_with_priority<RuntimeChecks>(f, std::make_tuple(execs...));
130+
}
131+
132+
template <typename RuntimeChecks = executor_runtime_checks, typename Function,
133+
typename... SupportedExecutors>
134+
void enable_exec_on_desc_priority(
135+
Function&& f, std::tuple<SupportedExecutors...> supported_execs) {
136+
static_assert(std::is_base_of<executor_runtime_checks, RuntimeChecks>::value,
137+
"Runtime checks should inherit from executor_runtime_checks");
138+
139+
using predicate = detail::executor_predicate<decltype(supported_execs)>;
140+
filter_tuple_values<predicate::template condition,
141+
decltype(best_fit_executors)>
142+
filter_available;
143+
144+
auto filtered = filter_available(best_fit_executors);
145+
146+
enable_exec_with_priority(f, filtered);
147+
}
148+
149+
template <typename RuntimeChecks = executor_runtime_checks, typename Function,
150+
typename... SupportedExecutors>
151+
void enable_exec_on_desc_priority(Function&& f,
152+
SupportedExecutors&&... supported_execs) {
153+
enable_exec_on_desc_priority<RuntimeChecks>(
154+
f, std::make_tuple(supported_execs...));
155+
}
156+
157+
} // namespace executor

common/include/pcl/experimental/executor/blocking.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,19 @@
22
* SPDX-License-Identifier: BSD-3-Clause
33
*
44
* Point Cloud Library (PCL) - www.pointclouds.org
5-
* Copyright (c) 2014-, Open Perception, Inc.
5+
* Copyright (c) 2020-, Open Perception, Inc.
66
* Author(s): Shrijit Singh <[email protected]>
77
*
88
*/
9-
#include <pcl/experimental/executor/property.h>
9+
#include <pcl/experimental/executor/property/blocking.hpp>
1010

1111
namespace executor {
12+
/**
13+
* \todo Can inline member variable in C++17 into blocking.hpp, eliminating
14+
* need for separate CPP file.
15+
* Workaround: https://stackoverflow.com/questions/8016780/undefined-reference-to-static-constexpr-char
16+
* inline constexpr blocking_t::possibly_t blocking_t::possibly;
17+
*/
1218
constexpr blocking_t::possibly_t blocking_t::possibly;
1319
constexpr blocking_t::always_t blocking_t::always;
1420
constexpr blocking_t::never_t blocking_t::never;

common/include/pcl/experimental/executor/default/cuda_executor.hpp renamed to common/include/pcl/experimental/executor/cuda_executor.hpp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
* SPDX-License-Identifier: BSD-3-Clause
33
*
44
* Point Cloud Library (PCL) - www.pointclouds.org
5-
* Copyright (c) 2014-, Open Perception, Inc.
5+
* Copyright (c) 2020-, Open Perception, Inc.
66
* Author: Shrijit Singh <[email protected]>
77
*
88
*/
99

1010
#pragma once
1111

12-
#ifdef CUDA
12+
#ifdef __CUDACC__
1313
#include <cuda_runtime_api.h>
1414
#endif
1515

@@ -18,7 +18,7 @@
1818

1919
namespace executor {
2020

21-
#ifdef CUDA
21+
#ifdef __CUDACC__
2222
template <typename F>
2323
__global__ void global_kernel(F f) {
2424
f();
@@ -28,7 +28,7 @@ __global__ void global_kernel(F f) {
2828
template <typename Blocking, typename ProtoAllocator>
2929
struct cuda_executor;
3030

31-
#ifdef CUDA
31+
#ifdef __CUDACC__
3232
template <>
3333
struct is_executor_available<cuda_executor> : std::true_type {};
3434
#endif
@@ -44,21 +44,25 @@ struct cuda_executor {
4444

4545
using shape_type = cuda_dim;
4646

47-
template <typename Executor, instance_of_base<Executor, cuda_executor> = 0>
47+
template <typename Executor, InstanceOf<Executor, cuda_executor> = 0>
4848
friend bool operator==(const cuda_executor& lhs,
4949
const Executor& rhs) noexcept {
50+
pcl::utils::ignore(lhs, rhs);
5051
return std::is_same<cuda_executor, Executor>::value;
5152
}
5253

53-
template <typename Executor, instance_of_base<Executor, cuda_executor> = 0>
54+
template <typename Executor, InstanceOf<Executor, cuda_executor> = 0>
5455
friend bool operator!=(const cuda_executor& lhs,
5556
const Executor& rhs) noexcept {
57+
pcl::utils::ignore(lhs, rhs);
5658
return !operator==(lhs, rhs);
5759
}
5860

5961
template <typename F>
6062
void execute(F& f) const {
61-
#ifdef CUDA
63+
static_assert(is_executor_available_v<cuda_executor>, "CUDA executor unavailable");
64+
pcl::utils::ignore(f);
65+
#ifdef __CUDACC__
6266
void* global_kernel_args[] = {static_cast<void*>(&f)};
6367
cudaLaunchKernel(reinterpret_cast<void*>(global_kernel<F>), 1, 1,
6468
global_kernel_args, 0, nullptr);
@@ -69,9 +73,10 @@ struct cuda_executor {
6973
// Passing rvalue reference of function doesn't currently work with CUDA for
7074
// some reason
7175
template <typename F>
72-
void bulk_execute(F& f, const shape_type shape) const {
73-
// TODO: Add custom shape property for CUDA executor
74-
#ifdef CUDA
76+
void bulk_execute(F& f, const shape_type& shape) const {
77+
static_assert(is_executor_available_v<cuda_executor>, "CUDA executor unavailable");
78+
pcl::utils::ignore(f, shape);
79+
#ifdef __CUDACC__
7580
void* global_kernel_args[] = {static_cast<void*>(&f)};
7681
dim3 grid_size(shape.grid_dim.x, shape.grid_dim.y, shape.grid_dim.z);
7782
dim3 block_size(shape.block_dim.x, shape.block_dim.y, shape.block_dim.z);
@@ -88,7 +93,9 @@ struct cuda_executor {
8893
return {};
8994
}
9095

91-
static constexpr auto name() { return "cuda"; }
96+
static constexpr auto name() { return "cuda_executor"; }
9297
};
9398

99+
using default_cuda_executor = cuda_executor<>;
100+
94101
} // namespace executor

common/include/pcl/experimental/executor/executor.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,18 @@
22
* SPDX-License-Identifier: BSD-3-Clause
33
*
44
* Point Cloud Library (PCL) - www.pointclouds.org
5-
* Copyright (c) 2014-, Open Perception, Inc.
5+
* Copyright (c) 2020-, Open Perception, Inc.
66
* Author: Shrijit Singh <[email protected]>
77
*
88
*/
99

1010
#pragma once
1111

12-
#include <pcl/experimental/executor/default/cuda_executor.hpp>
13-
#include <pcl/experimental/executor/default/inline_executor.hpp>
14-
#include <pcl/experimental/executor/default/omp_executor.hpp>
15-
#include <pcl/experimental/executor/default/sse_executor.hpp>
1612
#include <pcl/experimental/executor/property.h>
1713
#include <pcl/experimental/executor/type_trait.h>
1814

19-
namespace executor {
20-
using best_fit = executor::inline_executor<>;
21-
}
15+
#include <pcl/experimental/executor/best_fit.hpp>
16+
#include <pcl/experimental/executor/cuda_executor.hpp>
17+
#include <pcl/experimental/executor/inline_executor.hpp>
18+
#include <pcl/experimental/executor/omp_executor.hpp>
19+
#include <pcl/experimental/executor/sse_executor.hpp>

common/include/pcl/experimental/executor/default/inline_executor.hpp renamed to common/include/pcl/experimental/executor/inline_executor.hpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22
* SPDX-License-Identifier: BSD-3-Clause
33
*
44
* Point Cloud Library (PCL) - www.pointclouds.org
5-
* Copyright (c) 2014-, Open Perception, Inc.
5+
* Copyright (c) 2020-, Open Perception, Inc.
66
* Author: Shrijit Singh <[email protected]>
77
*
88
*/
99

1010
#pragma once
1111

12-
#include <pcl/common/utils.h>
1312
#include <pcl/experimental/executor/property.h>
1413
#include <pcl/experimental/executor/type_trait.h>
1514

@@ -26,15 +25,17 @@ template <typename Blocking = blocking_t::always_t,
2625
struct inline_executor {
2726
using shape_type = std::size_t;
2827

29-
template <typename Executor, instance_of_base<Executor, inline_executor> = 0>
28+
template <typename Executor, InstanceOf<Executor, inline_executor> = 0>
3029
friend bool operator==(const inline_executor& lhs,
3130
const Executor& rhs) noexcept {
31+
pcl::utils::ignore(lhs, rhs);
3232
return std::is_same<inline_executor, Executor>::value;
3333
}
3434

35-
template <typename Executor, instance_of_base<Executor, inline_executor> = 0>
35+
template <typename Executor, InstanceOf<Executor, inline_executor> = 0>
3636
friend bool operator!=(const inline_executor& lhs,
3737
const Executor& rhs) noexcept {
38+
pcl::utils::ignore(lhs, rhs);
3839
return !operator==(lhs, rhs);
3940
}
4041

@@ -44,7 +45,7 @@ struct inline_executor {
4445
}
4546

4647
template <typename F, typename... Args>
47-
void bulk_execute(F&& f, const std::size_t n) const {
48+
void bulk_execute(F&& f, const std::size_t& n) const {
4849
pcl::utils::ignore(n);
4950
f(0);
5051
}
@@ -56,7 +57,9 @@ struct inline_executor {
5657
return {};
5758
}
5859

59-
static constexpr auto name() { return "inline"; }
60+
static constexpr auto name() { return "inline_executor"; }
6061
};
6162

63+
using default_inline_executor = inline_executor<>;
64+
6265
} // namespace executor

0 commit comments

Comments
 (0)