co-authored by
Aniket Shivam
parent
9b8166e3f0
commit
d572cc1aab
+20
-10
@@ -99,8 +99,12 @@ namespace cute
|
||||
|
||||
// A dummy function that uses compilation failure to print a type
|
||||
template <class T>
|
||||
CUTE_HOST_DEVICE
|
||||
void
|
||||
CUTE_HOST_DEVICE void
|
||||
print_type() {
|
||||
static_assert(sizeof(T) < 0, "Printing type T.");
|
||||
}
|
||||
template <class T>
|
||||
CUTE_HOST_DEVICE void
|
||||
print_type(T&&) {
|
||||
static_assert(sizeof(T) < 0, "Printing type T.");
|
||||
}
|
||||
@@ -113,13 +117,23 @@ print_type(T&&) {
|
||||
// if (block0()) print(...);
|
||||
// if (thread(42)) print(...);
|
||||
|
||||
CUTE_HOST_DEVICE
|
||||
bool
|
||||
block(int bid)
|
||||
{
|
||||
#if defined(__CUDA_ARCH__)
|
||||
return blockIdx.x + blockIdx.y*gridDim.x + blockIdx.z*gridDim.x*gridDim.y == bid;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
CUTE_HOST_DEVICE
|
||||
bool
|
||||
thread(int tid, int bid)
|
||||
{
|
||||
#if defined(__CUDA_ARCH__)
|
||||
return (threadIdx.x + threadIdx.y*blockDim.x + threadIdx.z*blockDim.x*blockDim.y == tid)
|
||||
&& ( blockIdx.x + blockIdx.y* gridDim.x + blockIdx.z* gridDim.x* gridDim.y == bid);
|
||||
return (threadIdx.x + threadIdx.y*blockDim.x + threadIdx.z*blockDim.x*blockDim.y == tid) && block(bid);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
@@ -129,7 +143,7 @@ CUTE_HOST_DEVICE
|
||||
bool
|
||||
thread(int tid)
|
||||
{
|
||||
return thread(tid, 0);
|
||||
return thread(tid,0);
|
||||
}
|
||||
|
||||
CUTE_HOST_DEVICE
|
||||
@@ -143,11 +157,7 @@ CUTE_HOST_DEVICE
|
||||
bool
|
||||
block0()
|
||||
{
|
||||
#if defined(__CUDA_ARCH__)
|
||||
return !(blockIdx.x | blockIdx.y | blockIdx.z);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
return block(0);
|
||||
}
|
||||
|
||||
} // end namespace cute
|
||||
|
||||
@@ -30,10 +30,11 @@
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <cute/config.hpp>
|
||||
|
||||
#include <cute/util/type_traits.hpp>
|
||||
#include <cute/numeric/integral_constant.hpp>
|
||||
|
||||
//
|
||||
// CUDA compatible print and printf
|
||||
//
|
||||
@@ -123,7 +124,7 @@ print(char const& c) {
|
||||
}
|
||||
|
||||
template <class T,
|
||||
__CUTE_REQUIRES(std::is_integral<T>::value)>
|
||||
__CUTE_REQUIRES(CUTE_STL_NAMESPACE::is_integral<T>::value)>
|
||||
CUTE_HOST_DEVICE
|
||||
void
|
||||
print(T const& a) {
|
||||
|
||||
@@ -30,32 +30,97 @@
|
||||
**************************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#if defined(__CUDACC_RTC__)
|
||||
#include <cuda/std/type_traits>
|
||||
#include <cuda/std/utility>
|
||||
#include <cuda/std/cstddef>
|
||||
#include <cuda/std/cstdint>
|
||||
#include <cuda/std/limits>
|
||||
#else
|
||||
#include <type_traits>
|
||||
#include <utility> // tuple_size, tuple_element
|
||||
#include <cstddef> // ptrdiff_t
|
||||
#include <cstdint> // uintptr_t
|
||||
#include <limits> // numeric_limits
|
||||
#endif
|
||||
|
||||
#include <cute/config.hpp>
|
||||
|
||||
#define __CUTE_REQUIRES(...) typename std::enable_if<(__VA_ARGS__)>::type* = nullptr
|
||||
#define __CUTE_REQUIRES_V(...) typename std::enable_if<decltype((__VA_ARGS__))::value>::type* = nullptr
|
||||
namespace cute
|
||||
{
|
||||
using CUTE_STL_NAMESPACE::enable_if;
|
||||
using CUTE_STL_NAMESPACE::enable_if_t;
|
||||
}
|
||||
|
||||
#define __CUTE_REQUIRES(...) typename cute::enable_if<(__VA_ARGS__)>::type* = nullptr
|
||||
#define __CUTE_REQUIRES_V(...) typename cute::enable_if<decltype((__VA_ARGS__))::value>::type* = nullptr
|
||||
|
||||
namespace cute
|
||||
{
|
||||
|
||||
using std::conjunction;
|
||||
using std::conjunction_v;
|
||||
// <type_traits>
|
||||
using CUTE_STL_NAMESPACE::conjunction;
|
||||
using CUTE_STL_NAMESPACE::conjunction_v;
|
||||
|
||||
using std::disjunction;
|
||||
using std::disjunction_v;
|
||||
using CUTE_STL_NAMESPACE::disjunction;
|
||||
using CUTE_STL_NAMESPACE::disjunction_v;
|
||||
|
||||
using std::negation;
|
||||
using std::negation_v;
|
||||
using CUTE_STL_NAMESPACE::negation;
|
||||
using CUTE_STL_NAMESPACE::negation_v;
|
||||
|
||||
using std::void_t;
|
||||
using CUTE_STL_NAMESPACE::void_t;
|
||||
using CUTE_STL_NAMESPACE::is_void_v;
|
||||
|
||||
using CUTE_STL_NAMESPACE::is_base_of;
|
||||
using CUTE_STL_NAMESPACE::is_base_of_v;
|
||||
|
||||
// using CUTE_STL_NAMESPACE::true_type;
|
||||
// using CUTE_STL_NAMESPACE::false_type;
|
||||
|
||||
using CUTE_STL_NAMESPACE::conditional;
|
||||
using CUTE_STL_NAMESPACE::conditional_t;
|
||||
|
||||
using CUTE_STL_NAMESPACE::remove_cv_t;
|
||||
using CUTE_STL_NAMESPACE::remove_reference_t;
|
||||
|
||||
using CUTE_STL_NAMESPACE::extent;
|
||||
using CUTE_STL_NAMESPACE::remove_extent;
|
||||
|
||||
using CUTE_STL_NAMESPACE::decay;
|
||||
using CUTE_STL_NAMESPACE::decay_t;
|
||||
|
||||
using CUTE_STL_NAMESPACE::is_reference;
|
||||
using CUTE_STL_NAMESPACE::is_trivially_copyable;
|
||||
|
||||
using CUTE_STL_NAMESPACE::is_same;
|
||||
using CUTE_STL_NAMESPACE::is_same_v;
|
||||
|
||||
using CUTE_STL_NAMESPACE::is_arithmetic;
|
||||
using CUTE_STL_NAMESPACE::is_unsigned;
|
||||
using CUTE_STL_NAMESPACE::is_signed;
|
||||
// using CUTE_STL_NAMESPACE::is_integral;
|
||||
|
||||
using CUTE_STL_NAMESPACE::is_empty;
|
||||
|
||||
using CUTE_STL_NAMESPACE::invoke_result_t;
|
||||
|
||||
// <utility>
|
||||
using CUTE_STL_NAMESPACE::declval;
|
||||
|
||||
// <limits>
|
||||
using CUTE_STL_NAMESPACE::numeric_limits;
|
||||
|
||||
// <cstddef>
|
||||
using CUTE_STL_NAMESPACE::ptrdiff_t;
|
||||
|
||||
// <cstdint>
|
||||
using CUTE_STL_NAMESPACE::uintptr_t;
|
||||
|
||||
// C++20
|
||||
// using std::remove_cvref;
|
||||
template <class T>
|
||||
struct remove_cvref {
|
||||
using type = std::remove_cv_t<std::remove_reference_t<T>>;
|
||||
using type = remove_cv_t<remove_reference_t<T>>;
|
||||
};
|
||||
|
||||
// C++20
|
||||
@@ -63,38 +128,79 @@ struct remove_cvref {
|
||||
template <class T>
|
||||
using remove_cvref_t = typename remove_cvref<T>::type;
|
||||
|
||||
//
|
||||
// dependent_false
|
||||
//
|
||||
// @brief An always-false value that depends on one or more template parameters.
|
||||
// See
|
||||
// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1830r1.pdf
|
||||
// https://github.com/cplusplus/papers/issues/572
|
||||
// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2593r0.html
|
||||
template <class... Args>
|
||||
inline constexpr bool dependent_false = false;
|
||||
|
||||
//
|
||||
// tuple_size, tuple_element
|
||||
//
|
||||
// @brief CuTe-local tuple-traits to prevent conflicts with other libraries.
|
||||
// For cute:: types, we specialize std::tuple-traits, which is explicitly allowed.
|
||||
// cute::tuple, cute::array, cute::array_subbyte, etc
|
||||
// But CuTe wants to treat some external types as tuples as well. For those,
|
||||
// we specialize cute::tuple-traits to avoid polluting external traits.
|
||||
// dim3, uint3, etc
|
||||
|
||||
template <class T, class = void>
|
||||
struct tuple_size;
|
||||
|
||||
template <class T>
|
||||
struct tuple_size<T,void_t<typename CUTE_STL_NAMESPACE::tuple_size<T>::type>> : CUTE_STL_NAMESPACE::integral_constant<size_t, CUTE_STL_NAMESPACE::tuple_size<T>::value> {};
|
||||
|
||||
// S = : std::integral_constant<std::size_t, std::tuple_size<T>::value> {};
|
||||
|
||||
template <class T>
|
||||
constexpr size_t tuple_size_v = tuple_size<T>::value;
|
||||
|
||||
template <size_t I, class T, class = void>
|
||||
struct tuple_element;
|
||||
|
||||
template <size_t I, class T>
|
||||
struct tuple_element<I,T,void_t<typename CUTE_STL_NAMESPACE::tuple_element<I,T>::type>> : CUTE_STL_NAMESPACE::tuple_element<I,T> {};
|
||||
|
||||
template <size_t I, class T>
|
||||
using tuple_element_t = typename tuple_element<I,T>::type;
|
||||
|
||||
//
|
||||
// is_valid
|
||||
//
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class F, class... Args, class = decltype(std::declval<F&&>()(std::declval<Args&&>()...))>
|
||||
CUTE_HOST_DEVICE constexpr auto
|
||||
is_valid_impl(int) { return std::true_type{}; }
|
||||
template <class F, class... Args, class = decltype(declval<F&&>()(declval<Args&&>()...))>
|
||||
CUTE_HOST_DEVICE constexpr auto
|
||||
is_valid_impl(int) { return CUTE_STL_NAMESPACE::true_type{}; }
|
||||
|
||||
template <class F, class... Args>
|
||||
CUTE_HOST_DEVICE constexpr auto
|
||||
is_valid_impl(...) { return std::false_type{}; }
|
||||
CUTE_HOST_DEVICE constexpr auto
|
||||
is_valid_impl(...) { return CUTE_STL_NAMESPACE::false_type{}; }
|
||||
|
||||
template <class F>
|
||||
struct is_valid_fn {
|
||||
template <class... Args>
|
||||
CUTE_HOST_DEVICE constexpr auto
|
||||
CUTE_HOST_DEVICE constexpr auto
|
||||
operator()(Args&&...) const { return is_valid_impl<F, Args&&...>(int{}); }
|
||||
};
|
||||
|
||||
} // end namespace detail
|
||||
|
||||
template <class F>
|
||||
CUTE_HOST_DEVICE constexpr auto
|
||||
is_valid(F&&) {
|
||||
CUTE_HOST_DEVICE constexpr auto
|
||||
is_valid(F&&) {
|
||||
return detail::is_valid_fn<F&&>{};
|
||||
}
|
||||
|
||||
template <class F, class... Args>
|
||||
CUTE_HOST_DEVICE constexpr auto
|
||||
is_valid(F&&, Args&&...) {
|
||||
CUTE_HOST_DEVICE constexpr auto
|
||||
is_valid(F&&, Args&&...) {
|
||||
return detail::is_valid_impl<F&&, Args&&...>(int{});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user