26
26
#error "SYCL device compiler is built without ext_vector_type support"
27
27
#endif
28
28
29
- #if defined(__SYCL_DEVICE_ONLY__)
30
- #define __SYCL_USE_EXT_VECTOR_TYPE__
31
- #endif
32
-
33
29
#include < sycl/access/access.hpp> // for decorated, address_space
34
30
#include < sycl/aliases.hpp> // for half, cl_char, cl_int
35
31
#include < sycl/detail/common.hpp> // for ArrayCreator, RepeatV...
47
43
#include < sycl/ext/oneapi/bfloat16.hpp> // bfloat16
48
44
49
45
#include < array> // for array
50
- #include < assert.h > // for assert
46
+ #include < cassert > // for assert
51
47
#include < cstddef> // for size_t, NULL, byte
52
48
#include < cstdint> // for uint8_t, int16_t, int...
53
49
#include < functional> // for divides, multiplies
@@ -363,18 +359,30 @@ template <typename T>
363
359
using vec_data_t = typename detail::vec_helper<T>::RetType;
364
360
365
361
// /////////////////////// class sycl::vec /////////////////////////
366
- // / Provides a cross-patform vector class template that works efficiently on
367
- // / SYCL devices as well as in host C++ code.
368
- // /
369
- // / \ingroup sycl_api
362
+ // Provides a cross-platform vector class template that works efficiently on
363
+ // SYCL devices as well as in host C++ code.
370
364
template <typename Type, int NumElements>
371
365
class vec : public detail ::vec_arith<Type, NumElements> {
372
366
using DataT = Type;
373
367
368
+ // https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#memory-layout-and-alignment
369
+ // It is required by the SPEC to align vec<DataT, 3> with vec<DataT, 4>.
370
+ static constexpr size_t AdjustedNum = (NumElements == 3 ) ? 4 : NumElements;
371
+
374
372
// This represent type of underlying value. There should be only one field
375
373
// in the class, so vec<float, 16> should be equal to float16 in memory.
376
374
using DataType = typename detail::VecStorage<DataT, NumElements>::DataType;
377
375
376
+ public:
377
+ #ifdef __SYCL_DEVICE_ONLY__
378
+ // Type used for passing sycl::vec to SPIRV builtins.
379
+ // We can not use ext_vector_type(1) as it's not supported by SPIRV
380
+ // plugins (CTS fails).
381
+ using vector_t =
382
+ typename detail::VecStorage<DataT, NumElements>::VectorDataType;
383
+ #endif // __SYCL_DEVICE_ONLY__
384
+
385
+ private:
378
386
static constexpr bool IsHostHalf =
379
387
std::is_same_v<DataT, sycl::detail::half_impl::half> &&
380
388
std::is_same_v<sycl::detail::half_impl::StorageT,
@@ -383,7 +391,6 @@ class vec : public detail::vec_arith<Type, NumElements> {
383
391
static constexpr bool IsBfloat16 =
384
392
std::is_same_v<DataT, sycl::ext::oneapi::bfloat16>;
385
393
386
- static constexpr size_t AdjustedNum = (NumElements == 3 ) ? 4 : NumElements;
387
394
static constexpr size_t Sz = sizeof (DataT) * AdjustedNum;
388
395
static constexpr bool IsSizeGreaterThanMaxAlign =
389
396
(Sz > detail::MaxVecAlignment);
@@ -456,6 +463,8 @@ class vec : public detail::vec_arith<Type, NumElements> {
456
463
}
457
464
template <typename DataT_, typename T>
458
465
static constexpr auto FlattenVecArgHelper (const T &A) {
466
+ // static_cast required to avoid narrowing conversion warning
467
+ // when T = unsigned long int and DataT_ = int.
459
468
return std::array<DataT_, 1 >{vec_data<DataT_>::get (static_cast <DataT_>(A))};
460
469
}
461
470
template <typename DataT_, typename T> struct FlattenVecArg {
@@ -551,6 +560,7 @@ class vec : public detail::vec_arith<Type, NumElements> {
551
560
using EnableIfSuitableNumElements =
552
561
typename std::enable_if_t <SizeChecker<0 , NumElements, argTN...>::value>;
553
562
563
+ // Implementation detail for the next public ctor.
554
564
template <size_t ... Is>
555
565
constexpr vec (const std::array<vec_data_t <DataT>, NumElements> &Arr,
556
566
std::index_sequence<Is...>)
@@ -562,14 +572,13 @@ class vec : public detail::vec_arith<Type, NumElements> {
562
572
})(Arr[Is])...} {}
563
573
564
574
public:
575
+ // Aliases required by SPEC to make sycl::vec consistent
576
+ // with that of marray and buffer.
565
577
using element_type = DataT;
566
578
using value_type = DataT;
567
579
using rel_t = detail::rel_t <DataT>;
568
- #ifdef __SYCL_DEVICE_ONLY__
569
- using vector_t =
570
- typename detail::VecStorage<DataT, NumElements>::VectorDataType;
571
- #endif // __SYCL_DEVICE_ONLY__
572
580
581
+ /* ***************** Constructors **************/
573
582
vec () = default;
574
583
575
584
constexpr vec (const vec &Rhs) = default;
@@ -587,7 +596,7 @@ class vec : public detail::vec_arith<Type, NumElements> {
587
596
return *this ;
588
597
}
589
598
590
- #ifdef __SYCL_USE_EXT_VECTOR_TYPE__
599
+ #ifdef __SYCL_DEVICE_ONLY__
591
600
template <typename T = void >
592
601
using EnableIfNotHostHalf = typename std::enable_if_t <!IsHostHalf, T>;
593
602
@@ -601,7 +610,7 @@ class vec : public detail::vec_arith<Type, NumElements> {
601
610
template <typename T = void >
602
611
using EnableIfNotUsingArrayOnDevice =
603
612
typename std::enable_if_t <!IsUsingArrayOnDevice, T>;
604
- #endif // __SYCL_USE_EXT_VECTOR_TYPE__
613
+ #endif // __SYCL_DEVICE_ONLY__
605
614
606
615
template <typename T = void >
607
616
using EnableIfUsingArray =
@@ -612,7 +621,7 @@ class vec : public detail::vec_arith<Type, NumElements> {
612
621
typename std::enable_if_t <!IsUsingArrayOnDevice && !IsUsingArrayOnHost,
613
622
T>;
614
623
615
- #ifdef __SYCL_USE_EXT_VECTOR_TYPE__
624
+ #ifdef __SYCL_DEVICE_ONLY__
616
625
617
626
template <typename Ty = DataT>
618
627
explicit constexpr vec (const EnableIfNotUsingArrayOnDevice<Ty> &arg)
@@ -645,12 +654,17 @@ class vec : public detail::vec_arith<Type, NumElements> {
645
654
}
646
655
return *this ;
647
656
}
648
- #else // __SYCL_USE_EXT_VECTOR_TYPE__
657
+ #else // __SYCL_DEVICE_ONLY__
649
658
explicit constexpr vec (const DataT &arg)
650
659
: vec{detail::RepeatValue<NumElements>(
651
660
static_cast <vec_data_t <DataT>>(arg)),
652
661
std::make_index_sequence<NumElements>()} {}
653
662
663
+ /* ***************** Assignment Operators **************/
664
+
665
+ // Template required to prevent ambiguous overload with the copy assignment
666
+ // when NumElements == 1. The template prevents implicit conversion from
667
+ // vec<_, 1> to DataT.
654
668
template <typename Ty = DataT>
655
669
typename std::enable_if_t <
656
670
std::is_fundamental_v<vec_data_t <Ty>> ||
@@ -662,9 +676,9 @@ class vec : public detail::vec_arith<Type, NumElements> {
662
676
}
663
677
return *this ;
664
678
}
665
- #endif // __SYCL_USE_EXT_VECTOR_TYPE__
679
+ #endif // __SYCL_DEVICE_ONLY__
666
680
667
- #ifdef __SYCL_USE_EXT_VECTOR_TYPE__
681
+ #ifdef __SYCL_DEVICE_ONLY__
668
682
// Optimized naive constructors with NumElements of DataT values.
669
683
// We don't expect compilers to optimize vararg recursive functions well.
670
684
@@ -713,7 +727,7 @@ class vec : public detail::vec_arith<Type, NumElements> {
713
727
vec_data<Ty>::get (ArgA), vec_data<Ty>::get (ArgB),
714
728
vec_data<Ty>::get (ArgC), vec_data<Ty>::get (ArgD),
715
729
vec_data<Ty>::get (ArgE), vec_data<Ty>::get (ArgF)} {}
716
- #endif // __SYCL_USE_EXT_VECTOR_TYPE__
730
+ #endif // __SYCL_DEVICE_ONLY__
717
731
718
732
// Constructor from values of base type or vec of base type. Checks that
719
733
// base types are match and that the NumElements == sum of lengths of args.
@@ -736,6 +750,10 @@ class vec : public detail::vec_arith<Type, NumElements> {
736
750
}
737
751
}
738
752
753
+ /* Available only when: compiled for the device.
754
+ * Converts this SYCL vec instance to the underlying backend-native vector
755
+ * type defined by vector_t.
756
+ */
739
757
operator vector_t () const {
740
758
if constexpr (!IsUsingArrayOnDevice) {
741
759
return m_Data;
@@ -986,17 +1004,9 @@ class vec : public detail::vec_arith<Type, NumElements> {
986
1004
store (Offset, MultiPtr);
987
1005
}
988
1006
989
- void ConvertToDataT () {
990
- for (size_t i = 0 ; i < NumElements; ++i) {
991
- DataT tmp = getValue (i);
992
- setValue (i, tmp);
993
- }
994
- }
995
-
996
1007
private:
997
1008
// Generic method that execute "Operation" on underlying values.
998
-
999
- #ifdef __SYCL_USE_EXT_VECTOR_TYPE__
1009
+ #ifdef __SYCL_DEVICE_ONLY__
1000
1010
template <template <typename > class Operation ,
1001
1011
typename Ty = vec<DataT, NumElements>>
1002
1012
vec<DataT, NumElements>
@@ -1018,7 +1028,7 @@ class vec : public detail::vec_arith<Type, NumElements> {
1018
1028
}
1019
1029
return Result;
1020
1030
}
1021
- #else // __SYCL_USE_EXT_VECTOR_TYPE__
1031
+ #else // __SYCL_DEVICE_ONLY__
1022
1032
template <template <typename > class Operation >
1023
1033
vec<DataT, NumElements>
1024
1034
operatorHelper (const vec<DataT, NumElements> &Rhs) const {
@@ -1029,12 +1039,12 @@ class vec : public detail::vec_arith<Type, NumElements> {
1029
1039
}
1030
1040
return Result;
1031
1041
}
1032
- #endif // __SYCL_USE_EXT_VECTOR_TYPE__
1042
+ #endif // __SYCL_DEVICE_ONLY__
1033
1043
1034
1044
// setValue and getValue should be able to operate on different underlying
1035
1045
// types: enum cl_float#N , builtin vector float#N, builtin type float.
1036
1046
// These versions are for N > 1.
1037
- #ifdef __SYCL_USE_EXT_VECTOR_TYPE__
1047
+ #ifdef __SYCL_DEVICE_ONLY__
1038
1048
template <int Num = NumElements, typename Ty = int ,
1039
1049
typename = typename std::enable_if_t <1 != Num>>
1040
1050
constexpr void setValue (EnableIfNotHostHalf<Ty> Index, const DataT &Value,
@@ -1059,7 +1069,7 @@ class vec : public detail::vec_arith<Type, NumElements> {
1059
1069
constexpr DataT getValue (EnableIfHostHalf<Ty> Index, int ) const {
1060
1070
return vec_data<DataT>::get (m_Data.s [Index]);
1061
1071
}
1062
- #else // __SYCL_USE_EXT_VECTOR_TYPE__
1072
+ #else // __SYCL_DEVICE_ONLY__
1063
1073
template <int Num = NumElements,
1064
1074
typename = typename std::enable_if_t <1 != Num>>
1065
1075
constexpr void setValue (int Index, const DataT &Value, int ) {
@@ -1071,7 +1081,7 @@ class vec : public detail::vec_arith<Type, NumElements> {
1071
1081
constexpr DataT getValue (int Index, int ) const {
1072
1082
return vec_data<DataT>::get (m_Data[Index]);
1073
1083
}
1074
- #endif // __SYCL_USE_EXT_VECTOR_TYPE__
1084
+ #endif // __SYCL_DEVICE_ONLY__
1075
1085
1076
1086
// N==1 versions, used by host and device. Shouldn't trailing type be int?
1077
1087
template <int Num = NumElements,
0 commit comments