Skip to content

Commit

Permalink
[libc++][PSTL] Parallelize random_access_iterator
Browse files Browse the repository at this point in the history
P2408 requires this for C++23, but implementing it in C++20 is safe
because the only code impacted would be code that violated a
precondition of the parallel algorithm. It was P2408 intent to
enable implementations to backport this to C++20.

Closes #63447 .

Reviewed By: philnik, #libc

Differential Revision: https://reviews.llvm.org/D154305
  • Loading branch information
gonzalobg authored and mordante committed Aug 7, 2023
1 parent f6c7264 commit 0e2de66
Show file tree
Hide file tree
Showing 15 changed files with 49 additions and 39 deletions.
1 change: 0 additions & 1 deletion libcxx/include/__algorithm/pstl_any_all_none_of.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
#include <__iterator/cpp17_iterator_concepts.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include <__atomic/memory_order.h>
#include <__config>
#include <__functional/operations.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/concepts.h>
#include <__type_traits/is_execution_policy.h>
#include <__utility/pair.h>
#include <__utility/terminate_on_exception.h>
Expand Down Expand Up @@ -67,7 +67,7 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
_LIBCPP_HIDE_FROM_ABI bool
__pstl_any_of(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value) {
__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
return std::__terminate_on_exception([&] {
return std::__parallel_or(
__first, __last, [&__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
Expand All @@ -76,7 +76,7 @@ __pstl_any_of(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __la
});
});
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value) {
__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
return std::__simd_or(__first, __last - __first, __pred);
} else {
return std::any_of(__first, __last, __pred);
Expand Down
6 changes: 3 additions & 3 deletions libcxx/include/__algorithm/pstl_backends/cpu_backends/fill.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <__algorithm/fill.h>
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__iterator/concepts.h>
#include <__type_traits/is_execution_policy.h>
#include <__utility/terminate_on_exception.h>

Expand All @@ -37,7 +37,7 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
_LIBCPP_HIDE_FROM_ABI void
__pstl_fill(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value) {
__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
std::__terminate_on_exception([&] {
__par_backend::__parallel_for(
__first, __last, [&__value](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
Expand All @@ -46,7 +46,7 @@ __pstl_fill(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last
});
});
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value) {
__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
std::__simd_fill_n(__first, __last - __first, __value);
} else {
std::fill(__first, __last, __value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <__atomic/atomic.h>
#include <__config>
#include <__functional/operations.h>
#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/is_execution_policy.h>
#include <__utility/pair.h>
Expand Down Expand Up @@ -93,7 +94,7 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
__pstl_find_if(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value) {
__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
return std::__terminate_on_exception([&] {
return std::__parallel_find(
__first,
Expand All @@ -106,7 +107,7 @@ __pstl_find_if(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __l
true);
});
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value) {
__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
using __diff_t = __iter_diff_t<_ForwardIterator>;
return std::__simd_first(__first, __diff_t(0), __last - __first, [&__pred](_ForwardIterator __iter, __diff_t __i) {
return __pred(__iter[__i]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <__algorithm/for_each.h>
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__iterator/concepts.h>
#include <__type_traits/is_execution_policy.h>
#include <__utility/terminate_on_exception.h>

Expand All @@ -37,7 +37,7 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _Functor>
_LIBCPP_HIDE_FROM_ABI void
__pstl_for_each(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Functor __func) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value) {
__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
std::__terminate_on_exception([&] {
std::__par_backend::__parallel_for(
__first, __last, [__func](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
Expand All @@ -46,7 +46,7 @@ __pstl_for_each(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __
});
});
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value) {
__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
std::__simd_walk_1(__first, __last - __first, __func);
} else {
std::for_each(__first, __last, __func);
Expand Down
8 changes: 4 additions & 4 deletions libcxx/include/__algorithm/pstl_backends/cpu_backends/merge.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <__algorithm/merge.h>
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__config>
#include <__iterator/iterator_traits.h>
#include <__iterator/concepts.h>
#include <__type_traits/is_execution_policy.h>
#include <__utility/move.h>
#include <__utility/terminate_on_exception.h>
Expand All @@ -39,9 +39,9 @@ _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_merge(
_ForwardOutIterator __result,
_Comp __comp) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator1>::value &&
__has_random_access_iterator_category<_ForwardIterator2>::value &&
__has_random_access_iterator_category<_ForwardOutIterator>::value) {
__has_random_access_iterator_category_or_concept<_ForwardIterator1>::value &&
__has_random_access_iterator_category_or_concept<_ForwardIterator2>::value &&
__has_random_access_iterator_category_or_concept<_ForwardOutIterator>::value) {
return std::__terminate_on_exception([&] {
__par_backend::__parallel_merge(
__first1,
Expand Down
21 changes: 11 additions & 10 deletions libcxx/include/__algorithm/pstl_backends/cpu_backends/transform.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__algorithm/transform.h>
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
Expand Down Expand Up @@ -43,8 +44,8 @@ _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_transform(
_ForwardOutIterator __result,
_UnaryOperation __op) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value &&
__has_random_access_iterator_category<_ForwardOutIterator>::value) {
__has_random_access_iterator_category_or_concept<_ForwardIterator>::value &&
__has_random_access_iterator_category_or_concept<_ForwardOutIterator>::value) {
std::__terminate_on_exception([&] {
std::__par_backend::__parallel_for(
__first, __last, [__op, __first, __result](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
Expand All @@ -54,8 +55,8 @@ _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_transform(
});
return __result + (__last - __first);
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value &&
__has_random_access_iterator_category<_ForwardOutIterator>::value) {
__has_random_access_iterator_category_or_concept<_ForwardIterator>::value &&
__has_random_access_iterator_category_or_concept<_ForwardOutIterator>::value) {
return std::__simd_walk_2(
__first,
__last - __first,
Expand Down Expand Up @@ -90,9 +91,9 @@ _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_transform(
_ForwardOutIterator __result,
_BinaryOperation __op) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator1>::value &&
__has_random_access_iterator_category<_ForwardIterator2>::value &&
__has_random_access_iterator_category<_ForwardOutIterator>::value) {
__has_random_access_iterator_category_or_concept<_ForwardIterator1>::value &&
__has_random_access_iterator_category_or_concept<_ForwardIterator2>::value &&
__has_random_access_iterator_category_or_concept<_ForwardOutIterator>::value) {
std::__terminate_on_exception([&] {
std::__par_backend::__parallel_for(
__first1,
Expand All @@ -109,9 +110,9 @@ _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_transform(
});
return __result + (__last1 - __first1);
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator1>::value &&
__has_random_access_iterator_category<_ForwardIterator2>::value &&
__has_random_access_iterator_category<_ForwardOutIterator>::value) {
__has_random_access_iterator_category_or_concept<_ForwardIterator1>::value &&
__has_random_access_iterator_category_or_concept<_ForwardIterator2>::value &&
__has_random_access_iterator_category_or_concept<_ForwardOutIterator>::value) {
return std::__simd_walk_3(
__first1,
__last1 - __first1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <__algorithm/pstl_backends/cpu_backends/backend.h>
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h>
#include <__numeric/transform_reduce.h>
#include <__type_traits/is_arithmetic.h>
Expand Down Expand Up @@ -106,8 +107,8 @@ _LIBCPP_HIDE_FROM_ABI _Tp __pstl_transform_reduce(
_BinaryOperation1 __reduce,
_BinaryOperation2 __transform) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator1>::value &&
__has_random_access_iterator_category<_ForwardIterator2>::value) {
__has_random_access_iterator_category_or_concept<_ForwardIterator1>::value &&
__has_random_access_iterator_category_or_concept<_ForwardIterator2>::value) {
return std::__terminate_on_exception([&] {
return __par_backend::__parallel_transform_reduce(
__first1,
Expand All @@ -130,8 +131,8 @@ _LIBCPP_HIDE_FROM_ABI _Tp __pstl_transform_reduce(
});
});
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator1>::value &&
__has_random_access_iterator_category<_ForwardIterator2>::value) {
__has_random_access_iterator_category_or_concept<_ForwardIterator1>::value &&
__has_random_access_iterator_category_or_concept<_ForwardIterator2>::value) {
return std::__simd_transform_reduce(
__last1 - __first1, std::move(__init), std::move(__reduce), [&](__iter_diff_t<_ForwardIterator1> __i) {
return __transform(__first1[__i], __first2[__i]);
Expand All @@ -156,7 +157,7 @@ _LIBCPP_HIDE_FROM_ABI _Tp __pstl_transform_reduce(
_BinaryOperation __reduce,
_UnaryOperation __transform) {
if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value) {
__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
return std::__terminate_on_exception([&] {
return __par_backend::__parallel_transform_reduce(
std::move(__first),
Expand All @@ -175,7 +176,7 @@ _LIBCPP_HIDE_FROM_ABI _Tp __pstl_transform_reduce(
});
});
} else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> &&
__has_random_access_iterator_category<_ForwardIterator>::value) {
__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
return std::__simd_transform_reduce(
__last - __first,
std::move(__init),
Expand Down
4 changes: 2 additions & 2 deletions libcxx/include/__algorithm/pstl_copy.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include <__algorithm/pstl_transform.h>
#include <__config>
#include <__functional/identity.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/concepts.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_constant_evaluated.h>
#include <__type_traits/is_execution_policy.h>
Expand Down Expand Up @@ -67,7 +67,7 @@ copy_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _Forwar
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_copy_n),
[&__policy](_ForwardIterator __g_first, _Size __g_n, _ForwardOutIterator __g_result) {
if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value)
if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value)
return std::copy(__policy, __g_first, __g_first + __g_n, __g_result);
else
return std::copy_n(__g_first, __g_n, __g_result);
Expand Down
3 changes: 2 additions & 1 deletion libcxx/include/__algorithm/pstl_fill.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <__algorithm/pstl_for_each.h>
#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/cpp17_iterator_concepts.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
Expand Down Expand Up @@ -67,7 +68,7 @@ fill_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _SizeT __n, const
std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill_n),
[&](_ForwardIterator __g_first, _SizeT __g_n, const _Tp& __g_value) {
if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value)
if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value)
std::fill(__policy, __g_first, __g_first + __g_n, __g_value);
else
std::fill_n(__g_first, __g_n, __g_value);
Expand Down
1 change: 0 additions & 1 deletion libcxx/include/__algorithm/pstl_find.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
#include <__iterator/cpp17_iterator_concepts.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
Expand Down
4 changes: 2 additions & 2 deletions libcxx/include/__algorithm/pstl_for_each.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
#include <__algorithm/pstl_backend.h>
#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/cpp17_iterator_concepts.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
Expand Down Expand Up @@ -58,7 +58,7 @@ for_each_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __size,
return std::__pstl_frontend_dispatch(
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_for_each_n),
[&](_ForwardIterator __g_first, _Size __g_size, _Function __g_func) {
if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) {
if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
std::for_each(__policy, std::move(__g_first), __g_first + __g_size, std::move(__g_func));
} else {
std::for_each_n(std::move(__g_first), __g_size, std::move(__g_func));
Expand Down
1 change: 1 addition & 0 deletions libcxx/include/__algorithm/pstl_generate.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <__algorithm/pstl_frontend_dispatch.h>
#include <__config>
#include <__iterator/cpp17_iterator_concepts.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
Expand Down
1 change: 0 additions & 1 deletion libcxx/include/__algorithm/pstl_transform.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include <__algorithm/pstl_backend.h>
#include <__config>
#include <__iterator/cpp17_iterator_concepts.h>
#include <__iterator/iterator_traits.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_execution_policy.h>
#include <__type_traits/remove_cvref.h>
Expand Down
8 changes: 8 additions & 0 deletions libcxx/include/__iterator/concepts.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,14 @@ concept indirectly_copyable_storable =

#endif // _LIBCPP_STD_VER >= 20

template <class _Tp>
using __has_random_access_iterator_category_or_concept
#if _LIBCPP_STD_VER >= 20
= integral_constant<bool, random_access_iterator<_Tp>>;
#else // _LIBCPP_STD_VER < 20
= __has_random_access_iterator_category<_Tp>;
#endif // _LIBCPP_STD_VER

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP___ITERATOR_CONCEPTS_H

0 comments on commit 0e2de66

Please sign in to comment.