diff --git a/include/oneapi/dpl/pstl/algorithm_ranges_impl.h b/include/oneapi/dpl/pstl/algorithm_ranges_impl.h index 67ce904a72a..d899e51d062 100644 --- a/include/oneapi/dpl/pstl/algorithm_ranges_impl.h +++ b/include/oneapi/dpl/pstl/algorithm_ranges_impl.h @@ -70,7 +70,7 @@ __pattern_transform(_Tag __tag, _ExecutionPolicy&& __exec, _InRange&& __in_r, _O _Proj __proj) { static_assert(__is_parallel_tag_v<_Tag> || typename _Tag::__is_vector{}); - assert(std::ranges::size(__in_r) <= std::ranges::size(__out_r)); + assert(std::ranges::size(__in_r) <= std::ranges::size(__out_r)); // for debug purposes only auto __unary_op = [__op, __proj](auto&& __val) { return std::invoke(__op, std::invoke(__proj, std::forward(__val)));}; @@ -254,6 +254,227 @@ __pattern_search_n(__serial_tag, _ExecutionPolicy&& return std::ranges::search_n(std::forward<_R>(__r), __count, __value, __pred, __proj); } +//--------------------------------------------------------------------------------------------------------------------- +// pattern_count_if +//--------------------------------------------------------------------------------------------------------------------- + +template +std::ranges::range_difference_t<_R> +__pattern_count_if(_Tag __tag, _ExecutionPolicy&& __exec, _R&& __r, _Pred __pred, _Proj __proj) +{ + static_assert(__is_parallel_tag_v<_Tag> || typename _Tag::__is_vector{}); + + auto __pred_1 = [__pred, __proj](auto&& __val) { return std::invoke(__pred, std::invoke(__proj, + std::forward(__val)));}; + return oneapi::dpl::__internal::__pattern_count(__tag, std::forward<_ExecutionPolicy>(__exec), + std::ranges::begin(__r), std::ranges::begin(__r) + std::ranges::size(__r), __pred_1); +} + +template +std::ranges::range_difference_t<_R> +__pattern_count_if(__serial_tag, _ExecutionPolicy&& __exec, _R&& __r, _Pred __pred, _Proj __proj) +{ + return std::ranges::count_if(std::forward<_R>(__r), __pred, __proj); +} + +//--------------------------------------------------------------------------------------------------------------------- +// pattern_equal +//--------------------------------------------------------------------------------------------------------------------- +template +bool +__pattern_equal(_Tag __tag, _ExecutionPolicy&& __exec, _R1&& __r1, _R2&& __r2, _Pred __pred, + _Proj1 __proj1, _Proj2 __proj2) +{ + static_assert(__is_parallel_tag_v<_Tag> || typename _Tag::__is_vector{}); + + auto __pred_2 = [__pred, __proj1, __proj2](auto&& __val1, auto&& __val2) + { return std::invoke(__pred, std::invoke(__proj1, std::forward(__val1)), + std::invoke(__proj2, std::forward(__val2)));}; + + return oneapi::dpl::__internal::__pattern_equal(__tag, std::forward<_ExecutionPolicy>(__exec), + std::ranges::begin(__r1), std::ranges::begin(__r1) + std::ranges::size(__r1), std::ranges::begin(__r2), + std::ranges::begin(__r2) + std::ranges::size(__r2), __pred_2); +} + +template +bool +__pattern_equal(__serial_tag, _ExecutionPolicy&& __exec, _R1&& __r1, _R2&& __r2, _Pred __pred, _Proj1 __proj1, _Proj2 __proj2) +{ + return std::ranges::equal(std::forward<_R1>(__r1), std::forward<_R2>(__r2), __pred, __proj1, __proj2); +} + +//--------------------------------------------------------------------------------------------------------------------- +// pattern_is_sorted +//--------------------------------------------------------------------------------------------------------------------- + +template +bool +__pattern_is_sorted(_Tag __tag, _ExecutionPolicy&& __exec, _R&& __r, _Comp __comp, _Proj __proj) +{ + static_assert(__is_parallel_tag_v<_Tag> || typename _Tag::__is_vector{}); + + auto __pred_2 = [__comp, __proj](auto&& __val1, auto&& __val2) { return std::invoke(__comp, std::invoke(__proj, + std::forward(__val1)), std::invoke(__proj, std::forward(__val2)));}; + + return oneapi::dpl::__internal::__pattern_adjacent_find(__tag, std::forward<_ExecutionPolicy>(__exec), + std::ranges::begin(__r), std::ranges::begin(__r) + std::ranges::size(__r), + oneapi::dpl::__internal::__reorder_pred(__pred_2), oneapi::dpl::__internal::__or_semantic()) == __r.end(); +} + +template +bool +__pattern_is_sorted(__serial_tag, _ExecutionPolicy&& __exec, _R&& __r, _Comp __comp, _Proj __proj) +{ + return std::ranges::is_sorted(std::forward<_R>(__r), __comp, __proj); +} + +//--------------------------------------------------------------------------------------------------------------------- +// pattern_sort +//--------------------------------------------------------------------------------------------------------------------- + +template +auto +__pattern_sort_ranges(_Tag __tag, _ExecutionPolicy&& __exec, _R&& __r, _Comp __comp, _Proj __proj) +{ + static_assert(__is_parallel_tag_v<_Tag> || typename _Tag::__is_vector{}); + + auto __comp_2 = [__comp, __proj](auto&& __val1, auto&& __val2) { return std::invoke(__comp, std::invoke(__proj, + std::forward(__val1)), std::invoke(__proj, std::forward(__val2)));}; + // Call stable_sort pattern since __pattern_sort_ranges is shared between sort and stable_sort + // TODO: add a separate pattern for ranges::sort for better performance + oneapi::dpl::__internal::__pattern_stable_sort(__tag, std::forward<_ExecutionPolicy>(__exec), + std::ranges::begin(__r), std::ranges::begin(__r) + std::ranges::size(__r), __comp_2); + + return std::ranges::borrowed_iterator_t<_R>(std::ranges::begin(__r) + std::ranges::size(__r)); +} + +template +auto +__pattern_sort_ranges(__serial_tag, _ExecutionPolicy&& __exec, _R&& __r, _Comp __comp, _Proj __proj) +{ + return std::ranges::stable_sort(std::forward<_R>(__r), __comp, __proj); +} + +//--------------------------------------------------------------------------------------------------------------------- +// pattern_min_element +//--------------------------------------------------------------------------------------------------------------------- + +template +auto +__pattern_min_element(_Tag __tag, _ExecutionPolicy&& __exec, _R&& __r, _Comp __comp, _Proj __proj) +{ + static_assert(__is_parallel_tag_v<_Tag> || typename _Tag::__is_vector{}); + + auto __comp_2 = [__comp, __proj](auto&& __val1, auto&& __val2) { return std::invoke(__comp, std::invoke(__proj, + std::forward(__val1)), std::invoke(__proj, std::forward(__val2)));}; + + auto __res = oneapi::dpl::__internal::__pattern_min_element(__tag, std::forward<_ExecutionPolicy>(__exec), std::ranges::begin(__r), + std::ranges::begin(__r) + std::ranges::size(__r), __comp_2); + + return std::ranges::borrowed_iterator_t<_R>(__res); +} + +template +auto +__pattern_min_element(__serial_tag, _ExecutionPolicy&& __exec, _R&& __r, _Comp __comp, _Proj __proj) +{ + return std::ranges::min_element(std::forward<_R>(__r), __comp, __proj); +} + +//--------------------------------------------------------------------------------------------------------------------- +// pattern_copy +//--------------------------------------------------------------------------------------------------------------------- + +template +void +__pattern_copy(_Tag __tag, _ExecutionPolicy&& __exec, _InRange&& __in_r, _OutRange&& __out_r) +{ + static_assert(__is_parallel_tag_v<_Tag> || typename _Tag::__is_vector{}); + + assert(std::ranges::size(__in_r) <= std::ranges::size(__out_r)); // for debug purposes only + + oneapi::dpl::__internal::__pattern_walk2_brick(__tag, std::forward<_ExecutionPolicy>(__exec), + std::ranges::begin(__in_r), std::ranges::begin(__in_r) + std::ranges::size(__in_r), std::ranges::begin(__out_r), + oneapi::dpl::__internal::__brick_copy{}); +} + +template +void +__pattern_copy(__serial_tag, _ExecutionPolicy&& __exec, _InRange&& __in_r, _OutRange&& __out_r) +{ + std::ranges::copy(std::forward<_InRange>(__in_r), std::ranges::begin(__out_r)); +} +//--------------------------------------------------------------------------------------------------------------------- +// pattern_copy_if +//--------------------------------------------------------------------------------------------------------------------- + +template +auto +__pattern_copy_if_ranges(_Tag __tag, _ExecutionPolicy&& __exec, _InRange&& __in_r, _OutRange&& __out_r, _Pred __pred, _Proj __proj) +{ + static_assert(__is_parallel_tag_v<_Tag> || typename _Tag::__is_vector{}); + + auto __pred_1 = [__pred, __proj](auto&& __val) { return std::invoke(__pred, std::invoke(__proj, + std::forward(__val)));}; + + auto __res_idx = oneapi::dpl::__internal::__pattern_copy_if(__tag, std::forward<_ExecutionPolicy>(__exec), + std::ranges::begin(__in_r), std::ranges::begin(__in_r) + std::ranges::size(__in_r), + std::ranges::begin(__out_r), __pred_1) - std::ranges::begin(__out_r); + + using __return_type = std::ranges::copy_if_result, + std::ranges::borrowed_iterator_t<_OutRange>>; + + return __return_type{std::ranges::begin(__in_r) + std::ranges::size(__in_r), std::ranges::begin(__out_r) + __res_idx}; +} + +template +auto +__pattern_copy_if_ranges(__serial_tag, _ExecutionPolicy&& __exec, _InRange&& __in_r, _OutRange&& __out_r, + _Pred __pred, _Proj __proj) +{ + return std::ranges::copy_if(std::forward<_InRange>(__in_r), std::ranges::begin(__out_r), __pred, __proj); +} + +//--------------------------------------------------------------------------------------------------------------------- +// pattern_merge +//--------------------------------------------------------------------------------------------------------------------- + +template +auto +__pattern_merge(_Tag __tag, _ExecutionPolicy&& __exec, _R1&& __r1, _R2&& __r2, _OutRange&& __out_r, _Comp __comp, + _Proj1 __proj1, _Proj2 __proj2) +{ + static_assert(__is_parallel_tag_v<_Tag> || typename _Tag::__is_vector{}); + assert(std::ranges::size(__r1) + std::ranges::size(__r2) <= std::ranges::size(__out_r)); // for debug purposes only + + auto __comp_2 = [__comp, __proj1, __proj2](auto&& __val1, auto&& __val2) { return std::invoke(__comp, + std::invoke(__proj1, std::forward(__val1)), std::invoke(__proj2, + std::forward(__val2)));}; + + auto __res = oneapi::dpl::__internal::__pattern_merge(__tag, std::forward<_ExecutionPolicy>(__exec), + std::ranges::begin(__r1), std::ranges::begin(__r1) + std::ranges::size(__r1), std::ranges::begin(__r2), + std::ranges::begin(__r2) + std::ranges::size(__r2), std::ranges::begin(__out_r), __comp_2); + + using __return_type = std::ranges::merge_result, std::ranges::borrowed_iterator_t<_R2>, + std::ranges::borrowed_iterator_t<_OutRange>>; + + return __return_type{std::ranges::begin(__r1) + std::ranges::size(__r1), std::ranges::begin(__r2) + std::ranges::size(__r2), __res}; +} + +template +auto +__pattern_merge(__serial_tag, _ExecutionPolicy&& __exec, _R1&& __r1, _R2&& __r2, _OutRange&& __out_r, _Comp __comp, + _Proj1 __proj1, _Proj2 __proj2) +{ + return std::ranges::merge(std::forward<_R1>(__r1), std::forward<_R2>(__r2), std::ranges::begin(__out_r), __comp, __proj1, + __proj2); +} + } // namespace __ranges } // namespace __internal } // 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 ad16e2b1a2a..9d68892115b 100644 --- a/include/oneapi/dpl/pstl/glue_algorithm_ranges_impl.h +++ b/include/oneapi/dpl/pstl/glue_algorithm_ranges_impl.h @@ -318,6 +318,250 @@ struct __search_n_fn inline constexpr __internal::__search_n_fn search_n; +namespace __internal +{ +struct __count_if_fn +{ + template, _Proj>> _Pred> + requires oneapi::dpl::is_execution_policy_v> && std::ranges::sized_range<_R> + + std::ranges::range_difference_t<_R> + operator()(_ExecutionPolicy&& __exec, _R&& __r, _Pred __pred, _Proj __proj = {}) const + { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec); + return oneapi::dpl::__internal::__ranges::__pattern_count_if(__dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), std::forward<_R>(__r), __pred, __proj); + } +}; //__count_if_fn +} //__internal + +inline constexpr __internal::__count_if_fn count_if; + +namespace __internal +{ +struct __count_fn +{ + template + requires oneapi::dpl::is_execution_policy_v> && std::ranges::sized_range<_R> + && std::indirect_binary_predicate, _Proj>, + const _T*> + std::ranges::range_difference_t<_R> + operator()(_ExecutionPolicy&& __exec, _R&& __r, const _T& __value, _Proj __proj = {}) const + { + auto __pred = [__value](auto&& __val) { return std::ranges::equal_to{}( + std::forward(__val), __value);}; + return oneapi::dpl::ranges::count_if(std::forward<_ExecutionPolicy>(__exec), + std::forward<_R>(__r), __pred, __proj); + } +}; //__count_fn +} //__internal + +inline constexpr __internal::__count_fn count; + +namespace __internal +{ +struct __equal_fn +{ + template + requires oneapi::dpl::is_execution_policy_v> + && (std::ranges::sized_range<_R1> || std::ranges::sized_range<_R2>) + && std::indirectly_comparable, std::ranges::iterator_t<_R2>, _Pred, _Proj1, + _Proj2> + bool + operator()(_ExecutionPolicy&& __exec, _R1&& __r1, _R2&& __r2, _Pred __pred = {}, _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const + { + if constexpr(!std::ranges::sized_range<_R1> || !std::ranges::sized_range<_R2>) + return false; + else + { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec); + return oneapi::dpl::__internal::__ranges::__pattern_equal(__dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), std::forward<_R1>(__r1), std::forward<_R2>(__r2), __pred, + __proj1, __proj2); + } + } +}; //__equal_fn +} //__internal + +inline constexpr __internal::__equal_fn equal; + +namespace __internal +{ +struct __is_sorted_fn +{ + template, _Proj>> + _Comp = std::ranges::less> + requires oneapi::dpl::is_execution_policy_v> && std::ranges::sized_range<_R> + bool + operator()(_ExecutionPolicy&& __exec, _R&& __r, _Comp __comp = {}, _Proj __proj = {}) const + { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec); + return oneapi::dpl::__internal::__ranges::__pattern_is_sorted(__dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), std::forward<_R>(__r), __comp, __proj); + } +}; //__is_sorted_fn +} //__internal + +inline constexpr __internal::__is_sorted_fn is_sorted; + +namespace __internal +{ +struct __stable_sort_fn +{ + template + requires oneapi::dpl::is_execution_policy_v> && std::ranges::sized_range<_R> + && std::sortable, _Comp, _Proj> + auto + operator()(_ExecutionPolicy&& __exec, _R&& __r, _Comp __comp = {}, _Proj __proj = {}) const + { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec); + return oneapi::dpl::__internal::__ranges::__pattern_sort_ranges(__dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), std::forward<_R>(__r), __comp, __proj); + } +}; //__stable_sort_fn +} //__internal + +inline constexpr __internal::__stable_sort_fn stable_sort; + +namespace __internal +{ +struct __sort_fn +{ + template + requires oneapi::dpl::is_execution_policy_v> && std::ranges::sized_range<_R> + && std::sortable, _Comp, _Proj> + auto + operator()(_ExecutionPolicy&& __exec, _R&& __r, _Comp __comp = {}, _Proj __proj = {}) const + { + return oneapi::dpl::ranges::stable_sort(std::forward<_ExecutionPolicy>(__exec), std::forward<_R>(__r), + __comp, __proj); + } +}; //__sort_fn +} //__internal + +inline constexpr __internal::__sort_fn sort; + +namespace __internal +{ +struct __min_element_fn +{ + template, _Proj>> + _Comp = std::ranges::less> + requires oneapi::dpl::is_execution_policy_v> && std::ranges::sized_range<_R> + auto + operator()(_ExecutionPolicy&& __exec, _R&& __r, _Comp __comp = {}, _Proj __proj = {}) const + { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec); + return oneapi::dpl::__internal::__ranges::__pattern_min_element(__dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), std::forward<_R>(__r), __comp, __proj); + } +}; //__min_element_fn +} //__internal + +inline constexpr __internal::__min_element_fn min_element; + +namespace __internal +{ +struct __max_element_fn +{ + template, _Proj>> _Comp = std::ranges::less> + requires oneapi::dpl::is_execution_policy_v> && std::ranges::sized_range<_R> + auto + operator()(_ExecutionPolicy&& __exec, _R&& __r, _Comp __comp = {}, _Proj __proj = {}) const + { + return oneapi::dpl::ranges::min_element(std::forward<_ExecutionPolicy>(__exec), std::forward<_R>(__r), + oneapi::dpl::__internal::__reorder_pred(__comp), __proj); + } +}; //__max_element_fn +} //__internal + +inline constexpr __internal::__max_element_fn max_element; + +namespace __internal +{ +struct __copy_fn +{ + template + requires oneapi::dpl::is_execution_policy_v> + && std::ranges::sized_range<_InRange> && std::ranges::sized_range<_OutRange> + && std::indirectly_copyable, std::ranges::iterator_t<_OutRange>> + + std::ranges::copy_result, std::ranges::borrowed_iterator_t<_OutRange>> + operator()(_ExecutionPolicy&& __exec, _InRange&& __in_r, _OutRange&& __out_r) const + { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec); + + using _Size = std::common_type_t, std::ranges::range_size_t<_OutRange>>; + const _Size __size = std::ranges::min((_Size)std::ranges::size(__in_r), (_Size)std::ranges::size(__out_r)); + + oneapi::dpl::__internal::__ranges::__pattern_copy(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), + std::ranges::take_view(__in_r, __size), std::ranges::take_view(__out_r, __size)); + + return {std::ranges::begin(__in_r) + __size, std::ranges::begin(__out_r) + __size}; + } +}; //__copy_fn +} //__internal + +inline constexpr __internal::__copy_fn copy; + +namespace __internal +{ +struct __copy_if_fn +{ + template, _Proj>> _Pred> + requires oneapi::dpl::is_execution_policy_v> + && std::ranges::sized_range<_InRange> && std::ranges::sized_range<_OutRange> + && std::indirectly_copyable, std::ranges::iterator_t<_OutRange>> + auto + operator()(_ExecutionPolicy&& __exec, _InRange&& __in_r, _OutRange&& __out_r, _Pred __pred, _Proj __proj = {}) const + { + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec); + // No minimum common size is calculated here, because the size of the output range is unknown + return oneapi::dpl::__internal::__ranges::__pattern_copy_if_ranges(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), + std::forward<_InRange>(__in_r), std::forward<_OutRange>(__out_r), __pred, __proj); + } +}; //__copy_if_fn +} //__internal + +inline constexpr __internal::__copy_if_fn copy_if; + +namespace __internal +{ +struct __merge_fn +{ + template + requires oneapi::dpl::is_execution_policy_v> && std::ranges::sized_range<_R1> + && std::ranges::sized_range<_R2> && std::ranges::sized_range<_OutRange> + && std::mergeable, std::ranges::iterator_t<_R2>, + std::ranges::iterator_t<_OutRange>, _Comp, _Proj1, _Proj2> + auto + operator()(_ExecutionPolicy&& __exec, _R1&& __r1, _R2&& __r2, _OutRange&& __out_r, _Comp __comp = {}, _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const + { + // TODO: develop a strategy to get a common minimum size + const auto __dispatch_tag = oneapi::dpl::__ranges::__select_backend(__exec); + return oneapi::dpl::__internal::__ranges::__pattern_merge(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), + std::forward<_R1>(__r1), std::forward<_R2>(__r2), std::forward<_OutRange>(__out_r), __comp, __proj1, __proj2); + } +}; //__merge_fn +} //__internal + +inline constexpr __internal::__merge_fn merge; + } //ranges #endif //_ONEDPL_CPP20_RANGES_PRESENT 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 5d9b24ee4c5..487151ce414 100644 --- a/include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h +++ b/include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h @@ -86,7 +86,7 @@ void __pattern_transform(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _InRange&& __in_r, _OutRange&& __out_r, _F __op, _Proj __proj) { - assert(std::ranges::size(__in_r) <= std::ranges::size(__out_r)); + assert(std::ranges::size(__in_r) <= std::ranges::size(__out_r)); // for debug purposes only auto __unary_op = [__op, __proj](auto&& __val) { return std::invoke(__op, std::invoke(__proj, std::forward(__val)));}; @@ -113,6 +113,19 @@ __pattern_transform(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, oneapi::dpl::__ranges::views::all_write(std::forward<_OutRange>(__out_r))); } +template +void +__pattern_copy(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _InRange&& __in_r, _OutRange&& __out_r) +{ + assert(std::ranges::size(__in_r) <= std::ranges::size(__out_r)); // for debug purposes only + + oneapi::dpl::__internal::__ranges::__pattern_walk_n( + __tag, ::std::forward<_ExecutionPolicy>(__exec), + oneapi::dpl::__internal::__brick_copy{}, + oneapi::dpl::__ranges::views::all_read(std::forward<_InRange>(__in_r)), + oneapi::dpl::__ranges::views::all_write(std::forward<_OutRange>(__out_r))); +} + #endif //_ONEDPL_CPP20_RANGES_PRESENT //------------------------------------------------------------------------ @@ -169,6 +182,23 @@ __pattern_equal(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Range1&& oneapi::dpl::__ranges::zip_view(::std::forward<_Range1>(__rng1), ::std::forward<_Range2>(__rng2))); } +#if _ONEDPL_CPP20_RANGES_PRESENT +template +bool +__pattern_equal(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _R1&& __r1, _R2&& __r2, _Pred __pred, + _Proj1 __proj1, _Proj2 __proj2) +{ + auto __pred_2 = [__pred, __proj1, __proj2](auto&& __val1, auto&& __val2) + { return std::invoke(__pred, std::invoke(__proj1, std::forward(__val1)), + std::invoke(__proj2, std::forward(__val2)));}; + + return oneapi::dpl::__internal::__ranges::__pattern_equal(__tag, ::std::forward<_ExecutionPolicy>(__exec), + oneapi::dpl::__ranges::views::all_read(::std::forward<_R1>(__r1)), + oneapi::dpl::__ranges::views::all_read(::std::forward<_R2>(__r2)), __pred_2); +} +#endif //_ONEDPL_CPP20_RANGES_PRESENT + //------------------------------------------------------------------------ // find_if //------------------------------------------------------------------------ @@ -444,6 +474,21 @@ __pattern_adjacent_find_ranges(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy return std::ranges::borrowed_iterator_t<_R>(std::ranges::begin(__r) + __idx); } + +template +bool +__pattern_is_sorted(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _R&& __r, _Comp __comp, _Proj __proj) +{ + auto __pred_2 = [__comp, __proj](auto&& __val1, auto&& __val2) { return std::invoke(__comp, + std::invoke(__proj, std::forward(__val1)), + std::invoke(__proj, std::forward(__val2)));}; + + return oneapi::dpl::__internal::__ranges::__pattern_adjacent_find(__tag, + std::forward<_ExecutionPolicy>(__exec), oneapi::dpl::__ranges::views::all_read(__r), + oneapi::dpl::__internal::__reorder_pred(__pred_2), oneapi::dpl::__internal::__or_semantic()) + == std::ranges::size(__r); +} + #endif //_ONEDPL_CPP20_RANGES_PRESENT template @@ -470,6 +515,19 @@ __pattern_count(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Range&& _ .get(); } +#if _ONEDPL_CPP20_RANGES_PRESENT +template +std::ranges::range_difference_t<_R> +__pattern_count_if(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _R&& __r, _Pred __pred, _Proj __proj) +{ + auto __pred_1 = [__pred, __proj](auto&& __val) { return std::invoke(__pred, std::invoke(__proj, + std::forward(__val)));}; + + return oneapi::dpl::__internal::__ranges::__pattern_count(__tag, ::std::forward<_ExecutionPolicy>(__exec), + oneapi::dpl::__ranges::views::all_read(::std::forward<_R>(__r)), __pred_1); +} +#endif //_ONEDPL_CPP20_RANGES_PRESENT + //------------------------------------------------------------------------ // copy_if //------------------------------------------------------------------------ @@ -491,6 +549,28 @@ __pattern_copy_if(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _R return __res.get(); //is a blocking call } +#if _ONEDPL_CPP20_RANGES_PRESENT +template +auto +__pattern_copy_if_ranges(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _InRange&& __in_r, _OutRange&& __out_r, + _Pred __pred, _Proj __proj) +{ + auto __pred_1 = [__pred, __proj](auto&& __val) { return std::invoke(__pred, std::invoke(__proj, + std::forward(__val)));}; + + auto __res_idx = oneapi::dpl::__internal::__ranges::__pattern_copy_if(__tag, + std::forward<_ExecutionPolicy>(__exec), oneapi::dpl::__ranges::views::all_read(__in_r), + oneapi::dpl::__ranges::views::all_write(__out_r), __pred_1, + oneapi::dpl::__internal::__pstl_assign()); + + using __return_t = std::ranges::copy_if_result, + std::ranges::borrowed_iterator_t<_OutRange>>; + + return __return_t{std::ranges::begin(__in_r) + std::ranges::size(__in_r), std::ranges::begin(__out_r) + __res_idx}; +} +#endif //_ONEDPL_CPP20_RANGES_PRESENT + //------------------------------------------------------------------------ // remove_if //------------------------------------------------------------------------ @@ -638,6 +718,31 @@ __pattern_merge(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _Ran return __n; } +#if _ONEDPL_CPP20_RANGES_PRESENT +template +auto +__pattern_merge(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _R1&& __r1, _R2&& __r2, _OutRange&& __out_r, + _Comp __comp, _Proj1 __proj1, _Proj2 __proj2) +{ + assert(std::ranges::size(__r1) + std::ranges::size(__r2) <= std::ranges::size(__out_r)); // for debug purposes only + + auto __comp_2 = [__comp, __proj1, __proj2](auto&& __val1, auto&& __val2) { return std::invoke(__comp, + std::invoke(__proj1, std::forward(__val1)), + std::invoke(__proj2, std::forward(__val2)));}; + + auto __res = oneapi::dpl::__internal::__ranges::__pattern_merge(__tag, std::forward<_ExecutionPolicy>(__exec), + oneapi::dpl::__ranges::views::all_read(__r1), oneapi::dpl::__ranges::views::all_read(__r2), + oneapi::dpl::__ranges::views::all_write(__out_r), __comp_2); + + using __return_t = std::ranges::merge_result, std::ranges::borrowed_iterator_t<_R2>, + std::ranges::borrowed_iterator_t<_OutRange>>; + + return __return_t{std::ranges::begin(__r1) + std::ranges::size(__r1), std::ranges::begin(__r2) + + std::ranges::size(__r2), std::ranges::begin(__out_r) + __res}; +} +#endif //_ONEDPL_CPP20_RANGES_PRESENT + //------------------------------------------------------------------------ // sort //------------------------------------------------------------------------ @@ -652,6 +757,19 @@ __pattern_sort(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Range&& __ .__deferrable_wait(); } +#if _ONEDPL_CPP20_RANGES_PRESENT +template +auto +__pattern_sort_ranges(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _R&& __r, _Comp __comp, _Proj __proj) +{ + oneapi::dpl::__internal::__ranges::__pattern_sort(__tag, std::forward<_ExecutionPolicy>(__exec), + oneapi::dpl::__ranges::views::all(__r), __comp, __proj); + + return std::ranges::borrowed_iterator_t<_R>(std::ranges::begin(__r) + std::ranges::size(__r)); +} + +#endif //_ONEDPL_CPP20_RANGES_PRESENT + //------------------------------------------------------------------------ // min_element //------------------------------------------------------------------------ @@ -692,6 +810,23 @@ __pattern_min_element(__hetero_tag<_BackendTag>, _ExecutionPolicy&& __exec, _Ran return get<0>(__ret_idx); } +#if _ONEDPL_CPP20_RANGES_PRESENT +template +auto +__pattern_min_element(__hetero_tag<_BackendTag> __tag, _ExecutionPolicy&& __exec, _R&& __r, _Comp __comp, _Proj __proj) +{ + auto __comp_2 = [__comp, __proj](auto&& __val1, auto&& __val2) { return std::invoke(__comp, + std::invoke(__proj, std::forward(__val1)), + std::invoke(__proj, std::forward(__val2)));}; + + auto __idx = oneapi::dpl::__internal::__ranges::__pattern_min_element(__tag, std::forward<_ExecutionPolicy>(__exec), + oneapi::dpl::__ranges::views::all_read(__r), __comp_2); + + return std::ranges::borrowed_iterator_t<_R>(std::ranges::begin(__r) + __idx); +} + +#endif //_ONEDPL_CPP20_RANGES_PRESENT + //------------------------------------------------------------------------ // minmax_element //------------------------------------------------------------------------ diff --git a/include/oneapi/dpl/pstl/unseq_backend_simd.h b/include/oneapi/dpl/pstl/unseq_backend_simd.h index 7efea31d3ef..7e454c80268 100644 --- a/include/oneapi/dpl/pstl/unseq_backend_simd.h +++ b/include/oneapi/dpl/pstl/unseq_backend_simd.h @@ -667,8 +667,8 @@ __simd_min_element(_ForwardIterator __first, _Size __n, _Compare __comp) noexcep void operator()(const _ComplexType& __obj) { - if (!(*__min_comp)(__min_val, __obj.__min_val) && - ((*__min_comp)(__obj.__min_val, __min_val) || __obj.__min_ind - __min_ind < 0)) + if (!std::invoke(*__min_comp, __min_val, __obj.__min_val) && + (std::invoke(*__min_comp, __obj.__min_val, __min_val) || __obj.__min_ind - __min_ind < 0)) { __min_val = __obj.__min_val; __min_ind = __obj.__min_ind; diff --git a/include/oneapi/dpl/pstl/utils.h b/include/oneapi/dpl/pstl/utils.h index df2b7416e58..856a5eb2945 100644 --- a/include/oneapi/dpl/pstl/utils.h +++ b/include/oneapi/dpl/pstl/utils.h @@ -19,11 +19,12 @@ #include "onedpl_config.h" #include -#include -#include #include #include #include +#include +#include +#include #if _ONEDPL_BACKEND_SYCL # include "hetero/dpcpp/sycl_defs.h" @@ -139,7 +140,7 @@ struct __compare bool operator()(const _Xp& __x, const _Yp& __y) const { - return __comp(__proj(__x), __proj(__y)); + return std::invoke(__comp, std::invoke(__proj, __x), std::invoke(__proj, __y)); } }; diff --git a/test/parallel_api/ranges/std_ranges_copy.pass.cpp b/test/parallel_api/ranges/std_ranges_copy.pass.cpp new file mode 100644 index 00000000000..b0177f409b5 --- /dev/null +++ b/test/parallel_api/ranges/std_ranges_copy.pass.cpp @@ -0,0 +1,43 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Copyright (C) Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This file incorporates work covered by the following copyright and permission +// notice: +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// +//===----------------------------------------------------------------------===// + +#include "std_ranges_test.h" + +std::int32_t +main() +{ +#if _ENABLE_STD_RANGES_TESTING + using namespace test_std_ranges; + namespace dpl_ranges = oneapi::dpl::ranges; + + auto copy_checker = [](std::ranges::random_access_range auto&& r_in, + std::ranges::random_access_range auto&& r_out) + { + const auto size = std::ranges::min(std::ranges::size(r_in), std::ranges::size(r_out)); + + auto res = std::ranges::copy(std::ranges::take_view(r_in, size), std::ranges::take_view(r_out, size).begin()); + + using ret_type = std::ranges::copy_result, + std::ranges::borrowed_iterator_t>; + + return ret_type{std::ranges::begin(r_in) + size, std::ranges::begin(r_out) + size}; + }; + + test_range_algo<0, int, data_in_out_lim>{}(dpl_ranges::copy, copy_checker); + +#endif //_ENABLE_STD_RANGES_TESTING + + return TestUtils::done(_ENABLE_STD_RANGES_TESTING); +} diff --git a/test/parallel_api/ranges/std_ranges_copy_if.pass.cpp b/test/parallel_api/ranges/std_ranges_copy_if.pass.cpp new file mode 100644 index 00000000000..ec4bed91780 --- /dev/null +++ b/test/parallel_api/ranges/std_ranges_copy_if.pass.cpp @@ -0,0 +1,43 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Copyright (C) Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This file incorporates work covered by the following copyright and permission +// notice: +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// +//===----------------------------------------------------------------------===// + +#include "std_ranges_test.h" + +std::int32_t +main() +{ +#if _ENABLE_STD_RANGES_TESTING + using namespace test_std_ranges; + namespace dpl_ranges = oneapi::dpl::ranges; + + auto copy_if_checker = [](std::ranges::random_access_range auto&& r_in, + std::ranges::random_access_range auto&& r_out, auto&&... args) + { + auto res = std::ranges::copy_if(std::forward(r_in), std::ranges::begin(r_out), + std::forward(args)...); + + using ret_type = std::ranges::copy_if_result, + std::ranges::borrowed_iterator_t>; + return ret_type{res.in, res.out}; + }; + + test_range_algo<0, int, data_in_out>{}(dpl_ranges::copy_if, copy_if_checker, pred); + test_range_algo<1, int, data_in_out>{}(dpl_ranges::copy_if, copy_if_checker, pred, proj); + test_range_algo<2, P2, data_in_out>{}(dpl_ranges::copy_if, copy_if_checker, pred, &P2::x); + test_range_algo<3, P2, data_in_out>{}(dpl_ranges::copy_if, copy_if_checker, pred, &P2::proj); +#endif //_ENABLE_STD_RANGES_TESTING + + return TestUtils::done(_ENABLE_STD_RANGES_TESTING); +} diff --git a/test/parallel_api/ranges/std_ranges_count.pass.cpp b/test/parallel_api/ranges/std_ranges_count.pass.cpp new file mode 100644 index 00000000000..849fb7fea0e --- /dev/null +++ b/test/parallel_api/ranges/std_ranges_count.pass.cpp @@ -0,0 +1,32 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Copyright (C) Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This file incorporates work covered by the following copyright and permission +// notice: +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// +//===----------------------------------------------------------------------===// + +#include "std_ranges_test.h" + +std::int32_t +main() +{ +#if _ENABLE_STD_RANGES_TESTING + using namespace test_std_ranges; + namespace dpl_ranges = oneapi::dpl::ranges; + + test_range_algo<0>{}(dpl_ranges::count, std::ranges::count, 4); + test_range_algo<1>{}(dpl_ranges::count, std::ranges::count, 4, proj); + test_range_algo<2, P2>{}(dpl_ranges::count, std::ranges::count, 4, &P2::x); + test_range_algo<3, P2>{}(dpl_ranges::count, std::ranges::count, 4, &P2::proj); +#endif //_ENABLE_STD_RANGES_TESTING + + return TestUtils::done(_ENABLE_STD_RANGES_TESTING); +} diff --git a/test/parallel_api/ranges/std_ranges_count_if.pass.cpp b/test/parallel_api/ranges/std_ranges_count_if.pass.cpp new file mode 100644 index 00000000000..3a9743a5e86 --- /dev/null +++ b/test/parallel_api/ranges/std_ranges_count_if.pass.cpp @@ -0,0 +1,32 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Copyright (C) Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This file incorporates work covered by the following copyright and permission +// notice: +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// +//===----------------------------------------------------------------------===// + +#include "std_ranges_test.h" + +std::int32_t +main() +{ +#if _ENABLE_STD_RANGES_TESTING + using namespace test_std_ranges; + namespace dpl_ranges = oneapi::dpl::ranges; + + test_range_algo<0>{}(dpl_ranges::count_if, std::ranges::count_if, pred); + test_range_algo<1>{}(dpl_ranges::count_if, std::ranges::count_if, pred, proj); + test_range_algo<2, P2>{}(dpl_ranges::count_if, std::ranges::count_if, pred, &P2::x); + test_range_algo<3, P2>{}(dpl_ranges::count_if, std::ranges::count_if, pred, &P2::proj); +#endif //_ENABLE_STD_RANGES_TESTING + + return TestUtils::done(_ENABLE_STD_RANGES_TESTING); +} diff --git a/test/parallel_api/ranges/std_ranges_equal.pass.cpp b/test/parallel_api/ranges/std_ranges_equal.pass.cpp new file mode 100644 index 00000000000..f968528cd90 --- /dev/null +++ b/test/parallel_api/ranges/std_ranges_equal.pass.cpp @@ -0,0 +1,32 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Copyright (C) Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This file incorporates work covered by the following copyright and permission +// notice: +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// +//===----------------------------------------------------------------------===// + +#include "std_ranges_test.h" + +std::int32_t +main() +{ +#if _ENABLE_STD_RANGES_TESTING + using namespace test_std_ranges; + namespace dpl_ranges = oneapi::dpl::ranges; + + test_range_algo<0, int, data_in_in>{}(dpl_ranges::equal, std::ranges::equal, binary_pred); + test_range_algo<1, int, data_in_in>{}(dpl_ranges::equal, std::ranges::equal, binary_pred, proj, proj); + test_range_algo<2, P2, data_in_in>{}(dpl_ranges::equal, std::ranges::equal, binary_pred, &P2::x, &P2::x); + test_range_algo<3, P2, data_in_in>{}(dpl_ranges::equal, std::ranges::equal, binary_pred, &P2::proj, &P2::proj); +#endif //_ENABLE_STD_RANGES_TESTING + + return TestUtils::done(_ENABLE_STD_RANGES_TESTING); +} diff --git a/test/parallel_api/ranges/std_ranges_is_sorted.pass.cpp b/test/parallel_api/ranges/std_ranges_is_sorted.pass.cpp new file mode 100644 index 00000000000..fa050e08c24 --- /dev/null +++ b/test/parallel_api/ranges/std_ranges_is_sorted.pass.cpp @@ -0,0 +1,37 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Copyright (C) Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This file incorporates work covered by the following copyright and permission +// notice: +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// +//===----------------------------------------------------------------------===// + +#include "std_ranges_test.h" + +std::int32_t +main() +{ +#if _ENABLE_STD_RANGES_TESTING + using namespace test_std_ranges; + namespace dpl_ranges = oneapi::dpl::ranges; + + test_range_algo<0>{}(dpl_ranges::is_sorted, std::ranges::is_sorted, std::ranges::less{}); + + test_range_algo<1>{}(dpl_ranges::is_sorted, std::ranges::is_sorted, std::ranges::less{}, proj); + test_range_algo<2, P2>{}(dpl_ranges::is_sorted, std::ranges::is_sorted, std::ranges::less{}, &P2::x); + test_range_algo<3, P2>{}(dpl_ranges::is_sorted, std::ranges::is_sorted, std::ranges::less{}, &P2::proj); + + test_range_algo<4>{}(dpl_ranges::is_sorted, std::ranges::is_sorted, std::ranges::greater{}, proj); + test_range_algo<5, P2>{}(dpl_ranges::is_sorted, std::ranges::is_sorted, std::ranges::greater{}, &P2::x); + test_range_algo<6, P2>{}(dpl_ranges::is_sorted, std::ranges::is_sorted, std::ranges::greater{}, &P2::proj); +#endif //_ENABLE_STD_RANGES_TESTING + + return TestUtils::done(_ENABLE_STD_RANGES_TESTING); +} diff --git a/test/parallel_api/ranges/std_ranges_max_element.pass.cpp b/test/parallel_api/ranges/std_ranges_max_element.pass.cpp new file mode 100644 index 00000000000..ef008a5c14a --- /dev/null +++ b/test/parallel_api/ranges/std_ranges_max_element.pass.cpp @@ -0,0 +1,36 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Copyright (C) Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This file incorporates work covered by the following copyright and permission +// notice: +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// +//===----------------------------------------------------------------------===// + +#include "std_ranges_test.h" + +std::int32_t +main() +{ +#if _ENABLE_STD_RANGES_TESTING + using namespace test_std_ranges; + namespace dpl_ranges = oneapi::dpl::ranges; + + test_range_algo<0>{}(dpl_ranges::max_element, std::ranges::max_element, std::ranges::less{}); + test_range_algo<1>{}(dpl_ranges::max_element, std::ranges::max_element, std::ranges::less{}, proj); + test_range_algo<2, P2>{}(dpl_ranges::max_element, std::ranges::max_element, std::ranges::less{}, &P2::x); + test_range_algo<3, P2>{}(dpl_ranges::max_element, std::ranges::max_element, std::ranges::less{}, &P2::proj); + + test_range_algo<4>{}(dpl_ranges::max_element, std::ranges::max_element, std::ranges::greater{}, proj); + test_range_algo<5, P2>{}(dpl_ranges::max_element, std::ranges::max_element, std::ranges::greater{}, &P2::x); + test_range_algo<6, P2>{}(dpl_ranges::max_element, std::ranges::max_element, std::ranges::greater{}, &P2::proj); +#endif //_ENABLE_STD_RANGES_TESTING + + return TestUtils::done(_ENABLE_STD_RANGES_TESTING); +} diff --git a/test/parallel_api/ranges/std_ranges_merge.pass.cpp b/test/parallel_api/ranges/std_ranges_merge.pass.cpp new file mode 100644 index 00000000000..15112aa38e5 --- /dev/null +++ b/test/parallel_api/ranges/std_ranges_merge.pass.cpp @@ -0,0 +1,50 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Copyright (C) Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This file incorporates work covered by the following copyright and permission +// notice: +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// +//===----------------------------------------------------------------------===// + +#include "std_ranges_test.h" + +std::int32_t +main() +{ +#if _ENABLE_STD_RANGES_TESTING + using namespace test_std_ranges; + namespace dpl_ranges = oneapi::dpl::ranges; + + //A checker below modifies a return type; a range based version with policy has another return type. + auto merge_checker = [](std::ranges::random_access_range auto&& r_1, + std::ranges::random_access_range auto&& r_2, + std::ranges::random_access_range auto&& r_out, auto&&... args) + { + auto res = std::ranges::merge(std::forward(r_1), std::forward(r_2), + std::ranges::begin(r_out), std::forward(args)...); + + using ret_type = std::ranges::merge_result, + std::ranges::borrowed_iterator_t, std::ranges::borrowed_iterator_t>; + return ret_type{res.in1, res.in2, res.out}; + }; + + test_range_algo<0, int, data_in_in_out>{}(dpl_ranges::merge, merge_checker, std::ranges::less{}); + + test_range_algo<1, int, data_in_in_out>{}(dpl_ranges::merge, merge_checker, std::ranges::less{}, proj, proj); + test_range_algo<2, P2, data_in_in_out>{}(dpl_ranges::merge, merge_checker, std::ranges::less{}, &P2::x, &P2::x); + test_range_algo<3, P2, data_in_in_out>{}(dpl_ranges::merge, merge_checker, std::ranges::less{}, &P2::proj, &P2::proj); + + test_range_algo<4, int, data_in_in_out>{}(dpl_ranges::merge, merge_checker, std::ranges::greater{}, proj, proj); + test_range_algo<5, P2, data_in_in_out>{}(dpl_ranges::merge, merge_checker, std::ranges::greater{}, &P2::x, &P2::x); + test_range_algo<6, P2, data_in_in_out>{}(dpl_ranges::merge, merge_checker, std::ranges::greater{}, &P2::proj, &P2::proj); +#endif //_ENABLE_STD_RANGES_TESTING + + return TestUtils::done(_ENABLE_STD_RANGES_TESTING); +} diff --git a/test/parallel_api/ranges/std_ranges_min_element.pass.cpp b/test/parallel_api/ranges/std_ranges_min_element.pass.cpp new file mode 100644 index 00000000000..fdd8d4403b7 --- /dev/null +++ b/test/parallel_api/ranges/std_ranges_min_element.pass.cpp @@ -0,0 +1,37 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Copyright (C) Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This file incorporates work covered by the following copyright and permission +// notice: +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// +//===----------------------------------------------------------------------===// + +#include "std_ranges_test.h" + +std::int32_t +main() +{ +#if _ENABLE_STD_RANGES_TESTING + using namespace test_std_ranges; + namespace dpl_ranges = oneapi::dpl::ranges; + + test_range_algo<0>{}(dpl_ranges::min_element, std::ranges::min_element, std::ranges::less{}); + + test_range_algo<1>{}(dpl_ranges::min_element, std::ranges::min_element, std::ranges::less{}, proj); + test_range_algo<2, P2>{}(dpl_ranges::min_element, std::ranges::min_element, std::ranges::less{}, &P2::x); + test_range_algo<3, P2>{}(dpl_ranges::min_element, std::ranges::min_element, std::ranges::less{}, &P2::proj); + + test_range_algo<4>{}(dpl_ranges::min_element, std::ranges::min_element, std::ranges::greater{}, proj); + test_range_algo<5, P2>{}(dpl_ranges::min_element, std::ranges::min_element, std::ranges::greater{}, &P2::x); + test_range_algo<6, P2>{}(dpl_ranges::min_element, std::ranges::min_element, std::ranges::greater{}, &P2::proj); +#endif //_ENABLE_STD_RANGES_TESTING + + return TestUtils::done(_ENABLE_STD_RANGES_TESTING); +} diff --git a/test/parallel_api/ranges/std_ranges_sort.pass.cpp b/test/parallel_api/ranges/std_ranges_sort.pass.cpp new file mode 100644 index 00000000000..00cdff4f51a --- /dev/null +++ b/test/parallel_api/ranges/std_ranges_sort.pass.cpp @@ -0,0 +1,39 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Copyright (C) Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This file incorporates work covered by the following copyright and permission +// notice: +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// +//===----------------------------------------------------------------------===// + +#include "std_ranges_test.h" + +std::int32_t +main() +{ +#if _ENABLE_STD_RANGES_TESTING + using namespace test_std_ranges; + namespace dpl_ranges = oneapi::dpl::ranges; + + test_range_algo<0>{}(dpl_ranges::sort, std::ranges::sort); + test_range_algo<1>{}(dpl_ranges::sort, std::ranges::sort, std::ranges::less{}); + + test_range_algo<2>{}(dpl_ranges::sort, std::ranges::sort, std::ranges::less{}, proj); + test_range_algo<3>{}(dpl_ranges::sort, std::ranges::sort, std::ranges::greater{}, proj); + + test_range_algo<4, P2>{}(dpl_ranges::sort, std::ranges::sort, std::ranges::less{}, &P2::x); + test_range_algo<5, P2>{}(dpl_ranges::sort, std::ranges::sort, std::ranges::greater{}, &P2::x); + + test_range_algo<6, P2>{}(dpl_ranges::sort, std::ranges::sort, std::ranges::less{}, &P2::proj); + test_range_algo<7, P2>{}(dpl_ranges::sort, std::ranges::sort, std::ranges::greater{}, &P2::proj); +#endif //_ENABLE_STD_RANGES_TESTING + + return TestUtils::done(_ENABLE_STD_RANGES_TESTING); +} diff --git a/test/parallel_api/ranges/std_ranges_stable_sort.pass.cpp b/test/parallel_api/ranges/std_ranges_stable_sort.pass.cpp new file mode 100644 index 00000000000..923e0d49fa8 --- /dev/null +++ b/test/parallel_api/ranges/std_ranges_stable_sort.pass.cpp @@ -0,0 +1,39 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Copyright (C) Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This file incorporates work covered by the following copyright and permission +// notice: +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// +//===----------------------------------------------------------------------===// + +#include "std_ranges_test.h" + +std::int32_t +main() +{ +#if _ENABLE_STD_RANGES_TESTING + using namespace test_std_ranges; + namespace dpl_ranges = oneapi::dpl::ranges; + + test_range_algo<0>{}(dpl_ranges::stable_sort, std::ranges::stable_sort); + test_range_algo<1>{}(dpl_ranges::stable_sort, std::ranges::stable_sort, std::ranges::less{}); + + test_range_algo<2>{}(dpl_ranges::stable_sort, std::ranges::stable_sort, std::ranges::less{}, proj); + test_range_algo<3>{}(dpl_ranges::stable_sort, std::ranges::stable_sort, std::ranges::greater{}, proj); + + test_range_algo<4, P2>{}(dpl_ranges::stable_sort, std::ranges::stable_sort, std::ranges::less{}, &P2::x); + test_range_algo<5, P2>{}(dpl_ranges::stable_sort, std::ranges::stable_sort, std::ranges::greater{}, &P2::x); + + test_range_algo<6, P2>{}(dpl_ranges::stable_sort, std::ranges::stable_sort, std::ranges::less{}, &P2::proj); + test_range_algo<7, P2>{}(dpl_ranges::stable_sort, std::ranges::stable_sort, std::ranges::greater{}, &P2::proj); +#endif //_ENABLE_STD_RANGES_TESTING + + return TestUtils::done(_ENABLE_STD_RANGES_TESTING); +} diff --git a/test/parallel_api/ranges/std_ranges_test.h b/test/parallel_api/ranges/std_ranges_test.h index b92995ea9ee..99ddfaf2cde 100644 --- a/test/parallel_api/ranges/std_ranges_test.h +++ b/test/parallel_api/ranges/std_ranges_test.h @@ -50,8 +50,10 @@ enum TestDataMode { data_in, data_in_out, + data_in_out_lim, data_in_in, - data_in_in_out + data_in_in_out, + data_in_in_out_lim }; auto f_mutuable = [](auto&& val) { return val *= val; }; @@ -184,7 +186,7 @@ struct test process_data_in_out(int n_in, int n_out, Policy&& exec, Algo algo, Checker& checker, TransIn tr_in, TransOut tr_out, auto... args) { - static_assert(mode == data_in_out); + static_assert(mode == data_in_out || mode == data_in_out_lim); constexpr int max_n = 10; DataType data_in[max_n] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; @@ -223,6 +225,14 @@ struct test template std::enable_if_t && mode == data_in_out> operator()(Policy&& exec, Algo algo, Checker& checker, auto... args) + { + const int r_size = 10; + process_data_in_out(r_size, r_size, std::forward(exec), algo, checker, args...); + } + + template + std::enable_if_t && mode == data_in_out_lim> + operator()(Policy&& exec, Algo algo, Checker& checker, auto... args) { const int r_size = 10; process_data_in_out(r_size, r_size, std::forward(exec), algo, checker, args...); @@ -265,7 +275,7 @@ struct test void process_data_in_in_out(int n_in1, int n_in2, int n_out, Policy&& exec, Algo algo, Checker& checker, TransIn tr_in, TransOut tr_out, auto... args) { - static_assert(mode == data_in_in_out); + static_assert(mode == data_in_in_out || mode == data_in_in_out_lim); constexpr int max_n = 10; DataType data_in1[max_n] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; @@ -306,6 +316,14 @@ struct test template std::enable_if_t && mode == data_in_in_out> operator()(Policy&& exec, Algo algo, Checker& checker, auto... args) + { + const int r_size = 10; + process_data_in_in_out(r_size, r_size, r_size*2, std::forward(exec), algo, checker, args...); + } + + template + std::enable_if_t && mode == data_in_in_out_lim> + operator()(Policy&& exec, Algo algo, Checker& checker, auto... args) { const int r_size = 10; process_data_in_in_out(r_size, r_size, r_size, exec, algo, checker, args...); diff --git a/test/parallel_api/ranges/std_ranges_transform.pass.cpp b/test/parallel_api/ranges/std_ranges_transform.pass.cpp index c079dc310ba..4718750626e 100644 --- a/test/parallel_api/ranges/std_ranges_transform.pass.cpp +++ b/test/parallel_api/ranges/std_ranges_transform.pass.cpp @@ -38,10 +38,10 @@ main() return ret_type{std::ranges::begin(r_in) + size, std::ranges::begin(r_out) + size}; }; - test_range_algo<0, int, data_in_out>{}(dpl_ranges::transform, transform_unary_checker, f); - test_range_algo<1, int, data_in_out>{}(dpl_ranges::transform, transform_unary_checker, f, proj); - test_range_algo<2, P2, data_in_out>{}(dpl_ranges::transform, transform_unary_checker, f, &P2::x); - test_range_algo<3, P2, data_in_out>{}(dpl_ranges::transform, transform_unary_checker, f, &P2::proj); + test_range_algo<0, int, data_in_out_lim>{}(dpl_ranges::transform, transform_unary_checker, f); + test_range_algo<1, int, data_in_out_lim>{}(dpl_ranges::transform, transform_unary_checker, f, proj); + test_range_algo<2, P2, data_in_out_lim>{}(dpl_ranges::transform, transform_unary_checker, f, &P2::x); + test_range_algo<3, P2, data_in_out_lim>{}(dpl_ranges::transform, transform_unary_checker, f, &P2::proj); //A checker below modifies a return type; a range based version with policy has another return type. auto transform_binary_checker = [](std::ranges::random_access_range auto&& r_1, @@ -65,10 +65,10 @@ main() return ret_type{std::ranges::begin(r_1) + size, std::ranges::begin(r_2) + size, std::ranges::begin(r_out) + size}; }; - test_range_algo<4, int, data_in_in_out>{}(dpl_ranges::transform, transform_binary_checker, binary_f); - test_range_algo<5, int, data_in_in_out>{}(dpl_ranges::transform, transform_binary_checker, binary_f, proj, proj); - test_range_algo<6, P2, data_in_in_out>{}(dpl_ranges::transform, transform_binary_checker, binary_f, &P2::x, &P2::x); - test_range_algo<7, P2, data_in_in_out>{}(dpl_ranges::transform, transform_binary_checker, binary_f, &P2::proj, &P2::proj); + test_range_algo<4, int, data_in_in_out_lim>{}(dpl_ranges::transform, transform_binary_checker, binary_f); + test_range_algo<5, int, data_in_in_out_lim>{}(dpl_ranges::transform, transform_binary_checker, binary_f, proj, proj); + test_range_algo<6, P2, data_in_in_out_lim>{}(dpl_ranges::transform, transform_binary_checker, binary_f, &P2::x, &P2::x); + test_range_algo<7, P2, data_in_in_out_lim>{}(dpl_ranges::transform, transform_binary_checker, binary_f, &P2::proj, &P2::proj); #endif //_ENABLE_STD_RANGES_TESTING return TestUtils::done(_ENABLE_STD_RANGES_TESTING); diff --git a/test/support/test_config.h b/test/support/test_config.h index 1f4eea15852..65d94c92d46 100644 --- a/test/support/test_config.h +++ b/test/support/test_config.h @@ -268,4 +268,7 @@ // Intel(R) oneAPI DPC++/C++ compiler produces 'Unexpected kernel lambda size issue' error #define _PSTL_LAMBDA_PTR_TO_MEMBER_WINDOWS_BROKEN (_MSC_VER && TEST_DPCPP_BACKEND_PRESENT && __INTEL_LLVM_COMPILER <= 20250100) +// Intel(R) oneAPI DPC++/C++ compiler produces 'Unexpected kernel lambda size issue' error +#define _PSTL_LAMBDA_PTR_TO_MEMBER_WINDOWS_BROKEN (_MSC_VER && TEST_DPCPP_BACKEND_PRESENT && __INTEL_LLVM_COMPILER <= 20250100) + #endif // _TEST_CONFIG_H