18 #define __ESIMD_ENS sycl::ext::intel::experimental::esimd
19 #define __ESIMD_EDNS sycl::ext::intel::experimental::esimd::detail
24 namespace __ESIMD_ENS {
129 static_assert(VS == lsc_vector_size::n1 || VS == lsc_vector_size::n2 ||
130 VS == lsc_vector_size::n3 || VS == lsc_vector_size::n4 ||
131 VS == lsc_vector_size::n8 || VS == lsc_vector_size::n16 ||
132 VS == lsc_vector_size::n64 || VS == lsc_vector_size::n32,
133 "Unsupported vector size");
137 static_assert(VS == 1 || VS == 2 || VS == 3 || VS == 4 || VS == 8 ||
138 VS == 16 || VS == 32 || VS == 64,
139 "Unsupported vector size");
143 static_assert(DS != lsc_data_size::default_size ||
sizeof(T) == 1 ||
144 sizeof(T) == 2 ||
sizeof(T) == 4 ||
sizeof(T) == 8,
145 "Unsupported data type");
150 Op == __ESIMD_NS::atomic_op::sub ||
151 Op == __ESIMD_NS::atomic_op::inc ||
155 Op == __ESIMD_NS::atomic_op::cmpxchg ||
159 Op == __ESIMD_NS::atomic_op::minsint ||
160 Op == __ESIMD_NS::atomic_op::maxsint ||
163 Op == __ESIMD_NS::atomic_op::fcmpwr ||
164 Op == __ESIMD_NS::atomic_op::fadd ||
165 Op == __ESIMD_NS::atomic_op::fsub ||
166 Op == __ESIMD_NS::atomic_op::load ||
167 Op == __ESIMD_NS::atomic_op::store,
168 "Unsupported operation for LSC atomics");
172 template <__ESIMD_NS::atomic_op Op,
unsigned NumSrc>
174 check_lsc_atomic_op<Op>();
175 if constexpr (Op == __ESIMD_NS::atomic_op::inc ||
177 Op == __ESIMD_NS::atomic_op::load) {
178 static_assert(NumSrc == 0,
"No source operands are expected");
180 if constexpr (Op == __ESIMD_NS::atomic_op::store ||
182 Op == __ESIMD_NS::atomic_op::sub ||
183 Op == __ESIMD_NS::atomic_op::minsint ||
184 Op == __ESIMD_NS::atomic_op::maxsint ||
187 Op == __ESIMD_NS::atomic_op::fadd ||
188 Op == __ESIMD_NS::atomic_op::fsub ||
194 static_assert(NumSrc == 1,
"One source operand is expected");
196 if constexpr (Op == __ESIMD_NS::atomic_op::cmpxchg ||
197 Op == __ESIMD_NS::atomic_op::fcmpwr) {
198 static_assert(NumSrc == 2,
"Two source operands are expected");
203 check_lsc_atomic_op<Op>();
206 return lsc_atomic_op::iadd;
207 case __ESIMD_NS::atomic_op::sub:
208 return lsc_atomic_op::isub;
209 case __ESIMD_NS::atomic_op::inc:
210 return lsc_atomic_op::iinc;
212 return lsc_atomic_op::idec;
214 return lsc_atomic_op::umin;
216 return lsc_atomic_op::umax;
217 case __ESIMD_NS::atomic_op::cmpxchg:
218 return lsc_atomic_op::icas;
225 case __ESIMD_NS::atomic_op::minsint:
226 return lsc_atomic_op::smin;
227 case __ESIMD_NS::atomic_op::maxsint:
228 return lsc_atomic_op::smax;
233 case __ESIMD_NS::atomic_op::fcmpwr:
234 return lsc_atomic_op::fcas;
235 case __ESIMD_NS::atomic_op::fadd:
236 return lsc_atomic_op::fadd;
237 case __ESIMD_NS::atomic_op::fsub:
238 return lsc_atomic_op::fsub;
239 case __ESIMD_NS::atomic_op::load:
240 return lsc_atomic_op::load;
241 case __ESIMD_NS::atomic_op::store:
242 return lsc_atomic_op::store;
244 return lsc_atomic_op::iinc;
248 template <lsc_vector_size VS> constexpr uint8_t
to_int() {
249 check_lsc_vector_size<VS>();
251 case lsc_vector_size::n1:
253 case lsc_vector_size::n2:
255 case lsc_vector_size::n3:
257 case lsc_vector_size::n4:
259 case lsc_vector_size::n8:
261 case lsc_vector_size::n16:
263 case lsc_vector_size::n32:
265 case lsc_vector_size::n64:
273 check_lsc_vector_size<VS>();
276 return lsc_vector_size::n1;
278 return lsc_vector_size::n2;
280 return lsc_vector_size::n3;
282 return lsc_vector_size::n4;
284 return lsc_vector_size::n8;
286 return lsc_vector_size::n16;
288 return lsc_vector_size::n32;
290 return lsc_vector_size::n64;
292 return lsc_vector_size::n1;
296 template <
typename T, lsc_data_size DS>
298 check_lsc_data_size<T, DS>();
299 if (DS != lsc_data_size::default_size)
301 else if (
sizeof(T) == 1)
302 return lsc_data_size::u8;
303 else if (
sizeof(T) == 2)
304 return lsc_data_size::u16;
305 else if (
sizeof(T) == 4)
306 return lsc_data_size::u32;
307 else if (
sizeof(T) == 8)
308 return lsc_data_size::u64;
314 if (DS == lsc_data_size::u8)
315 return lsc_data_size::u8u32;
316 if (DS == lsc_data_size::u16)
317 return lsc_data_size::u16u32;
322 using type =
typename std::conditional<
sizeof(T) < 4, uint32_t, T>::
type;
327 using _type1 =
typename std::conditional<
sizeof(T) == 2, uint16_t, T>::
type;
328 using _type2 =
typename std::conditional<
sizeof(T) == 1, uint8_t, T>::
type;
332 typename std::conditional<
sizeof(_type2) == 1, _type2, _type1>::
type;
352 template <cache_h
int Last>
353 struct is_one_of_t<Last>
354 : std::conditional<Last == Hint, std::true_type, std::false_type>::type {
357 struct is_one_of_t<Head, Tail...>
358 : std::conditional<Head == Hint, std::true_type,
359 is_one_of_t<Tail...>>::type {};
364 return is_one_of_t<Hints...>::value;
369 return First == Val && Second == Val;
374 template <lsc_action Action, cache_h
int L1, cache_h
int L3>
380 L1H.template is_one_of<cache_hint::cached, cache_hint::uncached,
381 cache_hint::streaming>() &&
382 L3H.template is_one_of<cache_hint::cached,
383 cache_hint::uncached>() &&
384 !
are_both(L1H, L3H, cache_hint::uncached),
385 "unsupported cache hint");
386 }
else if constexpr (Action == lsc_action::load) {
388 are_both(L1H, L3H, cache_hint::none) ||
389 (L1H.template is_one_of<cache_hint::uncached, cache_hint::cached,
390 cache_hint::streaming>() &&
391 L3H.template is_one_of<cache_hint::uncached,
392 cache_hint::cached>()) ||
393 (L1H == cache_hint::read_invalidate && L3H == cache_hint::cached),
394 "unsupported cache hint");
395 }
else if constexpr (Action == lsc_action::store) {
396 static_assert(
are_both(L1H, L3H, cache_hint::none) ||
397 are_both(L1H, L3H, cache_hint::write_back) ||
398 (L1H.template is_one_of<cache_hint::uncached,
399 cache_hint::write_through,
400 cache_hint::streaming>() &&
401 L3H.template is_one_of<cache_hint::uncached,
402 cache_hint::write_back>()),
403 "unsupported cache hint");
404 }
else if constexpr (Action == lsc_action::atomic) {
405 static_assert(
are_both(L1H, L3H, cache_hint::none) ||
406 (L1H == cache_hint::uncached &&
407 L3H.template is_one_of<cache_hint::uncached,
408 cache_hint::write_back>()),
409 "unsupported cache hint");