14
14
15
15
namespace simsycl ::detail {
16
16
17
+ enum class group_type { nd_range, hierarchical_implicit_size, hierarchical_explicit_size };
18
+
17
19
template <int Dimensions>
18
- sycl::group<Dimensions> make_group (const sycl::item<Dimensions, false > &local_item,
20
+ sycl::group<Dimensions> make_group (const group_type type, const sycl::item<Dimensions, false > &local_item,
19
21
const sycl::item<Dimensions, true > &global_item, const sycl::item<Dimensions, false > &group_item,
20
22
detail::concurrent_group *impl) {
21
- return sycl::group<Dimensions>(local_item, global_item, group_item, impl);
22
- }
23
-
24
- template <int Dimensions>
25
- sycl::group<Dimensions> make_hierarchical_group (const sycl::item<Dimensions, false > &group_item,
26
- const std::optional<sycl::range<Dimensions>> &hier_local_range, detail::concurrent_group *impl) {
27
- return sycl::group<Dimensions>(group_item, hier_local_range, impl);
23
+ return sycl::group<Dimensions>(type, local_item, global_item, group_item, impl);
28
24
}
29
25
30
26
template <int Dimensions>
31
- bool is_hierarchical_group (const sycl::group<Dimensions> &g) {
32
- return g.m_hierarchical ;
27
+ group_type get_group_type (const sycl::group<Dimensions> &g) {
28
+ return g.m_type ;
33
29
}
34
30
35
- template <typename G>
31
+ template <typename G, int Dimensions >
36
32
class hierarchical_group_size_setter {
37
33
public:
38
- hierarchical_group_size_setter (G &g, size_t size) : m_g(g) {
39
- m_old_size = get_concurrent_group (m_g).cur_hier_local_size ;
40
- get_concurrent_group (m_g).cur_hier_local_size = size;
34
+ hierarchical_group_size_setter (G &g, sycl::range<Dimensions> flexible_size)
35
+ : m_g(g), m_old_local_item(g.m_local_item), m_old_global_item(g.m_global_item) {
36
+ g.m_local_item = simsycl::detail::make_item (sycl::id<Dimensions>(), flexible_size);
37
+ g.m_global_item
38
+ = simsycl::detail::make_item (sycl::id<Dimensions>(), g.m_group_item .get_range () * flexible_size);
41
39
}
42
40
43
- ~hierarchical_group_size_setter () { get_concurrent_group (m_g).cur_hier_local_size = m_old_size; }
41
+ ~hierarchical_group_size_setter () {
42
+ m_g.m_local_item = m_old_local_item;
43
+ m_g.m_global_item = m_old_global_item;
44
+ }
44
45
45
46
private:
46
47
G &m_g;
47
- size_t m_old_size;
48
+ sycl::item<Dimensions, false > m_old_local_item;
49
+ sycl::item<Dimensions, true > m_old_global_item;
48
50
};
49
51
50
52
} // namespace simsycl::detail
@@ -79,53 +81,35 @@ class group {
79
81
80
82
size_t get_group_id (int dimension) const { return m_group_item.get_id ()[dimension]; }
81
83
82
- SIMSYCL_DETAIL_DEPRECATED_IN_SYCL range<Dimensions> get_global_range () const {
84
+ [[deprecated( " non-standard " )]] range<Dimensions> get_global_range () const {
83
85
SIMSYCL_CHECK (
84
- !m_hierarchical && " get_global_range is not supported for from within a parallel_for_work_item context " );
86
+ m_global_item. get_range (). size () != 0 && " get_global_range called from hierarchical group scope? " );
85
87
return m_global_item.get_range ();
86
88
}
87
89
88
- size_t get_global_range (int dimension) const {
89
- SIMSYCL_CHECK (
90
- !m_hierarchical && " get_global_range is not supported for from within a parallel_for_work_item context" );
90
+ [[deprecated(" non-standard" )]] size_t get_global_range (int dimension) const {
91
91
return get_global_range ()[dimension];
92
92
}
93
93
94
94
id_type get_local_id () const {
95
- SIMSYCL_CHECK (
96
- !m_hierarchical && " get_local_id is not supported for from within a parallel_for_work_item context" );
95
+ SIMSYCL_CHECK (m_type == detail::group_type::nd_range
96
+ && " get_local_id is not supported for from within a parallel_for_work_item context" );
97
97
return m_local_item.get_id ();
98
98
}
99
99
100
- size_t get_local_id (int dimension) const {
101
- SIMSYCL_CHECK (
102
- !m_hierarchical && " get_local_id is not supported for from within a parallel_for_work_item context" );
103
- return get_local_id ()[dimension];
104
- }
100
+ size_t get_local_id (int dimension) const { return get_local_id ()[dimension]; }
105
101
106
102
size_t get_local_linear_id () const {
107
- SIMSYCL_CHECK (
108
- !m_hierarchical && " get_local_linear_id is not supported for from within a parallel_for_work_item context" );
103
+ SIMSYCL_CHECK (m_type == detail::group_type::nd_range
104
+ && " get_local_linear_id is not supported for from within a parallel_for_work_item context" );
109
105
return m_local_item.get_linear_id ();
110
106
}
111
107
112
- range_type get_local_range () const {
113
- SIMSYCL_CHECK (
114
- !m_hierarchical && " get_local_range is not supported for from within a parallel_for_work_item context" );
115
- return m_local_item.get_range ();
116
- }
108
+ range_type get_local_range () const { return m_local_item.get_range (); }
117
109
118
- size_t get_local_range (int dimension) const {
119
- SIMSYCL_CHECK (
120
- !m_hierarchical && " get_local_range is not supported for from within a parallel_for_work_item context" );
121
- return get_local_range ()[dimension];
122
- }
110
+ size_t get_local_range (int dimension) const { return get_local_range ()[dimension]; }
123
111
124
- size_t get_local_linear_range () const {
125
- SIMSYCL_CHECK (
126
- !m_hierarchical && " get_local_range is not supported for from within a parallel_for_work_item context" );
127
- return get_local_range ().size ();
128
- }
112
+ size_t get_local_linear_range () const { return get_local_range ().size (); }
129
113
130
114
range_type get_group_range () const { return m_group_item.get_range (); }
131
115
@@ -144,26 +128,27 @@ class group {
144
128
size_t get_group_linear_id () const { return m_group_item.get_linear_id (); }
145
129
146
130
bool leader () const {
147
- SIMSYCL_CHECK (!m_hierarchical && " leader() is not supported for from within a parallel_for_work_item context" );
131
+ SIMSYCL_CHECK (m_type == detail::group_type::nd_range
132
+ && " leader() is not supported for from within a parallel_for_work_item context" );
148
133
return (get_local_linear_id () == 0 );
149
134
}
150
135
151
136
template <typename WorkItemFunctionT>
152
137
void parallel_for_work_item (WorkItemFunctionT func) const {
153
- SIMSYCL_CHECK (m_hierarchical
138
+ SIMSYCL_CHECK (m_type != detail::group_type::nd_range
154
139
&& " parallel_for_work_item is only supported for from within a parallel_for_work_item context" );
155
- SIMSYCL_CHECK (m_hier_local_range. has_value ()
140
+ SIMSYCL_CHECK (m_type != detail::group_type::hierarchical_implicit_size
156
141
&& " parallel_for_work_item(func) without a range argument is only supported in a parallel_for_work_item "
157
142
" context with a set local range" );
158
- parallel_for_work_item (m_hier_local_range. value (), func);
143
+ parallel_for_work_item (m_local_item. get_range (), func);
159
144
}
160
145
161
146
// All parallel_for_work_item calls within a given parallel_for_work_group execution must have the same dimensions
162
147
template <typename WorkItemFunctionT>
163
148
void parallel_for_work_item (range<Dimensions> flexible_range, WorkItemFunctionT func) const {
164
- SIMSYCL_CHECK (m_hierarchical
149
+ SIMSYCL_CHECK (m_type != detail::group_type::nd_range
165
150
&& " parallel_for_work_item is only supported for from within a parallel_for_work_item context" );
166
- detail::hierarchical_group_size_setter set (*this , flexible_range. size () );
151
+ detail::hierarchical_group_size_setter set (*this , flexible_range);
167
152
if constexpr (Dimensions == 1 ) {
168
153
for (size_t i = 0 ; i < flexible_range[0 ]; ++i) {
169
154
const auto global_id = m_group_item.get_id () * flexible_range[0 ] + i;
@@ -292,33 +277,27 @@ class group {
292
277
friend bool operator !=(const group<Dimensions> &lhs, const group<Dimensions> &rhs) { return !(lhs == rhs); }
293
278
294
279
private:
295
- item<Dimensions, false /* WithOffset */ > m_local_item;
296
- item<Dimensions, true /* WithOffset */ > m_global_item;
297
- item<Dimensions, false /* WithOffset */ > m_group_item;
298
- detail::concurrent_group *m_concurrent_group;
299
-
300
- bool m_hierarchical = false ;
301
- std::optional<range<Dimensions>> m_hier_local_range;
280
+ template <typename G, int D>
281
+ friend class detail ::hierarchical_group_size_setter;
302
282
303
- group ( const item <Dimensions, false > &local_item, const item <Dimensions, true > &global_item ,
304
- const item<Dimensions, false > &group_item, detail::concurrent_group *impl)
305
- : m_local_item(local_item), m_global_item(global_item), m_group_item( group_item), m_concurrent_group( impl) {}
283
+ friend group <Dimensions> detail::make_group <Dimensions>( const detail::group_type type ,
284
+ const sycl:: item<Dimensions, false > &local_item, const sycl::item<Dimensions, true > &global_item,
285
+ const sycl::item<Dimensions, false > & group_item, detail::concurrent_group * impl);
306
286
307
- group (const item<Dimensions, false > &group_item, const std::optional<range<Dimensions>> &hier_local_range,
308
- detail::concurrent_group *impl)
309
- : m_local_item(group_item), m_global_item(group_item), m_group_item(group_item), m_concurrent_group(impl),
310
- m_hierarchical (true ), m_hier_local_range(hier_local_range) {}
311
-
312
- friend group<Dimensions> detail::make_group<Dimensions>(const sycl::item<Dimensions, false > &local_item,
313
- const sycl::item<Dimensions, true > &global_item, const sycl::item<Dimensions, false > &group_item,
314
- detail::concurrent_group *impl);
287
+ friend detail::group_type detail::get_group_type (const sycl::group<Dimensions> &g);
288
+ friend detail::concurrent_group &detail::get_concurrent_group<Dimensions>(const sycl::group<Dimensions> &g);
315
289
316
- friend group<Dimensions> detail::make_hierarchical_group<Dimensions>(
317
- const sycl::item<Dimensions, false > &group_item, const std::optional<sycl::range<Dimensions>> &hier_local_range,
318
- detail::concurrent_group *impl);
290
+ detail::group_type m_type;
291
+ mutable item<Dimensions, false /* WithOffset */ > m_local_item; // mutable for hierarchical_group_size_setter
292
+ mutable item<Dimensions, true /* WithOffset */ > m_global_item; // mutable for hierarchical_group_size_setter
293
+ item<Dimensions, false /* WithOffset */ > m_group_item;
294
+ detail::concurrent_group *m_concurrent_group;
319
295
320
- friend bool detail::is_hierarchical_group<Dimensions>(const sycl::group<Dimensions> &g);
321
- friend detail::concurrent_group &detail::get_concurrent_group<Dimensions>(const sycl::group<Dimensions> &g);
296
+ group (const detail::group_type type, const item<Dimensions, false > &local_item,
297
+ const item<Dimensions, true > &global_item, const item<Dimensions, false > &group_item,
298
+ detail::concurrent_group *impl)
299
+ : m_type(type), m_local_item(local_item), m_global_item(global_item), m_group_item(group_item),
300
+ m_concurrent_group (impl) {}
322
301
};
323
302
324
303
template <int Dimensions>
0 commit comments