From bbed8e17e3d238b168eace7ccf896417e2da38d8 Mon Sep 17 00:00:00 2001 From: Dmitriy Sobolev Date: Sun, 20 Jul 2025 22:45:44 +0100 Subject: [PATCH 01/10] [oneDPL] Add memory parallel range algorithms --- .../parallel_api/parallel_range_api.rst | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) 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 d5a353e5d..1cc4619d0 100644 --- a/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst +++ b/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst @@ -49,6 +49,33 @@ of parallel range algorithms. template using /*projected-value-type*/ = std::remove_cvref_t&>>; + // Extension of C++20 exposition-only special memory concepts as defined in [special.mem.concepts] + template + concept no-throw-sized-sentinel-for = // exposition only + no-throw-sentinel-for && + std::sized_sentinel_for; + + template + concept no-throw-bidirectional-iterator = // exposition only + no-throw-forward-iterator && + std::bidirectional_iterator; + + template + concept no-throw-random-access-iterator = // exposition only + no-throw-bidirectional-iterator && + std::random_access_iterator && + no-throw-sized-sentinel-for; + + template + concept no-throw-bidirectional-range = // exposition only + no-throw-forward-range && + no-throw-bidirectional-iterator>; + + template + concept no-throw-random-access-range = // exposition only + no-throw-bidirectional-range && + no-throw-random-access-iterator>; + Whole Sequence Operations +++++++++++++++++++++++++ @@ -526,5 +553,67 @@ In-place Mutating Operations } +Uninitialized Memory Algorithms ++++++++++++++++++++++++++++++++ + +.. code:: cpp + + // Defined in + + namespace oneapi::dpl::ranges { + + // uninitialized_default_construct + template + requires oneapi::dpl::is_execution_policy_v> && + std::ranges::sized_range && + std::default_initializable> + std::ranges::borrowed_iterator_t + uninitialized_default_construct (ExecutionPolicy&& pol, R&& r); + + // uninitialized_value_construct + template + requires oneapi::dpl::is_execution_policy_v> && + std::ranges::sized_range && + std::default_initializable> + std::ranges::borrowed_iterator_t + uninitialized_value_construct (ExecutionPolicy&& pol, R&& r, const std::ranges::range_value_t& value); + + // uninitialized_copy + template + requires oneapi::dpl::is_execution_policy_v> && + std::ranges::sized_range && std::ranges::sized_range && + std::constructible_from, std::ranges::range_reference_t> + std::ranges::uninitialized_copy_result, + std::ranges::borrowed_iterator_t> + uninitialized_copy (ExecutionPolicy&& pol, IR&& in_range, OR&& out_range); + + // uninitialized_move + template + requires oneapi::dpl::is_execution_policy_v> && + std::ranges::sized_range && std::ranges::sized_range && + std::constructible_from, std::ranges::range_reference_t> + std::ranges::uninitialized_move_result, + std::ranges::borrowed_iterator_t> + uninitialized_move (ExecutionPolicy&& pol, IR&& in_range, OR&& out_range); + + // uninitialized_fill + template + requires oneapi::dpl::is_execution_policy_v> && + std::ranges::sized_range && + std::constructible_from, const T&> + std::ranges::borrowed_iterator_t + uninitialized_fill (ExecutionPolicy&& pol, R&& r, const T& value); + + // destroy + template + requires oneapi::dpl::is_execution_policy_v> && + std::ranges::sized_range && + std::destructible> + std::ranges::borrowed_iterator_t + destroy (ExecutionPolicy&& pol, R&& r); + } + .. _`C++ Standard`: https://isocpp.org/std/the-standard .. _`SYCL`: https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html From a4516c219fe48e6c0c672787804fb161107828d2 Mon Sep 17 00:00:00 2001 From: Dmitriy Sobolev Date: Tue, 29 Jul 2025 22:02:21 +0100 Subject: [PATCH 02/10] Add a note about destroy and noexcept --- .../elements/oneDPL/source/parallel_api/parallel_range_api.rst | 1 + 1 file changed, 1 insertion(+) 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 1cc4619d0..bfee443c8 100644 --- a/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst +++ b/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst @@ -33,6 +33,7 @@ The following differences to the standard C++ range algorithms apply: 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. +- ``destroy`` is not marked with ``noexcept``. Except for these differences, the signatures of parallel range algorithms correspond to the working draft of the next edition of the C++ standard (C++26). From b69247a0bbd7a9b47bc2173a18ead91850eeb62a Mon Sep 17 00:00:00 2001 From: Dmitriy Sobolev Date: Tue, 5 Aug 2025 22:36:09 +0100 Subject: [PATCH 03/10] Keep only nothrow-random-access-range and its semantic requirements --- .../parallel_api/parallel_range_api.rst | 61 +++++++++---------- 1 file changed, 28 insertions(+), 33 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 bfee443c8..ec2a537b3 100644 --- a/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst +++ b/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst @@ -47,35 +47,30 @@ of parallel range algorithms. .. code:: cpp // C++20 analogue of std::projected_value_t; exposition only - template + template using /*projected-value-type*/ = std::remove_cvref_t&>>; - // Extension of C++20 exposition-only special memory concepts as defined in [special.mem.concepts] - template - concept no-throw-sized-sentinel-for = // exposition only - no-throw-sentinel-for && - std::sized_sentinel_for; - - template - concept no-throw-bidirectional-iterator = // exposition only - no-throw-forward-iterator && - std::bidirectional_iterator; - - template - concept no-throw-random-access-iterator = // exposition only - no-throw-bidirectional-iterator && - std::random_access_iterator && - no-throw-sized-sentinel-for; - - template - concept no-throw-bidirectional-range = // exposition only - no-throw-forward-range && - no-throw-bidirectional-iterator>; - - template - concept no-throw-random-access-range = // exposition only - no-throw-bidirectional-range && - no-throw-random-access-iterator>; + // C++20 analogue of nothrow-random-access-range proposed for C++26 in P3179R9; exposition only + template + concept nothrow-random-access-range = + std::ranges::random_access_range && + std::is_lvalue_reference_v> && + std::same_as>, std::iter_value_t> && + std::sized_sentinel_for, std::ranges::iterator_t>; + +Semantic Requirements +~~~~~~~~~~~~~~~~~~~~ + +A type ``R`` models ``nothrow-random-access-range`` if no exceptions are thrown from: + +- increment, decrement, copy construction, move construction, copy assignment, move assignment, + comparisons or indirection through valid iterators of type ``std::ranges::iterator_t``; +- ``-`` operator, copy construction, move construction, copy assignment, move assignment, + or comparisons between valid values of type ``std::ranges::iterator_t`` and ``std::ranges::sentinel_t``; +- ``-``, ``+``, ``-=``, ``+=``, ``[]`` operators on valid values of type + ``std::ranges::iterator_t`` and ``std::iter_difference_t>``; +- calls to ``std::ranges::begin()``, ``std::ranges::end()`` and ``std::ranges::size()`` + on an object of type ``R``. Whole Sequence Operations +++++++++++++++++++++++++ @@ -564,7 +559,7 @@ Uninitialized Memory Algorithms namespace oneapi::dpl::ranges { // uninitialized_default_construct - template + template requires oneapi::dpl::is_execution_policy_v> && std::ranges::sized_range && std::default_initializable> @@ -572,7 +567,7 @@ Uninitialized Memory Algorithms uninitialized_default_construct (ExecutionPolicy&& pol, R&& r); // uninitialized_value_construct - template + template requires oneapi::dpl::is_execution_policy_v> && std::ranges::sized_range && std::default_initializable> @@ -580,7 +575,7 @@ Uninitialized Memory Algorithms uninitialized_value_construct (ExecutionPolicy&& pol, R&& r, const std::ranges::range_value_t& value); // uninitialized_copy - template + template requires oneapi::dpl::is_execution_policy_v> && std::ranges::sized_range && std::ranges::sized_range && std::constructible_from, std::ranges::range_reference_t> @@ -590,7 +585,7 @@ Uninitialized Memory Algorithms // uninitialized_move template + /*nothrow-random-access-range*/ OR> requires oneapi::dpl::is_execution_policy_v> && std::ranges::sized_range && std::ranges::sized_range && std::constructible_from, std::ranges::range_reference_t> @@ -599,7 +594,7 @@ Uninitialized Memory Algorithms uninitialized_move (ExecutionPolicy&& pol, IR&& in_range, OR&& out_range); // uninitialized_fill - template requires oneapi::dpl::is_execution_policy_v> && std::ranges::sized_range && @@ -608,7 +603,7 @@ Uninitialized Memory Algorithms uninitialized_fill (ExecutionPolicy&& pol, R&& r, const T& value); // destroy - template + template requires oneapi::dpl::is_execution_policy_v> && std::ranges::sized_range && std::destructible> From 8ccc7edba15619189a721d0e2e28a5623a50d518 Mon Sep 17 00:00:00 2001 From: Dmitriy Sobolev Date: Tue, 5 Aug 2025 22:54:28 +0100 Subject: [PATCH 04/10] Fix formatting --- .../elements/oneDPL/source/parallel_api/parallel_range_api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ec2a537b3..b379f253a 100644 --- a/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst +++ b/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst @@ -59,7 +59,7 @@ of parallel range algorithms. std::sized_sentinel_for, std::ranges::iterator_t>; Semantic Requirements -~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~ A type ``R`` models ``nothrow-random-access-range`` if no exceptions are thrown from: From 8323daa4cc3adf9690d18b12357d01d43e3339d1 Mon Sep 17 00:00:00 2001 From: Dmitriy Sobolev Date: Wed, 6 Aug 2025 16:41:01 +0100 Subject: [PATCH 05/10] Add more details about destroy and noexcept --- .../oneDPL/source/parallel_api/parallel_range_api.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 b379f253a..e2b7c5d18 100644 --- a/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst +++ b/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst @@ -33,7 +33,9 @@ The following differences to the standard C++ range algorithms apply: 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. -- ``destroy`` is not marked with ``noexcept``. +- ``destroy`` is not marked with ``noexcept``, unlike how it is specified in the + `P3179R9 `_ + proposal for C++26. Except for these differences, the signatures of parallel range algorithms correspond to the working draft of the next edition of the C++ standard (C++26). From 1316e0fb26239146b592341b23799a93882f3242 Mon Sep 17 00:00:00 2001 From: Dmitriy Sobolev Date: Wed, 6 Aug 2025 16:56:44 +0100 Subject: [PATCH 06/10] range_reference_t -> range_rvalue_reference_t Co-authored-by: Dan Hoeflinger <109972525+danhoeflinger@users.noreply.github.com> --- .../elements/oneDPL/source/parallel_api/parallel_range_api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 e2b7c5d18..0209a8ac9 100644 --- a/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst +++ b/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst @@ -590,7 +590,7 @@ Uninitialized Memory Algorithms /*nothrow-random-access-range*/ OR> requires oneapi::dpl::is_execution_policy_v> && std::ranges::sized_range && std::ranges::sized_range && - std::constructible_from, std::ranges::range_reference_t> + std::constructible_from, std::ranges::range_rvalue_reference_t> std::ranges::uninitialized_move_result, std::ranges::borrowed_iterator_t> uninitialized_move (ExecutionPolicy&& pol, IR&& in_range, OR&& out_range); From f3d2408a4a3d486b30d3f8f33d4a2429066dfe69 Mon Sep 17 00:00:00 2001 From: Dmitriy Sobolev Date: Wed, 6 Aug 2025 17:07:08 +0100 Subject: [PATCH 07/10] Extract iterators in nothrow-random-access-range Co-authored-by: Dan Hoeflinger <109972525+danhoeflinger@users.noreply.github.com> --- .../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 0209a8ac9..987f3c7ae 100644 --- a/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst +++ b/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst @@ -56,8 +56,8 @@ of parallel range algorithms. template concept nothrow-random-access-range = std::ranges::random_access_range && - std::is_lvalue_reference_v> && - std::same_as>, std::iter_value_t> && + std::is_lvalue_reference_v>> && + std::same_as>>, std::iter_value_t>> && std::sized_sentinel_for, std::ranges::iterator_t>; Semantic Requirements From ceffff734b5cab2789dbf0e8b8b5ddaeeff36b88 Mon Sep 17 00:00:00 2001 From: Dmitriy Sobolev Date: Wed, 6 Aug 2025 17:08:53 +0100 Subject: [PATCH 08/10] Formatting --- .../elements/oneDPL/source/parallel_api/parallel_range_api.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 987f3c7ae..33aa814c7 100644 --- a/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst +++ b/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst @@ -57,7 +57,8 @@ of parallel range algorithms. concept nothrow-random-access-range = std::ranges::random_access_range && std::is_lvalue_reference_v>> && - std::same_as>>, std::iter_value_t>> && + std::same_as>>, + std::iter_value_t>> && std::sized_sentinel_for, std::ranges::iterator_t>; Semantic Requirements From 25a162c7d0a668109f0effe1f69c31086ec50098 Mon Sep 17 00:00:00 2001 From: Dmitriy Sobolev Date: Tue, 12 Aug 2025 16:21:32 +0100 Subject: [PATCH 09/10] Remove std::sized_sentinel_for --- .../oneDPL/source/parallel_api/parallel_range_api.rst | 5 ++--- 1 file changed, 2 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 33aa814c7..a31ef36d3 100644 --- a/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst +++ b/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst @@ -58,8 +58,7 @@ of parallel range algorithms. std::ranges::random_access_range && std::is_lvalue_reference_v>> && std::same_as>>, - std::iter_value_t>> && - std::sized_sentinel_for, std::ranges::iterator_t>; + std::iter_value_t>>; Semantic Requirements ~~~~~~~~~~~~~~~~~~~~~ @@ -69,7 +68,7 @@ A type ``R`` models ``nothrow-random-access-range`` if no exceptions are thrown - increment, decrement, copy construction, move construction, copy assignment, move assignment, comparisons or indirection through valid iterators of type ``std::ranges::iterator_t``; - ``-`` operator, copy construction, move construction, copy assignment, move assignment, - or comparisons between valid values of type ``std::ranges::iterator_t`` and ``std::ranges::sentinel_t``; + or comparisons between valid values of type ``std::ranges::iterator_t``; - ``-``, ``+``, ``-=``, ``+=``, ``[]`` operators on valid values of type ``std::ranges::iterator_t`` and ``std::iter_difference_t>``; - calls to ``std::ranges::begin()``, ``std::ranges::end()`` and ``std::ranges::size()`` From 2ceea7e87fd7a0438b4675bc073b2fb1bc8bc64e Mon Sep 17 00:00:00 2001 From: Dmitriy Sobolev Date: Tue, 12 Aug 2025 20:36:59 +0100 Subject: [PATCH 10/10] Compare added destroy with serial interface --- .../oneDPL/source/parallel_api/parallel_range_api.rst | 4 +--- 1 file changed, 1 insertion(+), 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 a31ef36d3..64dbab259 100644 --- a/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst +++ b/source/elements/oneDPL/source/parallel_api/parallel_range_api.rst @@ -33,9 +33,7 @@ The following differences to the standard C++ range algorithms apply: 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. -- ``destroy`` is not marked with ``noexcept``, unlike how it is specified in the - `P3179R9 `_ - proposal for C++26. +- ``destroy`` is not marked with ``noexcept``. Except for these differences, the signatures of parallel range algorithms correspond to the working draft of the next edition of the C++ standard (C++26).