Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 843c12d

Browse files
committed
[libc++][pstl] Implement tag dispatching mechanism for Parallel STL
Implement the mechanism that simplifies the execution policy/iterator category dispatching and allows to implement customizations for the parallel algorithms with adding custom tags Reviewed By: rodgert, MikeDvorskiy Differential Revision: https://reviews.llvm.org/D104492
1 parent 912f1c8 commit 843c12d

23 files changed

Lines changed: 2246 additions & 2349 deletions

pstl/include/pstl/internal/algorithm_fwd.h

Lines changed: 318 additions & 389 deletions
Large diffs are not rendered by default.

pstl/include/pstl/internal/algorithm_impl.h

Lines changed: 1219 additions & 1112 deletions
Large diffs are not rendered by default.

pstl/include/pstl/internal/execution_defs.h

Lines changed: 6 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -26,88 +26,20 @@ inline namespace v1
2626
// 2.4, Sequential execution policy
2727
class sequenced_policy
2828
{
29-
public:
30-
// For internal use only
31-
static constexpr std::false_type
32-
__allow_unsequenced()
33-
{
34-
return std::false_type{};
35-
}
36-
static constexpr std::false_type
37-
__allow_vector()
38-
{
39-
return std::false_type{};
40-
}
41-
static constexpr std::false_type
42-
__allow_parallel()
43-
{
44-
return std::false_type{};
45-
}
4629
};
4730

4831
// 2.5, Parallel execution policy
4932
class parallel_policy
5033
{
51-
public:
52-
// For internal use only
53-
static constexpr std::false_type
54-
__allow_unsequenced()
55-
{
56-
return std::false_type{};
57-
}
58-
static constexpr std::false_type
59-
__allow_vector()
60-
{
61-
return std::false_type{};
62-
}
63-
static constexpr std::true_type
64-
__allow_parallel()
65-
{
66-
return std::true_type{};
67-
}
6834
};
6935

7036
// 2.6, Parallel+Vector execution policy
7137
class parallel_unsequenced_policy
7238
{
73-
public:
74-
// For internal use only
75-
static constexpr std::true_type
76-
__allow_unsequenced()
77-
{
78-
return std::true_type{};
79-
}
80-
static constexpr std::true_type
81-
__allow_vector()
82-
{
83-
return std::true_type{};
84-
}
85-
static constexpr std::true_type
86-
__allow_parallel()
87-
{
88-
return std::true_type{};
89-
}
9039
};
9140

9241
class unsequenced_policy
9342
{
94-
public:
95-
// For internal use only
96-
static constexpr std::true_type
97-
__allow_unsequenced()
98-
{
99-
return std::true_type{};
100-
}
101-
static constexpr std::true_type
102-
__allow_vector()
103-
{
104-
return std::true_type{};
105-
}
106-
static constexpr std::false_type
107-
__allow_parallel()
108-
{
109-
return std::false_type{};
110-
}
11143
};
11244

11345
// 2.8, Execution policy objects
@@ -153,6 +85,12 @@ template <class ExecPolicy, class T>
15385
using __enable_if_execution_policy =
15486
typename std::enable_if<__pstl::execution::is_execution_policy<typename std::decay<ExecPolicy>::type>::value,
15587
T>::type;
88+
89+
template <class _IsVector>
90+
struct __serial_tag;
91+
template <class _IsVector>
92+
struct __parallel_tag;
93+
15694
} // namespace __internal
15795

15896
} // namespace __pstl

