Commit 79970ac7 authored by Carter Edwards's avatar Carter Edwards
Browse files

Kokkos: Simplify and improve compile-time robustness of View.

A templated function interface can be disable through 'enable_if'.
A non-templated function interface can be disabled by substituting
its input or return type with a unusable error-tag class based upon
a compile time condition.  For example, a View has an device shared
memory constructor if it is unmanaged.  If the View is managed then
the device argument type is substituted for the class
'ViewError::device_shmem_constructor_requires_unmanaged'.
parent 0801dbb7
......@@ -7,7 +7,7 @@
#include <Kokkos_View.hpp>
#include <Kokkos_Atomic.hpp>
#include <impl/Kokkos_ArrayTraits.hpp>
#include <impl/Kokkos_Traits.hpp>
#include <impl/Kokkos_UnorderedMap_impl.hpp>
#include <iostream>
......
......@@ -88,29 +88,6 @@ struct AssertShapeBoundsAbort< CudaSpace >
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
namespace Kokkos {
template< typename ValueType , class LayoutSrc , class MemoryTraits >
inline
void deep_copy( ValueType & dst ,
const View< ValueType , LayoutSrc , Cuda , MemoryTraits , Impl::LayoutScalar > & src )
{
(void)Impl::DeepCopy<HostSpace,CudaSpace>( & dst , src.ptr_on_device() , sizeof(ValueType) );
}
template< typename ValueType , class LayoutDst , class MemoryTraits >
inline
void deep_copy( const View< ValueType , LayoutDst , Cuda , MemoryTraits , Impl::LayoutScalar > & dst ,
const ValueType & src )
{
(void)Impl::DeepCopy<CudaSpace,HostSpace>( dst.ptr_on_device() , & src , sizeof(ValueType) );
}
} // namespace Kokkos
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
namespace Kokkos {
namespace Impl {
......
......@@ -50,7 +50,7 @@
#include <Kokkos_Macros.hpp>
#include <Kokkos_MemoryTraits.hpp>
#include <impl/Kokkos_ArrayTraits.hpp>
#include <impl/Kokkos_Traits.hpp>
/*--------------------------------------------------------------------------*/
......
......@@ -46,7 +46,7 @@
#ifndef KOKKOS_LAYOUT_HPP
#define KOKKOS_LAYOUT_HPP
#include <impl/Kokkos_ArrayTraits.hpp>
#include <impl/Kokkos_Traits.hpp>
namespace Kokkos {
......
......@@ -46,7 +46,7 @@
#include <cstddef>
#include <Kokkos_Macros.hpp>
#include <impl/Kokkos_ArrayTraits.hpp>
#include <impl/Kokkos_Traits.hpp>
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
......
......@@ -51,7 +51,7 @@
#include <Kokkos_MemoryTraits.hpp>
#include <impl/Kokkos_StaticAssert.hpp>
#include <impl/Kokkos_ArrayTraits.hpp>
#include <impl/Kokkos_Traits.hpp>
#include <impl/Kokkos_Shape.hpp>
#include <impl/Kokkos_AnalyzeShape.hpp>
......@@ -476,8 +476,8 @@ template< class OutputView , class InputView >
struct ViewRemap< OutputView , InputView , 0 >
{
typedef typename OutputView::value_type value_type ;
typedef typename OutputView::device_space dst_space ;
typedef typename InputView ::device_space src_space ;
typedef typename OutputView::memory_space dst_space ;
typedef typename InputView ::memory_space src_space ;
ViewRemap( const OutputView & arg_out , const InputView & arg_in )
{
......@@ -523,7 +523,7 @@ struct ViewFill< OutputView , 0 >
{
typedef typename OutputView::device_type device_type ;
typedef typename OutputView::const_value_type const_value_type ;
typedef typename OutputView::device_space dst_space ;
typedef typename OutputView::memory_space dst_space ;
ViewFill( const OutputView & arg_out , const_value_type & arg_in )
{
......@@ -810,40 +810,53 @@ subview( const View<T,L,D,M,S> & src ,
template< class T , class L , class D , class M , class S >
typename View<T,L,D,M,S>::HostMirror
create_mirror_view( const View<T,L,D,M,S> & view ,
typename Impl::enable_if<
Impl::ViewAssignable< typename View<T,L,D,M,S>::HostMirror , View<T,L,D,M,S> >::value
>::type * = 0 )
typename Impl::enable_if<(
View<T,L,D,M,S>::is_managed
), typename View<T,L,D,M,S>::HostMirror >::type
inline
create_mirror( const View<T,L,D,M,S> & src )
{
return view ;
typedef View<T,L,D,M,S> view_type ;
typedef typename view_type::HostMirror host_view_type ;
typedef typename view_type::memory_space memory_space ;
// 'view' is managed therefore we can allocate a
// compatible host_view through the ordinary constructor.
std::string label = memory_space::query_label( src.ptr_on_device() );
label.append("_mirror");
return host_view_type( label ,
src.dimension_0() ,
src.dimension_1() ,
src.dimension_2() ,
src.dimension_3() ,
src.dimension_4() ,
src.dimension_5() ,
src.dimension_6() ,
src.dimension_7() );
}
template< class T , class L , class D , class M , class S >
typename View<T,L,D,M,S>::HostMirror
create_mirror_view( const View<T,L,D,M,S> & view ,
typename Impl::enable_if<
! Impl::ViewAssignable< typename View<T,L,D,M,S>::HostMirror , View<T,L,D,M,S> >::value
>::type * = 0 )
typename Impl::enable_if<(
View<T,L,D,M,S>::is_managed &&
Impl::ViewAssignable< typename View<T,L,D,M,S>::HostMirror , View<T,L,D,M,S> >::value
), typename View<T,L,D,M,S>::HostMirror >::type
inline
create_mirror_view( const View<T,L,D,M,S> & src )
{
typedef typename View<T,L,D,M,S>::HostMirror host_view ;
host_view tmp ;
Impl::ViewAssignment< S >( tmp , view );
return tmp ;
return src ;
}
template< class T , class L , class D , class M , class S >
typename View<T,L,D,M,S>::HostMirror
create_mirror( const View<T,L,D,M,S> & view )
typename Impl::enable_if<(
View<T,L,D,M,S>::is_managed &&
! Impl::ViewAssignable< typename View<T,L,D,M,S>::HostMirror , View<T,L,D,M,S> >::value
), typename View<T,L,D,M,S>::HostMirror >::type
inline
create_mirror_view( const View<T,L,D,M,S> & src )
{
#if KOKKOS_MIRROR_VIEW_OPTIMIZE
return create_mirror_view( view );
#else
typedef typename View<T,L,D,M,S>::HostMirror host_view ;
host_view tmp ;
Impl::ViewAssignment< S >( tmp , view );
return tmp ;
#endif
return create_mirror( src );
}
} // namespace Kokkos
......@@ -852,7 +865,6 @@ create_mirror( const View<T,L,D,M,S> & view )
//----------------------------------------------------------------------------
#include <impl/Kokkos_ViewDefault.hpp>
#include <impl/Kokkos_ViewScalar.hpp>
#include <impl/Kokkos_ViewTileLeft.hpp>
//----------------------------------------------------------------------------
......
......@@ -46,7 +46,7 @@
#include <Kokkos_HostSpace.hpp>
#include <Kokkos_Parallel.hpp>
#include <impl/Kokkos_ArrayTraits.hpp>
#include <impl/Kokkos_Traits.hpp>
namespace Kokkos {
namespace Impl {
......
......@@ -158,20 +158,6 @@ void deep_copy( const View< DT, DL, OpenMP, DM, DS> & dst ,
Impl::OpenMPViewRemap< dst_type , src_type , dst_type::rank >( dst , src );
}
/** \brief Deep copy of scalar value */
template< typename ValueType , class LayoutSrc , class MemoryTraits >
inline
void deep_copy( ValueType & dst ,
const View< ValueType , LayoutSrc , OpenMP , MemoryTraits , Impl::LayoutScalar > & src )
{ dst = src ; }
template< typename ValueType , class LayoutDst , class MemoryTraits >
inline
void deep_copy( const View< ValueType , LayoutDst , OpenMP , MemoryTraits , Impl::LayoutScalar > & dst ,
const ValueType & src )
{ dst = src ; }
} // namespace Kokkos
#endif /* #ifndef KOKKOS_OPENMP_VIEW_HPP */
......
......@@ -52,31 +52,17 @@ namespace Kokkos {
template< class DataType , class Arg1Type , class Arg2Type , typename SizeType >
inline
typename CrsArray< DataType , Arg1Type , Arg2Type , SizeType >::HostMirror
create_mirror_view( const CrsArray<DataType,Arg1Type,Arg2Type,SizeType > & view ,
typename Impl::enable_if< ViewTraits<DataType,Arg1Type,Arg2Type,void>::is_hostspace >::type * = 0 )
{
return view ;
}
template< class DataType , class Arg1Type , class Arg2Type , typename SizeType >
inline
typename CrsArray< DataType , Arg1Type , Arg2Type , SizeType >::HostMirror
create_mirror_view( const CrsArray<DataType,Arg1Type,Arg2Type,SizeType > & view ,
typename Impl::enable_if< ! ViewTraits<DataType,Arg1Type,Arg2Type,void>::is_hostspace >::type * = 0 )
create_mirror( const CrsArray<DataType,Arg1Type,Arg2Type,SizeType > & view )
{
// Force copy:
typedef Impl::ViewAssignment< Impl::LayoutDefault > alloc ;
typedef CrsArray< DataType , Arg1Type , Arg2Type , SizeType > crsarray_type ;
typename crsarray_type::HostMirror tmp ;
typename crsarray_type::row_map_type::HostMirror tmp_row_map ;
// Allocation to match:
(void)alloc( tmp_row_map , view.row_map );
(void)alloc( tmp.entries , view.entries );
typename crsarray_type::row_map_type::HostMirror tmp_row_map = create_mirror( view.row_map );
// Assignment of 'const' from 'non-const'
tmp.row_map = tmp_row_map ;
tmp.row_map = tmp_row_map ; // Assignment of 'const' from 'non-const'
tmp.entries = create_mirror( view.entries );
// Deep copy:
deep_copy( tmp_row_map , view.row_map );
......@@ -88,34 +74,22 @@ create_mirror_view( const CrsArray<DataType,Arg1Type,Arg2Type,SizeType > & view
template< class DataType , class Arg1Type , class Arg2Type , typename SizeType >
inline
typename CrsArray< DataType , Arg1Type , Arg2Type , SizeType >::HostMirror
create_mirror( const CrsArray<DataType,Arg1Type,Arg2Type,SizeType > & view )
create_mirror_view( const CrsArray<DataType,Arg1Type,Arg2Type,SizeType > & view ,
typename Impl::enable_if< ViewTraits<DataType,Arg1Type,Arg2Type,void>::is_hostspace >::type * = 0 )
{
#if KOKKOS_MIRROR_VIEW_OPTIMIZE
// Allow choice via type:
return create_mirror_view( view );
#else
// Force copy:
typedef Impl::ViewAssignment< Impl::LayoutDefault > alloc ;
typedef CrsArray< DataType , Arg1Type , Arg2Type , SizeType > crsarray_type ;
typename crsarray_type::HostMirror tmp ;
typename crsarray_type::row_map_type::HostMirror tmp_row_map ;
// Allocation to match:
(void)alloc( tmp_row_map , view.row_map );
(void)alloc( tmp.entries , view.entries );
// Assignment of 'const' from 'non-const'
tmp.row_map = tmp_row_map ;
// Deep copy:
deep_copy( tmp_row_map , view.row_map );
deep_copy( tmp.entries , view.entries );
return view ;
}
return tmp ;
#endif
template< class DataType , class Arg1Type , class Arg2Type , typename SizeType >
inline
typename CrsArray< DataType , Arg1Type , Arg2Type , SizeType >::HostMirror
create_mirror_view( const CrsArray<DataType,Arg1Type,Arg2Type,SizeType > & view ,
typename Impl::enable_if< ! ViewTraits<DataType,Arg1Type,Arg2Type,void>::is_hostspace >::type * = 0 )
{
return create_mirror( view );
}
} // namespace Kokkos
//----------------------------------------------------------------------------
......
......@@ -57,12 +57,6 @@ struct PhysicalLayout {
int rank;
long long int stride[8]; //distance between two neighboring elements in a given dimension
template< class T , class L , class D , class M >
PhysicalLayout( const View<T,L,D,M,LayoutScalar> & view )
: layout_type( Scalar )
, rank( 0 )
{ for(int i=0;i<8;i++) stride[i] = 0; }
template< class T , class L , class D , class M >
PhysicalLayout( const View<T,L,D,M,LayoutDefault> & view )
: layout_type( is_same< typename View<T,L,D,M>::array_layout , LayoutLeft >::value ? Left : (
......
......@@ -48,7 +48,7 @@
#include <utility>
#include <Kokkos_Macros.hpp>
#include <Kokkos_Layout.hpp>
#include <impl/Kokkos_ArrayTraits.hpp>
#include <impl/Kokkos_Traits.hpp>
#include <impl/Kokkos_StaticAssert.hpp>
//----------------------------------------------------------------------------
......
......@@ -44,13 +44,58 @@
#ifndef KOKKOSTRAITS_HPP
#define KOKKOSTRAITS_HPP
#include <Kokkos_Macros.hpp>
namespace Kokkos {
namespace Impl {
/* TR1 conformal compile-time array traits utilities.
* Prefer to use TR1 when portably available.
/* C++11 conformal compile-time type traits utilities.
* Prefer to use C++11 when portably available.
*/
//----------------------------------------------------------------------------
// C++11 Helpers:
template < class T , T v >
struct integral_constant
{
static const T value = v ;
typedef T value_type;
typedef integral_constant<T,v> type;
KOKKOS_INLINE_FUNCTION operator T() { return v ; }
};
typedef integral_constant<bool,false> false_type ;
typedef integral_constant<bool,true> true_type ;
//----------------------------------------------------------------------------
// C++11 Type relationships:
template< class X , class Y > struct is_same : public false_type {};
template< class X > struct is_same<X,X> : public true_type {};
//----------------------------------------------------------------------------
// C++11 Type properties:
template <typename T> struct is_const : public false_type {};
template <typename T> struct is_const<const T> : public true_type {};
//----------------------------------------------------------------------------
// C++11 Type transformations:
template <typename T> struct remove_const { typedef T type; };
template <typename T> struct remove_const<const T> { typedef T type; };
template <typename T> struct add_const { typedef const T type; };
template <typename T> struct add_const<const T> { typedef const T type; };
//----------------------------------------------------------------------------
// C++11 Other type generators:
template< bool , class T , class F >
struct condition { typedef F type ; };
template< class T , class F >
struct condition<true,T,F> { typedef T type ; };
template< bool , class = void >
struct enable_if ;
......@@ -58,21 +103,24 @@ struct enable_if ;
template< class T >
struct enable_if< true , T > { typedef T type ; };
template< class , class T = void >
struct enable_if_type { typedef T type ; };
//----------------------------------------------------------------------------
} // namespace Impl
} // namespace Kokkos
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Other traits
template <class T, T v>
struct integral_constant
{
static const T value = v;
typedef T value_type;
typedef integral_constant<T,v> type;
};
namespace Kokkos {
namespace Impl {
typedef integral_constant<bool,false> false_type ;
typedef integral_constant<bool,true> true_type ;
//----------------------------------------------------------------------------
template< class , class T = void >
struct enable_if_type { typedef T type ; };
//----------------------------------------------------------------------------
template< bool B >
struct bool_ : public integral_constant<bool,B> {};
......@@ -84,9 +132,72 @@ template< int I >
struct int_ : public integral_constant<int,I> {};
//----------------------------------------------------------------------------
/** \brief If is the same type */
template< class X , class Y > struct is_same : public false_type {};
template< class X > struct is_same<X,X> : public true_type {};
// if_
template < bool Cond , typename TrueType , typename FalseType>
struct if_c
{
enum { value = Cond };
typedef FalseType type;
static KOKKOS_INLINE_FUNCTION
typename add_const<type>::type &
select( typename add_const<type>::type & v ) { return v ; }
static KOKKOS_INLINE_FUNCTION
typename remove_const<type>::type &
select( typename remove_const<type>::type & v ) { return v ; }
template< class T >
static KOKKOS_INLINE_FUNCTION
type select( const T & ) { return type(); }
template< class T >
static KOKKOS_INLINE_FUNCTION
typename add_const<type>::type &
select( const T & , typename add_const<type>::type & v ) { return v ; }
template< class T >
static KOKKOS_INLINE_FUNCTION
typename remove_const<type>::type &
select( const T & , typename remove_const<type>::type & v ) { return v ; }
};
template <typename TrueType, typename FalseType>
struct if_c< true , TrueType , FalseType >
{
enum { value = true };
typedef TrueType type;
static KOKKOS_INLINE_FUNCTION
typename add_const<type>::type &
select( typename add_const<type>::type & v ) { return v ; }
static KOKKOS_INLINE_FUNCTION
typename remove_const<type>::type &
select( typename remove_const<type>::type & v ) { return v ; }
template< class F >
static KOKKOS_INLINE_FUNCTION
type select( const F & ) { return type(); }
template< class F >
static KOKKOS_INLINE_FUNCTION
typename add_const<type>::type &
select( typename add_const<type>::type & v , const F & ) { return v ; }
template< class F >
static KOKKOS_INLINE_FUNCTION
typename remove_const<type>::type &
select( typename remove_const<type>::type & v , const F & ) { return v ; }
};
template <typename Cond, typename TrueType, typename FalseType>
struct if_ : public if_c<Cond::value, TrueType, FalseType> {};
//----------------------------------------------------------------------------
......@@ -118,45 +229,6 @@ struct power_of_two<1,true>
};
//----------------------------------------------------------------------------
// is_const
template <typename T>
struct is_const : public false_type {};
template <typename T>
struct is_const<const T> : public true_type {};
template <typename T> struct remove_const { typedef T type; };
template <typename T> struct remove_const<const T> { typedef T type; };
template <typename T> struct add_const { typedef const T type; };
template <typename T> struct add_const<const T> { typedef const T type; };
//----------------------------------------------------------------------------
// if_
template < bool Cond , typename TrueType, typename FalseType>
struct if_c
{
typedef TrueType type;
template< class T >
static inline const TrueType & select(const TrueType & a, const T & ) {return a;}
};
template <typename TrueType, typename FalseType>
struct if_c<false, TrueType, FalseType>
{
typedef FalseType type;
template< class T >
static inline const FalseType & select(const T & , const FalseType & b) {return b;}
};
template <typename Cond, typename TrueType, typename FalseType>
struct if_
: public if_c<Cond::value, TrueType, FalseType>
{};
} // namespace Impl
} // namespace Kokkos
......
This diff is collapsed.
......@@ -143,11 +143,11 @@ private:
public:
typedef Kokkos::View< const unsigned * [ElemNode] , Device , Kokkos::MemoryUnmanaged > elem_node_type ;
typedef Kokkos::View< const double * [3] , Device , Kokkos::MemoryUnmanaged > node_coord_type ;
typedef Kokkos::View< const unsigned * [3] , Device , Kokkos::MemoryUnmanaged > node_grid_type ;
typedef Kokkos::View< const unsigned * [2] , Device , Kokkos::MemoryUnmanaged > comm_list_type ;
typedef Kokkos::View< const unsigned * , Device , Kokkos::MemoryUnmanaged > send_nodeid_type ;
typedef Kokkos::View< const unsigned * [ElemNode] , Device > elem_node_type ;
typedef Kokkos::View< const double * [3] , Device > node_coord_type ;
typedef Kokkos::View< const unsigned * [3] , Device > node_grid_type ;
typedef Kokkos::View< const unsigned * [2] , Device > comm_list_type ;
typedef Kokkos::View< const unsigned * , Device > send_nodeid_type ;
KOKKOS_INLINE_FUNCTION
unsigned node_count() const { return m_node_grid.dimension_0(); }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment