//@HEADER // ************************************************************************ // // Kokkos v. 4.0 // Copyright (2022) National Technology & Engineering // Solutions of Sandia, LLC (NTESS). // // Under the terms of Contract DE-NA0003525 with NTESS, // the U.S. Government retains certain rights in this software. // // Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. // See https://kokkos.org/LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //@HEADER #ifndef KOKKOSTRAITS_HPP #define KOKKOSTRAITS_HPP #include #include #include #include #include #include namespace Kokkos { namespace Impl { //---------------------------------------------------------------------------- // Help with C++11 variadic argument packs template struct get_type { using type = void; }; template struct get_type<0, T, Pack...> { using type = T; }; template struct get_type { using type = typename get_type::type; }; template struct has_type { enum : bool { value = false }; }; template struct has_type { private: enum { self_value = std::is_same::value }; using next = has_type; static_assert( !(self_value && next::value), "Error: more than one member of the argument pack matches the type"); public: enum : bool { value = self_value || next::value }; }; template class Condition, typename... Pack> struct has_condition { enum : bool { value = false }; using type = DefaultType; }; template class Condition, typename S, typename... Pack> struct has_condition { private: enum { self_value = Condition::value }; using next = has_condition; static_assert( !(self_value && next::value), "Error: more than one member of the argument pack satisfies condition"); public: enum : bool { value = self_value || next::value }; using type = std::conditional_t; }; template struct are_integral { enum : bool { value = true }; }; template struct are_integral { enum { value = // Accept std::is_integral OR std::is_enum as an integral value // since a simple enum value is automically convertible to an // integral value. (std::is_integral::value || std::is_enum::value) && are_integral::value }; }; //---------------------------------------------------------------------------- } // namespace Impl } // namespace Kokkos //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Other traits namespace Kokkos { namespace Impl { //---------------------------------------------------------------------------- // if_ template struct if_c { enum : bool { value = Cond }; using type = FalseType; using value_type = std::remove_const_t>; using const_value_type = std::add_const_t; static KOKKOS_INLINE_FUNCTION const_value_type& select(const_value_type& v) { return v; } static KOKKOS_INLINE_FUNCTION value_type& select(value_type& v) { return v; } template static KOKKOS_INLINE_FUNCTION value_type& select(const T&) { value_type* ptr(0); return *ptr; } template static KOKKOS_INLINE_FUNCTION const_value_type& select(const T&, const_value_type& v) { return v; } template static KOKKOS_INLINE_FUNCTION value_type& select(const T&, value_type& v) { return v; } }; template struct if_c { enum : bool { value = true }; using type = TrueType; using value_type = std::remove_const_t>; using const_value_type = std::add_const_t; static KOKKOS_INLINE_FUNCTION const_value_type& select(const_value_type& v) { return v; } static KOKKOS_INLINE_FUNCTION value_type& select(value_type& v) { return v; } template static KOKKOS_INLINE_FUNCTION value_type& select(const T&) { value_type* ptr(0); return *ptr; } template static KOKKOS_INLINE_FUNCTION const_value_type& select(const_value_type& v, const F&) { return v; } template static KOKKOS_INLINE_FUNCTION value_type& select(value_type& v, const F&) { return v; } }; template struct if_c { enum : bool { value = false }; using type = void; using value_type = void; }; template struct if_c { enum : bool { value = true }; using type = void; using value_type = void; }; //---------------------------------------------------------------------------- // These 'constexpr'functions can be used as // both regular functions and meta-function. /**\brief There exists integral 'k' such that N = 2^k */ KOKKOS_INLINE_FUNCTION constexpr bool is_integral_power_of_two(const size_t N) { return (0 < N) && (0 == (N & (N - 1))); } /**\brief Return integral 'k' such that N = 2^k, assuming valid. */ KOKKOS_INLINE_FUNCTION constexpr unsigned integral_power_of_two_assume_valid(const size_t N) { return N == 1 ? 0 : 1 + integral_power_of_two_assume_valid(N >> 1); } /**\brief Return integral 'k' such that N = 2^k, if exists. * If does not exist return ~0u. */ KOKKOS_INLINE_FUNCTION constexpr unsigned integral_power_of_two(const size_t N) { return is_integral_power_of_two(N) ? integral_power_of_two_assume_valid(N) : ~0u; } /** \brief If power of two then return power, * otherwise return ~0u. */ KOKKOS_FORCEINLINE_FUNCTION unsigned power_of_two_if_valid(const unsigned N) { unsigned p = ~0u; if (is_integral_power_of_two(N)) { p = bit_scan_forward(N); } return p; } //---------------------------------------------------------------------------- template struct integral_nonzero_constant { // Declaration of 'static const' causes an unresolved linker symbol in debug // static const T value = v ; enum { value = T(v) }; using value_type = T; using type = integral_nonzero_constant; KOKKOS_INLINE_FUNCTION integral_nonzero_constant(const T&) {} }; template struct integral_nonzero_constant { const T value; using value_type = T; using type = integral_nonzero_constant; KOKKOS_INLINE_FUNCTION integral_nonzero_constant(const T& v) : value(v) {} }; //---------------------------------------------------------------------------- template struct make_all_extents_into_pointers { using type = T; }; template struct make_all_extents_into_pointers { using type = typename make_all_extents_into_pointers::type*; }; template struct make_all_extents_into_pointers { using type = typename make_all_extents_into_pointers::type*; }; } // namespace Impl } // namespace Kokkos //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- #endif /* #ifndef KOKKOSTRAITS_HPP */