#ifndef KOKKOS_CORE_CONCEPTS_HPP
#define KOKKOS_CORE_CONCEPTS_HPP
#include <type_traits>
#include <Kokkos_Core_fwd.hpp>
namespace Kokkos {
struct Static {};
struct Dynamic {};
template<class T>
struct Schedule
{
static_assert( std::is_same<T,Static>::value
|| std::is_same<T,Dynamic>::value
, "Kokkos: Invalid Schedule<> type."
);
using schedule_type = Schedule ;
using type = T;
};
template<typename T>
struct IndexType
{
static_assert(std::is_integral<T>::value,"Kokkos: Invalid IndexType<>.");
using index_type = IndexType ;
using type = T;
};
namespace Experimental {
struct WorkItemProperty {
template<unsigned long Property>
struct ImplWorkItemProperty {
static const unsigned value = Property;
using work_item_property = ImplWorkItemProperty<Property>;
};
constexpr static const ImplWorkItemProperty<0> None = ImplWorkItemProperty<0>();
constexpr static const ImplWorkItemProperty<1> HintLightWeight = ImplWorkItemProperty<1>();
constexpr static const ImplWorkItemProperty<2> HintHeavyWeight = ImplWorkItemProperty<2>();
constexpr static const ImplWorkItemProperty<4> HintRegular = ImplWorkItemProperty<4>();
constexpr static const ImplWorkItemProperty<8> HintIrregular = ImplWorkItemProperty<8>();
typedef ImplWorkItemProperty<0> None_t;
typedef ImplWorkItemProperty<1> HintLightWeight_t;
typedef ImplWorkItemProperty<2> HintHeavyWeight_t;
typedef ImplWorkItemProperty<4> HintRegular_t;
typedef ImplWorkItemProperty<8> HintIrregular_t;
};
template<unsigned long pv1, unsigned long pv2>
inline constexpr WorkItemProperty::ImplWorkItemProperty<pv1|pv2> operator |
(WorkItemProperty::ImplWorkItemProperty<pv1>, WorkItemProperty::ImplWorkItemProperty<pv2>) {
return WorkItemProperty::ImplWorkItemProperty<pv1|pv2>();
}
template<unsigned long pv1, unsigned long pv2>
inline constexpr WorkItemProperty::ImplWorkItemProperty<pv1&pv2> operator &
(WorkItemProperty::ImplWorkItemProperty<pv1>, WorkItemProperty::ImplWorkItemProperty<pv2>) {
return WorkItemProperty::ImplWorkItemProperty<pv1&pv2>();
}
template<unsigned long pv1, unsigned long pv2>
inline constexpr bool operator == (WorkItemProperty::ImplWorkItemProperty<pv1>, WorkItemProperty::ImplWorkItemProperty<pv2>) {
return pv1 == pv2;
}
}
template< unsigned int maxT = 0
, unsigned int minB = 0
>
struct LaunchBounds
{
using launch_bounds = LaunchBounds;
using type = LaunchBounds<maxT,minB>;
static unsigned int constexpr maxTperB {maxT};
static unsigned int constexpr minBperSM {minB};
};
}
namespace Kokkos {
#define KOKKOS_IMPL_IS_CONCEPT( CONCEPT ) \
template< typename T > struct is_ ## CONCEPT { \
private: \
template< typename , typename = std::true_type > struct have : std::false_type {}; \
template< typename U > struct have<U,typename std::is_base_of< \
typename std::remove_cv<typename U:: CONCEPT>::type, \
typename std::remove_cv<U>::type \
>::type> : std::true_type {}; \
template< typename U > struct have<U,typename std::is_base_of< \
typename std::remove_cv<typename U:: CONCEPT ## _type>::type, \
typename std::remove_cv<U>::type \
>::type> : std::true_type {}; \
public: \
enum { value = is_ ## CONCEPT::template have<T>::value }; \
};
KOKKOS_IMPL_IS_CONCEPT( memory_space )
KOKKOS_IMPL_IS_CONCEPT( memory_traits )
KOKKOS_IMPL_IS_CONCEPT( execution_space )
KOKKOS_IMPL_IS_CONCEPT( execution_policy )
KOKKOS_IMPL_IS_CONCEPT( array_layout )
KOKKOS_IMPL_IS_CONCEPT( reducer )
namespace Experimental {
KOKKOS_IMPL_IS_CONCEPT( work_item_property )
}
namespace Impl {
using Kokkos::is_memory_space ;
using Kokkos::is_memory_traits ;
using Kokkos::is_execution_space ;
using Kokkos::is_execution_policy ;
using Kokkos::is_array_layout ;
KOKKOS_IMPL_IS_CONCEPT( iteration_pattern )
KOKKOS_IMPL_IS_CONCEPT( schedule_type )
KOKKOS_IMPL_IS_CONCEPT( index_type )
KOKKOS_IMPL_IS_CONCEPT( launch_bounds )
KOKKOS_IMPL_IS_CONCEPT( thread_team_member )
KOKKOS_IMPL_IS_CONCEPT( host_thread_team_member )
}
#undef KOKKOS_IMPL_IS_CONCEPT
}
namespace Kokkos {
template< class ExecutionSpace , class MemorySpace >
struct Device {
static_assert( Kokkos::is_execution_space<ExecutionSpace>::value
, "Execution space is not valid" );
static_assert( Kokkos::is_memory_space<MemorySpace>::value
, "Memory space is not valid" );
typedef ExecutionSpace execution_space;
typedef MemorySpace memory_space;
typedef Device<execution_space,memory_space> device_type;
};
template< typename T >
struct is_space {
private:
template< typename , typename = void >
struct exe : std::false_type { typedef void space ; };
template< typename , typename = void >
struct mem : std::false_type { typedef void space ; };
template< typename , typename = void >
struct dev : std::false_type { typedef void space ; };
template< typename U >
struct exe<U,typename std::conditional<true,void,typename U::execution_space>::type>
: std::is_same<U,typename U::execution_space>::type
{ typedef typename U::execution_space space ; };
template< typename U >
struct mem<U,typename std::conditional<true,void,typename U::memory_space>::type>
: std::is_same<U,typename U::memory_space>::type
{ typedef typename U::memory_space space ; };
template< typename U >
struct dev<U,typename std::conditional<true,void,typename U::device_type>::type>
: std::is_same<U,typename U::device_type>::type
{ typedef typename U::device_type space ; };
typedef typename is_space::template exe<T> is_exe ;
typedef typename is_space::template mem<T> is_mem ;
typedef typename is_space::template dev<T> is_dev ;
public:
enum { value = is_exe::value || is_mem::value || is_dev::value };
typedef typename is_exe::space execution_space ;
typedef typename is_mem::space memory_space ;
typedef typename std::conditional
< std::is_same< memory_space , Kokkos::HostSpace >::value
#if defined( KOKKOS_ENABLE_CUDA )
|| std::is_same< memory_space , Kokkos::CudaUVMSpace >::value
|| std::is_same< memory_space , Kokkos::CudaHostPinnedSpace >::value
#endif
, memory_space
, Kokkos::HostSpace
>::type host_memory_space ;
#if defined( KOKKOS_ENABLE_CUDA )
typedef typename std::conditional
< std::is_same< execution_space , Kokkos::Cuda >::value
, Kokkos::DefaultHostExecutionSpace , execution_space
>::type host_execution_space ;
#else
#if defined( KOKKOS_ENABLE_OPENMPTARGET )
typedef typename std::conditional
< std::is_same< execution_space , Kokkos::Experimental::OpenMPTarget >::value
, Kokkos::DefaultHostExecutionSpace , execution_space
>::type host_execution_space ;
#else
typedef execution_space host_execution_space ;
#endif
#endif
typedef typename std::conditional
< std::is_same< execution_space , host_execution_space >::value &&
std::is_same< memory_space , host_memory_space >::value
, T , Kokkos::Device< host_execution_space , host_memory_space >
>::type host_mirror_space ;
};
namespace Impl {
using Kokkos::is_space ;
}
}
namespace Kokkos {
namespace Impl {
template< typename DstMemorySpace , typename SrcMemorySpace >
struct MemorySpaceAccess {
static_assert( Kokkos::is_memory_space< DstMemorySpace >::value &&
Kokkos::is_memory_space< SrcMemorySpace >::value
, "template arguments must be memory spaces" );
enum { assignable = std::is_same<DstMemorySpace,SrcMemorySpace>::value };
enum { accessible = assignable };
enum { deepcopy = assignable };
};
}}
namespace Kokkos {
template< typename AccessSpace , typename MemorySpace >
struct SpaceAccessibility {
private:
static_assert( Kokkos::is_space< AccessSpace >::value
, "template argument #1 must be a Kokkos space" );
static_assert( Kokkos::is_memory_space< MemorySpace >::value
, "template argument #2 must be a Kokkos memory space" );
static_assert( Kokkos::Impl::MemorySpaceAccess
< typename AccessSpace::execution_space::memory_space
, typename AccessSpace::memory_space
>::accessible
, "template argument #1 is an invalid space" );
typedef Kokkos::Impl::MemorySpaceAccess
< typename AccessSpace::execution_space::memory_space , MemorySpace >
exe_access ;
typedef Kokkos::Impl::MemorySpaceAccess
< typename AccessSpace::memory_space , MemorySpace >
mem_access ;
public:
enum { accessible = exe_access::accessible };
enum { assignable =
is_memory_space< AccessSpace >::value && mem_access::assignable };
enum { deepcopy = mem_access::deepcopy };
typedef typename std::conditional
< std::is_same<typename AccessSpace::memory_space,MemorySpace>::value ||
! exe_access::accessible
, AccessSpace
, Kokkos::Device< typename AccessSpace::execution_space , MemorySpace >
>::type space ;
};
}
namespace Kokkos {
namespace Impl {
using Kokkos::SpaceAccessibility ;
}}
#endif