Skip to content

Commit

Permalink
[SYCL] Move code sycl/types.hpp -> `sycl/detail/is_device_copyable.…
Browse files Browse the repository at this point in the history
…hpp` (#13755)
  • Loading branch information
aelovikov-intel authored May 13, 2024
1 parent aa0f7d4 commit d1d7e1d
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 80 deletions.
81 changes: 81 additions & 0 deletions sycl/include/sycl/detail/is_device_copyable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
//===----------------------------------------------------------------------===//
#pragma once

#include <sycl/detail/defines_elementary.hpp>

#include <array>
#include <optional>
#include <type_traits>
Expand Down Expand Up @@ -80,5 +82,84 @@ struct is_device_copyable<T[N]> : is_device_copyable<T> {};

template <typename T>
inline constexpr bool is_device_copyable_v = is_device_copyable<T>::value;
namespace detail {
template <typename T, typename = void>
struct IsDeprecatedDeviceCopyable : std::false_type {};

// TODO: using C++ attribute [[deprecated]] or the macro __SYCL2020_DEPRECATED
// does not produce expected warning message for the type 'T'.
template <typename T>
struct __SYCL2020_DEPRECATED("This type isn't device copyable in SYCL 2020")
IsDeprecatedDeviceCopyable<
T, std::enable_if_t<std::is_trivially_copy_constructible_v<T> &&
std::is_trivially_destructible_v<T> &&
!is_device_copyable_v<T>>> : std::true_type {};

template <typename T, int N>
struct __SYCL2020_DEPRECATED("This type isn't device copyable in SYCL 2020")
IsDeprecatedDeviceCopyable<T[N]> : IsDeprecatedDeviceCopyable<T> {};

#ifdef __SYCL_DEVICE_ONLY__
// Checks that the fields of the type T with indices 0 to (NumFieldsToCheck -
// 1) are device copyable.
template <typename T, unsigned NumFieldsToCheck>
struct CheckFieldsAreDeviceCopyable
: CheckFieldsAreDeviceCopyable<T, NumFieldsToCheck - 1> {
using FieldT = decltype(__builtin_field_type(T, NumFieldsToCheck - 1));
static_assert(is_device_copyable_v<FieldT> ||
detail::IsDeprecatedDeviceCopyable<FieldT>::value,
"The specified type is not device copyable");
};

template <typename T> struct CheckFieldsAreDeviceCopyable<T, 0> {};

// Checks that the base classes of the type T with indices 0 to
// (NumFieldsToCheck - 1) are device copyable.
template <typename T, unsigned NumBasesToCheck>
struct CheckBasesAreDeviceCopyable
: CheckBasesAreDeviceCopyable<T, NumBasesToCheck - 1> {
using BaseT = decltype(__builtin_base_type(T, NumBasesToCheck - 1));
static_assert(is_device_copyable_v<BaseT> ||
detail::IsDeprecatedDeviceCopyable<BaseT>::value,
"The specified type is not device copyable");
};

template <typename T> struct CheckBasesAreDeviceCopyable<T, 0> {};

// All the captures of a lambda or functor of type FuncT passed to a kernel
// must be is_device_copyable, which extends to bases and fields of FuncT.
// Fields are captures of lambda/functors and bases are possible base classes
// of functors also allowed by SYCL.
// The SYCL-2020 implementation must check each of the fields & bases of the
// type FuncT, only one level deep, which is enough to see if they are all
// device copyable by using the result of is_device_copyable returned for them.
// At this moment though the check also allowes using types for which
// (is_trivially_copy_constructible && is_trivially_destructible) returns true
// and (is_device_copyable) returns false. That is the deprecated behavior and
// is currently/temporarily supported only to not break older SYCL programs.
template <typename FuncT>
struct CheckDeviceCopyable
: CheckFieldsAreDeviceCopyable<FuncT, __builtin_num_fields(FuncT)>,
CheckBasesAreDeviceCopyable<FuncT, __builtin_num_bases(FuncT)> {};

template <typename TransformedArgType, int Dims, typename KernelType>
class RoundedRangeKernel;
template <typename TransformedArgType, int Dims, typename KernelType>
class RoundedRangeKernelWithKH;

// Below are two specializations for CheckDeviceCopyable when a kernel lambda
// is wrapped after range rounding optimization.
template <typename TransformedArgType, int Dims, typename KernelType>
struct CheckDeviceCopyable<
RoundedRangeKernel<TransformedArgType, Dims, KernelType>>
: CheckDeviceCopyable<KernelType> {};

template <typename TransformedArgType, int Dims, typename KernelType>
struct CheckDeviceCopyable<
RoundedRangeKernelWithKH<TransformedArgType, Dims, KernelType>>
: CheckDeviceCopyable<KernelType> {};

#endif // __SYCL_DEVICE_ONLY__
} // namespace detail
} // namespace _V1
} // namespace sycl
80 changes: 0 additions & 80 deletions sycl/include/sycl/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,83 +28,3 @@
#endif

