xref: /oneTBB/include/oneapi/tbb/blocked_range2d.h (revision 478de5b1)
1 /*
2     Copyright (c) 2005-2021 Intel Corporation
3 
4     Licensed under the Apache License, Version 2.0 (the "License");
5     you may not use this file except in compliance with the License.
6     You may obtain a copy of the License at
7 
8         http://www.apache.org/licenses/LICENSE-2.0
9 
10     Unless required by applicable law or agreed to in writing, software
11     distributed under the License is distributed on an "AS IS" BASIS,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15 */
16 
17 #ifndef __TBB_blocked_range2d_H
18 #define __TBB_blocked_range2d_H
19 
20 #include <cstddef>
21 
22 #include "detail/_config.h"
23 #include "detail/_namespace_injection.h"
24 #include "detail/_range_common.h"
25 
26 #include "blocked_range.h"
27 
28 namespace tbb {
29 namespace detail {
30 namespace d1 {
31 
32 //! A 2-dimensional range that models the Range concept.
33 /** @ingroup algorithms */
34 template<typename RowValue, typename ColValue = RowValue>
__TBB_requires(blocked_range_value<RowValue> && blocked_range_value<ColValue>)35     __TBB_requires(blocked_range_value<RowValue> &&
36                    blocked_range_value<ColValue>)
37 class blocked_range2d {
38 public:
39     //! Type for size of an iteration range
40     using row_range_type = blocked_range<RowValue>;
41     using col_range_type = blocked_range<ColValue>;
42 
43 private:
44     row_range_type my_rows;
45     col_range_type my_cols;
46 
47 public:
48     blocked_range2d( RowValue row_begin, RowValue row_end, typename row_range_type::size_type row_grainsize,
49                      ColValue col_begin, ColValue col_end, typename col_range_type::size_type col_grainsize ) :
50         my_rows(row_begin,row_end,row_grainsize),
51         my_cols(col_begin,col_end,col_grainsize)
52     {}
53 
54     blocked_range2d( RowValue row_begin, RowValue row_end,
55                      ColValue col_begin, ColValue col_end ) :
56         my_rows(row_begin,row_end),
57         my_cols(col_begin,col_end)
58     {}
59 
60     //! True if range is empty
61     bool empty() const {
62         // Range is empty if at least one dimension is empty.
63         return my_rows.empty() || my_cols.empty();
64     }
65 
66     //! True if range is divisible into two pieces.
67     bool is_divisible() const {
68         return my_rows.is_divisible() || my_cols.is_divisible();
69     }
70 
71     blocked_range2d( blocked_range2d& r, split ) :
72         my_rows(r.my_rows),
73         my_cols(r.my_cols)
74     {
75         split split_obj;
76         do_split(r, split_obj);
77     }
78 
79     blocked_range2d( blocked_range2d& r, proportional_split& proportion ) :
80         my_rows(r.my_rows),
81         my_cols(r.my_cols)
82     {
83         do_split(r, proportion);
84     }
85 
86     //! The rows of the iteration space
87     const row_range_type& rows() const { return my_rows; }
88 
89     //! The columns of the iteration space
90     const col_range_type& cols() const { return my_cols; }
91 
92 private:
93     template <typename Split>
94     void do_split( blocked_range2d& r, Split& split_obj ) {
95         if ( my_rows.size()*double(my_cols.grainsize()) < my_cols.size()*double(my_rows.grainsize()) ) {
96             my_cols.my_begin = col_range_type::do_split(r.my_cols, split_obj);
97         } else {
98             my_rows.my_begin = row_range_type::do_split(r.my_rows, split_obj);
99         }
100     }
101 };
102 
103 } // namespace d1
104 } // namespace detail
105 
106 inline namespace v1 {
107 using detail::d1::blocked_range2d;
108 } // namespace v1
109 } // namespace tbb
110 
111 #endif /* __TBB_blocked_range2d_H */
112