From c28614442ac9a6cfe618d38632e4c956baf02b15 Mon Sep 17 00:00:00 2001 From: Alexey Kukanov Date: Tue, 4 Feb 2025 00:35:29 +0100 Subject: [PATCH 1/4] Add 15 more parallel range algorithms --- .../parallel_api/parallel_range_api.rst | 194 +++++++++++++++++- 1 file changed, 192 insertions(+), 2 deletions(-) diff --git a/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst b/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst index 3bcc58bf9..11cf545ad 100644 --- a/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst +++ b/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst @@ -133,6 +133,18 @@ Element Search Operations std::ranges::borrowed_iterator_t find_if_not (ExecutionPolicy&& pol, R&& r, Pred pred, Proj proj = {}); + // find_first_of + template + requires oneapi::dpl::is_execution_policy_v> && + std::ranges::sized_range && std::ranges::sized_range && + std::indirectly_comparable< std::ranges::iterator_t, std::ranges::iterator_t, + Pred, Proj1, Proj2 > + std::ranges::borrowed_iterator_t + find_first_of (ExecutionPolicy&& pol, R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); + // adjacent_find template adjacent_find (ExecutionPolicy&& pol, R&& r, Pred pred = {}, Proj proj = {}); + } + +Minimum and Maximum ++++++++++++++++++++ + +.. code:: cpp + + // Defined in + + namespace oneapi::dpl::ranges { + + // min + template , Proj> > + Comp = std::ranges::less> + requires oneapi::dpl::is_execution_policy_v> && + std::ranges::sized_range && + std::indirectly_copyable_storable< std::ranges::iterator_t, + std::ranges::range_value_t* > + std::ranges::range_value_t + min (ExecutionPolicy&& pol, R&& r, Comp comp = {}, Proj proj = {}); + + // max + template , Proj> > + Comp = std::ranges::less> + requires oneapi::dpl::is_execution_policy_v> && + std::ranges::sized_range && + std::indirectly_copyable_storable< std::ranges::iterator_t, + std::ranges::range_value_t* > + std::ranges::range_value_t + max (ExecutionPolicy&& pol, R&& r, Comp comp = {}, Proj proj = {}); + + + // minmax + template , Proj> > + Comp = std::ranges::less> + requires oneapi::dpl::is_execution_policy_v> && + std::ranges::sized_range && + std::indirectly_copyable_storable< std::ranges::iterator_t, + std::ranges::range_value_t* > + std::ranges::minmax_result> + minmax (ExecutionPolicy&& pol, R&& r, Comp comp = {}, Proj proj = {}); + // min_element template max_element (ExecutionPolicy&& pol, R&& r, Comp comp = {}, Proj proj = {}); + // minmax_element + template , Proj> > + Comp = std::ranges::less> + requires oneapi::dpl::is_execution_policy_v> && + std::ranges::sized_range + std::ranges::minmax_element_result> + minmax_element (ExecutionPolicy&& pol, R&& r, Comp comp = {}, Proj proj = {}); + } Sequence Search and Comparison @@ -186,6 +256,32 @@ Sequence Search and Comparison bool equal (ExecutionPolicy&& pol, R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); + // mismatch + template + requires oneapi::dpl::is_execution_policy_v> && + (std::ranges::sized_range || std::ranges::sized_range) && + std::indirectly_comparable< std::ranges::iterator_t, std::ranges::iterator_t, + Pred, Proj1, Proj2 > + std::ranges::mismatch_result, + std::ranges::borrowed_iterator_t> + mismatch (ExecutionPolicy&& pol, R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); + + + // find_end + template + requires oneapi::dpl::is_execution_policy_v> && + std::ranges::sized_range && std::ranges::sized_range && + std::indirectly_comparable< std::ranges::iterator_t, std::ranges::iterator_t, + Pred, Proj1, Proj2 > + std::ranges::borrowed_subrange_t + find_end (ExecutionPolicy&& pol, R1&& r1, R2&& r2, Pred pred = {}, + Proj1 proj1 = {}, Proj2 proj2 = {}); + // search template bool is_sorted (ExecutionPolicy&& pol, R&& r, Comp comp = {}, Proj proj = {}); + // is_sorted_until + template , Proj> > + Comp = std::ranges::less> + requires oneapi::dpl::is_execution_policy_v> && + std::ranges::sized_range + std::ranges::borrowed_iterator_t + is_sorted_until (ExecutionPolicy&& pol, R&& r, Comp comp = {}, Proj proj = {}); + // merge template > copy_if (ExecutionPolicy&& pol, R&& r, OutR&& result, Pred pred, Proj proj = {}); + // move + template + requires oneapi::dpl::is_execution_policy_v> && + std::ranges::sized_range && std::ranges::sized_range && + std::indirectly_movable, std::ranges::iterator_t> + std::ranges::move_result, + std::ranges::borrowed_iterator_t> + move (ExecutionPolicy&& pol, R&& r, OutR&& result); + // transform (unary) template + + namespace oneapi::dpl::ranges { + + // fill + template > + requires oneapi::dpl::is_execution_policy_v> && + std::ranges::sized_range && + std::indirectly_writable, const T&> + std::ranges::borrowed_iterator_t + fill (ExecutionPolicy&& pol, R&& r, const T& value); + + // generate + template + requires oneapi::dpl::is_execution_policy_v> && + std::ranges::sized_range && std::invocable && + std::indirectly_writable, std::invoke_result_t> + std::ranges::borrowed_iterator_t + generate (ExecutionPolicy&& pol, R&& r, F gen); + + // replace + template , Proj>, typename T2 = T1> + requires oneapi::dpl::is_execution_policy_v> && + std::ranges::sized_range && + std::indirectly_writable, const T2&> && + std::indirect_binary_predicate< std::ranges::equal_to, + std::projected, Proj>, + const T1* > + std::ranges::borrowed_iterator_t + replace (ExecutionPolicy&& pol, R&& r, const T1& old_value, const T2& new_value, + Proj proj = {}); + + // replace_if + template , Proj>, + std::indirect_unary_predicate< std::projected, Proj> > Pred> + requires oneapi::dpl::is_execution_policy_v> && + std::ranges::sized_range && + std::indirectly_writable, const T&> + std::ranges::borrowed_iterator_t + replace_if (ExecutionPolicy&& pol, R&& r, Pred pred, const T& new_value, Proj proj = {}); + + // remove + template , Proj>> + requires oneapi::dpl::is_execution_policy_v> && + std::ranges::sized_range && std::permutable && + std::indirect_binary_predicate< std::ranges::equal_to, + std::projected, Proj>, + const T* > + std::ranges::borrowed_subrange_t + remove (ExecutionPolicy&& pol, R&& r, const T& value, Proj proj = {}); + + // remove_if + template , Proj> > Pred> + requires oneapi::dpl::is_execution_policy_v> && + std::ranges::sized_range && std::permutable> + std::ranges::borrowed_subrange_t + remove_if (ExecutionPolicy&& pol, R&& r, Pred pred, Proj proj = {}); + + } + .. _`C++ Standard`: https://isocpp.org/std/the-standard .. _`SYCL`: https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html From 005583b7b4b247970ed68169f697a7412d6c3493 Mon Sep 17 00:00:00 2001 From: Alexey Kukanov Date: Tue, 25 Mar 2025 21:45:47 +0100 Subject: [PATCH 2/4] Replace std::projected_value_t with an exposition-only template --- .../oneDPL/source/parallel_api/parallel_range_api.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst b/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst index 11cf545ad..a9b42b80f 100644 --- a/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst +++ b/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst @@ -469,7 +469,7 @@ In-place Mutating Operations // replace template , Proj>, typename T2 = T1> + typename T1 = /*projected-value-type*/, Proj>, typename T2 = T1> requires oneapi::dpl::is_execution_policy_v> && std::ranges::sized_range && std::indirectly_writable, const T2&> && @@ -483,7 +483,7 @@ In-place Mutating Operations // replace_if template , Proj>, + typename T = /*projected-value-type*/, Proj>, std::indirect_unary_predicate< std::projected, Proj> > Pred> requires oneapi::dpl::is_execution_policy_v> && std::ranges::sized_range && @@ -494,7 +494,7 @@ In-place Mutating Operations // remove template , Proj>> + typename T = /*projected-value-type*/, Proj>> requires oneapi::dpl::is_execution_policy_v> && std::ranges::sized_range && std::permutable && std::indirect_binary_predicate< std::ranges::equal_to, From 580ac972ecea600eda5da4f9d641a93533b26462 Mon Sep 17 00:00:00 2001 From: Alexey Kukanov Date: Tue, 29 Apr 2025 18:08:38 +0200 Subject: [PATCH 3/4] Remove 'generate' --- .../oneDPL/source/parallel_api/parallel_range_api.rst | 8 -------- 1 file changed, 8 deletions(-) diff --git a/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst b/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst index ec6e9f96c..2cefeeb2c 100644 --- a/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst +++ b/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst @@ -478,14 +478,6 @@ In-place Mutating Operations std::ranges::borrowed_iterator_t fill (ExecutionPolicy&& pol, R&& r, const T& value); - // generate - template - requires oneapi::dpl::is_execution_policy_v> && - std::ranges::sized_range && std::invocable && - std::indirectly_writable, std::invoke_result_t> - std::ranges::borrowed_iterator_t - generate (ExecutionPolicy&& pol, R&& r, F gen); - // replace template Date: Tue, 29 Apr 2025 18:27:10 +0200 Subject: [PATCH 4/4] Cosmetic updates in the description of differences with C++ range algorithms --- .../oneDPL/source/parallel_api/parallel_range_api.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst b/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst index 2cefeeb2c..d5a353e5d 100644 --- a/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst +++ b/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst @@ -20,7 +20,7 @@ predefined function objects which static function call operators have the requir The following differences to the standard C++ range algorithms apply: - Parallel range algorithms cannot be used in constant expressions. -- The execution policy parameter is added. +- The oneDPL execution policy parameter is added. - Output data sequences are defined as ranges, not iterators. - Both input and output ranges must support random access. - As a rule, both input and output ranges must be sized. @@ -30,7 +30,7 @@ The following differences to the standard C++ range algorithms apply: [*Note*: An example of an infinite range is ``std::views::repeat`` with no bound. -- *end note*] - For algorithms with bounded output ranges, processing may not need to go over all the input data. - In that case, the returned value usually contains iterators pointing to the positions past the last elements + In that case, the returned value contains iterators pointing to the positions past the last elements processed according to the algorithm semantics. - ``for_each`` does not return its function object.