pstl/include/pstl/internal/execution_impl.h

Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -23,76 +23,76 @@ namespace __pstl
2323
namespace __internal
2424
{
2525

26-
using namespace __pstl::execution;
26+
template <typename _IteratorTag, typename... _IteratorTypes>
27+
using __are_iterators_of = std::conjunction<
28+
std::is_base_of<_IteratorTag, typename std::iterator_traits<std::decay_t<_IteratorTypes>>::iterator_category>...>;
2729

28-
template <typename _IteratorType>
29-
struct __is_random_access_iterator
30-
: std::is_same<typename std::iterator_traits<_IteratorType>::iterator_category,
31-
std::random_access_iterator_tag>
32-
{
33-
};
30+
template <typename... _IteratorTypes>
31+
using __are_random_access_iterators = __are_iterators_of<std::random_access_iterator_tag, _IteratorTypes...>;
3432

35-
template <typename Policy>
36-
struct __policy_traits
33+
struct __serial_backend_tag
3734
{
3835
};
39-
40-
template <>
41-
struct __policy_traits<sequenced_policy>
36+
struct __tbb_backend_tag
4237
{
43-
typedef std::false_type __allow_parallel;
44-
typedef std::false_type __allow_unsequenced;
45-
typedef std::false_type __allow_vector;
4638
};
47-
48-
template <>
49-
struct __policy_traits<unsequenced_policy>
39+
struct __openmp_backend_tag
5040
{
51-
typedef std::false_type __allow_parallel;
52-
typedef std::true_type __allow_unsequenced;
53-
typedef std::true_type __allow_vector;
5441
};
5542

56-
template <>
57-
struct __policy_traits<parallel_policy>
43+
#if defined(_PSTL_PAR_BACKEND_TBB)
44+
using __par_backend_tag = __tbb_backend_tag;
45+
#elif defined(_PSTL_PAR_BACKEND_OPENMP)
46+
using __par_backend_tag = __openmp_backend_tag;
47+
#elif defined(_PSTL_PAR_BACKEND_SERIAL)
48+
using __par_backend_tag = __serial_backend_tag;
49+
#else
50+
# error "A parallel backend must be specified";
51+
#endif
52+
53+
template <class _IsVector>
54+
struct __serial_tag
5855
{
59-
typedef std::true_type __allow_parallel;
60-
typedef std::false_type __allow_unsequenced;
61-
typedef std::false_type __allow_vector;
56+
using __is_vector = _IsVector;
6257
};
6358

64-
template <>
65-
struct __policy_traits<parallel_unsequenced_policy>
59+
template <class _IsVector>
60+
struct __parallel_tag
6661
{
67-
typedef std::true_type __allow_parallel;
68-
typedef std::true_type __allow_unsequenced;
69-
typedef std::true_type __allow_vector;
62+
using __is_vector = _IsVector;
63+
// backend tag can be change depending on
64+
// TBB availability in the environment
65+
using __backend_tag = __par_backend_tag;
7066
};
7167

72-
template <typename _ExecutionPolicy>
73-
using __allow_vector =
74-
typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_vector;
68+
template <class _IsVector, class... _IteratorTypes>
69+
using __tag_type = typename std::conditional<__internal::__are_random_access_iterators<_IteratorTypes...>::value,
70+
__parallel_tag<_IsVector>, __serial_tag<_IsVector>>::type;
7571

76-
template <typename _ExecutionPolicy>
77-
using __allow_unsequenced =
78-
typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_unsequenced;
72+
template <class... _IteratorTypes>
73+
__serial_tag</*_IsVector = */ std::false_type>
74+
__select_backend(__pstl::execution::sequenced_policy, _IteratorTypes&&...)
75+
{
76+
return {};
77+
}
7978

80-
template <typename _ExecutionPolicy>
81-
using __allow_parallel =
82-
typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_parallel;
79+
template <class... _IteratorTypes>
80+
__serial_tag<__internal::__are_random_access_iterators<_IteratorTypes...>>
81+
__select_backend(__pstl::execution::unsequenced_policy, _IteratorTypes&&...)
82+
{
83+
return {};
84+
}
8385

84-
template <typename _ExecutionPolicy, typename... _IteratorTypes>
85-
typename std::conjunction<__allow_vector<_ExecutionPolicy>,
86-
__is_random_access_iterator<_IteratorTypes>...>::type
87-
__is_vectorization_preferred(_ExecutionPolicy&&)
86+
template <class... _IteratorTypes>
87+
__tag_type</*_IsVector = */ std::false_type, _IteratorTypes...>
88+
__select_backend(__pstl::execution::parallel_policy, _IteratorTypes&&...)
8889
{
8990
return {};
9091
}
9192

92-
template <typename _ExecutionPolicy, typename... _IteratorTypes>
93-
typename std::conjunction<__allow_parallel<_ExecutionPolicy>,
94-
__is_random_access_iterator<_IteratorTypes>...>::type
95-
__is_parallelization_preferred(_ExecutionPolicy&&)
93+
template <class... _IteratorTypes>
94+
__tag_type<__internal::__are_random_access_iterators<_IteratorTypes...>, _IteratorTypes...>
95+
__select_backend(__pstl::execution::parallel_unsequenced_policy, _IteratorTypes&&...)
9696
{
9797
return {};
9898
}

0 commit comments

Comments
 (0)