36
36
#include < sycl/detail/type_list.hpp> // for is_contained
37
37
#include < sycl/detail/type_traits.hpp> // for is_floating_point
38
38
#include < sycl/detail/vector_arith.hpp>
39
- #include < sycl/detail/vector_convert.hpp> // for convertImpl
40
39
#include < sycl/half_type.hpp> // for StorageT, half, Vec16...
41
40
42
41
#include < sycl/ext/oneapi/bfloat16.hpp> // bfloat16
53
52
#include < utility> // for index_sequence, make_...
54
53
55
54
namespace sycl {
55
+
56
+ // TODO: Fix in the next ABI breaking windows.
57
+ enum class rounding_mode { automatic = 0 , rte = 1 , rtz = 2 , rtp = 3 , rtn = 4 };
58
+
56
59
inline namespace _V1 {
57
60
58
61
struct elem {
@@ -406,18 +409,6 @@ class __SYCL_EBO vec
406
409
static constexpr size_t byte_size () noexcept { return sizeof (m_Data); }
407
410
408
411
private:
409
- // We interpret bool as int8_t, std::byte as uint8_t for conversion to other
410
- // types.
411
- template <typename T>
412
- using ConvertBoolAndByteT =
413
- typename detail::map_type<T,
414
- #if (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0)
415
- std::byte, /* ->*/ std::uint8_t , //
416
- #endif
417
- bool , /* ->*/ std::uint8_t , //
418
- T, /* ->*/ T //
419
- >::type;
420
-
421
412
// getValue should be able to operate on different underlying
422
413
// types: enum cl_float#N , builtin vector float#N, builtin type float.
423
414
constexpr auto getValue (int Index) const {
@@ -439,88 +430,10 @@ class __SYCL_EBO vec
439
430
}
440
431
441
432
public:
433
+ // Out-of-class definition is in `sycl/detail/vector_convert.hpp`
442
434
template <typename convertT,
443
435
rounding_mode roundingMode = rounding_mode::automatic>
444
- vec<convertT, NumElements> convert () const {
445
-
446
- using T = ConvertBoolAndByteT<DataT>;
447
- using R = ConvertBoolAndByteT<convertT>;
448
- using bfloat16 = sycl::ext::oneapi::bfloat16;
449
- static_assert (std::is_integral_v<R> ||
450
- detail::is_floating_point<R>::value ||
451
- std::is_same_v<R, bfloat16>,
452
- " Unsupported convertT" );
453
-
454
- using OpenCLT = detail::ConvertToOpenCLType_t<T>;
455
- using OpenCLR = detail::ConvertToOpenCLType_t<R>;
456
- vec<convertT, NumElements> Result;
457
-
458
- // convertImpl can't be called with the same From and To types and therefore
459
- // we need some special processing in a few cases.
460
- if constexpr (std::is_same_v<DataT, convertT>) {
461
- return *this ;
462
- } else if constexpr (std::is_same_v<OpenCLT, OpenCLR> ||
463
- std::is_same_v<T, R>) {
464
- for (size_t I = 0 ; I < NumElements; ++I)
465
- Result[I] = static_cast <convertT>(getValue (I));
466
- return Result;
467
- } else {
468
-
469
- #ifdef __SYCL_DEVICE_ONLY__
470
- using OpenCLVecT = OpenCLT __attribute__ ((ext_vector_type (NumElements)));
471
- using OpenCLVecR = OpenCLR __attribute__ ((ext_vector_type (NumElements)));
472
-
473
- auto NativeVector = sycl::bit_cast<vector_t >(*this );
474
- using ConvertTVecType = typename vec<convertT, NumElements>::vector_t ;
475
-
476
- // Whole vector conversion can only be done, if:
477
- constexpr bool canUseNativeVectorConvert =
478
- #ifdef __NVPTX__
479
- // TODO: Likely unnecessary as
480
- // https://github.com/intel/llvm/issues/11840 has been closed
481
- // already.
482
- false &&
483
- #endif
484
- NumElements > 1 &&
485
- // - vec storage has an equivalent OpenCL native vector it is
486
- // implicitly convertible to. There are some corner cases where it
487
- // is not the case with char, long and long long types.
488
- std::is_convertible_v<vector_t , OpenCLVecT> &&
489
- std::is_convertible_v<ConvertTVecType, OpenCLVecR> &&
490
- // - it is not a signed to unsigned (or vice versa) conversion
491
- // see comments within 'convertImpl' for more details;
492
- !detail::is_sint_to_from_uint<T, R>::value &&
493
- // - destination type is not bool. bool is stored as integer under the
494
- // hood and therefore conversion to bool looks like conversion
495
- // between two integer types. Since bit pattern for true and false
496
- // is not defined, there is no guarantee that integer conversion
497
- // yields right results here;
498
- !std::is_same_v<convertT, bool >;
499
-
500
- if constexpr (canUseNativeVectorConvert) {
501
- auto val = detail::convertImpl<T, R, roundingMode, NumElements, OpenCLVecT,
502
- OpenCLVecR>(NativeVector);
503
- Result.m_Data = sycl::bit_cast<decltype (Result.m_Data )>(val);
504
- } else
505
- #endif // __SYCL_DEVICE_ONLY__
506
- {
507
- // Otherwise, we fallback to per-element conversion:
508
- for (size_t I = 0 ; I < NumElements; ++I) {
509
- auto val =
510
- detail::convertImpl<T, R, roundingMode, 1 , OpenCLT, OpenCLR>(
511
- getValue (I));
512
- #ifdef __SYCL_DEVICE_ONLY__
513
- // On device, we interpret BF16 as uint16.
514
- if constexpr (std::is_same_v<convertT, bfloat16>)
515
- Result[I] = sycl::bit_cast<convertT>(val);
516
- else
517
- #endif
518
- Result[I] = static_cast <convertT>(val);
519
- }
520
- }
521
- }
522
- return Result;
523
- }
436
+ vec<convertT, NumElements> convert () const ;
524
437
525
438
template <typename asT> asT as () const { return sycl::bit_cast<asT>(*this ); }
526
439
0 commit comments