1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
/*========================== begin_copyright_notice ============================
Copyright (C) 2021 Intel Corporation
SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/
#ifndef CM_CL_DETAIL_VECTOR_IMPL_H
#define CM_CL_DETAIL_VECTOR_IMPL_H
#include <opencl_type_traits.h>
namespace cm {
namespace detail {
template<typename T, int width>
using vector_impl = T __attribute__((ext_vector_type(width)));
// offset into vector
using vector_offset_type = short;
template <typename To, typename From, int width>
constexpr int calc_bit_cast_width() {
if constexpr (sizeof(To) <= sizeof(From))
return width * (sizeof(From) / sizeof(To));
else {
constexpr auto ratio = sizeof(To) / sizeof(From);
static_assert(width % ratio == 0,
"cannot bitcast the provided vector to the requested type");
return width / ratio;
}
}
template <typename To, typename From, int width>
constexpr auto bit_cast(vector_impl<From, width> vec) {
using ret_t = vector_impl<To, calc_bit_cast_width<To, From, width>()>;
if constexpr (cl::is_same<To, From>::value)
return vec;
else
return __builtin_bit_cast(ret_t, vec);
}
// clang-9 somehow doesn't consider this function constexpr.
#if __clang_major__ > 9
template <typename T, int width>
constexpr int get_width(vector_impl<T, width>) {
return width;
}
#endif // __clang_major__ > 9
template <typename T> struct width_getter {};
template <typename T, int width>
struct width_getter<__private vector_impl<T, width>>
: public cl::integral_constant<int, width> {};
template <typename T, int width>
struct width_getter<__global vector_impl<T, width>>
: public cl::integral_constant<int, width> {};
template <typename T, int width>
struct width_getter<__constant vector_impl<T, width>>
: public cl::integral_constant<int, width> {};
template <typename T, int width>
struct width_getter<__local vector_impl<T, width>>
: public cl::integral_constant<int, width> {};
template <typename T, int width>
struct width_getter<__generic vector_impl<T, width>>
: public cl::integral_constant<int, width> {};
} // namespace detail
} // namespace cm
#endif // CM_CL_DETAIL_VECTOR_IMPL_H
|