diff --git a/include/oneapi/dpl/internal/async_impl/async_impl_hetero.h b/include/oneapi/dpl/internal/async_impl/async_impl_hetero.h index cd080b1e6a1..f053974f7b2 100644 --- a/include/oneapi/dpl/internal/async_impl/async_impl_hetero.h +++ b/include/oneapi/dpl/internal/async_impl/async_impl_hetero.h @@ -30,10 +30,10 @@ namespace dpl namespace __internal { -template = 0> +template auto -__pattern_walk1_async(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Function __f) +__pattern_walk1_async(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _ForwardIterator __first, + _ForwardIterator __last, _Function __f) { auto __n = __last - __first; assert(__n > 0); @@ -43,19 +43,19 @@ __pattern_walk1_async(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Forw auto __buf = __keep(__first, __last); auto __future_obj = oneapi::dpl::__par_backend_hetero::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), unseq_backend::walk_n<_ExecutionPolicy, _Function>{__f}, __n, - __buf.all_view()); + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), + unseq_backend::walk_n<_ExecutionPolicy, _Function>{__f}, __n, __buf.all_view()); return __future_obj; } template = 0> + typename _BackendTag, typename _ExecutionPolicy, typename _ForwardIterator1, typename _ForwardIterator2, + typename _Function> auto -__pattern_walk2_async(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Function __f) +__pattern_walk2_async(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _ForwardIterator1 __last1, _ForwardIterator2 __first2, _Function __f) { auto __n = __last1 - __first1; assert(__n > 0); @@ -67,8 +67,8 @@ __pattern_walk2_async(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Fo auto __buf2 = __keep2(__first2, __first2 + __n); auto __future = oneapi::dpl::__par_backend_hetero::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), unseq_backend::walk_n<_ExecutionPolicy, _Function>{__f}, __n, - __buf1.all_view(), __buf2.all_view()); + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), + unseq_backend::walk_n<_ExecutionPolicy, _Function>{__f}, __n, __buf1.all_view(), __buf2.all_view()); if constexpr (_IsSync::value) __future.wait(); @@ -76,11 +76,11 @@ __pattern_walk2_async(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Fo return __future.__make_future(__first2 + __n); } -template = 0> +template auto -__pattern_walk3_async(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator3 __first3, _Function __f) +__pattern_walk3_async(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator3 __first3, _Function __f) { auto __n = __last1 - __first1; assert(__n > 0); @@ -95,20 +95,22 @@ __pattern_walk3_async(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Fo oneapi::dpl::__ranges::__get_sycl_range<__par_backend_hetero::access_mode::write, _ForwardIterator3>(); auto __buf3 = __keep3(__first3, __first3 + __n); - auto __future = oneapi::dpl::__par_backend_hetero::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), unseq_backend::walk_n<_ExecutionPolicy, _Function>{__f}, __n, - __buf1.all_view(), __buf2.all_view(), __buf3.all_view()); + auto __future = + oneapi::dpl::__par_backend_hetero::__parallel_for(_BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), + unseq_backend::walk_n<_ExecutionPolicy, _Function>{__f}, __n, + __buf1.all_view(), __buf2.all_view(), __buf3.all_view()); return __future.__make_future(__first3 + __n); } -template = 0> +template auto -__pattern_walk2_brick_async(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Brick __brick) +__pattern_walk2_brick_async(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _ForwardIterator1 __last1, _ForwardIterator2 __first2, _Brick __brick) { return __pattern_walk2_async( + __tag, __par_backend_hetero::make_wrapped_policy<__walk2_brick_wrapper>(::std::forward<_ExecutionPolicy>(__exec)), __first1, __last1, __first2, __brick); } @@ -117,11 +119,10 @@ __pattern_walk2_brick_async(_ExecutionPolicy&& __exec, _ForwardIterator1 __first // transform_reduce (version with two binary functions) //------------------------------------------------------------------------ -template = 0> +template auto -__pattern_transform_reduce_async(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, +__pattern_transform_reduce_async(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) { @@ -141,7 +142,7 @@ __pattern_transform_reduce_async(_ExecutionPolicy&& __exec, _RandomAccessIterato return oneapi::dpl::__par_backend_hetero::__parallel_transform_reduce<_RepackedTp, ::std::true_type /*is_commutative*/>( - ::std::forward<_ExecutionPolicy>(__exec), __binary_op1, _Functor{__binary_op2}, + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __binary_op1, _Functor{__binary_op2}, unseq_backend::__init_value<_RepackedTp>{__init}, // initial value __buf1.all_view(), __buf2.all_view()); } @@ -150,12 +151,12 @@ __pattern_transform_reduce_async(_ExecutionPolicy&& __exec, _RandomAccessIterato // transform_reduce (with unary and binary functions) //------------------------------------------------------------------------ -template = 0> +template auto -__pattern_transform_reduce_async(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, - _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __unary_op) +__pattern_transform_reduce_async(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _ForwardIterator __first, + _ForwardIterator __last, _Tp __init, _BinaryOperation __binary_op, + _UnaryOperation __unary_op) { assert(__first < __last); @@ -168,18 +169,18 @@ __pattern_transform_reduce_async(_ExecutionPolicy&& __exec, _ForwardIterator __f return oneapi::dpl::__par_backend_hetero::__parallel_transform_reduce<_RepackedTp, ::std::true_type /*is_commutative*/>( - ::std::forward<_ExecutionPolicy>(__exec), __binary_op, _Functor{__unary_op}, + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __binary_op, _Functor{__unary_op}, unseq_backend::__init_value<_RepackedTp>{__init}, // initial value __buf.all_view()); } -template = 0> +template auto -__pattern_fill_async(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _T& __value) +__pattern_fill_async(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _ForwardIterator __first, + _ForwardIterator __last, const _T& __value) { return __pattern_walk1_async( - ::std::forward<_ExecutionPolicy>(__exec), + __tag, ::std::forward<_ExecutionPolicy>(__exec), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::write>(__first), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::write>(__last), fill_functor<_T>{__value}); @@ -189,13 +190,12 @@ __pattern_fill_async(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Forwa // transform_scan //------------------------------------------------------------------------ -template = 0> +template auto -__pattern_transform_scan_base_async(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, - _Iterator2 __result, _UnaryOperation __unary_op, _InitType __init, - _BinaryOperation __binary_op, _Inclusive) +__pattern_transform_scan_base_async(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Iterator1 __first, + _Iterator1 __last, _Iterator2 __result, _UnaryOperation __unary_op, + _InitType __init, _BinaryOperation __binary_op, _Inclusive) { assert(__first < __last); @@ -206,39 +206,39 @@ __pattern_transform_scan_base_async(_ExecutionPolicy&& __exec, _Iterator1 __firs auto __buf2 = __keep2(__result, __result + __n); auto __res = oneapi::dpl::__par_backend_hetero::__parallel_transform_scan( - ::std::forward<_ExecutionPolicy>(__exec), __buf1.all_view(), __buf2.all_view(), __n, __unary_op, __init, - __binary_op, _Inclusive{}); + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __buf1.all_view(), __buf2.all_view(), __n, __unary_op, + __init, __binary_op, _Inclusive{}); return __res.__make_future(__result + __n); } -template = 0> +template auto -__pattern_transform_scan_async(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, _Iterator2 __result, - _UnaryOperation __unary_op, _Type __init, _BinaryOperation __binary_op, _Inclusive) +__pattern_transform_scan_async(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator1 __first, + _Iterator1 __last, _Iterator2 __result, _UnaryOperation __unary_op, _Type __init, + _BinaryOperation __binary_op, _Inclusive) { using _RepackedType = __par_backend_hetero::__repacked_tuple_t<_Type>; using _InitType = unseq_backend::__init_value<_RepackedType>; - return __pattern_transform_scan_base_async(::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, - __unary_op, _InitType{__init}, __binary_op, _Inclusive{}); + return __pattern_transform_scan_base_async(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + __result, __unary_op, _InitType{__init}, __binary_op, _Inclusive{}); } // scan without initial element -template = 0> +template auto -__pattern_transform_scan_async(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, _Iterator2 __result, - _UnaryOperation __unary_op, _BinaryOperation __binary_op, _Inclusive) +__pattern_transform_scan_async(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator1 __first, + _Iterator1 __last, _Iterator2 __result, _UnaryOperation __unary_op, + _BinaryOperation __binary_op, _Inclusive) { using _ValueType = typename ::std::iterator_traits<_Iterator1>::value_type; using _RepackedType = __par_backend_hetero::__repacked_tuple_t<_ValueType>; using _InitType = unseq_backend::__no_init_value<_RepackedType>; - return __pattern_transform_scan_base_async(::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, - __unary_op, _InitType{}, __binary_op, _Inclusive{}); + return __pattern_transform_scan_base_async(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + __result, __unary_op, _InitType{}, __binary_op, _Inclusive{}); } } // namespace __internal diff --git a/include/oneapi/dpl/internal/async_impl/glue_async_impl.h b/include/oneapi/dpl/internal/async_impl/glue_async_impl.h index 26eca467131..dfd4a969ec8 100644 --- a/include/oneapi/dpl/internal/async_impl/glue_async_impl.h +++ b/include/oneapi/dpl/internal/async_impl/glue_async_impl.h @@ -43,9 +43,11 @@ auto transform_async(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, _UnaryOperation __op, _Events&&... __dependencies) { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __result); + wait_for_all(::std::forward<_Events>(__dependencies)...); auto ret_val = oneapi::dpl::__internal::__pattern_walk2_async( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, oneapi::dpl::__internal::__transform_functor<_UnaryOperation>{::std::move(__op)}); return ret_val; } @@ -59,9 +61,11 @@ transform_async(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardI _ForwardIterator2 __first2, _ForwardIterator __result, _BinaryOperation __op, _Events&&... __dependencies) { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first1, __first2, __result); + wait_for_all(::std::forward<_Events>(__dependencies)...); auto ret_val = oneapi::dpl::__internal::__pattern_walk3_async( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __result, + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __result, oneapi::dpl::__internal::__transform_functor<_BinaryOperation>(::std::move(__op))); return ret_val; } @@ -73,10 +77,12 @@ auto copy_async(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, _Events&&... __dependencies) { + auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __result); + wait_for_all(::std::forward<_Events>(__dependencies)...); auto ret_val = oneapi::dpl::__internal::__pattern_walk2_brick_async( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, - oneapi::dpl::__internal::__brick_copy<_ExecutionPolicy>{}); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, + oneapi::dpl::__internal::__brick_copy{}); return ret_val; } @@ -93,8 +99,11 @@ sort_async(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _Comp auto __keep = oneapi::dpl::__ranges::__get_sycl_range<__par_backend_hetero::access_mode::read_write, _Iterator>(); auto __buf = __keep(__first, __last); - return __par_backend_hetero::__parallel_stable_sort(::std::forward<_ExecutionPolicy>(__exec), __buf.all_view(), - __comp, oneapi::dpl::identity{}); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + using __backend_tag = typename decltype(__dispatch_tag)::__backend_tag; + + return __par_backend_hetero::__parallel_stable_sort(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), + __buf.all_view(), __comp, oneapi::dpl::identity{}); } template (__dependencies)...); - auto ret_val = - oneapi::dpl::__internal::__pattern_walk1_async(::std::forward<_ExecutionPolicy>(__exec), __first, __last, __f); + auto ret_val = oneapi::dpl::__internal::__pattern_walk1_async( + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __f); return ret_val; } @@ -130,10 +141,12 @@ auto reduce_async(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, _BinaryOperation __binary_op, _Events&&... __dependencies) { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + wait_for_all(::std::forward<_Events>(__dependencies)...); - auto ret_val = oneapi::dpl::__internal::__pattern_transform_reduce_async(::std::forward<_ExecutionPolicy>(__exec), - __first, __last, __init, __binary_op, - oneapi::dpl::__internal::__no_op()); + auto ret_val = oneapi::dpl::__internal::__pattern_transform_reduce_async( + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, __binary_op, + oneapi::dpl::__internal::__no_op()); return ret_val; } @@ -165,9 +178,11 @@ auto fill_async(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Events&&... __dependencies) { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + wait_for_all(::std::forward<_Events>(__dependencies)...); - return oneapi::dpl::__internal::__pattern_fill_async(::std::forward<_ExecutionPolicy>(__exec), __first, __last, - __value); + return oneapi::dpl::__internal::__pattern_fill_async(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __value); } // [async.transform_reduce] @@ -180,9 +195,12 @@ auto transform_reduce_async(_ExecutionPolicy&& __exec, _ForwardIt1 __first1, _ForwardIt1 __last1, _ForwardIt2 __first2, _T __init, _BinaryOp1 __binary_op1, _BinaryOp2 __binary_op2, _Events&&... __dependencies) { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first1, __first2); + wait_for_all(::std::forward<_Events>(__dependencies)...); return oneapi::dpl::__internal::__pattern_transform_reduce_async( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __init, __binary_op1, __binary_op2); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __init, __binary_op1, + __binary_op2); } template (__dependencies)...); - return oneapi::dpl::__internal::__pattern_transform_reduce_async(::std::forward<_ExecutionPolicy>(__exec), __first, - __last, __init, __binary_op, __unary_op); + return oneapi::dpl::__internal::__pattern_transform_reduce_async( + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, __binary_op, __unary_op); } template ::value_type; wait_for_all(::std::forward<_Events>(__dependencies)...); return oneapi::dpl::__internal::__pattern_transform_scan_async( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, oneapi::dpl::__internal::__no_op(), - ::std::plus<_ValueType>(), /*inclusive=*/::std::true_type()); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, + oneapi::dpl::__internal::__no_op(), ::std::plus<_ValueType>(), /*inclusive=*/::std::true_type()); } template (__dependencies)...); return oneapi::dpl::__internal::__pattern_transform_scan_async( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, oneapi::dpl::__internal::__no_op(), - __binary_op, /*inclusive=*/::std::true_type()); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, + oneapi::dpl::__internal::__no_op(), __binary_op, /*inclusive=*/::std::true_type()); } template (__dependencies)...); return oneapi::dpl::__internal::__pattern_transform_scan_async( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, oneapi::dpl::__internal::__no_op(), - __init, __binary_op, /*inclusive=*/::std::true_type()); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, + oneapi::dpl::__internal::__no_op(), __init, __binary_op, /*inclusive=*/::std::true_type()); } template (__dependencies)...); return oneapi::dpl::__internal::__pattern_transform_scan_async( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, oneapi::dpl::__internal::__no_op(), - __init, ::std::plus<_T>(), /*exclusive=*/::std::false_type()); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, + oneapi::dpl::__internal::__no_op(), __init, ::std::plus<_T>(), /*exclusive=*/::std::false_type()); } template (__dependencies)...); return oneapi::dpl::__internal::__pattern_transform_scan_async( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, oneapi::dpl::__internal::__no_op(), - __init, __binary_op, /*exclusive=*/::std::false_type()); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, + oneapi::dpl::__internal::__no_op(), __init, __binary_op, /*exclusive=*/::std::false_type()); } template (__dependencies)...); - return oneapi::dpl::__internal::__pattern_transform_scan_async(::std::forward<_ExecutionPolicy>(__exec), __first1, + return oneapi::dpl::__internal::__pattern_transform_scan_async(__dispatch_tag, + ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __unary_op, __init, __binary_op, /*exclusive=*/::std::false_type()); } @@ -299,10 +332,12 @@ transform_inclusive_scan_async(_ExecutionPolicy&& __exec, _ForwardIt1 __first1, _ForwardIt2 __first2, _BinaryOperation __binary_op, _UnaryOperation __unary_op, _Events&&... __dependencies) { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first1, __first2); + wait_for_all(::std::forward<_Events>(__dependencies)...); - return oneapi::dpl::__internal::__pattern_transform_scan_async(::std::forward<_ExecutionPolicy>(__exec), __first1, - __last1, __first2, __unary_op, __binary_op, - /*inclusive=*/::std::true_type()); + return oneapi::dpl::__internal::__pattern_transform_scan_async( + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __unary_op, __binary_op, + /*inclusive=*/::std::true_type()); } template (__dependencies)...); - return oneapi::dpl::__internal::__pattern_transform_scan_async(::std::forward<_ExecutionPolicy>(__exec), __first1, + return oneapi::dpl::__internal::__pattern_transform_scan_async(__dispatch_tag, + ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __unary_op, __init, __binary_op, /*inclusive=*/::std::true_type()); } diff --git a/include/oneapi/dpl/internal/binary_search_impl.h b/include/oneapi/dpl/internal/binary_search_impl.h index 0c689fe6b8e..59c2f74ea82 100644 --- a/include/oneapi/dpl/internal/binary_search_impl.h +++ b/include/oneapi/dpl/internal/binary_search_impl.h @@ -68,36 +68,42 @@ struct custom_brick } }; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy -lower_bound_impl(Policy&& policy, InputIterator1 start, InputIterator1 end, InputIterator2 value_start, +OutputIterator +lower_bound_impl(_Tag, Policy&& policy, InputIterator1 start, InputIterator1 end, InputIterator2 value_start, InputIterator2 value_end, OutputIterator result, StrictWeakOrdering comp) { + static_assert(__internal::__is_host_dispatch_tag_v<_Tag>); + return oneapi::dpl::transform(policy, value_start, value_end, result, [=](typename ::std::iterator_traits::reference val) { return ::std::lower_bound(start, end, val, comp) - start; }); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy -upper_bound_impl(Policy&& policy, InputIterator1 start, InputIterator1 end, InputIterator2 value_start, +OutputIterator +upper_bound_impl(_Tag, Policy&& policy, InputIterator1 start, InputIterator1 end, InputIterator2 value_start, InputIterator2 value_end, OutputIterator result, StrictWeakOrdering comp) { + static_assert(__internal::__is_host_dispatch_tag_v<_Tag>); + return oneapi::dpl::transform(policy, value_start, value_end, result, [=](typename ::std::iterator_traits::reference val) { return ::std::upper_bound(start, end, val, comp) - start; }); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy -binary_search_impl(Policy&& policy, InputIterator1 start, InputIterator1 end, InputIterator2 value_start, +OutputIterator +binary_search_impl(_Tag, Policy&& policy, InputIterator1 start, InputIterator1 end, InputIterator2 value_start, InputIterator2 value_end, OutputIterator result, StrictWeakOrdering comp) { + static_assert(__internal::__is_host_dispatch_tag_v<_Tag>); + return oneapi::dpl::transform(policy, value_start, value_end, result, [=](typename ::std::iterator_traits::reference val) { return ::std::binary_search(start, end, val, comp); @@ -105,11 +111,11 @@ binary_search_impl(Policy&& policy, InputIterator1 start, InputIterator1 end, In } #if _ONEDPL_BACKEND_SYCL -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy -lower_bound_impl(Policy&& policy, InputIterator1 start, InputIterator1 end, InputIterator2 value_start, - InputIterator2 value_end, OutputIterator result, StrictWeakOrdering comp) +template +OutputIterator +lower_bound_impl(__internal::__hetero_tag<_BackendTag>, Policy&& policy, InputIterator1 start, InputIterator1 end, + InputIterator2 value_start, InputIterator2 value_end, OutputIterator result, StrictWeakOrdering comp) { namespace __bknd = __par_backend_hetero; const auto size = ::std::distance(start, end); @@ -128,18 +134,18 @@ lower_bound_impl(Policy&& policy, InputIterator1 start, InputIterator1 end, Inpu auto keep_result = oneapi::dpl::__ranges::__get_sycl_range<__bknd::access_mode::read_write, OutputIterator>(); auto result_buf = keep_result(result, result + value_size); auto zip_vw = make_zip_view(input_buf.all_view(), value_buf.all_view(), result_buf.all_view()); - __bknd::__parallel_for(::std::forward(policy), + __bknd::__parallel_for(_BackendTag{}, ::std::forward(policy), custom_brick{comp, size}, value_size, zip_vw) .wait(); return result + value_size; } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy -upper_bound_impl(Policy&& policy, InputIterator1 start, InputIterator1 end, InputIterator2 value_start, - InputIterator2 value_end, OutputIterator result, StrictWeakOrdering comp) +template +OutputIterator +upper_bound_impl(__internal::__hetero_tag<_BackendTag>, Policy&& policy, InputIterator1 start, InputIterator1 end, + InputIterator2 value_start, InputIterator2 value_end, OutputIterator result, StrictWeakOrdering comp) { namespace __bknd = __par_backend_hetero; const auto size = ::std::distance(start, end); @@ -158,18 +164,18 @@ upper_bound_impl(Policy&& policy, InputIterator1 start, InputIterator1 end, Inpu auto keep_result = oneapi::dpl::__ranges::__get_sycl_range<__bknd::access_mode::read_write, OutputIterator>(); auto result_buf = keep_result(result, result + value_size); auto zip_vw = make_zip_view(input_buf.all_view(), value_buf.all_view(), result_buf.all_view()); - __bknd::__parallel_for(::std::forward(policy), + __bknd::__parallel_for(_BackendTag{}, ::std::forward(policy), custom_brick{comp, size}, value_size, zip_vw) .wait(); return result + value_size; } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy -binary_search_impl(Policy&& policy, InputIterator1 start, InputIterator1 end, InputIterator2 value_start, - InputIterator2 value_end, OutputIterator result, StrictWeakOrdering comp) +template +OutputIterator +binary_search_impl(__internal::__hetero_tag<_BackendTag>, Policy&& policy, InputIterator1 start, InputIterator1 end, + InputIterator2 value_start, InputIterator2 value_end, OutputIterator result, StrictWeakOrdering comp) { namespace __bknd = __par_backend_hetero; const auto size = ::std::distance(start, end); @@ -188,7 +194,7 @@ binary_search_impl(Policy&& policy, InputIterator1 start, InputIterator1 end, In auto keep_result = oneapi::dpl::__ranges::__get_sycl_range<__bknd::access_mode::read_write, OutputIterator>(); auto result_buf = keep_result(result, result + value_size); auto zip_vw = make_zip_view(input_buf.all_view(), value_buf.all_view(), result_buf.all_view()); - __bknd::__parallel_for(::std::forward(policy), + __bknd::__parallel_for(_BackendTag{}, ::std::forward(policy), custom_brick{comp, size}, value_size, zip_vw) .wait(); @@ -204,8 +210,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy lower_bound(Policy&& policy, InputIterator1 start, InputIterator1 end, InputIterator2 value_start, InputIterator2 value_end, OutputIterator result) { - return internal::lower_bound_impl(::std::forward(policy), start, end, value_start, value_end, result, - oneapi::dpl::__internal::__pstl_less()); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(policy, start, value_start, result); + + return internal::lower_bound_impl(__dispatch_tag, ::std::forward(policy), start, end, value_start, + value_end, result, oneapi::dpl::__internal::__pstl_less()); } template lower_bound(Policy&& policy, InputIterator1 start, InputIterator1 end, InputIterator2 value_start, InputIterator2 value_end, OutputIterator result, StrictWeakOrdering comp) { - return internal::lower_bound_impl(::std::forward(policy), start, end, value_start, value_end, result, comp); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(policy, start, value_start, result); + + return internal::lower_bound_impl(__dispatch_tag, ::std::forward(policy), start, end, value_start, + value_end, result, comp); } //Lower Bound end @@ -225,8 +236,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy upper_bound(Policy&& policy, InputIterator1 start, InputIterator1 end, InputIterator2 value_start, InputIterator2 value_end, OutputIterator result) { - return internal::upper_bound_impl(::std::forward(policy), start, end, value_start, value_end, result, - oneapi::dpl::__internal::__pstl_less()); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(policy, start, value_start, result); + + return internal::upper_bound_impl(__dispatch_tag, ::std::forward(policy), start, end, value_start, + value_end, result, oneapi::dpl::__internal::__pstl_less()); } template upper_bound(Policy&& policy, InputIterator1 start, InputIterator1 end, InputIterator2 value_start, InputIterator2 value_end, OutputIterator result, StrictWeakOrdering comp) { - return internal::upper_bound_impl(::std::forward(policy), start, end, value_start, value_end, result, comp); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(policy, start, value_start, result); + + return internal::upper_bound_impl(__dispatch_tag, ::std::forward(policy), start, end, value_start, + value_end, result, comp); } //Upper Bound end @@ -247,8 +263,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy binary_search(Policy&& policy, InputIterator1 start, InputIterator1 end, InputIterator2 value_start, InputIterator2 value_end, OutputIterator result) { - return internal::binary_search_impl(::std::forward(policy), start, end, value_start, value_end, result, - oneapi::dpl::__internal::__pstl_less()); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(policy, start, value_start, result); + + return internal::binary_search_impl(__dispatch_tag, ::std::forward(policy), start, end, value_start, + value_end, result, oneapi::dpl::__internal::__pstl_less()); } template binary_search(Policy&& policy, InputIterator1 start, InputIterator1 end, InputIterator2 value_start, InputIterator2 value_end, OutputIterator result, StrictWeakOrdering comp) { - return internal::binary_search_impl(::std::forward(policy), start, end, value_start, value_end, result, - comp); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(policy, start, value_start, result); + + return internal::binary_search_impl(__dispatch_tag, ::std::forward(policy), start, end, value_start, + value_end, result, comp); } //Binary search end diff --git a/include/oneapi/dpl/internal/exclusive_scan_by_segment_impl.h b/include/oneapi/dpl/internal/exclusive_scan_by_segment_impl.h index 79d8239ea12..cd33872aa0d 100644 --- a/include/oneapi/dpl/internal/exclusive_scan_by_segment_impl.h +++ b/include/oneapi/dpl/internal/exclusive_scan_by_segment_impl.h @@ -37,12 +37,15 @@ class ExclusiveScan1; template class ExclusiveScan2; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy -pattern_exclusive_scan_by_segment(Policy&& policy, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, - OutputIterator result, T init, BinaryPredicate binary_pred, Operator binary_op) +template +OutputIterator +pattern_exclusive_scan_by_segment(_Tag, Policy&& policy, InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, OutputIterator result, T init, BinaryPredicate binary_pred, + Operator binary_op) { + static_assert(__internal::__is_host_dispatch_tag_v<_Tag>); + const auto n = ::std::distance(first1, last1); // Check for empty and single element ranges @@ -61,7 +64,7 @@ pattern_exclusive_scan_by_segment(Policy&& policy, InputIterator1 first1, InputI InputIterator2 last2 = first2 + n; // compute head flags - oneapi::dpl::__par_backend::__buffer _flags(n); + oneapi::dpl::__par_backend::__buffer _flags(policy, n); auto flags = _flags.get(); flags[0] = 1; @@ -69,7 +72,7 @@ pattern_exclusive_scan_by_segment(Policy&& policy, InputIterator1 first1, InputI oneapi::dpl::__internal::__not_pred(binary_pred)); // shift input one to the right and initialize segments with init - oneapi::dpl::__par_backend::__buffer _temp(n); + oneapi::dpl::__par_backend::__buffer _temp(policy, n); auto temp = _temp.get(); temp[0] = init; @@ -91,22 +94,24 @@ pattern_exclusive_scan_by_segment(Policy&& policy, InputIterator1 first1, InputI } #if _ONEDPL_BACKEND_SYCL -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy -exclusive_scan_by_segment_impl(Policy&& policy, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, - OutputIterator result, T init, BinaryPredicate binary_pred, Operator binary_op, +template +OutputIterator +exclusive_scan_by_segment_impl(__internal::__hetero_tag<_BackendTag> __tag, Policy&& policy, InputIterator1 first1, + InputIterator1 last1, InputIterator2 first2, OutputIterator result, T init, + BinaryPredicate binary_pred, Operator binary_op, ::std::true_type /* has_known_identity*/) { - return internal::__scan_by_segment_impl_common(::std::forward(policy), first1, last1, first2, result, init, - binary_pred, binary_op, ::std::false_type{}); + return internal::__scan_by_segment_impl_common(__tag, ::std::forward(policy), first1, last1, first2, result, + init, binary_pred, binary_op, ::std::false_type{}); } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy -exclusive_scan_by_segment_impl(Policy&& policy, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, - OutputIterator result, T init, BinaryPredicate binary_pred, Operator binary_op, +template +OutputIterator +exclusive_scan_by_segment_impl(__internal::__hetero_tag<_BackendTag>, Policy&& policy, InputIterator1 first1, + InputIterator1 last1, InputIterator2 first2, OutputIterator result, T init, + BinaryPredicate binary_pred, Operator binary_op, ::std::false_type /* has_known_identity*/) { @@ -160,14 +165,15 @@ exclusive_scan_by_segment_impl(Policy&& policy, InputIterator1 first1, InputIter return result + n; } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy -pattern_exclusive_scan_by_segment(Policy&& policy, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, - OutputIterator result, T init, BinaryPredicate binary_pred, Operator binary_op) +template +OutputIterator +pattern_exclusive_scan_by_segment(__internal::__hetero_tag<_BackendTag> __tag, Policy&& policy, InputIterator1 first1, + InputIterator1 last1, InputIterator2 first2, OutputIterator result, T init, + BinaryPredicate binary_pred, Operator binary_op) { return internal::exclusive_scan_by_segment_impl( - ::std::forward(policy), first1, last1, first2, result, init, binary_pred, binary_op, + __tag, ::std::forward(policy), first1, last1, first2, result, init, binary_pred, binary_op, typename unseq_backend::__has_known_identity< Operator, typename ::std::iterator_traits::value_type>::type{}); } @@ -181,8 +187,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy exclusive_scan_by_segment(Policy&& policy, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, T init, BinaryPredicate binary_pred, Operator binary_op) { - return internal::pattern_exclusive_scan_by_segment(::std::forward(policy), first1, last1, first2, result, - init, binary_pred, binary_op); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(policy, first1, first2, result); + + return internal::pattern_exclusive_scan_by_segment(__dispatch_tag, ::std::forward(policy), first1, last1, + first2, result, init, binary_pred, binary_op); } template class InclusiveScan1; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy -pattern_inclusive_scan_by_segment(Policy&& policy, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, - OutputIterator result, BinaryPredicate binary_pred, BinaryOperator binary_op) +OutputIterator +pattern_inclusive_scan_by_segment(_Tag, Policy&& policy, InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, OutputIterator result, BinaryPredicate binary_pred, + BinaryOperator binary_op) { + static_assert(__internal::__is_host_dispatch_tag_v<_Tag>); + const auto n = ::std::distance(first1, last1); // Check for empty and single element ranges @@ -56,7 +59,7 @@ pattern_inclusive_scan_by_segment(Policy&& policy, InputIterator1 first1, InputI typedef unsigned int FlagType; typedef typename ::std::iterator_traits::value_type ValueType; - oneapi::dpl::__par_backend::__buffer _mask(n); + oneapi::dpl::__par_backend::__buffer _mask(policy, n); auto mask = _mask.get(); mask[0] = 1; @@ -72,24 +75,26 @@ pattern_inclusive_scan_by_segment(Policy&& policy, InputIterator1 first1, InputI } #if _ONEDPL_BACKEND_SYCL -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy -inclusive_scan_by_segment_impl(Policy&& policy, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, - OutputIterator result, BinaryPredicate binary_pred, BinaryOperator binary_op, +template +OutputIterator +inclusive_scan_by_segment_impl(__internal::__hetero_tag<_BackendTag> __tag, Policy&& policy, InputIterator1 first1, + InputIterator1 last1, InputIterator2 first2, OutputIterator result, + BinaryPredicate binary_pred, BinaryOperator binary_op, ::std::true_type /* has_known_identity */) { using iter_value_t = typename ::std::iterator_traits::value_type; iter_value_t identity = unseq_backend::__known_identity; - return internal::__scan_by_segment_impl_common(::std::forward(policy), first1, last1, first2, result, + return internal::__scan_by_segment_impl_common(__tag, ::std::forward(policy), first1, last1, first2, result, identity, binary_pred, binary_op, ::std::true_type{}); } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy -inclusive_scan_by_segment_impl(Policy&& policy, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, - OutputIterator result, BinaryPredicate binary_pred, BinaryOperator binary_op, +template +OutputIterator +inclusive_scan_by_segment_impl(__internal::__hetero_tag<_BackendTag>, Policy&& policy, InputIterator1 first1, + InputIterator1 last1, InputIterator2 first2, OutputIterator result, + BinaryPredicate binary_pred, BinaryOperator binary_op, ::std::false_type /* has_known_identity */) { @@ -123,14 +128,15 @@ inclusive_scan_by_segment_impl(Policy&& policy, InputIterator1 first1, InputIter return result + n; } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy -pattern_inclusive_scan_by_segment(Policy&& policy, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, - OutputIterator result, BinaryPredicate binary_pred, BinaryOperator binary_op) +template +OutputIterator +pattern_inclusive_scan_by_segment(__internal::__hetero_tag<_BackendTag> __tag, Policy&& policy, InputIterator1 first1, + InputIterator1 last1, InputIterator2 first2, OutputIterator result, + BinaryPredicate binary_pred, BinaryOperator binary_op) { return internal::inclusive_scan_by_segment_impl( - ::std::forward(policy), first1, last1, first2, result, binary_pred, binary_op, + __tag, ::std::forward(policy), first1, last1, first2, result, binary_pred, binary_op, typename unseq_backend::__has_known_identity< BinaryOperator, typename ::std::iterator_traits::value_type>::type{}); } @@ -144,8 +150,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy inclusive_scan_by_segment(Policy&& policy, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryPredicate binary_pred, BinaryOperator binary_op) { - return internal::pattern_inclusive_scan_by_segment(::std::forward(policy), first1, last1, first2, result, - binary_pred, binary_op); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(policy, first1, first2, result); + + return internal::pattern_inclusive_scan_by_segment(__dispatch_tag, ::std::forward(policy), first1, last1, + first2, result, binary_pred, binary_op); } template diff --git a/include/oneapi/dpl/internal/reduce_by_segment_impl.h b/include/oneapi/dpl/internal/reduce_by_segment_impl.h index 0102d6c2925..78986bca302 100644 --- a/include/oneapi/dpl/internal/reduce_by_segment_impl.h +++ b/include/oneapi/dpl/internal/reduce_by_segment_impl.h @@ -78,13 +78,15 @@ class Reduce3; template class Reduce4; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy> -reduce_by_segment_impl(Policy&& policy, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, +::std::pair +reduce_by_segment_impl(_Tag, Policy&& policy, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator1 result1, OutputIterator2 result2, BinaryPred binary_pred, BinaryOperator binary_op) { + static_assert(__internal::__is_host_dispatch_tag_v<_Tag>); + // The algorithm reduces values in [first2, first2 + (last1-first1)) where the associated // keys for the values are equal to the adjacent key. This function's implementation is a derivative work // and responsible for the second copyright notice in this header. @@ -112,7 +114,7 @@ reduce_by_segment_impl(Policy&& policy, InputIterator1 first1, InputIterator1 la // buffer that is used to store a flag indicating if the associated key is not equal to // the next key, and thus its associated sum should be part of the final result - oneapi::dpl::__par_backend::__buffer _mask(n + 1); + oneapi::dpl::__par_backend::__buffer _mask(policy, n + 1); auto mask = _mask.get(); mask[0] = 1; @@ -128,11 +130,11 @@ reduce_by_segment_impl(Policy&& policy, InputIterator1 first1, InputIterator1 la // buffer stores the sums of values associated with a given key. Sums are copied with // a shift into result2, and the shift is computed at the same time as the sums, so the // sums can't be written to result2 directly. - oneapi::dpl::__par_backend::__buffer _scanned_values(n); + oneapi::dpl::__par_backend::__buffer _scanned_values(policy, n); // Buffer is used to store results of the scan of the mask. Values indicate which position // in result2 needs to be written with the scanned_values element. - oneapi::dpl::__par_backend::__buffer _scanned_tail_flags(n); + oneapi::dpl::__par_backend::__buffer _scanned_tail_flags(policy, n); // Compute the sum of the segments. scanned_tail_flags values are not used. inclusive_scan(policy, make_zip_iterator(first2, _mask.get()), make_zip_iterator(first2, _mask.get()) + n, @@ -188,12 +190,12 @@ template using _SegReducePrefixPhase = __seg_reduce_prefix_kernel<_Name...>; } // namespace -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range3>> -__sycl_reduce_by_segment(_ExecutionPolicy&& __exec, _Range1&& __keys, _Range2&& __values, _Range3&& __out_keys, - _Range4&& __out_values, _BinaryPredicate __binary_pred, _BinaryOperator __binary_op, +template +oneapi::dpl::__internal::__difference_t<_Range3> +__sycl_reduce_by_segment(__internal::__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Range1&& __keys, + _Range2&& __values, _Range3&& __out_keys, _Range4&& __out_values, + _BinaryPredicate __binary_pred, _BinaryOperator __binary_op, ::std::false_type /* has_known_identity */) { return oneapi::dpl::experimental::ranges::reduce_by_segment( @@ -201,12 +203,12 @@ __sycl_reduce_by_segment(_ExecutionPolicy&& __exec, _Range1&& __keys, _Range2&& ::std::forward<_Range3>(__out_keys), ::std::forward<_Range4>(__out_values), __binary_pred, __binary_op); } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range3>> -__sycl_reduce_by_segment(_ExecutionPolicy&& __exec, _Range1&& __keys, _Range2&& __values, _Range3&& __out_keys, - _Range4&& __out_values, _BinaryPredicate __binary_pred, _BinaryOperator __binary_op, +template +oneapi::dpl::__internal::__difference_t<_Range3> +__sycl_reduce_by_segment(__internal::__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Range1&& __keys, + _Range2&& __values, _Range3&& __out_keys, _Range4&& __out_values, + _BinaryPredicate __binary_pred, _BinaryOperator __binary_op, ::std::true_type /* has_known_identity */) { using _CustomName = oneapi::dpl::__internal::__policy_kernel_name<_ExecutionPolicy>; @@ -570,12 +572,12 @@ __sycl_reduce_by_segment(_ExecutionPolicy&& __exec, _Range1&& __keys, _Range2&& return __end_idx.get_host_access()[0] + 1; } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy> -reduce_by_segment_impl(Policy&& policy, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, - OutputIterator1 result1, OutputIterator2 result2, BinaryPred binary_pred, - BinaryOperator binary_op) +template +::std::pair +reduce_by_segment_impl(__internal::__hetero_tag<_BackendTag> __tag, Policy&& policy, InputIterator1 first1, + InputIterator1 last1, InputIterator2 first2, OutputIterator1 result1, OutputIterator2 result2, + BinaryPred binary_pred, BinaryOperator binary_op) { // The algorithm reduces values in [first2, first2 + (last1-first1)) where the associated // keys for the values are equal to the adjacent key. @@ -609,9 +611,9 @@ reduce_by_segment_impl(Policy&& policy, InputIterator1 first1, InputIterator1 la typename ::std::iterator_traits::value_type>::type; // number of unique keys - _CountType __n = __sycl_reduce_by_segment(::std::forward(policy), key_buf.all_view(), value_buf.all_view(), - key_output_buf.all_view(), value_output_buf.all_view(), binary_pred, - binary_op, has_known_identity{}); + _CountType __n = __sycl_reduce_by_segment( + __tag, ::std::forward(policy), key_buf.all_view(), value_buf.all_view(), key_output_buf.all_view(), + value_output_buf.all_view(), binary_pred, binary_op, has_known_identity{}); return ::std::make_pair(result1 + __n, result2 + __n); } @@ -624,8 +626,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy(policy), first1, last1, first2, result1, result2, - binary_pred, binary_op); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(policy, first1, first2, result1, result2); + + return internal::reduce_by_segment_impl(__dispatch_tag, ::std::forward(policy), first1, last1, first2, + result1, result2, binary_pred, binary_op); } template using _SegScanPrefixPhase = __seg_scan_prefix_kernel<__is_inclusive, _Name...>; - template void - operator()(_ExecutionPolicy&& __exec, _Range1&& __keys, _Range2&& __values, _Range3&& __out_values, + operator()(_BackendTag, _ExecutionPolicy&& __exec, _Range1&& __keys, _Range2&& __values, _Range3&& __out_values, _BinaryPredicate __binary_pred, _BinaryOperator __binary_op, _T __init, _T __identity) { using _CustomName = oneapi::dpl::__internal::__policy_kernel_name<_ExecutionPolicy>; @@ -364,11 +364,12 @@ struct __sycl_scan_by_segment_impl } }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy -__scan_by_segment_impl_common(Policy&& policy, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, - OutputIterator result, T init, BinaryPredicate binary_pred, Operator binary_op, Inclusive) +template +OutputIterator +__scan_by_segment_impl_common(__internal::__hetero_tag<_BackendTag>, Policy&& policy, InputIterator1 first1, + InputIterator1 last1, InputIterator2 first2, OutputIterator result, T init, + BinaryPredicate binary_pred, Operator binary_op, Inclusive) { const auto n = ::std::distance(first1, last1); @@ -389,7 +390,7 @@ __scan_by_segment_impl_common(Policy&& policy, InputIterator1 first1, InputItera constexpr iter_value_t identity = unseq_backend::__known_identity; - __sycl_scan_by_segment_impl()(::std::forward(policy), key_buf.all_view(), + __sycl_scan_by_segment_impl()(_BackendTag{}, ::std::forward(policy), key_buf.all_view(), value_buf.all_view(), value_output_buf.all_view(), binary_pred, binary_op, init, identity); return result + n; diff --git a/include/oneapi/dpl/pstl/algorithm_fwd.h b/include/oneapi/dpl/pstl/algorithm_fwd.h index 34d09140fb0..5af00e5425c 100644 --- a/include/oneapi/dpl/pstl/algorithm_fwd.h +++ b/include/oneapi/dpl/pstl/algorithm_fwd.h @@ -26,6 +26,11 @@ namespace dpl namespace __internal { +template +struct __parallel_tag; + +struct __parallel_forward_tag; + //------------------------------------------------------------------------ // any_of //------------------------------------------------------------------------ @@ -40,15 +45,13 @@ bool __brick_any_of(const _RandomAccessIterator, const _RandomAccessIterator, _Pred, /*__is_vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_any_of(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Pred, _IsVector, - /*parallel=*/::std::false_type) noexcept; +template +bool +__pattern_any_of(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Pred) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_any_of(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Pred, _IsVector, - /*parallel=*/::std::true_type); +template +bool +__pattern_any_of(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Pred); //------------------------------------------------------------------------ // walk1 (pseudo) @@ -64,34 +67,26 @@ template void __brick_walk1(_RandomAccessIterator, _RandomAccessIterator, _Function, /*vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_walk1(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Function, _IsVector, - /*parallel=*/::std::false_type) noexcept; +template +void +__pattern_walk1(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Function) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy_conditional< - _ExecutionPolicy, __is_random_access_iterator_v<_RandomAccessIterator>> -__pattern_walk1(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Function __f, - _IsVector __is_vector, - /*parallel=*/::std::true_type); +template +void +__pattern_walk1(__parallel_forward_tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Function); -template -oneapi::dpl::__internal::__enable_if_host_execution_policy_conditional< - _ExecutionPolicy, !__is_random_access_iterator_v<_RandomAccessIterator>> -__pattern_walk1(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Function __f, - _IsVector __is_vector, - /*parallel=*/::std::true_type); +template +void +__pattern_walk1(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Function); -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_walk_brick(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Brick, - /*parallel=*/::std::false_type) noexcept; +template +void +__pattern_walk_brick(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Brick) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_walk_brick(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Brick, - /*parallel=*/::std::true_type); +template +void +__pattern_walk_brick(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _Brick); //------------------------------------------------------------------------ // walk1_n @@ -105,25 +100,21 @@ template _RandomAccessIterator __brick_walk1_n(_RandomAccessIterator, _DifferenceType, _Function, /*vectorTag=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_walk1_n(_ExecutionPolicy&&, _ForwardIterator, _Size, _Function, _IsVector, - /*is_parallel=*/::std::false_type) noexcept; +template +_ForwardIterator +__pattern_walk1_n(_Tag, _ExecutionPolicy&&, _ForwardIterator, _Size, _Function) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_walk1_n(_ExecutionPolicy&&, _RandomAccessIterator, _Size, _Function, _IsVector, - /*is_parallel=*/::std::true_type); +template +_RandomAccessIterator +__pattern_walk1_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _Size, _Function); -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_walk_brick_n(_ExecutionPolicy&&, _ForwardIterator, _Size, _Brick, - /*is_parallel=*/::std::false_type) noexcept; +template +_ForwardIterator +__pattern_walk_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator, _Size, _Brick) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_walk_brick_n(_ExecutionPolicy&&, _RandomAccessIterator, _Size, _Brick, - /*is_parallel=*/::std::true_type); +template +_RandomAccessIterator +__pattern_walk_brick_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _Size, _Brick); //------------------------------------------------------------------------ // walk2 (pseudo) @@ -147,65 +138,58 @@ template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator2> -__pattern_walk2(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Function, _IsVector, - /*parallel=*/::std::false_type) noexcept; - -template -oneapi::dpl::__internal::__enable_if_host_execution_policy_conditional< - _ExecutionPolicy, __is_random_access_iterator_v<_RandomAccessIterator1, _RandomAccessIterator2>, - _RandomAccessIterator2> -__pattern_walk2(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _Function __f, _IsVector __is_vector, /*parallel=*/::std::true_type); - -template -oneapi::dpl::__internal::__enable_if_host_execution_policy_conditional< - _ExecutionPolicy, !__is_random_access_iterator_v<_ForwardIterator1, _ForwardIterator2>, _ForwardIterator2> -__pattern_walk2(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Function __f, _IsVector __is_vector, /*parallel=*/::std::true_type); - -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator2> -__pattern_walk2_n(_ExecutionPolicy&&, _ForwardIterator1, _Size, _ForwardIterator2, _Function, _IsVector, - /*parallel=*/::std::false_type) noexcept; - -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator2> -__pattern_walk2_n(_ExecutionPolicy&&, _RandomAccessIterator1, _Size, _RandomAccessIterator2, _Function, _IsVector, - /*parallel=*/::std::true_type); +template +_ForwardIterator2 +__pattern_walk2(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Function) noexcept; + +template +_RandomAccessIterator2 +__pattern_walk2(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _Function); + +template +_ForwardIterator2 +__pattern_walk2(__parallel_forward_tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, + _Function); + +template +_ForwardIterator2 +__pattern_walk2_n(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _Size, _ForwardIterator2, _Function) noexcept; + +template +_RandomAccessIterator2 +__pattern_walk2_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _Size, _RandomAccessIterator2, + _Function); + +template +_ForwardIterator2 +__pattern_walk2_brick(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, + _Brick) noexcept; + +template +_RandomAccessIterator2 +__pattern_walk2_brick(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _Brick); template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator2> -__pattern_walk2_brick(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Brick, - /*parallel=*/::std::false_type) noexcept; - -template -oneapi::dpl::__internal::__enable_if_host_execution_policy_conditional< - _ExecutionPolicy, __is_random_access_iterator_v<_RandomAccessIterator1, _RandomAccessIterator2>, - _RandomAccessIterator2> -__pattern_walk2_brick(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _Brick __brick, /*parallel=*/::std::true_type); - -template -oneapi::dpl::__internal::__enable_if_host_execution_policy_conditional< - _ExecutionPolicy, !__is_random_access_iterator_v<_RandomAccessIterator1, _RandomAccessIterator2>, - _RandomAccessIterator2> -__pattern_walk2_brick(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _Brick __brick, /*parallel=*/::std::true_type); - -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator2> -__pattern_walk2_brick_n(_ExecutionPolicy&&, _ForwardIterator1, _Size, _ForwardIterator2, _Brick, - /*parallel=*/::std::false_type) noexcept; - -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator2> -__pattern_walk2_brick_n(_ExecutionPolicy&&, _RandomAccessIterator1, _Size, _RandomAccessIterator2, _Brick, - /*parallel=*/::std::true_type); +_ForwardIterator2 +__pattern_walk2_brick(__parallel_forward_tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, + _ForwardIterator2, _Brick); + +template +_ForwardIterator2 +__pattern_walk2_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _Size, _ForwardIterator2, _Brick) noexcept; + +template +_RandomAccessIterator2 +__pattern_walk2_brick_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _Size, + _RandomAccessIterator2, _Brick); //------------------------------------------------------------------------ // walk3 (pseudo) @@ -222,50 +206,39 @@ _RandomAccessIterator3 __brick_walk3(_RandomAccessIterator1, _RandomAccessIterat _RandomAccessIterator3, _Function, /*vector=*/::std::true_type) noexcept; +template +_ForwardIterator3 +__pattern_walk3(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator3, + _Function) noexcept; + +template +_RandomAccessIterator3 +__pattern_walk3(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator3, _Function); + template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator3> -__pattern_walk3(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator3, - _Function, _IsVector, - /*parallel=*/::std::false_type) noexcept; - -template -oneapi::dpl::__internal::__enable_if_host_execution_policy_conditional< - _ExecutionPolicy, - __is_random_access_iterator_v<_RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator3>, - _RandomAccessIterator3> -__pattern_walk3(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator3 __first3, _Function __f, _IsVector __is_vector, - /*parallel=*/::std::true_type); - -template -oneapi::dpl::__internal::__enable_if_host_execution_policy_conditional< - _ExecutionPolicy, - !__is_random_access_iterator_v<_RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator3>, - _RandomAccessIterator3> -__pattern_walk3(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator3 __first3, _Function __f, _IsVector __is_vector, - /*parallel=*/::std::true_type); + class _Function> +_ForwardIterator3 +__pattern_walk3(__parallel_forward_tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, + _ForwardIterator3, _Function); //------------------------------------------------------------------------ // transform_if //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator2> -__pattern_walk2_transform_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Function __func, _IsVector __is_vector, - _IsParallel __is_parallel) noexcept; +template +_ForwardIterator2 +__pattern_walk2_transform_if(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, + _Function) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator3> -__pattern_walk3_transform_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator3 __first3, _Function __func, - _IsVector __is_vector, _IsParallel __is_parallel) noexcept; +template +_ForwardIterator3 +__pattern_walk3_transform_if(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, + _ForwardIterator3, _Function) noexcept; //------------------------------------------------------------------------ // equal @@ -279,17 +252,16 @@ template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_equal(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _BinaryPredicate, - _IsVector, /* is_parallel = */ ::std::false_type) noexcept; +template +bool +__pattern_equal(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, + _BinaryPredicate) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_equal(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _BinaryPredicate, _IsVector, /* is_parallel = */ ::std::true_type); +template +bool +__pattern_equal(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator2, _BinaryPredicate); template bool __brick_equal(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, _BinaryPredicate, @@ -299,17 +271,16 @@ template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_equal(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _BinaryPredicate, _IsVector, /* is_parallel = */ ::std::false_type) noexcept; +template +bool +__pattern_equal(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, + _BinaryPredicate) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_equal(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _BinaryPredicate, _IsVector, /* is_parallel = */ ::std::true_type); +template +bool +__pattern_equal(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _BinaryPredicate); //------------------------------------------------------------------------ // find_if @@ -323,15 +294,14 @@ template _RandomAccessIterator __brick_find_if(_RandomAccessIterator, _RandomAccessIterator, _Predicate, /*is_vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_find_if(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Predicate, _IsVector, - /*is_parallel=*/::std::false_type) noexcept; +template +_ForwardIterator +__pattern_find_if(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Predicate) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_find_if(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Predicate, _IsVector, - /*is_parallel=*/::std::true_type); +template +_RandomAccessIterator +__pattern_find_if(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _Predicate); //------------------------------------------------------------------------ // find_end @@ -347,19 +317,16 @@ _RandomAccessIterator1 __brick_find_end(_RandomAccessIterator1, _RandomAccessIte _RandomAccessIterator2, _BinaryPredicate, /*__is_vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator1> -__pattern_find_end(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _BinaryPredicate, _IsVector, - /*is_parallel=*/::std::false_type) noexcept; +template +_ForwardIterator1 +__pattern_find_end(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, + _BinaryPredicate) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator1> -__pattern_find_end(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _BinaryPredicate, _IsVector, - /*is_parallel=*/::std::true_type); +template +_RandomAccessIterator1 +__pattern_find_end(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator2, _BinaryPredicate); //------------------------------------------------------------------------ // find_first_of @@ -375,17 +342,16 @@ _RandomAccessIterator1 __brick_find_first_of(_RandomAccessIterator1, _RandomAcce _RandomAccessIterator2, _BinaryPredicate, /*__is_vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator1> -__pattern_find_first_of(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _BinaryPredicate, _IsVector, /*is_parallel=*/::std::false_type) noexcept; +template +_ForwardIterator1 +__pattern_find_first_of(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, + _ForwardIterator2, _BinaryPredicate) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator1> -__pattern_find_first_of(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _BinaryPredicate, _IsVector, /*is_parallel=*/::std::true_type); +template +_RandomAccessIterator1 +__pattern_find_first_of(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator2, _BinaryPredicate); //------------------------------------------------------------------------ // search @@ -401,19 +367,16 @@ _RandomAccessIterator1 __brick_search(_RandomAccessIterator1, _RandomAccessItera _RandomAccessIterator2, _BinaryPredicate, /*vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator1> -__pattern_search(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _BinaryPredicate, _IsVector, - /*is_parallel=*/::std::false_type) noexcept; +template +_ForwardIterator1 +__pattern_search(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, + _BinaryPredicate) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator1> -__pattern_search(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _BinaryPredicate, _IsVector, - /*is_parallel=*/::std::true_type); +template +_RandomAccessIterator1 +__pattern_search(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator2, _BinaryPredicate); //------------------------------------------------------------------------ // search_n @@ -429,31 +392,28 @@ _RandomAccessIterator __brick_search_n(_RandomAccessIterator, _RandomAccessIterator, _Size, const _Tp&, _BinaryPredicate, /*vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_search_n(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Size, const _Tp&, _BinaryPredicate, - IsVector, - /*is_parallel=*/::std::false_type) noexcept; +template +_ForwardIterator +__pattern_search_n(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Size, const _Tp&, + _BinaryPredicate) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_search_n(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Size, const _Tp&, - _BinaryPredicate, IsVector, - /*is_parallel=*/::std::true_type); +template +_RandomAccessIterator +__pattern_search_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Size, + const _Tp&, _BinaryPredicate); //------------------------------------------------------------------------ // copy_n //------------------------------------------------------------------------ -template +template struct __brick_copy_n; -template +template struct __brick_copy; -template +template struct __brick_move; //------------------------------------------------------------------------ @@ -510,16 +470,16 @@ void __brick_partition_by_mask(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator1, _OutputIterator2, bool*, /*vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_copy_if(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _UnaryPredicate, _IsVector, - /*parallel=*/::std::false_type) noexcept; +template +_OutputIterator +__pattern_copy_if(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, + _UnaryPredicate) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_copy_if(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator, _UnaryPredicate, - _IsVector, /*parallel=*/::std::true_type); +template +_RandomAccessIterator2 +__pattern_copy_if(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _UnaryPredicate); //------------------------------------------------------------------------ // count @@ -535,17 +495,14 @@ typename ::std::iterator_traits<_ForwardIterator>::difference_type __brick_count(_ForwardIterator, _ForwardIterator, _Predicate, /* is_vector = */ ::std::false_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy< - _ExecutionPolicy, typename ::std::iterator_traits<_ForwardIterator>::difference_type> -__pattern_count(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Predicate, - /* is_parallel */ ::std::false_type, _IsVector) noexcept; +template +typename ::std::iterator_traits<_ForwardIterator>::difference_type +__pattern_count(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Predicate) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy< - _ExecutionPolicy, typename ::std::iterator_traits<_RandomAccessIterator>::difference_type> -__pattern_count(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Predicate, - /* is_parallel */ ::std::true_type, _IsVector); +template +typename ::std::iterator_traits<_RandomAccessIterator>::difference_type +__pattern_count(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _Predicate); //------------------------------------------------------------------------ // unique @@ -559,15 +516,14 @@ template _RandomAccessIterator __brick_unique(_RandomAccessIterator, _RandomAccessIterator, _BinaryPredicate, /*is_vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_unique(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _BinaryPredicate, _IsVector, - /*is_parallel=*/::std::false_type) noexcept; +template +_ForwardIterator +__pattern_unique(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _BinaryPredicate) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_unique(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _BinaryPredicate, _IsVector, - /*is_parallel=*/::std::true_type); +template +_RandomAccessIterator +__pattern_unique(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _BinaryPredicate); //------------------------------------------------------------------------ // unique_copy @@ -581,11 +537,10 @@ template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_unique_copy(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryPredicate, - _IsVector, /*parallel=*/::std::false_type) noexcept; +template +_OutputIterator +__pattern_unique_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, + _BinaryPredicate) noexcept; template _DifferenceType @@ -597,11 +552,11 @@ _DifferenceType __brick_calc_mask_2(_RandomAccessIterator, _RandomAccessIterator, bool* __restrict, _BinaryPredicate, /*vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_unique_copy(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator, - _BinaryPredicate, _IsVector, /*parallel=*/::std::true_type); +template +_RandomAccessIterator2 +__pattern_unique_copy(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _BinaryPredicate); //------------------------------------------------------------------------ // reverse @@ -623,15 +578,13 @@ template void __brick_reverse(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, /*is_vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_reverse(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _IsVector, - /*is_parallel=*/::std::false_type) noexcept; +template +void +__pattern_reverse(_Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_reverse(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _IsVector, - /*is_parallel=*/::std::true_type); +template +void +__pattern_reverse(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator); //------------------------------------------------------------------------ // reverse_copy @@ -645,15 +598,15 @@ template _OutputIterator __brick_reverse_copy(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator, /*is_vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_reverse_copy(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _OutputIterator, _IsVector, - /*is_parallel=*/::std::false_type) noexcept; +template +_OutputIterator +__pattern_reverse_copy(_Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, + _OutputIterator) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_reverse_copy(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator, _IsVector, - /*is_parallel=*/::std::true_type); +template +_RandomAccessIterator2 +__pattern_reverse_copy(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2); //------------------------------------------------------------------------ // rotate @@ -667,40 +620,36 @@ template _RandomAccessIterator __brick_rotate(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, /*is_vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_rotate(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator, _IsVector, - /*is_parallel=*/::std::false_type) noexcept; +template +_ForwardIterator +__pattern_rotate(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_rotate(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _IsVector, - /*is_parallel=*/::std::true_type); +template +_RandomAccessIterator +__pattern_rotate(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _RandomAccessIterator); //------------------------------------------------------------------------ // rotate_copy //------------------------------------------------------------------------ -template -_OutputIterator __brick_rotate_copy(_ForwardIterator, _ForwardIterator, _ForwardIterator, _OutputIterator, - /*__is_vector=*/::std::false_type) noexcept; +template +_OutputIterator __brick_rotate_copy(_Tag, _ForwardIterator, _ForwardIterator, _ForwardIterator, + _OutputIterator) noexcept; -template -_OutputIterator __brick_rotate_copy(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, - _OutputIterator, - /*__is_vector=*/::std::true_type) noexcept; +template +_OutputIterator __brick_rotate_copy(__parallel_tag<_IsVector>, _RandomAccessIterator, _RandomAccessIterator, + _RandomAccessIterator, _OutputIterator) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_rotate_copy(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator, _OutputIterator, - _IsVector, - /*is_parallel=*/::std::false_type) noexcept; +template +_OutputIterator +__pattern_rotate_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator, + _OutputIterator) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_rotate_copy(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, - _OutputIterator, _IsVector, - /*is_parallel=*/::std::true_type); +template +_RandomAccessIterator2 +__pattern_rotate_copy(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator1, _RandomAccessIterator2); //------------------------------------------------------------------------ // is_partitioned @@ -714,15 +663,14 @@ template bool __brick_is_partitioned(_RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate, /*is_vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_is_partitioned(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate, _IsVector, - /*is_parallel=*/::std::false_type) noexcept; +template +bool +__pattern_is_partitioned(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_is_partitioned(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate, _IsVector, - /*is_parallel=*/::std::true_type); +template +bool +__pattern_is_partitioned(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _UnaryPredicate); //------------------------------------------------------------------------ // partition @@ -736,15 +684,14 @@ template _RandomAccessIterator __brick_partition(_RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate, /*is_vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_partition(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate, _IsVector, - /*is_parallel=*/::std::false_type) noexcept; +template +_ForwardIterator +__pattern_partition(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_partition(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate, _IsVector, - /*is_parallel=*/::std::true_type); +template +_RandomAccessIterator +__pattern_partition(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _UnaryPredicate); //------------------------------------------------------------------------ // stable_partition @@ -758,16 +705,15 @@ template _RandomAccessIterator __brick_stable_partition(_RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate, /*__is_vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _BidirectionalIterator> -__pattern_stable_partition(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _UnaryPredicate, - _IsVector, - /*is_parallelization=*/::std::false_type) noexcept; +template +_BidirectionalIterator +__pattern_stable_partition(_Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, + _UnaryPredicate) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_stable_partition(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate, _IsVector, - /*is_parallelization=*/::std::true_type); +template +_RandomAccessIterator +__pattern_stable_partition(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _UnaryPredicate); //------------------------------------------------------------------------ // partition_copy @@ -784,104 +730,88 @@ ::std::pair<_OutputIterator1, _OutputIterator2> __brick_partition_copy(_RandomAc _UnaryPredicate, /*is_vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, - ::std::pair<_OutputIterator1, _OutputIterator2>> -__pattern_partition_copy(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator1, _OutputIterator2, - _UnaryPredicate, _IsVector, - /*is_parallelization=*/::std::false_type) noexcept; +template +::std::pair<_OutputIterator1, _OutputIterator2> +__pattern_partition_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator1, + _OutputIterator2, _UnaryPredicate) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, - ::std::pair<_OutputIterator1, _OutputIterator2>> -__pattern_partition_copy(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator1, - _OutputIterator2, _UnaryPredicate, _IsVector, - /*is_parallelization=*/::std::true_type); +template +::std::pair<_RandomAccessIterator2, _RandomAccessIterator3> +__pattern_partition_copy(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator3, _UnaryPredicate); //------------------------------------------------------------------------ // sort //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_sort(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsVector /*is_vector*/, - /*is_parallel=*/::std::false_type, _IsMoveConstructible) noexcept; +template +void +__pattern_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, + _IsMoveConstructible) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_sort(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsVector /*is_vector*/, - /*is_parallel=*/::std::true_type, +template +void +__pattern_sort(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, /*is_move_constructible=*/::std::true_type); //------------------------------------------------------------------------ // stable_sort //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, - _IsVector /*is_vector*/, - /*is_parallel=*/::std::false_type) noexcept; +template +void +__pattern_stable_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, - _IsVector /*is_vector*/, - /*is_parallel=*/::std::true_type); +template +void +__pattern_stable_sort(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _Compare); //------------------------------------------------------------------------ // sort_by_key //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_sort_by_key(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __keys_first, - _RandomAccessIterator1 __keys_last, _RandomAccessIterator2 __values_first, _Compare __comp, - _IsVector /*vector=*/, /*is_parallel=*/::std::false_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_sort_by_key(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __keys_first, - _RandomAccessIterator1 __keys_last, _RandomAccessIterator2 __values_first, _Compare __comp, - _IsVector /*vector=*/, /*is_parallel=*/::std::true_type); +template +void +__pattern_sort_by_key(_Tag, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, + _Compare) noexcept; + +template +void +__pattern_sort_by_key(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _Compare); //------------------------------------------------------------------------ // partial_sort //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_partial_sort(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, - _Compare, _IsVector, - /*is_parallel=*/::std::false_type) noexcept; +template +void +__pattern_partial_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, + _Compare) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_partial_sort(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, - _Compare, _IsVector, - /*is_parallel=*/::std::true_type); +template +void +__pattern_partial_sort(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _RandomAccessIterator, _Compare); //------------------------------------------------------------------------ // partial_sort_copy //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator2> -__pattern_partial_sort_copy(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _Compare, _IsVector, - /*is_parallel=*/::std::false_type) noexcept; +template +_RandomAccessIterator +__pattern_partial_sort_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _RandomAccessIterator, + _RandomAccessIterator, _Compare) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator2> -__pattern_partial_sort_copy(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _Compare, _IsVector, - /*is_parallel=*/::std::true_type); +template +_RandomAccessIterator +__pattern_partial_sort_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _RandomAccessIterator, + _RandomAccessIterator, _Compare) noexcept; //------------------------------------------------------------------------ // adjacent_find @@ -897,59 +827,54 @@ _ForwardIterator __brick_adjacent_find(_ForwardIterator, _ForwardIterator, _BinaryPredicate, /* IsVector = */ ::std::false_type, bool) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_adjacent_find(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _BinaryPredicate, - /* is_parallel */ ::std::false_type, _IsVector, _Semantic) noexcept; +template +_ForwardIterator +__pattern_adjacent_find(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _BinaryPredicate, + _Semantic) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_adjacent_find(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _BinaryPredicate, - /* is_parallel */ ::std::true_type, _IsVector, _Semantic); +template +_RandomAccessIterator +__pattern_adjacent_find(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _BinaryPredicate, _Semantic); //------------------------------------------------------------------------ // nth_element //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_nth_element(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare, - _IsVector, - /*is_parallel=*/::std::false_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_nth_element(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare, - _IsVector, - /*is_parallel=*/::std::true_type); +template +void +__pattern_nth_element(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, + _Compare) noexcept; + +template +void +__pattern_nth_element(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _RandomAccessIterator, _Compare); //------------------------------------------------------------------------ // fill, fill_n //------------------------------------------------------------------------ -template +template struct __brick_fill; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_fill(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, const _Tp&, - /*is_parallel=*/::std::false_type, _IsVector) noexcept; +template +void +__pattern_fill(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, const _Tp&) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_fill(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, const _Tp&, - /*is_parallel=*/::std::true_type, _IsVector); +template +_RandomAccessIterator +__pattern_fill(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, const _Tp&); -template +template struct __brick_fill_n; -template +template _OutputIterator -__pattern_fill_n(_ExecutionPolicy&&, _OutputIterator, _Size, const _Tp&, - /*is_parallel=*/::std::false_type, _IsVector) noexcept; +__pattern_fill_n(_Tag, _ExecutionPolicy&&, _OutputIterator, _Size, const _Tp&) noexcept; -template +template _RandomAccessIterator -__pattern_fill_n(_ExecutionPolicy&&, _RandomAccessIterator, _Size, const _Tp&, - /*is_parallel=*/::std::true_type, _IsVector); +__pattern_fill_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _Size, const _Tp&); //------------------------------------------------------------------------ // generate, generate_n @@ -963,15 +888,14 @@ template void __brick_generate(_ForwardIterator, _ForwardIterator, _Generator, /* is_vector = */ ::std::false_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_generate(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Generator, - /*is_parallel=*/::std::false_type, _IsVector) noexcept; +template +void +__pattern_generate(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Generator) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_generate(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Generator, - /*is_parallel=*/::std::true_type, _IsVector); +template +_RandomAccessIterator +__pattern_generate(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _Generator); template _RandomAccessIterator __brick_generate_n(_RandomAccessIterator, Size, _Generator, @@ -981,15 +905,13 @@ template OutputIterator __brick_generate_n(OutputIterator, Size, _Generator, /* is_vector = */ ::std::false_type) noexcept; -template -OutputIterator -__pattern_generate_n(_ExecutionPolicy&&, OutputIterator, Size, _Generator, - /*is_parallel=*/::std::false_type, _IsVector) noexcept; +template +_OutputIterator +__pattern_generate_n(_Tag, _ExecutionPolicy&&, _OutputIterator, _Size, _Generator) noexcept; -template +template _RandomAccessIterator -__pattern_generate_n(_ExecutionPolicy&&, _RandomAccessIterator, Size, _Generator, - /*is_parallel=*/::std::true_type, _IsVector); +__pattern_generate_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _Size, _Generator); //------------------------------------------------------------------------ // remove @@ -1002,15 +924,14 @@ template _RandomAccessIterator __brick_remove_if(_RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate, /* __is_vector = */ ::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_remove_if(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate, _IsVector, - /*is_parallel*/ ::std::false_type) noexcept; +template +_ForwardIterator +__pattern_remove_if(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_remove_if(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate, _IsVector, - /*is_parallel*/ ::std::true_type); +template +_RandomAccessIterator +__pattern_remove_if(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _UnaryPredicate); //------------------------------------------------------------------------ // merge @@ -1026,18 +947,17 @@ _OutputIterator __brick_merge(_RandomAccessIterator1, _RandomAccessIterator1, _R _RandomAccessIterator2, _OutputIterator, _Compare, /* __is_vector = */ ::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_merge(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _OutputIterator, _Compare, _IsVector, /* is_parallel = */ ::std::false_type) noexcept; +template +_OutputIterator +__pattern_merge(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, + _OutputIterator, _Compare) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_merge(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _OutputIterator, _Compare, _IsVector, - /* is_parallel = */ ::std::true_type); +template +_RandomAccessIterator3 +__pattern_merge(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator2, _RandomAccessIterator3, _Compare); //------------------------------------------------------------------------ // inplace_merge @@ -1051,34 +971,30 @@ template void __brick_inplace_merge(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare, /* __is_vector = */ ::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_inplace_merge(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _BidirectionalIterator, - _Compare, _IsVector, - /* is_parallel = */ ::std::false_type) noexcept; +template +void +__pattern_inplace_merge(_Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, + _BidirectionalIterator, _Compare) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_inplace_merge(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, - _Compare, _IsVector, - /*is_parallel=*/::std::true_type); +template +void +__pattern_inplace_merge(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _RandomAccessIterator, _Compare); //------------------------------------------------------------------------ // includes //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_includes(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _Compare, _IsVector, - /*is_parallel=*/::std::false_type) noexcept; +template +bool +__pattern_includes(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, + _Compare) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_includes(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _Compare, _IsVector, - /*is_parallel=*/::std::true_type); +template +bool +__pattern_includes(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator2, _Compare); //------------------------------------------------------------------------ // set_union @@ -1094,17 +1010,17 @@ _OutputIterator __brick_set_union(_RandomAccessIterator1, _RandomAccessIterator1 _RandomAccessIterator2, _OutputIterator, _Compare, /*__is_vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_set_union(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _OutputIterator, _Compare, _IsVector, /*is_parallel=*/::std::false_type) noexcept; +template +_OutputIterator +__pattern_set_union(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, + _ForwardIterator2, _OutputIterator, _Compare) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_set_union(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _OutputIterator, _Compare, _IsVector, /*is_parallel=*/::std::true_type); +template +_OutputIterator +__pattern_set_union(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator2, _OutputIterator, _Compare); //------------------------------------------------------------------------ // set_intersection @@ -1120,19 +1036,18 @@ _OutputIterator __brick_set_intersection(_RandomAccessIterator1, _RandomAccessIt _RandomAccessIterator2, _OutputIterator, _Compare, /*__is_vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_set_intersection(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator2, _OutputIterator, _Compare, _IsVector, - /*is_parallel=*/::std::false_type) noexcept; +template +_OutputIterator +__pattern_set_intersection(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, + _ForwardIterator2, _OutputIterator, _Compare) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_set_intersection(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _OutputIterator, _Compare, _IsVector, - /*is_parallel=*/::std::true_type); +template +_RandomAccessIterator3 +__pattern_set_intersection(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, + _RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator2, + _RandomAccessIterator3, _Compare); //------------------------------------------------------------------------ // set_difference @@ -1148,18 +1063,17 @@ _OutputIterator __brick_set_difference(_RandomAccessIterator1, _RandomAccessIter _RandomAccessIterator2, _OutputIterator, _Compare, /*__is_vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_set_difference(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _OutputIterator, _Compare, _IsVector, /*is_parallel=*/::std::false_type) noexcept; +template +_OutputIterator +__pattern_set_difference(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, + _ForwardIterator2, _OutputIterator, _Compare) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_set_difference(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _OutputIterator, _Compare, _IsVector, - /*is_parallel=*/::std::true_type); +template +_RandomAccessIterator3 +__pattern_set_difference(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator2, _RandomAccessIterator3, _Compare); //------------------------------------------------------------------------ // set_symmetric_difference @@ -1175,19 +1089,18 @@ _OutputIterator __brick_set_symmetric_difference(_RandomAccessIterator1, _Random _RandomAccessIterator2, _OutputIterator, _Compare, /*__is_vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_set_symmetric_difference(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator2, _OutputIterator, _Compare, _IsVector, - /*is_parallel=*/::std::false_type) noexcept; +template +_OutputIterator +__pattern_set_symmetric_difference(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, + _ForwardIterator2, _OutputIterator, _Compare) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_set_symmetric_difference(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, - _RandomAccessIterator2, _RandomAccessIterator2, _OutputIterator, _Compare, _IsVector, - /*is_parallel=*/::std::true_type); +template +_RandomAccessIterator3 +__pattern_set_symmetric_difference(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, + _RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator2, + _RandomAccessIterator3, _Compare); //------------------------------------------------------------------------ // is_heap_until @@ -1201,15 +1114,14 @@ template _RandomAccessIterator __brick_is_heap_until(_RandomAccessIterator, _RandomAccessIterator, _Compare, /* __is_vector = */ ::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_is_heap_until(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsVector, - /* is_parallel = */ ::std::false_type) noexcept; +template +_RandomAccessIterator +__pattern_is_heap_until(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_is_heap_until(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsVector, - /* is_parallel = */ ::std::true_type); +template +_RandomAccessIterator +__pattern_is_heap_until(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _Compare); //------------------------------------------------------------------------ // is_heap @@ -1223,15 +1135,14 @@ template bool __brick_is_heap(_RandomAccessIterator, _RandomAccessIterator, _Compare, /* __is_vector = */ ::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_is_heap(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsVector, - /* is_parallel = */ ::std::false_type) noexcept; +template +bool +__pattern_is_heap(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_is_heap(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsVector, - /* is_parallel = */ ::std::true_type); +template +bool +__pattern_is_heap(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _Compare); //------------------------------------------------------------------------ // min_element @@ -1245,15 +1156,14 @@ template _RandomAccessIterator __brick_min_element(_RandomAccessIterator, _RandomAccessIterator, _Compare, /* __is_vector = */ ::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_min_element(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare, _IsVector, - /* is_parallel = */ ::std::false_type) noexcept; +template +_ForwardIterator +__pattern_min_element(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_min_element(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsVector, - /* is_parallel = */ ::std::true_type); +template +_RandomAccessIterator +__pattern_min_element(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _Compare); //------------------------------------------------------------------------ // minmax_element @@ -1268,17 +1178,14 @@ ::std::pair<_RandomAccessIterator, _RandomAccessIterator> __brick_minmax_element(_RandomAccessIterator, _RandomAccessIterator, _Compare, /* __is_vector = */ ::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, - ::std::pair<_ForwardIterator, _ForwardIterator>> -__pattern_minmax_element(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare, _IsVector, - /* is_parallel = */ ::std::false_type) noexcept; +template +::std::pair<_ForwardIterator, _ForwardIterator> +__pattern_minmax_element(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, - ::std::pair<_RandomAccessIterator, _RandomAccessIterator>> -__pattern_minmax_element(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsVector, - /* is_parallel = */ ::std::true_type); +template +::std::pair<_RandomAccessIterator, _RandomAccessIterator> +__pattern_minmax_element(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _Compare); //------------------------------------------------------------------------ // mismatch @@ -1295,19 +1202,16 @@ ::std::pair<_RandomAccessIterator1, _RandomAccessIterator2> _Predicate, /* __is_vector = */ ::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, - ::std::pair<_ForwardIterator1, _ForwardIterator2>> -__pattern_mismatch(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _Predicate, _IsVector, - /* is_parallel = */ ::std::false_type) noexcept; +template +::std::pair<_ForwardIterator1, _ForwardIterator2> +__pattern_mismatch(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, + _Predicate) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, - ::std::pair<_RandomAccessIterator1, _RandomAccessIterator2>> -__pattern_mismatch(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _Predicate, _IsVector, /* is_parallel = */ ::std::true_type); +template +::std::pair<_RandomAccessIterator1, _RandomAccessIterator2> +__pattern_mismatch(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator2, _Predicate); //------------------------------------------------------------------------ // lexicographical_compare @@ -1323,24 +1227,21 @@ bool __brick_lexicographical_compare(_RandomAccessIterator1, _RandomAccessIterat _RandomAccessIterator2, _Compare, /* __is_vector = */ ::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_lexicographical_compare(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator2, _Compare, _IsVector, - /* is_parallel = */ ::std::false_type) noexcept; +template +bool +__pattern_lexicographical_compare(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, + _ForwardIterator2, _Compare) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_lexicographical_compare(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, - _RandomAccessIterator2, _RandomAccessIterator2, _Compare, _IsVector, - /* is_parallel = */ ::std::true_type); +template +bool +__pattern_lexicographical_compare(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, + _RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator2, + _Compare) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator2> -__pattern_swap(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Function, _IsVector, - _IsParallel); +template +_ForwardIterator2 +__pattern_swap(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Function); //------------------------------------------------------------------------ // shift_left @@ -1356,23 +1257,24 @@ _ForwardIterator __brick_shift_left(_ForwardIterator, _ForwardIterator, typename ::std::iterator_traits<_ForwardIterator>::difference_type, /*__is_vector=*/::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_shift_left(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, - typename ::std::iterator_traits<_ForwardIterator>::difference_type, _IsVector, - /*is_parallel=*/::std::false_type) noexcept; - -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_shift_left(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, - typename ::std::iterator_traits<_ForwardIterator>::difference_type, _IsVector, - /*is_parallel=*/::std::true_type); - -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _BidirectionalIterator> -__pattern_shift_right(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, - typename ::std::iterator_traits<_BidirectionalIterator>::difference_type, _IsVector, - _IsParallel is_parallel); +template +_ForwardIterator +__pattern_shift_left(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, + typename ::std::iterator_traits<_ForwardIterator>::difference_type) noexcept; + +template +_RandomAccessIterator +__pattern_shift_left(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + typename ::std::iterator_traits<_RandomAccessIterator>::difference_type); + +//------------------------------------------------------------------------ +// shift_right +//------------------------------------------------------------------------ + +template +_BidirectionalIterator +__pattern_shift_right(_Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, + typename ::std::iterator_traits<_BidirectionalIterator>::difference_type); } // namespace __internal } // namespace dpl diff --git a/include/oneapi/dpl/pstl/algorithm_impl.h b/include/oneapi/dpl/pstl/algorithm_impl.h index 7d3e07c4ec0..d0be4420f8c 100644 --- a/include/oneapi/dpl/pstl/algorithm_impl.h +++ b/include/oneapi/dpl/pstl/algorithm_impl.h @@ -63,23 +63,24 @@ __brick_any_of(const _RandomAccessIterator __first, const _RandomAccessIterator return __unseq_backend::__simd_or(__first, __last - __first, __pred); }; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_any_of(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred, - _IsVector __is_vector, /*parallel=*/::std::false_type) noexcept +template +bool +__pattern_any_of(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) noexcept { - return __internal::__brick_any_of(__first, __last, __pred, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_any_of(__first, __last, __pred, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_any_of(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Pred __pred, - _IsVector __is_vector, /*parallel=*/::std::true_type) +template +bool +__pattern_any_of(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Pred __pred) { return __internal::__except_handler([&]() { - return __internal::__parallel_or(::std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__pred, __is_vector](_RandomAccessIterator __i, _RandomAccessIterator __j) { - return __internal::__brick_any_of(__i, __j, __pred, __is_vector); + return __internal::__parallel_or(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__pred](_RandomAccessIterator __i, _RandomAccessIterator __j) { + return __internal::__brick_any_of(__i, __j, __pred, _IsVector{}); }); }); } @@ -134,64 +135,66 @@ __brick_walk1(_DifferenceType __n, _Function __f, ::std::true_type) noexcept oneapi::dpl::__internal::__brick_walk1(__n, __f, ::std::false_type{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_walk1(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Function __f, - _IsVector __is_vector, - /*parallel=*/::std::false_type) noexcept +template +void +__pattern_walk1(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Function __f) noexcept { - __internal::__brick_walk1(__first, __last, __f, __is_vector); + static_assert(__is_serial_tag_v<_Tag>); + + __internal::__brick_walk1(__first, __last, __f, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy_conditional< - _ExecutionPolicy, __is_random_access_iterator_v<_RandomAccessIterator>> -__pattern_walk1(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Function __f, - _IsVector __is_vector, - /*parallel=*/::std::true_type) +template +void +__pattern_walk1(__parallel_forward_tag, _ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, + _Function __f) { + using __backend_tag = typename __parallel_forward_tag::__backend_tag; + + typedef typename ::std::iterator_traits<_ForwardIterator>::reference _ReferenceType; + auto __func = [&__f](_ReferenceType arg) { __f(arg); }; __internal::__except_handler([&]() { - __par_backend::__parallel_for(::std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__f, __is_vector](_RandomAccessIterator __i, _RandomAccessIterator __j) { - __internal::__brick_walk1(__i, __j, __f, __is_vector); - }); + __par_backend::__parallel_for_each(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + __func); }); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy_conditional<_ExecutionPolicy, - !__is_random_access_iterator_v<_ForwardIterator>> -__pattern_walk1(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Function __f, _IsVector, - /*parallel=*/::std::true_type) +template +void +__pattern_walk1(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Function __f) { - typedef typename ::std::iterator_traits<_ForwardIterator>::reference _ReferenceType; - auto __func = [&__f](_ReferenceType arg) { __f(arg); }; + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + __internal::__except_handler([&]() { - __par_backend::__parallel_for_each(::std::forward<_ExecutionPolicy>(__exec), __first, __last, __func); + __par_backend::__parallel_for(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__f](_RandomAccessIterator __i, _RandomAccessIterator __j) { + __internal::__brick_walk1(__i, __j, __f, _IsVector{}); + }); }); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_walk_brick(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Brick __brick, - /*parallel=*/::std::false_type) noexcept +template +void +__pattern_walk_brick(_Tag, _ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, + _Brick __brick) noexcept { - const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); - __brick(__first, __last, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + __brick(__first, __last, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_walk_brick(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Brick __brick, - /*parallel=*/::std::true_type) +template +void +__pattern_walk_brick(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Brick __brick) { - const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec); + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + __internal::__except_handler([&]() { - __par_backend::__parallel_for(::std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__brick, __is_vector](_RandomAccessIterator __i, _RandomAccessIterator __j) { - __brick(__i, __j, __is_vector); - }); + __par_backend::__parallel_for( + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__brick](_RandomAccessIterator __i, _RandomAccessIterator __j) { __brick(__i, __j, _IsVector{}); }); }); } @@ -214,45 +217,45 @@ __brick_walk1_n(_RandomAccessIterator __first, _DifferenceType __n, _Function __ return __unseq_backend::__simd_walk_1(__first, __n, __f); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_walk1_n(_ExecutionPolicy&&, _ForwardIterator __first, _Size __n, _Function __f, _IsVector __is_vector, - /*is_parallel=*/::std::false_type) noexcept +template +_ForwardIterator +__pattern_walk1_n(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _Size __n, _Function __f) noexcept { - return __internal::__brick_walk1_n(__first, __n, __f, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_walk1_n(__first, __n, __f, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_walk1_n(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Size __n, _Function __f, - _IsVector __is_vector, - /*is_parallel=*/::std::true_type) +template +_RandomAccessIterator +__pattern_walk1_n(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Size __n, + _Function __f) { - oneapi::dpl::__internal::__pattern_walk1(::std::forward<_ExecutionPolicy>(__exec), __first, __first + __n, __f, - __is_vector, ::std::true_type()); + oneapi::dpl::__internal::__pattern_walk1(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __first + __n, + __f); return __first + __n; } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_walk_brick_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, _Brick __brick, - /*is_parallel=*/::std::false_type) noexcept +template +_ForwardIterator +__pattern_walk_brick_n(_Tag, _ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, _Brick __brick) noexcept { - const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); - return __brick(__first, __n, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __brick(__first, __n, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_walk_brick_n(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Size __n, _Brick __brick, - /*is_parallel=*/::std::true_type) +template +_RandomAccessIterator +__pattern_walk_brick_n(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Size __n, + _Brick __brick) { - const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec); + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + return __internal::__except_handler([&]() { - __par_backend::__parallel_for(::std::forward<_ExecutionPolicy>(__exec), __first, __first + __n, - [__brick, __is_vector](_RandomAccessIterator __i, _RandomAccessIterator __j) { - __brick(__i, __j - __i, __is_vector); - }); + __par_backend::__parallel_for( + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __first + __n, + [__brick](_RandomAccessIterator __i, _RandomAccessIterator __j) { __brick(__i, __j - __i, _IsVector{}); }); return __first + __n; }); } @@ -299,38 +302,41 @@ __brick_walk2_n(_RandomAccessIterator1 __first1, _Size __n, _RandomAccessIterato return __unseq_backend::__simd_walk_2(__first1, __n, __first2, __f); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator2> -__pattern_walk2(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _Function __f, _IsVector __is_vector, /*parallel=*/::std::false_type) noexcept +template +_ForwardIterator2 +__pattern_walk2(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _Function __f) noexcept { - return __internal::__brick_walk2(__first1, __last1, __first2, __f, __is_vector); + static_assert(__is_serial_tag_v<_Tag>); + + return __internal::__brick_walk2(__first1, __last1, __first2, __f, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy_conditional< - _ExecutionPolicy, __is_random_access_iterator_v<_RandomAccessIterator1, _RandomAccessIterator2>, - _RandomAccessIterator2> -__pattern_walk2(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _Function __f, _IsVector __is_vector, /*parallel=*/::std::true_type) +template +_RandomAccessIterator2 +__pattern_walk2(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _Function __f) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + return __internal::__except_handler([&]() { __par_backend::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - [__f, __first1, __first2, __is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { - __internal::__brick_walk2(__i, __j, __first2 + (__i - __first1), __f, __is_vector); + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, + [__f, __first1, __first2](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + __internal::__brick_walk2(__i, __j, __first2 + (__i - __first1), __f, _IsVector{}); }); return __first2 + (__last1 - __first1); }); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy_conditional< - _ExecutionPolicy, !__is_random_access_iterator_v<_ForwardIterator1, _ForwardIterator2>, _ForwardIterator2> -__pattern_walk2(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Function __f, _IsVector, /*parallel=*/::std::true_type) +template +_ForwardIterator2 +__pattern_walk2(__parallel_forward_tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _ForwardIterator1 __last1, _ForwardIterator2 __first2, _Function __f) { + using __backend_tag = typename __parallel_forward_tag::__backend_tag; + return __internal::__except_handler([&]() { using _iterator_tuple = zip_forward_iterator<_ForwardIterator1, _ForwardIterator2>; auto __begin = _iterator_tuple(__first1, __first2); @@ -339,7 +345,7 @@ __pattern_walk2(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardI typedef typename ::std::iterator_traits<_ForwardIterator1>::reference _ReferenceType1; typedef typename ::std::iterator_traits<_ForwardIterator2>::reference _ReferenceType2; - __par_backend::__parallel_for_each(::std::forward<_ExecutionPolicy>(__exec), __begin, __end, + __par_backend::__parallel_for_each(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __begin, __end, [&__f](::std::tuple<_ReferenceType1, _ReferenceType2> __val) { __f(::std::get<0>(__val), ::std::get<1>(__val)); }); @@ -352,51 +358,50 @@ __pattern_walk2(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardI }); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator2> -__pattern_walk2_n(_ExecutionPolicy&&, _ForwardIterator1 __first1, _Size __n, _ForwardIterator2 __first2, _Function __f, - _IsVector __is_vector, /*parallel=*/::std::false_type) noexcept +template +_ForwardIterator2 +__pattern_walk2_n(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _Size __n, _ForwardIterator2 __first2, + _Function __f) noexcept { - return __internal::__brick_walk2_n(__first1, __n, __first2, __f, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_walk2_n(__first1, __n, __first2, __f, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator2> -__pattern_walk2_n(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _Size __n, - _RandomAccessIterator2 __first2, _Function __f, _IsVector __is_vector, /*parallel=*/::std::true_type) +template +_RandomAccessIterator2 +__pattern_walk2_n(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _Size __n, _RandomAccessIterator2 __first2, _Function __f) { - return __internal::__pattern_walk2(::std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, __first2, - __f, __is_vector, ::std::true_type()); + return __internal::__pattern_walk2(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, + __first2, __f); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator2> -__pattern_walk2_brick(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Brick __brick, /*parallel=*/::std::false_type) noexcept +template +_ForwardIterator2 +__pattern_walk2_brick(_Tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _Brick __brick) noexcept { - const auto __is_vector = - __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec); - return __brick(__first1, __last1, __first2, __is_vector); + static_assert(__is_serial_tag_v<_Tag>); + + return __brick(__first1, __last1, __first2, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy_conditional< - _ExecutionPolicy, __is_random_access_iterator_v<_RandomAccessIterator1, _RandomAccessIterator2>, - _RandomAccessIterator2> -__pattern_walk2_brick(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _Brick __brick, /*parallel=*/::std::true_type) +template +_RandomAccessIterator2 +__pattern_walk2_brick(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _Brick __brick) { - const auto __is_vector = - __internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator1, _RandomAccessIterator2>( - __exec); + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; return __except_handler([&]() { __par_backend::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - [&__is_vector, __first1, __first2, __brick](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { - __brick(__i, __j, __first2 + (__i - __first1), __is_vector); + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, + [__first1, __first2, __brick](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + __brick(__i, __j, __first2 + (__i - __first1), _IsVector{}); }); return __first2 + (__last1 - __first1); }); @@ -404,11 +409,12 @@ __pattern_walk2_brick(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1 //TODO: it postponed till adding more or less effective parallel implementation template -oneapi::dpl::__internal::__enable_if_host_execution_policy_conditional< - _ExecutionPolicy, !__is_random_access_iterator_v<_ForwardIterator1, _ForwardIterator2>, _ForwardIterator2> -__pattern_walk2_brick(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Brick __brick, /*parallel=*/::std::true_type) +_ForwardIterator2 +__pattern_walk2_brick(__parallel_forward_tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _ForwardIterator1 __last1, _ForwardIterator2 __first2, _Brick __brick) { + using __backend_tag = typename __parallel_forward_tag::__backend_tag; + using _iterator_tuple = zip_forward_iterator<_ForwardIterator1, _ForwardIterator2>; auto __begin = _iterator_tuple(__first1, __first2); auto __end = _iterator_tuple(__last1, /*dummy parameter*/ _ForwardIterator2()); @@ -417,7 +423,7 @@ __pattern_walk2_brick(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Fo typedef typename ::std::iterator_traits<_ForwardIterator2>::reference _ReferenceType2; return __except_handler([&]() { - __par_backend::__parallel_for_each(::std::forward<_ExecutionPolicy>(__exec), __begin, __end, + __par_backend::__parallel_for_each(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __begin, __end, [__brick](::std::tuple<_ReferenceType1, _ReferenceType2> __val) { __brick(::std::get<0>(__val), ::std::forward<_ReferenceType2>(::std::get<1>(__val))); @@ -431,33 +437,33 @@ __pattern_walk2_brick(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Fo }); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator2> -__pattern_walk2_brick_n(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _Size __n, - _RandomAccessIterator2 __first2, _Brick __brick, /*parallel=*/::std::true_type) +template +_RandomAccessIterator2 +__pattern_walk2_brick_n(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _Size __n, _RandomAccessIterator2 __first2, _Brick __brick) { - const auto __is_vector = - __internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator1, _RandomAccessIterator2>( - __exec); + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; return __except_handler([&]() { __par_backend::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, - [&__is_vector, __first1, __first2, __brick](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { - __brick(__i, __j - __i, __first2 + (__i - __first1), __is_vector); + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, + [__first1, __first2, __brick](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + __brick(__i, __j - __i, __first2 + (__i - __first1), _IsVector{}); }); return __first2 + __n; }); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator2> -__pattern_walk2_brick_n(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Size __n, _ForwardIterator2 __first2, - _Brick __brick, /*parallel=*/::std::false_type) noexcept +template +_ForwardIterator2 +__pattern_walk2_brick_n(_Tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Size __n, + _ForwardIterator2 __first2, _Brick __brick) noexcept { - const auto __is_vector = - __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec); - return __brick(__first1, __n, __first2, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __brick(__first1, __n, __first2, typename _Tag::__is_vector{}); } //------------------------------------------------------------------------ @@ -483,46 +489,45 @@ __brick_walk3(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _ return __unseq_backend::__simd_walk_3(__first1, __last1 - __first1, __first2, __first3, __f); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator3> -__pattern_walk3(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator3 __first3, _Function __f, _IsVector __is_vector, - /*parallel=*/::std::false_type) noexcept +template +_ForwardIterator3 +__pattern_walk3(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator3 __first3, _Function __f) noexcept { - return __internal::__brick_walk3(__first1, __last1, __first2, __first3, __f, __is_vector); + static_assert(__is_serial_tag_v<_Tag>); + + return __internal::__brick_walk3(__first1, __last1, __first2, __first3, __f, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy_conditional< - _ExecutionPolicy, - __is_random_access_iterator_v<_RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator3>, - _RandomAccessIterator3> -__pattern_walk3(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator3 __first3, _Function __f, _IsVector __is_vector, - /*parallel=*/::std::true_type) +template +_RandomAccessIterator3 +__pattern_walk3(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator3 __first3, + _Function __f) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + return __internal::__except_handler([&]() { __par_backend::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - [__f, __first1, __first2, __first3, __is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, + [__f, __first1, __first2, __first3](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { __internal::__brick_walk3(__i, __j, __first2 + (__i - __first1), __first3 + (__i - __first1), __f, - __is_vector); + _IsVector{}); }); return __first3 + (__last1 - __first1); }); } template -oneapi::dpl::__internal::__enable_if_host_execution_policy_conditional< - _ExecutionPolicy, !__is_random_access_iterator_v<_ForwardIterator1, _ForwardIterator2, _ForwardIterator3>, - _ForwardIterator3> -__pattern_walk3(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator3 __first3, _Function __f, _IsVector, - /*parallel=*/::std::true_type) + class _Function> +_ForwardIterator3 +__pattern_walk3(__parallel_forward_tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator3 __first3, _Function __f) { + using __backend_tag = typename __parallel_forward_tag::__backend_tag; + return __internal::__except_handler([&]() { using _iterator_tuple = zip_forward_iterator<_ForwardIterator1, _ForwardIterator2, _ForwardIterator3>; auto __begin = _iterator_tuple(__first1, __first2, __first3); @@ -533,7 +538,7 @@ __pattern_walk3(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardI typedef typename ::std::iterator_traits<_ForwardIterator2>::reference _ReferenceType2; typedef typename ::std::iterator_traits<_ForwardIterator3>::reference _ReferenceType3; - __par_backend::__parallel_for_each(::std::forward<_ExecutionPolicy>(__exec), __begin, __end, + __par_backend::__parallel_for_each(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __begin, __end, [&](::std::tuple<_ReferenceType1, _ReferenceType2, _ReferenceType3> __val) { __f(::std::get<0>(__val), ::std::get<1>(__val), ::std::get<2>(__val)); }); @@ -550,26 +555,28 @@ __pattern_walk3(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardI // transform_if //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator2> -__pattern_walk2_transform_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Function __func, _IsVector __is_vector, - _IsParallel __is_parallel) noexcept +template +_ForwardIterator2 +__pattern_walk2_transform_if(_Tag __tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _ForwardIterator1 __last1, _ForwardIterator2 __first2, _Function __func) noexcept { - return __pattern_walk2(::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __func, __is_vector, - __is_parallel); + static_assert(__is_host_dispatch_tag_v<_Tag>); + + return __pattern_walk2(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __func); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator3> -__pattern_walk3_transform_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator3 __first3, _Function __func, - _IsVector __is_vector, _IsParallel __is_parallel) noexcept +template +_ForwardIterator3 +__pattern_walk3_transform_if(_Tag __tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator3 __first3, + _Function __func) noexcept { - return __pattern_walk3(::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __first3, __func, - __is_vector, __is_parallel); + static_assert(__is_host_dispatch_tag_v<_Tag>); + + return __pattern_walk3(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __first3, + __func); } //------------------------------------------------------------------------ @@ -596,32 +603,32 @@ __brick_equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _ .first == __last1; } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_equal(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _BinaryPredicate __p, _IsVector __is_vector, /* is_parallel = */ - ::std::false_type) noexcept +template +bool +__pattern_equal(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __p) noexcept { - return __internal::__brick_equal(__first1, __last1, __first2, __last2, __p, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_equal(__first1, __last1, __first2, __last2, __p, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_equal(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __p, - _IsVector __is_vector, /*is_parallel=*/::std::true_type) +template +bool +__pattern_equal(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, + _BinaryPredicate __p) { if (__last1 - __first1 != __last2 - __first2) return false; return __internal::__except_handler([&]() { return !__internal::__parallel_or( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - [__first1, __first2, __p, __is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + __tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, + [__first1, __first2, __p](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { return !__internal::__brick_equal(__i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1), - __p, __is_vector); + __p, _IsVector{}); }); }); } @@ -647,27 +654,27 @@ __brick_equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _ .first == __last1; } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_equal(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _BinaryPredicate __p, _IsVector __is_vector, /* is_parallel = */ ::std::false_type) noexcept +template +bool +__pattern_equal(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _BinaryPredicate __p) noexcept { - return __internal::__brick_equal(__first1, __last1, __first2, __p, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_equal(__first1, __last1, __first2, __p, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_equal(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _BinaryPredicate __p, _IsVector __is_vector, - /*is_parallel=*/::std::true_type) +template +bool +__pattern_equal(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _BinaryPredicate __p) { return __internal::__except_handler([&]() { return !__internal::__parallel_or( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - [__first1, __first2, __p, __is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { - return !__internal::__brick_equal(__i, __j, __first2 + (__i - __first1), __p, __is_vector); + __tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, + [__first1, __first2, __p](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + return !__internal::__brick_equal(__i, __j, __first2 + (__i - __first1), __p, _IsVector{}); }); }); } @@ -694,27 +701,28 @@ __brick_find_if(_RandomAccessIterator __first, _RandomAccessIterator __last, _Pr [&__pred](_RandomAccessIterator __it, _SizeType __i) { return __pred(__it[__i]); }); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_find_if(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, - _IsVector __is_vector, - /*is_parallel=*/::std::false_type) noexcept +template +_ForwardIterator +__pattern_find_if(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred) noexcept { - return __internal::__brick_find_if(__first, __last, __pred, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_find_if(__first, __last, __pred, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_find_if(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Predicate __pred, _IsVector __is_vector, - /*is_parallel=*/::std::true_type) +template +_RandomAccessIterator +__pattern_find_if(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Predicate __pred) { return __except_handler([&]() { - return __parallel_find(::std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__pred, __is_vector](_RandomAccessIterator __i, _RandomAccessIterator __j) { - return __brick_find_if(__i, __j, __pred, __is_vector); - }, - ::std::true_type{}); + return __parallel_find( + __tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__pred](_RandomAccessIterator __i, _RandomAccessIterator __j) { + return __brick_find_if(__i, __j, __pred, _IsVector{}); + }, + ::std::true_type{}); }); } @@ -836,40 +844,39 @@ __brick_find_end(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, return __find_subrange(__first, __last, __last, __s_first, __s_last, __pred, false, ::std::true_type()); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator1> -__pattern_find_end(_ExecutionPolicy&&, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, - _ForwardIterator2 __s_last, _BinaryPredicate __pred, _IsVector __is_vector, - /*is_parallel=*/::std::false_type) noexcept +template +_ForwardIterator1 +__pattern_find_end(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first, _ForwardIterator1 __last, + _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred) noexcept { - return __internal::__brick_find_end(__first, __last, __s_first, __s_last, __pred, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_find_end(__first, __last, __s_first, __s_last, __pred, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator1> -__pattern_find_end(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, _RandomAccessIterator1 __last, - _RandomAccessIterator2 __s_first, _RandomAccessIterator2 __s_last, _BinaryPredicate __pred, - _IsVector __is_vector, /*is_parallel=*/::std::true_type) +template +_RandomAccessIterator1 +__pattern_find_end(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, _RandomAccessIterator2 __s_first, _RandomAccessIterator2 __s_last, + _BinaryPredicate __pred) { if (__last - __first == __s_last - __s_first) { - const bool __res = __internal::__pattern_equal(::std::forward<_ExecutionPolicy>(__exec), __first, __last, - __s_first, __pred, __is_vector, ::std::true_type()); + const bool __res = __internal::__pattern_equal(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + __s_first, __pred); return __res ? __first : __last; } else { return __internal::__except_handler([&]() { - return __internal::__parallel_find(::std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__last, __s_first, __s_last, __pred, - __is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { - return __internal::__find_subrange(__i, __j, __last, __s_first, - __s_last, __pred, false, - __is_vector); - }, - ::std::false_type{}); + return __internal::__parallel_find( + __tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__last, __s_first, __s_last, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + return __internal::__find_subrange(__i, __j, __last, __s_first, __s_last, __pred, false, + _IsVector{}); + }, + ::std::false_type{}); }); } } @@ -893,28 +900,29 @@ __brick_find_first_of(_ForwardIterator1 __first, _ForwardIterator1 __last, _Forw return __unseq_backend::__simd_find_first_of(__first, __last, __s_first, __s_last, __pred); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator1> -__pattern_find_first_of(_ExecutionPolicy&&, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred, - _IsVector __is_vector, /*is_parallel=*/::std::false_type) noexcept +template +_ForwardIterator1 +__pattern_find_first_of(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first, _ForwardIterator1 __last, + _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred) noexcept { - return __internal::__brick_find_first_of(__first, __last, __s_first, __s_last, __pred, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_find_first_of(__first, __last, __s_first, __s_last, __pred, + typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator1> -__pattern_find_first_of(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred, - _IsVector __is_vector, /*is_parallel=*/::std::true_type) +template +_RandomAccessIterator1 +__pattern_find_first_of(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, _RandomAccessIterator2 __s_first, + _RandomAccessIterator2 __s_last, _BinaryPredicate __pred) { return __internal::__except_handler([&]() { return __internal::__parallel_find( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__s_first, __s_last, &__pred, __is_vector](_ForwardIterator1 __i, _ForwardIterator1 __j) { - return __internal::__brick_find_first_of(__i, __j, __s_first, __s_last, __pred, __is_vector); + __tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__s_first, __s_last, &__pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + return __internal::__brick_find_first_of(__i, __j, __s_first, __s_last, __pred, _IsVector{}); }, ::std::true_type{}); }); @@ -939,41 +947,39 @@ __brick_search(_ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIter return __internal::__find_subrange(__first, __last, __last, __s_first, __s_last, __pred, true, ::std::true_type()); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator1> -__pattern_search(_ExecutionPolicy&&, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, - _ForwardIterator2 __s_last, _BinaryPredicate __pred, _IsVector __is_vector, - /*is_parallel=*/::std::false_type) noexcept +template +_ForwardIterator1 +__pattern_search(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first, _ForwardIterator1 __last, + _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred) noexcept { - return __internal::__brick_search(__first, __last, __s_first, __s_last, __pred, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_search(__first, __last, __s_first, __s_last, __pred, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator1> -__pattern_search(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, _RandomAccessIterator1 __last, - _RandomAccessIterator2 __s_first, _RandomAccessIterator2 __s_last, _BinaryPredicate __pred, - _IsVector __is_vector, - /*is_parallel=*/::std::true_type) +template +_RandomAccessIterator1 +__pattern_search(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, _RandomAccessIterator2 __s_first, _RandomAccessIterator2 __s_last, + _BinaryPredicate __pred) { if (__last - __first == __s_last - __s_first) { - const bool __res = __internal::__pattern_equal(::std::forward<_ExecutionPolicy>(__exec), __first, __last, - __s_first, __pred, __is_vector, ::std::true_type()); + const bool __res = __internal::__pattern_equal(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + __s_first, __pred); return __res ? __first : __last; } else { return __internal::__except_handler([&]() { - return __internal::__parallel_find(::std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__last, __s_first, __s_last, __pred, - __is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { - return __internal::__find_subrange(__i, __j, __last, __s_first, - __s_last, __pred, true, - __is_vector); - }, - ::std::true_type{}); + return __internal::__parallel_find( + __tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__last, __s_first, __s_last, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + return __internal::__find_subrange(__i, __j, __last, __s_first, __s_last, __pred, true, + _IsVector{}); + }, + /*_IsFirst=*/::std::true_type{}); }); } } @@ -997,38 +1003,36 @@ __brick_search_n(_RandomAccessIterator __first, _RandomAccessIterator __last, _S return __internal::__find_subrange(__first, __last, __last, __count, __value, __pred, ::std::true_type()); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_search_n(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Size __count, - const _Tp& __value, _BinaryPredicate __pred, _IsVector __is_vector, - /*is_parallel=*/::std::false_type) noexcept +template +_ForwardIterator +__pattern_search_n(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Size __count, + const _Tp& __value, _BinaryPredicate __pred) noexcept { - return __internal::__brick_search_n(__first, __last, __count, __value, __pred, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_search_n(__first, __last, __count, __value, __pred, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_search_n(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Size __count, const _Tp& __value, _BinaryPredicate __pred, _IsVector __is_vector, - /*is_parallel=*/::std::true_type) +template +_RandomAccessIterator +__pattern_search_n(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Size __count, const _Tp& __value, _BinaryPredicate __pred) { if (static_cast<_Size>(__last - __first) == __count) { - const bool __result = !__internal::__pattern_any_of( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, - [&__value, &__pred](const _Tp& __val) { return !__pred(__val, __value); }, __is_vector, - /*is_parallel*/ ::std::true_type()); + const bool __result = + !__internal::__pattern_any_of(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + [&__value, &__pred](const _Tp& __val) { return !__pred(__val, __value); }); return __result ? __first : __last; } else { - return __internal::__except_handler([&__exec, __first, __last, __count, &__value, __pred, __is_vector]() { + return __internal::__except_handler([__tag, &__exec, __first, __last, __count, &__value, __pred]() { return __internal::__parallel_find( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__last, __count, &__value, __pred, __is_vector](_RandomAccessIterator __i, _RandomAccessIterator __j) { - return __internal::__find_subrange(__i, __j, __last, __count, __value, __pred, __is_vector); + __tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__last, __count, &__value, __pred](_RandomAccessIterator __i, _RandomAccessIterator __j) { + return __internal::__find_subrange(__i, __j, __last, __count, __value, __pred, _IsVector{}); }, ::std::true_type{}); }); @@ -1042,8 +1046,9 @@ __pattern_search_n(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Ra // clear that doing so is worth the trouble and extra layers of call chain. // Sometimes a little duplication for sake of regularity is better than the alternative. -template -struct __brick_copy_n<_ExecutionPolicy, oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy>> +template +struct __brick_copy_n<_Tag, _ExecutionPolicy, + ::std::enable_if_t>> { template _RandomAccessIterator2 @@ -1067,10 +1072,9 @@ struct __brick_copy_n<_ExecutionPolicy, oneapi::dpl::__internal::__enable_if_hos // copy //------------------------------------------------------------------------ -template -struct __brick_copy<_ExecutionPolicy, oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy>> +template +struct __brick_copy<_Tag, _ExecutionPolicy, ::std::enable_if_t<__is_host_dispatch_tag_v<_Tag>>> { - template _RandomAccessIterator2 operator()(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, @@ -1100,10 +1104,9 @@ struct __brick_copy<_ExecutionPolicy, oneapi::dpl::__internal::__enable_if_host_ // move //------------------------------------------------------------------------ -template -struct __brick_move<_ExecutionPolicy, oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy>> +template +struct __brick_move<_Tag, _ExecutionPolicy, ::std::enable_if_t<__is_host_dispatch_tag_v<_Tag>>> { - template _RandomAccessIterator2 operator()(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, @@ -1120,14 +1123,17 @@ struct __brick_move<_ExecutionPolicy, oneapi::dpl::__internal::__enable_if_host_ { return ::std::move(__first, __last, __result); } -}; -template -struct __brick_move_destroy; + template + void + operator()(_ReferenceType1&& __val, _ReferenceType2&& __result) const + { + __result = ::std::move(__val); + } +}; -template -struct __brick_move_destroy<_ExecutionPolicy, - oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy>> +template >> +struct __brick_move_destroy { template _RandomAccessIterator2 @@ -1295,48 +1301,51 @@ __brick_partition_by_mask(_RandomAccessIterator1 __first, _RandomAccessIterator1 #endif } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_copy_if(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, - _UnaryPredicate __pred, _IsVector __is_vector, /*parallel=*/::std::false_type) noexcept +template +_OutputIterator +__pattern_copy_if(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, + _UnaryPredicate __pred) noexcept { - return __internal::__brick_copy_if(__first, __last, __result, __pred, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_copy_if(__first, __last, __result, __pred, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator2> -__pattern_copy_if(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, _RandomAccessIterator1 __last, - _RandomAccessIterator2 __result, _UnaryPredicate __pred, _IsVector __is_vector, - /*parallel=*/::std::true_type) +template +_RandomAccessIterator2 +__pattern_copy_if(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, _UnaryPredicate __pred) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + typedef typename ::std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; const _DifferenceType __n = __last - __first; if (_DifferenceType(1) < __n) { - __par_backend::__buffer<_ExecutionPolicy, bool> __mask_buf(__n); - return __internal::__except_handler([&__exec, __n, __first, __result, __is_vector, __pred, &__mask_buf]() { + __par_backend::__buffer<_ExecutionPolicy, bool> __mask_buf(__exec, __n); + return __internal::__except_handler([&__exec, __n, __first, __result, __pred, &__mask_buf]() { bool* __mask = __mask_buf.get(); _DifferenceType __m{}; __par_backend::__parallel_strict_scan( - ::std::forward<_ExecutionPolicy>(__exec), __n, _DifferenceType(0), + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __n, _DifferenceType(0), [=](_DifferenceType __i, _DifferenceType __len) { // Reduce return __internal::__brick_calc_mask_1<_DifferenceType>(__first + __i, __first + (__i + __len), - __mask + __i, __pred, __is_vector) + __mask + __i, __pred, _IsVector{}) .first; }, ::std::plus<_DifferenceType>(), // Combine [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { // Scan __internal::__brick_copy_by_mask( __first + __i, __first + (__i + __len), __result + __initial, __mask + __i, - [](_RandomAccessIterator1 __x, _RandomAccessIterator2 __z) { *__z = *__x; }, __is_vector); + [](_RandomAccessIterator1 __x, _RandomAccessIterator2 __z) { *__z = *__x; }, _IsVector{}); }, [&__m](_DifferenceType __total) { __m = __total; }); return __result + __m; }); } // trivial sequence - use serial algorithm - return __internal::__brick_copy_if(__first, __last, __result, __pred, __is_vector); + return __internal::__brick_copy_if(__first, __last, __result, __pred, _IsVector{}); } //------------------------------------------------------------------------ @@ -1358,22 +1367,22 @@ __brick_count(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pr return ::std::count_if(__first, __last, __pred); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy< - _ExecutionPolicy, typename ::std::iterator_traits<_ForwardIterator>::difference_type> -__pattern_count(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, - /* is_parallel */ ::std::false_type, _IsVector __is_vector) noexcept +template +typename ::std::iterator_traits<_ForwardIterator>::difference_type +__pattern_count(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) noexcept { - return __internal::__brick_count(__first, __last, __pred, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_count(__first, __last, __pred, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy< - _ExecutionPolicy, typename ::std::iterator_traits<_RandomAccessIterator>::difference_type> -__pattern_count(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Predicate __pred, - /* is_parallel */ ::std::true_type, _IsVector __is_vector) +template +typename ::std::iterator_traits<_RandomAccessIterator>::difference_type +__pattern_count(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Predicate __pred) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + typedef typename ::std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType; //trivial pre-checks @@ -1382,9 +1391,10 @@ __pattern_count(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Rando return __internal::__except_handler([&]() { return __par_backend::__parallel_reduce( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, _SizeType(0), - [__pred, __is_vector](_RandomAccessIterator __begin, _RandomAccessIterator __end, _SizeType __value) - -> _SizeType { return __value + __internal::__brick_count(__begin, __end, __pred, __is_vector); }, + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, _SizeType(0), + [__pred](_RandomAccessIterator __begin, _RandomAccessIterator __end, _SizeType __value) -> _SizeType { + return __value + __internal::__brick_count(__begin, __end, __pred, _IsVector{}); + }, ::std::plus<_SizeType>()); }); } @@ -1410,32 +1420,36 @@ __brick_unique(_RandomAccessIterator __first, _RandomAccessIterator __last, _Bin return ::std::unique(__first, __last, __pred); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_unique(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred, - _IsVector __is_vector, /*is_parallel=*/::std::false_type) noexcept +template +_ForwardIterator +__pattern_unique(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _BinaryPredicate __pred) noexcept { - return __internal::__brick_unique(__first, __last, __pred, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_unique(__first, __last, __pred, typename _Tag::__is_vector{}); } // That function is shared between two algorithms - remove_if (__pattern_remove_if) and unique (pattern unique). But a mask calculation is different. // So, a caller passes _CalcMask brick into remove_elements. -template -_ForwardIterator -__remove_elements(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _CalcMask __calc_mask, - _IsVector __is_vector) +template +_RandomAccessIterator +__remove_elements(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _CalcMask __calc_mask) { - typedef typename ::std::iterator_traits<_ForwardIterator>::difference_type _DifferenceType; - typedef typename ::std::iterator_traits<_ForwardIterator>::value_type _Tp; + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + + typedef typename ::std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType; + typedef typename ::std::iterator_traits<_RandomAccessIterator>::value_type _Tp; _DifferenceType __n = __last - __first; - __par_backend::__buffer<_ExecutionPolicy, bool> __mask_buf(__n); + __par_backend::__buffer<_ExecutionPolicy, bool> __mask_buf(__exec, __n); // 1. find a first iterator that should be removed return __internal::__except_handler([&]() { bool* __mask = __mask_buf.get(); _DifferenceType __min = __par_backend::__parallel_reduce( - ::std::forward<_ExecutionPolicy>(__exec), _DifferenceType(0), __n, __n, - [__first, __mask, &__calc_mask, __is_vector](_DifferenceType __i, _DifferenceType __j, - _DifferenceType __local_min) -> _DifferenceType { + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), _DifferenceType(0), __n, __n, + [__first, __mask, &__calc_mask](_DifferenceType __i, _DifferenceType __j, + _DifferenceType __local_min) -> _DifferenceType { // Create mask __calc_mask(__mask + __i, __mask + __j, __first + __i); @@ -1445,8 +1459,8 @@ __remove_elements(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardI return __local_min; } // find first iterator that should be removed - bool* __result = __internal::__brick_find_if(__mask + __i, __mask + __j, - [](bool __val) { return !__val; }, __is_vector); + bool* __result = __internal::__brick_find_if( + __mask + __i, __mask + __j, [](bool __val) { return !__val; }, _IsVector{}); if (__result - __mask == __j) { return __local_min; @@ -1465,45 +1479,45 @@ __remove_elements(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardI __n -= __min; __first += __min; - __par_backend::__buffer<_ExecutionPolicy, _Tp> __buf(__n); + __par_backend::__buffer<_ExecutionPolicy, _Tp> __buf(__exec, __n); _Tp* __result = __buf.get(); __mask += __min; _DifferenceType __m{}; // 2. Elements that doesn't satisfy pred are moved to result __par_backend::__parallel_strict_scan( - ::std::forward<_ExecutionPolicy>(__exec), __n, _DifferenceType(0), - [__mask, __is_vector](_DifferenceType __i, _DifferenceType __len) { - return __internal::__brick_count(__mask + __i, __mask + __i + __len, [](bool __val) { return __val; }, - __is_vector); + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __n, _DifferenceType(0), + [__mask](_DifferenceType __i, _DifferenceType __len) { + return __internal::__brick_count( + __mask + __i, __mask + __i + __len, [](bool __val) { return __val; }, _IsVector{}); }, ::std::plus<_DifferenceType>(), [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { __internal::__brick_copy_by_mask( __first + __i, __first + __i + __len, __result + __initial, __mask + __i, - [](_ForwardIterator __x, _Tp* __z) { + [](_RandomAccessIterator __x, _Tp* __z) { if constexpr (::std::is_trivial_v<_Tp>) *__z = ::std::move(*__x); else ::new (::std::addressof(*__z)) _Tp(::std::move(*__x)); }, - __is_vector); + _IsVector{}); }, [&__m](_DifferenceType __total) { __m = __total; }); // 3. Elements from result are moved to [first, last) - __par_backend::__parallel_for(::std::forward<_ExecutionPolicy>(__exec), __result, __result + __m, - [__result, __first, __is_vector](_Tp* __i, _Tp* __j) { - __brick_move_destroy<_ExecutionPolicy>{}(__i, __j, __first + (__i - __result), - __is_vector); + __par_backend::__parallel_for(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __result, + __result + __m, [__result, __first](_Tp* __i, _Tp* __j) { + __brick_move_destroy<__parallel_tag<_IsVector>, _ExecutionPolicy>{}( + __i, __j, __first + (__i - __result), _IsVector{}); }); return __first + __m; }); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_unique(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _BinaryPredicate __pred, _IsVector __is_vector, /*is_parallel=*/::std::true_type) +template +_RandomAccessIterator +__pattern_unique(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _BinaryPredicate __pred) { typedef typename ::std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType; @@ -1514,16 +1528,15 @@ __pattern_unique(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Rand if (__first + 1 == __last || __first + 2 == __last) { // Trivial sequence - use serial algorithm - return __internal::__brick_unique(__first, __last, __pred, __is_vector); + return __internal::__brick_unique(__first, __last, __pred, _IsVector{}); } return __internal::__remove_elements( - ::std::forward<_ExecutionPolicy>(__exec), ++__first, __last, - [&__pred, __is_vector](bool* __b, bool* __e, _RandomAccessIterator __it) { + __tag, ::std::forward<_ExecutionPolicy>(__exec), ++__first, __last, + [&__pred](bool* __b, bool* __e, _RandomAccessIterator __it) { __internal::__brick_walk3( __b, __e, __it - 1, __it, - [&__pred](bool& __x, _ReferenceType __y, _ReferenceType __z) { __x = !__pred(__y, __z); }, __is_vector); - }, - __is_vector); + [&__pred](bool& __x, _ReferenceType __y, _ReferenceType __z) { __x = !__pred(__y, __z); }, _IsVector{}); + }); } //------------------------------------------------------------------------ @@ -1550,13 +1563,14 @@ __brick_unique_copy(_RandomAccessIterator1 __first, _RandomAccessIterator1 __las #endif } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_unique_copy(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, - _BinaryPredicate __pred, _IsVector __is_vector, /*parallel=*/::std::false_type) noexcept +template +_OutputIterator +__pattern_unique_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _OutputIterator __result, _BinaryPredicate __pred) noexcept { - return __internal::__brick_unique_copy(__first, __last, __result, __pred, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_unique_copy(__first, __last, __result, __pred, typename _Tag::__is_vector{}); } template @@ -1581,25 +1595,26 @@ __brick_calc_mask_2(_RandomAccessIterator __first, _RandomAccessIterator __last, return __unseq_backend::__simd_calc_mask_2(__first, __last - __first, __mask, __pred); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator2> -__pattern_unique_copy(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, _RandomAccessIterator1 __last, - _RandomAccessIterator2 __result, _BinaryPredicate __pred, _IsVector __is_vector, - /*parallel=*/::std::true_type) +template +_RandomAccessIterator2 +__pattern_unique_copy(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, _BinaryPredicate __pred) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + typedef typename ::std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; const _DifferenceType __n = __last - __first; if (_DifferenceType(2) < __n) { - __par_backend::__buffer<_ExecutionPolicy, bool> __mask_buf(__n); + __par_backend::__buffer<_ExecutionPolicy, bool> __mask_buf(__exec, __n); if (_DifferenceType(2) < __n) { - return __internal::__except_handler([&__exec, __n, __first, __result, __pred, __is_vector, &__mask_buf]() { + return __internal::__except_handler([&__exec, __n, __first, __result, __pred, &__mask_buf]() { bool* __mask = __mask_buf.get(); _DifferenceType __m{}; __par_backend::__parallel_strict_scan( - ::std::forward<_ExecutionPolicy>(__exec), __n, _DifferenceType(0), + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __n, _DifferenceType(0), [=](_DifferenceType __i, _DifferenceType __len) -> _DifferenceType { // Reduce _DifferenceType __extra = 0; if (__i == 0) @@ -1612,7 +1627,7 @@ __pattern_unique_copy(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, ++__extra; } return __internal::__brick_calc_mask_2<_DifferenceType>(__first + __i, __first + (__i + __len), - __mask + __i, __pred, __is_vector) + + __mask + __i, __pred, _IsVector{}) + __extra; }, ::std::plus<_DifferenceType>(), // Combine @@ -1620,7 +1635,7 @@ __pattern_unique_copy(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, // Phase 2 is same as for __pattern_copy_if __internal::__brick_copy_by_mask( __first + __i, __first + (__i + __len), __result + __initial, __mask + __i, - [](_RandomAccessIterator1 __x, _RandomAccessIterator2 __z) { *__z = *__x; }, __is_vector); + [](_RandomAccessIterator1 __x, _RandomAccessIterator2 __z) { *__z = *__x; }, _IsVector{}); }, [&__m](_DifferenceType __total) { __m = __total; }); return __result + __m; @@ -1628,7 +1643,7 @@ __pattern_unique_copy(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, } } // trivial sequence - use serial algorithm - return __internal::__brick_unique_copy(__first, __last, __result, __pred, __is_vector); + return __internal::__brick_unique_copy(__first, __last, __result, __pred, _IsVector{}); } //------------------------------------------------------------------------ @@ -1685,27 +1700,29 @@ __brick_reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, _Ra }); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_reverse(_ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last, - _IsVector _is_vector, - /*is_parallel=*/::std::false_type) noexcept +template +void +__pattern_reverse(_Tag, _ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last) noexcept { - __internal::__brick_reverse(__first, __last, _is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + __internal::__brick_reverse(__first, __last, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_reverse(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _IsVector __is_vector, /*is_parallel=*/::std::true_type) +template +void +__pattern_reverse(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + if (__first == __last) return; __par_backend::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), __first, __first + (__last - __first) / 2, - [__is_vector, __first, __last](_RandomAccessIterator __inner_first, _RandomAccessIterator __inner_last) { - __internal::__brick_reverse(__inner_first, __inner_last, __last - (__inner_first - __first), __is_vector); + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __first + (__last - __first) / 2, + [__first, __last](_RandomAccessIterator __inner_first, _RandomAccessIterator __inner_last) { + __internal::__brick_reverse(__inner_first, __inner_last, __last - (__inner_first - __first), _IsVector{}); }); } @@ -1733,31 +1750,34 @@ __brick_reverse_copy(_RandomAccessIterator1 __first, _RandomAccessIterator1 __la __d_first, [](_ReferenceType1 __x, _ReferenceType2 __y) { __y = __x; }); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_reverse_copy(_ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last, - _OutputIterator __d_first, _IsVector __is_vector, /*is_parallel=*/::std::false_type) noexcept +template +_OutputIterator +__pattern_reverse_copy(_Tag, _ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last, + _OutputIterator __d_first) noexcept { - return __internal::__brick_reverse_copy(__first, __last, __d_first, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_reverse_copy(__first, __last, __d_first, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator2> -__pattern_reverse_copy(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, _RandomAccessIterator1 __last, - _RandomAccessIterator2 __d_first, _IsVector __is_vector, /*is_parallel=*/::std::true_type) +template +_RandomAccessIterator2 +__pattern_reverse_copy(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, _RandomAccessIterator2 __d_first) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + auto __len = __last - __first; if (__len == 0) return __d_first; - __par_backend::__parallel_for(::std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__is_vector, __first, __len, __d_first](_RandomAccessIterator1 __inner_first, - _RandomAccessIterator1 __inner_last) { - __internal::__brick_reverse_copy(__inner_first, __inner_last, - __d_first + (__len - (__inner_last - __first)), - __is_vector); - }); + __par_backend::__parallel_for( + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__first, __len, __d_first](_RandomAccessIterator1 __inner_first, _RandomAccessIterator1 __inner_last) { + __internal::__brick_reverse_copy(__inner_first, __inner_last, + __d_first + (__len - (__inner_last - __first)), _IsVector{}); + }); return __d_first + __len; } @@ -1813,43 +1833,47 @@ __brick_rotate(_RandomAccessIterator __first, _RandomAccessIterator __middle, _R return __ret; } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_rotate(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, - _IsVector __is_vector, /*is_parallel=*/::std::false_type) noexcept +template +_ForwardIterator +__pattern_rotate(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __middle, + _ForwardIterator __last) noexcept { - return __internal::__brick_rotate(__first, __middle, __last, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_rotate(__first, __middle, __last, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_rotate(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __middle, - _RandomAccessIterator __last, _IsVector __is_vector, /*is_parallel=*/::std::true_type) +template +_RandomAccessIterator +__pattern_rotate(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __middle, _RandomAccessIterator __last) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + typedef typename ::std::iterator_traits<_RandomAccessIterator>::value_type _Tp; auto __n = __last - __first; auto __m = __middle - __first; if (__m <= __n / 2) { - __par_backend::__buffer<_ExecutionPolicy, _Tp> __buf(__n - __m); - return __internal::__except_handler([&__exec, __n, __m, __first, __middle, __last, __is_vector, &__buf]() { + __par_backend::__buffer<_ExecutionPolicy, _Tp> __buf(__exec, __n - __m); + return __internal::__except_handler([&__exec, __n, __m, __first, __middle, __last, &__buf]() { _Tp* __result = __buf.get(); - __par_backend::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), __middle, __last, - [__middle, __result, __is_vector](_RandomAccessIterator __b, _RandomAccessIterator __e) { - __internal::__brick_uninitialized_move(__b, __e, __result + (__b - __middle), __is_vector); - }); - - __par_backend::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), __first, __middle, - [__last, __middle, __is_vector](_RandomAccessIterator __b, _RandomAccessIterator __e) { - __internal::__brick_move<_ExecutionPolicy>{}(__b, __e, __b + (__last - __middle), __is_vector); - }); - - __par_backend::__parallel_for(::std::forward<_ExecutionPolicy>(__exec), __result, __result + (__n - __m), - [__first, __result, __is_vector](_Tp* __b, _Tp* __e) { - __brick_move_destroy<_ExecutionPolicy>{}( - __b, __e, __first + (__b - __result), __is_vector); + __par_backend::__parallel_for(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __middle, __last, + [__middle, __result](_RandomAccessIterator __b, _RandomAccessIterator __e) { + __internal::__brick_uninitialized_move( + __b, __e, __result + (__b - __middle), _IsVector{}); + }); + + __par_backend::__parallel_for(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __middle, + [__last, __middle](_RandomAccessIterator __b, _RandomAccessIterator __e) { + __internal::__brick_move<__parallel_tag<_IsVector>, _ExecutionPolicy>{}( + __b, __e, __b + (__last - __middle), _IsVector{}); + }); + + __par_backend::__parallel_for(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __result, + __result + (__n - __m), [__first, __result](_Tp* __b, _Tp* __e) { + __brick_move_destroy<__parallel_tag<_IsVector>, _ExecutionPolicy>{}( + __b, __e, __first + (__b - __result), _IsVector{}); }); return __first + (__last - __middle); @@ -1857,25 +1881,25 @@ __pattern_rotate(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Rand } else { - __par_backend::__buffer<_ExecutionPolicy, _Tp> __buf(__m); - return __internal::__except_handler([&__exec, __n, __m, __first, __middle, __last, __is_vector, &__buf]() { + __par_backend::__buffer<_ExecutionPolicy, _Tp> __buf(__exec, __m); + return __internal::__except_handler([&__exec, __n, __m, __first, __middle, __last, &__buf]() { _Tp* __result = __buf.get(); - __par_backend::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), __first, __middle, - [__first, __result, __is_vector](_RandomAccessIterator __b, _RandomAccessIterator __e) { - __internal::__brick_uninitialized_move(__b, __e, __result + (__b - __first), __is_vector); - }); - - __par_backend::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), __middle, __last, - [__first, __middle, __is_vector](_RandomAccessIterator __b, _RandomAccessIterator __e) { - __internal::__brick_move<_ExecutionPolicy>{}(__b, __e, __first + (__b - __middle), __is_vector); - }); - - __par_backend::__parallel_for(::std::forward<_ExecutionPolicy>(__exec), __result, __result + __m, - [__n, __m, __first, __result, __is_vector](_Tp* __b, _Tp* __e) { - __brick_move_destroy<_ExecutionPolicy>{}( - __b, __e, __first + ((__n - __m) + (__b - __result)), __is_vector); + __par_backend::__parallel_for(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __middle, + [__first, __result](_RandomAccessIterator __b, _RandomAccessIterator __e) { + __internal::__brick_uninitialized_move( + __b, __e, __result + (__b - __first), _IsVector{}); + }); + + __par_backend::__parallel_for(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __middle, __last, + [__first, __middle](_RandomAccessIterator __b, _RandomAccessIterator __e) { + __internal::__brick_move<__parallel_tag<_IsVector>, _ExecutionPolicy>{}( + __b, __e, __first + (__b - __middle), _IsVector{}); + }); + + __par_backend::__parallel_for(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __result, + __result + __m, [__n, __m, __first, __result](_Tp* __b, _Tp* __e) { + __brick_move_destroy<__parallel_tag<_IsVector>, _ExecutionPolicy>{}( + __b, __e, __first + ((__n - __m) + (__b - __result)), _IsVector{}); }); return __first + (__last - __middle); @@ -1887,59 +1911,64 @@ __pattern_rotate(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Rand // rotate_copy //------------------------------------------------------------------------ -template +template _OutputIterator -__brick_rotate_copy(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, - _OutputIterator __result, /*__is_vector=*/::std::false_type) noexcept +__brick_rotate_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __middle, + _ForwardIterator __last, _OutputIterator __result) noexcept { + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + return ::std::rotate_copy(__first, __middle, __last, __result); } -template +template _RandomAccessIterator2 -__brick_rotate_copy(_ExecutionPolicy&&, _RandomAccessIterator1 __first, _RandomAccessIterator1 __middle, - _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, - /*__is_vector=*/::std::true_type) noexcept +__brick_rotate_copy(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __middle, _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result) noexcept { - _RandomAccessIterator2 __res = __brick_copy<_ExecutionPolicy>{}(__middle, __last, __result, ::std::true_type()); - return __internal::__brick_copy<_ExecutionPolicy>{}(__first, __middle, __res, ::std::true_type()); + _RandomAccessIterator2 __res = + __brick_copy<__parallel_tag<_IsVector>, _ExecutionPolicy>{}(__middle, __last, __result); + return __internal::__brick_copy<__parallel_tag<_IsVector>, _ExecutionPolicy>{}(__first, __middle, __res); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_rotate_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __middle, - _ForwardIterator __last, _OutputIterator __result, _IsVector __is_vector, - /*is_parallel=*/::std::false_type) noexcept +template +_OutputIterator +__pattern_rotate_copy(_Tag __tag, _ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __middle, + _ForwardIterator __last, _OutputIterator __result) noexcept { - return __internal::__brick_rotate_copy(::std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, - __result, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_rotate_copy(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, + __result); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator2> -__pattern_rotate_copy(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, _RandomAccessIterator1 __middle, - _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, _IsVector __is_vector, - /*is_parallel=*/::std::true_type) +template +_RandomAccessIterator2 +__pattern_rotate_copy(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __middle, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + __par_backend::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__first, __last, __middle, __result, __is_vector](_RandomAccessIterator1 __b, _RandomAccessIterator1 __e) { - __internal::__brick_copy<_ExecutionPolicy> __copy{}; + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__first, __last, __middle, __result](_RandomAccessIterator1 __b, _RandomAccessIterator1 __e) { + __internal::__brick_copy<__parallel_tag<_IsVector>, _ExecutionPolicy> __copy{}; if (__b > __middle) { - __copy(__b, __e, __result + (__b - __middle), __is_vector); + __copy(__b, __e, __result + (__b - __middle), _IsVector{}); } else { _RandomAccessIterator2 __new_result = __result + ((__last - __middle) + (__b - __first)); if (__e < __middle) { - __copy(__b, __e, __new_result, __is_vector); + __copy(__b, __e, __new_result, _IsVector{}); } else { - __copy(__b, __middle, __new_result, __is_vector); - __copy(__middle, __e, __result, __is_vector); + __copy(__b, __middle, __new_result, _IsVector{}); + __copy(__middle, __e, __result, _IsVector{}); } } }); @@ -1985,19 +2014,23 @@ __brick_is_partitioned(_RandomAccessIterator __first, _RandomAccessIterator __la } } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_is_partitioned(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred, - _IsVector __is_vector, /*is_parallel=*/::std::false_type) noexcept +template +bool +__pattern_is_partitioned(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _UnaryPredicate __pred) noexcept { - return __internal::__brick_is_partitioned(__first, __last, __pred, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_is_partitioned(__first, __last, __pred, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_is_partitioned(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _UnaryPredicate __pred, _IsVector __is_vector, /*is_parallel=*/::std::true_type) +template +bool +__pattern_is_partitioned(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _UnaryPredicate __pred) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + //trivial pre-checks if (__first == __last) return true; @@ -2035,9 +2068,9 @@ __pattern_is_partitioned(_ExecutionPolicy&& __exec, _RandomAccessIterator __firs const _ReduceType __identity{__not_init, __last}; _ReduceType __result = __par_backend::__parallel_reduce( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __identity, - [&__pred, __combine, __is_vector](_RandomAccessIterator __i, _RandomAccessIterator __j, - _ReduceType __value) -> _ReduceType { + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __identity, + [&__pred, __combine](_RandomAccessIterator __i, _RandomAccessIterator __j, + _ReduceType __value) -> _ReduceType { if (__value.__val == __broken) return _ReduceType{__broken, __i}; @@ -2047,11 +2080,11 @@ __pattern_is_partitioned(_ExecutionPolicy&& __exec, _RandomAccessIterator __firs { // find first element that don't satisfy pred _RandomAccessIterator __x = - __internal::__brick_find_if(__i + 1, __j, __not_pred<_UnaryPredicate&>(__pred), __is_vector); + __internal::__brick_find_if(__i + 1, __j, __not_pred<_UnaryPredicate&>(__pred), _IsVector{}); if (__x != __j) { // find first element after "x" that satisfy pred - _RandomAccessIterator __y = __internal::__brick_find_if(__x + 1, __j, __pred, __is_vector); + _RandomAccessIterator __y = __internal::__brick_find_if(__x + 1, __j, __pred, _IsVector{}); // if it was found then range isn't partitioned by pred if (__y != __j) return _ReduceType{__broken, __i}; @@ -2065,7 +2098,7 @@ __pattern_is_partitioned(_ExecutionPolicy&& __exec, _RandomAccessIterator __firs { // if first element doesn't satisfy pred // then we should find the first element that satisfy pred. // If we found it then range isn't partitioned by pred - if (__internal::__brick_find_if(__i + 1, __j, __pred, __is_vector) != __j) + if (__internal::__brick_find_if(__i + 1, __j, __pred, _IsVector{}) != __j) return _ReduceType{__broken, __i}; __res = _ReduceType{__all_false, __i}; @@ -2111,19 +2144,22 @@ __brick_partition(_RandomAccessIterator __first, _RandomAccessIterator __last, _ return ::std::partition(__first, __last, __pred); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_partition(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred, - _IsVector __is_vector, /*is_parallel=*/::std::false_type) noexcept +template +_ForwardIterator +__pattern_partition(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _UnaryPredicate __pred) noexcept { - return __internal::__brick_partition(__first, __last, __pred, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_partition(__first, __last, __pred, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_partition(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _UnaryPredicate __pred, _IsVector __is_vector, /*is_parallel=*/::std::true_type) +template +_RandomAccessIterator +__pattern_partition(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _UnaryPredicate __pred) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; // partitioned range: elements before pivot satisfy pred (true part), // elements after pivot don't satisfy pred (false part) @@ -2138,7 +2174,7 @@ __pattern_partition(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _R _PartitionRange __init{__last, __last, __last}; // lambda for merging two partitioned ranges to one partitioned range - auto __reductor = [&__exec, __is_vector](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange { + auto __reductor = [&__exec](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange { auto __size1 = __val1.__end - __val1.__pivot; auto __size2 = __val2.__pivot - __val2.__begin; auto __new_begin = __val2.__begin - (__val1.__end - __val1.__begin); @@ -2153,10 +2189,10 @@ __pattern_partition(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _R else if (__size2 > __size1) { __par_backend::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), __val1.__pivot, __val1.__pivot + __size1, - [__val1, __val2, __size1, __is_vector](_RandomAccessIterator __i, _RandomAccessIterator __j) { + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __val1.__pivot, __val1.__pivot + __size1, + [__val1, __val2, __size1](_RandomAccessIterator __i, _RandomAccessIterator __j) { __internal::__brick_swap_ranges(__i, __j, (__val2.__pivot - __size1) + (__i - __val1.__pivot), - __is_vector); + _IsVector{}); }); return {__new_begin, __val2.__pivot - __size1, __val2.__end}; } @@ -2164,20 +2200,20 @@ __pattern_partition(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _R else { __par_backend::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), __val1.__pivot, __val1.__pivot + __size2, - [__val1, __val2, __is_vector](_RandomAccessIterator __i, _RandomAccessIterator __j) { - __internal::__brick_swap_ranges(__i, __j, __val2.__begin + (__i - __val1.__pivot), __is_vector); + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __val1.__pivot, __val1.__pivot + __size2, + [__val1, __val2](_RandomAccessIterator __i, _RandomAccessIterator __j) { + __internal::__brick_swap_ranges(__i, __j, __val2.__begin + (__i - __val1.__pivot), _IsVector{}); }); return {__new_begin, __val1.__pivot + __size2, __val2.__end}; } }; _PartitionRange __result = __par_backend::__parallel_reduce( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, - [__pred, __is_vector, __reductor](_RandomAccessIterator __i, _RandomAccessIterator __j, - _PartitionRange __value) -> _PartitionRange { + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, + [__pred, __reductor](_RandomAccessIterator __i, _RandomAccessIterator __j, + _PartitionRange __value) -> _PartitionRange { //1. serial partition - _RandomAccessIterator __pivot = __internal::__brick_partition(__i, __j, __pred, __is_vector); + _RandomAccessIterator __pivot = __internal::__brick_partition(__i, __j, __pred, _IsVector{}); // 2. merging of two ranges (left and right respectively) return __reductor(__value, {__i, __pivot, __j}); @@ -2208,21 +2244,23 @@ __brick_stable_partition(_RandomAccessIterator __first, _RandomAccessIterator __ return ::std::stable_partition(__first, __last, __pred); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _BidirectionalIterator> -__pattern_stable_partition(_ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last, - _UnaryPredicate __pred, _IsVector __is_vector, - /*is_parallelization=*/::std::false_type) noexcept +template +_BidirectionalIterator +__pattern_stable_partition(_Tag, _ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last, + _UnaryPredicate __pred) noexcept { - return __internal::__brick_stable_partition(__first, __last, __pred, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_stable_partition(__first, __last, __pred, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_stable_partition(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _UnaryPredicate __pred, _IsVector __is_vector, - /*is_parallelization=*/::std::true_type) +template +_RandomAccessIterator +__pattern_stable_partition(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _UnaryPredicate __pred) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + // partitioned range: elements before pivot satisfy pred (true part), // elements after pivot don't satisfy pred (false part) struct _PartitionRange @@ -2236,7 +2274,7 @@ __pattern_stable_partition(_ExecutionPolicy&& __exec, _RandomAccessIterator __fi _PartitionRange __init{__last, __last, __last}; // lambda for merging two partitioned ranges to one partitioned range - auto __reductor = [__is_vector](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange { + auto __reductor = [](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange { auto __size1 = __val1.__end - __val1.__pivot; auto __new_begin = __val2.__begin - (__val1.__end - __val1.__begin); @@ -2249,17 +2287,17 @@ __pattern_stable_partition(_ExecutionPolicy&& __exec, _RandomAccessIterator __fi // then we should swap the false part of left range and last part of true part of right range else { - __internal::__brick_rotate(__val1.__pivot, __val2.__begin, __val2.__pivot, __is_vector); + __internal::__brick_rotate(__val1.__pivot, __val2.__begin, __val2.__pivot, _IsVector{}); return {__new_begin, __val2.__pivot - __size1, __val2.__end}; } }; _PartitionRange __result = __par_backend::__parallel_reduce( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, - [&__pred, __is_vector, __reductor](_RandomAccessIterator __i, _RandomAccessIterator __j, - _PartitionRange __value) -> _PartitionRange { + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, + [&__pred, __reductor](_RandomAccessIterator __i, _RandomAccessIterator __j, + _PartitionRange __value) -> _PartitionRange { //1. serial stable_partition - _RandomAccessIterator __pivot = __internal::__brick_stable_partition(__i, __j, __pred, __is_vector); + _RandomAccessIterator __pivot = __internal::__brick_stable_partition(__i, __j, __pred, _IsVector{}); // 2. merging of two ranges (left and right respectively) return __reductor(__value, {__i, __pivot, __j}); @@ -2295,40 +2333,42 @@ __brick_partition_copy(_RandomAccessIterator1 __first, _RandomAccessIterator1 __ #endif } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, - ::std::pair<_OutputIterator1, _OutputIterator2>> -__pattern_partition_copy(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, - _OutputIterator1 __out_true, _OutputIterator2 __out_false, _UnaryPredicate __pred, - _IsVector __is_vector, /*is_parallelization=*/::std::false_type) noexcept +template +::std::pair<_OutputIterator1, _OutputIterator2> +__pattern_partition_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _OutputIterator1 __out_true, _OutputIterator2 __out_false, _UnaryPredicate __pred) noexcept { - return __internal::__brick_partition_copy(__first, __last, __out_true, __out_false, __pred, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_partition_copy(__first, __last, __out_true, __out_false, __pred, + typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, - ::std::pair<_RandomAccessIterator2, _RandomAccessIterator3>> -__pattern_partition_copy(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, _RandomAccessIterator1 __last, - _RandomAccessIterator2 __out_true, _RandomAccessIterator3 __out_false, _UnaryPredicate __pred, - _IsVector __is_vector, /*is_parallelization=*/::std::true_type) +template +::std::pair<_RandomAccessIterator2, _RandomAccessIterator3> +__pattern_partition_copy(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, _RandomAccessIterator2 __out_true, + _RandomAccessIterator3 __out_false, _UnaryPredicate __pred) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + typedef typename ::std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; typedef ::std::pair<_DifferenceType, _DifferenceType> _ReturnType; const _DifferenceType __n = __last - __first; if (_DifferenceType(1) < __n) { - __par_backend::__buffer<_ExecutionPolicy, bool> __mask_buf(__n); - return __internal::__except_handler([&__exec, __n, __first, __out_true, __out_false, __is_vector, __pred, - &__mask_buf]() { + __par_backend::__buffer<_ExecutionPolicy, bool> __mask_buf(__exec, __n); + return __internal::__except_handler([&__exec, __n, __first, __out_true, __out_false, __pred, &__mask_buf]() { bool* __mask = __mask_buf.get(); _ReturnType __m{}; __par_backend::__parallel_strict_scan( - ::std::forward<_ExecutionPolicy>(__exec), __n, ::std::make_pair(_DifferenceType(0), _DifferenceType(0)), + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __n, + ::std::make_pair(_DifferenceType(0), _DifferenceType(0)), [=](_DifferenceType __i, _DifferenceType __len) { // Reduce return __internal::__brick_calc_mask_1<_DifferenceType>(__first + __i, __first + (__i + __len), - __mask + __i, __pred, __is_vector); + __mask + __i, __pred, _IsVector{}); }, [](const _ReturnType& __x, const _ReturnType& __y) -> _ReturnType { return ::std::make_pair(__x.first + __y.first, __x.second + __y.second); @@ -2336,39 +2376,45 @@ __pattern_partition_copy(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __fir [=](_DifferenceType __i, _DifferenceType __len, _ReturnType __initial) { // Scan __internal::__brick_partition_by_mask(__first + __i, __first + (__i + __len), __out_true + __initial.first, __out_false + __initial.second, - __mask + __i, __is_vector); + __mask + __i, _IsVector{}); }, [&__m](_ReturnType __total) { __m = __total; }); return ::std::make_pair(__out_true + __m.first, __out_false + __m.second); }); } // trivial sequence - use serial algorithm - return __internal::__brick_partition_copy(__first, __last, __out_true, __out_false, __pred, __is_vector); + return __internal::__brick_partition_copy(__first, __last, __out_true, __out_false, __pred, _IsVector{}); } //------------------------------------------------------------------------ // sort //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, - _IsVector /*is_vector*/, /*is_parallel=*/::std::false_type, _IsMoveConstructible) noexcept +template +void +__pattern_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, + _IsMoveConstructible) noexcept { + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + ::std::sort(__first, __last, __comp); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, - _IsVector /*is_vector*/, /*is_parallel=*/::std::true_type, /*is_move_constructible=*/::std::true_type) +template +void +__pattern_sort(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp, + /*is_move_constructible=*/::std::true_type) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + __internal::__except_handler([&]() { - __par_backend::__parallel_stable_sort(::std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, - [](_RandomAccessIterator __first, _RandomAccessIterator __last, - _Compare __comp) { ::std::sort(__first, __last, __comp); }, - __last - __first); + __par_backend::__parallel_stable_sort( + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, + [](_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + ::std::sort(__first, __last, __comp); + }, + __last - __first); }); } @@ -2376,24 +2422,30 @@ __pattern_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Random // stable_sort //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, - _IsVector /*is_vector*/, /*is_parallel=*/::std::false_type) noexcept +template +void +__pattern_stable_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) noexcept { + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + ::std::stable_sort(__first, __last, __comp); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Compare __comp, _IsVector /*is_vector*/, /*is_parallel=*/::std::true_type) +template +void +__pattern_stable_sort(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + __internal::__except_handler([&]() { - __par_backend::__parallel_stable_sort(::std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, - [](_RandomAccessIterator __first, _RandomAccessIterator __last, - _Compare __comp) { ::std::stable_sort(__first, __last, __comp); }, - __last - __first); + __par_backend::__parallel_stable_sort( + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, + [](_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + ::std::stable_sort(__first, __last, __comp); + }, + __last - __first); }); } @@ -2401,41 +2453,47 @@ __pattern_stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, // sort_by_key //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_sort_by_key(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __keys_first, - _RandomAccessIterator1 __keys_last, _RandomAccessIterator2 __values_first, _Compare __comp, - _IsVector /*vector=*/, /*is_parallel=*/::std::false_type) noexcept +template +void +__pattern_sort_by_key(_Tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __keys_first, + _RandomAccessIterator1 __keys_last, _RandomAccessIterator2 __values_first, + _Compare __comp) noexcept { + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + auto __beg = oneapi::dpl::make_zip_iterator(__keys_first, __values_first); auto __end = __beg + (__keys_last - __keys_first); - auto __cmp_f = - [__comp](const auto& __a, const auto& __b) { return __comp(::std::get<0>(__a), ::std::get<0>(__b)); }; + auto __cmp_f = [__comp](const auto& __a, const auto& __b) { + return __comp(::std::get<0>(__a), ::std::get<0>(__b)); + }; ::std::sort(__beg, __end, __cmp_f); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_sort_by_key(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __keys_first, - _RandomAccessIterator1 __keys_last, _RandomAccessIterator2 __values_first, _Compare __comp, - _IsVector /*vector=*/, /*is_parallel=*/::std::true_type) +template +void +__pattern_sort_by_key(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __keys_first, + _RandomAccessIterator1 __keys_last, _RandomAccessIterator2 __values_first, _Compare __comp) { - static_assert(::std::is_move_constructible_v::value_type> - && ::std::is_move_constructible_v::value_type>, + static_assert( + ::std::is_move_constructible_v::value_type> && + ::std::is_move_constructible_v::value_type>, "The keys and values should be move constructible in case of parallel execution."); auto __beg = oneapi::dpl::make_zip_iterator(__keys_first, __values_first); auto __end = __beg + (__keys_last - __keys_first); - auto __cmp_f = - [__comp](const auto& __a, const auto& __b) { return __comp(::std::get<0>(__a), ::std::get<0>(__b)); }; + auto __cmp_f = [__comp](const auto& __a, const auto& __b) { + return __comp(::std::get<0>(__a), ::std::get<0>(__b)); + }; + + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; __internal::__except_handler([&]() { - __par_backend::__parallel_stable_sort(::std::forward<_ExecutionPolicy>(__exec), __beg, __end, __cmp_f, - [](auto __first, auto __last, auto __cmp) - { ::std::sort(__first, __last, __cmp); },__end - __beg); + __par_backend::__parallel_stable_sort( + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __beg, __end, __cmp_f, + [](auto __first, auto __last, auto __cmp) { ::std::sort(__first, __last, __cmp); }, __end - __beg); }); } @@ -2443,27 +2501,30 @@ __pattern_sort_by_key(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __keys_f // partial_sort //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_partial_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __middle, - _RandomAccessIterator __last, _Compare __comp, _IsVector, - /*is_parallel=*/::std::false_type) noexcept +template +void +__pattern_partial_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __middle, + _RandomAccessIterator __last, _Compare __comp) noexcept { + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + ::std::partial_sort(__first, __middle, __last, __comp); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_partial_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __middle, - _RandomAccessIterator __last, _Compare __comp, _IsVector, /*is_parallel=*/::std::true_type) +template +void +__pattern_partial_sort(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + const auto __n = __middle - __first; if (__n == 0) return; __except_handler([&]() { __par_backend::__parallel_stable_sort( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, [__n](_RandomAccessIterator __begin, _RandomAccessIterator __end, _Compare __comp) { if (__n < __end - __begin) ::std::partial_sort(__begin, __begin + __n, __end, __comp); @@ -2478,22 +2539,25 @@ __pattern_partial_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, // partial_sort_copy //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_partial_sort_copy(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, - _RandomAccessIterator __d_first, _RandomAccessIterator __d_last, _Compare __comp, _IsVector, - /*is_parallel=*/::std::false_type) noexcept +template +_RandomAccessIterator +__pattern_partial_sort_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _RandomAccessIterator __d_first, _RandomAccessIterator __d_last, _Compare __comp) noexcept { + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + return ::std::partial_sort_copy(__first, __last, __d_first, __d_last, __comp); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator2> -__pattern_partial_sort_copy(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, _RandomAccessIterator1 __last, - _RandomAccessIterator2 __d_first, _RandomAccessIterator2 __d_last, _Compare __comp, - _IsVector __is_vector, /*is_parallel=*/::std::true_type) +template +_RandomAccessIterator2 +__pattern_partial_sort_copy(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, _RandomAccessIterator2 __d_first, + _RandomAccessIterator2 __d_last, _Compare __comp) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + if (__last == __first || __d_last == __d_first) { return __d_first; @@ -2504,14 +2568,13 @@ __pattern_partial_sort_copy(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __ if (__n2 >= __n1) { __par_backend::__parallel_stable_sort( - ::std::forward<_ExecutionPolicy>(__exec), __d_first, __d_first + __n1, __comp, - [__first, __d_first, __is_vector](_RandomAccessIterator2 __i, _RandomAccessIterator2 __j, - _Compare __comp) { + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __d_first, __d_first + __n1, __comp, + [__first, __d_first](_RandomAccessIterator2 __i, _RandomAccessIterator2 __j, _Compare __comp) { _RandomAccessIterator1 __i1 = __first + (__i - __d_first); _RandomAccessIterator1 __j1 = __first + (__j - __d_first); // 1. Copy elements from input to output - __brick_copy<_ExecutionPolicy>{}(__i1, __j1, __i, __is_vector); + __brick_copy<__parallel_tag<_IsVector>, _ExecutionPolicy>{}(__i1, __j1, __i, _IsVector{}); // 2. Sort elements in output sequence ::std::sort(__i, __j, __comp); }, @@ -2522,38 +2585,39 @@ __pattern_partial_sort_copy(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __ { typedef typename ::std::iterator_traits<_RandomAccessIterator1>::value_type _T1; typedef typename ::std::iterator_traits<_RandomAccessIterator2>::value_type _T2; - __par_backend::__buffer<_ExecutionPolicy, _T1> __buf(__n1); + __par_backend::__buffer<_ExecutionPolicy, _T1> __buf(__exec, __n1); _T1* __r = __buf.get(); - __par_backend::__parallel_stable_sort(::std::forward<_ExecutionPolicy>(__exec), __r, __r + __n1, __comp, - [__n2, __first, __r](_T1* __i, _T1* __j, _Compare __comp) { - _RandomAccessIterator1 __it = __first + (__i - __r); + __par_backend::__parallel_stable_sort( + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __r, __r + __n1, __comp, + [__n2, __first, __r](_T1* __i, _T1* __j, _Compare __comp) { + _RandomAccessIterator1 __it = __first + (__i - __r); - // 1. Copy elements from input to raw memory - for (_T1* __k = __i; __k != __j; ++__k, ++__it) - { - ::new (__k) _T2(*__it); - } + // 1. Copy elements from input to raw memory + for (_T1* __k = __i; __k != __j; ++__k, ++__it) + { + ::new (__k) _T2(*__it); + } - // 2. Sort elements in temporary buffer - if (__n2 < __j - __i) - ::std::partial_sort(__i, __i + __n2, __j, __comp); - else - ::std::sort(__i, __j, __comp); - }, - __n2); + // 2. Sort elements in temporary buffer + if (__n2 < __j - __i) + ::std::partial_sort(__i, __i + __n2, __j, __comp); + else + ::std::sort(__i, __j, __comp); + }, + __n2); // 3. Move elements from temporary buffer to output - __par_backend::__parallel_for(::std::forward<_ExecutionPolicy>(__exec), __r, __r + __n2, - [__r, __d_first, __is_vector](_T1* __i, _T1* __j) { - __brick_move_destroy<_ExecutionPolicy>{}( - __i, __j, __d_first + (__i - __r), __is_vector); + __par_backend::__parallel_for(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __r, __r + __n2, + [__r, __d_first](_T1* __i, _T1* __j) { + __brick_move_destroy<__parallel_tag<_IsVector>, _ExecutionPolicy>{}( + __i, __j, __d_first + (__i - __r), _IsVector{}); }); if constexpr (!::std::is_trivially_destructible_v<_T1>) - __par_backend::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), __r + __n2, __r + __n1, - [__is_vector](_T1* __i, _T1* __j) { __brick_destroy(__i, __j, __is_vector); }); + __par_backend::__parallel_for(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __r + __n2, + __r + __n1, + [](_T1* __i, _T1* __j) { __brick_destroy(__i, __j, _IsVector{}); }); return __d_first + __n2; } @@ -2579,28 +2643,31 @@ __brick_adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _Binary return ::std::adjacent_find(__first, __last, __pred); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_adjacent_find(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred, - /* is_parallel */ ::std::false_type, _IsVector __is_vector, _Semantic) noexcept +template +_ForwardIterator +__pattern_adjacent_find(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _BinaryPredicate __pred, _Semantic) noexcept { - return __internal::__brick_adjacent_find(__first, __last, __pred, __is_vector, _Semantic::value); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_adjacent_find(__first, __last, __pred, typename _Tag::__is_vector{}, _Semantic::value); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_adjacent_find(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _BinaryPredicate __pred, /* is_parallel */ ::std::true_type, _IsVector __is_vector, - _Semantic __or_semantic) +template +_RandomAccessIterator +__pattern_adjacent_find(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _BinaryPredicate __pred, _Semantic __or_semantic) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + if (__last - __first < 2) return __last; return __internal::__except_handler([&]() { return __par_backend::__parallel_reduce( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __last, - [__last, __pred, __is_vector, __or_semantic](_RandomAccessIterator __begin, _RandomAccessIterator __end, - _RandomAccessIterator __value) -> _RandomAccessIterator { + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __last, + [__last, __pred, __or_semantic](_RandomAccessIterator __begin, _RandomAccessIterator __end, + _RandomAccessIterator __value) -> _RandomAccessIterator { // TODO: investigate performance benefits from the use of shared variable for the result, // checking (compare_and_swap idiom) its __value at __first. if (__or_semantic && __value < __last) @@ -2619,7 +2686,7 @@ __pattern_adjacent_find(_ExecutionPolicy&& __exec, _RandomAccessIterator __first //correct the global result iterator if the "brick" returns a local "__last" const _RandomAccessIterator __res = - __internal::__brick_adjacent_find(__begin, __end, __pred, __is_vector, __or_semantic); + __internal::__brick_adjacent_find(__begin, __end, __pred, _IsVector{}, __or_semantic); if (__res < __end) __value = __res; } @@ -2636,20 +2703,20 @@ __pattern_adjacent_find(_ExecutionPolicy&& __exec, _RandomAccessIterator __first // nth_element //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_nth_element(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __nth, - _RandomAccessIterator __last, _Compare __comp, _IsVector, - /*is_parallel=*/::std::false_type) noexcept +template +void +__pattern_nth_element(_Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __nth, + _RandomAccessIterator __last, _Compare __comp) noexcept { + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + ::std::nth_element(__first, __nth, __last, __comp); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_nth_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __nth, - _RandomAccessIterator __last, _Compare __comp, _IsVector __is_vector, - /*is_parallel=*/::std::true_type) +template +void +__pattern_nth_element(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) { if (__first == __last || __nth == __last) { @@ -2661,10 +2728,8 @@ __pattern_nth_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __x; do { - __x = __internal::__pattern_partition(::std::forward<_ExecutionPolicy>(__exec), __first + 1, __last, - [&__comp, __first](const _Tp& __x) { return __comp(__x, *__first); }, - __is_vector, - /*is_parallel=*/::std::true_type()); + __x = __internal::__pattern_partition(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first + 1, __last, + [&__comp, __first](const _Tp& __x) { return __comp(__x, *__first); }); --__x; if (__x != __first) { @@ -2692,8 +2757,8 @@ __pattern_nth_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, //------------------------------------------------------------------------ // fill, fill_n //------------------------------------------------------------------------ -template -struct __brick_fill<_Tp, _ExecutionPolicy, oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy>> +template +struct __brick_fill<_Tag, _ExecutionPolicy, _Tp, ::std::enable_if_t<__is_host_dispatch_tag_v<_Tag>>> { const _Tp& __value; @@ -2714,33 +2779,34 @@ struct __brick_fill<_Tp, _ExecutionPolicy, oneapi::dpl::__internal::__enable_if_ } }; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_fill(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, - /*is_parallel=*/::std::false_type, _IsVector __is_vector) noexcept +template +void +__pattern_fill(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) noexcept { - __internal::__brick_fill<_Tp, _ExecutionPolicy>{__value}(__first, __last, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + __internal::__brick_fill<_Tag, _ExecutionPolicy, _Tp>{__value}(__first, __last, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_fill(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - const _Tp& __value, - /*is_parallel=*/::std::true_type, _IsVector __is_vector) +template +_RandomAccessIterator +__pattern_fill(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, const _Tp& __value) { - return __internal::__except_handler([&__exec, __first, __last, &__value, __is_vector]() { - __par_backend::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, - [&__value, __is_vector](_RandomAccessIterator __begin, _RandomAccessIterator __end) { - __internal::__brick_fill<_Tp, _ExecutionPolicy>{__value}(__begin, __end, __is_vector); - }); + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + + return __internal::__except_handler([&__exec, __first, __last, &__value]() { + __par_backend::__parallel_for(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + [&__value](_RandomAccessIterator __begin, _RandomAccessIterator __end) { + __internal::__brick_fill<__parallel_tag<_IsVector>, _ExecutionPolicy, _Tp>{ + __value}(__begin, __end, _IsVector{}); + }); return __last; }); } -template -struct __brick_fill_n<_Tp, _ExecutionPolicy, - oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy>> +template +struct __brick_fill_n<_Tag, _ExecutionPolicy, _Tp, ::std::enable_if_t<__is_host_dispatch_tag_v<_Tag>>> { const _Tp& __value; @@ -2761,21 +2827,23 @@ struct __brick_fill_n<_Tp, _ExecutionPolicy, } }; -template +template _OutputIterator -__pattern_fill_n(_ExecutionPolicy&&, _OutputIterator __first, _Size __count, const _Tp& __value, - /*is_parallel=*/::std::false_type, _IsVector __is_vector) noexcept +__pattern_fill_n(_Tag, _ExecutionPolicy&&, _OutputIterator __first, _Size __count, const _Tp& __value) noexcept { - return __internal::__brick_fill_n<_Tp, _ExecutionPolicy>{__value}(__first, __count, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_fill_n<_Tag, _ExecutionPolicy, _Tp>{__value}(__first, __count, + typename _Tag::__is_vector{}); } -template +template _RandomAccessIterator -__pattern_fill_n(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Size __count, const _Tp& __value, - /*is_parallel=*/::std::true_type, _IsVector __is_vector) +__pattern_fill_n(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _Size __count, const _Tp& __value) { - return __internal::__pattern_fill(::std::forward<_ExecutionPolicy>(__exec), __first, __first + __count, __value, - ::std::true_type(), __is_vector); + return __internal::__pattern_fill(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __first + __count, + __value); } //------------------------------------------------------------------------ @@ -2797,24 +2865,26 @@ __brick_generate(_ForwardIterator __first, _ForwardIterator __last, _Generator _ ::std::generate(__first, __last, __g); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_generate(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Generator __g, - /*is_parallel=*/::std::false_type, _IsVector __is_vector) noexcept +template +void +__pattern_generate(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Generator __g) noexcept { - __internal::__brick_generate(__first, __last, __g, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + __internal::__brick_generate(__first, __last, __g, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_generate(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Generator __g, - /*is_parallel=*/::std::true_type, _IsVector __is_vector) +template +_RandomAccessIterator +__pattern_generate(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Generator __g) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + return __internal::__except_handler([&]() { - __par_backend::__parallel_for(::std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__g, __is_vector](_RandomAccessIterator __begin, _RandomAccessIterator __end) { - __internal::__brick_generate(__begin, __end, __g, __is_vector); + __par_backend::__parallel_for(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__g](_RandomAccessIterator __begin, _RandomAccessIterator __end) { + __internal::__brick_generate(__begin, __end, __g, _IsVector{}); }); return __last; }); @@ -2835,23 +2905,24 @@ __brick_generate_n(OutputIterator __first, Size __count, _Generator __g, /* is_v return ::std::generate_n(__first, __count, __g); } -template +template _OutputIterator -__pattern_generate_n(_ExecutionPolicy&&, _OutputIterator __first, _Size __count, _Generator __g, - /*is_parallel=*/::std::false_type, _IsVector __is_vector) noexcept +__pattern_generate_n(_Tag, _ExecutionPolicy&&, _OutputIterator __first, _Size __count, _Generator __g) noexcept { - return __internal::__brick_generate_n(__first, __count, __g, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_generate_n(__first, __count, __g, typename _Tag::__is_vector{}); } -template +template _RandomAccessIterator -__pattern_generate_n(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Size __count, _Generator __g, - /*is_parallel=*/::std::true_type, _IsVector __is_vector) +__pattern_generate_n(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _Size __count, _Generator __g) { static_assert(__is_random_access_iterator_v<_RandomAccessIterator>, "Pattern-brick error. Should be a random access iterator."); - return __internal::__pattern_generate(::std::forward<_ExecutionPolicy>(__exec), __first, __first + __count, __g, - ::std::true_type(), __is_vector); + return __internal::__pattern_generate(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __first + __count, + __g); } //------------------------------------------------------------------------ @@ -2878,34 +2949,35 @@ __brick_remove_if(_RandomAccessIterator __first, _RandomAccessIterator __last, _ #endif } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_remove_if(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred, - _IsVector __is_vector, /*is_parallel*/ ::std::false_type) noexcept +template +_ForwardIterator +__pattern_remove_if(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _UnaryPredicate __pred) noexcept { - return __internal::__brick_remove_if(__first, __last, __pred, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_remove_if(__first, __last, __pred, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_remove_if(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _UnaryPredicate __pred, _IsVector __is_vector, /*is_parallel*/ ::std::true_type) +template +_RandomAccessIterator +__pattern_remove_if(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _UnaryPredicate __pred) { typedef typename ::std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType; if (__first == __last || __first + 1 == __last) { // Trivial sequence - use serial algorithm - return __internal::__brick_remove_if(__first, __last, __pred, __is_vector); + return __internal::__brick_remove_if(__first, __last, __pred, _IsVector{}); } return __internal::__remove_elements( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, - [&__pred, __is_vector](bool* __b, bool* __e, _RandomAccessIterator __it) { - __internal::__brick_walk2(__b, __e, __it, [&__pred](bool& __x, _ReferenceType __y) { __x = !__pred(__y); }, - __is_vector); - }, - __is_vector); + __tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + [&__pred](bool* __b, bool* __e, _RandomAccessIterator __it) { + __internal::__brick_walk2( + __b, __e, __it, [&__pred](bool& __x, _ReferenceType __y) { __x = !__pred(__y); }, _IsVector{}); + }); } //------------------------------------------------------------------------ @@ -2931,29 +3003,34 @@ __brick_merge(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _ return ::std::merge(__first1, __last1, __first2, __last2, __d_first, __comp); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_merge(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _OutputIterator __d_first, _Compare __comp, _IsVector __is_vector, - /* is_parallel = */ ::std::false_type) noexcept +template +_OutputIterator +__pattern_merge(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __d_first, + _Compare __comp) noexcept { - return __internal::__brick_merge(__first1, __last1, __first2, __last2, __d_first, __comp, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_merge(__first1, __last1, __first2, __last2, __d_first, __comp, + typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator3> -__pattern_merge(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _RandomAccessIterator3 __d_first, - _Compare __comp, _IsVector __is_vector, /* is_parallel = */ ::std::true_type) +template +_RandomAccessIterator3 +__pattern_merge(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, + _RandomAccessIterator3 __d_first, _Compare __comp) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + __par_backend::__parallel_merge( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __d_first, __comp, - [__is_vector](_RandomAccessIterator1 __f1, _RandomAccessIterator1 __l1, _RandomAccessIterator2 __f2, - _RandomAccessIterator2 __l2, _RandomAccessIterator3 __f3, _Compare __comp) { - return __internal::__brick_merge(__f1, __l1, __f2, __l2, __f3, __comp, __is_vector); - }); + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __d_first, + __comp, + [](_RandomAccessIterator1 __f1, _RandomAccessIterator1 __l1, _RandomAccessIterator2 __f2, + _RandomAccessIterator2 __l2, _RandomAccessIterator3 __f3, + _Compare __comp) { return __internal::__brick_merge(__f1, __l1, __f2, __l2, __f3, __comp, _IsVector{}); }); return __d_first + (__last1 - __first1) + (__last2 - __first2); } @@ -2977,28 +3054,31 @@ __brick_inplace_merge(_RandomAccessIterator __first, _RandomAccessIterator __mid ::std::inplace_merge(__first, __middle, __last, __comp); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_inplace_merge(_ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __middle, - _BidirectionalIterator __last, _Compare __comp, _IsVector __is_vector, - /* is_parallel = */ ::std::false_type) noexcept +template +void +__pattern_inplace_merge(_Tag, _ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __middle, + _BidirectionalIterator __last, _Compare __comp) noexcept { - __internal::__brick_inplace_merge(__first, __middle, __last, __comp, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + __internal::__brick_inplace_merge(__first, __middle, __last, __comp, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_inplace_merge(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __middle, - _RandomAccessIterator __last, _Compare __comp, _IsVector __is_vector, - /*is_parallel=*/::std::true_type) +template +void +__pattern_inplace_merge(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + if (__first == __last || __first == __middle || __middle == __last) { return; } + typedef typename ::std::iterator_traits<_RandomAccessIterator>::value_type _Tp; auto __n = __last - __first; - __par_backend::__buffer<_ExecutionPolicy, _Tp> __buf(__n); + __par_backend::__buffer<_ExecutionPolicy, _Tp> __buf(__exec, __n); _Tp* __r = __buf.get(); __internal::__except_handler([&]() { auto __move_values = [](_RandomAccessIterator __x, _Tp* __z) { @@ -3009,11 +3089,11 @@ __pattern_inplace_merge(_ExecutionPolicy&& __exec, _RandomAccessIterator __first }; auto __move_sequences = [](_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Tp* __first2) { - return __internal::__brick_uninitialized_move(__first1, __last1, __first2, _IsVector()); + return __internal::__brick_uninitialized_move(__first1, __last1, __first2, _IsVector{}); }; __par_backend::__parallel_merge( - ::std::forward<_ExecutionPolicy>(__exec), __first, __middle, __middle, __last, __r, __comp, + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __middle, __middle, __last, __r, __comp, [__n, __move_values, __move_sequences](_RandomAccessIterator __f1, _RandomAccessIterator __l1, _RandomAccessIterator __f2, _RandomAccessIterator __l2, _Tp* __f3, _Compare __comp) { @@ -3021,10 +3101,11 @@ __pattern_inplace_merge(_ExecutionPolicy&& __exec, _RandomAccessIterator __first __move_sequences, __move_sequences); return __f3 + (__l1 - __f1) + (__l2 - __f2); }); - __par_backend::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), __r, __r + __n, [__r, __first, __is_vector](_Tp* __i, _Tp* __j) { - __brick_move_destroy<_ExecutionPolicy>{}(__i, __j, __first + (__i - __r), __is_vector); - }); + __par_backend::__parallel_for(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __r, __r + __n, + [__r, __first](_Tp* __i, _Tp* __j) { + __brick_move_destroy<__parallel_tag<_IsVector>, _ExecutionPolicy>{}( + __i, __j, __first + (__i - __r), _IsVector{}); + }); }); } @@ -3032,21 +3113,22 @@ __pattern_inplace_merge(_ExecutionPolicy&& __exec, _RandomAccessIterator __first // includes //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_includes(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp, _IsVector, - /*is_parallel=*/::std::false_type) noexcept +template +bool +__pattern_includes(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp) noexcept { + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + return ::std::includes(__first1, __last1, __first2, __last2, __comp); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_includes(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _Compare __comp, _IsVector, - /*is_parallel=*/::std::true_type) +template +bool +__pattern_includes(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, + _Compare __comp) { if (__first2 == __last2) return true; @@ -3068,14 +3150,14 @@ __pattern_includes(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _ return __internal::__except_handler([&]() { return !__internal::__parallel_or( - ::std::forward<_ExecutionPolicy>(__exec), __first2, __last2, + __tag, ::std::forward<_ExecutionPolicy>(__exec), __first2, __last2, [__first1, __last1, __first2, __last2, &__comp](_RandomAccessIterator2 __i, _RandomAccessIterator2 __j) { assert(__j > __i); //assert(__j - __i > 1); //1. moving boundaries to "consume" subsequence of equal elements auto __is_equal_sorted = [&__comp](_RandomAccessIterator2 __a, _RandomAccessIterator2 __b) -> bool { - //enough one call of __comp due to compared couple belongs to one sorted sequience + //enough one call of __comp due to compared couple belongs to one sorted sequence return !__comp(*__a, *__b); }; @@ -3105,14 +3187,16 @@ __pattern_includes(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _ inline constexpr auto __set_algo_cut_off = 1000; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__parallel_set_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp, - _SizeFunction __size_func, _SetOP __set_op, _IsVector __is_vector) +template +_OutputIterator +__parallel_set_op(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, + _OutputIterator __result, _Compare __comp, _SizeFunction __size_func, _SetOP __set_op) { - typedef typename ::std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType; + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + + typedef typename ::std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; typedef typename ::std::iterator_traits<_OutputIterator>::value_type _T; struct _SetRange @@ -3128,23 +3212,23 @@ __parallel_set_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forwar const _DifferenceType __n1 = __last1 - __first1; const _DifferenceType __n2 = __last2 - __first2; - __par_backend::__buffer<_ExecutionPolicy, _T> __buf(__size_func(__n1, __n2)); + __par_backend::__buffer<_ExecutionPolicy, _T> __buf(__exec, __size_func(__n1, __n2)); - return __internal::__except_handler([&__exec, __n1, __first1, __last1, __first2, __last2, __result, __is_vector, - __comp, __size_func, __set_op, &__buf]() { + return __internal::__except_handler([&__exec, __n1, __first1, __last1, __first2, __last2, __result, __comp, + __size_func, __set_op, &__buf]() { auto __tmp_memory = __buf.get(); _DifferenceType __m{}; auto __scan = [=](_DifferenceType, _DifferenceType, const _SetRange& __s) { // Scan if (!__s.empty()) - __brick_move_destroy<_ExecutionPolicy>{}(__tmp_memory + __s.__buf_pos, - __tmp_memory + (__s.__buf_pos + __s.__len), - __result + __s.__pos, __is_vector); + __brick_move_destroy<__parallel_tag<_IsVector>, _ExecutionPolicy>{}( + __tmp_memory + __s.__buf_pos, __tmp_memory + (__s.__buf_pos + __s.__len), __result + __s.__pos, + _IsVector{}); }; __par_backend::__parallel_strict_scan( - ::std::forward<_ExecutionPolicy>(__exec), __n1, _SetRange{0, 0, 0}, //-1, 0}, - [=](_DifferenceType __i, _DifferenceType __len) { // Reduce + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __n1, _SetRange{0, 0, 0}, //-1, 0}, + [=](_DifferenceType __i, _DifferenceType __len) { // Reduce //[__b; __e) - a subrange of the first sequence, to reduce - _ForwardIterator1 __b = __first1 + __i, __e = __first1 + (__i + __len); + _RandomAccessIterator1 __b = __first1 + __i, __e = __first1 + (__i + __len); //try searching for the first element which not equal to *__b if (__b != __first1) @@ -3157,7 +3241,7 @@ __parallel_set_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forwar //check is [__b; __e) empty if (__e - __b < 1) { - _ForwardIterator2 __bb = __last2; + _RandomAccessIterator2 __bb = __last2; if (__b != __last1) __bb = ::std::lower_bound(__first2, __last2, *__b, __comp); @@ -3166,11 +3250,11 @@ __parallel_set_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forwar } //try searching for "corresponding" subrange [__bb; __ee) in the second sequence - _ForwardIterator2 __bb = __first2; + _RandomAccessIterator2 __bb = __first2; if (__b != __first1) __bb = ::std::lower_bound(__first2, __last2, *__b, __comp); - _ForwardIterator2 __ee = __last2; + _RandomAccessIterator2 __ee = __last2; if (__e != __last1) __ee = ::std::lower_bound(__bb, __last2, *__e, __comp); @@ -3196,64 +3280,66 @@ __parallel_set_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forwar } //a shared parallel pattern for '__pattern_set_union' and '__pattern_set_symmetric_difference' -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__parallel_set_union_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, - _Compare __comp, _SetUnionOp __set_union_op, _IsVector __is_vector) +template +_OutputIterator +__parallel_set_union_op(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, + _OutputIterator __result, _Compare __comp, _SetUnionOp __set_union_op) { - typedef typename ::std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType; + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + + typedef typename ::std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; const auto __n1 = __last1 - __first1; const auto __n2 = __last2 - __first2; - __brick_copy<_ExecutionPolicy> __copy_range{}; + __brick_copy<__parallel_tag<_IsVector>, _ExecutionPolicy> __copy_range{}; // {1} {}: parallel copying just first sequence if (__n2 == 0) - return __internal::__pattern_walk2_brick(::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, - __copy_range, ::std::true_type()); + return __internal::__pattern_walk2_brick(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, + __result, __copy_range); // {} {2}: parallel copying justmake second sequence if (__n1 == 0) - return __internal::__pattern_walk2_brick(::std::forward<_ExecutionPolicy>(__exec), __first2, __last2, __result, - __copy_range, ::std::true_type()); + return __internal::__pattern_walk2_brick(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first2, __last2, + __result, __copy_range); // testing whether the sequences are intersected - _ForwardIterator1 __left_bound_seq_1 = ::std::lower_bound(__first1, __last1, *__first2, __comp); + _RandomAccessIterator1 __left_bound_seq_1 = ::std::lower_bound(__first1, __last1, *__first2, __comp); if (__left_bound_seq_1 == __last1) { //{1} < {2}: seq2 is wholly greater than seq1, so, do parallel copying seq1 and seq2 __par_backend::__parallel_invoke( - ::std::forward<_ExecutionPolicy>(__exec), + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), [=] { - __internal::__pattern_walk2_brick(::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, - __copy_range, ::std::true_type()); + __internal::__pattern_walk2_brick(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, + __result, __copy_range); }, [=] { - __internal::__pattern_walk2_brick(::std::forward<_ExecutionPolicy>(__exec), __first2, __last2, - __result + __n1, __copy_range, ::std::true_type()); + __internal::__pattern_walk2_brick(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first2, __last2, + __result + __n1, __copy_range); }); return __result + __n1 + __n2; } // testing whether the sequences are intersected - _ForwardIterator2 __left_bound_seq_2 = ::std::lower_bound(__first2, __last2, *__first1, __comp); + _RandomAccessIterator2 __left_bound_seq_2 = ::std::lower_bound(__first2, __last2, *__first1, __comp); if (__left_bound_seq_2 == __last2) { //{2} < {1}: seq2 is wholly greater than seq1, so, do parallel copying seq1 and seq2 __par_backend::__parallel_invoke( - ::std::forward<_ExecutionPolicy>(__exec), + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), [=] { - __internal::__pattern_walk2_brick(::std::forward<_ExecutionPolicy>(__exec), __first2, __last2, __result, - __copy_range, ::std::true_type()); + __internal::__pattern_walk2_brick(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first2, __last2, + __result, __copy_range); }, [=] { - __internal::__pattern_walk2_brick(::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - __result + __n2, __copy_range, ::std::true_type()); + __internal::__pattern_walk2_brick(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, + __result + __n2, __copy_range); }); return __result + __n1 + __n2; } @@ -3264,17 +3350,17 @@ __parallel_set_union_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ auto __res_or = __result; __result += __m1; //we know proper offset due to [first1; left_bound_seq_1) < [first2; last2) __par_backend::__parallel_invoke( - ::std::forward<_ExecutionPolicy>(__exec), + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), //do parallel copying of [first1; left_bound_seq_1) [=] { - __internal::__pattern_walk2_brick(::std::forward<_ExecutionPolicy>(__exec), __first1, - __left_bound_seq_1, __res_or, __copy_range, ::std::true_type()); + __internal::__pattern_walk2_brick(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, + __left_bound_seq_1, __res_or, __copy_range); }, [=, &__result] { __result = __internal::__parallel_set_op( - ::std::forward<_ExecutionPolicy>(__exec), __left_bound_seq_1, __last1, __first2, __last2, __result, - __comp, [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, __set_union_op, - __is_vector); + __tag, ::std::forward<_ExecutionPolicy>(__exec), __left_bound_seq_1, __last1, __first2, __last2, + __result, __comp, [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, + __set_union_op); }); return __result; } @@ -3286,24 +3372,24 @@ __parallel_set_union_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ auto __res_or = __result; __result += __m2; //we know proper offset due to [first2; left_bound_seq_2) < [first1; last1) __par_backend::__parallel_invoke( - ::std::forward<_ExecutionPolicy>(__exec), + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), //do parallel copying of [first2; left_bound_seq_2) [=] { - __internal::__pattern_walk2_brick(::std::forward<_ExecutionPolicy>(__exec), __first2, - __left_bound_seq_2, __res_or, __copy_range, ::std::true_type()); + __internal::__pattern_walk2_brick(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first2, + __left_bound_seq_2, __res_or, __copy_range); }, [=, &__result] { __result = __internal::__parallel_set_op( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __left_bound_seq_2, __last2, __result, - __comp, [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, __set_union_op, - __is_vector); + __tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __left_bound_seq_2, __last2, + __result, __comp, [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, + __set_union_op); }); return __result; } return __internal::__parallel_set_op( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, - [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, __set_union_op, __is_vector); + __tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, + [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, __set_union_op); } //------------------------------------------------------------------------ @@ -3340,25 +3426,26 @@ __brick_set_union(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last return ::std::set_union(__first1, __last1, __first2, __last2, __result, __comp); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_set_union(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp, - _IsVector __is_vector, - /*is_parallel=*/::std::false_type) noexcept +template +_OutputIterator +__pattern_set_union(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, + _Compare __comp) noexcept { - return __internal::__brick_set_union(__first1, __last1, __first2, __last2, __result, __comp, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_set_union(__first1, __last1, __first2, __last2, __result, __comp, + typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_set_union(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _OutputIterator __result, - _Compare __comp, _IsVector __is_vector, /*__is_parallel=*/::std::true_type) +template +_OutputIterator +__pattern_set_union(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, + _OutputIterator __result, _Compare __comp) { - const auto __n1 = __last1 - __first1; const auto __n2 = __last2 - __first2; @@ -3368,13 +3455,12 @@ __pattern_set_union(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, typedef typename ::std::iterator_traits<_OutputIterator>::value_type _Tp; return __parallel_set_union_op( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, + __tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, [](_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _Tp* __result, _Compare __comp) { return oneapi::dpl::__utils::__set_union_construct(__first1, __last1, __first2, __last2, __result, __comp, __BrickCopyConstruct<_IsVector>()); - }, - __is_vector); + }); } //------------------------------------------------------------------------ @@ -3401,23 +3487,25 @@ __brick_set_intersection(_RandomAccessIterator1 __first1, _RandomAccessIterator1 return ::std::set_intersection(__first1, __last1, __first2, __last2, __result, __comp); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_set_intersection(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, +template +_OutputIterator +__pattern_set_intersection(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, - _Compare __comp, _IsVector __is_vector, /*is_parallel=*/::std::false_type) noexcept + _Compare __comp) noexcept { - return __internal::__brick_set_intersection(__first1, __last1, __first2, __last2, __result, __comp, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_set_intersection(__first1, __last1, __first2, __last2, __result, __comp, + typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator3> -__pattern_set_intersection(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, - _RandomAccessIterator3 __result, _Compare __comp, _IsVector __is_vector, - /*is_parallel=*/::std::true_type) +template +_RandomAccessIterator3 +__pattern_set_intersection(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, _RandomAccessIterator3 __result, _Compare __comp) { typedef typename ::std::iterator_traits<_RandomAccessIterator3>::value_type _T; typedef typename ::std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; @@ -3446,14 +3534,13 @@ __pattern_set_intersection(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __f { //we know proper offset due to [first1; left_bound_seq_1) < [first2; last2) return __internal::__parallel_set_op( - ::std::forward<_ExecutionPolicy>(__exec), __left_bound_seq_1, __last1, __first2, __last2, __result, __comp, - [](_DifferenceType __n, _DifferenceType __m) { return ::std::min(__n, __m); }, + __tag, ::std::forward<_ExecutionPolicy>(__exec), __left_bound_seq_1, __last1, __first2, __last2, __result, + __comp, [](_DifferenceType __n, _DifferenceType __m) { return ::std::min(__n, __m); }, [](_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _T* __result, _Compare __comp) { return oneapi::dpl::__utils::__set_intersection_construct(__first1, __last1, __first2, __last2, __result, __comp); - }, - __is_vector); + }); } const auto __m2 = __last2 - __left_bound_seq_2 + __n1; @@ -3461,14 +3548,13 @@ __pattern_set_intersection(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __f { //we know proper offset due to [first2; left_bound_seq_2) < [first1; last1) __result = __internal::__parallel_set_op( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __left_bound_seq_2, __last2, __result, __comp, - [](_DifferenceType __n, _DifferenceType __m) { return ::std::min(__n, __m); }, + __tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __left_bound_seq_2, __last2, __result, + __comp, [](_DifferenceType __n, _DifferenceType __m) { return ::std::min(__n, __m); }, [](_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _T* __result, _Compare __comp) { return oneapi::dpl::__utils::__set_intersection_construct(__first2, __last2, __first1, __last1, __result, __comp); - }, - __is_vector); + }); return __result; } @@ -3499,23 +3585,25 @@ __brick_set_difference(_RandomAccessIterator1 __first1, _RandomAccessIterator1 _ return ::std::set_difference(__first1, __last1, __first2, __last2, __result, __comp); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_set_difference(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, +template +_OutputIterator +__pattern_set_difference(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, - _Compare __comp, _IsVector __is_vector, /*is_parallel=*/::std::false_type) noexcept + _Compare __comp) noexcept { - return __internal::__brick_set_difference(__first1, __last1, __first2, __last2, __result, __comp, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_set_difference(__first1, __last1, __first2, __last2, __result, __comp, + typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator3> -__pattern_set_difference(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, - _RandomAccessIterator3 __result, _Compare __comp, _IsVector __is_vector, - /*is_parallel=*/::std::true_type) +template +_RandomAccessIterator3 +__pattern_set_difference(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, _RandomAccessIterator3 __result, _Compare __comp) { typedef typename ::std::iterator_traits<_RandomAccessIterator3>::value_type _T; typedef typename ::std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; @@ -3529,33 +3617,32 @@ __pattern_set_difference(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __fir // {1} \ {}: parallel copying just first sequence if (__n2 == 0) - return __pattern_walk2_brick(::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, - __internal::__brick_copy<_ExecutionPolicy>{}, ::std::true_type()); + return __pattern_walk2_brick(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, + __internal::__brick_copy<__parallel_tag<_IsVector>, _ExecutionPolicy>{}); // testing whether the sequences are intersected _RandomAccessIterator1 __left_bound_seq_1 = ::std::lower_bound(__first1, __last1, *__first2, __comp); //{1} < {2}: seq 2 is wholly greater than seq 1, so, parallel copying just first sequence if (__left_bound_seq_1 == __last1) - return __pattern_walk2_brick(::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, - __internal::__brick_copy<_ExecutionPolicy>{}, ::std::true_type()); + return __pattern_walk2_brick(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, + __internal::__brick_copy<__parallel_tag<_IsVector>, _ExecutionPolicy>{}); // testing whether the sequences are intersected _RandomAccessIterator2 __left_bound_seq_2 = ::std::lower_bound(__first2, __last2, *__first1, __comp); //{2} < {1}: seq 1 is wholly greater than seq 2, so, parallel copying just first sequence if (__left_bound_seq_2 == __last2) - return __internal::__pattern_walk2_brick(::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, - __brick_copy<_ExecutionPolicy>{}, ::std::true_type()); + return __internal::__pattern_walk2_brick(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, + __result, __brick_copy<__parallel_tag<_IsVector>, _ExecutionPolicy>{}); if (__n1 + __n2 > __set_algo_cut_off) return __parallel_set_op( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, + __tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, [](_DifferenceType __n, _DifferenceType) { return __n; }, [](_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _T* __result, _Compare __comp) { return oneapi::dpl::__utils::__set_difference_construct(__first1, __last1, __first2, __last2, __result, __comp, __BrickCopyConstruct<_IsVector>()); - }, - __is_vector); + }); // use serial algorithm return ::std::set_difference(__first1, __last1, __first2, __last2, __result, __comp); @@ -3585,26 +3672,27 @@ __brick_set_symmetric_difference(_RandomAccessIterator1 __first1, _RandomAccessI return ::std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_set_symmetric_difference(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, +template +_OutputIterator +__pattern_set_symmetric_difference(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, - _Compare __comp, _IsVector __is_vector, /*is_parallel=*/::std::false_type) noexcept + _Compare __comp) noexcept { + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + return __internal::__brick_set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp, - __is_vector); + typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator3> -__pattern_set_symmetric_difference(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, - _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, _RandomAccessIterator3 __result, _Compare __comp, - _IsVector __is_vector, /*is_parallel=*/::std::true_type) +template +_RandomAccessIterator3 +__pattern_set_symmetric_difference(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, + _RandomAccessIterator3 __result, _Compare __comp) { - const auto __n1 = __last1 - __first1; const auto __n2 = __last2 - __first2; @@ -3614,13 +3702,12 @@ __pattern_set_symmetric_difference(_ExecutionPolicy&& __exec, _RandomAccessItera typedef typename ::std::iterator_traits<_RandomAccessIterator3>::value_type _T; return __internal::__parallel_set_union_op( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, + __tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, [](_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _T* __result, _Compare __comp) { return oneapi::dpl::__utils::__set_symmetric_difference_construct( __first1, __last1, __first2, __last2, __result, __comp, __BrickCopyConstruct<_IsVector>()); - }, - __is_vector); + }); } //------------------------------------------------------------------------ @@ -3646,12 +3733,14 @@ __brick_is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __las [&__comp](_RandomAccessIterator __it, _SizeType __i) { return __comp(__it[(__i - 1) / 2], __it[__i]); }); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_is_heap_until(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Compare __comp, _IsVector __is_vector, /* is_parallel = */ ::std::false_type) noexcept +template +_RandomAccessIterator +__pattern_is_heap_until(_Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) noexcept { - return __internal::__brick_is_heap_until(__first, __last, __comp, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_is_heap_until(__first, __last, __comp, typename _Tag::__is_vector{}); } template @@ -3676,18 +3765,18 @@ __is_heap_until_local(_RandomAccessIterator __first, _DifferenceType __begin, _D [&__comp](_RandomAccessIterator __it, _DifferenceType __i) { return __comp(__it[(__i - 1) / 2], __it[__i]); }); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Compare __comp, _IsVector __is_vector, /* is_parallel = */ ::std::true_type) +template +_RandomAccessIterator +__pattern_is_heap_until(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) { return __internal::__except_handler([&]() { - return __parallel_find(::std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__first, __comp, __is_vector](_RandomAccessIterator __i, _RandomAccessIterator __j) { - return __internal::__is_heap_until_local(__first, __i - __first, __j - __first, - __comp, __is_vector); - }, - ::std::true_type{}); + return __parallel_find( + __tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__first, __comp](_RandomAccessIterator __i, _RandomAccessIterator __j) { + return __internal::__is_heap_until_local(__first, __i - __first, __j - __first, __comp, _IsVector{}); + }, + ::std::true_type{}); }); } @@ -3732,24 +3821,26 @@ __is_heap_local(_RandomAccessIterator __first, _DifferenceType __begin, _Differe }); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_is_heap(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, - _IsVector __is_vector, /* is_parallel = */ ::std::false_type) noexcept +template +bool +__pattern_is_heap(_Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) noexcept { - return __internal::__brick_is_heap(__first, __last, __comp, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_is_heap(__first, __last, __comp, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Compare __comp, _IsVector __is_vector, /* is_parallel = */ ::std::true_type) +template +bool +__pattern_is_heap(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) { return __internal::__except_handler([&]() { - return !__parallel_or(::std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__first, __comp, __is_vector](_RandomAccessIterator __i, _RandomAccessIterator __j) { + return !__parallel_or(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__first, __comp](_RandomAccessIterator __i, _RandomAccessIterator __j) { return !__internal::__is_heap_local(__first, __i - __first, __j - __first, __comp, - __is_vector); + _IsVector{}); }); }); } @@ -3778,30 +3869,34 @@ __brick_min_element(_RandomAccessIterator __first, _RandomAccessIterator __last, #endif } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_min_element(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp, - _IsVector __is_vector, /* is_parallel = */ ::std::false_type) noexcept +template +_ForwardIterator +__pattern_min_element(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _Compare __comp) noexcept { - return __internal::__brick_min_element(__first, __last, __comp, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_min_element(__first, __last, __comp, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_min_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Compare __comp, _IsVector __is_vector, /* is_parallel = */ ::std::true_type) +template +_RandomAccessIterator +__pattern_min_element(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + // a trivial case pre-check if (__last - __first < 2) return __first; return __internal::__except_handler([&]() { return __par_backend::__parallel_reduce( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, /*identity*/ __last, + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, /*identity*/ __last, [=](_RandomAccessIterator __begin, _RandomAccessIterator __end, _RandomAccessIterator __init) -> _RandomAccessIterator { const _RandomAccessIterator __subresult = - __internal::__brick_min_element(__begin, __end, __comp, __is_vector); + __internal::__brick_min_element(__begin, __end, __comp, _IsVector{}); return __init == __last ? __subresult : __internal::__cmp_iterators_by_values(__init, __subresult, __comp, oneapi::dpl::__internal::__pstl_less()); @@ -3841,21 +3936,23 @@ __brick_minmax_element(_RandomAccessIterator __first, _RandomAccessIterator __la #endif } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, - ::std::pair<_ForwardIterator, _ForwardIterator>> -__pattern_minmax_element(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp, - _IsVector __is_vector, /* is_parallel = */ ::std::false_type) noexcept +template +::std::pair<_ForwardIterator, _ForwardIterator> +__pattern_minmax_element(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _Compare __comp) noexcept { - return __internal::__brick_minmax_element(__first, __last, __comp, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_minmax_element(__first, __last, __comp, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, - ::std::pair<_RandomAccessIterator, _RandomAccessIterator>> -__pattern_minmax_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Compare __comp, _IsVector __is_vector, /* is_parallel = */ ::std::true_type) +template +::std::pair<_RandomAccessIterator, _RandomAccessIterator> +__pattern_minmax_element(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + // a trivial case pre-check if (__last - __first < 2) return ::std::make_pair(__first, __first); @@ -3864,10 +3961,10 @@ __pattern_minmax_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __firs typedef ::std::pair<_RandomAccessIterator, _RandomAccessIterator> _Result; return __par_backend::__parallel_reduce( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, /*identity*/ ::std::make_pair(__last, __last), [=, &__comp](_RandomAccessIterator __begin, _RandomAccessIterator __end, _Result __init) -> _Result { - const _Result __subresult = __internal::__brick_minmax_element(__begin, __end, __comp, __is_vector); + const _Result __subresult = __internal::__brick_minmax_element(__begin, __end, __comp, _IsVector{}); if (__init.first == __last) // = identity return __subresult; return ::std::make_pair( @@ -3920,31 +4017,30 @@ __brick_mismatch(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1 return __unseq_backend::__simd_first(__first1, __n, __first2, __not_pred<_Predicate&>(__pred)); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, - ::std::pair<_ForwardIterator1, _ForwardIterator2>> -__pattern_mismatch(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Predicate __pred, _IsVector __is_vector, - /* is_parallel = */ ::std::false_type) noexcept +template +::std::pair<_ForwardIterator1, _ForwardIterator2> +__pattern_mismatch(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Predicate __pred) noexcept { - return __internal::__brick_mismatch(__first1, __last1, __first2, __last2, __pred, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_mismatch(__first1, __last1, __first2, __last2, __pred, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, - ::std::pair<_RandomAccessIterator1, _RandomAccessIterator2>> -__pattern_mismatch(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _Predicate __pred, - _IsVector __is_vector, /* is_parallel = */ ::std::true_type) +template +::std::pair<_RandomAccessIterator1, _RandomAccessIterator2> +__pattern_mismatch(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, + _Predicate __pred) { return __internal::__except_handler([&]() { auto __n = ::std::min(__last1 - __first1, __last2 - __first2); auto __result = __internal::__parallel_find( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, - [__first1, __first2, __pred, __is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + __tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, + [__first1, __first2, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { return __internal::__brick_mismatch(__i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1), - __pred, __is_vector) + __pred, _IsVector{}) .first; }, ::std::true_type{}); @@ -4002,22 +4098,24 @@ __brick_lexicographical_compare(_RandomAccessIterator1 __first1, _RandomAccessIt } } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_lexicographical_compare(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp, - _IsVector __is_vector, /* is_parallel = */ ::std::false_type) noexcept +template +bool +__pattern_lexicographical_compare(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp) noexcept { - return __internal::__brick_lexicographical_compare(__first1, __last1, __first2, __last2, __comp, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_lexicographical_compare(__first1, __last1, __first2, __last2, __comp, + typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, bool> -__pattern_lexicographical_compare(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, - _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, _Compare __comp, _IsVector __is_vector, - /* is_parallel = */ ::std::true_type) +template +bool +__pattern_lexicographical_compare(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, + _Compare __comp) noexcept { if (__first2 == __last2) { // if second sequence is empty @@ -4035,13 +4133,14 @@ __pattern_lexicographical_compare(_ExecutionPolicy&& __exec, _RandomAccessIterat --__last2; auto __n = ::std::min(__last1 - __first1, __last2 - __first2); auto __result = __internal::__parallel_find( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, - [__first1, __first2, &__comp, __is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { - return __internal::__brick_mismatch(__i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1), - [&__comp](const _RefType1 __x, const _RefType2 __y) { - return !__comp(__x, __y) && !__comp(__y, __x); - }, - __is_vector) + __tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, + [__first1, __first2, &__comp](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + return __internal::__brick_mismatch( + __i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1), + [&__comp](const _RefType1 __x, const _RefType2 __y) { + return !__comp(__x, __y) && !__comp(__y, __x); + }, + _IsVector{}) .first; }, ::std::true_type{}); @@ -4061,14 +4160,14 @@ __pattern_lexicographical_compare(_ExecutionPolicy&& __exec, _RandomAccessIterat // swap //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator2> -__pattern_swap(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Function __f, _IsVector __is_vector, _IsParallel __is_parallel) +template +_ForwardIterator2 +__pattern_swap(_Tag __tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _Function __f) { - return __pattern_walk2(::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __f, __is_vector, - __is_parallel); + static_assert(__is_host_dispatch_tag_v<_Tag>); + + return __pattern_walk2(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __f); } //------------------------------------------------------------------------ @@ -4139,21 +4238,24 @@ __brick_shift_left(_ForwardIterator __first, _ForwardIterator __last, return __first + __size_res; } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_shift_left(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, - typename ::std::iterator_traits<_ForwardIterator>::difference_type __n, _IsVector __is_vector, - /*is_parallel=*/::std::false_type) noexcept +template +_ForwardIterator +__pattern_shift_left(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + typename ::std::iterator_traits<_ForwardIterator>::difference_type __n) noexcept { - return __brick_shift_left(__first, __last, __n, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __brick_shift_left(__first, __last, __n, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_shift_left(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, - typename ::std::iterator_traits<_ForwardIterator>::difference_type __n, _IsVector __is_vector, - /*is_parallel=*/::std::true_type) +template +_RandomAccessIterator +__pattern_shift_left(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, + typename ::std::iterator_traits<_RandomAccessIterator>::difference_type __n) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + //If (n > 0 && n < m), returns first + (m - n). Otherwise, if n > 0, returns first. Otherwise, returns last. if (__n <= 0) return __last; @@ -4161,7 +4263,7 @@ __pattern_shift_left(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Forwa if (__n >= __size) return __first; - using _DiffType = typename ::std::iterator_traits<_ForwardIterator>::difference_type; + using _DiffType = typename ::std::iterator_traits<_RandomAccessIterator>::difference_type; _DiffType __mid = __size / 2 + __size % 2; _DiffType __size_res = __size - __n; @@ -4169,10 +4271,10 @@ __pattern_shift_left(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Forwa //1. n >= size/2; there is enough memory to 'total' parallel copying if (__n >= __mid) { - __par_backend::__parallel_for(::std::forward<_ExecutionPolicy>(__exec), __n, __size, - [__first, __n, __is_vector](_DiffType __i, _DiffType __j) { - __brick_move<_ExecutionPolicy>{}(__first + __i, __first + __j, - __first + __i - __n, __is_vector); + __par_backend::__parallel_for(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __n, __size, + [__first, __n](_DiffType __i, _DiffType __j) { + __brick_move<__parallel_tag<_IsVector>, _ExecutionPolicy>{}( + __first + __i, __first + __j, __first + __i - __n, _IsVector{}); }); } else //2. n < size/2; there is not enough memory to parallel copying; doing parallel copying by n elements @@ -4181,10 +4283,10 @@ __pattern_shift_left(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Forwa for (auto __k = __n; __k < __size; __k += __n) { auto __end = ::std::min(__k + __n, __size); - __par_backend::__parallel_for(::std::forward<_ExecutionPolicy>(__exec), __k, __end, - [__first, __n, __is_vector](_DiffType __i, _DiffType __j) { - __brick_move<_ExecutionPolicy>{}(__first + __i, __first + __j, - __first + __i - __n, __is_vector); + __par_backend::__parallel_for(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __k, __end, + [__first, __n](_DiffType __i, _DiffType __j) { + __brick_move<__parallel_tag<_IsVector>, _ExecutionPolicy>{}( + __first + __i, __first + __j, __first + __i - __n, _IsVector{}); }); } } @@ -4192,16 +4294,18 @@ __pattern_shift_left(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Forwa return __first + __size_res; } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _BidirectionalIterator> -__pattern_shift_right(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, - typename ::std::iterator_traits<_BidirectionalIterator>::difference_type __n, - _IsVector __is_vector, _IsParallel is_parallel) +template +_BidirectionalIterator +__pattern_shift_right(_Tag __tag, _ExecutionPolicy&& __exec, _BidirectionalIterator __first, + _BidirectionalIterator __last, + typename ::std::iterator_traits<_BidirectionalIterator>::difference_type __n) { + static_assert(__is_host_dispatch_tag_v<_Tag>); + using _ReverseIterator = typename ::std::reverse_iterator<_BidirectionalIterator>; - auto __res = oneapi::dpl::__internal::__pattern_shift_left(::std::forward<_ExecutionPolicy>(__exec), - _ReverseIterator(__last), _ReverseIterator(__first), __n, - __is_vector, is_parallel); + + auto __res = oneapi::dpl::__internal::__pattern_shift_left( + __tag, ::std::forward<_ExecutionPolicy>(__exec), _ReverseIterator(__last), _ReverseIterator(__first), __n); return __res.base(); } diff --git a/include/oneapi/dpl/pstl/execution_defs.h b/include/oneapi/dpl/pstl/execution_defs.h index d16a030b216..26287ccbf6e 100644 --- a/include/oneapi/dpl/pstl/execution_defs.h +++ b/include/oneapi/dpl/pstl/execution_defs.h @@ -31,88 +31,20 @@ inline namespace v1 // 2.4, Sequential execution policy class sequenced_policy { - public: - // For internal use only - static constexpr ::std::false_type - __allow_unsequenced() - { - return ::std::false_type{}; - } - static constexpr ::std::false_type - __allow_vector() - { - return ::std::false_type{}; - } - static constexpr ::std::false_type - __allow_parallel() - { - return ::std::false_type{}; - } }; // 2.5, Parallel execution policy class parallel_policy { - public: - // For internal use only - static constexpr ::std::false_type - __allow_unsequenced() - { - return ::std::false_type{}; - } - static constexpr ::std::false_type - __allow_vector() - { - return ::std::false_type{}; - } - static constexpr ::std::true_type - __allow_parallel() - { - return ::std::true_type{}; - } }; // 2.6, Parallel+Vector execution policy class parallel_unsequenced_policy { - public: - // For internal use only - static constexpr ::std::true_type - __allow_unsequenced() - { - return ::std::true_type{}; - } - static constexpr ::std::true_type - __allow_vector() - { - return ::std::true_type{}; - } - static constexpr ::std::true_type - __allow_parallel() - { - return ::std::true_type{}; - } }; class unsequenced_policy { - public: - // For internal use only - static constexpr ::std::true_type - __allow_unsequenced() - { - return ::std::true_type{}; - } - static constexpr ::std::true_type - __allow_vector() - { - return ::std::true_type{}; - } - static constexpr ::std::false_type - __allow_parallel() - { - return ::std::false_type{}; - } }; // 2.8, Execution policy objects @@ -180,14 +112,6 @@ template using __enable_if_execution_policy = ::std::enable_if_t>, _T>; -template -using __enable_if_host_execution_policy = - ::std::enable_if_t<__is_host_execution_policy<::std::decay_t<_ExecPolicy>>::value, _T>; - -template -using __enable_if_host_execution_policy_conditional = - ::std::enable_if_t<__is_host_execution_policy<::std::decay_t<_ExecPolicy>>::value && __condition, _T>; - template struct __ref_or_copy_impl { @@ -213,6 +137,22 @@ __check_size(...) -> typename ::std::iterator_traits<_It>::difference_type; template using __difference_t = ::std::make_signed_t(0))>; +//------------------------------------------------------------------------ +// backend tags +//------------------------------------------------------------------------ + +struct __serial_backend_tag +{ +}; + +struct __tbb_backend_tag +{ +}; + +struct __omp_backend_tag +{ +}; + } // namespace __internal } // namespace dpl diff --git a/include/oneapi/dpl/pstl/execution_impl.h b/include/oneapi/dpl/pstl/execution_impl.h index 70631a27114..133717bf68e 100644 --- a/include/oneapi/dpl/pstl/execution_impl.h +++ b/include/oneapi/dpl/pstl/execution_impl.h @@ -19,6 +19,7 @@ #include #include +#include "parallel_backend.h" #include "execution_defs.h" #include "iterator_defs.h" @@ -29,100 +30,134 @@ namespace dpl namespace __internal { -/* predicate */ +//------------------------------------------------------------------------ +// backend selector with tags +//------------------------------------------------------------------------ + +#if _ONEDPL_PAR_BACKEND_TBB +using __par_backend_tag = __tbb_backend_tag; +#elif _ONEDPL_PAR_BACKEND_OPENMP +using __par_backend_tag = __omp_backend_tag; +#elif _ONEDPL_PAR_BACKEND_SERIAL +using __par_backend_tag = __serial_backend_tag; +#else +# error "Parallel backend was not specified" +#endif + +template +struct __serial_tag +{ + using __is_vector = _IsVector; +}; -template -::std::false_type __lazy_and(_Tp, ::std::false_type) +template +struct __parallel_tag { - return ::std::false_type{}; -} + using __is_vector = _IsVector; + using __backend_tag = __par_backend_tag; +}; -template -inline _Tp -__lazy_and(_Tp __a, ::std::true_type) +struct __parallel_forward_tag { - return __a; + using __is_vector = ::std::false_type; + using __backend_tag = __par_backend_tag; +}; + +//---------------------------------------------------------- +// __select_backend (for the host policies) +//---------------------------------------------------------- + +template +using __parallel_policy_tag_selector_t = ::std::conditional_t< + __internal::__is_random_access_iterator_v<_IteratorTypes...>, __parallel_tag<_IsVector>, + ::std::conditional_t<__is_forward_iterator_v<_IteratorTypes...>, __parallel_forward_tag, __serial_tag<_IsVector>>>; + +template +__serial_tag +__select_backend(oneapi::dpl::execution::sequenced_policy, _IteratorTypes&&...) +{ + return {}; } -template -::std::true_type __lazy_or(_Tp, ::std::true_type) +template +__serial_tag<__internal::__is_random_access_iterator<_IteratorTypes...>> +__select_backend(oneapi::dpl::execution::unsequenced_policy, _IteratorTypes&&...) { - return ::std::true_type{}; + return {}; } -template -inline _Tp -__lazy_or(_Tp __a, ::std::false_type) +template +__parallel_policy_tag_selector_t +__select_backend(oneapi::dpl::execution::parallel_policy, _IteratorTypes&&...) { - return __a; + return {}; } -/* policy */ -template -struct __policy_traits +template +__parallel_policy_tag_selector_t<__internal::__is_random_access_iterator<_IteratorTypes...>, _IteratorTypes...> +__select_backend(oneapi::dpl::execution::parallel_unsequenced_policy, _IteratorTypes&&...) { -}; + return {}; +} -template <> -struct __policy_traits +//---------------------------------------------------------- +// __is_serial_tag, __is_serial_tag_v +//---------------------------------------------------------- + +template +struct __is_serial_tag : ::std::false_type { - typedef ::std::false_type __allow_parallel; - typedef ::std::false_type __allow_unsequenced; - typedef ::std::false_type __allow_vector; }; -template <> -struct __policy_traits +template +struct __is_serial_tag<__serial_tag<_IsVector>> : ::std::true_type { - typedef ::std::false_type __allow_parallel; - typedef ::std::true_type __allow_unsequenced; - typedef ::std::true_type __allow_vector; }; -template <> -struct __policy_traits +template +inline constexpr bool __is_serial_tag_v = __is_serial_tag<_Tag>::value; + +//---------------------------------------------------------- +// __is_parallel_forward_tag, __is_parallel_forward_tag_v +//---------------------------------------------------------- + +template +struct __is_parallel_forward_tag : ::std::false_type { - typedef ::std::true_type __allow_parallel; - typedef ::std::false_type __allow_unsequenced; - typedef ::std::false_type __allow_vector; }; template <> -struct __policy_traits +struct __is_parallel_forward_tag<__parallel_forward_tag> : ::std::true_type { - typedef ::std::true_type __allow_parallel; - typedef ::std::true_type __allow_unsequenced; - typedef ::std::true_type __allow_vector; }; -template -using __allow_vector = typename __internal::__policy_traits<::std::decay_t<_ExecutionPolicy>>::__allow_vector; - -template -using __allow_unsequenced = typename __internal::__policy_traits<::std::decay_t<_ExecutionPolicy>>::__allow_unsequenced; +template +inline constexpr bool __is_parallel_forward_tag_v = __is_parallel_forward_tag<_Tag>::value; -template -using __allow_parallel = typename __internal::__policy_traits<::std::decay_t<_ExecutionPolicy>>::__allow_parallel; +//---------------------------------------------------------- +// __is_parallel_tag, __is_parallel_tag_v +//---------------------------------------------------------- -template -auto -__is_vectorization_preferred(_ExecutionPolicy& __exec) - -> decltype(__internal::__lazy_and(__exec.__allow_vector(), - __internal::__is_random_access_iterator_t<_IteratorTypes...>())) +template +struct __is_parallel_tag : ::std::false_type { - return __internal::__lazy_and(__exec.__allow_vector(), - __internal::__is_random_access_iterator_t<_IteratorTypes...>()); -} +}; -template -auto -__is_parallelization_preferred(_ExecutionPolicy& __exec) - -> decltype(__internal::__lazy_and(__exec.__allow_parallel(), - __internal::__is_random_access_iterator_t<_IteratorTypes...>())) +template +struct __is_parallel_tag<__parallel_tag<_IsVector>> : ::std::true_type { - return __internal::__lazy_and(__exec.__allow_parallel(), - __internal::__is_random_access_iterator_t<_IteratorTypes...>()); -} +}; + +template +inline constexpr bool __is_parallel_tag_v = __is_parallel_tag<_Tag>::value; + +//---------------------------------------------------------- +// __is_host_dispatch_tag_v +//---------------------------------------------------------- + +template +inline constexpr bool __is_host_dispatch_tag_v = + __is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag> || __is_parallel_tag_v<_Tag>; } // namespace __internal } // namespace dpl diff --git a/include/oneapi/dpl/pstl/experimental/internal/for_loop.h b/include/oneapi/dpl/pstl/experimental/internal/for_loop.h index 4a61dd7c09b..5d8802083d3 100644 --- a/include/oneapi/dpl/pstl/experimental/internal/for_loop.h +++ b/include/oneapi/dpl/pstl/experimental/internal/for_loop.h @@ -56,6 +56,9 @@ template void for_loop(_ExecutionPolicy&& __exec, type_identity_t<_Ip> __start, _Ip __finish, _Rest&&... __rest) { + static_assert(oneapi::dpl::__internal::__is_host_execution_policy<::std::decay_t<_ExecutionPolicy>>::value, + "for_loop is implemented for the host policies only"); + oneapi::dpl::__internal::__for_loop_repack(::std::forward<_ExecutionPolicy>(__exec), __start, __finish, oneapi::dpl::__internal::__single_stride_type{}, ::std::forward_as_tuple(::std::forward<_Rest>(__rest)...)); @@ -65,6 +68,9 @@ template __start, _Ip __finish, _Sp __stride, _Rest&&... __rest) { + static_assert(oneapi::dpl::__internal::__is_host_execution_policy<::std::decay_t<_ExecutionPolicy>>::value, + "for_loop_strided is implemented for the host policies only"); + oneapi::dpl::__internal::__for_loop_repack(::std::forward<_ExecutionPolicy>(__exec), __start, __finish, __stride, ::std::forward_as_tuple(::std::forward<_Rest>(__rest)...)); } @@ -73,6 +79,9 @@ template >::value, + "for_loop_n is implemented for the host policies only"); + oneapi::dpl::__internal::__for_loop_repack_n(::std::forward<_ExecutionPolicy>(__exec), __start, __n, oneapi::dpl::__internal::__single_stride_type{}, ::std::forward_as_tuple(::std::forward<_Rest>(__rest)...)); @@ -82,6 +91,9 @@ template >::value, + "for_loop_n_strided is implemented for the host policies only"); + oneapi::dpl::__internal::__for_loop_repack_n(::std::forward<_ExecutionPolicy>(__exec), __start, __n, __stride, ::std::forward_as_tuple(::std::forward<_Rest>(__rest)...)); } diff --git a/include/oneapi/dpl/pstl/experimental/internal/for_loop_impl.h b/include/oneapi/dpl/pstl/experimental/internal/for_loop_impl.h index d7f738036c3..47769c4645d 100644 --- a/include/oneapi/dpl/pstl/experimental/internal/for_loop_impl.h +++ b/include/oneapi/dpl/pstl/experimental/internal/for_loop_impl.h @@ -65,7 +65,7 @@ struct __difference<_Ip, ::std::enable_if_t<::std::is_integral_v<_Ip>>> template struct __difference<_Ip, ::std::enable_if_t>> { - using __type = typename oneapi::dpl::__internal::__iterator_traits<_Ip>::difference_type; + using __type = typename ::std::iterator_traits<_Ip>::difference_type; }; // This type is used as a stride value when it's known that stride == 1 at compile time(the case of for_loop and for_loop_n). @@ -232,9 +232,9 @@ __pattern_for_loop(_ExecutionPolicy&& __exec, _Ip __first, _Ip __last, _Function } template -::std::enable_if_t<::std::is_same_v::iterator_category, - ::std::bidirectional_iterator_tag>, - _IndexType> +::std::enable_if_t< + ::std::is_same_v::iterator_category, ::std::bidirectional_iterator_tag>, + _IndexType> __execute_loop_strided(_Ip __first, _Ip __last, _Function __f, _Sp __stride, _Pack& __pack, _IndexType) noexcept { _IndexType __ordinal_position = 0; @@ -269,11 +269,10 @@ __execute_loop_strided(_Ip __first, _Ip __last, _Function __f, _Sp __stride, _Pa } template -::std::enable_if_t<::std::is_same_v::iterator_category, - ::std::forward_iterator_tag> || - ::std::is_same_v::iterator_category, - ::std::input_iterator_tag>, - _IndexType> +::std::enable_if_t< + ::std::is_same_v::iterator_category, ::std::forward_iterator_tag> || + ::std::is_same_v::iterator_category, ::std::input_iterator_tag>, + _IndexType> __execute_loop_strided(_Ip __first, _Ip __last, _Function __f, _Sp __stride, _Pack& __pack, _IndexType) noexcept { _IndexType __ordinal_position = 0; @@ -398,26 +397,27 @@ __pattern_for_loop_n(_ExecutionPolicy&& __exec, _Ip __first, _Size __n, _Functio // Create an identity pack object, operations are done on copies of it. const __pack_type __identity{__reduction_pack_tag(), ::std::forward<_Rest>(__rest)...}; + using __backend_tag = typename oneapi::dpl::__internal::__parallel_tag<_IsVector>::__backend_tag; oneapi::dpl::__internal::__except_handler([&]() { - return __par_backend::__parallel_reduce(::std::forward<_ExecutionPolicy>(__exec), _Size(0), __n, __identity, - [__is_vector, __first, __f](_Size __i, _Size __j, __pack_type __value) { - const auto __subseq_start = __first + __i; - const auto __length = __j - __i; - - oneapi::dpl::__internal::__brick_walk1( - __length, - [&__value, __f, __i, __subseq_start](_Size __idx) { - __value.__apply_func(__f, __subseq_start + __idx, - __i + __idx); - }, - __is_vector); - - return __value; - }, - [](__pack_type __lhs, const __pack_type& __rhs) { - __lhs.__combine(__rhs); - return __lhs; - }) + return __par_backend::__parallel_reduce( + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), _Size(0), __n, __identity, + [__is_vector, __first, __f](_Size __i, _Size __j, __pack_type __value) { + const auto __subseq_start = __first + __i; + const auto __length = __j - __i; + + oneapi::dpl::__internal::__brick_walk1( + __length, + [&__value, __f, __i, __subseq_start](_Size __idx) { + __value.__apply_func(__f, __subseq_start + __idx, __i + __idx); + }, + __is_vector); + + return __value; + }, + [](__pack_type __lhs, const __pack_type& __rhs) { + __lhs.__combine(__rhs); + return __lhs; + }) .__finalize(__n); }); } @@ -433,9 +433,10 @@ __pattern_for_loop_n(_ExecutionPolicy&& __exec, _Ip __first, _Size __n, _Functio // Create an identity pack object, operations are done on copies of it. const __pack_type __identity{__reduction_pack_tag(), ::std::forward<_Rest>(__rest)...}; + using __backend_tag = typename oneapi::dpl::__internal::__parallel_tag<_IsVector>::__backend_tag; oneapi::dpl::__internal::__except_handler([&]() { return __par_backend::__parallel_reduce( - ::std::forward<_ExecutionPolicy>(__exec), _Size(0), __n, __identity, + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), _Size(0), __n, __identity, [__is_vector, __first, __f, __stride](_Size __i, _Size __j, __pack_type __value) { const auto __subseq_start = __first + __i * __stride; const auto __length = __j - __i; @@ -472,48 +473,25 @@ __pattern_for_loop(_ExecutionPolicy&& __exec, _Ip __first, _Ip __last, _Function // Helper structure to split code functions for integral and iterator types so the return // value can be successfully deduced. -template -struct __use_par_vec_helper; - template -struct __use_par_vec_helper<_Ip, ::std::enable_if_t<::std::is_integral_v<_Ip>>> +struct __use_par_vec_helper { - template - static constexpr auto - __use_vector(_ExecutionPolicy&& __exec) -> decltype(__exec.__allow_vector()) - { - return __exec.__allow_vector(); - } - - template - static constexpr auto - __use_parallel(_ExecutionPolicy&& __exec) -> decltype(__exec.__allow_parallel()) - { - return __exec.__allow_parallel(); - } -}; + using __it_type = std::conditional_t, _Ip*, _Ip>; -template -struct __use_par_vec_helper<_Ip, ::std::enable_if_t>> -{ template static constexpr auto __use_vector(_ExecutionPolicy&& __exec) - -> decltype(oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _Ip>( - ::std::forward<_ExecutionPolicy>(__exec))) { - return oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _Ip>( - ::std::forward<_ExecutionPolicy>(__exec)); + using __tag_type = decltype(oneapi::dpl::__internal::__select_backend(__exec, std::declval<__it_type>())); + return typename __tag_type::__is_vector{}; } template static constexpr auto __use_parallel(_ExecutionPolicy&& __exec) - -> decltype(oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _Ip>( - ::std::forward<_ExecutionPolicy>(__exec))) { - return oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _Ip>( - ::std::forward<_ExecutionPolicy>(__exec)); + using __tag_type = decltype(oneapi::dpl::__internal::__select_backend(__exec, std::declval<__it_type>())); + return oneapi::dpl::__internal::__is_parallel_tag<__tag_type>{}; } }; @@ -521,7 +499,6 @@ struct __use_par_vec_helper<_Ip, ::std::enable_if_t>> template auto __use_vectorization(_ExecutionPolicy&& __exec) - -> decltype(__use_par_vec_helper<_Ip>::__use_vector(::std::forward<_ExecutionPolicy>(__exec))) { return __use_par_vec_helper<_Ip>::__use_vector(::std::forward<_ExecutionPolicy>(__exec)); } @@ -529,7 +506,6 @@ __use_vectorization(_ExecutionPolicy&& __exec) template auto __use_parallelization(_ExecutionPolicy&& __exec) - -> decltype(__use_par_vec_helper<_Ip>::__use_parallel(::std::forward<_ExecutionPolicy>(__exec))) { return __use_par_vec_helper<_Ip>::__use_parallel(::std::forward<_ExecutionPolicy>(__exec)); } diff --git a/include/oneapi/dpl/pstl/glue_algorithm_impl.h b/include/oneapi/dpl/pstl/glue_algorithm_impl.h index 952087c68ad..0d17726cc24 100644 --- a/include/oneapi/dpl/pstl/glue_algorithm_impl.h +++ b/include/oneapi/dpl/pstl/glue_algorithm_impl.h @@ -43,10 +43,10 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> any_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { - return oneapi::dpl::__internal::__pattern_any_of( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_any_of(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, + __last, __pred); } // [alg.all_of] @@ -75,20 +75,20 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy> for_each(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Function __f) { - oneapi::dpl::__internal::__pattern_walk1( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __f, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - __exec.__allow_parallel()); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + oneapi::dpl::__internal::__pattern_walk1(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + __f); } template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> for_each_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, _Function __f) { - return oneapi::dpl::__internal::__pattern_walk1_n( - ::std::forward<_ExecutionPolicy>(__exec), __first, __n, __f, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_walk1_n(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, + __n, __f); } // [alg.find] @@ -97,10 +97,10 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> find_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { - return oneapi::dpl::__internal::__pattern_find_if( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_find_if(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, + __last, __pred); } template @@ -129,12 +129,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Forward find_end(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred) { - return oneapi::dpl::__internal::__pattern_find_end( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __s_first); + + return oneapi::dpl::__internal::__pattern_find_end(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __s_first, __s_last, __pred); } template @@ -152,12 +150,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Forward find_first_of(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred) { - return oneapi::dpl::__internal::__pattern_find_first_of( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __s_first); + + return oneapi::dpl::__internal::__pattern_find_first_of(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __s_first, __s_last, __pred); } template @@ -175,22 +171,23 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Forward adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { typedef typename ::std::iterator_traits<_ForwardIterator>::value_type _ValueType; - return oneapi::dpl::__internal::__pattern_adjacent_find( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, ::std::equal_to<_ValueType>(), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__first_semantic()); + + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_adjacent_find(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, ::std::equal_to<_ValueType>(), + oneapi::dpl::__internal::__first_semantic()); } template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { - return oneapi::dpl::__internal::__pattern_adjacent_find( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__first_semantic()); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_adjacent_find(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __pred, + oneapi::dpl::__internal::__first_semantic()); } // [alg.count] @@ -203,12 +200,12 @@ oneapi::dpl::__internal::__enable_if_execution_policy< _ExecutionPolicy, typename ::std::iterator_traits<_ForwardIterator>::difference_type> count(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + return oneapi::dpl::__internal::__pattern_count( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, oneapi::dpl::__internal::__equal_value>( - __value), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); + __value)); } template @@ -216,10 +213,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy< _ExecutionPolicy, typename ::std::iterator_traits<_ForwardIterator>::difference_type> count_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { - return oneapi::dpl::__internal::__pattern_count( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_count(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, + __last, __pred); } // [alg.search] @@ -229,12 +226,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Forward search(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred) { - return oneapi::dpl::__internal::__pattern_search( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __s_first); + + return oneapi::dpl::__internal::__pattern_search(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, + __last, __s_first, __s_last, __pred); } template @@ -251,10 +246,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Forward search_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value, _BinaryPredicate __pred) { - return oneapi::dpl::__internal::__pattern_search_n( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __count, __value, __pred, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_search_n(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __count, __value, __pred); } template @@ -272,11 +267,11 @@ template copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result) { + auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __result); + return oneapi::dpl::__internal::__pattern_walk2_brick( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, - oneapi::dpl::__internal::__brick_copy<_ExecutionPolicy>{}, - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, + oneapi::dpl::__internal::__brick_copy{}); } template @@ -285,11 +280,11 @@ copy_n(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _Size __n, _Forward { using _DecayedExecutionPolicy = ::std::decay_t<_ExecutionPolicy>; + auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __result); + return oneapi::dpl::__internal::__pattern_walk2_brick_n( - ::std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, - oneapi::dpl::__internal::__brick_copy_n<_DecayedExecutionPolicy>{}, - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, + oneapi::dpl::__internal::__brick_copy_n{}); } template @@ -297,12 +292,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Forward copy_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, _Predicate __pred) { - return oneapi::dpl::__internal::__pattern_copy_if( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pred, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __result); + + return oneapi::dpl::__internal::__pattern_copy_if(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, + __last, __result, __pred); } // [alg.swap] @@ -314,16 +307,14 @@ swap_ranges(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardItera { typedef typename ::std::iterator_traits<_ForwardIterator1>::reference _ReferenceType1; typedef typename ::std::iterator_traits<_ForwardIterator2>::reference _ReferenceType2; - return oneapi::dpl::__internal::__pattern_swap( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, - [](_ReferenceType1 __x, _ReferenceType2 __y) { - using ::std::swap; - swap(__x, __y); - }, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first1, __first2); + + return oneapi::dpl::__internal::__pattern_swap(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, + __last1, __first2, [](_ReferenceType1 __x, _ReferenceType2 __y) { + using ::std::swap; + swap(__x, __y); + }); } // [alg.transform] @@ -333,12 +324,11 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Forward transform(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, _UnaryOperation __op) { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __result); + return oneapi::dpl::__internal::__pattern_walk2( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, - oneapi::dpl::__internal::__transform_functor<_UnaryOperation>{::std::move(__op)}, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec), - __exec.__allow_parallel()); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, + oneapi::dpl::__internal::__transform_functor<_UnaryOperation>{::std::move(__op)}); } // we can't use non-const __op here @@ -348,12 +338,11 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Forward transform(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator __result, _BinaryOperation __op) { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first1, __first2, __result); + return oneapi::dpl::__internal::__pattern_walk3( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __result, - oneapi::dpl::__internal::__transform_functor<_BinaryOperation>(::std::move(__op)), - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator>(__exec), - __exec.__allow_parallel()); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __result, + oneapi::dpl::__internal::__transform_functor<_BinaryOperation>(::std::move(__op))); } // [alg.transform_if] @@ -364,14 +353,12 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Forward transform_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, _UnaryOperation __op, _UnaryPredicate __pred) { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __result); + return oneapi::dpl::__internal::__pattern_walk2_transform_if( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, oneapi::dpl::__internal::__transform_if_unary_functor<_UnaryOperation, _UnaryPredicate>(::std::move(__op), - ::std::move(__pred)), - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + ::std::move(__pred))); } template (__exec), __first1, __last1, __first2, __result, - oneapi::dpl::__internal::__transform_if_binary_functor<_BinaryOperation, _BinaryPredicate>(::std::move(__op), - ::std::move(__pred)), - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator3>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator3>(__exec)); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __result, + oneapi::dpl::__internal::__transform_if_binary_functor<_BinaryOperation, _BinaryPredicate>( + ::std::move(__op), ::std::move(__pred))); } // [alg.replace] @@ -397,13 +382,13 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy> replace_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred, const _Tp& __new_value) { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + oneapi::dpl::__internal::__pattern_walk1( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, oneapi::dpl::__internal::__replace_functor< oneapi::dpl::__internal::__ref_or_copy<_ExecutionPolicy, const _Tp>, - oneapi::dpl::__internal::__ref_or_copy<_ExecutionPolicy, _UnaryPredicate>>(__new_value, __pred), - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); + oneapi::dpl::__internal::__ref_or_copy<_ExecutionPolicy, _UnaryPredicate>>(__new_value, __pred)); } template @@ -423,18 +408,16 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Forward replace_copy_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, _UnaryPredicate __pred, const _Tp& __new_value) { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __result); + return oneapi::dpl::__internal::__pattern_walk2( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, oneapi::dpl::__internal::__replace_copy_functor< oneapi::dpl::__internal::__ref_or_copy<_ExecutionPolicy, const _Tp>, ::std::conditional_t, _UnaryPredicate, oneapi::dpl::__internal::__ref_or_copy<_ExecutionPolicy, _UnaryPredicate>>>( - __new_value, __pred), - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + __new_value, __pred)); } template @@ -455,10 +438,10 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy> fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { - oneapi::dpl::__internal::__pattern_fill( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __value, - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + oneapi::dpl::__internal::__pattern_fill(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + __value); } template @@ -468,10 +451,10 @@ fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __count, const if (__count <= 0) return __first; - return oneapi::dpl::__internal::__pattern_fill_n( - ::std::forward<_ExecutionPolicy>(__exec), __first, __count, __value, - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_fill_n(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, + __count, __value); } // [alg.generate] @@ -479,10 +462,10 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy> generate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Generator __g) { - oneapi::dpl::__internal::__pattern_generate( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __g, - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + oneapi::dpl::__internal::__pattern_generate(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, + __last, __g); } template @@ -492,10 +475,10 @@ generate_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __count, _ if (__count <= 0) return __first; - return oneapi::dpl::__internal::__pattern_generate_n( - ::std::forward<_ExecutionPolicy>(__exec), __first, __count, __g, - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_generate_n(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __count, __g); } // [alg.remove] @@ -526,10 +509,10 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> remove_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) { - return oneapi::dpl::__internal::__pattern_remove_if( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_remove_if(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __pred); } template @@ -548,10 +531,10 @@ template unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { - return oneapi::dpl::__internal::__pattern_unique( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_unique(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, + __last, __pred); } template @@ -567,12 +550,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Forward unique_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, _BinaryPredicate __pred) { - return oneapi::dpl::__internal::__pattern_unique_copy( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pred, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __result); + + return oneapi::dpl::__internal::__pattern_unique_copy(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __result, __pred); } template @@ -589,10 +570,10 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy> reverse(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last) { - oneapi::dpl::__internal::__pattern_reverse( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + oneapi::dpl::__internal::__pattern_reverse(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, + __last); } template @@ -600,12 +581,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Forward reverse_copy(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, _ForwardIterator __d_first) { - return oneapi::dpl::__internal::__pattern_reverse_copy( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator, - _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator, - _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __d_first); + + return oneapi::dpl::__internal::__pattern_reverse_copy(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __d_first); } // [alg.rotate] @@ -614,10 +593,10 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> rotate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) { - return oneapi::dpl::__internal::__pattern_rotate( - ::std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_rotate(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, + __middle, __last); } template @@ -625,12 +604,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Forward rotate_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __middle, _ForwardIterator1 __last, _ForwardIterator2 __result) { - return oneapi::dpl::__internal::__pattern_rotate_copy( - ::std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __result, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __result); + + return oneapi::dpl::__internal::__pattern_rotate_copy(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __middle, __last, __result); } // [alg.partitions] @@ -639,20 +616,20 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) { - return oneapi::dpl::__internal::__pattern_is_partitioned( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_is_partitioned(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __pred); } template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> partition(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) { - return oneapi::dpl::__internal::__pattern_partition( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_partition(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __pred); } template @@ -660,10 +637,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Bidirec stable_partition(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, _UnaryPredicate __pred) { - return oneapi::dpl::__internal::__pattern_stable_partition( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_stable_partition(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __pred); } template (__exec), __first, __last, __out_true, __out_false, __pred, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator, _ForwardIterator1, - _ForwardIterator2>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator, _ForwardIterator1, - _ForwardIterator2>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __out_true, __out_false); + + return oneapi::dpl::__internal::__pattern_partition_copy(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __out_true, __out_false, __pred); } // [alg.sort] @@ -687,12 +662,12 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy> sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + typedef typename ::std::iterator_traits<_RandomAccessIterator>::value_type _InputType; - oneapi::dpl::__internal::__pattern_sort( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec), - typename ::std::is_move_constructible<_InputType>::type()); + + oneapi::dpl::__internal::__pattern_sort(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + __comp, typename ::std::is_move_constructible<_InputType>::type()); } template @@ -709,10 +684,10 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy> stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { - oneapi::dpl::__internal::__pattern_stable_sort( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + oneapi::dpl::__internal::__pattern_stable_sort(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, + __last, __comp); } template @@ -731,12 +706,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy> sort_by_key(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __keys_first, _RandomAccessIterator1 __keys_last, _RandomAccessIterator2 __values_first, _Compare __comp) { - oneapi::dpl::__internal::__pattern_sort_by_key( - ::std::forward<_ExecutionPolicy>(__exec), __keys_first, __keys_last, __values_first, __comp, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator1, - _RandomAccessIterator2>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator1, - _RandomAccessIterator2>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __keys_first, __values_first); + + oneapi::dpl::__internal::__pattern_sort_by_key(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __keys_first, __keys_last, __values_first, __comp); } template @@ -756,12 +729,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) { - return oneapi::dpl::__internal::__pattern_mismatch( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __pred, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first1, __first2); + + return oneapi::dpl::__internal::__pattern_mismatch(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first1, __last1, __first2, __last2, __pred); } template @@ -802,10 +773,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _BinaryPredicate __p) { - return oneapi::dpl::__internal::__pattern_equal( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __p, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first1, __first2); + + return oneapi::dpl::__internal::__pattern_equal(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, + __last1, __first2, __p); } template @@ -821,10 +792,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __p) { - return oneapi::dpl::__internal::__pattern_equal( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __p, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first1, __first2); + + return oneapi::dpl::__internal::__pattern_equal(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, + __last1, __first2, __last2, __p); } template @@ -843,11 +814,11 @@ move(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __l { using _DecayedExecutionPolicy = ::std::decay_t<_ExecutionPolicy>; + auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __d_first); + return oneapi::dpl::__internal::__pattern_walk2_brick( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, - oneapi::dpl::__internal::__brick_move<_DecayedExecutionPolicy>{}, - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, + oneapi::dpl::__internal::__brick_move{}); } // [partial.sort] @@ -857,10 +828,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy> partial_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp) { - oneapi::dpl::__internal::__pattern_partial_sort( - ::std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __comp, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + oneapi::dpl::__internal::__pattern_partial_sort(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, + __middle, __last, __comp); } template @@ -879,12 +850,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomA partial_sort_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _RandomAccessIterator __d_first, _RandomAccessIterator __d_last, _Compare __comp) { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __d_first); + return oneapi::dpl::__internal::__pattern_partial_sort_copy( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __d_last, __comp, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator, - _RandomAccessIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator, - _RandomAccessIterator>(__exec)); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __d_last, __comp); } template @@ -901,12 +870,11 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + const _ForwardIterator __res = oneapi::dpl::__internal::__pattern_adjacent_find( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, - oneapi::dpl::__internal::__reorder_pred<_Compare>(__comp), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__first_semantic()); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + oneapi::dpl::__internal::__reorder_pred<_Compare>(__comp), oneapi::dpl::__internal::__first_semantic()); return __res == __last ? __last : oneapi::dpl::__internal::__pstl_next(__res); } @@ -922,12 +890,12 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { - return oneapi::dpl::__internal::__pattern_adjacent_find( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, - oneapi::dpl::__internal::__reorder_pred<_Compare>(__comp), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__or_semantic()) == __last; + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_adjacent_find(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, + oneapi::dpl::__internal::__reorder_pred<_Compare>(__comp), + oneapi::dpl::__internal::__or_semantic()) == __last; } template @@ -945,12 +913,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Forward merge(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __d_first, _Compare __comp) { - return oneapi::dpl::__internal::__pattern_merge( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __d_first, __comp, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first1, __first2, __d_first); + + return oneapi::dpl::__internal::__pattern_merge(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, + __last1, __first2, __last2, __d_first, __comp); } template @@ -967,10 +933,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy> inplace_merge(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Compare __comp) { - oneapi::dpl::__internal::__pattern_inplace_merge( - ::std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __comp, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + oneapi::dpl::__internal::__pattern_inplace_merge(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, + __middle, __last, __comp); } template @@ -989,12 +955,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp) { - return oneapi::dpl::__internal::__pattern_includes( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __comp, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first1, __first2); + + return oneapi::dpl::__internal::__pattern_includes(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first1, __last1, __first2, __last2, __comp); } template @@ -1014,12 +978,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Forward set_union(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp) { - return oneapi::dpl::__internal::__pattern_set_union( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first1, __first2, __result); + + return oneapi::dpl::__internal::__pattern_set_union(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first1, __last1, __first2, __last2, __result, __comp); } template @@ -1039,12 +1001,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Forward set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp) { - return oneapi::dpl::__internal::__pattern_set_intersection( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first1, __first2, __result); + + return oneapi::dpl::__internal::__pattern_set_intersection(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first1, __last1, __first2, __last2, __result, __comp); } template @@ -1064,12 +1024,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Forward set_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp) { - return oneapi::dpl::__internal::__pattern_set_difference( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first1, __first2, __result); + + return oneapi::dpl::__internal::__pattern_set_difference(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first1, __last1, __first2, __last2, __result, __comp); } template @@ -1090,12 +1048,11 @@ set_symmetric_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp) { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first1, __first2, __result); + return oneapi::dpl::__internal::__pattern_set_symmetric_difference( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator>(__exec)); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, + __comp); } template @@ -1112,10 +1069,10 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { - return oneapi::dpl::__internal::__pattern_is_heap_until( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_is_heap_until(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __comp); } template @@ -1130,10 +1087,10 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { - return oneapi::dpl::__internal::__pattern_is_heap( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_is_heap(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, + __last, __comp); } template @@ -1150,10 +1107,10 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { - return oneapi::dpl::__internal::__pattern_min_element( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_min_element(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __comp); } template @@ -1185,10 +1142,10 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, ::std::pair<_ForwardIterator, _ForwardIterator>> minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { - return oneapi::dpl::__internal::__pattern_minmax_element( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_minmax_element(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __comp); } template @@ -1206,10 +1163,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy> nth_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) { - oneapi::dpl::__internal::__pattern_nth_element( - ::std::forward<_ExecutionPolicy>(__exec), __first, __nth, __last, __comp, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + oneapi::dpl::__internal::__pattern_nth_element(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, + __nth, __last, __comp); } template @@ -1228,12 +1185,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> lexicographical_compare(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp) { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first1, __first2); + return oneapi::dpl::__internal::__pattern_lexicographical_compare( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __comp, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __comp); } template @@ -1252,10 +1207,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Forward shift_left(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, typename ::std::iterator_traits<_ForwardIterator>::difference_type __n) { - return oneapi::dpl::__internal::__pattern_shift_left( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __n, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_shift_left(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __n); } // [shift.right] @@ -1265,10 +1220,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Bidirec shift_right(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, typename ::std::iterator_traits<_BidirectionalIterator>::difference_type __n) { - return oneapi::dpl::__internal::__pattern_shift_right( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __n, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_shift_right(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __n); } } // namespace dpl diff --git a/include/oneapi/dpl/pstl/glue_algorithm_ranges_impl.h b/include/oneapi/dpl/pstl/glue_algorithm_ranges_impl.h index bbe5cc72ac8..4e51d0e4e2a 100644 --- a/include/oneapi/dpl/pstl/glue_algorithm_ranges_impl.h +++ b/include/oneapi/dpl/pstl/glue_algorithm_ranges_impl.h @@ -39,7 +39,9 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> any_of(_ExecutionPolicy&& __exec, _Range&& __rng, _Predicate __pred) { - return oneapi::dpl::__internal::__ranges::__pattern_any_of(::std::forward<_ExecutionPolicy>(__exec), + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng); + + return oneapi::dpl::__internal::__ranges::__pattern_any_of(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range>(__rng)), __pred); } @@ -70,7 +72,9 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy> for_each(_ExecutionPolicy&& __exec, _Range&& __rng, _Function __f) { - oneapi::dpl::__internal::__ranges::__pattern_walk_n(::std::forward<_ExecutionPolicy>(__exec), __f, + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng); + + oneapi::dpl::__internal::__ranges::__pattern_walk_n(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __f, views::all(::std::forward<_Range>(__rng))); } @@ -80,7 +84,10 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, oneapi::dpl::__internal::__difference_t<_Range>> find_if(_ExecutionPolicy&& __exec, _Range&& __rng, _Predicate __pred) { - return oneapi::dpl::__internal::__ranges::__pattern_find_if(::std::forward<_ExecutionPolicy>(__exec), + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng); + + return oneapi::dpl::__internal::__ranges::__pattern_find_if(__dispatch_tag, + ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range>(__rng)), __pred); } @@ -111,8 +118,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, oneapi::dpl::__internal::__difference_t<_Range1>> find_end(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _BinaryPredicate __pred) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng1, __rng2); + return oneapi::dpl::__internal::__ranges::__pattern_find_end( - ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng1)), + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng1)), views::all_read(::std::forward<_Range2>(__rng2)), __pred); } @@ -132,8 +141,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, oneapi::dpl::__internal::__difference_t<_Range1>> find_first_of(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _BinaryPredicate __pred) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng1, __rng2); + return oneapi::dpl::__internal::__ranges::__pattern_find_first_of( - ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng1)), + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng1)), views::all_read(::std::forward<_Range2>(__rng2)), __pred); } @@ -152,9 +163,11 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, oneapi::dpl::__internal::__difference_t<_Range>> adjacent_find(_ExecutionPolicy&& __exec, _Range&& __rng, _BinaryPredicate __pred) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng); + return oneapi::dpl::__internal::__ranges::__pattern_adjacent_find( - ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range>(__rng)), __pred, - oneapi::dpl::__internal::__first_semantic()); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range>(__rng)), + __pred, oneapi::dpl::__internal::__first_semantic()); } template @@ -172,7 +185,9 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, oneapi::dpl::__internal::__difference_t<_Range>> count_if(_ExecutionPolicy&& __exec, _Range&& __rng, _Predicate __pred) { - return oneapi::dpl::__internal::__ranges::__pattern_count(::std::forward<_ExecutionPolicy>(__exec), + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng); + + return oneapi::dpl::__internal::__ranges::__pattern_count(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range>(__rng)), __pred); } @@ -193,8 +208,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, oneapi::dpl::__internal::__difference_t<_Range1>> search(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _BinaryPredicate __pred) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng1, __rng2); + return oneapi::dpl::__internal::__ranges::__pattern_search( - ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng1)), + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng1)), views::all_read(::std::forward<_Range2>(__rng2)), __pred); } @@ -211,9 +228,11 @@ template > search_n(_ExecutionPolicy&& __exec, _Range&& __rng, _Size __count, const _Tp& __value, _BinaryPredicate __pred) { - return oneapi::dpl::__internal::__ranges::__pattern_search_n(::std::forward<_ExecutionPolicy>(__exec), - views::all_read(::std::forward<_Range>(__rng)), - __count, __value, __pred); + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng); + + return oneapi::dpl::__internal::__ranges::__pattern_search_n( + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range>(__rng)), + __count, __value, __pred); } template @@ -230,8 +249,11 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy> copy(_ExecutionPolicy&& __exec, _Range1&& __rng, _Range2&& __result) { + auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng, __result); + oneapi::dpl::__internal::__ranges::__pattern_walk_n( - ::std::forward<_ExecutionPolicy>(__exec), oneapi::dpl::__internal::__brick_copy<_ExecutionPolicy>{}, + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + oneapi::dpl::__internal::__brick_copy{}, views::all_read(::std::forward<_Range1>(__rng)), views::all_write(::std::forward<_Range2>(__result))); } @@ -240,8 +262,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, oneapi::dpl::__internal::__difference_t<_Range2>> copy_if(_ExecutionPolicy&& __exec, _Range1&& __rng, _Range2&& __result, _Predicate __pred) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng, __result); + return oneapi::dpl::__internal::__ranges::__pattern_copy_if( - ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng)), + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng)), views::all_write(::std::forward<_Range2>(__result)), __pred, oneapi::dpl::__internal::__pstl_assign()); } @@ -252,11 +276,13 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, oneapi::dpl::__internal::__difference_t<_Range1>> swap_ranges(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng1, __rng2); + using _ReferenceType1 = oneapi::dpl::__internal::__value_t<_Range1>&; using _ReferenceType2 = oneapi::dpl::__internal::__value_t<_Range2>&; return oneapi::dpl::__internal::__ranges::__pattern_swap( - ::std::forward<_ExecutionPolicy>(__exec), views::all(::std::forward<_Range1>(__rng1)), + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all(::std::forward<_Range1>(__rng1)), views::all(::std::forward<_Range2>(__rng2)), [](_ReferenceType1 __x, _ReferenceType2 __y) { using ::std::swap; swap(__x, __y); @@ -269,8 +295,10 @@ template transform(_ExecutionPolicy&& __exec, _Range1&& __rng, _Range2&& __result, _UnaryOperation __op) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng, __result); + oneapi::dpl::__internal::__ranges::__pattern_walk_n( - ::std::forward<_ExecutionPolicy>(__exec), [__op](auto x, auto& z) { z = __op(x); }, + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), [__op](auto x, auto& z) { z = __op(x); }, views::all_read(::std::forward<_Range1>(__rng)), views::all_write(::std::forward<_Range2>(__result))); } @@ -278,8 +306,10 @@ template transform(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _Range3&& __result, _BinaryOperation __op) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng1, __rng2, __result); + oneapi::dpl::__internal::__ranges::__pattern_walk_n( - ::std::forward<_ExecutionPolicy>(__exec), [__op](auto x, auto y, auto& z) { z = __op(x, y); }, + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), [__op](auto x, auto y, auto& z) { z = __op(x, y); }, views::all_read(::std::forward<_Range1>(__rng1)), views::all_read(::std::forward<_Range2>(__rng2)), views::all_write(::std::forward<_Range3>(__result))); } @@ -290,8 +320,10 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, oneapi::dpl::__internal::__difference_t<_Range>> remove_if(_ExecutionPolicy&& __exec, _Range&& __rng, _UnaryPredicate __pred) { - return oneapi::dpl::__internal::__ranges::__pattern_remove_if(::std::forward<_ExecutionPolicy>(__exec), - views::all(::std::forward<_Range>(__rng)), __pred); + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng); + + return oneapi::dpl::__internal::__ranges::__pattern_remove_if( + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all(::std::forward<_Range>(__rng)), __pred); } template @@ -332,7 +364,9 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, oneapi::dpl::__internal::__difference_t<_Range>> unique(_ExecutionPolicy&& __exec, _Range&& __rng, _BinaryPredicate __pred) { - return oneapi::dpl::__internal::__ranges::__pattern_unique(::std::forward<_ExecutionPolicy>(__exec), + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng); + + return oneapi::dpl::__internal::__ranges::__pattern_unique(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all(::std::forward<_Range>(__rng)), __pred); } @@ -349,8 +383,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, oneapi::dpl::__internal::__difference_t<_Range2>> unique_copy(_ExecutionPolicy&& __exec, _Range1&& __rng, _Range2&& __result, _BinaryPredicate __pred) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng, __result); + return oneapi::dpl::__internal::__ranges::__pattern_unique_copy( - ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng)), + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng)), views::all_write(::std::forward<_Range2>(__result)), __pred, oneapi::dpl::__internal::__pstl_assign()); } @@ -406,8 +442,10 @@ template replace_if(_ExecutionPolicy&& __exec, _Range&& __rng, _UnaryPredicate __pred, const _Tp& __new_value) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng); + oneapi::dpl::__internal::__ranges::__pattern_walk_n( - ::std::forward<_ExecutionPolicy>(__exec), + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), oneapi::dpl::__internal::__replace_functor< oneapi::dpl::__internal::__ref_or_copy<_ExecutionPolicy, const _Tp>, oneapi::dpl::__internal::__ref_or_copy<_ExecutionPolicy, _UnaryPredicate>>(__new_value, __pred), @@ -431,9 +469,11 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, replace_copy_if(_ExecutionPolicy&& __exec, _Range1&& __rng, _Range2&& __result, _UnaryPredicate __pred, const _Tp& __new_value) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng, __result); + auto __src = views::all_read(::std::forward<_Range1>(__rng)); oneapi::dpl::__internal::__ranges::__pattern_walk_n( - ::std::forward<_ExecutionPolicy>(__exec), + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), oneapi::dpl::__internal::__replace_copy_functor< oneapi::dpl::__internal::__ref_or_copy<_ExecutionPolicy, const _Tp>, ::std::conditional_t, @@ -463,7 +503,9 @@ template sort(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp, _Proj __proj) { - oneapi::dpl::__internal::__ranges::__pattern_sort(::std::forward<_ExecutionPolicy>(__exec), + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng); + + oneapi::dpl::__internal::__ranges::__pattern_sort(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all(::std::forward<_Range>(__rng)), __comp, __proj); } @@ -498,10 +540,12 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, oneapi::dpl::__internal::__difference_t<_Range>> is_sorted_until(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng); + auto __view = views::all_read(::std::forward<_Range>(__rng)); const auto __res = oneapi::dpl::__internal::__ranges::__pattern_adjacent_find( - ::std::forward<_ExecutionPolicy>(__exec), __view, oneapi::dpl::__internal::__reorder_pred<_Compare>(__comp), - oneapi::dpl::__internal::__first_semantic()); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __view, + oneapi::dpl::__internal::__reorder_pred<_Compare>(__comp), oneapi::dpl::__internal::__first_semantic()); return __res == __view.size() ? __res : __res + 1; } @@ -518,9 +562,11 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> is_sorted(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng); + auto __view = views::all_read(::std::forward<_Range>(__rng)); return oneapi::dpl::__internal::__ranges::__pattern_adjacent_find( - ::std::forward<_ExecutionPolicy>(__exec), __view, + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __view, oneapi::dpl::__internal::__reorder_pred<_Compare>(__comp), oneapi::dpl::__internal::__or_semantic()) == __view.size(); } @@ -539,7 +585,9 @@ template equal(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _BinaryPredicate __p) { - return oneapi::dpl::__internal::__ranges::__pattern_equal(::std::forward<_ExecutionPolicy>(__exec), + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng1, __rng2); + + return oneapi::dpl::__internal::__ranges::__pattern_equal(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng1)), views::all_read(::std::forward<_Range2>(__rng2)), __p); } @@ -558,10 +606,13 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy> move(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2) { + auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng1, __rng2); + using _DecayedExecutionPolicy = ::std::decay_t<_ExecutionPolicy>; oneapi::dpl::__internal::__ranges::__pattern_walk_n( - ::std::forward<_ExecutionPolicy>(__exec), oneapi::dpl::__internal::__brick_move<_DecayedExecutionPolicy>{}, + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + oneapi::dpl::__internal::__brick_move{}, views::all_read(::std::forward<_Range1>(__rng1)), views::all_write(::std::forward<_Range2>(__rng2))); } @@ -572,8 +623,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, oneapi::dpl::__internal::__difference_t<_Range3>> merge(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _Range3&& __rng3, _Compare __comp) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng1, __rng2, __rng3); + return oneapi::dpl::__internal::__ranges::__pattern_merge( - ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng1)), + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng1)), views::all_read(::std::forward<_Range2>(__rng2)), views::all_write(::std::forward<_Range3>(__rng3)), __comp); } @@ -593,8 +646,11 @@ template oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, oneapi::dpl::__internal::__difference_t<_Range>> min_element(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng); + return oneapi::dpl::__internal::__ranges::__pattern_min_element( - ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range>(__rng)), __comp); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range>(__rng)), + __comp); } template @@ -628,8 +684,11 @@ oneapi::dpl::__internal::__enable_if_execution_policy< ::std::pair, oneapi::dpl::__internal::__difference_t<_Range>>> minmax_element(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng); + return oneapi::dpl::__internal::__ranges::__pattern_minmax_element( - ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range>(__rng)), __comp); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range>(__rng)), + __comp); } template @@ -649,8 +708,11 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, reduce_by_segment(_ExecutionPolicy&& __exec, _Range1&& __keys, _Range2&& __values, _Range3&& __out_keys, _Range4&& __out_values, _BinaryPredicate __binary_pred, _BinaryOperator __binary_op) { + const auto __dispatch_tag = + oneapi::dpl::__ranges::__select_backend(__exec, __keys, __values, __out_keys, __out_values); + return oneapi::dpl::__internal::__ranges::__pattern_reduce_by_segment( - ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__keys)), + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__keys)), views::all_read(::std::forward<_Range2>(__values)), views::all_write(::std::forward<_Range3>(__out_keys)), views::all_write(::std::forward<_Range4>(__out_values)), __binary_pred, __binary_op); } diff --git a/include/oneapi/dpl/pstl/glue_memory_impl.h b/include/oneapi/dpl/pstl/glue_memory_impl.h index 082856131e7..fac93889dfb 100644 --- a/include/oneapi/dpl/pstl/glue_memory_impl.h +++ b/include/oneapi/dpl/pstl/glue_memory_impl.h @@ -45,25 +45,19 @@ uninitialized_copy(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIter typedef typename ::std::iterator_traits<_ForwardIterator>::value_type _ValueType2; typedef ::std::decay_t<_ExecutionPolicy> _DecayedExecutionPolicy; - const auto __is_parallel = - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>( - __exec); - const auto __is_vector = - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>( - __exec); + auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __result); if constexpr (::std::is_trivial_v<_ValueType1> && ::std::is_trivial_v<_ValueType2>) { return oneapi::dpl::__internal::__pattern_walk2_brick( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, - oneapi::dpl::__internal::__brick_copy<_DecayedExecutionPolicy>{}, __is_parallel); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, + oneapi::dpl::__internal::__brick_copy{}); } else { return oneapi::dpl::__internal::__pattern_walk2( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, - oneapi::dpl::__internal::__op_uninitialized_copy<_DecayedExecutionPolicy>{}, __is_vector, - __is_parallel); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, + oneapi::dpl::__internal::__op_uninitialized_copy<_DecayedExecutionPolicy>{}); } } @@ -75,25 +69,19 @@ uninitialized_copy_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __ typedef typename ::std::iterator_traits<_ForwardIterator>::value_type _ValueType2; typedef ::std::decay_t<_ExecutionPolicy> _DecayedExecutionPolicy; - const auto __is_parallel = - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>( - __exec); - const auto __is_vector = - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>( - __exec); + auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __result); if constexpr (::std::is_trivial_v<_ValueType1> && ::std::is_trivial_v<_ValueType2>) { return oneapi::dpl::__internal::__pattern_walk2_brick_n( - ::std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, - oneapi::dpl::__internal::__brick_copy_n<_DecayedExecutionPolicy>{}, __is_parallel); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, + oneapi::dpl::__internal::__brick_copy_n{}); } else { return oneapi::dpl::__internal::__pattern_walk2_n( - ::std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, - oneapi::dpl::__internal::__op_uninitialized_copy<_DecayedExecutionPolicy>{}, __is_vector, - __is_parallel); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, + oneapi::dpl::__internal::__op_uninitialized_copy<_DecayedExecutionPolicy>{}); } } @@ -107,25 +95,19 @@ uninitialized_move(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIter typedef typename ::std::iterator_traits<_ForwardIterator>::value_type _ValueType2; typedef ::std::decay_t<_ExecutionPolicy> _DecayedExecutionPolicy; - const auto __is_parallel = - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>( - __exec); - const auto __is_vector = - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>( - __exec); + auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __result); if constexpr (::std::is_trivial_v<_ValueType1> && ::std::is_trivial_v<_ValueType2>) { return oneapi::dpl::__internal::__pattern_walk2_brick( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, - oneapi::dpl::__internal::__brick_copy<_DecayedExecutionPolicy>{}, __is_parallel); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, + oneapi::dpl::__internal::__brick_copy{}); } else { return oneapi::dpl::__internal::__pattern_walk2( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, - oneapi::dpl::__internal::__op_uninitialized_move<_DecayedExecutionPolicy>{}, __is_vector, - __is_parallel); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, + oneapi::dpl::__internal::__op_uninitialized_move<_DecayedExecutionPolicy>{}); } } @@ -137,25 +119,19 @@ uninitialized_move_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __ typedef typename ::std::iterator_traits<_ForwardIterator>::value_type _ValueType2; typedef ::std::decay_t<_ExecutionPolicy> _DecayedExecutionPolicy; - const auto __is_parallel = - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>( - __exec); - const auto __is_vector = - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>( - __exec); + auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __result); if constexpr (::std::is_trivial_v<_ValueType1> && ::std::is_trivial_v<_ValueType2>) { return oneapi::dpl::__internal::__pattern_walk2_brick_n( - ::std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, - oneapi::dpl::__internal::__brick_copy_n<_DecayedExecutionPolicy>{}, __is_parallel); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, + oneapi::dpl::__internal::__brick_copy_n{}); } else { return oneapi::dpl::__internal::__pattern_walk2_n( - ::std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, - oneapi::dpl::__internal::__op_uninitialized_move<_DecayedExecutionPolicy>{}, __is_vector, - __is_parallel); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, + oneapi::dpl::__internal::__op_uninitialized_move<_DecayedExecutionPolicy>{}); } } @@ -168,24 +144,20 @@ uninitialized_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Forward typedef typename ::std::iterator_traits<_ForwardIterator>::value_type _ValueType; typedef ::std::decay_t<_ExecutionPolicy> _DecayedExecutionPolicy; - const auto __is_parallel = - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); - const auto __is_vector = - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); + auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); if constexpr (::std::is_arithmetic_v<_ValueType>) { oneapi::dpl::__internal::__pattern_walk_brick( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, - oneapi::dpl::__internal::__brick_fill<_ValueType, _DecayedExecutionPolicy>{_ValueType(__value)}, - __is_parallel); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + oneapi::dpl::__internal::__brick_fill{ + _ValueType(__value)}); } else { oneapi::dpl::__internal::__pattern_walk1( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, - oneapi::dpl::__internal::__op_uninitialized_fill<_Tp, _DecayedExecutionPolicy>{__value}, __is_vector, - __is_parallel); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + oneapi::dpl::__internal::__op_uninitialized_fill<_Tp, _DecayedExecutionPolicy>{__value}); } } @@ -196,27 +168,46 @@ uninitialized_fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size typedef typename ::std::iterator_traits<_ForwardIterator>::value_type _ValueType; typedef ::std::decay_t<_ExecutionPolicy> _DecayedExecutionPolicy; - const auto __is_parallel = - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); - const auto __is_vector = - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); + auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); if constexpr (::std::is_arithmetic_v<_ValueType>) { return oneapi::dpl::__internal::__pattern_walk_brick_n( - ::std::forward<_ExecutionPolicy>(__exec), __first, __n, - oneapi::dpl::__internal::__brick_fill_n<_ValueType, _DecayedExecutionPolicy>{_ValueType(__value)}, - __is_parallel); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __n, + oneapi::dpl::__internal::__brick_fill_n{ + _ValueType(__value)}); } else { return oneapi::dpl::__internal::__pattern_walk1_n( - ::std::forward<_ExecutionPolicy>(__exec), __first, __n, - oneapi::dpl::__internal::__op_uninitialized_fill<_Tp, _DecayedExecutionPolicy>{__value}, __is_vector, - __is_parallel); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __n, + oneapi::dpl::__internal::__op_uninitialized_fill<_Tp, _DecayedExecutionPolicy>{__value}); } } +#if (_PSTL_ICPX_OMP_SIMD_DESTROY_WINDOWS_BROKEN || _ONEDPL_ICPX_OMP_SIMD_DESTROY_WINDOWS_BROKEN) + +const oneapi::dpl::execution::parallel_policy& +get_unvectorized_policy(const oneapi::dpl::execution::parallel_unsequenced_policy&) +{ + return oneapi::dpl::execution::par; +} + +const oneapi::dpl::execution::sequenced_policy& +get_unvectorized_policy(const oneapi::dpl::execution::unsequenced_policy&) +{ + return oneapi::dpl::execution::seq; +} + +template +const _ExecutionPolicy& +get_unvectorized_policy(const _ExecutionPolicy& __exec) +{ + return __exec; +} + +#endif // (_PSTL_ICPX_OMP_SIMD_DESTROY_WINDOWS_BROKEN || _ONEDPL_ICPX_OMP_SIMD_DESTROY_WINDOWS_BROKEN) + // [specialized.destroy] template @@ -226,25 +217,17 @@ destroy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __ typedef typename ::std::iterator_traits<_ForwardIterator>::value_type _ValueType; typedef typename ::std::iterator_traits<_ForwardIterator>::reference _ReferenceType; - const auto __is_parallel = - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); - using _is_vector_type = + if constexpr (!::std::is_trivially_destructible_v<_ValueType>) + { + const auto __dispatch_tag = #if (_PSTL_ICPX_OMP_SIMD_DESTROY_WINDOWS_BROKEN || _ONEDPL_ICPX_OMP_SIMD_DESTROY_WINDOWS_BROKEN) - ::std::conditional_t< - oneapi::dpl::__internal::__is_host_execution_policy<::std::decay_t<_ExecutionPolicy>>::value, - ::std::false_type, - decltype(oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>( - __exec))>; + oneapi::dpl::__internal::__select_backend(get_unvectorized_policy(__exec), __first); #else - decltype(oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); -#endif // _PSTL_ICPX_OMP_SIMD_DESTROY_WINDOWS_BROKEN || _ONEDPL_ICPX_OMP_SIMD_DESTROY_WINDOWS_BROKEN - constexpr _is_vector_type __is_vector; + oneapi::dpl::__internal::__select_backend(__exec, __first); +#endif - if constexpr (!::std::is_trivially_destructible_v<_ValueType>) - { - oneapi::dpl::__internal::__pattern_walk1( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, - [](_ReferenceType __val) { __val.~_ValueType(); }, __is_vector, __is_parallel); + oneapi::dpl::__internal::__pattern_walk1(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, + __last, [](_ReferenceType __val) { __val.~_ValueType(); }); } } @@ -255,29 +238,22 @@ destroy_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n) typedef typename ::std::iterator_traits<_ForwardIterator>::value_type _ValueType; typedef typename ::std::iterator_traits<_ForwardIterator>::reference _ReferenceType; - const auto __is_parallel = - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); - using _is_vector_type = -#if (_PSTL_ICPX_OMP_SIMD_DESTROY_WINDOWS_BROKEN || _ONEDPL_ICPX_OMP_SIMD_DESTROY_WINDOWS_BROKEN) - ::std::conditional_t< - oneapi::dpl::__internal::__is_host_execution_policy<::std::decay_t<_ExecutionPolicy>>::value, - ::std::false_type, - decltype(oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>( - __exec))>; -#else - decltype(oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); -#endif // _PSTL_ICPX_OMP_SIMD_DESTROY_WINDOWS_BROKEN || _ONEDPL_ICPX_OMP_SIMD_DESTROY_WINDOWS_BROKEN - constexpr _is_vector_type __is_vector; - if constexpr (::std::is_trivially_destructible_v<_ValueType>) { return oneapi::dpl::__internal::__pstl_next(__first, __n); } else { - return oneapi::dpl::__internal::__pattern_walk1_n(::std::forward<_ExecutionPolicy>(__exec), __first, __n, - [](_ReferenceType __val) { __val.~_ValueType(); }, - __is_vector, __is_parallel); + const auto __dispatch_tag = +#if (_PSTL_ICPX_OMP_SIMD_DESTROY_WINDOWS_BROKEN || _ONEDPL_ICPX_OMP_SIMD_DESTROY_WINDOWS_BROKEN) + oneapi::dpl::__internal::__select_backend(get_unvectorized_policy(__exec), __first); +#else + oneapi::dpl::__internal::__select_backend(__exec, __first); +#endif + + return oneapi::dpl::__internal::__pattern_walk1_n(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __n, + [](_ReferenceType __val) { __val.~_ValueType(); }); } } @@ -290,17 +266,13 @@ uninitialized_default_construct(_ExecutionPolicy&& __exec, _ForwardIterator __fi typedef typename ::std::iterator_traits<_ForwardIterator>::value_type _ValueType; typedef ::std::decay_t<_ExecutionPolicy> _DecayedExecutionPolicy; - const auto __is_parallel = - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); - const auto __is_vector = - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); - if constexpr (!::std::is_trivial_v<_ValueType>) { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + oneapi::dpl::__internal::__pattern_walk1( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, - oneapi::dpl::__internal::__op_uninitialized_default_construct<_DecayedExecutionPolicy>{}, __is_vector, - __is_parallel); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + oneapi::dpl::__internal::__op_uninitialized_default_construct<_DecayedExecutionPolicy>{}); } } @@ -311,21 +283,17 @@ uninitialized_default_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __ typedef typename ::std::iterator_traits<_ForwardIterator>::value_type _ValueType; typedef ::std::decay_t<_ExecutionPolicy> _DecayedExecutionPolicy; - const auto __is_parallel = - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); - const auto __is_vector = - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); - if constexpr (::std::is_trivial_v<_ValueType>) { return oneapi::dpl::__internal::__pstl_next(__first, __n); } else { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + return oneapi::dpl::__internal::__pattern_walk1_n( - ::std::forward<_ExecutionPolicy>(__exec), __first, __n, - oneapi::dpl::__internal::__op_uninitialized_default_construct<_DecayedExecutionPolicy>{}, __is_vector, - __is_parallel); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __n, + oneapi::dpl::__internal::__op_uninitialized_default_construct<_DecayedExecutionPolicy>{}); } } @@ -338,24 +306,20 @@ uninitialized_value_construct(_ExecutionPolicy&& __exec, _ForwardIterator __firs typedef typename ::std::iterator_traits<_ForwardIterator>::value_type _ValueType; typedef ::std::decay_t<_ExecutionPolicy> _DecayedExecutionPolicy; - const auto __is_parallel = - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); - const auto __is_vector = - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); + auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); if constexpr (::std::is_trivial_v<_ValueType>) { oneapi::dpl::__internal::__pattern_walk_brick( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, - oneapi::dpl::__internal::__brick_fill<_ValueType, _DecayedExecutionPolicy>{_ValueType()}, - __is_parallel); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + oneapi::dpl::__internal::__brick_fill{ + _ValueType()}); } else { oneapi::dpl::__internal::__pattern_walk1( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, - oneapi::dpl::__internal::__op_uninitialized_value_construct<_DecayedExecutionPolicy>{}, __is_vector, - __is_parallel); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + oneapi::dpl::__internal::__op_uninitialized_value_construct<_DecayedExecutionPolicy>{}); } } @@ -366,24 +330,20 @@ uninitialized_value_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __fi typedef typename ::std::iterator_traits<_ForwardIterator>::value_type _ValueType; typedef ::std::decay_t<_ExecutionPolicy> _DecayedExecutionPolicy; - const auto __is_parallel = - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); - const auto __is_vector = - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec); + auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); if constexpr (::std::is_trivial_v<_ValueType>) { return oneapi::dpl::__internal::__pattern_walk_brick_n( - ::std::forward<_ExecutionPolicy>(__exec), __first, __n, - oneapi::dpl::__internal::__brick_fill_n<_ValueType, _DecayedExecutionPolicy>{_ValueType()}, - __is_parallel); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __n, + oneapi::dpl::__internal::__brick_fill_n{ + _ValueType()}); } else { return oneapi::dpl::__internal::__pattern_walk1_n( - ::std::forward<_ExecutionPolicy>(__exec), __first, __n, - oneapi::dpl::__internal::__op_uninitialized_value_construct<_DecayedExecutionPolicy>{}, __is_vector, - __is_parallel); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __n, + oneapi::dpl::__internal::__op_uninitialized_value_construct<_DecayedExecutionPolicy>{}); } } diff --git a/include/oneapi/dpl/pstl/glue_numeric_impl.h b/include/oneapi/dpl/pstl/glue_numeric_impl.h index f2564db3132..17ed09d0ca4 100644 --- a/include/oneapi/dpl/pstl/glue_numeric_impl.h +++ b/include/oneapi/dpl/pstl/glue_numeric_impl.h @@ -70,13 +70,12 @@ transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forward _ForwardIterator2 __first2, _Tp __init) { typedef typename ::std::iterator_traits<_ForwardIterator1>::value_type _InputType; + + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first1, __first2); + return oneapi::dpl::__internal::__pattern_transform_reduce( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __init, ::std::plus<_InputType>(), - ::std::multiplies<_InputType>(), - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __init, + ::std::plus<_InputType>(), ::std::multiplies<_InputType>()); } template transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) { - return oneapi::dpl::__internal::__pattern_transform_reduce( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __init, __binary_op1, __binary_op2, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first1, __first2); + + return oneapi::dpl::__internal::__pattern_transform_reduce(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first1, __last1, __first2, __init, __binary_op1, + __binary_op2); } template @@ -98,10 +96,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __unary_op) { - return oneapi::dpl::__internal::__pattern_transform_reduce( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, __binary_op, __unary_op, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first); + + return oneapi::dpl::__internal::__pattern_transform_reduce(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __init, __binary_op, __unary_op); } // [exclusive.scan] @@ -225,13 +223,11 @@ transform_exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ _ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __unary_op) { - return oneapi::dpl::__internal::__pattern_transform_scan( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __unary_op, __init, __binary_op, - /*inclusive=*/::std::false_type(), - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __result); + + return oneapi::dpl::__internal::__pattern_transform_scan(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __result, __unary_op, __init, __binary_op, + /*inclusive=*/::std::false_type()); } // [transform.inclusive.scan] @@ -243,13 +239,11 @@ transform_inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ _ForwardIterator2 __result, _BinaryOperation __binary_op, _UnaryOperation __unary_op, _Tp __init) { - return oneapi::dpl::__internal::__pattern_transform_scan( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __unary_op, __init, __binary_op, - /*inclusive=*/::std::true_type(), - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __result); + + return oneapi::dpl::__internal::__pattern_transform_scan(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __result, __unary_op, __init, __binary_op, + /*inclusive=*/::std::true_type()); } template (__exec), __first, __last, __result, __unary_op, __binary_op, - /*inclusive=*/::std::true_type(), - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __result); + + return oneapi::dpl::__internal::__pattern_transform_scan(__dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), + __first, __last, __result, __unary_op, __binary_op, + /*inclusive=*/::std::true_type()); } // [adjacent.difference] @@ -274,16 +266,13 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Forward adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first, _BinaryOperation __op) { - if (__first == __last) return __d_first; + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(__exec, __first, __d_first); + return oneapi::dpl::__internal::__pattern_adjacent_difference( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __op, - oneapi::dpl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec), - oneapi::dpl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( - __exec)); + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __op); } template diff --git a/include/oneapi/dpl/pstl/glue_numeric_ranges_impl.h b/include/oneapi/dpl/pstl/glue_numeric_ranges_impl.h index 42d7c6e15a3..521ebee46b7 100644 --- a/include/oneapi/dpl/pstl/glue_numeric_ranges_impl.h +++ b/include/oneapi/dpl/pstl/glue_numeric_ranges_impl.h @@ -63,9 +63,11 @@ template transform_reduce(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _Tp __init) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng1, __rng2); + using _ValueType = oneapi::dpl::__internal::__value_t<_Range1>; return oneapi::dpl::__internal::__ranges::__pattern_transform_reduce( - ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng1)), + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng1)), views::all_read(::std::forward<_Range2>(__rng2)), __init, ::std::plus<_ValueType>(), ::std::multiplies<_ValueType>()); } @@ -76,8 +78,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> transform_reduce(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng1, __rng2); + return oneapi::dpl::__internal::__ranges::__pattern_transform_reduce( - ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng1)), + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng1)), views::all_read(::std::forward<_Range2>(__rng2)), __init, __binary_op1, __binary_op2); } @@ -86,9 +90,11 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> transform_reduce(_ExecutionPolicy&& __exec, _Range&& __rng, _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __unary_op) { - return oneapi::dpl::__internal::__ranges::__pattern_transform_reduce(::std::forward<_ExecutionPolicy>(__exec), - views::all_read(::std::forward<_Range>(__rng)), - __init, __binary_op, __unary_op); + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng); + + return oneapi::dpl::__internal::__ranges::__pattern_transform_reduce( + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range>(__rng)), + __init, __binary_op, __unary_op); } // [exclusive.scan] @@ -154,8 +160,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, transform_exclusive_scan(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __unary_op) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng1, __rng2); + return oneapi::dpl::__internal::__ranges::__pattern_transform_scan( - ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng1)), + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng1)), views::all_write(::std::forward<_Range2>(__rng2)), __unary_op, __init, __binary_op, /*inclusive=*/::std::false_type()); } @@ -169,8 +177,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, transform_inclusive_scan(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _BinaryOperation __binary_op, _UnaryOperation __unary_op, _Tp __init) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng1, __rng2); + return oneapi::dpl::__internal::__ranges::__pattern_transform_scan( - ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng1)), + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng1)), views::all_write(::std::forward<_Range2>(__rng2)), __unary_op, __init, __binary_op, /*inclusive=*/::std::true_type()); } @@ -182,8 +192,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, transform_inclusive_scan(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _BinaryOperation __binary_op, _UnaryOperation __unary_op) { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec, __rng1, __rng2); + return oneapi::dpl::__internal::__ranges::__pattern_transform_scan( - ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng1)), + __dispatch_tag, ::std::forward<_ExecutionPolicy>(__exec), views::all_read(::std::forward<_Range1>(__rng1)), views::all_write(::std::forward<_Range2>(__rng2)), __unary_op, __binary_op, /*inclusive=*/::std::true_type()); } diff --git a/include/oneapi/dpl/pstl/hetero/algorithm_impl_hetero.h b/include/oneapi/dpl/pstl/hetero/algorithm_impl_hetero.h index 677be98e975..a630c1cc2dd 100644 --- a/include/oneapi/dpl/pstl/hetero/algorithm_impl_hetero.h +++ b/include/oneapi/dpl/pstl/hetero/algorithm_impl_hetero.h @@ -39,10 +39,10 @@ namespace __internal // walk1 //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy> -__pattern_walk1(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Function __f, - /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +void +__pattern_walk1(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, + _Function __f) { auto __n = __last - __first; if (__n <= 0) @@ -52,9 +52,8 @@ __pattern_walk1(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIte oneapi::dpl::__ranges::__get_sycl_range<__par_backend_hetero::access_mode::read_write, _ForwardIterator>(); auto __buf = __keep(__first, __last); - oneapi::dpl::__par_backend_hetero::__parallel_for(::std::forward<_ExecutionPolicy>(__exec), - unseq_backend::walk_n<_ExecutionPolicy, _Function>{__f}, __n, - __buf.all_view()) + oneapi::dpl::__par_backend_hetero::__parallel_for( + _BackendTag{}, __exec, unseq_backend::walk_n<_ExecutionPolicy, _Function>{__f}, __n, __buf.all_view()) .wait(); } @@ -62,13 +61,13 @@ __pattern_walk1(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIte // walk1_n //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_walk1_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, _Function __f, - /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +_ForwardIterator +__pattern_walk1_n(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, + _Function __f) { - __pattern_walk1(::std::forward<_ExecutionPolicy>(__exec), __first, __first + __n, __f, - /*vector=*/::std::true_type(), /*parallel=*/::std::true_type()); + __pattern_walk1(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __first + __n, __f); return __first + __n; } @@ -82,10 +81,11 @@ __pattern_walk1_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _ForwardIterator2> -__pattern_walk2(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Function __f, /*vector=*/::std::true_type, /*parallel=*/::std::true_type) + typename _BackendTag, typename _ExecutionPolicy, typename _ForwardIterator1, typename _ForwardIterator2, + typename _Function> +_ForwardIterator2 +__pattern_walk2(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _ForwardIterator1 __last1, _ForwardIterator2 __first2, _Function __f) { auto __n = __last1 - __first1; if (__n <= 0) @@ -98,8 +98,8 @@ __pattern_walk2(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardI auto __buf2 = __keep2(__first2, __first2 + __n); auto __future_obj = oneapi::dpl::__par_backend_hetero::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), unseq_backend::walk_n<_ExecutionPolicy, _Function>{__f}, __n, - __buf1.all_view(), __buf2.all_view()); + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), + unseq_backend::walk_n<_ExecutionPolicy, _Function>{__f}, __n, __buf1.all_view(), __buf2.all_view()); if constexpr (_IsSync()) __future_obj.wait(); @@ -107,45 +107,42 @@ __pattern_walk2(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardI return __first2 + __n; } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _ForwardIterator2> -__pattern_walk2_n(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Size __n, _ForwardIterator2 __first2, - _Function __f, /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +_ForwardIterator2 +__pattern_walk2_n(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Size __n, + _ForwardIterator2 __first2, _Function __f) { - return __pattern_walk2(::std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, __first2, __f, - ::std::true_type(), ::std::true_type()); + return __pattern_walk2(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, __first2, __f); } //------------------------------------------------------------------------ // swap //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _ForwardIterator2> -__pattern_swap(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Function __f, /*is_vector=*/::std::true_type, - /*is_parallel=*/::std::true_type) +template +_ForwardIterator2 +__pattern_swap(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _ForwardIterator1 __last1, _ForwardIterator2 __first2, _Function __f) { return __pattern_walk2(::std::forward<_ExecutionPolicy>(__exec), - __first1, __last1, __first2, __f, - ::std::true_type(), ::std::true_type()); + __par_backend_hetero::access_mode::read_write>( + __tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __f); } //------------------------------------------------------------------------ // walk3 //------------------------------------------------------------------------ -template <__par_backend_hetero::access_mode __acc_mode1 = __par_backend_hetero::access_mode::read, +template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _ForwardIterator3> -__pattern_walk3(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator3 __first3, _Function __f, /*vector=*/::std::true_type, - /*parallel=*/::std::true_type) +_ForwardIterator3 +__pattern_walk3(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator3 __first3, _Function __f) { auto __n = __last1 - __first1; if (__n <= 0) @@ -158,7 +155,7 @@ __pattern_walk3(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardI auto __keep3 = oneapi::dpl::__ranges::__get_sycl_range<__acc_mode3, _ForwardIterator3>(); auto __buf3 = __keep3(__first3, __first3 + __n); - oneapi::dpl::__par_backend_hetero::__parallel_for(::std::forward<_ExecutionPolicy>(__exec), + oneapi::dpl::__par_backend_hetero::__parallel_for(_BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), unseq_backend::walk_n<_ExecutionPolicy, _Function>{__f}, __n, __buf1.all_view(), __buf2.all_view(), __buf3.all_view()) .wait(); @@ -175,18 +172,18 @@ struct __walk_brick_wrapper { }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy> -__pattern_walk_brick(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Function __f, - /*parallel=*/::std::true_type) +template +void +__pattern_walk_brick(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _ForwardIterator __first, + _ForwardIterator __last, _Function __f) { if (__last - __first <= 0) return; __pattern_walk1( + __tag, __par_backend_hetero::make_wrapped_policy<__walk_brick_wrapper>(::std::forward<_ExecutionPolicy>(__exec)), - __first, __last, __f, - /*vector=*/::std::true_type{}, /*parallel=*/::std::true_type{}); + __first, __last, __f); } template @@ -194,15 +191,16 @@ struct __walk_brick_n_wrapper { }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_walk_brick_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, _Function __f, - /*parallel=*/::std::true_type) +template +_ForwardIterator +__pattern_walk_brick_n(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, + _Function __f) { __pattern_walk1( + __tag, __par_backend_hetero::make_wrapped_policy<__walk_brick_n_wrapper>(::std::forward<_ExecutionPolicy>(__exec)), - __first, __first + __n, __f, - /*vector=*/::std::true_type{}, /*parallel=*/::std::true_type{}); + __first, __first + __n, __f); return __first + __n; } @@ -215,15 +213,16 @@ struct __walk2_brick_wrapper { }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _ForwardIterator2> -__pattern_walk2_brick(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Brick __brick, /*parallel*/ ::std::true_type) +template +_ForwardIterator2 +__pattern_walk2_brick(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _ForwardIterator1 __last1, _ForwardIterator2 __first2, _Brick __brick) { return __pattern_walk2( + __tag, __par_backend_hetero::make_wrapped_policy<__walk2_brick_wrapper>(::std::forward<_ExecutionPolicy>(__exec)), - __first1, __last1, __first2, __brick, - /*vector=*/::std::true_type{}, /*parallel*/ ::std::true_type{}); + __first1, __last1, __first2, __brick); } template @@ -231,17 +230,16 @@ struct __walk2_brick_n_wrapper { }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _ForwardIterator2> -__pattern_walk2_brick_n(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Size __n, _ForwardIterator2 __first2, - _Brick __brick, /*parallel*/ ::std::true_type) +template +_ForwardIterator2 +__pattern_walk2_brick_n(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _Size __n, _ForwardIterator2 __first2, _Brick __brick) { - return __pattern_walk2( + __tag, __par_backend_hetero::make_wrapped_policy<__walk2_brick_n_wrapper>(::std::forward<_ExecutionPolicy>(__exec)), - __first1, __first1 + __n, __first2, __brick, - /*vector=*/::std::true_type{}, /*parallel*/ ::std::true_type{}); + __first1, __first1 + __n, __first2, __brick); } //------------------------------------------------------------------------ @@ -253,21 +251,20 @@ struct __walk2_transform_if_wrapper { }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _ForwardIterator2> -__pattern_walk2_transform_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Function __func, - /*vector=*/::std::true_type, - /*parallel=*/::std::true_type) +template +_ForwardIterator2 +__pattern_walk2_transform_if(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _ForwardIterator1 __last1, _ForwardIterator2 __first2, _Function __func) { // Require `read_write` access mode for output sequence to force a copy in for host iterators to capture incoming // values of the output sequence for elements where the predicate is false. return __pattern_walk2( + __tag, __par_backend_hetero::make_wrapped_policy<__walk2_transform_if_wrapper>( ::std::forward<_ExecutionPolicy>(__exec)), - __first1, __last1, __first2, __func, - /*vector=*/::std::true_type{}, /*parallel*/ ::std::true_type{}); + __first1, __last1, __first2, __func); } template @@ -275,22 +272,21 @@ struct __walk3_transform_if_wrapper { }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _ForwardIterator3> -__pattern_walk3_transform_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator3 __first3, _Function __func, - /*vector=*/::std::true_type, - /*parallel=*/::std::true_type) +template +_ForwardIterator3 +__pattern_walk3_transform_if(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator3 __first3, + _Function __func) { // Require `read_write` access mode for output sequence to force a copy in for host iterators to capture incoming // values of the output sequence for elements where the predicate is false. - return __pattern_walk3<__par_backend_hetero::access_mode::read, __par_backend_hetero::access_mode::read, - __par_backend_hetero::access_mode::read_write>( + return __pattern_walk3<_BackendTag, __par_backend_hetero::access_mode::read, + __par_backend_hetero::access_mode::read, __par_backend_hetero::access_mode::read_write>( + __tag, __par_backend_hetero::make_wrapped_policy<__walk3_transform_if_wrapper>( ::std::forward<_ExecutionPolicy>(__exec)), - __first1, __last1, __first2, __first3, __func, - /*vector=*/::std::true_type{}, /*parallel*/ ::std::true_type{}); + __first1, __last1, __first2, __first3, __func); } //------------------------------------------------------------------------ @@ -309,18 +305,26 @@ struct fill_functor } }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _T& __value, - /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +_ForwardIterator +__pattern_fill(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _ForwardIterator __first, + _ForwardIterator __last, const _T& __value) { - __pattern_walk1(::std::forward<_ExecutionPolicy>(__exec), + __pattern_walk1(__tag, ::std::forward<_ExecutionPolicy>(__exec), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::write>(__first), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::write>(__last), - fill_functor<_T>{__value}, ::std::true_type{}, ::std::true_type{}); + fill_functor<_T>{__value}); return __last; } +template +_ForwardIterator +__pattern_fill_n(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __count, + const _T& __value) +{ + return __pattern_fill(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __first + __count, __value); +} + //------------------------------------------------------------------------ // generate //------------------------------------------------------------------------ @@ -338,24 +342,32 @@ struct generate_functor } }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_generate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Generator __g, - /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +_ForwardIterator +__pattern_generate(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _ForwardIterator __first, + _ForwardIterator __last, _Generator __g) { - __pattern_walk1(::std::forward<_ExecutionPolicy>(__exec), + __pattern_walk1(__tag, ::std::forward<_ExecutionPolicy>(__exec), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::write>(__first), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::write>(__last), - generate_functor<_Generator>{__g}, ::std::true_type{}, ::std::true_type{}); + generate_functor<_Generator>{__g}); return __last; } +template +_ForwardIterator +__pattern_generate_n(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _ForwardIterator __first, + _Size __count, _Generator __g) +{ + return __pattern_generate(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __first + __count, __g); +} + //------------------------------------------------------------------------ // brick_copy, brick_move //------------------------------------------------------------------------ -template -struct __brick_copy_n<_ExecutionPolicy, oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy>> +template +struct __brick_copy_n<__hetero_tag<_BackendTag>, _ExecutionPolicy> { template void @@ -365,48 +377,46 @@ struct __brick_copy_n<_ExecutionPolicy, oneapi::dpl::__internal::__enable_if_het } }; -template -struct __brick_copy<_ExecutionPolicy, oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy>> +template +struct __brick_copy<__hetero_tag<_BackendTag>, _ExecutionPolicy> { template - oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy> + void operator()(_SourceT&& __source, _TargetT&& __target) const { __target = ::std::forward<_SourceT>(__source); } }; -template -struct __brick_move<_ExecutionPolicy, oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy>> +template +struct __brick_move<__hetero_tag<_BackendTag>, _ExecutionPolicy> { template - oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy> + void operator()(_SourceT&& __source, _TargetT&& __target) const { __target = ::std::move(__source); } }; -template -struct __brick_fill<_SourceT, _ExecutionPolicy, - oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy>> +template +struct __brick_fill<__hetero_tag<_BackendTag>, _ExecutionPolicy, _SourceT> { _SourceT __value; template - oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy> + void operator()(_TargetT& __target) const { __target = __value; } }; -template -struct __brick_fill_n<_SourceT, _ExecutionPolicy, - oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy>> +template +struct __brick_fill_n<__hetero_tag<_BackendTag>, _ExecutionPolicy, _SourceT> { _SourceT __value; template - oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy> + void operator()(_TargetT& __target) const { __target = __value; @@ -417,10 +427,10 @@ struct __brick_fill_n<_SourceT, _ExecutionPolicy, // min_element, max_element //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator> -__pattern_min_element(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _Compare __comp, - /*vector*/ ::std::true_type, /*parallel*/ ::std::true_type) +template +_Iterator +__pattern_min_element(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, + _Compare __comp) { if (__first == __last) return __last; @@ -467,7 +477,7 @@ __pattern_min_element(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __ auto __buf = __keep(__first, __last); auto __ret_idx = oneapi::dpl::__par_backend_hetero::__parallel_transform_reduce<_ReduceValueType, _Commutative>( - ::std::forward<_ExecutionPolicy>(__exec), __reduce_fn, __transform_fn, + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __reduce_fn, __transform_fn, unseq_backend::__no_init_value{}, // no initial value __buf.all_view()) .get(); @@ -493,10 +503,10 @@ __pattern_min_element(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __ // However the solution requires use of custom pattern or substantial redesign of existing parallel_transform_reduce. // -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, ::std::pair<_Iterator, _Iterator>> -__pattern_minmax_element(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _Compare __comp, - /*vector*/ ::std::true_type, /*parallel*/ ::std::true_type) +template +::std::pair<_Iterator, _Iterator> +__pattern_minmax_element(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, + _Compare __comp) { if (__first == __last) return ::std::make_pair(__first, __first); @@ -535,7 +545,7 @@ __pattern_minmax_element(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator auto __ret = oneapi::dpl::__par_backend_hetero::__parallel_transform_reduce<_ReduceValueType, ::std::false_type /*is_commutative*/>( - ::std::forward<_ExecutionPolicy>(__exec), __reduce_fn, __transform_fn, + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __reduce_fn, __transform_fn, unseq_backend::__no_init_value{}, // no initial value __buf.all_view()) .get(); @@ -547,11 +557,10 @@ __pattern_minmax_element(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator // adjacent_find //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator> -__pattern_adjacent_find(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _BinaryPredicate __predicate, - /*parallel*/ ::std::true_type, /*vector*/ ::std::true_type, - oneapi::dpl::__internal::__or_semantic) +template +_Iterator +__pattern_adjacent_find(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, + _BinaryPredicate __predicate, oneapi::dpl::__internal::__or_semantic) { if (__last - __first < 2) return __last; @@ -567,8 +576,8 @@ __pattern_adjacent_find(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator // TODO: in case of confilicting names // __par_backend_hetero::make_wrapped_policy<__par_backend_hetero::__or_policy_wrapper>() bool result = __par_backend_hetero::__parallel_find_or( - ::std::forward<_ExecutionPolicy>(__exec), _Predicate{adjacent_find_fn<_BinaryPredicate>{__predicate}}, - __par_backend_hetero::__parallel_or_tag{}, + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), + _Predicate{adjacent_find_fn<_BinaryPredicate>{__predicate}}, __par_backend_hetero::__parallel_or_tag{}, oneapi::dpl::__ranges::make_zip_view(__buf1.all_view(), __buf2.all_view())); // inverted conditional because of @@ -576,11 +585,10 @@ __pattern_adjacent_find(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator return result ? __first : __last; } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator> -__pattern_adjacent_find(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _BinaryPredicate __predicate, - /*parallel*/ ::std::true_type, /*vector*/ ::std::true_type, - oneapi::dpl::__internal::__first_semantic) +template +_Iterator +__pattern_adjacent_find(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, + _BinaryPredicate __predicate, oneapi::dpl::__internal::__first_semantic) { if (__last - __first < 2) return __last; @@ -589,7 +597,7 @@ __pattern_adjacent_find(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator oneapi::dpl::unseq_backend::single_match_pred<_ExecutionPolicy, adjacent_find_fn<_BinaryPredicate>>; auto __result = __par_backend_hetero::__parallel_find( - ::std::forward<_ExecutionPolicy>(__exec), + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __par_backend_hetero::zip( __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__first), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__first + 1)), @@ -609,11 +617,10 @@ __pattern_adjacent_find(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator // count, count_if //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy< - _ExecutionPolicy, typename ::std::iterator_traits<_Iterator>::difference_type> -__pattern_count(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _Predicate __predicate, - /*parallel*/ ::std::true_type, /*vector*/ ::std::true_type) +template +typename ::std::iterator_traits<_Iterator>::difference_type +__pattern_count(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, + _Predicate __predicate) { if (__first == __last) return 0; @@ -632,7 +639,7 @@ __pattern_count(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, return oneapi::dpl::__par_backend_hetero::__parallel_transform_reduce<_ReduceValueType, ::std::true_type /*is_commutative*/>( - ::std::forward<_ExecutionPolicy>(__exec), __reduce_fn, __transform_fn, + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __reduce_fn, __transform_fn, unseq_backend::__no_init_value{}, // no initial value __buf.all_view()) .get(); @@ -642,10 +649,10 @@ __pattern_count(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, // any_of //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, bool> -__pattern_any_of(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _Pred __pred, - /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +bool +__pattern_any_of(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, + _Pred __pred) { if (__first == __last) return false; @@ -656,6 +663,7 @@ __pattern_any_of(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, auto __buf = __keep(__first, __last); return oneapi::dpl::__par_backend_hetero::__parallel_find_or( + _BackendTag{}, __par_backend_hetero::make_wrapped_policy<__par_backend_hetero::__or_policy_wrapper>( ::std::forward<_ExecutionPolicy>(__exec)), _Predicate{__pred}, __par_backend_hetero::__parallel_or_tag{}, __buf.all_view()); @@ -665,11 +673,10 @@ __pattern_any_of(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, // equal //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, bool> -__pattern_equal(_ExecutionPolicy&& __exec, _Iterator1 __first1, _Iterator1 __last1, _Iterator2 __first2, - _Iterator2 __last2, _Pred __pred, - /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +bool +__pattern_equal(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Iterator1 __first1, _Iterator1 __last1, + _Iterator2 __first2, _Iterator2 __last2, _Pred __pred) { if (__last1 == __first1 || __last2 == __first2 || __last1 - __first1 != __last2 - __first2) return false; @@ -684,7 +691,7 @@ __pattern_equal(_ExecutionPolicy&& __exec, _Iterator1 __first1, _Iterator1 __las // TODO: in case of confilicting names // __par_backend_hetero::make_wrapped_policy<__par_backend_hetero::__or_policy_wrapper>() return !__par_backend_hetero::__parallel_find_or( - ::std::forward<_ExecutionPolicy>(__exec), _Predicate{equal_predicate<_Pred>{__pred}}, + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), _Predicate{equal_predicate<_Pred>{__pred}}, __par_backend_hetero::__parallel_or_tag{}, oneapi::dpl::__ranges::make_zip_view(__buf1.all_view(), __buf2.all_view())); } @@ -693,24 +700,23 @@ __pattern_equal(_ExecutionPolicy&& __exec, _Iterator1 __first1, _Iterator1 __las // equal version for sequences with equal length //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, bool> -__pattern_equal(_ExecutionPolicy&& __exec, _Iterator1 __first1, _Iterator1 __last1, _Iterator2 __first2, _Pred __pred, - /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +bool +__pattern_equal(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator1 __first1, _Iterator1 __last1, + _Iterator2 __first2, _Pred __pred) { - return oneapi::dpl::__internal::__pattern_equal(::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - __first2, __first2 + (__last1 - __first1), __pred, - /*vector=*/::std::true_type{}, /*parallel=*/::std::true_type{}); + return oneapi::dpl::__internal::__pattern_equal(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, + __first2, __first2 + (__last1 - __first1), __pred); } //------------------------------------------------------------------------ // find_if //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator> -__pattern_find_if(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _Pred __pred, - /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +_Iterator +__pattern_find_if(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, + _Pred __pred) { if (__first == __last) return __last; @@ -718,7 +724,7 @@ __pattern_find_if(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last using _Predicate = oneapi::dpl::unseq_backend::single_match_pred<_ExecutionPolicy, _Pred>; return __par_backend_hetero::__parallel_find( - ::std::forward<_ExecutionPolicy>(__exec), + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__first), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__last), _Predicate{__pred}, ::std::true_type{}); @@ -728,18 +734,18 @@ __pattern_find_if(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last // find_end //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator1> -__pattern_find_end(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, _Iterator2 __s_first, - _Iterator2 __s_last, _Pred __pred, /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +_Iterator1 +__pattern_find_end(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, + _Iterator2 __s_first, _Iterator2 __s_last, _Pred __pred) { if (__first == __last || __s_last == __s_first || __last - __first < __s_last - __s_first) return __last; if (__last - __first == __s_last - __s_first) { - const bool __res = __pattern_equal(::std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __pred, - ::std::true_type(), ::std::true_type()); + const bool __res = + __pattern_equal(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __pred); return __res ? __first : __last; } else @@ -747,7 +753,7 @@ __pattern_find_end(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __l using _Predicate = unseq_backend::multiple_match_pred<_ExecutionPolicy, _Pred>; return __par_backend_hetero::__parallel_find( - ::std::forward<_ExecutionPolicy>(__exec), + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__first), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__last), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__s_first), @@ -760,10 +766,10 @@ __pattern_find_end(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __l // find_first_of //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator1> -__pattern_find_first_of(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, _Iterator2 __s_first, - _Iterator2 __s_last, _Pred __pred, /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +_Iterator1 +__pattern_find_first_of(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, + _Iterator2 __s_first, _Iterator2 __s_last, _Pred __pred) { if (__first == __last || __s_last == __s_first) return __last; @@ -773,7 +779,7 @@ __pattern_find_first_of(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator // TODO: To check whether it makes sense to iterate over the second sequence in case of // distance(__first, __last) < distance(__s_first, __s_last). return __par_backend_hetero::__parallel_find( - ::std::forward<_ExecutionPolicy>(__exec), + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__first), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__last), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__s_first), @@ -790,10 +796,10 @@ class equal_wrapper { }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator1> -__pattern_search(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, _Iterator2 __s_first, - _Iterator2 __s_last, _Pred __pred, /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +_Iterator1 +__pattern_search(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, + _Iterator2 __s_first, _Iterator2 __s_last, _Pred __pred) { if (__s_last == __s_first) return __first; @@ -804,14 +810,14 @@ __pattern_search(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __las if (__last - __first == __s_last - __s_first) { const bool __res = __pattern_equal( - __par_backend_hetero::make_wrapped_policy(::std::forward<_ExecutionPolicy>(__exec)), __first, - __last, __s_first, __pred, ::std::true_type(), ::std::true_type()); + __tag, __par_backend_hetero::make_wrapped_policy(::std::forward<_ExecutionPolicy>(__exec)), + __first, __last, __s_first, __pred); return __res ? __first : __last; } using _Predicate = unseq_backend::multiple_match_pred<_ExecutionPolicy, _Pred>; return __par_backend_hetero::__parallel_find( - ::std::forward<_ExecutionPolicy>(__exec), + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__first), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__last), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__s_first), @@ -837,10 +843,11 @@ struct __search_n_unary_predicate } }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator> -__pattern_search_n(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _Size __count, const _Tp& __value, - _BinaryPredicate __pred, /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +_Iterator +__pattern_search_n(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, + _Size __count, const _Tp& __value, _BinaryPredicate __pred) { if (__count <= 0) return __first; @@ -850,16 +857,15 @@ __pattern_search_n(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __las if (__last - __first == __count) { - return (!__internal::__pattern_any_of(::std::forward<_ExecutionPolicy>(__exec), __first, __last, - __search_n_unary_predicate<_Tp, _BinaryPredicate>{__value, __pred}, - ::std::true_type{}, ::std::true_type{})) + return (!__internal::__pattern_any_of(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + __search_n_unary_predicate<_Tp, _BinaryPredicate>{__value, __pred})) ? __first : __last; } using _Predicate = unseq_backend::n_elem_match_pred<_ExecutionPolicy, _BinaryPredicate, _Tp, _Size>; return __par_backend_hetero::__parallel_find( - ::std::forward<_ExecutionPolicy>(__exec), + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__first), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__last), _Predicate{__pred, __value, __count}, ::std::true_type{}); @@ -869,10 +875,10 @@ __pattern_search_n(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __las // mismatch //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, ::std::pair<_Iterator1, _Iterator2>> -__pattern_mismatch(_ExecutionPolicy&& __exec, _Iterator1 __first1, _Iterator1 __last1, _Iterator2 __first2, - _Iterator2 __last2, _Pred __pred, /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +::std::pair<_Iterator1, _Iterator2> +__pattern_mismatch(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Iterator1 __first1, _Iterator1 __last1, + _Iterator2 __first2, _Iterator2 __last2, _Pred __pred) { auto __n = ::std::min(__last1 - __first1, __last2 - __first2); if (__n <= 0) @@ -883,9 +889,9 @@ __pattern_mismatch(_ExecutionPolicy&& __exec, _Iterator1 __first1, _Iterator1 __ auto __first_zip = __par_backend_hetero::zip( __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__first1), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__first2)); - auto __result = - __par_backend_hetero::__parallel_find(::std::forward<_ExecutionPolicy>(__exec), __first_zip, __first_zip + __n, - _Predicate{equal_predicate<_Pred>{__pred}}, ::std::true_type{}); + auto __result = __par_backend_hetero::__parallel_find( + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __first_zip, __first_zip + __n, + _Predicate{equal_predicate<_Pred>{__pred}}, ::std::true_type{}); __n = __result - __first_zip; return ::std::make_pair(__first1 + __n, __first2 + __n); } @@ -894,12 +900,11 @@ __pattern_mismatch(_ExecutionPolicy&& __exec, _Iterator1 __first1, _Iterator1 __ // copy_if //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy< - _ExecutionPolicy, ::std::pair<_IteratorOrTuple, typename ::std::iterator_traits<_Iterator1>::difference_type>> -__pattern_scan_copy(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, _IteratorOrTuple __output_first, - _CreateMaskOp __create_mask_op, _CopyByMaskOp __copy_by_mask_op) +template +::std::pair<_IteratorOrTuple, typename ::std::iterator_traits<_Iterator1>::difference_type> +__pattern_scan_copy(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, + _IteratorOrTuple __output_first, _CreateMaskOp __create_mask_op, _CopyByMaskOp __copy_by_mask_op) { using _It1DifferenceType = typename ::std::iterator_traits<_Iterator1>::difference_type; @@ -914,18 +919,19 @@ __pattern_scan_copy(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __ oneapi::dpl::__ranges::__get_sycl_range<__par_backend_hetero::access_mode::write, _IteratorOrTuple>(); auto __buf2 = __keep2(__output_first, __output_first + __n); - auto __res = - __par_backend_hetero::__parallel_scan_copy(::std::forward<_ExecutionPolicy>(__exec), __buf1.all_view(), - __buf2.all_view(), __n, __create_mask_op, __copy_by_mask_op); + auto __res = __par_backend_hetero::__parallel_scan_copy(_BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), + __buf1.all_view(), __buf2.all_view(), __n, __create_mask_op, + __copy_by_mask_op); ::std::size_t __num_copied = __res.get(); return ::std::make_pair(__output_first + __n, __num_copied); } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator2> -__pattern_copy_if(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, _Iterator2 __result_first, - _Predicate __pred, /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +_Iterator2 +__pattern_copy_if(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, + _Iterator2 __result_first, _Predicate __pred) { using _It1DifferenceType = typename ::std::iterator_traits<_Iterator1>::difference_type; @@ -939,8 +945,8 @@ __pattern_copy_if(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __la auto __keep2 = oneapi::dpl::__ranges::__get_sycl_range<__par_backend_hetero::access_mode::write, _Iterator2>(); auto __buf2 = __keep2(__result_first, __result_first + __n); - auto __res = __par_backend_hetero::__parallel_copy_if(::std::forward<_ExecutionPolicy>(__exec), __buf1.all_view(), - __buf2.all_view(), __n, __pred); + auto __res = __par_backend_hetero::__parallel_copy_if(_BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), + __buf1.all_view(), __buf2.all_view(), __n, __pred); ::std::size_t __num_copied = __res.get(); return __result_first + __num_copied; @@ -950,12 +956,11 @@ __pattern_copy_if(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __la // partition_copy //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, ::std::pair<_Iterator2, _Iterator3>> -__pattern_partition_copy(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, _Iterator2 __result1, - _Iterator3 __result2, _UnaryPredicate __pred, /*vector*/ ::std::true_type, - /*parallel*/ ::std::true_type) +template +::std::pair<_Iterator2, _Iterator3> +__pattern_partition_copy(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator1 __first, + _Iterator1 __last, _Iterator2 __result1, _Iterator3 __result2, _UnaryPredicate __pred) { if (__first == __last) return ::std::make_pair(__result1, __result2); @@ -967,7 +972,7 @@ __pattern_partition_copy(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterato unseq_backend::__partition_by_mask<_ReduceOp, /*inclusive*/ ::std::true_type> __copy_by_mask_op{_ReduceOp{}}; auto __result = __pattern_scan_copy( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + __tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __par_backend_hetero::zip( __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::write>(__result1), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::write>(__result2)), @@ -980,10 +985,11 @@ __pattern_partition_copy(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterato // unique_copy //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator2> -__pattern_unique_copy(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, _Iterator2 __result_first, - _BinaryPredicate __pred, /*vector*/ ::std::true_type, /*parallel*/ ::std::true_type) +template +_Iterator2 +__pattern_unique_copy(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, + _Iterator2 __result_first, _BinaryPredicate __pred) { using _It1DifferenceType = typename ::std::iterator_traits<_Iterator1>::difference_type; unseq_backend::__copy_by_mask<::std::plus<_It1DifferenceType>, oneapi::dpl::__internal::__pstl_assign, @@ -992,8 +998,8 @@ __pattern_unique_copy(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __create_mask_unique_copy<__not_pred<_BinaryPredicate>, _It1DifferenceType> __create_mask_op{ __not_pred<_BinaryPredicate>{__pred}}; - auto __result = __pattern_scan_copy(::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result_first, - __create_mask_op, __copy_by_mask_op); + auto __result = __pattern_scan_copy(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + __result_first, __create_mask_op, __copy_by_mask_op); return __result_first + __result.second; } @@ -1007,10 +1013,10 @@ class copy_back_wrapper2 { }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator> -__pattern_remove_if(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _Predicate __pred, - /*vector*/ ::std::true_type, /*parallel*/ ::std::true_type) +template +_Iterator +__pattern_remove_if(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, + _Predicate __pred) { if (__last == __first) return __last; @@ -1019,19 +1025,19 @@ __pattern_remove_if(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __la oneapi::dpl::__par_backend_hetero::__buffer<_ExecutionPolicy, _ValueType> __buf(__exec, __last - __first); auto __copy_first = __buf.get(); - auto __copy_last = __pattern_copy_if(__exec, __first, __last, __copy_first, __not_pred<_Predicate>{__pred}, - /*vector=*/::std::true_type{}, /*parallel*/ ::std::true_type{}); + + auto __copy_last = __pattern_copy_if(__tag, __exec, __first, __last, __copy_first, __not_pred<_Predicate>{__pred}); //TODO: optimize copy back depending on Iterator, i.e. set_final_data for host iterator/pointer return __pattern_walk2( - __par_backend_hetero::make_wrapped_policy(::std::forward<_ExecutionPolicy>(__exec)), - __copy_first, __copy_last, __first, __brick_copy<_ExecutionPolicy>{}, ::std::true_type{}, ::std::true_type{}); + __tag, __par_backend_hetero::make_wrapped_policy(::std::forward<_ExecutionPolicy>(__exec)), + __copy_first, __copy_last, __first, __brick_copy<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}); } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator> -__pattern_unique(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _BinaryPredicate __pred, - /*vector*/ ::std::true_type, /*parallel*/ ::std::true_type) +template +_Iterator +__pattern_unique(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, + _BinaryPredicate __pred) { if (__last - __first < 2) return __last; @@ -1040,14 +1046,13 @@ __pattern_unique(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, oneapi::dpl::__par_backend_hetero::__buffer<_ExecutionPolicy, _ValueType> __buf(__exec, __last - __first); auto __copy_first = __buf.get(); - auto __copy_last = __pattern_unique_copy(__exec, __first, __last, __copy_first, __pred, - /*vector=*/::std::true_type{}, /*parallel*/ ::std::true_type{}); + auto __copy_last = __pattern_unique_copy(__tag, __exec, __first, __last, __copy_first, __pred); //TODO: optimize copy back depending on Iterator, i.e. set_final_data for host iterator/pointer return __pattern_walk2( - __par_backend_hetero::make_wrapped_policy(::std::forward<_ExecutionPolicy>(__exec)), - __copy_first, __copy_last, __first, __brick_copy<_ExecutionPolicy>{}, ::std::true_type{}, ::std::true_type{}); + __tag, __par_backend_hetero::make_wrapped_policy(::std::forward<_ExecutionPolicy>(__exec)), + __copy_first, __copy_last, __first, __brick_copy<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}); } //------------------------------------------------------------------------ @@ -1062,10 +1067,10 @@ enum _IsPartitionedReduceType : signed char __true_false }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, bool> -__pattern_is_partitioned(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _Predicate __predicate, - /*parallel*/ ::std::true_type, /*vector*/ ::std::true_type) +template +bool +__pattern_is_partitioned(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, + _Predicate __predicate) { if (__last - __first < 2) return true; @@ -1086,7 +1091,7 @@ __pattern_is_partitioned(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator auto __res = oneapi::dpl::__par_backend_hetero::__parallel_transform_reduce<_ReduceValueType, ::std::false_type /*is_commutative*/>( - ::std::forward<_ExecutionPolicy>(__exec), __reduce_fn, __transform_fn, + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __reduce_fn, __transform_fn, unseq_backend::__no_init_value{}, // no initial value __buf.all_view()) .get(); @@ -1113,10 +1118,10 @@ struct __is_heap_check } }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -__pattern_is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Compare __comp, /* vector */ ::std::true_type, /* parallel = */ ::std::true_type) +template +_RandomAccessIterator +__pattern_is_heap_until(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) { if (__last - __first < 2) return __last; @@ -1125,16 +1130,16 @@ __pattern_is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first oneapi::dpl::unseq_backend::single_match_pred_by_idx<_ExecutionPolicy, __is_heap_check<_Compare>>; return __par_backend_hetero::__parallel_find( - ::std::forward<_ExecutionPolicy>(__exec), + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__first), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__last), _Predicate{__comp}, ::std::true_type{}); } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, bool> -__pattern_is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Compare __comp, /* vector */ ::std::true_type, /* parallel = */ ::std::true_type) +template +bool +__pattern_is_heap(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) { if (__last - __first < 2) return true; @@ -1143,7 +1148,7 @@ __pattern_is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Ran oneapi::dpl::unseq_backend::single_match_pred_by_idx<_ExecutionPolicy, __is_heap_check<_Compare>>; return !__par_backend_hetero::__parallel_or( - ::std::forward<_ExecutionPolicy>(__exec), + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__first), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__last), _Predicate{__comp}); } @@ -1151,11 +1156,12 @@ __pattern_is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Ran //------------------------------------------------------------------------ // merge //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator3> -__pattern_merge(_ExecutionPolicy&& __exec, _Iterator1 __first1, _Iterator1 __last1, _Iterator2 __first2, - _Iterator2 __last2, _Iterator3 __d_first, _Compare __comp, /*vector=*/::std::true_type, - /*parallel=*/::std::true_type) + +template +_Iterator3 +__pattern_merge(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator1 __first1, _Iterator1 __last1, + _Iterator2 __first2, _Iterator2 __last2, _Iterator3 __d_first, _Compare __comp) { auto __n1 = __last1 - __first1; auto __n2 = __last2 - __first2; @@ -1166,16 +1172,18 @@ __pattern_merge(_ExecutionPolicy&& __exec, _Iterator1 __first1, _Iterator1 __las //To consider the direct copying pattern call in case just one of sequences is empty. if (__n1 == 0) oneapi::dpl::__internal::__pattern_walk2_brick( + __tag, oneapi::dpl::__par_backend_hetero::make_wrapped_policy( ::std::forward<_ExecutionPolicy>(__exec)), - __first2, __last2, __d_first, oneapi::dpl::__internal::__brick_copy<_ExecutionPolicy>{}, - ::std::true_type()); + __first2, __last2, __d_first, + oneapi::dpl::__internal::__brick_copy<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}); else if (__n2 == 0) oneapi::dpl::__internal::__pattern_walk2_brick( + __tag, oneapi::dpl::__par_backend_hetero::make_wrapped_policy( ::std::forward<_ExecutionPolicy>(__exec)), - __first1, __last1, __d_first, oneapi::dpl::__internal::__brick_copy<_ExecutionPolicy>{}, - ::std::true_type()); + __first1, __last1, __d_first, + oneapi::dpl::__internal::__brick_copy<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}); else { auto __keep1 = oneapi::dpl::__ranges::__get_sycl_range<__par_backend_hetero::access_mode::read, _Iterator1>(); @@ -1186,19 +1194,21 @@ __pattern_merge(_ExecutionPolicy&& __exec, _Iterator1 __first1, _Iterator1 __las auto __keep3 = oneapi::dpl::__ranges::__get_sycl_range<__par_backend_hetero::access_mode::write, _Iterator3>(); auto __buf3 = __keep3(__d_first, __d_first + __n); - __par_backend_hetero::__parallel_merge(::std::forward<_ExecutionPolicy>(__exec), __buf1.all_view(), - __buf2.all_view(), __buf3.all_view(), __comp) + __par_backend_hetero::__parallel_merge(_BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), + __buf1.all_view(), __buf2.all_view(), __buf3.all_view(), __comp) .wait(); } return __d_first + __n; } + //------------------------------------------------------------------------ // inplace_merge //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy> -__pattern_inplace_merge(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __middle, _Iterator __last, - _Compare __comp, /*vector=*/::std::true_type, /*parallel=*/::std::true_type) + +template +void +__pattern_inplace_merge(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator __first, + _Iterator __middle, _Iterator __last, _Compare __comp) { using _ValueType = typename ::std::iterator_traits<_Iterator>::value_type; @@ -1212,26 +1222,26 @@ __pattern_inplace_merge(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator auto __copy_first = __buf.get(); auto __copy_last = __copy_first + __n; - __pattern_merge(__exec, __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__first), - __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__middle), - __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__middle), - __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__last), - __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::write>(__copy_first), - __comp, ::std::true_type{}, ::std::true_type{}); + __pattern_merge( + __tag, __exec, __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__first), + __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__middle), + __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__middle), + __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__last), + __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::write>(__copy_first), __comp); //TODO: optimize copy back depending on Iterator, i.e. set_final_data for host iterator/pointer __pattern_walk2( - __par_backend_hetero::make_wrapped_policy(::std::forward<_ExecutionPolicy>(__exec)), - __copy_first, __copy_last, __first, __brick_move<_ExecutionPolicy>{}, ::std::true_type{}, ::std::true_type{}); + __tag, __par_backend_hetero::make_wrapped_policy(::std::forward<_ExecutionPolicy>(__exec)), + __copy_first, __copy_last, __first, __brick_move<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}); } //------------------------------------------------------------------------ // sort //------------------------------------------------------------------------ -template +template void -__stable_sort_with_projection(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _Compare __comp, - _Proj __proj) +__stable_sort_with_projection(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, + _Compare __comp, _Proj __proj) { if (__last - __first < 2) return; @@ -1239,60 +1249,58 @@ __stable_sort_with_projection(_ExecutionPolicy&& __exec, _Iterator __first, _Ite auto __keep = oneapi::dpl::__ranges::__get_sycl_range<__par_backend_hetero::access_mode::read_write, _Iterator>(); auto __buf = __keep(__first, __last); - __par_backend_hetero::__parallel_stable_sort( - ::std::forward<_ExecutionPolicy>(__exec), __buf.all_view(), __comp, __proj).wait(); + __par_backend_hetero::__parallel_stable_sort(_BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), + __buf.all_view(), __comp, __proj) + .wait(); } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy> -__pattern_sort(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _Compare __comp, - /*vector=*/::std::true_type, /*parallel=*/::std::true_type, /*is_move_constructible=*/::std::true_type) +template +void +__pattern_sort(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, + _Compare __comp, /*is_move_constructible=*/::std::true_type) { - __stable_sort_with_projection(::std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, + __stable_sort_with_projection(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, oneapi::dpl::identity{}); } //------------------------------------------------------------------------ // stable_sort //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy> -__pattern_stable_sort(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _Compare __comp, - /*vector=*/::std::true_type, /*parallel=*/::std::true_type) + +template +void +__pattern_stable_sort(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, + _Compare __comp) { - __stable_sort_with_projection(::std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, + __stable_sort_with_projection(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, oneapi::dpl::identity{}); } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy> -__pattern_sort_by_key(_ExecutionPolicy&& __exec, _Iterator1 __keys_first, _Iterator1 __keys_last, - _Iterator2 __values_first, _Compare __comp, /*vector=*/::std::true_type, - /*parallel=*/::std::true_type) +template +void +__pattern_sort_by_key(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator1 __keys_first, + _Iterator1 __keys_last, _Iterator2 __values_first, _Compare __comp) { - static_assert(::std::is_move_constructible_v::value_type> - && ::std::is_move_constructible_v::value_type>, - "The keys and values should be move constructible in case of parallel execution."); + static_assert(::std::is_move_constructible_v::value_type> && + ::std::is_move_constructible_v::value_type>, + "The keys and values should be move constructible in case of parallel execution."); auto __beg = oneapi::dpl::make_zip_iterator(__keys_first, __values_first); auto __end = __beg + (__keys_last - __keys_first); - __stable_sort_with_projection(::std::forward<_ExecutionPolicy>(__exec), __beg, __end, __comp, + __stable_sort_with_projection(__tag, ::std::forward<_ExecutionPolicy>(__exec), __beg, __end, __comp, [](const auto& __a) { return ::std::get<0>(__a); }); } - -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator> -__pattern_stable_partition(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _UnaryPredicate __pred, - /*vector*/ ::std::true_type, /*parallel*/ ::std::true_type) +template +_Iterator +__pattern_stable_partition(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator __first, + _Iterator __last, _UnaryPredicate __pred) { if (__last == __first) return __last; else if (__last - __first < 2) - return __pattern_any_of(::std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, ::std::true_type(), - ::std::true_type()) - ? __last - : __first; + return __pattern_any_of(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred) ? __last + : __first; using _ValueType = typename ::std::iterator_traits<_Iterator>::value_type; @@ -1303,42 +1311,39 @@ __pattern_stable_partition(_ExecutionPolicy&& __exec, _Iterator __first, _Iterat auto __true_result = __true_buf.get(); auto __false_result = __false_buf.get(); - auto copy_result = __pattern_partition_copy(__exec, __first, __last, __true_result, __false_result, __pred, - /*vector=*/::std::true_type{}, /*parallel*/ ::std::true_type{}); + auto copy_result = __pattern_partition_copy(__tag, __exec, __first, __last, __true_result, __false_result, __pred); auto true_count = copy_result.first - __true_result; //TODO: optimize copy back if possible (inplace, decrease number of submits) __pattern_walk2( - __par_backend_hetero::make_wrapped_policy(__exec), - __true_result, copy_result.first, __first, __brick_move<_ExecutionPolicy>{}, ::std::true_type{}, - ::std::true_type{}); + __tag, __par_backend_hetero::make_wrapped_policy(__exec), __true_result, copy_result.first, + __first, __brick_move<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}); + __pattern_walk2( - __par_backend_hetero::make_wrapped_policy(::std::forward<_ExecutionPolicy>(__exec)), - __false_result, copy_result.second, __first + true_count, __brick_move<_ExecutionPolicy>{}, ::std::true_type{}, - ::std::true_type{}); + __tag, __par_backend_hetero::make_wrapped_policy(::std::forward<_ExecutionPolicy>(__exec)), + __false_result, copy_result.second, __first + true_count, + __brick_move<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}); return __first + true_count; } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator> -__pattern_partition(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _UnaryPredicate __pred, - /*vector*/ ::std::true_type, /*parallel*/ ::std::true_type) +template +_Iterator +__pattern_partition(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, + _UnaryPredicate __pred) { //TODO: consider nonstable approaches - return __pattern_stable_partition(::std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, - ::std::true_type(), ::std::true_type()); + return __pattern_stable_partition(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred); } //------------------------------------------------------------------------ // lexicographical_compare //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, bool> -__pattern_lexicographical_compare(_ExecutionPolicy&& __exec, _Iterator1 __first1, _Iterator1 __last1, - _Iterator2 __first2, _Iterator2 __last2, _Compare __comp, /*vector*/ ::std::true_type, - /*parallel*/ ::std::true_type) +template +bool +__pattern_lexicographical_compare(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Iterator1 __first1, + _Iterator1 __last1, _Iterator2 __first2, _Iterator2 __last2, _Compare __comp) { //trivial pre-checks if (__first2 == __last2) @@ -1375,7 +1380,7 @@ __pattern_lexicographical_compare(_ExecutionPolicy&& __exec, _Iterator1 __first1 auto __ret_idx = oneapi::dpl::__par_backend_hetero::__parallel_transform_reduce<_ReduceValueType, ::std::false_type /*is_commutative*/>( - ::std::forward<_ExecutionPolicy>(__exec), __reduce_fn, __transform_fn, + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __reduce_fn, __transform_fn, unseq_backend::__no_init_value{}, // no initial value __buf1.all_view(), __buf2.all_view()) .get(); @@ -1383,11 +1388,11 @@ __pattern_lexicographical_compare(_ExecutionPolicy&& __exec, _Iterator1 __first1 return __ret_idx ? __ret_idx == 1 : (__last1 - __first1) < (__last2 - __first2); } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, bool> -__pattern_includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp, /*vector=*/::std::true_type, - /*parallel=*/::std::true_type) +template +bool +__pattern_includes(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp) { //according to the spec if (__first2 == __last2) @@ -1403,7 +1408,7 @@ __pattern_includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forwa using __brick_include_type = unseq_backend::__brick_includes<_ExecutionPolicy, _Compare, _Size1, _Size2>; return !__par_backend_hetero::__parallel_or( - ::std::forward<_ExecutionPolicy>(__exec), + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__first2), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__last2), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read>(__first1), @@ -1414,16 +1419,17 @@ __pattern_includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forwa //------------------------------------------------------------------------ // partial_sort //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy> -__pattern_partial_sort(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __mid, _Iterator __last, _Compare __comp, - /*vector=*/::std::true_type, /*parallel=*/::std::true_type) + +template +void +__pattern_partial_sort(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __mid, + _Iterator __last, _Compare __comp) { if (__last - __first < 2) return; __par_backend_hetero::__parallel_partial_sort( - ::std::forward<_ExecutionPolicy>(__exec), + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read_write>(__first), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read_write>(__mid), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read_write>(__last), __comp) @@ -1459,11 +1465,11 @@ struct __partial_sort_2 { }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _OutIterator> -__pattern_partial_sort_copy(_ExecutionPolicy&& __exec, _InIterator __first, _InIterator __last, - _OutIterator __out_first, _OutIterator __out_last, _Compare __comp, - /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +_OutIterator +__pattern_partial_sort_copy(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _InIterator __first, + _InIterator __last, _OutIterator __out_first, _OutIterator __out_last, _Compare __comp) { using _ValueType = typename ::std::iterator_traits<_InIterator>::value_type; @@ -1481,13 +1487,14 @@ __pattern_partial_sort_copy(_ExecutionPolicy&& __exec, _InIterator __first, _InI // If our output buffer is larger than the input buffer, simply copy elements to the output and use // full sort on them. auto __out_end = __pattern_walk2( - __par_backend_hetero::make_wrapped_policy<__initial_copy_1>(__exec), __first, __last, __out_first, - __brick_copy<_ExecutionPolicy>{}, ::std::true_type{}, ::std::true_type{}); + __tag, __par_backend_hetero::make_wrapped_policy<__initial_copy_1>(__exec), __first, __last, __out_first, + __brick_copy<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}); - // Use reqular sort as partial_sort isn't required to be stable + // Use regular sort as partial_sort isn't required to be stable __pattern_sort( + __tag, __par_backend_hetero::make_wrapped_policy<__partial_sort_1>(::std::forward<_ExecutionPolicy>(__exec)), - __out_first, __out_end, __comp, ::std::true_type{}, ::std::true_type{}, ::std::true_type{}); + __out_first, __out_end, __comp, ::std::true_type{}); return __out_end; } @@ -1500,22 +1507,22 @@ __pattern_partial_sort_copy(_ExecutionPolicy&& __exec, _InIterator __first, _InI oneapi::dpl::__par_backend_hetero::__buffer<_ExecutionPolicy, _ValueType> __buf(__exec, __in_size); auto __buf_first = __buf.get(); + auto __buf_last = __pattern_walk2( - __par_backend_hetero::make_wrapped_policy<__initial_copy_2>(__exec), __first, __last, __buf_first, - __brick_copy<_ExecutionPolicy>{}, ::std::true_type{}, ::std::true_type{}); + __tag, __par_backend_hetero::make_wrapped_policy<__initial_copy_2>(__exec), __first, __last, __buf_first, + __brick_copy<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}); auto __buf_mid = __buf_first + __out_size; __par_backend_hetero::__parallel_partial_sort( - __par_backend_hetero::make_wrapped_policy<__partial_sort_2>(__exec), + _BackendTag{}, __par_backend_hetero::make_wrapped_policy<__partial_sort_2>(__exec), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read_write>(__buf_first), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read_write>(__buf_mid), __par_backend_hetero::make_iter_mode<__par_backend_hetero::access_mode::read_write>(__buf_last), __comp); return __pattern_walk2( - __par_backend_hetero::make_wrapped_policy<__copy_back>(::std::forward<_ExecutionPolicy>(__exec)), - __buf_first, __buf_mid, __out_first, __brick_copy<_ExecutionPolicy>{}, ::std::true_type{}, - ::std::true_type{}); + __tag, __par_backend_hetero::make_wrapped_policy<__copy_back>(::std::forward<_ExecutionPolicy>(__exec)), + __buf_first, __buf_mid, __out_first, __brick_copy<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}); } } @@ -1523,10 +1530,10 @@ __pattern_partial_sort_copy(_ExecutionPolicy&& __exec, _InIterator __first, _InI // nth_element //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy> -__pattern_nth_element(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __nth, _Iterator __last, _Compare __comp, - /*vector*/ ::std::true_type, /*parallel*/ ::std::true_type) +template +void +__pattern_nth_element(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __nth, + _Iterator __last, _Compare __comp) { if (__first == __last || __nth == __last) return; @@ -1534,17 +1541,16 @@ __pattern_nth_element(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __ // TODO: check partition-based implementation // - try to avoid host dereference issue // - measure performance of the issue-free implementation - __pattern_partial_sort(::std::forward<_ExecutionPolicy>(__exec), __first, __nth + 1, __last, __comp, - /*vector*/ ::std::true_type{}, /*parallel*/ ::std::true_type{}); + __pattern_partial_sort(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __nth + 1, __last, __comp); } //------------------------------------------------------------------------ // reverse //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy> -__pattern_reverse(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, /*vector=*/::std::true_type, - /*parallel=*/::std::true_type) + +template +void +__pattern_reverse(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last) { auto __n = __last - __first; if (__n <= 0) @@ -1553,7 +1559,7 @@ __pattern_reverse(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last auto __keep = oneapi::dpl::__ranges::__get_sycl_range<__par_backend_hetero::access_mode::read_write, _Iterator>(); auto __buf = __keep(__first, __last); oneapi::dpl::__par_backend_hetero::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), unseq_backend::__reverse_functor::difference_type>{__n}, __n / 2, __buf.all_view()) .wait(); @@ -1562,10 +1568,11 @@ __pattern_reverse(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last //------------------------------------------------------------------------ // reverse_copy //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_reverse_copy(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, - _ForwardIterator __result, /*vector=*/::std::true_type, /*parallel=*/::std::true_type) + +template +_ForwardIterator +__pattern_reverse_copy(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _BidirectionalIterator __first, + _BidirectionalIterator __last, _ForwardIterator __result) { auto __n = __last - __first; if (__n <= 0) @@ -1578,7 +1585,7 @@ __pattern_reverse_copy(_ExecutionPolicy&& __exec, _BidirectionalIterator __first oneapi::dpl::__ranges::__get_sycl_range<__par_backend_hetero::access_mode::write, _ForwardIterator>(); auto __buf2 = __keep2(__result, __result + __n); oneapi::dpl::__par_backend_hetero::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), unseq_backend::__reverse_copy::difference_type>{__n}, __n, __buf1.all_view(), __buf2.all_view()) .wait(); @@ -1599,10 +1606,10 @@ class __rotate_wrapper { }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator> -__pattern_rotate(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __new_first, _Iterator __last, - /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +_Iterator +__pattern_rotate(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __new_first, + _Iterator __last) { auto __n = __last - __first; if (__n <= 0) @@ -1619,15 +1626,15 @@ __pattern_rotate(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __new_f const auto __shift = __new_first - __first; oneapi::dpl::__par_backend_hetero::__parallel_for( - oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__rotate_wrapper>(__exec), + _BackendTag{}, oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__rotate_wrapper>(__exec), unseq_backend::__rotate_copy::difference_type>{__n, __shift}, __n, __buf.all_view(), __temp_rng); - using _Function = __brick_move<_ExecutionPolicy>; + using _Function = __brick_move<__hetero_tag<_BackendTag>, _ExecutionPolicy>; auto __brick = unseq_backend::walk_n<_ExecutionPolicy, _Function>{_Function{}}; - oneapi::dpl::__par_backend_hetero::__parallel_for(::std::forward<_ExecutionPolicy>(__exec), __brick, __n, - __temp_rng, __buf.all_view()) + oneapi::dpl::__par_backend_hetero::__parallel_for(_BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __brick, + __n, __temp_rng, __buf.all_view()) .wait(); return __first + (__last - __new_first); @@ -1636,11 +1643,11 @@ __pattern_rotate(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __new_f //------------------------------------------------------------------------ // rotate_copy //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _ForwardIterator> -__pattern_rotate_copy(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __new_first, - _BidirectionalIterator __last, _ForwardIterator __result, /*vector=*/::std::true_type, - /*parallel=*/::std::true_type) + +template +_ForwardIterator +__pattern_rotate_copy(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _BidirectionalIterator __first, + _BidirectionalIterator __new_first, _BidirectionalIterator __last, _ForwardIterator __result) { auto __n = __last - __first; if (__n <= 0) @@ -1656,7 +1663,7 @@ __pattern_rotate_copy(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, const auto __shift = __new_first - __first; oneapi::dpl::__par_backend_hetero::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), unseq_backend::__rotate_copy::difference_type>{__n, __shift}, __n, __buf1.all_view(), __buf2.all_view()) @@ -1665,12 +1672,12 @@ __pattern_rotate_copy(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, return __result + __n; } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_hetero_set_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, - _Compare __comp, _IsOpDifference) +template +_OutputIterator +__pattern_hetero_set_op(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _OutputIterator __result, _Compare __comp, _IsOpDifference) { typedef typename ::std::iterator_traits<_ForwardIterator1>::difference_type _Size1; typedef typename ::std::iterator_traits<_ForwardIterator2>::difference_type _Size2; @@ -1709,7 +1716,7 @@ __pattern_hetero_set_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ auto __result_size = __par_backend_hetero::__parallel_transform_scan_base( - ::std::forward<_ExecutionPolicy>(__exec), + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), oneapi::dpl::__ranges::make_zip_view( __buf1.all_view(), __buf2.all_view(), oneapi::dpl::__ranges::all_view( @@ -1730,19 +1737,19 @@ __pattern_hetero_set_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ return __result + __result_size; } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, - _Compare __comp, /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +_OutputIterator +__pattern_set_intersection(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _OutputIterator __result, _Compare __comp) { // intersection is empty if (__first1 == __last1 || __first2 == __last2) return __result; - return __pattern_hetero_set_op(::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, - __result, __comp, unseq_backend::_IntersectionTag()); + return __pattern_hetero_set_op(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, + __last2, __result, __comp, unseq_backend::_IntersectionTag()); } //Dummy names to avoid kernel problems @@ -1751,13 +1758,12 @@ class __set_difference_copy_case_1 { }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_set_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, - _Compare __comp, /*vector=*/::std::true_type, - /*parallel=*/::std::true_type) +template +_OutputIterator +__pattern_set_difference(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _OutputIterator __result, _Compare __comp) { // {} \ {2}: the difference is empty if (__first1 == __last1) @@ -1767,13 +1773,15 @@ __pattern_set_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, if (__first2 == __last2) { return oneapi::dpl::__internal::__pattern_walk2_brick( + __tag, oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__set_difference_copy_case_1>( ::std::forward<_ExecutionPolicy>(__exec)), - __first1, __last1, __result, oneapi::dpl::__internal::__brick_copy<_ExecutionPolicy>{}, ::std::true_type()); + __first1, __last1, __result, + oneapi::dpl::__internal::__brick_copy<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}); } - return __pattern_hetero_set_op(::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, - __result, __comp, unseq_backend::_DifferenceTag()); + return __pattern_hetero_set_op(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, + __last2, __result, __comp, unseq_backend::_DifferenceTag()); } //Dummy names to avoid kernel problems @@ -1787,12 +1795,12 @@ class __set_union_copy_case_2 { }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_set_union(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp, - /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +_OutputIterator +__pattern_set_union(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _OutputIterator __result, _Compare __comp) { if (__first1 == __last1 && __first2 == __last2) return __result; @@ -1801,18 +1809,22 @@ __pattern_set_union(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forw if (__first1 == __last1) { return oneapi::dpl::__internal::__pattern_walk2_brick( + __tag, oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__set_union_copy_case_1>( ::std::forward<_ExecutionPolicy>(__exec)), - __first2, __last2, __result, oneapi::dpl::__internal::__brick_copy<_ExecutionPolicy>{}, ::std::true_type()); + __first2, __last2, __result, + oneapi::dpl::__internal::__brick_copy<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}); } //{2} is empty if (__first2 == __last2) { return oneapi::dpl::__internal::__pattern_walk2_brick( + __tag, oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__set_union_copy_case_2>( ::std::forward<_ExecutionPolicy>(__exec)), - __first1, __last1, __result, oneapi::dpl::__internal::__brick_copy<_ExecutionPolicy>{}, ::std::true_type()); + __first1, __last1, __result, + oneapi::dpl::__internal::__brick_copy<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}); } typedef typename ::std::iterator_traits<_OutputIterator>::value_type _ValueType; @@ -1823,15 +1835,17 @@ __pattern_set_union(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forw auto __buf = __diff.get(); //1. Calc difference {2} \ {1} - const auto __n_diff = oneapi::dpl::__internal::__pattern_hetero_set_op(__exec,__first2, __last2, __first1, __last1, - __buf,__comp, unseq_backend::_DifferenceTag() - ) - __buf; + const auto __n_diff = + oneapi::dpl::__internal::__pattern_hetero_set_op(__tag, __exec, __first2, __last2, __first1, __last1, __buf, + __comp, unseq_backend::_DifferenceTag()) - + __buf; + //2. Merge {1} and the difference return oneapi::dpl::__internal::__pattern_merge( + __tag, oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__set_union_copy_case_2>( ::std::forward<_ExecutionPolicy>(__exec)), - __first1, __last1, __buf, __buf + __n_diff, __result, __comp, - /*vector=*/::std::true_type(), /*parallel=*/::std::true_type()); + __first1, __last1, __buf, __buf + __n_diff, __result, __comp); } //Dummy names to avoid kernel problems @@ -1862,13 +1876,12 @@ class __set_symmetric_difference_phase_2 // 1. Calc difference {1} \ {2} // 2. Calc difference {2} \ {1} // 3. Merge the differences -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_set_symmetric_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, - _Compare __comp, /*vector=*/::std::true_type, - /*parallel=*/::std::true_type) +template +_OutputIterator +__pattern_set_symmetric_difference(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, + _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp) { if (__first1 == __last1 && __first2 == __last2) return __result; @@ -1877,18 +1890,22 @@ __pattern_set_symmetric_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 if (__first1 == __last1) { return oneapi::dpl::__internal::__pattern_walk2_brick( + __tag, oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__set_symmetric_difference_copy_case_1>( ::std::forward<_ExecutionPolicy>(__exec)), - __first2, __last2, __result, oneapi::dpl::__internal::__brick_copy<_ExecutionPolicy>{}, ::std::true_type()); + __first2, __last2, __result, + oneapi::dpl::__internal::__brick_copy<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}); } //{2} is empty if (__first2 == __last2) { return oneapi::dpl::__internal::__pattern_walk2_brick( + __tag, oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__set_symmetric_difference_copy_case_2>( ::std::forward<_ExecutionPolicy>(__exec)), - __first1, __last1, __result, oneapi::dpl::__internal::__brick_copy<_ExecutionPolicy>{}, ::std::true_type()); + __first1, __last1, __result, + oneapi::dpl::__internal::__brick_copy<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}); } typedef typename ::std::iterator_traits<_OutputIterator>::value_type _ValueType; @@ -1904,21 +1921,21 @@ __pattern_set_symmetric_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 //1. Calc difference {1} \ {2} const auto __n_diff_1 = oneapi::dpl::__internal::__pattern_hetero_set_op( - oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__set_symmetric_difference_phase_1>(__exec), + __tag, oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__set_symmetric_difference_phase_1>(__exec), __first1, __last1, __first2, __last2, __buf_1, __comp, unseq_backend::_DifferenceTag()) - __buf_1; //2. Calc difference {2} \ {1} const auto __n_diff_2 = oneapi::dpl::__internal::__pattern_hetero_set_op( - oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__set_symmetric_difference_phase_2>(__exec), + __tag, oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__set_symmetric_difference_phase_2>(__exec), __first2, __last2, __first1, __last1, __buf_2, __comp, unseq_backend::_DifferenceTag()) - __buf_2; //3. Merge the differences - return oneapi::dpl::__internal::__pattern_merge(::std::forward<_ExecutionPolicy>(__exec), __buf_1, + return oneapi::dpl::__internal::__pattern_merge(__tag, ::std::forward<_ExecutionPolicy>(__exec), __buf_1, __buf_1 + __n_diff_1, __buf_2, __buf_2 + __n_diff_2, __result, - __comp, ::std::true_type(), ::std::true_type()); + __comp); } template @@ -1926,10 +1943,10 @@ class __shift_left_right { }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range>> -__pattern_shift_left(_ExecutionPolicy&& __exec, _Range __rng, oneapi::dpl::__internal::__difference_t<_Range> __n) +template +oneapi::dpl::__internal::__difference_t<_Range> +__pattern_shift_left(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Range __rng, + oneapi::dpl::__internal::__difference_t<_Range> __n) { //If (n > 0 && n < m), returns first + (m - n). Otherwise, if n > 0, returns first. Otherwise, returns last. using _DiffType = oneapi::dpl::__internal::__difference_t<_Range>; @@ -1943,21 +1960,22 @@ __pattern_shift_left(_ExecutionPolicy&& __exec, _Range __rng, oneapi::dpl::__int //1. n >= size/2; 'size - _n' parallel copying if (__n >= __mid) { - using _Function = __brick_move<_ExecutionPolicy>; + using _Function = __brick_move<__hetero_tag<_BackendTag>, _ExecutionPolicy>; auto __brick = oneapi::dpl::unseq_backend::walk_n<_ExecutionPolicy, _Function>{_Function{}}; //TODO: to consider use just "read" access mode for a source range and just "write" - for a destination range. auto __src = oneapi::dpl::__ranges::drop_view_simple<_Range, _DiffType>(__rng, __n); auto __dst = oneapi::dpl::__ranges::take_view_simple<_Range, _DiffType>(__rng, __size_res); - oneapi::dpl::__par_backend_hetero::__parallel_for(::std::forward<_ExecutionPolicy>(__exec), __brick, __size_res, - __src, __dst) + oneapi::dpl::__par_backend_hetero::__parallel_for(_BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), + __brick, __size_res, __src, __dst) .wait(); } else //2. n < size/2; 'n' parallel copying { auto __brick = unseq_backend::__brick_shift_left<_ExecutionPolicy, _DiffType>{__size, __n}; oneapi::dpl::__par_backend_hetero::__parallel_for( + _BackendTag{}, oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__shift_left_right>( ::std::forward<_ExecutionPolicy>(__exec)), __brick, __n, __rng) @@ -1967,11 +1985,10 @@ __pattern_shift_left(_ExecutionPolicy&& __exec, _Range __rng, oneapi::dpl::__int return __size_res; } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator> -__pattern_shift_left(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, - typename ::std::iterator_traits<_Iterator>::difference_type __n, /*vector=*/::std::true_type, - /*is_parallel=*/::std::true_type) +template +_Iterator +__pattern_shift_left(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, + typename ::std::iterator_traits<_Iterator>::difference_type __n) { //If (n > 0 && n < m), returns first + (m - n). Otherwise, if n > 0, returns first. Otherwise, returns last. auto __size = __last - __first; @@ -1983,16 +2000,15 @@ __pattern_shift_left(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __l auto __keep = oneapi::dpl::__ranges::__get_sycl_range<__par_backend_hetero::access_mode::read_write, _Iterator>(); auto __buf = __keep(__first, __last); - auto __res = - oneapi::dpl::__internal::__pattern_shift_left(::std::forward<_ExecutionPolicy>(__exec), __buf.all_view(), __n); + auto __res = oneapi::dpl::__internal::__pattern_shift_left(__tag, ::std::forward<_ExecutionPolicy>(__exec), + __buf.all_view(), __n); return __first + __res; } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator> -__pattern_shift_right(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, - typename ::std::iterator_traits<_Iterator>::difference_type __n, /*vector=*/::std::true_type, - /*is_parallel=*/::std::true_type) +template +_Iterator +__pattern_shift_right(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, + typename ::std::iterator_traits<_Iterator>::difference_type __n) { //If (n > 0 && n < m), returns first + n. Otherwise, if n > 0, returns last. Otherwise, returns first. auto __size = __last - __first; @@ -2006,7 +2022,8 @@ __pattern_shift_right(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __ //A shift right is the shift left with a reverse logic. auto __rng = oneapi::dpl::__ranges::reverse_view_simple{__buf.all_view()}; - auto __res = oneapi::dpl::__internal::__pattern_shift_left(::std::forward<_ExecutionPolicy>(__exec), __rng, __n); + auto __res = + oneapi::dpl::__internal::__pattern_shift_left(__tag, ::std::forward<_ExecutionPolicy>(__exec), __rng, __n); return __last - __res; } diff --git a/include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h b/include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h index bee1d1f1f69..25ce34a8680 100644 --- a/include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h +++ b/include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h @@ -39,14 +39,14 @@ namespace __ranges // walk_n //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy> -__pattern_walk_n(_ExecutionPolicy&& __exec, _Function __f, _Ranges&&... __rngs) +template +void +__pattern_walk_n(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Function __f, _Ranges&&... __rngs) { auto __n = oneapi::dpl::__ranges::__get_first_range_size(__rngs...); if (__n > 0) { - oneapi::dpl::__par_backend_hetero::__parallel_for(::std::forward<_ExecutionPolicy>(__exec), + oneapi::dpl::__par_backend_hetero::__parallel_for(_BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), unseq_backend::walk_n<_ExecutionPolicy, _Function>{__f}, __n, ::std::forward<_Ranges>(__rngs)...) .wait(); @@ -67,13 +67,15 @@ class __swap2_wrapper { }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, bool> -__pattern_swap(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _Function __f) +template +bool +__pattern_swap(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, + _Function __f) { if (__rng1.size() <= __rng2.size()) { oneapi::dpl::__internal::__ranges::__pattern_walk_n( + __tag, oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__swap1_wrapper>( ::std::forward<_ExecutionPolicy>(__exec)), __f, __rng1, __rng2); @@ -81,6 +83,7 @@ __pattern_swap(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _F } oneapi::dpl::__internal::__ranges::__pattern_walk_n( + __tag, oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__swap2_wrapper>( ::std::forward<_ExecutionPolicy>(__exec)), __f, __rng2, __rng1); @@ -91,9 +94,9 @@ __pattern_swap(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _F // equal //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, bool> -__pattern_equal(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _Pred __pred) +template +bool +__pattern_equal(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _Pred __pred) { if (__rng1.empty() || __rng2.empty() || __rng1.size() != __rng2.size()) return false; @@ -103,7 +106,7 @@ __pattern_equal(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _ // TODO: in case of confilicting names // __par_backend_hetero::make_wrapped_policy<__par_backend_hetero::__or_policy_wrapper>() return !oneapi::dpl::__par_backend_hetero::__parallel_find_or( - ::std::forward<_ExecutionPolicy>(__exec), _Predicate{equal_predicate<_Pred>{__pred}}, + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), _Predicate{equal_predicate<_Pred>{__pred}}, oneapi::dpl::__par_backend_hetero::__parallel_or_tag{}, oneapi::dpl::__ranges::zip_view(::std::forward<_Range1>(__rng1), ::std::forward<_Range2>(__rng2))); } @@ -112,10 +115,9 @@ __pattern_equal(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _ // find_if //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range>> -__pattern_find_if(_ExecutionPolicy&& __exec, _Range&& __rng, _Pred __pred) +template +oneapi::dpl::__internal::__difference_t<_Range> +__pattern_find_if(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Range&& __rng, _Pred __pred) { //trivial pre-checks if (__rng.empty()) @@ -125,6 +127,7 @@ __pattern_find_if(_ExecutionPolicy&& __exec, _Range&& __rng, _Pred __pred) using _TagType = oneapi::dpl::__par_backend_hetero::__parallel_find_forward_tag<_Range>; return oneapi::dpl::__par_backend_hetero::__parallel_find_or( + _BackendTag{}, __par_backend_hetero::make_wrapped_policy<__par_backend_hetero::__find_policy_wrapper>( ::std::forward<_ExecutionPolicy>(__exec)), _Predicate{__pred}, _TagType{}, ::std::forward<_Range>(__rng)); @@ -134,10 +137,10 @@ __pattern_find_if(_ExecutionPolicy&& __exec, _Range&& __rng, _Pred __pred) // find_end //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range1>> -__pattern_find_end(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _Pred __pred) +template +oneapi::dpl::__internal::__difference_t<_Range1> +__pattern_find_end(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, + _Pred __pred) { //trivial pre-checks if (__rng1.empty() || __rng2.empty() || __rng1.size() < __rng2.size()) @@ -145,8 +148,8 @@ __pattern_find_end(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2 if (__rng1.size() == __rng2.size()) { - const bool __res = __pattern_equal(::std::forward<_ExecutionPolicy>(__exec), __rng1, - ::std::forward<_Range2>(__rng2), __pred); + const bool __res = __ranges::__pattern_equal(__tag, ::std::forward<_ExecutionPolicy>(__exec), __rng1, + ::std::forward<_Range2>(__rng2), __pred); return __res ? 0 : __rng1.size(); } @@ -154,6 +157,7 @@ __pattern_find_end(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2 using _TagType = __par_backend_hetero::__parallel_find_backward_tag<_Range1>; return oneapi::dpl::__par_backend_hetero::__parallel_find_or( + _BackendTag{}, __par_backend_hetero::make_wrapped_policy<__par_backend_hetero::__find_policy_wrapper>( ::std::forward<_ExecutionPolicy>(__exec)), _Predicate{__pred}, _TagType{}, ::std::forward<_Range1>(__rng1), ::std::forward<_Range2>(__rng2)); @@ -163,10 +167,10 @@ __pattern_find_end(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2 // find_first_of //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range1>> -__pattern_find_first_of(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _Pred __pred) +template +oneapi::dpl::__internal::__difference_t<_Range1> +__pattern_find_first_of(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, + _Pred __pred) { //trivial pre-checks if (__rng1.empty() || __rng2.empty()) @@ -177,6 +181,7 @@ __pattern_find_first_of(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& _ //TODO: To check whether it makes sense to iterate over the second sequence in case of __rng1.size() < __rng2.size() return oneapi::dpl::__par_backend_hetero::__parallel_find_or( + _BackendTag{}, __par_backend_hetero::make_wrapped_policy<__par_backend_hetero::__find_policy_wrapper>( ::std::forward<_ExecutionPolicy>(__exec)), _Predicate{__pred}, _TagType{}, ::std::forward<_Range1>(__rng1), ::std::forward<_Range2>(__rng2)); @@ -186,15 +191,16 @@ __pattern_find_first_of(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& _ // any_of //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, bool> -__pattern_any_of(_ExecutionPolicy&& __exec, _Range&& __rng, _Pred __pred) +template +bool +__pattern_any_of(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Range&& __rng, _Pred __pred) { if (__rng.empty()) return false; using _Predicate = oneapi::dpl::unseq_backend::single_match_pred<_ExecutionPolicy, _Pred>; return oneapi::dpl::__par_backend_hetero::__parallel_find_or( + _BackendTag{}, __par_backend_hetero::make_wrapped_policy( ::std::forward<_ExecutionPolicy>(__exec)), _Predicate{__pred}, oneapi::dpl::__par_backend_hetero::__parallel_or_tag{}, ::std::forward<_Range>(__rng)); @@ -209,10 +215,10 @@ class equal_wrapper { }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range1>> -__pattern_search(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _Pred __pred) +template +oneapi::dpl::__internal::__difference_t<_Range1> +__pattern_search(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, + _Pred __pred) { //trivial pre-checks if (__rng2.empty()) @@ -222,8 +228,8 @@ __pattern_search(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, if (__rng1.size() == __rng2.size()) { - const bool __res = __pattern_equal( - __par_backend_hetero::make_wrapped_policy(::std::forward<_ExecutionPolicy>(__exec)), + const bool __res = __ranges::__pattern_equal( + __tag, __par_backend_hetero::make_wrapped_policy(::std::forward<_ExecutionPolicy>(__exec)), __rng1, ::std::forward<_Range2>(__rng2), __pred); return __res ? 0 : __rng1.size(); } @@ -232,8 +238,9 @@ __pattern_search(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, using _TagType = oneapi::dpl::__par_backend_hetero::__parallel_find_forward_tag<_Range1>; return oneapi::dpl::__par_backend_hetero::__parallel_find_or( - oneapi::dpl::__par_backend_hetero::make_wrapped_policy - (::std::forward<_ExecutionPolicy>(__exec)), + _BackendTag{}, + oneapi::dpl::__par_backend_hetero::make_wrapped_policy< + oneapi::dpl::__par_backend_hetero::__find_policy_wrapper>(::std::forward<_ExecutionPolicy>(__exec)), _Predicate{__pred}, _TagType{}, ::std::forward<_Range1>(__rng1), ::std::forward<_Range2>(__rng2)); } @@ -241,18 +248,19 @@ __pattern_search(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, // search_n //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range>> -__pattern_search_n(_ExecutionPolicy&& __exec, _Range&& __rng, _Size __count, const _Tp& __value, - _BinaryPredicate __pred) +template +oneapi::dpl::__internal::__difference_t<_Range> +__pattern_search_n(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Range&& __rng, _Size __count, + const _Tp& __value, _BinaryPredicate __pred) { //TODO: To consider definition a kind of special factory "multiple_view" (addition to standard "single_view"). //The factory "multiple_view" would generate a range of N identical values. auto __s_rng = oneapi::dpl::experimental::ranges::views::iota(0, __count) | oneapi::dpl::experimental::ranges::views::transform([__value](auto) { return __value; }); - return __pattern_search(::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range>(__rng), __s_rng, __pred); + return __ranges::__pattern_search(__tag, ::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range>(__rng), + __s_rng, __pred); } template @@ -273,11 +281,11 @@ return_value(_Size __res, _Size __size, ::std::false_type) // adjacent_find //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range>> -__pattern_adjacent_find(_ExecutionPolicy&& __exec, _Range&& __rng, _BinaryPredicate __predicate, - _OrFirstTag __is__or_semantic) +template +oneapi::dpl::__internal::__difference_t<_Range> +__pattern_adjacent_find(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Range&& __rng, + _BinaryPredicate __predicate, _OrFirstTag __is__or_semantic) { if (__rng.size() < 2) return __rng.size(); @@ -290,21 +298,21 @@ __pattern_adjacent_find(_ExecutionPolicy&& __exec, _Range&& __rng, _BinaryPredic auto __rng1 = __rng | oneapi::dpl::experimental::ranges::views::take(__rng.size() - 1); auto __rng2 = __rng | oneapi::dpl::experimental::ranges::views::drop(1); - // TODO: in case of confilicting names + // TODO: in case of conflicting names // __par_backend_hetero::make_wrapped_policy<__par_backend_hetero::__or_policy_wrapper>() auto result = oneapi::dpl::__par_backend_hetero::__parallel_find_or( - ::std::forward<_ExecutionPolicy>(__exec), _Predicate{adjacent_find_fn<_BinaryPredicate>{__predicate}}, - _TagType{}, oneapi::dpl::__ranges::zip_view(__rng1, __rng2)); + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), + _Predicate{adjacent_find_fn<_BinaryPredicate>{__predicate}}, _TagType{}, + oneapi::dpl::__ranges::zip_view(__rng1, __rng2)); // inverted conditional because of // reorder_predicate in glue_algorithm_impl.h return return_value(result, __rng.size(), __is__or_semantic); } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range>> -__pattern_count(_ExecutionPolicy&& __exec, _Range&& __rng, _Predicate __predicate) +template +oneapi::dpl::__internal::__difference_t<_Range> +__pattern_count(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Range&& __rng, _Predicate __predicate) { if (__rng.size() == 0) return 0; @@ -320,7 +328,7 @@ __pattern_count(_ExecutionPolicy&& __exec, _Range&& __rng, _Predicate __predicat return oneapi::dpl::__par_backend_hetero::__parallel_transform_reduce<_ReduceValueType, ::std::true_type /*is_commutative*/>( - ::std::forward<_ExecutionPolicy>(__exec), __reduce_fn, __transform_fn, + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __reduce_fn, __transform_fn, unseq_backend::__no_init_value{}, // no initial value ::std::forward<_Range>(__rng)) .get(); @@ -330,11 +338,11 @@ __pattern_count(_ExecutionPolicy&& __exec, _Range&& __rng, _Predicate __predicat // copy_if //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range1>> -__pattern_scan_copy(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _CreateMaskOp __create_mask_op, - _CopyByMaskOp __copy_by_mask_op) +template +oneapi::dpl::__internal::__difference_t<_Range1> +__pattern_scan_copy(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, + _CreateMaskOp __create_mask_op, _CopyByMaskOp __copy_by_mask_op) { if (__rng1.size() == 0) return __rng1.size(); @@ -356,7 +364,7 @@ __pattern_scan_copy(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng auto __res = __par_backend_hetero::__parallel_transform_scan_base( - ::std::forward<_ExecutionPolicy>(__exec), + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), oneapi::dpl::__ranges::zip_view( __rng1, oneapi::dpl::__ranges::all_view( __mask_buf.get_buffer())), @@ -376,11 +384,11 @@ __pattern_scan_copy(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng return __res; } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range2>> -__pattern_copy_if(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _Predicate __pred, _Assign) +oneapi::dpl::__internal::__difference_t<_Range2> +__pattern_copy_if(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, + _Predicate __pred, _Assign) { using _SizeType = decltype(__rng1.size()); using _ReduceOp = ::std::plus<_SizeType>; @@ -388,18 +396,18 @@ __pattern_copy_if(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, unseq_backend::__create_mask<_Predicate, _SizeType> __create_mask_op{__pred}; unseq_backend::__copy_by_mask<_ReduceOp, _Assign, /*inclusive*/ ::std::true_type, 1> __copy_by_mask_op; - return __pattern_scan_copy(::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range1>(__rng1), - ::std::forward<_Range2>(__rng2), __create_mask_op, __copy_by_mask_op); + return __ranges::__pattern_scan_copy(__tag, ::std::forward<_ExecutionPolicy>(__exec), + ::std::forward<_Range1>(__rng1), ::std::forward<_Range2>(__rng2), + __create_mask_op, __copy_by_mask_op); } //------------------------------------------------------------------------ // remove_if //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range>> -__pattern_remove_if(_ExecutionPolicy&& __exec, _Range&& __rng, _Predicate __pred) +template +oneapi::dpl::__internal::__difference_t<_Range> +__pattern_remove_if(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Range&& __rng, _Predicate __pred) { if (__rng.size() == 0) return __rng.size(); @@ -409,13 +417,14 @@ __pattern_remove_if(_ExecutionPolicy&& __exec, _Range&& __rng, _Predicate __pred oneapi::dpl::__par_backend_hetero::__buffer<_ExecutionPolicy, _ValueType> __buf(__exec, __rng.size()); auto __copy_rng = oneapi::dpl::__ranges::views::all(__buf.get_buffer()); - auto __copy_last_id = __pattern_copy_if(__exec, __rng, __copy_rng, __not_pred<_Predicate>{__pred}, - oneapi::dpl::__internal::__pstl_assign()); + auto __copy_last_id = __ranges::__pattern_copy_if(__tag, __exec, __rng, __copy_rng, __not_pred<_Predicate>{__pred}, + oneapi::dpl::__internal::__pstl_assign()); auto __copy_rng_truncated = __copy_rng | oneapi::dpl::experimental::ranges::views::take(__copy_last_id); - oneapi::dpl::__internal::__ranges::__pattern_walk_n(::std::forward<_ExecutionPolicy>(__exec), - oneapi::dpl::__internal::__brick_copy<_ExecutionPolicy>{}, - __copy_rng_truncated, ::std::forward<_Range>(__rng)); + oneapi::dpl::__internal::__ranges::__pattern_walk_n( + __tag, ::std::forward<_ExecutionPolicy>(__exec), + oneapi::dpl::__internal::__brick_copy<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}, __copy_rng_truncated, + ::std::forward<_Range>(__rng)); return __copy_last_id; } @@ -424,11 +433,11 @@ __pattern_remove_if(_ExecutionPolicy&& __exec, _Range&& __rng, _Predicate __pred // unique_copy //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range2>> -__pattern_unique_copy(_ExecutionPolicy&& __exec, _Range1&& __rng, _Range2&& __result, _BinaryPredicate __pred, _Assign) +template +oneapi::dpl::__internal::__difference_t<_Range2> +__pattern_unique_copy(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Range1&& __rng, _Range2&& __result, + _BinaryPredicate __pred, _Assign) { using _It1DifferenceType = oneapi::dpl::__internal::__difference_t<_Range1>; unseq_backend::__copy_by_mask<::std::plus<_It1DifferenceType>, _Assign, /*inclusive*/ ::std::true_type, 1> @@ -436,18 +445,18 @@ __pattern_unique_copy(_ExecutionPolicy&& __exec, _Range1&& __rng, _Range2&& __re __create_mask_unique_copy<__not_pred<_BinaryPredicate>, _It1DifferenceType> __create_mask_op{ __not_pred<_BinaryPredicate>{__pred}}; - return __pattern_scan_copy(::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range1>(__rng), - ::std::forward<_Range2>(__result), __create_mask_op, __copy_by_mask_op); + return __ranges::__pattern_scan_copy(__tag, ::std::forward<_ExecutionPolicy>(__exec), + ::std::forward<_Range1>(__rng), ::std::forward<_Range2>(__result), + __create_mask_op, __copy_by_mask_op); } //------------------------------------------------------------------------ // unique //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range>> -__pattern_unique(_ExecutionPolicy&& __exec, _Range&& __rng, _BinaryPredicate __pred) +template +oneapi::dpl::__internal::__difference_t<_Range> +__pattern_unique(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Range&& __rng, _BinaryPredicate __pred) { if (__rng.size() == 0) return __rng.size(); @@ -456,10 +465,12 @@ __pattern_unique(_ExecutionPolicy&& __exec, _Range&& __rng, _BinaryPredicate __p oneapi::dpl::__par_backend_hetero::__buffer<_ExecutionPolicy, _ValueType> __buf(__exec, __rng.size()); auto res_rng = oneapi::dpl::__ranges::views::all(__buf.get_buffer()); - auto res = __pattern_unique_copy(__exec, __rng, res_rng, __pred, oneapi::dpl::__internal::__pstl_assign()); + auto res = __ranges::__pattern_unique_copy(__tag, __exec, __rng, res_rng, __pred, + oneapi::dpl::__internal::__pstl_assign()); - __pattern_walk_n(::std::forward<_ExecutionPolicy>(__exec), __brick_copy<_ExecutionPolicy>{}, res_rng, - ::std::forward<_Range>(__rng)); + __ranges::__pattern_walk_n(__tag, ::std::forward<_ExecutionPolicy>(__exec), + __brick_copy<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}, res_rng, + ::std::forward<_Range>(__rng)); return res; } @@ -477,10 +488,11 @@ class __copy2_wrapper { }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range3>> -__pattern_merge(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _Range3&& __rng3, _Compare __comp) +template +oneapi::dpl::__internal::__difference_t<_Range3> +__pattern_merge(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, + _Range3&& __rng3, _Compare __comp) { auto __n1 = __rng1.size(); auto __n2 = __rng2.size(); @@ -492,22 +504,24 @@ __pattern_merge(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _ if (__n1 == 0) { oneapi::dpl::__internal::__ranges::__pattern_walk_n( + __tag, oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__copy1_wrapper>( ::std::forward<_ExecutionPolicy>(__exec)), - oneapi::dpl::__internal::__brick_copy<_ExecutionPolicy>{}, ::std::forward<_Range2>(__rng2), - ::std::forward<_Range3>(__rng3)); + oneapi::dpl::__internal::__brick_copy<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}, + ::std::forward<_Range2>(__rng2), ::std::forward<_Range3>(__rng3)); } else if (__n2 == 0) { oneapi::dpl::__internal::__ranges::__pattern_walk_n( + __tag, oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__copy2_wrapper>( ::std::forward<_ExecutionPolicy>(__exec)), - oneapi::dpl::__internal::__brick_copy<_ExecutionPolicy>{}, ::std::forward<_Range1>(__rng1), - ::std::forward<_Range3>(__rng3)); + oneapi::dpl::__internal::__brick_copy<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}, + ::std::forward<_Range1>(__rng1), ::std::forward<_Range3>(__rng3)); } else { - __par_backend_hetero::__parallel_merge(::std::forward<_ExecutionPolicy>(__exec), + __par_backend_hetero::__parallel_merge(_BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range1>(__rng1), ::std::forward<_Range2>(__rng2), ::std::forward<_Range3>(__rng3), __comp) .wait(); @@ -520,12 +534,12 @@ __pattern_merge(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _ // sort //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy> -__pattern_sort(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp, _Proj __proj) +template +void +__pattern_sort(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp, _Proj __proj) { if (__rng.size() >= 2) - __par_backend_hetero::__parallel_stable_sort(::std::forward<_ExecutionPolicy>(__exec), + __par_backend_hetero::__parallel_stable_sort(_BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range>(__rng), __comp, __proj) .wait(); } @@ -534,10 +548,9 @@ __pattern_sort(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp, _Proj // min_element //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range>> -__pattern_min_element(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp) +template +oneapi::dpl::__internal::__difference_t<_Range> +__pattern_min_element(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp) { //If size == 1, result is the zero-indexed element. If size == 0, result is 0. if (__rng.size() < 2) @@ -562,7 +575,7 @@ __pattern_min_element(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp auto __ret_idx = oneapi::dpl::__par_backend_hetero::__parallel_transform_reduce<_ReduceValueType, ::std::false_type /*is_commutative*/>( - ::std::forward<_ExecutionPolicy>(__exec), __reduce_fn, __transform_fn, + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __reduce_fn, __transform_fn, unseq_backend::__no_init_value{}, // no initial value ::std::forward<_Range>(__rng)) .get(); @@ -575,11 +588,9 @@ __pattern_min_element(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp // minmax_element //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy< - _ExecutionPolicy, - ::std::pair, oneapi::dpl::__internal::__difference_t<_Range>>> -__pattern_minmax_element(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp) +template +::std::pair, oneapi::dpl::__internal::__difference_t<_Range>> +__pattern_minmax_element(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp) { //If size == 1, result is the zero-indexed element. If size == 0, result is 0. if (__rng.size() < 2) @@ -618,7 +629,7 @@ __pattern_minmax_element(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __c _ReduceValueType __ret = oneapi::dpl::__par_backend_hetero::__parallel_transform_reduce<_ReduceValueType, ::std::false_type /*is_commutative*/>( - ::std::forward<_ExecutionPolicy>(__exec), __reduce_fn, __transform_fn, + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __reduce_fn, __transform_fn, unseq_backend::__no_init_value{}, // no initial value ::std::forward<_Range>(__rng)) .get(); @@ -661,12 +672,12 @@ class __assign_key2_wrapper { }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range3>> -__pattern_reduce_by_segment(_ExecutionPolicy&& __exec, _Range1&& __keys, _Range2&& __values, _Range3&& __out_keys, - _Range4&& __out_values, _BinaryPredicate __binary_pred, _BinaryOperator __binary_op) +template +oneapi::dpl::__internal::__difference_t<_Range3> +__pattern_reduce_by_segment(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Range1&& __keys, + _Range2&& __values, _Range3&& __out_keys, _Range4&& __out_values, + _BinaryPredicate __binary_pred, _BinaryOperator __binary_op) { // The algorithm reduces values in __values where the // associated keys for the values are equal to the adjacent key. @@ -684,15 +695,16 @@ __pattern_reduce_by_segment(_ExecutionPolicy&& __exec, _Range1&& __keys, _Range2 if (__n == 1) { - __brick_copy<_ExecutionPolicy> __copy_range{}; + __brick_copy<__hetero_tag<_BackendTag>, _ExecutionPolicy> __copy_range{}; oneapi::dpl::__internal::__ranges::__pattern_walk_n( - oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__copy_keys_wrapper>(__exec), - __copy_range, ::std::forward<_Range1>(__keys), ::std::forward<_Range3>(__out_keys)); + __tag, oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__copy_keys_wrapper>(__exec), __copy_range, + ::std::forward<_Range1>(__keys), ::std::forward<_Range3>(__out_keys)); oneapi::dpl::__internal::__ranges::__pattern_walk_n( - oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__copy_values_wrapper> - (::std::forward<_ExecutionPolicy>(__exec)), + __tag, + oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__copy_values_wrapper>( + ::std::forward<_ExecutionPolicy>(__exec)), __copy_range, ::std::forward<_Range2>(__values), ::std::forward<_Range4>(__out_values)); return 1; @@ -730,8 +742,8 @@ __pattern_reduce_by_segment(_ExecutionPolicy&& __exec, _Range1&& __keys, _Range2 // evenly divisible by wg size (ensures segments are not long), or has a key not equal to the // adjacent element (marks end of real segments) // TODO: replace wgroup size with segment size based on platform specifics. - auto __intermediate_result_end = __pattern_copy_if( - oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__assign_key1_wrapper>(__exec), __view1, __view2, + auto __intermediate_result_end = __ranges::__pattern_copy_if( + __tag, oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__assign_key1_wrapper>(__exec), __view1, __view2, [__n, __binary_pred, __wgroup_size](const auto& __a) { // The size of key range for the (i-1) view is one less, so for the 0th index we do not check the keys // for (i-1), but we still need to get its key value as it is the start of a segment @@ -745,7 +757,7 @@ __pattern_reduce_by_segment(_ExecutionPolicy&& __exec, _Range1&& __keys, _Range2 //reduce by segment oneapi::dpl::__par_backend_hetero::__parallel_for( - oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__reduce1_wrapper>(__exec), + _BackendTag{}, oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__reduce1_wrapper>(__exec), unseq_backend::__brick_reduce_idx<_BinaryOperator, decltype(__n)>(__binary_op, __n), __intermediate_result_end, oneapi::dpl::__ranges::take_view_simple(experimental::ranges::views::all_read(__idx), __intermediate_result_end), @@ -773,8 +785,8 @@ __pattern_reduce_by_segment(_ExecutionPolicy&& __exec, _Range1&& __keys, _Range2 // element is copied if it is the 0th element (marks beginning of first segment), or has a key not equal to // the adjacent element (end of a segment). Artificial segments based on wg size are not created. - auto __result_end = __pattern_copy_if( - oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__assign_key2_wrapper>(__exec), __view3, __view4, + auto __result_end = __ranges::__pattern_copy_if( + __tag, oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__assign_key2_wrapper>(__exec), __view3, __view4, [__binary_pred](const auto& __a) { // The size of key range for the (i-1) view is one less, so for the 0th index we do not check the keys // for (i-1), but we still need to get its key value as it is the start of a segment @@ -786,6 +798,7 @@ __pattern_reduce_by_segment(_ExecutionPolicy&& __exec, _Range1&& __keys, _Range2 //reduce by segment oneapi::dpl::__par_backend_hetero::__parallel_for( + _BackendTag{}, oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__reduce2_wrapper>( ::std::forward<_ExecutionPolicy>(__exec)), unseq_backend::__brick_reduce_idx<_BinaryOperator, decltype(__intermediate_result_end)>( diff --git a/include/oneapi/dpl/pstl/hetero/dpcpp/execution_sycl_defs.h b/include/oneapi/dpl/pstl/hetero/dpcpp/execution_sycl_defs.h index de875bee324..e1e06e17e96 100644 --- a/include/oneapi/dpl/pstl/hetero/dpcpp/execution_sycl_defs.h +++ b/include/oneapi/dpl/pstl/hetero/dpcpp/execution_sycl_defs.h @@ -18,6 +18,7 @@ #include "../../onedpl_config.h" #include "../../execution_defs.h" +#include "../../iterator_defs.h" #include "sycl_defs.h" @@ -59,24 +60,6 @@ class device_policy return q; } - // For internal use only - static constexpr ::std::true_type - __allow_unsequenced() - { - return ::std::true_type{}; - } - // __allow_vector is needed for __is_vectorization_preferred - static constexpr ::std::true_type - __allow_vector() - { - return ::std::true_type{}; - } - static constexpr ::std::true_type - __allow_parallel() - { - return ::std::true_type{}; - } - private: sycl::queue q; }; @@ -98,7 +81,7 @@ class fpga_policy : public device_policy # else __dpl_sycl::__fpga_selector() # endif // _ONEDPL_FPGA_EMU - )) + )) { } @@ -106,14 +89,6 @@ class fpga_policy : public device_policy fpga_policy(const fpga_policy& other) : base(other.queue()){}; explicit fpga_policy(sycl::queue q) : base(q) {} explicit fpga_policy(sycl::device d) : base(d) {} - - // For internal use only - - const base& - __device_policy() const - { - return static_cast(*this); - }; }; #endif // _ONEDPL_FPGA_DEVICE @@ -311,6 +286,66 @@ using __enable_if_device_execution_policy_double_no_default = __is_convertible_to_event<_Events...>, _T>; +template +struct __hetero_tag +{ + using __backend_tag = _BackendTag; +}; + +struct __device_backend_tag +{ +}; + +//---------------------------------------------------------- +// __select_backend (for the hetero policies) +//---------------------------------------------------------- + +template +__hetero_tag<__device_backend_tag> +__select_backend(const execution::device_policy<_KernelName>&, _IteratorTypes&&...) +{ + static_assert(__is_random_access_iterator_v<_IteratorTypes...>); + return {}; +} + +#if _ONEDPL_FPGA_DEVICE +struct __fpga_backend_tag : __device_backend_tag +{ +}; + +template +__hetero_tag<__fpga_backend_tag> +__select_backend(const execution::fpga_policy<_Factor, _KernelName>&, _IteratorTypes&&...) +{ + static_assert(__is_random_access_iterator_v<_IteratorTypes...>); + return {}; +} +#endif + +//---------------------------------------------------------- +// __is_hetero_backend_tag, __is_hetero_backend_tag_v +//---------------------------------------------------------- + +template +struct __is_hetero_backend_tag : ::std::false_type +{ +}; + +template <> +struct __is_hetero_backend_tag<__device_backend_tag> : ::std::true_type +{ +}; + +#if _ONEDPL_FPGA_DEVICE +template <> +struct __is_hetero_backend_tag<__fpga_backend_tag> : ::std::true_type +{ +}; +#endif + +template +inline constexpr bool __is_hetero_backend_tag_v = __is_hetero_backend_tag<_BackendTag>::value; + } // namespace __internal } // namespace dpl diff --git a/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl.h b/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl.h index e0152a4006a..d60d5b3626e 100644 --- a/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl.h +++ b/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl.h @@ -244,10 +244,10 @@ struct __parallel_for_submitter<__internal::__optional_kernel_name<_Name...>> //General version of parallel_for, one additional parameter - __count of iterations of loop __cgh.parallel_for, //for some algorithms happens that size of processing range is n, but amount of iterations is n/2. -template = 0, typename... _Ranges> +template auto -__parallel_for(_ExecutionPolicy&& __exec, _Fp __brick, _Index __count, _Ranges&&... __rngs) +__parallel_for(oneapi::dpl::__internal::__device_backend_tag, _ExecutionPolicy&& __exec, _Fp __brick, _Index __count, + _Ranges&&... __rngs) { using _CustomName = oneapi::dpl::__internal::__policy_kernel_name<_ExecutionPolicy>; using _ForKernel = oneapi::dpl::__par_backend_hetero::__internal::__kernel_name_provider<_CustomName>; @@ -659,9 +659,10 @@ struct __parallel_copy_if_static_single_group_submitter<_Size, _ElemsPerItem, _W template auto -__parallel_transform_scan_single_group(_ExecutionPolicy&& __exec, _InRng&& __in_rng, _OutRng&& __out_rng, - ::std::size_t __n, _UnaryOperation __unary_op, _InitType __init, - _BinaryOperation __binary_op, _Inclusive) +__parallel_transform_scan_single_group(oneapi::dpl::__internal::__device_backend_tag, _ExecutionPolicy&& __exec, + _InRng&& __in_rng, _OutRng&& __out_rng, ::std::size_t __n, + _UnaryOperation __unary_op, _InitType __init, _BinaryOperation __binary_op, + _Inclusive) { using _CustomName = oneapi::dpl::__internal::__policy_kernel_name<_ExecutionPolicy>; @@ -735,12 +736,11 @@ __parallel_transform_scan_single_group(_ExecutionPolicy&& __exec, _InRng&& __in_ } template = 0> + typename _LocalScan, typename _GroupScan, typename _GlobalScan> auto -__parallel_transform_scan_base(_ExecutionPolicy&& __exec, _Range1&& __in_rng, _Range2&& __out_rng, - _BinaryOperation __binary_op, _InitType __init, _LocalScan __local_scan, - _GroupScan __group_scan, _GlobalScan __global_scan) +__parallel_transform_scan_base(oneapi::dpl::__internal::__device_backend_tag, _ExecutionPolicy&& __exec, + _Range1&& __in_rng, _Range2&& __out_rng, _BinaryOperation __binary_op, _InitType __init, + _LocalScan __local_scan, _GroupScan __group_scan, _GlobalScan __global_scan) { using _CustomName = oneapi::dpl::__internal::__policy_kernel_name<_ExecutionPolicy>; @@ -753,11 +753,11 @@ __parallel_transform_scan_base(_ExecutionPolicy&& __exec, _Range1&& __in_rng, _R } template = 0> + typename _BinaryOperation, typename _Inclusive> auto -__parallel_transform_scan(_ExecutionPolicy&& __exec, _Range1&& __in_rng, _Range2&& __out_rng, ::std::size_t __n, - _UnaryOperation __unary_op, _InitType __init, _BinaryOperation __binary_op, _Inclusive) +__parallel_transform_scan(oneapi::dpl::__internal::__device_backend_tag __backend_tag, _ExecutionPolicy&& __exec, + _Range1&& __in_rng, _Range2&& __out_rng, ::std::size_t __n, _UnaryOperation __unary_op, + _InitType __init, _BinaryOperation __binary_op, _Inclusive) { using _Type = typename _InitType::__value_type; @@ -779,7 +779,7 @@ __parallel_transform_scan(_ExecutionPolicy&& __exec, _Range1&& __in_rng, _Range2 if (__n <= __single_group_upper_limit && __max_slm_size >= __req_slm_size) { return __parallel_transform_scan_single_group( - std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range1>(__in_rng), + __backend_tag, std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range1>(__in_rng), ::std::forward<_Range2>(__out_rng), __n, __unary_op, __init, __binary_op, _Inclusive{}); } } @@ -796,7 +796,7 @@ __parallel_transform_scan(_ExecutionPolicy&& __exec, _Range1&& __in_rng, _Range2 return __future( __parallel_transform_scan_base( - ::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range1>(__in_rng), + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range1>(__in_rng), ::std::forward<_Range2>(__out_rng), __binary_op, __init, // local scan unseq_backend::__scan<_Inclusive, _ExecutionPolicy, _BinaryOperation, _UnaryFunctor, _Assigner, _Assigner, @@ -852,11 +852,11 @@ struct __invoke_single_group_copy_if }; template = 0> + typename _CopyByMaskOp> auto -__parallel_scan_copy(_ExecutionPolicy&& __exec, _InRng&& __in_rng, _OutRng&& __out_rng, _Size __n, - _CreateMaskOp __create_mask_op, _CopyByMaskOp __copy_by_mask_op) +__parallel_scan_copy(oneapi::dpl::__internal::__device_backend_tag __backend_tag, _ExecutionPolicy&& __exec, + _InRng&& __in_rng, _OutRng&& __out_rng, _Size __n, _CreateMaskOp __create_mask_op, + _CopyByMaskOp __copy_by_mask_op) { using _ReduceOp = ::std::plus<_Size>; using _Assigner = unseq_backend::__scan_assigner; @@ -874,7 +874,7 @@ __parallel_scan_copy(_ExecutionPolicy&& __exec, _InRng&& __in_rng, _OutRng&& __o oneapi::dpl::__par_backend_hetero::__buffer<_ExecutionPolicy, int32_t> __mask_buf(__exec, __n); return __parallel_transform_scan_base( - ::std::forward<_ExecutionPolicy>(__exec), + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), oneapi::dpl::__ranges::make_zip_view( ::std::forward<_InRng>(__in_rng), oneapi::dpl::__ranges::all_view( @@ -892,10 +892,10 @@ __parallel_scan_copy(_ExecutionPolicy&& __exec, _InRng&& __in_rng, _OutRng&& __o __copy_by_mask_op); } -template = 0> +template auto -__parallel_copy_if(_ExecutionPolicy&& __exec, _InRng&& __in_rng, _OutRng&& __out_rng, _Size __n, _Pred __pred) +__parallel_copy_if(oneapi::dpl::__internal::__device_backend_tag __backend_tag, _ExecutionPolicy&& __exec, + _InRng&& __in_rng, _OutRng&& __out_rng, _Size __n, _Pred __pred) { using _SingleGroupInvoker = __invoke_single_group_copy_if<_Size>; @@ -930,8 +930,9 @@ __parallel_copy_if(_ExecutionPolicy&& __exec, _InRng&& __in_rng, _OutRng&& __out using CopyOp = unseq_backend::__copy_by_mask<_ReduceOp, oneapi::dpl::__internal::__pstl_assign, /*inclusive*/ ::std::true_type, 1>; - return __parallel_scan_copy(::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_InRng>(__in_rng), - ::std::forward<_OutRng>(__out_rng), __n, CreateOp{__pred}, CopyOp{}); + return __parallel_scan_copy(__backend_tag, ::std::forward<_ExecutionPolicy>(__exec), + ::std::forward<_InRng>(__in_rng), ::std::forward<_OutRng>(__out_rng), __n, + CreateOp{__pred}, CopyOp{}); } } @@ -1071,12 +1072,11 @@ struct __early_exit_find_or // Base pattern for __parallel_or and __parallel_find. The execution depends on tag type _BrickTag. template -oneapi::dpl::__internal::__enable_if_device_execution_policy< - _ExecutionPolicy, - ::std::conditional_t<::std::is_same_v<_BrickTag, __parallel_or_tag>, bool, - oneapi::dpl::__internal::__difference_t< - typename oneapi::dpl::__ranges::__get_first_range_type<_Ranges...>::type>>> -__parallel_find_or(_ExecutionPolicy&& __exec, _Brick __f, _BrickTag __brick_tag, _Ranges&&... __rngs) +::std::conditional_t< + ::std::is_same_v<_BrickTag, __parallel_or_tag>, bool, + oneapi::dpl::__internal::__difference_t::type>> +__parallel_find_or(oneapi::dpl::__internal::__device_backend_tag, _ExecutionPolicy&& __exec, _Brick __f, + _BrickTag __brick_tag, _Ranges&&... __rngs) { using _CustomName = oneapi::dpl::__internal::__policy_kernel_name<_ExecutionPolicy>; using _AtomicType = typename _BrickTag::_AtomicType; @@ -1182,9 +1182,9 @@ class __or_policy_wrapper }; template -oneapi::dpl::__internal::__enable_if_device_execution_policy<_ExecutionPolicy, bool> -__parallel_or(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, _Iterator2 __s_first, - _Iterator2 __s_last, _Brick __f) +bool +__parallel_or(oneapi::dpl::__internal::__device_backend_tag __backend_tag, _ExecutionPolicy&& __exec, + _Iterator1 __first, _Iterator1 __last, _Iterator2 __s_first, _Iterator2 __s_last, _Brick __f) { auto __keep = oneapi::dpl::__ranges::__get_sycl_range<__par_backend_hetero::access_mode::read, _Iterator1>(); auto __buf = __keep(__first, __last); @@ -1192,6 +1192,7 @@ __parallel_or(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, auto __s_buf = __s_keep(__s_first, __s_last); return oneapi::dpl::__par_backend_hetero::__parallel_find_or( + __backend_tag, __par_backend_hetero::make_wrapped_policy<__or_policy_wrapper>(::std::forward<_ExecutionPolicy>(__exec)), __f, __parallel_or_tag{}, __buf.all_view(), __s_buf.all_view()); } @@ -1200,13 +1201,15 @@ __parallel_or(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, // TODO: check if similar pattern may apply to other algorithms. If so, these overloads should be moved out of // backend code. template -oneapi::dpl::__internal::__enable_if_device_execution_policy<_ExecutionPolicy, bool> -__parallel_or(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _Brick __f) +bool +__parallel_or(oneapi::dpl::__internal::__device_backend_tag __backend_tag, _ExecutionPolicy&& __exec, _Iterator __first, + _Iterator __last, _Brick __f) { auto __keep = oneapi::dpl::__ranges::__get_sycl_range<__par_backend_hetero::access_mode::read, _Iterator>(); auto __buf = __keep(__first, __last); return oneapi::dpl::__par_backend_hetero::__parallel_find_or( + __backend_tag, __par_backend_hetero::make_wrapped_policy<__or_policy_wrapper>(::std::forward<_ExecutionPolicy>(__exec)), __f, __parallel_or_tag{}, __buf.all_view()); } @@ -1221,9 +1224,9 @@ class __find_policy_wrapper }; template -oneapi::dpl::__internal::__enable_if_device_execution_policy<_ExecutionPolicy, _Iterator1> -__parallel_find(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, _Iterator2 __s_first, - _Iterator2 __s_last, _Brick __f, _IsFirst) +_Iterator1 +__parallel_find(oneapi::dpl::__internal::__device_backend_tag __backend_tag, _ExecutionPolicy&& __exec, + _Iterator1 __first, _Iterator1 __last, _Iterator2 __s_first, _Iterator2 __s_last, _Brick __f, _IsFirst) { auto __keep = oneapi::dpl::__ranges::__get_sycl_range<__par_backend_hetero::access_mode::read, _Iterator1>(); auto __buf = __keep(__first, __last); @@ -1233,6 +1236,7 @@ __parallel_find(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last using _TagType = ::std::conditional_t<_IsFirst::value, __parallel_find_forward_tag, __parallel_find_backward_tag>; return __first + oneapi::dpl::__par_backend_hetero::__parallel_find_or( + __backend_tag, __par_backend_hetero::make_wrapped_policy<__find_policy_wrapper>( ::std::forward<_ExecutionPolicy>(__exec)), __f, _TagType{}, __buf.all_view(), __s_buf.all_view()); @@ -1242,8 +1246,9 @@ __parallel_find(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last // TODO: check if similar pattern may apply to other algorithms. If so, these overloads should be moved out of // backend code. template -oneapi::dpl::__internal::__enable_if_device_execution_policy<_ExecutionPolicy, _Iterator> -__parallel_find(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _Brick __f, _IsFirst) +_Iterator +__parallel_find(oneapi::dpl::__internal::__device_backend_tag __backend_tag, _ExecutionPolicy&& __exec, + _Iterator __first, _Iterator __last, _Brick __f, _IsFirst) { auto __keep = oneapi::dpl::__ranges::__get_sycl_range<__par_backend_hetero::access_mode::read, _Iterator>(); auto __buf = __keep(__first, __last); @@ -1251,6 +1256,7 @@ __parallel_find(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, using _TagType = ::std::conditional_t<_IsFirst::value, __parallel_find_forward_tag, __parallel_find_backward_tag>; return __first + oneapi::dpl::__par_backend_hetero::__parallel_find_or( + __backend_tag, __par_backend_hetero::make_wrapped_policy<__find_policy_wrapper>( ::std::forward<_ExecutionPolicy>(__exec)), __f, _TagType{}, __buf.all_view()); @@ -1482,10 +1488,10 @@ struct __parallel_merge_submitter<_IdType, __internal::__optional_kernel_name<_N template class __merge_kernel_name; -template = 0> +template auto -__parallel_merge(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _Range3&& __rng3, _Compare __comp) +__parallel_merge(oneapi::dpl::__internal::__device_backend_tag, _ExecutionPolicy&& __exec, _Range1&& __rng1, + _Range2&& __rng2, _Range3&& __rng3, _Compare __comp) { using _CustomName = oneapi::dpl::__internal::__policy_kernel_name<_ExecutionPolicy>; @@ -1493,19 +1499,20 @@ __parallel_merge(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, if (__n <= std::numeric_limits<::std::uint32_t>::max()) { using _wi_index_type = ::std::uint32_t; - using _MergeKernel = oneapi::dpl::__par_backend_hetero::__internal::__kernel_name_provider<__merge_kernel_name<_CustomName, _wi_index_type>>; - return __parallel_merge_submitter<_wi_index_type, _MergeKernel>()(::std::forward<_ExecutionPolicy>(__exec), - ::std::forward<_Range1>(__rng1), ::std::forward<_Range2>(__rng2), - ::std::forward<_Range3>(__rng3), __comp); - + using _MergeKernel = oneapi::dpl::__par_backend_hetero::__internal::__kernel_name_provider< + __merge_kernel_name<_CustomName, _wi_index_type>>; + return __parallel_merge_submitter<_wi_index_type, _MergeKernel>()( + ::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range1>(__rng1), ::std::forward<_Range2>(__rng2), + ::std::forward<_Range3>(__rng3), __comp); } else { using _wi_index_type = ::std::uint64_t; - using _MergeKernel = oneapi::dpl::__par_backend_hetero::__internal::__kernel_name_provider<__merge_kernel_name<_CustomName, _wi_index_type>>; - return __parallel_merge_submitter<_wi_index_type, _MergeKernel>()(::std::forward<_ExecutionPolicy>(__exec), - ::std::forward<_Range1>(__rng1), ::std::forward<_Range2>(__rng2), - ::std::forward<_Range3>(__rng3), __comp); + using _MergeKernel = oneapi::dpl::__par_backend_hetero::__internal::__kernel_name_provider< + __merge_kernel_name<_CustomName, _wi_index_type>>; + return __parallel_merge_submitter<_wi_index_type, _MergeKernel>()( + ::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range1>(__rng1), ::std::forward<_Range2>(__rng2), + ::std::forward<_Range3>(__rng3), __comp); } } @@ -1544,9 +1551,9 @@ struct __parallel_sort_submitter<_IdType, __internal::__optional_kernel_name<_Le __internal::__optional_kernel_name<_GlobalSortName...>, __internal::__optional_kernel_name<_CopyBackName...>> { - template + template auto - operator()(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp) const + operator()(_BackendTag, _ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp) const { using _Tp = oneapi::dpl::__internal::__value_t<_Range>; using _Size = oneapi::dpl::__internal::__difference_t<_Range>; @@ -1636,10 +1643,10 @@ struct __parallel_sort_submitter<_IdType, __internal::__optional_kernel_name<_Le } }; -template = 0> +template auto -__parallel_sort_impl(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp) +__parallel_sort_impl(oneapi::dpl::__internal::__device_backend_tag, _ExecutionPolicy&& __exec, _Range&& __rng, + _Compare __comp) { using _CustomName = oneapi::dpl::__internal::__policy_kernel_name<_ExecutionPolicy>; @@ -1654,7 +1661,8 @@ __parallel_sort_impl(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp) using _CopyBackKernel = oneapi::dpl::__par_backend_hetero::__internal::__kernel_name_provider<__sort_copy_back_kernel<_CustomName, _wi_index_type>>; return __parallel_sort_submitter<_wi_index_type, _LeafSortKernel, _GlobalSortKernel, _CopyBackKernel>()( - ::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range>(__rng), __comp); + oneapi::dpl::__internal::__device_backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), + ::std::forward<_Range>(__rng), __comp); } else { @@ -1666,7 +1674,8 @@ __parallel_sort_impl(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp) using _CopyBackKernel = oneapi::dpl::__par_backend_hetero::__internal::__kernel_name_provider<__sort_copy_back_kernel<_CustomName, _wi_index_type>>; return __parallel_sort_submitter<_wi_index_type, _LeafSortKernel, _GlobalSortKernel, _CopyBackKernel>()( - ::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range>(__rng), __comp); + oneapi::dpl::__internal::__device_backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), + ::std::forward<_Range>(__rng), __comp); } } @@ -1678,9 +1687,9 @@ template struct __parallel_partial_sort_submitter<__internal::__optional_kernel_name<_GlobalSortName...>, __internal::__optional_kernel_name<_CopyBackName...>> { - template + template auto - operator()(_ExecutionPolicy&& __exec, _Range&& __rng, _Merge __merge, _Compare __comp) const + operator()(_BackendTag, _ExecutionPolicy&& __exec, _Range&& __rng, _Merge __merge, _Compare __comp) const { using _Tp = oneapi::dpl::__internal::__value_t<_Range>; using _Size = oneapi::dpl::__internal::__difference_t<_Range>; @@ -1743,10 +1752,10 @@ struct __parallel_partial_sort_submitter<__internal::__optional_kernel_name<_Glo } }; -template = 0> +template auto -__parallel_partial_sort_impl(_ExecutionPolicy&& __exec, _Range&& __rng, _Merge __merge, _Compare __comp) +__parallel_partial_sort_impl(oneapi::dpl::__internal::__device_backend_tag, _ExecutionPolicy&& __exec, _Range&& __rng, + _Merge __merge, _Compare __comp) { using _CustomName = oneapi::dpl::__internal::__policy_kernel_name<_ExecutionPolicy>; using _GlobalSortKernel = @@ -1755,7 +1764,8 @@ __parallel_partial_sort_impl(_ExecutionPolicy&& __exec, _Range&& __rng, _Merge _ oneapi::dpl::__par_backend_hetero::__internal::__kernel_name_provider<__sort_copy_back_kernel<_CustomName>>; return __parallel_partial_sort_submitter<_GlobalSortKernel, _CopyBackKernel>()( - ::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range>(__rng), __merge, __comp); + oneapi::dpl::__internal::__device_backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), + ::std::forward<_Range>(__rng), __merge, __comp); } //------------------------------------------------------------------------ @@ -1776,31 +1786,32 @@ struct __is_radix_sort_usable_for_type }; #if _USE_RADIX_SORT -template > && - __is_radix_sort_usable_for_type, _Compare>::value, - int> = 0> +template < + typename _ExecutionPolicy, typename _Range, typename _Compare, typename _Proj, + ::std::enable_if_t< + __is_radix_sort_usable_for_type, _Compare>::value, int> = 0> auto -__parallel_stable_sort(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare, _Proj __proj) +__parallel_stable_sort(oneapi::dpl::__internal::__device_backend_tag __backend_tag, _ExecutionPolicy&& __exec, + _Range&& __rng, _Compare, _Proj __proj) { return __parallel_radix_sort<__internal::__is_comp_ascending<::std::decay_t<_Compare>>::value>( - ::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range>(__rng), __proj); + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range>(__rng), __proj); } #endif -template > && - !__is_radix_sort_usable_for_type, _Compare>::value, - int> = 0> +template < + typename _ExecutionPolicy, typename _Range, typename _Compare, typename _Proj, + ::std::enable_if_t< + !__is_radix_sort_usable_for_type, _Compare>::value, int> = 0> auto -__parallel_stable_sort(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp, _Proj __proj) +__parallel_stable_sort(oneapi::dpl::__internal::__device_backend_tag __backend_tag, _ExecutionPolicy&& __exec, + _Range&& __rng, _Compare __comp, _Proj __proj) { auto __cmp_f = [__comp, __proj](const auto& __a, const auto& __b) mutable { return __comp(__proj(__a), __proj(__b)); }; - return __parallel_sort_impl(::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range>(__rng), __cmp_f); + return __parallel_sort_impl(__backend_tag, ::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range>(__rng), + __cmp_f); } //------------------------------------------------------------------------ @@ -1810,21 +1821,19 @@ __parallel_stable_sort(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __com // TODO: check if it makes sense to move these wrappers out of backend to a common place // TODO: consider changing __partial_merge_kernel to make it compatible with // __full_merge_kernel in order to use __parallel_sort_impl routine -template = 0> +template auto -__parallel_partial_sort(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __mid, _Iterator __last, - _Compare __comp) +__parallel_partial_sort(oneapi::dpl::__internal::__device_backend_tag __backend_tag, _ExecutionPolicy&& __exec, + _Iterator __first, _Iterator __mid, _Iterator __last, _Compare __comp) { const auto __mid_idx = __mid - __first; auto __keep = oneapi::dpl::__ranges::__get_sycl_range<__par_backend_hetero::access_mode::read_write, _Iterator>(); auto __buf = __keep(__first, __last); - return __parallel_partial_sort_impl(::std::forward<_ExecutionPolicy>(__exec), __buf.all_view(), + return __parallel_partial_sort_impl(__backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __buf.all_view(), __partial_merge_kernel{__mid_idx}, __comp); } - } // namespace __par_backend_hetero } // namespace dpl } // namespace oneapi diff --git a/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_fpga.h b/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_fpga.h index b8410261c60..95d23fc16e9 100644 --- a/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_fpga.h +++ b/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_fpga.h @@ -77,10 +77,10 @@ struct __parallel_for_fpga_submitter<__internal::__optional_kernel_name<_Name... } }; -template = 0> +template auto -__parallel_for(_ExecutionPolicy&& __exec, _Fp __brick, _Index __count, _Ranges&&... __rngs) +__parallel_for(oneapi::dpl::__internal::__fpga_backend_tag, _ExecutionPolicy&& __exec, _Fp __brick, _Index __count, + _Ranges&&... __rngs) { using _CustomName = oneapi::dpl::__internal::__policy_kernel_name<_ExecutionPolicy>; using __parallel_for_name = __internal::__kernel_name_provider<_CustomName>; @@ -89,201 +89,23 @@ __parallel_for(_ExecutionPolicy&& __exec, _Fp __brick, _Index __count, _Ranges&& __count, std::forward<_Ranges>(__rngs)...); } -//------------------------------------------------------------------------ -// parallel_transform_reduce -//------------------------------------------------------------------------ - -template = 0, - typename... _Ranges> -auto -__parallel_transform_reduce(_ExecutionPolicy&& __exec, _ReduceOp __reduce_op, _TransformOp __transform_op, - _InitType __init, _Ranges&&... __rngs) -{ - // workaround until we implement more performant version for patterns - return oneapi::dpl::__par_backend_hetero::__parallel_transform_reduce<_Tp, _Commutative>( - __exec.__device_policy(), __reduce_op, __transform_op, __init, ::std::forward<_Ranges>(__rngs)...); -} - -//------------------------------------------------------------------------ -// parallel_transform_scan -//------------------------------------------------------------------------ - -template = 0> -auto -__parallel_transform_scan(_ExecutionPolicy&& __exec, _Range1&& __in_rng, _Range2&& __out_rng, ::std::size_t __n, - _UnaryOperation __unary_op, _InitType __init, _BinaryOperation __binary_op, _Inclusive) -{ - // workaround until we implement more performant version for patterns - return oneapi::dpl::__par_backend_hetero::__parallel_transform_scan( - __exec.__device_policy(), ::std::forward<_Range1>(__in_rng), ::std::forward<_Range2>(__out_rng), __n, - __unary_op, __init, __binary_op, _Inclusive{}); -} - -template = 0> -auto -__parallel_transform_scan_base(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, - _BinaryOperation __binary_op, _InitType __init, _LocalScan __local_scan, - _GroupScan __group_scan, _GlobalScan __global_scan) -{ - // workaround until we implement more performant version for patterns - return oneapi::dpl::__par_backend_hetero::__parallel_transform_scan_base( - __exec.__device_policy(), ::std::forward<_Range1>(__rng1), ::std::forward<_Range2>(__rng2), __binary_op, __init, - __local_scan, __group_scan, __global_scan); -} - -template = 0> -auto -__parallel_copy_if(_ExecutionPolicy&& __exec, _InRng&& __in_rng, _OutRng&& __out_rng, _Size __n, _Pred __pred) -{ - // workaround until we implement more performant version for patterns - return oneapi::dpl::__par_backend_hetero::__parallel_copy_if( - __exec.__device_policy(), ::std::forward<_InRng>(__in_rng), ::std::forward<_OutRng>(__out_rng), __n, __pred); -} - -template = 0> -auto -__parallel_scan_copy(_ExecutionPolicy&& __exec, _InRng&& __in_rng, _OutRng&& __out_rng, _Size __n, - _CreateMaskOp __create_mask_op, _CopyByMaskOp __copy_by_mask_op) -{ - // workaround until we implement more performant version for patterns - return oneapi::dpl::__par_backend_hetero::__parallel_scan_copy( - __exec.__device_policy(), ::std::forward<_InRng>(__in_rng), ::std::forward<_OutRng>(__out_rng), __n, - __create_mask_op, __copy_by_mask_op); -} - -//------------------------------------------------------------------------ -// __parallel_find_or -//----------------------------------------------------------------------- -template -oneapi::dpl::__internal::__enable_if_fpga_execution_policy< - _ExecutionPolicy, - ::std::conditional_t<::std::is_same_v<_BrickTag, __parallel_or_tag>, bool, - oneapi::dpl::__internal::__difference_t< - typename oneapi::dpl::__ranges::__get_first_range_type<_Ranges...>::type>>> -__parallel_find_or(_ExecutionPolicy&& __exec, _Brick __f, _BrickTag __brick_tag, _Ranges&&... __rngs) -{ - return oneapi::dpl::__par_backend_hetero::__parallel_find_or(__exec.__device_policy(), __f, __brick_tag, - ::std::forward<_Ranges>(__rngs)...); -} - -//------------------------------------------------------------------------ -// parallel_or -//----------------------------------------------------------------------- -template -oneapi::dpl::__internal::__enable_if_fpga_execution_policy<_ExecutionPolicy, bool> -__parallel_or(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, _Iterator2 __s_first, - _Iterator2 __s_last, _Brick __f) -{ - // workaround until we implement more performant version for patterns - return oneapi::dpl::__par_backend_hetero::__parallel_or(__exec.__device_policy(), __first, __last, __s_first, - __s_last, __f); -} - -template -oneapi::dpl::__internal::__enable_if_fpga_execution_policy<_ExecutionPolicy, bool> -__parallel_or(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _Brick __f) -{ - // workaround until we implement more performant version for patterns - return oneapi::dpl::__par_backend_hetero::__parallel_or(__exec.__device_policy(), __first, __last, __f); -} - -//------------------------------------------------------------------------ -// parallel_find -//----------------------------------------------------------------------- - -template -oneapi::dpl::__internal::__enable_if_fpga_execution_policy<_ExecutionPolicy, _Iterator1> -__parallel_find(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, _Iterator2 __s_first, - _Iterator2 __s_last, _Brick __f, _IsFirst __is_first) -{ - // workaround until we implement more performant version for patterns - return oneapi::dpl::__par_backend_hetero::__parallel_find(__exec.__device_policy(), __first, __last, __s_first, - __s_last, __f, __is_first); -} - -template -oneapi::dpl::__internal::__enable_if_fpga_execution_policy<_ExecutionPolicy, _Iterator> -__parallel_find(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __last, _Brick __f, _IsFirst __is_first) -{ - // workaround until we implement more performant version for patterns - return oneapi::dpl::__par_backend_hetero::__parallel_find(__exec.__device_policy(), __first, __last, __f, - __is_first); -} - -//------------------------------------------------------------------------ -// parallel_merge -//----------------------------------------------------------------------- - -template -auto -__parallel_merge(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _Range3&& __rng3, _Compare __comp) - -> oneapi::dpl::__internal::__enable_if_fpga_execution_policy< - _ExecutionPolicy, decltype(oneapi::dpl::__par_backend_hetero::__parallel_merge( - __exec.__device_policy(), ::std::forward<_Range1>(__rng1), - ::std::forward<_Range2>(__rng2), ::std::forward<_Range3>(__rng3), __comp))> -{ - // workaround until we implement more performant version for patterns - return oneapi::dpl::__par_backend_hetero::__parallel_merge( - __exec.__device_policy(), ::std::forward<_Range1>(__rng1), ::std::forward<_Range2>(__rng2), - ::std::forward<_Range3>(__rng3), __comp); -} - -//------------------------------------------------------------------------ -// parallel_stable_sort -//----------------------------------------------------------------------- - -template = 0> -auto -__parallel_stable_sort(_ExecutionPolicy&& __exec, _Range&& __rng, _Compare __comp, _Proj __proj) -{ - // workaround until we implement more performant version for patterns - return oneapi::dpl::__par_backend_hetero::__parallel_stable_sort(__exec.__device_policy(), - ::std::forward<_Range>(__rng), __comp, __proj); -} - -//------------------------------------------------------------------------ -// parallel_partial_sort -//----------------------------------------------------------------------- - -// TODO: check if it makes sense to move these wrappers out of backend to a common place -template = 0> -auto -__parallel_partial_sort(_ExecutionPolicy&& __exec, _Iterator __first, _Iterator __mid, _Iterator __last, - _Compare __comp) -{ - // workaround until we implement more performant version for patterns - return oneapi::dpl::__par_backend_hetero::__parallel_partial_sort(__exec.__device_policy(), __first, __mid, __last, - __comp); -} - //------------------------------------------------------------------------ // parallel_histogram //----------------------------------------------------------------------- // TODO: check if it makes sense to move these wrappers out of backend to a common place -template = 0> +template auto -__parallel_histogram(_ExecutionPolicy&& __exec, const _Event& __init_event, _Range1&& __input, _Range2&& __bins, - const _BinHashMgr& __binhash_manager) +__parallel_histogram(oneapi::dpl::__internal::__fpga_backend_tag, _ExecutionPolicy&& __exec, const _Event& __init_event, + _Range1&& __input, _Range2&& __bins, const _BinHashMgr& __binhash_manager) { static_assert(sizeof(oneapi::dpl::__internal::__value_t<_Range2>) <= sizeof(::std::uint32_t), "histogram is not supported on FPGA devices with output types greater than 32 bits"); // workaround until we implement more performant version for patterns - return oneapi::dpl::__par_backend_hetero::__parallel_histogram(__exec.__device_policy(), __init_event, - ::std::forward<_Range1>(__input), - ::std::forward<_Range2>(__bins), __binhash_manager); + return oneapi::dpl::__par_backend_hetero::__parallel_histogram( + oneapi::dpl::__internal::__device_backend_tag{}, __exec, __init_event, ::std::forward<_Range1>(__input), + ::std::forward<_Range2>(__bins), __binhash_manager); } } // namespace __par_backend_hetero diff --git a/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_histogram.h b/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_histogram.h index fdcf06ad984..e7ac2ba50e1 100644 --- a/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_histogram.h +++ b/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_histogram.h @@ -285,9 +285,9 @@ struct __histogram_general_registers_local_reduction_submitter<__iters_per_work_ template <::std::uint16_t __iters_per_work_item, ::std::uint8_t __bins_per_work_item, typename _ExecutionPolicy, typename _Range1, typename _Range2, typename _BinHashMgr> auto -__histogram_general_registers_local_reduction(_ExecutionPolicy&& __exec, const sycl::event& __init_event, - ::std::uint16_t __work_group_size, _Range1&& __input, _Range2&& __bins, - const _BinHashMgr& __binhash_manager) +__histogram_general_registers_local_reduction(oneapi::dpl::__internal::__device_backend_tag, _ExecutionPolicy&& __exec, + const sycl::event& __init_event, ::std::uint16_t __work_group_size, + _Range1&& __input, _Range2&& __bins, const _BinHashMgr& __binhash_manager) { using _kernel_base_name = typename ::std::decay_t<_ExecutionPolicy>::kernel_name; @@ -380,9 +380,9 @@ struct __histogram_general_local_atomics_submitter<__iters_per_work_item, template <::std::uint16_t __iters_per_work_item, typename _ExecutionPolicy, typename _Range1, typename _Range2, typename _BinHashMgr> auto -__histogram_general_local_atomics(_ExecutionPolicy&& __exec, const sycl::event& __init_event, - ::std::uint16_t __work_group_size, _Range1&& __input, _Range2&& __bins, - const _BinHashMgr& __binhash_manager) +__histogram_general_local_atomics(oneapi::dpl::__internal::__device_backend_tag, _ExecutionPolicy&& __exec, + const sycl::event& __init_event, ::std::uint16_t __work_group_size, _Range1&& __input, + _Range2&& __bins, const _BinHashMgr& __binhash_manager) { using _kernel_base_name = typename ::std::decay_t<_ExecutionPolicy>::kernel_name; @@ -405,11 +405,11 @@ struct __histogram_general_private_global_atomics_submitter; template struct __histogram_general_private_global_atomics_submitter<__internal::__optional_kernel_name<_KernelName...>> { - template + template auto - operator()(_ExecutionPolicy&& __exec, const sycl::event& __init_event, ::std::uint16_t __min_iters_per_work_item, - ::std::uint16_t __work_group_size, _Range1&& __input, _Range2&& __bins, - const _BinHashMgr& __binhash_manager) + operator()(_BackendTag, _ExecutionPolicy&& __exec, const sycl::event& __init_event, + ::std::uint16_t __min_iters_per_work_item, ::std::uint16_t __work_group_size, _Range1&& __input, + _Range2&& __bins, const _BinHashMgr& __binhash_manager) { const ::std::size_t __n = __input.size(); const ::std::size_t __num_bins = __bins.size(); @@ -477,9 +477,10 @@ struct __histogram_general_private_global_atomics_submitter<__internal::__option }; template auto -__histogram_general_private_global_atomics(_ExecutionPolicy&& __exec, const sycl::event& __init_event, - ::std::uint16_t __min_iters_per_work_item, ::std::uint16_t __work_group_size, - _Range1&& __input, _Range2&& __bins, const _BinHashMgr& __binhash_manager) +__histogram_general_private_global_atomics(oneapi::dpl::__internal::__device_backend_tag, _ExecutionPolicy&& __exec, + const sycl::event& __init_event, ::std::uint16_t __min_iters_per_work_item, + ::std::uint16_t __work_group_size, _Range1&& __input, _Range2&& __bins, + const _BinHashMgr& __binhash_manager) { using _kernel_base_name = typename ::std::decay_t<_ExecutionPolicy>::kernel_name; @@ -487,14 +488,16 @@ __histogram_general_private_global_atomics(_ExecutionPolicy&& __exec, const sycl __histo_kernel_private_glocal_atomics<_kernel_base_name>>; return __histogram_general_private_global_atomics_submitter<_global_atomics_name>()( - ::std::forward<_ExecutionPolicy>(__exec), __init_event, __min_iters_per_work_item, __work_group_size, - ::std::forward<_Range1>(__input), ::std::forward<_Range2>(__bins), __binhash_manager); + oneapi::dpl::__internal::__device_backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __init_event, + __min_iters_per_work_item, __work_group_size, ::std::forward<_Range1>(__input), ::std::forward<_Range2>(__bins), + __binhash_manager); } template <::std::uint16_t __iters_per_work_item, typename _ExecutionPolicy, typename _Range1, typename _Range2, typename _BinHashMgr> auto -__parallel_histogram_select_kernel(_ExecutionPolicy&& __exec, const sycl::event& __init_event, _Range1&& __input, +__parallel_histogram_select_kernel(oneapi::dpl::__internal::__device_backend_tag __backend_tag, + _ExecutionPolicy&& __exec, const sycl::event& __init_event, _Range1&& __input, _Range2&& __bins, const _BinHashMgr& __binhash_manager) { using _private_histogram_type = ::std::uint16_t; @@ -513,7 +516,7 @@ __parallel_histogram_select_kernel(_ExecutionPolicy&& __exec, const sycl::event& { return __future( __histogram_general_registers_local_reduction<__iters_per_work_item, __max_work_item_private_bins>( - ::std::forward<_ExecutionPolicy>(__exec), __init_event, __work_group_size, + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __init_event, __work_group_size, ::std::forward<_Range1>(__input), ::std::forward<_Range2>(__bins), __binhash_manager)); } // if bins fit into SLM, use local atomics @@ -522,8 +525,8 @@ __parallel_histogram_select_kernel(_ExecutionPolicy&& __exec, const sycl::event& __local_mem_size) { return __future(__histogram_general_local_atomics<__iters_per_work_item>( - ::std::forward<_ExecutionPolicy>(__exec), __init_event, __work_group_size, ::std::forward<_Range1>(__input), - ::std::forward<_Range2>(__bins), __binhash_manager)); + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __init_event, __work_group_size, + ::std::forward<_Range1>(__input), ::std::forward<_Range2>(__bins), __binhash_manager)); } else // otherwise, use global atomics (private copies per workgroup) { @@ -533,26 +536,27 @@ __parallel_histogram_select_kernel(_ExecutionPolicy&& __exec, const sycl::event& // private copies of the histogram bins in global memory. No unrolling is taken advantage of here because it // is a runtime argument. return __future(__histogram_general_private_global_atomics( - ::std::forward<_ExecutionPolicy>(__exec), __init_event, __iters_per_work_item, __work_group_size, - ::std::forward<_Range1>(__input), ::std::forward<_Range2>(__bins), __binhash_manager)); + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __init_event, __iters_per_work_item, + __work_group_size, ::std::forward<_Range1>(__input), ::std::forward<_Range2>(__bins), __binhash_manager)); } } template auto -__parallel_histogram(_ExecutionPolicy&& __exec, const sycl::event& __init_event, _Range1&& __input, _Range2&& __bins, +__parallel_histogram(oneapi::dpl::__internal::__device_backend_tag __backend_tag, _ExecutionPolicy&& __exec, + const sycl::event& __init_event, _Range1&& __input, _Range2&& __bins, const _BinHashMgr& __binhash_manager) { if (__input.size() < 1048576) // 2^20 { return __parallel_histogram_select_kernel( - ::std::forward<_ExecutionPolicy>(__exec), __init_event, ::std::forward<_Range1>(__input), + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __init_event, ::std::forward<_Range1>(__input), ::std::forward<_Range2>(__bins), __binhash_manager); } else { return __parallel_histogram_select_kernel( - ::std::forward<_ExecutionPolicy>(__exec), __init_event, ::std::forward<_Range1>(__input), + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __init_event, ::std::forward<_Range1>(__input), ::std::forward<_Range2>(__bins), __binhash_manager); } } diff --git a/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_radix_sort.h b/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_radix_sort.h index 04fa8d3f124..4fd1aa1bef9 100644 --- a/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_radix_sort.h +++ b/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_radix_sort.h @@ -757,7 +757,8 @@ struct __parallel_radix_sort_iteration //----------------------------------------------------------------------- template auto -__parallel_radix_sort(_ExecutionPolicy&& __exec, _Range&& __in_rng, _Proj __proj) +__parallel_radix_sort(oneapi::dpl::__internal::__device_backend_tag, _ExecutionPolicy&& __exec, _Range&& __in_rng, + _Proj __proj) { const ::std::size_t __n = __in_rng.size(); assert(__n > 1); diff --git a/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_reduce.h b/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_reduce.h index c856083041e..cd474afbf1f 100644 --- a/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_reduce.h +++ b/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_reduce.h @@ -106,11 +106,10 @@ struct __parallel_transform_reduce_small_submitter<_Tp, __work_group_size, __ite __internal::__optional_kernel_name<_Name...>> { template = 0, typename... _Ranges> auto - operator()(_ExecutionPolicy&& __exec, const _Size __n, _ReduceOp __reduce_op, _TransformOp __transform_op, - _InitType __init, _Ranges&&... __rngs) const + operator()(oneapi::dpl::__internal::__device_backend_tag, _ExecutionPolicy&& __exec, const _Size __n, + _ReduceOp __reduce_op, _TransformOp __transform_op, _InitType __init, _Ranges&&... __rngs) const { auto __transform_pattern = unseq_backend::transform_reduce<_ExecutionPolicy, __iters_per_work_item, _ReduceOp, _TransformOp, @@ -140,9 +139,10 @@ struct __parallel_transform_reduce_small_submitter<_Tp, __work_group_size, __ite template = 0, typename... _Ranges> + typename... _Ranges> auto -__parallel_transform_reduce_small_impl(_ExecutionPolicy&& __exec, const _Size __n, _ReduceOp __reduce_op, +__parallel_transform_reduce_small_impl(oneapi::dpl::__internal::__device_backend_tag __backend_tag, + _ExecutionPolicy&& __exec, const _Size __n, _ReduceOp __reduce_op, _TransformOp __transform_op, _InitType __init, _Ranges&&... __rngs) { using _CustomName = oneapi::dpl::__internal::__policy_kernel_name<_ExecutionPolicy>; @@ -150,9 +150,9 @@ __parallel_transform_reduce_small_impl(_ExecutionPolicy&& __exec, const _Size __ __reduce_small_kernel<::std::integral_constant<::std::uint8_t, __iters_per_work_item>, _CustomName>>; return __parallel_transform_reduce_small_submitter<_Tp, __work_group_size, __iters_per_work_item, _Commutative, - _ReduceKernel>()(::std::forward<_ExecutionPolicy>(__exec), __n, - __reduce_op, __transform_op, __init, - ::std::forward<_Ranges>(__rngs)...); + _ReduceKernel>()( + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, + ::std::forward<_Ranges>(__rngs)...); } // Submits the first kernel of the parallel_transform_reduce for mid-sized arrays. @@ -168,11 +168,11 @@ struct __parallel_transform_reduce_device_kernel_submitter<_Tp, __work_group_siz __internal::__optional_kernel_name<_KernelName...>> { template = 0, typename... _Ranges> auto - operator()(_ExecutionPolicy&& __exec, _Size __n, _ReduceOp __reduce_op, _TransformOp __transform_op, - _InitType __init, sycl::buffer<_Tp>& __temp, _Ranges&&... __rngs) const + operator()(oneapi::dpl::__internal::__device_backend_tag, _ExecutionPolicy&& __exec, _Size __n, + _ReduceOp __reduce_op, _TransformOp __transform_op, _InitType __init, sycl::buffer<_Tp>& __temp, + _Ranges&&... __rngs) const { auto __transform_pattern = unseq_backend::transform_reduce<_ExecutionPolicy, __iters_per_work_item, _ReduceOp, _TransformOp, @@ -209,11 +209,11 @@ template > { - template = 0> + template auto - operator()(_ExecutionPolicy&& __exec, sycl::event& __reduce_event, _Size __n, _ReduceOp __reduce_op, - _TransformOp __transform_op, _InitType __init, sycl::buffer<_Tp>& __temp) const + operator()(oneapi::dpl::__internal::__device_backend_tag, _ExecutionPolicy&& __exec, sycl::event& __reduce_event, + _Size __n, _ReduceOp __reduce_op, _TransformOp __transform_op, _InitType __init, + sycl::buffer<_Tp>& __temp) const { using _NoOpFunctor = unseq_backend::walk_n<_ExecutionPolicy, oneapi::dpl::__internal::__no_op>; auto __transform_pattern = @@ -259,10 +259,10 @@ struct __parallel_transform_reduce_work_group_kernel_submitter< template = 0, typename... _Ranges> + typename _Size, typename _ReduceOp, typename _TransformOp, typename _InitType, typename... _Ranges> auto -__parallel_transform_reduce_mid_impl(_ExecutionPolicy&& __exec, _Size __n, _ReduceOp __reduce_op, +__parallel_transform_reduce_mid_impl(oneapi::dpl::__internal::__device_backend_tag __backend_tag, + _ExecutionPolicy&& __exec, _Size __n, _ReduceOp __reduce_op, _TransformOp __transform_op, _InitType __init, _Ranges&&... __rngs) { using _CustomName = oneapi::dpl::__internal::__policy_kernel_name<_ExecutionPolicy>; @@ -283,12 +283,14 @@ __parallel_transform_reduce_mid_impl(_ExecutionPolicy&& __exec, _Size __n, _Redu sycl::event __reduce_event = __parallel_transform_reduce_device_kernel_submitter<_Tp, __work_group_size, __iters_per_work_item_device_kernel, _Commutative, _ReduceDeviceKernel>()( - __exec, __n, __reduce_op, __transform_op, __init, __temp, ::std::forward<_Ranges>(__rngs)...); + __backend_tag, __exec, __n, __reduce_op, __transform_op, __init, __temp, + ::std::forward<_Ranges>(__rngs)...); __n = __n_groups; // Number of preliminary results from the device kernel. return __parallel_transform_reduce_work_group_kernel_submitter< _Tp, __work_group_size, __iters_per_work_item_work_group_kernel, _Commutative, _ReduceWorkGroupKernel>()( - ::std::forward<_ExecutionPolicy>(__exec), __reduce_event, __n, __reduce_op, __transform_op, __init, __temp); + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __reduce_event, __n, __reduce_op, __transform_op, + __init, __temp); } // General implementation using a tree reduction @@ -296,11 +298,11 @@ template = 0, typename... _Ranges> static auto - submit(_ExecutionPolicy&& __exec, _Size __n, ::std::uint16_t __work_group_size, _ReduceOp __reduce_op, - _TransformOp __transform_op, _InitType __init, _Ranges&&... __rngs) + submit(oneapi::dpl::__internal::__device_backend_tag, _ExecutionPolicy&& __exec, _Size __n, + ::std::uint16_t __work_group_size, _ReduceOp __reduce_op, _TransformOp __transform_op, _InitType __init, + _Ranges&&... __rngs) { using _CustomName = oneapi::dpl::__internal::__policy_kernel_name<_ExecutionPolicy>; using _NoOpFunctor = unseq_backend::walk_n<_ExecutionPolicy, oneapi::dpl::__internal::__no_op>; @@ -417,11 +419,10 @@ struct __parallel_transform_reduce_impl // Big arrays are processed with a recursive tree reduction. __work_group_size * __iters_per_work_item elements are // reduced in each step. template = 0, - typename... _Ranges> + typename _InitType, typename... _Ranges> auto -__parallel_transform_reduce(_ExecutionPolicy&& __exec, _ReduceOp __reduce_op, _TransformOp __transform_op, - _InitType __init, _Ranges&&... __rngs) +__parallel_transform_reduce(oneapi::dpl::__internal::__device_backend_tag __backend_tag, _ExecutionPolicy&& __exec, + _ReduceOp __reduce_op, _TransformOp __transform_op, _InitType __init, _Ranges&&... __rngs) { auto __n = oneapi::dpl::__ranges::__get_first_range_size(__rngs...); assert(__n > 0); @@ -437,37 +438,37 @@ __parallel_transform_reduce(_ExecutionPolicy&& __exec, _ReduceOp __reduce_op, _T if (__n <= 256) { return __parallel_transform_reduce_small_impl<_Tp, 256, 1, _Commutative>( - ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, ::std::forward<_Ranges>(__rngs)...); } else if (__n <= 512) { return __parallel_transform_reduce_small_impl<_Tp, 256, 2, _Commutative>( - ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, ::std::forward<_Ranges>(__rngs)...); } else if (__n <= 1024) { return __parallel_transform_reduce_small_impl<_Tp, 256, 4, _Commutative>( - ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, ::std::forward<_Ranges>(__rngs)...); } else if (__n <= 2048) { return __parallel_transform_reduce_small_impl<_Tp, 256, 8, _Commutative>( - ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, ::std::forward<_Ranges>(__rngs)...); } else if (__n <= 4096) { return __parallel_transform_reduce_small_impl<_Tp, 256, 16, _Commutative>( - ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, ::std::forward<_Ranges>(__rngs)...); } else if (__n <= 8192) { return __parallel_transform_reduce_small_impl<_Tp, 256, 32, _Commutative>( - ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, ::std::forward<_Ranges>(__rngs)...); } @@ -477,44 +478,44 @@ __parallel_transform_reduce(_ExecutionPolicy&& __exec, _ReduceOp __reduce_op, _T else if (__n <= 2097152) { return __parallel_transform_reduce_mid_impl<_Tp, 256, 32, 1, _Commutative>( - ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, ::std::forward<_Ranges>(__rngs)...); } else if (__n <= 4194304) { return __parallel_transform_reduce_mid_impl<_Tp, 256, 32, 2, _Commutative>( - ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, ::std::forward<_Ranges>(__rngs)...); } else if (__n <= 8388608) { return __parallel_transform_reduce_mid_impl<_Tp, 256, 32, 4, _Commutative>( - ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, ::std::forward<_Ranges>(__rngs)...); } else if (__n <= 16777216) { return __parallel_transform_reduce_mid_impl<_Tp, 256, 32, 8, _Commutative>( - ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, ::std::forward<_Ranges>(__rngs)...); } else if (__n <= 33554432) { return __parallel_transform_reduce_mid_impl<_Tp, 256, 32, 16, _Commutative>( - ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, ::std::forward<_Ranges>(__rngs)...); } else if (__n <= 67108864) { return __parallel_transform_reduce_mid_impl<_Tp, 256, 32, 32, _Commutative>( - ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __n, __reduce_op, __transform_op, __init, ::std::forward<_Ranges>(__rngs)...); } } // Otherwise use a recursive tree reduction. return __parallel_transform_reduce_impl<_Tp, 32, _Commutative>::submit( - ::std::forward<_ExecutionPolicy>(__exec), __n, __work_group_size, __reduce_op, __transform_op, __init, - ::std::forward<_Ranges>(__rngs)...); + __backend_tag, ::std::forward<_ExecutionPolicy>(__exec), __n, __work_group_size, __reduce_op, __transform_op, + __init, ::std::forward<_Ranges>(__rngs)...); } } // namespace __par_backend_hetero diff --git a/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_utils.h b/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_utils.h index c0c0ee40946..bbfd53662ad 100644 --- a/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_utils.h +++ b/include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_utils.h @@ -386,8 +386,6 @@ class __buffer_impl __container_t __container; public: - static_assert(::std::is_same_v<_ExecutionPolicy, ::std::decay_t<_ExecutionPolicy>>); - __buffer_impl(_ExecutionPolicy /*__exec*/, ::std::size_t __n_elements) : __container{sycl::range<1>(__n_elements)} { } diff --git a/include/oneapi/dpl/pstl/hetero/dpcpp/utils_ranges_sycl.h b/include/oneapi/dpl/pstl/hetero/dpcpp/utils_ranges_sycl.h index ea0bbcc0010..1821301e911 100644 --- a/include/oneapi/dpl/pstl/hetero/dpcpp/utils_ranges_sycl.h +++ b/include/oneapi/dpl/pstl/hetero/dpcpp/utils_ranges_sycl.h @@ -716,6 +716,32 @@ struct __get_sycl_range } }; +//---------------------------------------------------------- +// __select_backend (for the hetero policies) +//---------------------------------------------------------- + +//TODO required correct implementation of this __ranges::__select_backend() +// 1. There is still not RA ranges checks +// 2. Obviously, a return tag is not necessarily oneapi::dpl::__internal::__hetero_tag +template +oneapi::dpl::__internal::__hetero_tag +__select_backend(const execution::device_policy<_KernelName>&, _Ranges&&...) +{ + return {}; +} + +#if _ONEDPL_FPGA_DEVICE +//TODO required correct implementation of this __ranges::__select_backend() +// 1. There is still not RA ranges checks +// 2. Obviously, a return tag is not necessarily oneapi::dpl::__internal::__hetero_tag +template +oneapi::dpl::__internal::__hetero_tag +__select_backend(const execution::fpga_policy<_Factor, _KernelName>&, _Ranges&&...) +{ + return {}; +} +#endif + } // namespace __ranges } // namespace dpl } // namespace oneapi diff --git a/include/oneapi/dpl/pstl/hetero/histogram_impl_hetero.h b/include/oneapi/dpl/pstl/hetero/histogram_impl_hetero.h index 27179622b6b..87d22e9a0a7 100644 --- a/include/oneapi/dpl/pstl/hetero/histogram_impl_hetero.h +++ b/include/oneapi/dpl/pstl/hetero/histogram_impl_hetero.h @@ -117,11 +117,12 @@ struct __hist_fill_zeros_wrapper { }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy> -__pattern_histogram(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, _RandomAccessIterator1 __last, - _Size __num_bins, _BinHash&& __func, _RandomAccessIterator2 __histogram_first) +template +void +__pattern_histogram(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, _Size __num_bins, _BinHash&& __func, + _RandomAccessIterator2 __histogram_first) { //If there are no histogram bins there is nothing to do if (__num_bins > 0) @@ -143,7 +144,7 @@ __pattern_histogram(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, _ //fill histogram bins with zeros auto __init_event = oneapi::dpl::__par_backend_hetero::__parallel_for( - oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__hist_fill_zeros_wrapper>(__exec), + _BackendTag{}, oneapi::dpl::__par_backend_hetero::make_wrapped_policy<__hist_fill_zeros_wrapper>(__exec), unseq_backend::walk_n<_ExecutionPolicy, decltype(__fill_func)>{__fill_func}, __num_bins, __bins); if (__n > 0) @@ -156,8 +157,8 @@ __pattern_histogram(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, _ _RandomAccessIterator1>(); auto __input_buf = __keep_input(__first, __last); - __parallel_histogram(::std::forward<_ExecutionPolicy>(__exec), __init_event, __input_buf.all_view(), - ::std::move(__bins), __binhash_manager) + __parallel_histogram(_BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __init_event, + __input_buf.all_view(), ::std::move(__bins), __binhash_manager) .wait(); } else diff --git a/include/oneapi/dpl/pstl/hetero/numeric_impl_hetero.h b/include/oneapi/dpl/pstl/hetero/numeric_impl_hetero.h index 60c1001f5b8..23beae41c10 100644 --- a/include/oneapi/dpl/pstl/hetero/numeric_impl_hetero.h +++ b/include/oneapi/dpl/pstl/hetero/numeric_impl_hetero.h @@ -37,12 +37,12 @@ namespace __internal // transform_reduce (version with two binary functions) //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Tp> -__pattern_transform_reduce(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, - _BinaryOperation2 __binary_op2, /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +_Tp +__pattern_transform_reduce(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _Tp __init, + _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) { if (__first1 == __last1) return __init; @@ -60,7 +60,7 @@ __pattern_transform_reduce(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __f return oneapi::dpl::__par_backend_hetero::__parallel_transform_reduce<_RepackedTp, ::std::true_type /*is_commutative*/>( - ::std::forward<_ExecutionPolicy>(__exec), __binary_op1, _Functor{__binary_op2}, + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __binary_op1, _Functor{__binary_op2}, unseq_backend::__init_value<_RepackedTp>{__init}, // initial value __buf1.all_view(), __buf2.all_view()) .get(); @@ -70,12 +70,12 @@ __pattern_transform_reduce(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __f // transform_reduce (with unary and binary functions) //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Tp> -__pattern_transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, - _BinaryOperation __binary_op, _UnaryOperation __unary_op, /*vector=*/::std::true_type, - /*parallel=*/::std::true_type) +template +_Tp +__pattern_transform_reduce(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _ForwardIterator __first, + _ForwardIterator __last, _Tp __init, _BinaryOperation __binary_op, + _UnaryOperation __unary_op) { if (__first == __last) return __init; @@ -88,7 +88,7 @@ __pattern_transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, return oneapi::dpl::__par_backend_hetero::__parallel_transform_reduce<_RepackedTp, ::std::true_type /*is_commutative*/>( - ::std::forward<_ExecutionPolicy>(__exec), __binary_op, _Functor{__unary_op}, + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __binary_op, _Functor{__unary_op}, unseq_backend::__init_value<_RepackedTp>{__init}, // initial value __buf.all_view()) .get(); @@ -122,11 +122,12 @@ __iterators_possibly_equal(const sycl_iterator<_Mode1, _T, _Allocator>& __it1, } #endif // _ONEDPL_BACKEND_SYCL -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator2> -__pattern_transform_scan_base(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, _Iterator2 __result, - _UnaryOperation __unary_op, _InitType __init, _BinaryOperation __binary_op, _Inclusive) +template +_Iterator2 +__pattern_transform_scan_base(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator1 __first, + _Iterator1 __last, _Iterator2 __result, _UnaryOperation __unary_op, _InitType __init, + _BinaryOperation __binary_op, _Inclusive) { if (__first == __last) return __result; @@ -143,9 +144,9 @@ __pattern_transform_scan_base(_ExecutionPolicy&& __exec, _Iterator1 __first, _It auto __keep2 = oneapi::dpl::__ranges::__get_sycl_range<__par_backend_hetero::access_mode::write, _Iterator2>(); auto __buf2 = __keep2(__result, __result + __n); - oneapi::dpl::__par_backend_hetero::__parallel_transform_scan(::std::forward<_ExecutionPolicy>(__exec), - __buf1.all_view(), __buf2.all_view(), __n, - __unary_op, __init, __binary_op, _Inclusive{}) + oneapi::dpl::__par_backend_hetero::__parallel_transform_scan( + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __buf1.all_view(), __buf2.all_view(), __n, + __unary_op, __init, __binary_op, _Inclusive{}) .wait(); } else @@ -168,48 +169,48 @@ __pattern_transform_scan_base(_ExecutionPolicy&& __exec, _Iterator1 __first, _It auto __buf2 = __keep2(__first_tmp, __last_tmp); // Run main algorithm and save data into temporary buffer - oneapi::dpl::__par_backend_hetero::__parallel_transform_scan(__policy, __buf1.all_view(), __buf2.all_view(), - __n, __unary_op, __init, __binary_op, _Inclusive{}) + oneapi::dpl::__par_backend_hetero::__parallel_transform_scan(_BackendTag{}, __policy, __buf1.all_view(), + __buf2.all_view(), __n, __unary_op, __init, + __binary_op, _Inclusive{}) .wait(); // Move data from temporary buffer into results - oneapi::dpl::__internal::__pattern_walk2_brick(::std::move(__policy), __first_tmp, __last_tmp, __result, - oneapi::dpl::__internal::__brick_move<_NewExecutionPolicy>{}, - ::std::true_type{}); + oneapi::dpl::__internal::__pattern_walk2_brick( + __tag, ::std::move(__policy), __first_tmp, __last_tmp, __result, + oneapi::dpl::__internal::__brick_move<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}); //TODO: optimize copy back depending on Iterator, i.e. set_final_data for host iterator/pointer } return __result + __n; } - -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator2> -__pattern_transform_scan(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, _Iterator2 __result, - _UnaryOperation __unary_op, _Type __init, _BinaryOperation __binary_op, _Inclusive, - /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +_Iterator2 +__pattern_transform_scan(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator1 __first, + _Iterator1 __last, _Iterator2 __result, _UnaryOperation __unary_op, _Type __init, + _BinaryOperation __binary_op, _Inclusive) { using _RepackedType = __par_backend_hetero::__repacked_tuple_t<_Type>; using _InitType = unseq_backend::__init_value<_RepackedType>; - return __pattern_transform_scan_base(::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, + return __pattern_transform_scan_base(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __unary_op, _InitType{__init}, __binary_op, _Inclusive{}); } // scan without initial element -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Iterator2> -__pattern_transform_scan(_ExecutionPolicy&& __exec, _Iterator1 __first, _Iterator1 __last, _Iterator2 __result, - _UnaryOperation __unary_op, _BinaryOperation __binary_op, _Inclusive, - /*vector=*/::std::true_type, /*parallel=*/::std::true_type) +template +_Iterator2 +__pattern_transform_scan(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Iterator1 __first, + _Iterator1 __last, _Iterator2 __result, _UnaryOperation __unary_op, + _BinaryOperation __binary_op, _Inclusive) { using _Type = typename ::std::iterator_traits<_Iterator1>::value_type; using _RepackedType = __par_backend_hetero::__repacked_tuple_t<_Type>; using _InitType = unseq_backend::__no_init_value<_RepackedType>; - return __pattern_transform_scan_base(::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, + return __pattern_transform_scan_base(__tag, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __unary_op, _InitType{}, __binary_op, _Inclusive{}); } @@ -223,11 +224,11 @@ struct adjacent_difference_wrapper { }; -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _ForwardIterator2> -__pattern_adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __d_first, _BinaryOperation __op, /*vector*/ ::std::true_type, - /*parallel*/ ::std::true_type) +template +_ForwardIterator2 +__pattern_adjacent_difference(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first, + _ForwardIterator1 __last, _ForwardIterator2 __d_first, _BinaryOperation __op) { auto __n = __last - __first; if (__n <= 0) @@ -242,13 +243,12 @@ __pattern_adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __fir // if we have the only element, just copy it according to the specification if (__n == 1) { - return __internal::__except_handler([&__exec, __first, __last, __d_first, __d_last, &__op]() { + return __internal::__except_handler([__tag, &__exec, __first, __last, __d_first, __d_last, &__op]() { auto __wrapped_policy = __par_backend_hetero::make_wrapped_policy( ::std::forward<_ExecutionPolicy>(__exec)); - __internal::__pattern_walk2_brick(__wrapped_policy, __first, __last, __d_first, - __internal::__brick_copy{}, - ::std::true_type{}); + __internal::__pattern_walk2_brick(__tag, __wrapped_policy, __first, __last, __d_first, + __internal::__brick_copy<__hetero_tag<_BackendTag>, _ExecutionPolicy>{}); return __d_last; }); @@ -270,8 +270,8 @@ __pattern_adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __fir using _Function = unseq_backend::walk_adjacent_difference<_ExecutionPolicy, decltype(__fn)>; - oneapi::dpl::__par_backend_hetero::__parallel_for(__exec, _Function{__fn}, __n, __buf1.all_view(), - __buf2.all_view()) + oneapi::dpl::__par_backend_hetero::__parallel_for(_BackendTag{}, __exec, _Function{__fn}, __n, + __buf1.all_view(), __buf2.all_view()) .wait(); return __d_last; diff --git a/include/oneapi/dpl/pstl/hetero/numeric_ranges_impl_hetero.h b/include/oneapi/dpl/pstl/hetero/numeric_ranges_impl_hetero.h index 0b104a5ff4b..969b05ab914 100644 --- a/include/oneapi/dpl/pstl/hetero/numeric_ranges_impl_hetero.h +++ b/include/oneapi/dpl/pstl/hetero/numeric_ranges_impl_hetero.h @@ -37,11 +37,11 @@ namespace __ranges // transform_reduce (version with two binary functions) //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Tp> -__pattern_transform_reduce(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _Tp __init, - _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) +template +_Tp +__pattern_transform_reduce(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, + _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) { if (__rng1.empty()) return __init; @@ -51,7 +51,7 @@ __pattern_transform_reduce(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2& return oneapi::dpl::__par_backend_hetero::__parallel_transform_reduce<_RepackedTp, ::std::true_type /*is_commutative*/>( - ::std::forward<_ExecutionPolicy>(__exec), __binary_op1, _Functor{__binary_op2}, + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __binary_op1, _Functor{__binary_op2}, unseq_backend::__init_value<_RepackedTp>{__init}, // initial value ::std::forward<_Range1>(__rng1), ::std::forward<_Range2>(__rng2)) .get(); @@ -61,10 +61,11 @@ __pattern_transform_reduce(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2& // transform_reduce (with unary and binary functions) //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, _Tp> -__pattern_transform_reduce(_ExecutionPolicy&& __exec, _Range&& __rng, _Tp __init, _BinaryOperation __binary_op, - _UnaryOperation __unary_op) +template +_Tp +__pattern_transform_reduce(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Range&& __rng, _Tp __init, + _BinaryOperation __binary_op, _UnaryOperation __unary_op) { if (__rng.empty()) return __init; @@ -74,7 +75,7 @@ __pattern_transform_reduce(_ExecutionPolicy&& __exec, _Range&& __rng, _Tp __init return oneapi::dpl::__par_backend_hetero::__parallel_transform_reduce<_RepackedTp, ::std::true_type /*is_commutative*/>( - ::std::forward<_ExecutionPolicy>(__exec), __binary_op, _Functor{__unary_op}, + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), __binary_op, _Functor{__unary_op}, unseq_backend::__init_value<_RepackedTp>{__init}, // initial value ::std::forward<_Range>(__rng)) .get(); @@ -84,12 +85,11 @@ __pattern_transform_reduce(_ExecutionPolicy&& __exec, _Range&& __rng, _Tp __init // transform_scan //------------------------------------------------------------------------ -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range2>> -__pattern_transform_scan_base(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _UnaryOperation __unary_op, - _InitType __init, _BinaryOperation __binary_op, _Inclusive) +template +oneapi::dpl::__internal::__difference_t<_Range2> +__pattern_transform_scan_base(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, + _UnaryOperation __unary_op, _InitType __init, _BinaryOperation __binary_op, _Inclusive) { if (__rng1.empty()) return 0; @@ -106,8 +106,8 @@ __pattern_transform_scan_base(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Rang _NoOpFunctor __get_data_op; oneapi::dpl::__par_backend_hetero::__parallel_transform_scan_base( - ::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range1>(__rng1), ::std::forward<_Range2>(__rng2), - __binary_op, __init, + _BackendTag{}, ::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range1>(__rng1), + ::std::forward<_Range2>(__rng2), __binary_op, __init, // local scan unseq_backend::__scan<_Inclusive, _ExecutionPolicy, _BinaryOperation, _UnaryFunctor, _Assigner, _Assigner, _NoOpFunctor, _InitType>{__binary_op, _UnaryFunctor{__unary_op}, __assign_op, __assign_op, @@ -122,36 +122,34 @@ __pattern_transform_scan_base(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Rang return __rng1_size; } -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range2>> -__pattern_transform_scan(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _UnaryOperation __unary_op, - _Type __init, _BinaryOperation __binary_op, _Inclusive) +template +oneapi::dpl::__internal::__difference_t<_Range2> +__pattern_transform_scan(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, + _UnaryOperation __unary_op, _Type __init, _BinaryOperation __binary_op, _Inclusive) { using _RepackedType = __par_backend_hetero::__repacked_tuple_t<_Type>; using _InitType = unseq_backend::__init_value<_RepackedType>; - return __pattern_transform_scan_base(::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range1>(__rng1), - ::std::forward<_Range2>(__rng2), __unary_op, _InitType{__init}, __binary_op, - _Inclusive{}); + return __pattern_transform_scan_base(__tag, ::std::forward<_ExecutionPolicy>(__exec), + ::std::forward<_Range1>(__rng1), ::std::forward<_Range2>(__rng2), __unary_op, + _InitType{__init}, __binary_op, _Inclusive{}); } // scan without initial element -template -oneapi::dpl::__internal::__enable_if_hetero_execution_policy<_ExecutionPolicy, - oneapi::dpl::__internal::__difference_t<_Range2>> -__pattern_transform_scan(_ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, _UnaryOperation __unary_op, - _BinaryOperation __binary_op, _Inclusive) +oneapi::dpl::__internal::__difference_t<_Range2> +__pattern_transform_scan(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Range1&& __rng1, _Range2&& __rng2, + _UnaryOperation __unary_op, _BinaryOperation __binary_op, _Inclusive) { using _Type = oneapi::dpl::__internal::__value_t<_Range1>; using _RepackedType = __par_backend_hetero::__repacked_tuple_t<_Type>; using _InitType = unseq_backend::__no_init_value<_RepackedType>; - return __pattern_transform_scan_base(::std::forward<_ExecutionPolicy>(__exec), ::std::forward<_Range1>(__rng1), - ::std::forward<_Range2>(__rng2), __unary_op, _InitType{}, __binary_op, - _Inclusive{}); + return __pattern_transform_scan_base(__tag, ::std::forward<_ExecutionPolicy>(__exec), + ::std::forward<_Range1>(__rng1), ::std::forward<_Range2>(__rng2), __unary_op, + _InitType{}, __binary_op, _Inclusive{}); } } // namespace __ranges diff --git a/include/oneapi/dpl/pstl/histogram_impl.h b/include/oneapi/dpl/pstl/histogram_impl.h index 4c8f5204793..362685bd19c 100644 --- a/include/oneapi/dpl/pstl/histogram_impl.h +++ b/include/oneapi/dpl/pstl/histogram_impl.h @@ -32,12 +32,14 @@ namespace dpl namespace __internal { -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy> -__pattern_histogram(_ExecutionPolicy&& exec, _RandomAccessIterator1 __first, _RandomAccessIterator1 __last, +void +__pattern_histogram(_Tag, _ExecutionPolicy&& exec, _RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _Size __num_bins, _IdxHashFunc __func, _RandomAccessIterator2 __histogram_first) { + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + static_assert(sizeof(_Size) == 0 /*false*/, "Histogram API is currently unsupported for policies other than device execution policies"); } @@ -50,8 +52,10 @@ oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomA histogram(_ExecutionPolicy&& exec, _RandomAccessIterator1 first, _RandomAccessIterator1 last, _Size num_bins, _ValueType first_bin_min_val, _ValueType last_bin_max_val, _RandomAccessIterator2 histogram_first) { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(exec, first, histogram_first); + oneapi::dpl::__internal::__pattern_histogram( - ::std::forward<_ExecutionPolicy>(exec), first, last, num_bins, + __dispatch_tag, ::std::forward<_ExecutionPolicy>(exec), first, last, num_bins, oneapi::dpl::__internal::__evenly_divided_binhash<_ValueType>(first_bin_min_val, last_bin_max_val, num_bins), histogram_first); return histogram_first + num_bins; @@ -64,9 +68,11 @@ histogram(_ExecutionPolicy&& exec, _RandomAccessIterator1 first, _RandomAccessIt _RandomAccessIterator2 boundary_first, _RandomAccessIterator2 boundary_last, _RandomAccessIterator3 histogram_first) { + const auto __dispatch_tag = oneapi::dpl::__internal::__select_backend(exec, first, boundary_first, histogram_first); + ::std::ptrdiff_t num_bins = boundary_last - boundary_first - 1; oneapi::dpl::__internal::__pattern_histogram( - ::std::forward<_ExecutionPolicy>(exec), first, last, num_bins, + __dispatch_tag, ::std::forward<_ExecutionPolicy>(exec), first, last, num_bins, oneapi::dpl::__internal::__custom_boundary_binhash{boundary_first, boundary_last}, histogram_first); return histogram_first + num_bins; } diff --git a/include/oneapi/dpl/pstl/iterator_defs.h b/include/oneapi/dpl/pstl/iterator_defs.h index ad778064493..1b85d74fc40 100644 --- a/include/oneapi/dpl/pstl/iterator_defs.h +++ b/include/oneapi/dpl/pstl/iterator_defs.h @@ -27,61 +27,33 @@ namespace dpl namespace __internal { -// Internal wrapper around ::std::iterator_traits as it is required to be -// SFINAE-friendly(not produce "hard" error when _Ip is not an iterator) -// only starting with C++17. Although many standard library implementations -// provide it for older versions, we cannot rely on that. -template -struct __iterator_traits -{ -}; - -template -struct __iterator_traits<_Ip, - ::std::void_t> - : ::std::iterator_traits<_Ip> -{ -}; - -// Handles _Tp* and const _Tp* specializations -template -struct __iterator_traits<_Tp*, void> : ::std::iterator_traits<_Tp*> -{ -}; - -// Make is_random_access_iterator not to fail with a 'hard' error when it's used in SFINAE with -// a non-iterator type by providing a default value. -template -struct __is_random_access_iterator_impl : ::std::false_type -{ -}; +// Make is_random_access_iterator and is_forward_iterator not to fail with a 'hard' error when it's used in +// SFINAE with a non-iterator type by providing a default value. +template +auto +__is_iterator_of(int) -> decltype( + ::std::conjunction<::std::is_base_of< + _IteratorTag, typename ::std::iterator_traits<::std::decay_t<_IteratorTypes>>::iterator_category>...>{}); -template -struct __is_random_access_iterator_impl<_IteratorType, - ::std::void_t::iterator_category>> - : ::std::is_same::iterator_category, ::std::random_access_iterator_tag> -{ -}; +template +auto +__is_iterator_of(...) -> ::std::false_type; -/* iterator */ -template -struct __is_random_access_iterator - : ::std::conditional_t<__is_random_access_iterator_impl<_IteratorType>::value, - __is_random_access_iterator<_OtherIteratorTypes...>, ::std::false_type> +template +struct __is_random_access_iterator : decltype(__is_iterator_of<::std::random_access_iterator_tag, _IteratorTypes...>(0)) { }; -template -struct __is_random_access_iterator<_IteratorType> : __is_random_access_iterator_impl<_IteratorType> +template +struct __is_forward_iterator : decltype(__is_iterator_of<::std::forward_iterator_tag, _IteratorTypes...>(0)) { }; template -using __is_random_access_iterator_t = typename __is_random_access_iterator<_IteratorTypes...>::type; +inline constexpr bool __is_random_access_iterator_v = __is_random_access_iterator<_IteratorTypes...>::value; template -inline constexpr bool __is_random_access_iterator_v = __is_random_access_iterator<_IteratorTypes...>::value; +inline constexpr bool __is_forward_iterator_v = __is_forward_iterator<_IteratorTypes...>::value; } // namespace __internal } // namespace dpl diff --git a/include/oneapi/dpl/pstl/numeric_fwd.h b/include/oneapi/dpl/pstl/numeric_fwd.h index c663cd5c2d4..1c835443e78 100644 --- a/include/oneapi/dpl/pstl/numeric_fwd.h +++ b/include/oneapi/dpl/pstl/numeric_fwd.h @@ -25,6 +25,8 @@ namespace dpl { namespace __internal { +template +struct __parallel_tag; //------------------------------------------------------------------------ // transform_reduce (version with two binary functions, according to draft N4659) @@ -41,19 +43,17 @@ _Tp __brick_transform_reduce(_ForwardIterator1, _ForwardIterator1, _ForwardItera _BinaryOperation2, /*__is_vector=*/::std::false_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _Tp> -__pattern_transform_reduce(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Tp, - _BinaryOperation1, _BinaryOperation2, _IsVector, - /*is_parallel=*/::std::false_type) noexcept; +template +_Tp +__pattern_transform_reduce(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Tp, + _BinaryOperation1, _BinaryOperation2) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _Tp> -__pattern_transform_reduce(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _Tp, _BinaryOperation1, _BinaryOperation2, _IsVector __is_vector, - /*is_parallel=*/::std::true_type); +template +_Tp +__pattern_transform_reduce(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, + _RandomAccessIterator1, _RandomAccessIterator2, _Tp, _BinaryOperation1, _BinaryOperation2); //------------------------------------------------------------------------ // transform_reduce (version with unary and binary functions) @@ -67,19 +67,29 @@ template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _Tp> -__pattern_transform_reduce(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Tp, _BinaryOperation, - _UnaryOperation, _IsVector, - /*is_parallel=*/::std::false_type) noexcept; - -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _Tp> -__pattern_transform_reduce(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Tp, _BinaryOperation, - _UnaryOperation, _IsVector, - /*is_parallel=*/::std::true_type); +template +_Tp +__pattern_transform_reduce(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Tp, + _BinaryOperation1, _BinaryOperation2 __bnary_op2) noexcept; + +template +_Tp +__pattern_transform_reduce(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, + _RandomAccessIterator1, _RandomAccessIterator2, _Tp, _BinaryOperation1, _BinaryOperation2); + +template +_Tp +__pattern_transform_reduce(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Tp, _BinaryOperation, + _UnaryOperation) noexcept; + +template +_Tp +__pattern_transform_reduce(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _Tp, _BinaryOperation, _UnaryOperation); //------------------------------------------------------------------------ // transform_exclusive_scan @@ -97,36 +107,30 @@ ::std::pair<_OutputIterator, _Tp> __brick_transform_scan(_RandomAccessIterator, _UnaryOperation, _Tp, _BinaryOperation, /*Inclusive*/ ::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_transform_scan(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _UnaryOperation, _Tp, - _BinaryOperation, _Inclusive, _IsVector, - /*is_parallel=*/::std::false_type) noexcept; - -template -oneapi::dpl::__internal::__enable_if_host_execution_policy_conditional< - _ExecutionPolicy, !::std::is_floating_point_v<_Tp>, _OutputIterator> -__pattern_transform_scan(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator, - _UnaryOperation, _Tp, _BinaryOperation, _Inclusive, _IsVector, - /*is_parallel=*/::std::true_type); - -template -oneapi::dpl::__internal::__enable_if_host_execution_policy_conditional<_ExecutionPolicy, - ::std::is_floating_point_v<_Tp>, _OutputIterator> -__pattern_transform_scan(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator, - _UnaryOperation, _Tp, _BinaryOperation, _Inclusive, _IsVector, - /*is_parallel=*/::std::true_type); +template +_OutputIterator +__pattern_transform_scan(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _UnaryOperation, + _Tp, _BinaryOperation, _Inclusive) noexcept; + +template +::std::enable_if_t, _OutputIterator> +__pattern_transform_scan(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _OutputIterator, _UnaryOperation, _Tp, _BinaryOperation, _Inclusive); + +template +::std::enable_if_t<::std::is_floating_point_v<_Tp>, _OutputIterator> +__pattern_transform_scan(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _OutputIterator, _UnaryOperation, _Tp, _BinaryOperation, _Inclusive); // transform_scan without initial element -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_transform_scan(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, - _OutputIterator __result, _UnaryOperation __unary_op, _BinaryOperation __binary_op, _Inclusive, - _IsVector __is_vector, _IsParallel __is_parallel); +template +_OutputIterator +__pattern_transform_scan(_Tag, _ExecutionPolicy&& __exec, _ForwardIterator, _ForwardIterator, _OutputIterator, + _UnaryOperation, _BinaryOperation, _Inclusive); //------------------------------------------------------------------------ // adjacent_difference @@ -141,17 +145,16 @@ _OutputIterator __brick_adjacent_difference(_RandomAccessIterator, _RandomAccess _BinaryOperation, /*is_vector*/ ::std::true_type) noexcept; -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_adjacent_difference(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryOperation, - _IsVector, /*is_parallel*/ ::std::false_type) noexcept; - -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_adjacent_difference(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator, - _BinaryOperation, _IsVector, /*is_parallel*/ ::std::true_type); +template +_OutputIterator +__pattern_adjacent_difference(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, + _BinaryOperation) noexcept; + +template +_RandomAccessIterator2 +__pattern_adjacent_difference(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, + _RandomAccessIterator1, _RandomAccessIterator2, _BinaryOperation); } // namespace __internal } // namespace dpl diff --git a/include/oneapi/dpl/pstl/numeric_impl.h b/include/oneapi/dpl/pstl/numeric_impl.h index 8e65580918c..b87a02ba428 100644 --- a/include/oneapi/dpl/pstl/numeric_impl.h +++ b/include/oneapi/dpl/pstl/numeric_impl.h @@ -61,36 +61,40 @@ __brick_transform_reduce(_RandomAccessIterator1 __first1, _RandomAccessIterator1 [=, &__binary_op2](_DifferenceType __i) { return __binary_op2(__first1[__i], __first2[__i]); }); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _Tp> -__pattern_transform_reduce(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, +template +_Tp +__pattern_transform_reduce(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, - _BinaryOperation2 __binary_op2, _IsVector __is_vector, - /*is_parallel=*/::std::false_type) noexcept + _BinaryOperation2 __binary_op2) noexcept { - return __brick_transform_reduce(__first1, __last1, __first2, __init, __binary_op1, __binary_op2, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __brick_transform_reduce(__first1, __last1, __first2, __init, __binary_op1, __binary_op2, + typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _Tp> -__pattern_transform_reduce(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, - _BinaryOperation2 __binary_op2, _IsVector __is_vector, /*is_parallel=*/::std::true_type) +template +_Tp +__pattern_transform_reduce(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _Tp __init, + _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + return __internal::__except_handler([&]() { return __par_backend::__parallel_transform_reduce( - ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first1, __last1, [__first1, __first2, __binary_op2](_RandomAccessIterator1 __i) mutable { return __binary_op2(*__i, *(__first2 + (__i - __first1))); }, __init, __binary_op1, // Combine - [__first1, __first2, __binary_op1, __binary_op2, - __is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j, _Tp __init) -> _Tp { + [__first1, __first2, __binary_op1, __binary_op2](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j, + _Tp __init) -> _Tp { return __internal::__brick_transform_reduce(__i, __j, __first2 + (__i - __first1), __init, __binary_op1, - __binary_op2, __is_vector); + __binary_op2, _IsVector{}); }); }); } @@ -123,29 +127,33 @@ __brick_transform_reduce(_RandomAccessIterator __first, _RandomAccessIterator __ [=, &__unary_op](_DifferenceType __i) { return __unary_op(__first[__i]); }); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _Tp> -__pattern_transform_reduce(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, - _BinaryOperation __binary_op, _UnaryOperation __unary_op, _IsVector __is_vector, - /*is_parallel=*/::std::false_type) noexcept +template +_Tp +__pattern_transform_reduce(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, + _BinaryOperation __binary_op, _UnaryOperation __unary_op) noexcept { - return __internal::__brick_transform_reduce(__first, __last, __init, __binary_op, __unary_op, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_transform_reduce(__first, __last, __init, __binary_op, __unary_op, + typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _Tp> -__pattern_transform_reduce(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __unary_op, _IsVector __is_vector, - /*is_parallel=*/::std::true_type) +template +_Tp +__pattern_transform_reduce(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Tp __init, _BinaryOperation __binary_op, + _UnaryOperation __unary_op) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + return __internal::__except_handler([&]() { return __par_backend::__parallel_transform_reduce( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last, + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, [__unary_op](_RandomAccessIterator __i) mutable { return __unary_op(*__i); }, __init, __binary_op, - [__unary_op, __binary_op, __is_vector](_RandomAccessIterator __i, _RandomAccessIterator __j, _Tp __init) { - return __internal::__brick_transform_reduce(__i, __j, __init, __binary_op, __unary_op, __is_vector); + [__unary_op, __binary_op](_RandomAccessIterator __i, _RandomAccessIterator __j, _Tp __init) { + return __internal::__brick_transform_reduce(__i, __j, __init, __binary_op, __unary_op, _IsVector{}); }); }); } @@ -228,31 +236,34 @@ __brick_transform_scan(_RandomAccessIterator __first, _RandomAccessIterator __la /*is_vector=*/::std::false_type()); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_transform_scan(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, +template +_OutputIterator +__pattern_transform_scan(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op, - _Inclusive, _IsVector __is_vector, /*is_parallel=*/::std::false_type) noexcept + _Inclusive) noexcept { + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + return __internal::__brick_transform_scan(__first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(), - __is_vector) + typename _Tag::__is_vector{}) .first; } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy_conditional< - _ExecutionPolicy, !::std::is_floating_point_v<_Tp>, _OutputIterator> -__pattern_transform_scan(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op, - _Inclusive, _IsVector __is_vector, /*is_parallel=*/::std::true_type) +template +::std::enable_if_t, _OutputIterator> +__pattern_transform_scan(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init, + _BinaryOperation __binary_op, _Inclusive) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + typedef typename ::std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType; return __internal::__except_handler([&]() { __par_backend::__parallel_transform_scan( - ::std::forward<_ExecutionPolicy>(__exec), __last - __first, + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __last - __first, [__first, __unary_op](_DifferenceType __i) mutable { return __unary_op(__first[__i]); }, __init, __binary_op, [__first, __unary_op, __binary_op](_DifferenceType __i, _DifferenceType __j, _Tp __init) { @@ -261,24 +272,24 @@ __pattern_transform_scan(_ExecutionPolicy&& __exec, _RandomAccessIterator __firs __unary_op, /*__is_vector*/ ::std::false_type()); }, - [__first, __unary_op, __binary_op, __result, __is_vector](_DifferenceType __i, _DifferenceType __j, - _Tp __init) { + [__first, __unary_op, __binary_op, __result](_DifferenceType __i, _DifferenceType __j, _Tp __init) { return __internal::__brick_transform_scan(__first + __i, __first + __j, __result + __i, __unary_op, - __init, __binary_op, _Inclusive(), __is_vector) + __init, __binary_op, _Inclusive(), _IsVector{}) .second; }); return __result + (__last - __first); }); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy_conditional<_ExecutionPolicy, - ::std::is_floating_point_v<_Tp>, _OutputIterator> -__pattern_transform_scan(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op, - _Inclusive, _IsVector __is_vector, /*is_parallel=*/::std::true_type) +template +::std::enable_if_t<::std::is_floating_point_v<_Tp>, _OutputIterator> +__pattern_transform_scan(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init, + _BinaryOperation __binary_op, _Inclusive) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + typedef typename ::std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType; _DifferenceType __n = __last - __first; @@ -286,12 +297,13 @@ __pattern_transform_scan(_ExecutionPolicy&& __exec, _RandomAccessIterator __firs { return __result; } + return __internal::__except_handler([&]() { __par_backend::__parallel_strict_scan( - ::std::forward<_ExecutionPolicy>(__exec), __n, __init, - [__first, __unary_op, __binary_op, __result, __is_vector](_DifferenceType __i, _DifferenceType __len) { + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __n, __init, + [__first, __unary_op, __binary_op, __result](_DifferenceType __i, _DifferenceType __len) { return __internal::__brick_transform_scan(__first + __i, __first + (__i + __len), __result + __i, - __unary_op, _Tp{}, __binary_op, _Inclusive(), __is_vector) + __unary_op, _Tp{}, __binary_op, _Inclusive(), _IsVector{}) .second; }, __binary_op, @@ -309,20 +321,22 @@ __pattern_transform_scan(_ExecutionPolicy&& __exec, _RandomAccessIterator __firs } // transform_scan without initial element -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_transform_scan(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, - _OutputIterator __result, _UnaryOperation __unary_op, _BinaryOperation __binary_op, _Inclusive, - _IsVector __is_vector, _IsParallel __is_parallel) +template +_OutputIterator +__pattern_transform_scan(_Tag __tag, _ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, + _OutputIterator __result, _UnaryOperation __unary_op, _BinaryOperation __binary_op, _Inclusive) { + static_assert(__is_host_dispatch_tag_v<_Tag>); + typedef typename ::std::iterator_traits<_ForwardIterator>::value_type _ValueType; if (__first != __last) { _ValueType __tmp = __unary_op(*__first); *__result = __tmp; - return __pattern_transform_scan(::std::forward<_ExecutionPolicy>(__exec), ++__first, __last, ++__result, - __unary_op, __tmp, __binary_op, _Inclusive(), __is_vector, __is_parallel); + + return __pattern_transform_scan(__tag, ::std::forward<_ExecutionPolicy>(__exec), ++__first, __last, ++__result, + __unary_op, __tmp, __binary_op, _Inclusive()); } else { @@ -360,36 +374,37 @@ __brick_adjacent_difference(_RandomAccessIterator1 __first, _RandomAccessIterato [&__op](_ReferenceType1 __x, _ReferenceType1 __y, _ReferenceType2 __z) { __z = __op(__x, __y); }); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _OutputIterator> -__pattern_adjacent_difference(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, - _OutputIterator __d_first, _BinaryOperation __op, _IsVector __is_vector, - /*is_parallel*/ ::std::false_type) noexcept +template +_OutputIterator +__pattern_adjacent_difference(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _OutputIterator __d_first, _BinaryOperation __op) noexcept { - return __internal::__brick_adjacent_difference(__first, __last, __d_first, __op, __is_vector); + static_assert(__is_serial_tag_v<_Tag> || __is_parallel_forward_tag_v<_Tag>); + + return __internal::__brick_adjacent_difference(__first, __last, __d_first, __op, typename _Tag::__is_vector{}); } -template -oneapi::dpl::__internal::__enable_if_host_execution_policy<_ExecutionPolicy, _RandomAccessIterator2> -__pattern_adjacent_difference(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, _RandomAccessIterator1 __last, - _RandomAccessIterator2 __d_first, _BinaryOperation __op, _IsVector __is_vector, - /*is_parallel=*/::std::true_type) +template +_RandomAccessIterator2 +__pattern_adjacent_difference(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, _RandomAccessIterator2 __d_first, _BinaryOperation __op) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + assert(__first != __last); typedef typename ::std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1; typedef typename ::std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2; *__d_first = *__first; __par_backend::__parallel_for( - ::std::forward<_ExecutionPolicy>(__exec), __first, __last - 1, - [&__op, __is_vector, __d_first, __first](_RandomAccessIterator1 __b, _RandomAccessIterator1 __e) { + __backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last - 1, + [&__op, __d_first, __first](_RandomAccessIterator1 __b, _RandomAccessIterator1 __e) { _RandomAccessIterator2 __d_b = __d_first + (__b - __first); __internal::__brick_walk3( __b, __e, __b + 1, __d_b + 1, [&__op](_ReferenceType1 __x, _ReferenceType1 __y, _ReferenceType2 __z) { __z = __op(__y, __x); }, - __is_vector); + _IsVector{}); }); return __d_first + (__last - __first); } diff --git a/include/oneapi/dpl/pstl/omp/parallel_for.h b/include/oneapi/dpl/pstl/omp/parallel_for.h index 5b6ed66453a..1a0ea24d798 100644 --- a/include/oneapi/dpl/pstl/omp/parallel_for.h +++ b/include/oneapi/dpl/pstl/omp/parallel_for.h @@ -49,7 +49,7 @@ __parallel_for_body(_Index __first, _Index __last, _Fp __f) template void -__parallel_for(_ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f) +__parallel_for(oneapi::dpl::__internal::__omp_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f) { if (omp_in_parallel()) { diff --git a/include/oneapi/dpl/pstl/omp/parallel_for_each.h b/include/oneapi/dpl/pstl/omp/parallel_for_each.h index 7877ef095ef..32410cbe927 100644 --- a/include/oneapi/dpl/pstl/omp/parallel_for_each.h +++ b/include/oneapi/dpl/pstl/omp/parallel_for_each.h @@ -44,7 +44,8 @@ __parallel_for_each_body(_ForwardIterator __first, _ForwardIterator __last, _Fp template void -__parallel_for_each(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Fp __f) +__parallel_for_each(oneapi::dpl::__internal::__omp_backend_tag, _ExecutionPolicy&&, _ForwardIterator __first, + _ForwardIterator __last, _Fp __f) { if (omp_in_parallel()) { diff --git a/include/oneapi/dpl/pstl/omp/parallel_invoke.h b/include/oneapi/dpl/pstl/omp/parallel_invoke.h index 32491ab9dfd..3503096add5 100644 --- a/include/oneapi/dpl/pstl/omp/parallel_invoke.h +++ b/include/oneapi/dpl/pstl/omp/parallel_invoke.h @@ -38,7 +38,7 @@ __parallel_invoke_body(_F1&& __f1, _F2&& __f2) template void -__parallel_invoke(_ExecutionPolicy&&, _F1&& __f1, _F2&& __f2) +__parallel_invoke(oneapi::dpl::__internal::__omp_backend_tag, _ExecutionPolicy&&, _F1&& __f1, _F2&& __f2) { if (omp_in_parallel()) { diff --git a/include/oneapi/dpl/pstl/omp/parallel_merge.h b/include/oneapi/dpl/pstl/omp/parallel_merge.h index 911d4b2643b..162ef097801 100644 --- a/include/oneapi/dpl/pstl/omp/parallel_merge.h +++ b/include/oneapi/dpl/pstl/omp/parallel_merge.h @@ -71,10 +71,9 @@ __parallel_merge_body(std::size_t __size_x, std::size_t __size_y, _RandomAccessI template void -__parallel_merge(_ExecutionPolicy&& /*__exec*/, _RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, - _RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp, - _LeafMerge __leaf_merge) - +__parallel_merge(oneapi::dpl::__internal::__omp_backend_tag, _ExecutionPolicy&& /*__exec*/, _RandomAccessIterator1 __xs, + _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye, + _RandomAccessIterator3 __zs, _Compare __comp, _LeafMerge __leaf_merge) { std::size_t __size_x = __xe - __xs; std::size_t __size_y = __ye - __ys; diff --git a/include/oneapi/dpl/pstl/omp/parallel_reduce.h b/include/oneapi/dpl/pstl/omp/parallel_reduce.h index beefe09b738..4fc62cdf3d8 100644 --- a/include/oneapi/dpl/pstl/omp/parallel_reduce.h +++ b/include/oneapi/dpl/pstl/omp/parallel_reduce.h @@ -52,8 +52,8 @@ __parallel_reduce_body(_RandomAccessIterator __first, _RandomAccessIterator __la template _Value -__parallel_reduce(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Value __identity, - _RealBody __real_body, _Reduction __reduction) +__parallel_reduce(oneapi::dpl::__internal::__omp_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Value __identity, _RealBody __real_body, _Reduction __reduction) { // We don't create a nested parallel region in an existing parallel region: // just create tasks. diff --git a/include/oneapi/dpl/pstl/omp/parallel_scan.h b/include/oneapi/dpl/pstl/omp/parallel_scan.h index 29c6c77be54..c3bc022cb2e 100644 --- a/include/oneapi/dpl/pstl/omp/parallel_scan.h +++ b/include/oneapi/dpl/pstl/omp/parallel_scan.h @@ -82,13 +82,14 @@ __downsweep(_Index __i, _Index __m, _Index __tilesize, _Tp* __r, _Index __lastsi template void -__parallel_strict_scan_body(_Index __n, _Tp __initial, _Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex) +__parallel_strict_scan_body(_ExecutionPolicy&& __exec, _Index __n, _Tp __initial, _Rp __reduce, _Cp __combine, + _Sp __scan, _Ap __apex) { _Index __p = omp_get_num_threads(); const _Index __slack = 4; _Index __tilesize = (__n - 1) / (__slack * __p) + 1; _Index __m = (__n - 1) / __tilesize; - __buffer<_ExecutionPolicy, _Tp> __buf(__m + 1); + __buffer<_ExecutionPolicy, _Tp> __buf(::std::forward<_ExecutionPolicy>(__exec), __m + 1); _Tp* __r = __buf.get(); oneapi::dpl::__omp_backend::__upsweep(_Index(0), _Index(__m + 1), __tilesize, __r, __n - __m * __tilesize, __reduce, @@ -108,8 +109,8 @@ __parallel_strict_scan_body(_Index __n, _Tp __initial, _Rp __reduce, _Cp __combi template void -__parallel_strict_scan(_ExecutionPolicy&&, _Index __n, _Tp __initial, _Rp __reduce, _Cp __combine, _Sp __scan, - _Ap __apex) +__parallel_strict_scan(oneapi::dpl::__internal::__omp_backend_tag, _ExecutionPolicy&& __exec, _Index __n, _Tp __initial, + _Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex) { if (__n <= __default_chunk_size) { @@ -128,16 +129,16 @@ __parallel_strict_scan(_ExecutionPolicy&&, _Index __n, _Tp __initial, _Rp __redu if (omp_in_parallel()) { - oneapi::dpl::__omp_backend::__parallel_strict_scan_body<_ExecutionPolicy>(__n, __initial, __reduce, __combine, - __scan, __apex); + oneapi::dpl::__omp_backend::__parallel_strict_scan_body(::std::forward<_ExecutionPolicy>(__exec), __n, + __initial, __reduce, __combine, __scan, __apex); } else { _PSTL_PRAGMA(omp parallel) _PSTL_PRAGMA(omp single nowait) { - oneapi::dpl::__omp_backend::__parallel_strict_scan_body<_ExecutionPolicy>(__n, __initial, __reduce, - __combine, __scan, __apex); + oneapi::dpl::__omp_backend::__parallel_strict_scan_body(::std::forward<_ExecutionPolicy>(__exec), __n, + __initial, __reduce, __combine, __scan, __apex); } } } diff --git a/include/oneapi/dpl/pstl/omp/parallel_stable_sort.h b/include/oneapi/dpl/pstl/omp/parallel_stable_sort.h index 14aa7b7bf04..4633a3fcade 100644 --- a/include/oneapi/dpl/pstl/omp/parallel_stable_sort.h +++ b/include/oneapi/dpl/pstl/omp/parallel_stable_sort.h @@ -123,8 +123,9 @@ __parallel_stable_sort_body(_RandomAccessIterator __xs, _RandomAccessIterator __ template void -__parallel_stable_sort(_ExecutionPolicy&& /*__exec*/, _RandomAccessIterator __xs, _RandomAccessIterator __xe, - _Compare __comp, _LeafSort __leaf_sort, std::size_t __nsort = 0) +__parallel_stable_sort(oneapi::dpl::__internal::__omp_backend_tag, _ExecutionPolicy&& /*__exec*/, + _RandomAccessIterator __xs, _RandomAccessIterator __xe, _Compare __comp, _LeafSort __leaf_sort, + std::size_t __nsort = 0) { auto __count = static_cast(__xe - __xs); if (__count <= __default_chunk_size || __nsort < __count) diff --git a/include/oneapi/dpl/pstl/omp/parallel_transform_reduce.h b/include/oneapi/dpl/pstl/omp/parallel_transform_reduce.h index d94e5fd36e9..2c6cf06577b 100644 --- a/include/oneapi/dpl/pstl/omp/parallel_transform_reduce.h +++ b/include/oneapi/dpl/pstl/omp/parallel_transform_reduce.h @@ -86,8 +86,9 @@ __transform_reduce_body(_RandomAccessIterator __first, _RandomAccessIterator __l template _Value -__parallel_transform_reduce(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, - _UnaryOp __unary_op, _Value __init, _Combiner __combiner, _Reduction __reduction) +__parallel_transform_reduce(oneapi::dpl::__internal::__omp_backend_tag, _ExecutionPolicy&&, + _RandomAccessIterator __first, _RandomAccessIterator __last, _UnaryOp __unary_op, + _Value __init, _Combiner __combiner, _Reduction __reduction) { _Value __result = __init; if (omp_in_parallel()) diff --git a/include/oneapi/dpl/pstl/omp/parallel_transform_scan.h b/include/oneapi/dpl/pstl/omp/parallel_transform_scan.h index 98262635d1e..35c28b4330c 100644 --- a/include/oneapi/dpl/pstl/omp/parallel_transform_scan.h +++ b/include/oneapi/dpl/pstl/omp/parallel_transform_scan.h @@ -27,8 +27,8 @@ namespace __omp_backend template _Tp -__parallel_transform_scan(_ExecutionPolicy&&, _Index __n, _Up /* __u */, _Tp __init, _Cp /* __combine */, - _Rp /* __brick_reduce */, _Sp __scan) +__parallel_transform_scan(oneapi::dpl::__internal::__omp_backend_tag, _ExecutionPolicy&&, _Index __n, _Up /* __u */, + _Tp __init, _Cp /* __combine */, _Rp /* __brick_reduce */, _Sp __scan) { // TODO: parallelize this function. return __scan(_Index(0), __n, __init); diff --git a/include/oneapi/dpl/pstl/omp/util.h b/include/oneapi/dpl/pstl/omp/util.h index bcbfecc23e4..e7c4e3cbc40 100644 --- a/include/oneapi/dpl/pstl/omp/util.h +++ b/include/oneapi/dpl/pstl/omp/util.h @@ -48,7 +48,7 @@ namespace __omp_backend // use to cancel execution //------------------------------------------------------------------------ inline void -__cancel_execution() +__cancel_execution(oneapi::dpl::__internal::__omp_backend_tag) { // TODO: Figure out how to make cancellation work. } @@ -68,9 +68,10 @@ class __buffer_impl operator=(const __buffer_impl&) = delete; public: - static_assert(::std::is_same_v<_ExecutionPolicy, ::std::decay_t<_ExecutionPolicy>>); - - __buffer_impl(std::size_t __n) : __allocator_(), __ptr_(__allocator_.allocate(__n)), __buf_size_(__n) {} + __buffer_impl(_ExecutionPolicy /*__exec*/, std::size_t __n) + : __allocator_(), __ptr_(__allocator_.allocate(__n)), __buf_size_(__n) + { + } operator bool() const { return __ptr_ != nullptr; } diff --git a/include/oneapi/dpl/pstl/parallel_backend.h b/include/oneapi/dpl/pstl/parallel_backend.h index 1e78d1f635b..b243e8fb492 100644 --- a/include/oneapi/dpl/pstl/parallel_backend.h +++ b/include/oneapi/dpl/pstl/parallel_backend.h @@ -18,14 +18,14 @@ // Select a parallel backend #if ONEDPL_USE_TBB_BACKEND || (!defined(ONEDPL_USE_TBB_BACKEND) && !ONEDPL_USE_OPENMP_BACKEND && _ONEDPL_TBB_AVAILABLE) -# include "parallel_backend_tbb.h" # define _ONEDPL_PAR_BACKEND_TBB 1 +# include "parallel_backend_tbb.h" #elif ONEDPL_USE_OPENMP_BACKEND || (!defined(ONEDPL_USE_OPENMP_BACKEND) && _ONEDPL_OPENMP_AVAILABLE) -# include "parallel_backend_omp.h" # define _ONEDPL_PAR_BACKEND_OPENMP 1 +# include "parallel_backend_omp.h" #else -# include "parallel_backend_serial.h" # define _ONEDPL_PAR_BACKEND_SERIAL 1 +# include "parallel_backend_serial.h" #endif #if _ONEDPL_BACKEND_SYCL diff --git a/include/oneapi/dpl/pstl/parallel_backend_serial.h b/include/oneapi/dpl/pstl/parallel_backend_serial.h index a2dd6468a34..edd6652d359 100644 --- a/include/oneapi/dpl/pstl/parallel_backend_serial.h +++ b/include/oneapi/dpl/pstl/parallel_backend_serial.h @@ -43,9 +43,10 @@ class __buffer_impl operator=(const __buffer_impl&) = delete; public: - static_assert(::std::is_same_v<_ExecutionPolicy, ::std::decay_t<_ExecutionPolicy>>); - - __buffer_impl(::std::size_t __n) : __allocator_(), __ptr_(__allocator_.allocate(__n)), __buf_size_(__n) {} + __buffer_impl(_ExecutionPolicy /*__exec*/, ::std::size_t __n) + : __allocator_(), __ptr_(__allocator_.allocate(__n)), __buf_size_(__n) + { + } operator bool() const { return __ptr_ != nullptr; } _Tp* @@ -60,21 +61,22 @@ template using __buffer = __buffer_impl<::std::decay_t<_ExecutionPolicy>, _Tp>; inline void -__cancel_execution() +__cancel_execution(oneapi::dpl::__internal::__serial_backend_tag) { } template void -__parallel_for(_ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f) +__parallel_for(oneapi::dpl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last, + _Fp __f) { __f(__first, __last); } template _Value -__parallel_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, const _Value& __identity, - const _RealBody& __real_body, const _Reduction&) +__parallel_reduce(oneapi::dpl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last, + const _Value& __identity, const _RealBody& __real_body, const _Reduction&) { if (__first == __last) { @@ -88,16 +90,16 @@ __parallel_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, const _Valu template _Tp -__parallel_transform_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp, - _Reduce __reduce) +__parallel_transform_reduce(oneapi::dpl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __first, + _Index __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduce __reduce) { return __reduce(__first, __last, __init); } template void -__parallel_strict_scan(_ExecutionPolicy&&, _Index __n, _Tp __initial, _Rp __reduce, _Cp __combine, _Sp __scan, - _Ap __apex) +__parallel_strict_scan(oneapi::dpl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __n, _Tp __initial, + _Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex) { _Tp __sum = __initial; if (__n) @@ -109,15 +111,16 @@ __parallel_strict_scan(_ExecutionPolicy&&, _Index __n, _Tp __initial, _Rp __redu template _Tp -__parallel_transform_scan(_ExecutionPolicy&&, _Index __n, _UnaryOp, _Tp __init, _BinaryOp, _Reduce, _Scan __scan) +__parallel_transform_scan(oneapi::dpl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __n, _UnaryOp, + _Tp __init, _BinaryOp, _Reduce, _Scan __scan) { return __scan(_Index(0), __n, __init); } template void -__parallel_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, - _LeafSort __leaf_sort, ::std::size_t = 0) +__parallel_stable_sort(oneapi::dpl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort, ::std::size_t = 0) { __leaf_sort(__first, __last, __comp); } @@ -125,16 +128,16 @@ __parallel_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _Rando template void -__parallel_merge(_ExecutionPolicy&&, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _RandomAccessIterator3 __outit, - _Compare __comp, _LeafMerge __leaf_merge) +__parallel_merge(oneapi::dpl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, + _RandomAccessIterator3 __outit, _Compare __comp, _LeafMerge __leaf_merge) { __leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp); } template void -__parallel_invoke(_ExecutionPolicy&&, _F1&& __f1, _F2&& __f2) +__parallel_invoke(oneapi::dpl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _F1&& __f1, _F2&& __f2) { ::std::forward<_F1>(__f1)(); ::std::forward<_F2>(__f2)(); @@ -142,7 +145,8 @@ __parallel_invoke(_ExecutionPolicy&&, _F1&& __f1, _F2&& __f2) template void -__parallel_for_each(_ExecutionPolicy&&, _ForwardIterator __begin, _ForwardIterator __end, _Fp __f) +__parallel_for_each(oneapi::dpl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _ForwardIterator __begin, + _ForwardIterator __end, _Fp __f) { for (auto __iter = __begin; __iter != __end; ++__iter) __f(*__iter); diff --git a/include/oneapi/dpl/pstl/parallel_backend_tbb.h b/include/oneapi/dpl/pstl/parallel_backend_tbb.h index 556e305e1c7..2ddfa61007a 100644 --- a/include/oneapi/dpl/pstl/parallel_backend_tbb.h +++ b/include/oneapi/dpl/pstl/parallel_backend_tbb.h @@ -23,6 +23,7 @@ #include #include "parallel_backend_utils.h" +#include "execution_impl.h" // Bring in minimal required subset of Intel(R) Threading Building Blocks (Intel(R) TBB) #include @@ -64,10 +65,11 @@ class __buffer_impl operator=(const __buffer_impl&) = delete; public: - static_assert(::std::is_same_v<_ExecutionPolicy, ::std::decay_t<_ExecutionPolicy>>); - //! Try to obtain buffer of given size to store objects of _Tp type - __buffer_impl(const ::std::size_t __n) : _M_allocator(), _M_ptr(_M_allocator.allocate(__n)), _M_buf_size(__n) {} + __buffer_impl(_ExecutionPolicy /*__exec*/, const ::std::size_t __n) + : _M_allocator(), _M_ptr(_M_allocator.allocate(__n)), _M_buf_size(__n) + { + } //! True if buffer was successfully obtained, zero otherwise. operator bool() const { return _M_ptr != nullptr; } //! Return pointer to buffer, or nullptr if buffer could not be obtained. @@ -85,7 +87,7 @@ using __buffer = __buffer_impl<::std::decay_t<_ExecutionPolicy>, _Tp>; // Wrapper for tbb::task inline void -__cancel_execution() +__cancel_execution(oneapi::dpl::__internal::__tbb_backend_tag) { #if TBB_INTERFACE_VERSION <= 12000 tbb::task::self().group()->cancel_group_execution(); @@ -118,7 +120,7 @@ class __parallel_for_body // wrapper over tbb::parallel_for template void -__parallel_for(_ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f) +__parallel_for(oneapi::dpl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f) { tbb::this_task_arena::isolate([=]() { tbb::parallel_for(tbb::blocked_range<_Index>(__first, __last), __parallel_for_body<_Index, _Fp>(__f)); @@ -129,8 +131,8 @@ __parallel_for(_ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f) // wrapper over tbb::parallel_reduce template _Value -__parallel_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, const _Value& __identity, - const _RealBody& __real_body, const _Reduction& __reduction) +__parallel_reduce(oneapi::dpl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last, + const _Value& __identity, const _RealBody& __real_body, const _Reduction& __reduction) { return tbb::this_task_arena::isolate([__first, __last, &__identity, &__real_body, &__reduction]() -> _Value { return tbb::parallel_reduce( @@ -210,8 +212,8 @@ struct __par_trans_red_body template _Tp -__parallel_transform_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, _Up __u, _Tp __init, _Cp __combine, - _Rp __brick_reduce) +__parallel_transform_reduce(oneapi::dpl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __first, + _Index __last, _Up __u, _Tp __init, _Cp __combine, _Rp __brick_reduce) { __tbb_backend::__par_trans_red_body<_Index, _Up, _Tp, _Cp, _Rp> __body(__u, __init, __combine, __brick_reduce); // The grain size of 3 is used in order to provide minimum 2 elements for each body @@ -379,8 +381,8 @@ __downsweep(_Index __i, _Index __m, _Index __tilesize, _Tp* __r, _Index __lastsi // T must have a trivial constructor and destructor. template void -__parallel_strict_scan(_ExecutionPolicy&&, _Index __n, _Tp __initial, _Rp __reduce, _Cp __combine, _Sp __scan, - _Ap __apex) +__parallel_strict_scan(oneapi::dpl::__internal::__tbb_backend_tag, _ExecutionPolicy&& __exec, _Index __n, _Tp __initial, + _Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex) { tbb::this_task_arena::isolate([=, &__combine]() { if (__n > 1) @@ -389,7 +391,7 @@ __parallel_strict_scan(_ExecutionPolicy&&, _Index __n, _Tp __initial, _Rp __redu const _Index __slack = 4; _Index __tilesize = (__n - 1) / (__slack * __p) + 1; _Index __m = (__n - 1) / __tilesize; - __tbb_backend::__buffer<_ExecutionPolicy, _Tp> __buf(__m + 1); + __tbb_backend::__buffer<_ExecutionPolicy, _Tp> __buf(__exec, __m + 1); _Tp* __r = __buf.get(); __tbb_backend::__upsweep(_Index(0), _Index(__m + 1), __tilesize, __r, __n - __m * __tilesize, __reduce, __combine); @@ -419,8 +421,8 @@ __parallel_strict_scan(_ExecutionPolicy&&, _Index __n, _Tp __initial, _Rp __redu template _Tp -__parallel_transform_scan(_ExecutionPolicy&&, _Index __n, _Up __u, _Tp __init, _Cp __combine, _Rp __brick_reduce, - _Sp __scan) +__parallel_transform_scan(oneapi::dpl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __n, _Up __u, + _Tp __init, _Cp __combine, _Rp __brick_reduce, _Sp __scan) { __trans_scan_body<_Index, _Up, _Tp, _Cp, _Rp, _Sp> __body(__u, __init, __combine, __brick_reduce, __scan); auto __range = tbb::blocked_range<_Index>(0, __n); @@ -1182,8 +1184,9 @@ __stable_sort_func<_RandomAccessIterator1, _RandomAccessIterator2, _Compare, _Le template void -__parallel_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __xs, _RandomAccessIterator __xe, _Compare __comp, - _LeafSort __leaf_sort, ::std::size_t __nsort) +__parallel_stable_sort(oneapi::dpl::__internal::__tbb_backend_tag, _ExecutionPolicy&& __exec, + _RandomAccessIterator __xs, _RandomAccessIterator __xe, _Compare __comp, _LeafSort __leaf_sort, + ::std::size_t __nsort) { tbb::this_task_arena::isolate([=, &__nsort]() { //sorting based on task tree and parallel merge @@ -1194,7 +1197,7 @@ __parallel_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __xs, _RandomAc const _DifferenceType __sort_cut_off = _ONEDPL_STABLE_SORT_CUT_OFF; if (__n > __sort_cut_off) { - __tbb_backend::__buffer<_ExecutionPolicy, _ValueType> __buf(__n); + __tbb_backend::__buffer<_ExecutionPolicy, _ValueType> __buf(__exec, __n); __root_task<__stable_sort_func<_RandomAccessIterator, _ValueType*, _Compare, _LeafSort>> __root{ __xs, __xe, __buf.get(), true, __comp, __leaf_sort, __nsort, __xs, __buf.get()}; __task::spawn_root_and_wait(__root); @@ -1274,9 +1277,9 @@ operator()(__task* __self) template void -__parallel_merge(_ExecutionPolicy&&, _RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, - _RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp, - _LeafMerge __leaf_merge) +__parallel_merge(oneapi::dpl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator1 __xs, + _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye, + _RandomAccessIterator3 __zs, _Compare __comp, _LeafMerge __leaf_merge) { typedef typename ::std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType1; typedef typename ::std::iterator_traits<_RandomAccessIterator2>::difference_type _DifferenceType2; @@ -1303,9 +1306,10 @@ __parallel_merge(_ExecutionPolicy&&, _RandomAccessIterator1 __xs, _RandomAccessI //------------------------------------------------------------------------ // parallel_invoke //------------------------------------------------------------------------ + template void -__parallel_invoke(_ExecutionPolicy&&, _F1&& __f1, _F2&& __f2) +__parallel_invoke(oneapi::dpl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _F1&& __f1, _F2&& __f2) { //TODO: a version of tbb::this_task_arena::isolate with variadic arguments pack should be added in the future tbb::this_task_arena::isolate( @@ -1315,9 +1319,11 @@ __parallel_invoke(_ExecutionPolicy&&, _F1&& __f1, _F2&& __f2) //------------------------------------------------------------------------ // parallel_for_each //------------------------------------------------------------------------ + template void -__parallel_for_each(_ExecutionPolicy&&, _ForwardIterator __begin, _ForwardIterator __end, _Fp __f) +__parallel_for_each(oneapi::dpl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _ForwardIterator __begin, + _ForwardIterator __end, _Fp __f) { tbb::this_task_arena::isolate([&]() { tbb::parallel_for_each(__begin, __end, __f); }); } diff --git a/include/oneapi/dpl/pstl/parallel_impl.h b/include/oneapi/dpl/pstl/parallel_impl.h index a2d7d20e562..66d9d8d1741 100644 --- a/include/oneapi/dpl/pstl/parallel_impl.h +++ b/include/oneapi/dpl/pstl/parallel_impl.h @@ -32,10 +32,13 @@ namespace __internal //----------------------------------------------------------------------- /** Return extremum value returned by brick f[i,j) for subranges [i,j) of [first,last) Each f[i,j) must return a value in [i,j). */ -template +template _Index -__parallel_find(_ExecutionPolicy&& __exec, _Index __first, _Index __last, _Brick __f, _IsFirst) +__parallel_find(__parallel_tag<_IsVector>, _ExecutionPolicy&& __exec, _Index __first, _Index __last, _Brick __f, + _IsFirst) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + typedef typename ::std::iterator_traits<_Index>::difference_type _DifferenceType; const _DifferenceType __n = __last - __first; _DifferenceType __initial_dist = _IsFirst::value ? __n : -1; @@ -44,7 +47,7 @@ __parallel_find(_ExecutionPolicy&& __exec, _Index __first, _Index __last, _Brick ::std::atomic<_DifferenceType> __extremum(__initial_dist); // TODO: find out what is better here: parallel_for or parallel_reduce - __par_backend::__parallel_for(::std::forward<_ExecutionPolicy>(__exec), __first, __last, + __par_backend::__parallel_for(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, [__comp, __f, __first, &__extremum](_Index __i, _Index __j) { // See "Reducing Contention Through Priority Updates", PPoPP '13, for discussion of // why using a shared variable scales fairly well in this situation. @@ -70,17 +73,19 @@ __parallel_find(_ExecutionPolicy&& __exec, _Index __first, _Index __last, _Brick // parallel_or //------------------------------------------------------------------------ //! Return true if brick f[i,j) returns true for some subrange [i,j) of [first,last) -template +template bool -__parallel_or(_ExecutionPolicy&& __exec, _Index __first, _Index __last, _Brick __f) +__parallel_or(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _Index __first, _Index __last, _Brick __f) { + using __backend_tag = typename __parallel_tag<_IsVector>::__backend_tag; + ::std::atomic __found(false); - __par_backend::__parallel_for(::std::forward<_ExecutionPolicy>(__exec), __first, __last, + __par_backend::__parallel_for(__backend_tag{}, ::std::forward<_ExecutionPolicy>(__exec), __first, __last, [__f, &__found](_Index __i, _Index __j) { if (!__found.load(::std::memory_order_relaxed) && __f(__i, __j)) { __found.store(true, ::std::memory_order_relaxed); - __par_backend::__cancel_execution(); + __par_backend::__cancel_execution(__backend_tag{}); } }); return __found; diff --git a/test/parallel_api/experimental/for_loop.pass.cpp b/test/parallel_api/experimental/for_loop.pass.cpp index 8c59ffe1afd..725d2bc9747 100644 --- a/test/parallel_api/experimental/for_loop.pass.cpp +++ b/test/parallel_api/experimental/for_loop.pass.cpp @@ -296,8 +296,9 @@ test_for_loop() Sequence in_out(n, Gen()); Sequence expected = in_out; - invoke_on_all_policies<>()(test_for_loop_impl(), in_out.begin(), in_out.end(), expected.begin(), expected.end(), - in_out.size()); + // for_loop staff is implemented for the host policies only + invoke_on_all_host_policies()(test_for_loop_impl(), in_out.begin(), in_out.end(), expected.begin(), + expected.end(), in_out.size()); } } @@ -313,8 +314,9 @@ test_for_loop_strided() ::std::vector strides = {1, 2, 10, n > 1 ? n - 1 : 1, n > 0 ? n : 1, n + 1}; for (size_t stride : strides) { - invoke_on_all_policies<>()(test_for_loop_strided_impl(), in_out.begin(), in_out.end(), expected.begin(), - expected.end(), in_out.size(), stride); + // for_loop staff is implemented for the host policies only + invoke_on_all_host_policies()(test_for_loop_strided_impl(), in_out.begin(), in_out.end(), expected.begin(), + expected.end(), in_out.size(), stride); } } } diff --git a/test/parallel_api/experimental/for_loop_induction.pass.cpp b/test/parallel_api/experimental/for_loop_induction.pass.cpp index 505ceb54e1e..e01569c58a1 100644 --- a/test/parallel_api/experimental/for_loop_induction.pass.cpp +++ b/test/parallel_api/experimental/for_loop_induction.pass.cpp @@ -153,8 +153,10 @@ test() { Sequence in_out(n, [](long int k) { return T(k % 5 != 1 ? 3 * k - 7 : 0); }); Sequence expected = in_out; - invoke_on_all_policies<>()(test_body(), in_out.begin(), in_out.end(), expected.begin(), expected.end(), - in_out.size()); + + // for_loop staff is implemented for the host policies only + invoke_on_all_host_policies()(test_body(), in_out.begin(), in_out.end(), expected.begin(), expected.end(), + in_out.size()); } } diff --git a/test/parallel_api/experimental/for_loop_reduction.pass.cpp b/test/parallel_api/experimental/for_loop_reduction.pass.cpp index cfd918ff2bd..7f6b2b9e7f5 100644 --- a/test/parallel_api/experimental/for_loop_reduction.pass.cpp +++ b/test/parallel_api/experimental/for_loop_reduction.pass.cpp @@ -77,8 +77,10 @@ test() { Sequence in_out(n, [](long int k) { return T(k % 5 != 1 ? 3 * k - 7 : 0); }); Sequence expected = in_out; - invoke_on_all_policies<>()(test_body(), in_out.begin(), in_out.end(), expected.begin(), expected.end(), - in_out.size()); + + // for_loop staff is implemented for the host policies only + invoke_on_all_host_policies()(test_body(), in_out.begin(), in_out.end(), expected.begin(), expected.end(), + in_out.size()); } } @@ -176,10 +178,12 @@ test_predefined(::std::initializer_list init_list) // Just arbitrary numbers Sequence in_out = init_list; Sequence expected = in_out; - invoke_on_all_policies<>()(test_body_predefined(), in_out.begin(), in_out.end(), expected.begin(), expected.end(), - in_out.size()); - invoke_on_all_policies<>()(test_body_predefined_bits(), in_out.begin(), in_out.end(), expected.begin(), - expected.end(), in_out.size()); + + // for_loop staff is implemented for the host policies only + invoke_on_all_host_policies()(test_body_predefined(), in_out.begin(), in_out.end(), expected.begin(), + expected.end(), in_out.size()); + invoke_on_all_host_policies()(test_body_predefined_bits(), in_out.begin(), in_out.end(), expected.begin(), + expected.end(), in_out.size()); } void