#include <sycl/ext/oneapi/bfloat16.hpp> // bfloat16

namespace sycl {
inline namespace _V1 {
namespace detail {

template <typename T, typename = void>
struct IsDeprecatedDeviceCopyable : std::false_type {};

// TODO: using C++ attribute [[deprecated]] or the macro __SYCL2020_DEPRECATED
// does not produce expected warning message for the type 'T'.
template <typename T>
struct __SYCL2020_DEPRECATED("This type isn't device copyable in SYCL 2020")
IsDeprecatedDeviceCopyable<
T, std::enable_if_t<std::is_trivially_copy_constructible_v<T> &&
std::is_trivially_destructible_v<T> &&
!is_device_copyable_v<T>>> : std::true_type {};

template <typename T, int N>
struct __SYCL2020_DEPRECATED("This type isn't device copyable in SYCL 2020")
IsDeprecatedDeviceCopyable<T[N]> : IsDeprecatedDeviceCopyable<T> {};

#ifdef __SYCL_DEVICE_ONLY__
// Checks that the fields of the type T with indices 0 to (NumFieldsToCheck -
// 1) are device copyable.
template <typename T, unsigned NumFieldsToCheck>
struct CheckFieldsAreDeviceCopyable
: CheckFieldsAreDeviceCopyable<T, NumFieldsToCheck - 1> {
using FieldT = decltype(__builtin_field_type(T, NumFieldsToCheck - 1));
static_assert(is_device_copyable_v<FieldT> ||
detail::IsDeprecatedDeviceCopyable<FieldT>::value,
"The specified type is not device copyable");
};

template <typename T> struct CheckFieldsAreDeviceCopyable<T, 0> {};

// Checks that the base classes of the type T with indices 0 to
// (NumFieldsToCheck - 1) are device copyable.
template <typename T, unsigned NumBasesToCheck>
struct CheckBasesAreDeviceCopyable
: CheckBasesAreDeviceCopyable<T, NumBasesToCheck - 1> {
using BaseT = decltype(__builtin_base_type(T, NumBasesToCheck - 1));
static_assert(is_device_copyable_v<BaseT> ||
detail::IsDeprecatedDeviceCopyable<BaseT>::value,
"The specified type is not device copyable");
};

template <typename T> struct CheckBasesAreDeviceCopyable<T, 0> {};

// All the captures of a lambda or functor of type FuncT passed to a kernel
// must be is_device_copyable, which extends to bases and fields of FuncT.
// Fields are captures of lambda/functors and bases are possible base classes
// of functors also allowed by SYCL.
// The SYCL-2020 implementation must check each of the fields & bases of the
// type FuncT, only one level deep, which is enough to see if they are all
// device copyable by using the result of is_device_copyable returned for them.
// At this moment though the check also allowes using types for which
// (is_trivially_copy_constructible && is_trivially_destructible) returns true
// and (is_device_copyable) returns false. That is the deprecated behavior and
// is currently/temporarily supported only to not break older SYCL programs.
template <typename FuncT>
struct CheckDeviceCopyable
: CheckFieldsAreDeviceCopyable<FuncT, __builtin_num_fields(FuncT)>,
CheckBasesAreDeviceCopyable<FuncT, __builtin_num_bases(FuncT)> {};

// Below are two specializations for CheckDeviceCopyable when a kernel lambda
// is wrapped after range rounding optimization.
template <typename TransformedArgType, int Dims, typename KernelType>
struct CheckDeviceCopyable<
RoundedRangeKernel<TransformedArgType, Dims, KernelType>>
: CheckDeviceCopyable<KernelType> {};

template <typename TransformedArgType, int Dims, typename KernelType>
struct CheckDeviceCopyable<
RoundedRangeKernelWithKH<TransformedArgType, Dims, KernelType>>
: CheckDeviceCopyable<KernelType> {};

#endif // __SYCL_DEVICE_ONLY__
} // namespace detail
} // namespace _V1
} // namespace sycl

0 comments on commit d1d7e1d

Please sign in to comment.