Skip to content

Commit 39c46a2

Browse files
tobiasweinzierl80akukanovsasalla23aepanchi
authored
Add blocked_nd_range class template (#555)
Signed-off-by: Tobias Weinzierl <[email protected]> Co-authored-by: Alexey Kukanov <[email protected]> Co-authored-by: Johannes Bockhorst <[email protected]> Co-authored-by: Alexandra <[email protected]>
1 parent 73f1aff commit 39c46a2

File tree

6 files changed

+184
-0
lines changed

6 files changed

+184
-0
lines changed

source/elements/oneTBB/source/algorithms.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Types that meet the :doc:`Range requirements <named_requirements/algorithms/rang
3939
algorithms/blocked_ranges/blocked_range_cls.rst
4040
algorithms/blocked_ranges/blocked_range2d_cls.rst
4141
algorithms/blocked_ranges/blocked_range3d_cls.rst
42+
algorithms/blocked_ranges/blocked_nd_range_cls.rst
4243

4344
.. _Partitioners:
4445

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
.. SPDX-FileCopyrightText: 2019-2024 Intel Corporation
2+
.. SPDX-FileCopyrightText: Contributors to the oneAPI Specification project.
3+
..
4+
.. SPDX-License-Identifier: CC-BY-4.0
5+
6+
================
7+
blocked_nd_range
8+
================
9+
**[algorithms.blocked_nd_range]**
10+
11+
Class template that represents a recursively divisible N-dimensional half-open interval.
12+
13+
A ``blocked_nd_range`` is the N-dimensional extension of ``blocked_range``.
14+
You can interpret it as a Cartesian product of N instances of ``blocked_range``.
15+
It meets the :doc:`Range requirements <../../named_requirements/algorithms/range>`.
16+
17+
Unlike ``blocked_range2d`` and ``blocked_range3d``, all dimensions of ``blocked_nd_range`` must be specified
18+
over the same ``Value`` type. The class constructors also differ from those of ``blocked_range2d/3d``.
19+
Different naming patterns indicate the distinction between the classes.
20+
For example, ``blocked_nd_range<int,2>`` is analogous but not identical to ``blocked_range2d<int,int>``.
21+
22+
.. code:: cpp
23+
24+
namespace oneapi {
25+
namespace tbb {
26+
27+
template<typename Value, unsigned int N>
28+
class blocked_nd_range {
29+
public:
30+
// Types
31+
using value_type = Value;
32+
using dim_range_type = blocked_range<value_type>;
33+
using size_type = typename dim_range_type::size_type;
34+
35+
// Constructors
36+
blocked_nd_range(const dim_range_type& dim0 /*, ... - exactly N parameters of the same type*/);
37+
blocked_nd_range(const value_type (&dim_size)[N], size_type grainsize = 1);
38+
blocked_nd_range(blocked_nd_range& r, split);
39+
blocked_nd_range(blocked_nd_range& r, proportional_split proportion);
40+
41+
// Capacity
42+
static constexpr unsigned int dim_count();
43+
bool empty() const;
44+
45+
// Access
46+
bool is_divisible() const;
47+
const dim_range_type& dim(unsigned int dimension) const;
48+
};
49+
50+
} // namespace tbb
51+
} // namespace oneapi
52+
53+
Requirements:
54+
55+
* ``N`` must be greater than 0.
56+
* The *Value* must meet the :doc:`BlockedRangeValue requirements <../../named_requirements/algorithms/blocked_range_val>`.
57+
58+
Member types
59+
------------
60+
61+
.. code:: cpp
62+
63+
using value_type = Value;
64+
65+
The type of the range values.
66+
67+
.. code:: cpp
68+
69+
using dim_range_type = blocked_range<value_type>;
70+
71+
The type that represents one out of the N dimensions.
72+
73+
.. code:: cpp
74+
75+
using size_type = typename dim_range_type::size_type;
76+
77+
The type for measuring the size of a dimension.
78+
79+
Member functions
80+
----------------
81+
82+
.. code:: cpp
83+
84+
blocked_nd_range( const dim_range_type& dim0 /*, ... - exactly N parameters of the same type*/ );
85+
86+
**Effects:** Constructs a ``blocked_nd_range`` representing an N-dimensional space of values.
87+
The space is the half-open Cartesian product of one-dimensional ranges ``dim0 x ...``.
88+
The constructor must take exactly N arguments, which types match ``const dim_range_type&``.
89+
90+
**Example:** For ``blocked_nd_range<int,4>``, this constructor is equivalent to
91+
``blocked_nd_range( const blocked_range<int>&, const blocked_range<int>&, const blocked_range<int>&, const blocked_range<int>& )``.
92+
93+
.. note::
94+
This constructor cannot be substituted with a variadic template constructor
95+
``template <typename... Dims> blocked_nd_range( const Dims&... dims )``, even if the latter
96+
is constrained by the size and type requirements for the parameter pack ``Dims``.
97+
That is because the types in ``Dims`` could not be automatically deduced from arguments specified as
98+
braced initialization lists, and so expressions like ``blocked_nd_range<int,4>{{0,1},{0,2},{0,3},{0,4}}``
99+
would fail to compile.
100+
101+
.. code:: cpp
102+
103+
blocked_nd_range( const value_type (&dim_size)[N], size_type grainsize = 1 );
104+
105+
**Effects:** Constructs a ``blocked_nd_range`` representing an N-dimensional space of values.
106+
The space is the half-open Cartesian product of ranges ``[0, dim_size[0]) x [0, dim_size[1]) x ...``
107+
each having the same grain size.
108+
109+
**Example:** The ``blocked_nd_range<int,4> r( {5,6,7,8}, 4 );`` statement constructs a four-dimensional
110+
space that contains all value tuples ``(i, j, k, l)``, where ``i`` ranges from 0 (included)
111+
to 5 (excluded) with a grain size of 4, ``j`` ranges from 0 to 6 with a grain size of 4, and so forth.
112+
113+
.. code:: cpp
114+
115+
blocked_nd_range( blocked_nd_range& range, split );
116+
117+
Basic splitting constructor.
118+
119+
**Requirements**: ``is_divisible()`` is true.
120+
121+
**Effects**: Partitions ``range`` into two subranges. The newly constructed ``blocked_nd_range`` is approximately
122+
the half of the original ``range``, and ``range`` is updated to be the remainder.
123+
Splitting is done across one dimension, while other dimensions and the grain sizes for
124+
each subrange remain the same as in the original ``range``.
125+
126+
.. note::
127+
It is recommended to split across the dimension with the biggest size-to-grainsize ratio,
128+
so that, after repeated splitting, subranges become of approximately square/cubic/hypercubic shape
129+
if all grain sizes are the same.
130+
131+
.. code:: cpp
132+
133+
blocked_nd_range( blocked_nd_range& range, proportional_split proportion );
134+
135+
Proportional splitting constructor.
136+
137+
**Requirements**: ``is_divisible()`` is true.
138+
139+
**Effects**: Partitions ``range`` into two subranges in the given ``proportion`` across one of its dimensions.
140+
The effect is similar to the basic splitting constructor, except for proportional splitting of the selected
141+
dimension, as specified for :doc:`blocked_range <blocked_range_cls>`.
142+
Other dimensions and the grain sizes for each subrange remain the same as in the original ``range``.
143+
144+
.. code:: cpp
145+
146+
static constexpr unsigned int dim_count();
147+
148+
**Returns:** The number of dimensions set by the class template argument ``N``.
149+
150+
.. code:: cpp
151+
152+
bool empty() const;
153+
154+
**Effects**: Determines if the range is empty.
155+
156+
**Returns:** True if for any of the range dimensions ``empty()`` is true; false, otherwise.
157+
158+
.. code:: cpp
159+
160+
bool is_divisible() const;
161+
162+
**Effects**: Determines if the range can be split into subranges.
163+
164+
**Returns:** True if for any of the range dimensions ``is_divisible()`` is true; false, otherwise.
165+
166+
.. code:: cpp
167+
168+
const dim_range_type& dim(unsigned int dimension) const;
169+
170+
**Requirements**: 0 <= ``dimension`` < N.
171+
172+
**Returns:** ``blocked_range`` containing the value space along the dimension specified by the argument.
173+
174+
See also:
175+
176+
* :doc:`blocked_range <blocked_range_cls>`
177+
* :doc:`blocked_range2d <blocked_range2d_cls>`
178+
* :doc:`blocked_range3d <blocked_range3d_cls>`
179+

source/elements/oneTBB/source/algorithms/split_tags/proportional_split_cls.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ the class should be split.
1919
// Defined in header <oneapi/tbb/blocked_range.h>
2020
// Defined in header <oneapi/tbb/blocked_range2d.h>
2121
// Defined in header <oneapi/tbb/blocked_range3d.h>
22+
// Defined in header <oneapi/tbb/blocked_nd_range.h>
2223
// Defined in header <oneapi/tbb/partitioner.h>
2324
// Defined in header <oneapi/tbb/parallel_for.h>
2425
// Defined in header <oneapi/tbb/parallel_reduce.h>

source/elements/oneTBB/source/algorithms/split_tags/split_cls.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ An argument of type ``split`` is used to distinguish a splitting constructor fro
1515
// Defined in header <oneapi/tbb/blocked_range.h>
1616
// Defined in header <oneapi/tbb/blocked_range2d.h>
1717
// Defined in header <oneapi/tbb/blocked_range3d.h>
18+
// Defined in header <oneapi/tbb/blocked_nd_range.h>
1819
// Defined in header <oneapi/tbb/partitioner.h>
1920
// Defined in header <oneapi/tbb/parallel_for.h>
2021
// Defined in header <oneapi/tbb/parallel_reduce.h>

source/elements/oneTBB/source/named_requirements/algorithms/blocked_range_val.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,6 @@ See also:
5252
* :doc:`blocked_range class <../../algorithms/blocked_ranges/blocked_range_cls>`
5353
* :doc:`blocked_range2d class <../../algorithms/blocked_ranges/blocked_range2d_cls>`
5454
* :doc:`blocked_range3d class <../../algorithms/blocked_ranges/blocked_range3d_cls>`
55+
* :doc:`blocked_nd_range class <../../algorithms/blocked_ranges/blocked_nd_range_cls>`
5556
* :doc:`parallel_reduce algorithm <../../algorithms/functions/parallel_reduce_func>`
5657
* :doc:`parallel_for algorithm <../../algorithms/functions/parallel_for_func>`

source/elements/oneTBB/source/named_requirements/algorithms/range.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ See also:
6969
* :doc:`blocked_range class <../../algorithms/blocked_ranges/blocked_range_cls>`
7070
* :doc:`blocked_range2d class <../../algorithms/blocked_ranges/blocked_range2d_cls>`
7171
* :doc:`blocked_range3d class <../../algorithms/blocked_ranges/blocked_range3d_cls>`
72+
* :doc:`blocked_nd_range class <../../algorithms/blocked_ranges/blocked_nd_range_cls>`
7273
* :doc:`parallel_reduce algorithm <../../algorithms/functions/parallel_reduce_func>`
7374
* :doc:`parallel_for algorithm <../../algorithms/functions/parallel_for_func>`
7475
* :doc:`split class <../../algorithms/split_tags/split_cls>`

0 commit comments

Comments
 (0)