From 39c46a239a4c9b323c96f7498a7e0194808cacab Mon Sep 17 00:00:00 2001 From: tobiasweinzierl80 Date: Tue, 29 Oct 2024 13:16:36 +0000 Subject: [PATCH] Add blocked_nd_range class template (#555) Signed-off-by: Tobias Weinzierl Co-authored-by: Alexey Kukanov Co-authored-by: Johannes Bockhorst Co-authored-by: Alexandra --- source/elements/oneTBB/source/algorithms.rst | 1 + .../blocked_ranges/blocked_nd_range_cls.rst | 179 ++++++++++++++++++ .../split_tags/proportional_split_cls.rst | 1 + .../algorithms/split_tags/split_cls.rst | 1 + .../algorithms/blocked_range_val.rst | 1 + .../named_requirements/algorithms/range.rst | 1 + 6 files changed, 184 insertions(+) create mode 100644 source/elements/oneTBB/source/algorithms/blocked_ranges/blocked_nd_range_cls.rst diff --git a/source/elements/oneTBB/source/algorithms.rst b/source/elements/oneTBB/source/algorithms.rst index 7e90ce5636..278dd1247f 100644 --- a/source/elements/oneTBB/source/algorithms.rst +++ b/source/elements/oneTBB/source/algorithms.rst @@ -39,6 +39,7 @@ Types that meet the :doc:`Range requirements `. + +Unlike ``blocked_range2d`` and ``blocked_range3d``, all dimensions of ``blocked_nd_range`` must be specified +over the same ``Value`` type. The class constructors also differ from those of ``blocked_range2d/3d``. +Different naming patterns indicate the distinction between the classes. +For example, ``blocked_nd_range`` is analogous but not identical to ``blocked_range2d``. + +.. code:: cpp + + namespace oneapi { + namespace tbb { + + template + class blocked_nd_range { + public: + // Types + using value_type = Value; + using dim_range_type = blocked_range; + using size_type = typename dim_range_type::size_type; + + // Constructors + blocked_nd_range(const dim_range_type& dim0 /*, ... - exactly N parameters of the same type*/); + blocked_nd_range(const value_type (&dim_size)[N], size_type grainsize = 1); + blocked_nd_range(blocked_nd_range& r, split); + blocked_nd_range(blocked_nd_range& r, proportional_split proportion); + + // Capacity + static constexpr unsigned int dim_count(); + bool empty() const; + + // Access + bool is_divisible() const; + const dim_range_type& dim(unsigned int dimension) const; + }; + + } // namespace tbb + } // namespace oneapi + +Requirements: + +* ``N`` must be greater than 0. +* The *Value* must meet the :doc:`BlockedRangeValue requirements <../../named_requirements/algorithms/blocked_range_val>`. + +Member types +------------ + +.. code:: cpp + + using value_type = Value; + +The type of the range values. + +.. code:: cpp + + using dim_range_type = blocked_range; + +The type that represents one out of the N dimensions. + +.. code:: cpp + + using size_type = typename dim_range_type::size_type; + +The type for measuring the size of a dimension. + +Member functions +---------------- + +.. code:: cpp + + blocked_nd_range( const dim_range_type& dim0 /*, ... - exactly N parameters of the same type*/ ); + +**Effects:** Constructs a ``blocked_nd_range`` representing an N-dimensional space of values. +The space is the half-open Cartesian product of one-dimensional ranges ``dim0 x ...``. +The constructor must take exactly N arguments, which types match ``const dim_range_type&``. + +**Example:** For ``blocked_nd_range``, this constructor is equivalent to +``blocked_nd_range( const blocked_range&, const blocked_range&, const blocked_range&, const blocked_range& )``. + +.. note:: + This constructor cannot be substituted with a variadic template constructor + ``template blocked_nd_range( const Dims&... dims )``, even if the latter + is constrained by the size and type requirements for the parameter pack ``Dims``. + That is because the types in ``Dims`` could not be automatically deduced from arguments specified as + braced initialization lists, and so expressions like ``blocked_nd_range{{0,1},{0,2},{0,3},{0,4}}`` + would fail to compile. + +.. code:: cpp + + blocked_nd_range( const value_type (&dim_size)[N], size_type grainsize = 1 ); + +**Effects:** Constructs a ``blocked_nd_range`` representing an N-dimensional space of values. +The space is the half-open Cartesian product of ranges ``[0, dim_size[0]) x [0, dim_size[1]) x ...`` +each having the same grain size. + +**Example:** The ``blocked_nd_range r( {5,6,7,8}, 4 );`` statement constructs a four-dimensional +space that contains all value tuples ``(i, j, k, l)``, where ``i`` ranges from 0 (included) +to 5 (excluded) with a grain size of 4, ``j`` ranges from 0 to 6 with a grain size of 4, and so forth. + +.. code:: cpp + + blocked_nd_range( blocked_nd_range& range, split ); + +Basic splitting constructor. + +**Requirements**: ``is_divisible()`` is true. + +**Effects**: Partitions ``range`` into two subranges. The newly constructed ``blocked_nd_range`` is approximately +the half of the original ``range``, and ``range`` is updated to be the remainder. +Splitting is done across one dimension, while other dimensions and the grain sizes for +each subrange remain the same as in the original ``range``. + +.. note:: + It is recommended to split across the dimension with the biggest size-to-grainsize ratio, + so that, after repeated splitting, subranges become of approximately square/cubic/hypercubic shape + if all grain sizes are the same. + +.. code:: cpp + + blocked_nd_range( blocked_nd_range& range, proportional_split proportion ); + +Proportional splitting constructor. + +**Requirements**: ``is_divisible()`` is true. + +**Effects**: Partitions ``range`` into two subranges in the given ``proportion`` across one of its dimensions. +The effect is similar to the basic splitting constructor, except for proportional splitting of the selected +dimension, as specified for :doc:`blocked_range `. +Other dimensions and the grain sizes for each subrange remain the same as in the original ``range``. + +.. code:: cpp + + static constexpr unsigned int dim_count(); + +**Returns:** The number of dimensions set by the class template argument ``N``. + +.. code:: cpp + + bool empty() const; + +**Effects**: Determines if the range is empty. + +**Returns:** True if for any of the range dimensions ``empty()`` is true; false, otherwise. + +.. code:: cpp + + bool is_divisible() const; + +**Effects**: Determines if the range can be split into subranges. + +**Returns:** True if for any of the range dimensions ``is_divisible()`` is true; false, otherwise. + +.. code:: cpp + + const dim_range_type& dim(unsigned int dimension) const; + +**Requirements**: 0 <= ``dimension`` < N. + +**Returns:** ``blocked_range`` containing the value space along the dimension specified by the argument. + +See also: + +* :doc:`blocked_range ` +* :doc:`blocked_range2d ` +* :doc:`blocked_range3d ` + diff --git a/source/elements/oneTBB/source/algorithms/split_tags/proportional_split_cls.rst b/source/elements/oneTBB/source/algorithms/split_tags/proportional_split_cls.rst index af82f48c1c..b3e95ec529 100644 --- a/source/elements/oneTBB/source/algorithms/split_tags/proportional_split_cls.rst +++ b/source/elements/oneTBB/source/algorithms/split_tags/proportional_split_cls.rst @@ -19,6 +19,7 @@ the class should be split. // Defined in header // Defined in header // Defined in header + // Defined in header // Defined in header // Defined in header // Defined in header diff --git a/source/elements/oneTBB/source/algorithms/split_tags/split_cls.rst b/source/elements/oneTBB/source/algorithms/split_tags/split_cls.rst index ed1504584e..bc78c68d45 100644 --- a/source/elements/oneTBB/source/algorithms/split_tags/split_cls.rst +++ b/source/elements/oneTBB/source/algorithms/split_tags/split_cls.rst @@ -15,6 +15,7 @@ An argument of type ``split`` is used to distinguish a splitting constructor fro // Defined in header // Defined in header // Defined in header + // Defined in header // Defined in header // Defined in header // Defined in header diff --git a/source/elements/oneTBB/source/named_requirements/algorithms/blocked_range_val.rst b/source/elements/oneTBB/source/named_requirements/algorithms/blocked_range_val.rst index afb1d78a65..582ba95c20 100644 --- a/source/elements/oneTBB/source/named_requirements/algorithms/blocked_range_val.rst +++ b/source/elements/oneTBB/source/named_requirements/algorithms/blocked_range_val.rst @@ -52,5 +52,6 @@ See also: * :doc:`blocked_range class <../../algorithms/blocked_ranges/blocked_range_cls>` * :doc:`blocked_range2d class <../../algorithms/blocked_ranges/blocked_range2d_cls>` * :doc:`blocked_range3d class <../../algorithms/blocked_ranges/blocked_range3d_cls>` +* :doc:`blocked_nd_range class <../../algorithms/blocked_ranges/blocked_nd_range_cls>` * :doc:`parallel_reduce algorithm <../../algorithms/functions/parallel_reduce_func>` * :doc:`parallel_for algorithm <../../algorithms/functions/parallel_for_func>` diff --git a/source/elements/oneTBB/source/named_requirements/algorithms/range.rst b/source/elements/oneTBB/source/named_requirements/algorithms/range.rst index bfa02052f5..4a43e60d5d 100644 --- a/source/elements/oneTBB/source/named_requirements/algorithms/range.rst +++ b/source/elements/oneTBB/source/named_requirements/algorithms/range.rst @@ -69,6 +69,7 @@ See also: * :doc:`blocked_range class <../../algorithms/blocked_ranges/blocked_range_cls>` * :doc:`blocked_range2d class <../../algorithms/blocked_ranges/blocked_range2d_cls>` * :doc:`blocked_range3d class <../../algorithms/blocked_ranges/blocked_range3d_cls>` +* :doc:`blocked_nd_range class <../../algorithms/blocked_ranges/blocked_nd_range_cls>` * :doc:`parallel_reduce algorithm <../../algorithms/functions/parallel_reduce_func>` * :doc:`parallel_for algorithm <../../algorithms/functions/parallel_for_func>` * :doc:`split class <../../algorithms/split_tags/split_cls>`