Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[onedpl][ranges][doc] + Range-based API description #1596

Merged
merged 38 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
976dbb8
[onedpl][doc] + Range-based API description
MikeDvorskiy May 21, 2024
1c38faa
[oneDPL][doc] + introduction for oneapi::dpl::ext::ranges
MikeDvorskiy May 21, 2024
525a3ca
[onedpl][doc][ranges] + supported std ranges description
MikeDvorskiy May 21, 2024
daa301e
[onedpl][doc][ranges] + algo list
MikeDvorskiy May 21, 2024
8594c37
[onedpl][doc][ranges] + minor change in the wording
MikeDvorskiy May 21, 2024
e712352
[oneDPL][doc][ranges] + changes in the wording
MikeDvorskiy May 21, 2024
dcb74e4
[onedpl][doc][ranges] + wording about ranges support in "Pass Data.."…
MikeDvorskiy May 21, 2024
3931b76
[onedpl][doc][ranges] + minor changes in formatting
MikeDvorskiy May 21, 2024
5f3b885
[onedpl][doc][ranges] + example
MikeDvorskiy May 21, 2024
56ffa81
[oneDPL][doc][ranges] minor change in an example
MikeDvorskiy May 21, 2024
a661f97
[oneDPL][doc][ranges] views::reverse() => views::reverse
MikeDvorskiy May 21, 2024
15bc630
[oneDPL][doc][ranges] + minor change in an exemlple
MikeDvorskiy May 21, 2024
9d6a770
[oneDPL][doc][ranges] + minor change in Parallel API topic
MikeDvorskiy May 21, 2024
47368f0
+ fix a typo
MikeDvorskiy May 22, 2024
d0cb76d
+ fix a typo
MikeDvorskiy May 22, 2024
3b77301
+ fix a typo
MikeDvorskiy May 22, 2024
96b0558
[oneDPL][ranges][doc] minor changes
MikeDvorskiy Jul 17, 2024
358ddb3
Merge branch 'main' into std_ranges_support_as_ext
akukanov Sep 10, 2024
6f30bb7
Split experimental and production APIs into separate pages
akukanov Sep 10, 2024
ed18aba
Add missed backquotes, split long lines
akukanov Sep 11, 2024
5a67152
Add a short description to the Parallel API page
akukanov Sep 12, 2024
9aab1a4
Reworked the new page for range algorithms
akukanov Sep 13, 2024
8a63b1c
Rework the page for experimental range APIs
akukanov Sep 13, 2024
d9b06e6
Merge branch 'main' into std_ranges_support_as_ext
akukanov Sep 13, 2024
5d270e9
Address review feedback
akukanov Sep 13, 2024
07d3c99
Address feedback to a previous documentation patch
akukanov Sep 13, 2024
724b0ad
Consistently use angle brackets around header file names
akukanov Sep 14, 2024
bf80964
Fix the exanples
akukanov Sep 16, 2024
e31aaf7
Reorganize the page on data passing, add information for range algori…
akukanov Sep 16, 2024
58118a9
Fix labels, address feedback
akukanov Sep 16, 2024
4d951e8
Fix rendering and improve code examples
akukanov Sep 16, 2024
f776759
Refer to host policies as standard-aligned almost everywhere
akukanov Sep 16, 2024
7bf3c17
Add another note and a cross-reference from 'Parallel range algorithms'
akukanov Sep 16, 2024
85b2029
Avoid the `USM memory' tautology
akukanov Sep 16, 2024
6cd8a4e
Reduce ambiguity between host memory and host-allocated USM
akukanov Sep 17, 2024
6d00f35
Fix a typo
akukanov Sep 17, 2024
ed681eb
Fix rendering
akukanov Sep 17, 2024
64f9f63
Address review comments
akukanov Sep 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,17 @@ of vector elements. Some implementations may optimize multiple ``bool`` elements
for multithreading. For this reason, it is recommended to avoid ``std::vector<bool>`` for anything but a read-only
input with the C++ standard execution policies.

When using a host execution policy, you can use one of the following ways to pass data to an algorithm:
dmitriy-sobolev marked this conversation as resolved.
Show resolved Hide resolved

* The host-side iterators and pointers
MikeDvorskiy marked this conversation as resolved.
Show resolved Hide resolved
* The random access standard factories and adapters on top of the factories, random access containers, ``std::ranges::subrange`` and ``std::span`` on top of host-side pointers and iterators.
MikeDvorskiy marked this conversation as resolved.
Show resolved Hide resolved

When using a device execution policy, you can use one of the following ways to pass data to an algorithm:

* ``oneapi:dpl::begin`` and ``oneapi::dpl::end`` functions
* Unified shared memory (USM) pointers
* ``std::vector`` with or without a USM allocator
* The random access standard factories and adapters on top of the factories, ``std::vector`` with USM allocator, ``std::ranges::subrange`` and ``std::span`` on top of USM pointers.
MikeDvorskiy marked this conversation as resolved.
Show resolved Hide resolved

.. _use-buffer-wrappers:

Expand Down Expand Up @@ -158,4 +164,4 @@ combination with ``std::vector::size()`` as shown in the example above, rather t
``std::vector``. That is because for some implementations of the C++ Standard Library it might not
be possible for |onedpl_short| to detect that iterators are pointing to USM-allocated data. In that
case the data will be treated as if it were host-allocated, with an extra copy made to a SYCL buffer.
Retrieving USM pointers from ``std::vector`` as shown guarantees no unintended copying.
Retrieving USM pointers from ``std::vector`` as shown guarantees no unintended copying.
127 changes: 101 additions & 26 deletions documentation/library_guide/parallel_api/range_based_api.rst
Original file line number Diff line number Diff line change
@@ -1,15 +1,107 @@
Range-Based API Algorithms
##########################
.. Note::

The use of the range-based API requires C++17 and the C++ standard libraries coming with GCC 8.1 (or higher)
or Clang 7 (or higher).

C++20 introduces the Ranges library. C++20 standard splits ranges into two categories: factories and adaptors.
A range factory does not have underlying data. An element is generated on success by an index or by dereferencing an iterator.
A range adaptor, from the |onedpl_long| (|onedpl_short|) perspective, is a utility that transforms the base range,
or another adapted range, into a view with custom behavior.

|onedpl_short| supports just random access ranges, because they allow efficient and constant-time access to elements at any position in the range. This enables effective workload distribution among multiple threads or processing units, which is crucial for achieving high performance in parallel execution.
MikeDvorskiy marked this conversation as resolved.
Show resolved Hide resolved

|onedpl_short| introduces two set of range based algorithms:
MikeDvorskiy marked this conversation as resolved.
Show resolved Hide resolved

* The oneapi::dpl::ext::ranges namespace supports integration with the Ranges Library coming with C++20 standard and introduced by std::ranges namespace, allowing you to leverage oneDPL parallel algorithms with the standard ranges paradigm. The functionality is implemented for the host and the device execution policies and requires C++20.
akukanov marked this conversation as resolved.
Show resolved Hide resolved
akukanov marked this conversation as resolved.
Show resolved Hide resolved
akukanov marked this conversation as resolved.
Show resolved Hide resolved
* The oneapi::dpl::experimental::ranges namespace supports integration with oneDPL ranges introducing by oneapi::dpl::experimental::ranges namespace, allowing you to leverage oneDPL parallel algorithms with the range functionality like the Ranges Library from C++20 standard. The functionality is implemented for the device execution policies only and requires C++17.
akukanov marked this conversation as resolved.
Show resolved Hide resolved
akukanov marked this conversation as resolved.
Show resolved Hide resolved

.. Note::

The use of the oneapi::dpl::ext::ranges requires C++20 and the C++ standard libraries coming with GCC 10 (or higher) or Clang 10 (or higher).
akukanov marked this conversation as resolved.
Show resolved Hide resolved
akukanov marked this conversation as resolved.
Show resolved Hide resolved
akukanov marked this conversation as resolved.
Show resolved Hide resolved
mmichel11 marked this conversation as resolved.
Show resolved Hide resolved
akukanov marked this conversation as resolved.
Show resolved Hide resolved
The use of the oneapi::dpl::experimental::ranges requires C++17 and the C++ standard libraries coming with GCC 8.1 (or higher) or Clang 7 (or higher).
akukanov marked this conversation as resolved.
Show resolved Hide resolved


Range-Based API (The standard C++ Ranges Library)
akukanov marked this conversation as resolved.
Show resolved Hide resolved
-------------------------------------------------

The following C++ standard random access adaptors and factories are supported with the oneDPL parallel algorithms:

* ``std::ranges::views::all``: A range adaptor object that returns a view that includes all elements of its range argument.
* ``std::ranges::iota_view``: A range factory that generates a sequence of N elements, which starts from an initial value and ends by final N-1.
* ``std::ranges::single_view``: A view that contains exactly one element of a specified value.
* ``std::ranges::subrange``: A utility that combines together an iterator and a sentinel into a single object that models a view.
akukanov marked this conversation as resolved.
Show resolved Hide resolved
* ``std::ranges::transform_view``: A range adapter that represents a view of a underlying sequence after applying a transformation to each element.
* ``std::ranges::reverse_view``: A range adapter that produces a reversed sequence of elements provided by another view.
* ``std::ranges::take_view``: A range adapter that produces a view of the first N elements from another view.
* ``std::ranges::drop_view``: A range adapter that produces a view excluding the first N elements from another view.

The following algorithms are available in the oneapi::dpl::ext::ranges namespace to use with the mentioned standard ranges:
akukanov marked this conversation as resolved.
Show resolved Hide resolved
akukanov marked this conversation as resolved.
Show resolved Hide resolved

* ``for_each``
akukanov marked this conversation as resolved.
Show resolved Hide resolved
* ``transform``
akukanov marked this conversation as resolved.
Show resolved Hide resolved
* ``find``
* ``find_if``
* ``find_if_not``
* ``all_of``
* ``any_of``
* ``none_of``
* ``adjacent_find``
* ``search``
* ``search_n``
* ``count_if``
* ``count``
* ``equal``
* ``sort``
* ``stable_sort``
* ``is_sorted``
* ``min_element``
* ``max_element``
* ``copy``
* ``copy_if``
* ``merge``

Example of Range-Based API Usage (The standard C++ Ranges Library)
MikeDvorskiy marked this conversation as resolved.
Show resolved Hide resolved
------------------------------------------------------------------

.. code:: cpp

using namespace oneapi::dpl::ext::ranges;

{
std::vector<int> vec_in = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
std::vector<int> vec_out(vec_in.size());

auto view_in = std::ranges::views::all(vec_in) | std::ranges::views::reverse;
copy(oneapi::dpl::execution::par, view_in, vec_out);
}
{
using shared_allocator = sycl::usm_allocator<int, sycl::usm::alloc::shared>;

std::vector<int, shared_allocator> vec_in = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
std::vector<int, shared_allocator> vec_out(vec_in.size());

auto view_in = std::ranges::subrange(vec_in.begin(), vec_in.end()) | std::ranges::views::reverse;
copy(oneapi::dpl::execution::dpcpp_default, view_in, std::span(vec_out));
}

Experimental Range-Based API (The oneDPL ranges)
MikeDvorskiy marked this conversation as resolved.
Show resolved Hide resolved
------------------------------------------------

The following viewable ranges are declared in the ``oneapi::dpl::experimental::ranges`` namespace.
Only the ranges shown below and ``sycl::buffer`` are available as ranges for range-based algorithms.
akukanov marked this conversation as resolved.
Show resolved Hide resolved

.. _viewable-ranges:

* ``views::iota``: A range factory that generates a sequence of N elements, which starts from an initial value and ends by final N-1.
* ``views::all``: A custom utility that represents a view of all or a part of ``sycl::buffer`` underlying elements for reading and writing on a device.
* ``views::all_read``: A custom utility that represents a view of all or a part of ``sycl::buffer`` underlying elements for reading on a device.
* ``views::all_write``: A custom utility that represents a view of all or a part of ``sycl::buffer`` underlying elements for writing on a device.
* ``views::host_all``: A custom utility that represents a view of all or a part of ``sycl::buffer`` underlying elements for reading and writing on the host.
* ``views::subrange``: A utility that represents a view of unified shared memory (USM) data range defined by a two USM pointers.
* ``views::zip``: A custom range adapter that produces one ``zip_view`` from other several views.
* ``views::transform``: A range adapter that represents a view of a underlying sequence after applying a transformation to each element.
* ``views::reverse``: A range adapter that produces a reversed sequence of elements provided by another view.
* ``views::take``: A range adapter that produces a view of the first N elements from another view.
* ``views::drop``: A range adapter that produces a view excluding the first N elements from another view.

|onedpl_short| supports an ``iota_view`` range factory.

A ``sycl::buffer`` wrapped with ``all_view`` can be used as the range.
Expand All @@ -20,8 +112,8 @@ The range adaptors may be combined into a pipeline with a ``base`` range at the
.. code:: cpp

sycl::buffer<int> buf(data, sycl::range<1>(10));
auto range_1 = iota_view(0, 10) | views::reverse();
auto range_2 = all_view(buf) | views::reverse();
auto range_1 = iota_view(0, 10) | views::reverse;
auto range_2 = all_view(buf) | views::reverse;

For the range, based on the ``all_view`` factory, data access is permitted on a device only. ``size()`` and ``empty()`` methods are allowed
to be called on both host and device.
Expand Down Expand Up @@ -89,25 +181,8 @@ These algorithms are declared in the ``oneapi::dpl::experimental::ranges`` names
To make these algorithms available, the ``<oneapi/dpl/ranges>`` header should be included (after ``<oneapi/dpl/execution>``).
Use of the range-based API requires C++17 and the C++ standard libraries that come with GCC 8.1 (or higher) or Clang 7 (or higher).

The following viewable ranges are declared in the ``oneapi::dpl::experimental::ranges`` namespace.
Only the ranges shown below and ``sycl::buffer`` are available as ranges for range-based algorithms.

.. _viewable-ranges:

* ``views::iota``: A range factory that generates a sequence of N elements, which starts from an initial value and ends by final N-1.
* ``views::all``: A custom utility that represents a view of all or a part of ``sycl::buffer`` underlying elements for reading and writing on a device.
* ``views::all_read``: A custom utility that represents a view of all or a part of ``sycl::buffer`` underlying elements for reading on a device.
* ``views::all_write``: A custom utility that represents a view of all or a part of ``sycl::buffer`` underlying elements for writing on a device.
* ``views::host_all``: A custom utility that represents a view of all or a part of ``sycl::buffer`` underlying elements for reading and writing on the host.
* ``views::subrange``: A utility that represents a view of unified shared memory (USM) data range defined by a two USM pointers.
* ``views::zip``: A custom range adapter that produces one ``zip_view`` from other several views.
* ``views::transform``: A range adapter that represents a view of a underlying sequence after applying a transformation to each element.
* ``views::reverse``: A range adapter that produces a reversed sequence of elements provided by another view.
* ``views::take``: A range adapter that produces a view of the first N elements from another view.
* ``views::drop``: A range adapter that produces a view excluding the first N elements from another view.

Example of Range-Based API Usage
--------------------------------
Example of Range-Based API Usage (The oneDPL ranges)
MikeDvorskiy marked this conversation as resolved.
Show resolved Hide resolved
----------------------------------------------------

.. code:: cpp

Expand All @@ -117,7 +192,7 @@ Example of Range-Based API Usage
sycl::buffer<int> A(data, sycl::range<1>(max_n));
sycl::buffer<int> B(data2, sycl::range<1>(max_n));

auto view = all_view(A) | views::reverse();
auto view = all_view(A) | views::reverse;
auto range_res = all_view<int, sycl::access::mode::write>(B);

copy(oneapi::dpl::execution::dpcpp_default, view, range_res);
Expand Down
1 change: 1 addition & 0 deletions documentation/library_guide/parallel_api_main.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ provides specific versions of the algorithms, including:
* Segmented reduce
* Segmented scan
* Vectorized search algorithms
* Range-based API versions of the algorithms

Parallel API offers support for the parallel and vectorized execution of algorithms on Intel®
processors and heterogeneity support with a DPC++ based implementation for device execution policies.
Expand Down
Loading