1916 lines
73 KiB
C++
Executable File
1916 lines
73 KiB
C++
Executable File
/*
|
|
//@HEADER
|
|
// ************************************************************************
|
|
//
|
|
// Kokkos v. 2.0
|
|
// Copyright (2014) Sandia Corporation
|
|
//
|
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
|
// the U.S. Government retains certain rights in this software.
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without
|
|
// modification, are permitted provided that the following conditions are
|
|
// met:
|
|
//
|
|
// 1. Redistributions of source code must retain the above copyright
|
|
// notice, this list of conditions and the following disclaimer.
|
|
//
|
|
// 2. Redistributions in binary form must reproduce the above copyright
|
|
// notice, this list of conditions and the following disclaimer in the
|
|
// documentation and/or other materials provided with the distribution.
|
|
//
|
|
// 3. Neither the name of the Corporation nor the names of the
|
|
// contributors may be used to endorse or promote products derived from
|
|
// this software without specific prior written permission.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
|
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
|
|
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
//
|
|
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
|
|
//
|
|
// ************************************************************************
|
|
//@HEADER
|
|
*/
|
|
|
|
#ifndef KOKKOS_VIEW_HPP
|
|
#define KOKKOS_VIEW_HPP
|
|
|
|
#include <string>
|
|
#include <Kokkos_Core_fwd.hpp>
|
|
#include <Kokkos_HostSpace.hpp>
|
|
#include <Kokkos_MemoryTraits.hpp>
|
|
|
|
#if ! defined( KOKKOS_USING_EXPERIMENTAL_VIEW )
|
|
|
|
#include <impl/Kokkos_StaticAssert.hpp>
|
|
#include <impl/Kokkos_Traits.hpp>
|
|
#include <impl/Kokkos_Shape.hpp>
|
|
#include <impl/Kokkos_AnalyzeShape.hpp>
|
|
#include <impl/Kokkos_ViewOffset.hpp>
|
|
#include <impl/Kokkos_ViewSupport.hpp>
|
|
#include <impl/Kokkos_Tags.hpp>
|
|
#include <type_traits>
|
|
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
|
|
namespace Kokkos {
|
|
namespace Impl {
|
|
|
|
/** \brief View specialization mapping of view traits to a specialization tag */
|
|
template< class ValueType ,
|
|
class ArraySpecialize ,
|
|
class ArrayLayout ,
|
|
class MemorySpace ,
|
|
class MemoryTraits >
|
|
struct ViewSpecialize ;
|
|
|
|
/** \brief Defines the type of a subview given a source view type
|
|
* and subview argument types.
|
|
*/
|
|
template< class SrcViewType
|
|
, class Arg0Type
|
|
, class Arg1Type
|
|
, class Arg2Type
|
|
, class Arg3Type
|
|
, class Arg4Type
|
|
, class Arg5Type
|
|
, class Arg6Type
|
|
, class Arg7Type
|
|
>
|
|
struct ViewSubview /* { typedef ... type ; } */ ;
|
|
|
|
template< class DstViewSpecialize ,
|
|
class SrcViewSpecialize = void ,
|
|
class Enable = void >
|
|
struct ViewAssignment ;
|
|
|
|
template< class DstMemorySpace , class SrcMemorySpace >
|
|
struct DeepCopy ;
|
|
|
|
} /* namespace Impl */
|
|
} // namespace Kokkos
|
|
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
|
|
namespace Kokkos {
|
|
|
|
/** \class ViewTraits
|
|
* \brief Traits class for accessing attributes of a View.
|
|
*
|
|
* This is an implementation detail of View. It is only of interest
|
|
* to developers implementing a new specialization of View.
|
|
*
|
|
* Template argument permutations:
|
|
* - View< DataType , void , void , void >
|
|
* - View< DataType , Space , void , void >
|
|
* - View< DataType , Space , MemoryTraits , void >
|
|
* - View< DataType , Space , void , MemoryTraits >
|
|
* - View< DataType , ArrayLayout , void , void >
|
|
* - View< DataType , ArrayLayout , Space , void >
|
|
* - View< DataType , ArrayLayout , MemoryTraits , void >
|
|
* - View< DataType , ArrayLayout , Space , MemoryTraits >
|
|
* - View< DataType , MemoryTraits , void , void >
|
|
*/
|
|
|
|
template< class DataType ,
|
|
class Arg1 = void ,
|
|
class Arg2 = void ,
|
|
class Arg3 = void >
|
|
class ViewTraits {
|
|
private:
|
|
|
|
// Layout, Space, and MemoryTraits are optional
|
|
// but need to appear in that order. That means Layout
|
|
// can only be Arg1, Space can be Arg1 or Arg2, and
|
|
// MemoryTraits can be Arg1, Arg2 or Arg3
|
|
|
|
enum { Arg1IsLayout = Impl::is_array_layout<Arg1>::value };
|
|
|
|
enum { Arg1IsSpace = Impl::is_space<Arg1>::value };
|
|
enum { Arg2IsSpace = Impl::is_space<Arg2>::value };
|
|
|
|
enum { Arg1IsMemoryTraits = Impl::is_memory_traits<Arg1>::value };
|
|
enum { Arg2IsMemoryTraits = Impl::is_memory_traits<Arg2>::value };
|
|
enum { Arg3IsMemoryTraits = Impl::is_memory_traits<Arg3>::value };
|
|
|
|
enum { Arg1IsVoid = Impl::is_same< Arg1 , void >::value };
|
|
enum { Arg2IsVoid = Impl::is_same< Arg2 , void >::value };
|
|
enum { Arg3IsVoid = Impl::is_same< Arg3 , void >::value };
|
|
|
|
// Arg1 is Layout, Space, MemoryTraits, or void
|
|
typedef typename
|
|
Impl::StaticAssert<
|
|
( 1 == Arg1IsLayout + Arg1IsSpace + Arg1IsMemoryTraits + Arg1IsVoid )
|
|
, Arg1 >::type Arg1Verified ;
|
|
|
|
// If Arg1 is Layout then Arg2 is Space, MemoryTraits, or void
|
|
// If Arg1 is Space then Arg2 is MemoryTraits or void
|
|
// If Arg1 is MemoryTraits then Arg2 is void
|
|
// If Arg1 is Void then Arg2 is void
|
|
typedef typename
|
|
Impl::StaticAssert<
|
|
( Arg1IsLayout && ( 1 == Arg2IsSpace + Arg2IsMemoryTraits + Arg2IsVoid ) ) ||
|
|
( Arg1IsSpace && ( 0 == Arg2IsSpace ) && ( 1 == Arg2IsMemoryTraits + Arg2IsVoid ) ) ||
|
|
( Arg1IsMemoryTraits && Arg2IsVoid ) ||
|
|
( Arg1IsVoid && Arg2IsVoid )
|
|
, Arg2 >::type Arg2Verified ;
|
|
|
|
// Arg3 is MemoryTraits or void and at most one argument is MemoryTraits
|
|
typedef typename
|
|
Impl::StaticAssert<
|
|
( 1 == Arg3IsMemoryTraits + Arg3IsVoid ) &&
|
|
( Arg1IsMemoryTraits + Arg2IsMemoryTraits + Arg3IsMemoryTraits <= 1 )
|
|
, Arg3 >::type Arg3Verified ;
|
|
|
|
// Arg1 or Arg2 may have execution and memory spaces
|
|
typedef typename Impl::if_c<( Arg1IsSpace ), Arg1Verified ,
|
|
typename Impl::if_c<( Arg2IsSpace ), Arg2Verified ,
|
|
Kokkos::DefaultExecutionSpace
|
|
>::type >::type::execution_space ExecutionSpace ;
|
|
|
|
typedef typename Impl::if_c<( Arg1IsSpace ), Arg1Verified ,
|
|
typename Impl::if_c<( Arg2IsSpace ), Arg2Verified ,
|
|
Kokkos::DefaultExecutionSpace
|
|
>::type >::type::memory_space MemorySpace ;
|
|
|
|
typedef typename Impl::is_space<
|
|
typename Impl::if_c<( Arg1IsSpace ), Arg1Verified ,
|
|
typename Impl::if_c<( Arg2IsSpace ), Arg2Verified ,
|
|
Kokkos::DefaultExecutionSpace
|
|
>::type >::type >::host_mirror_space HostMirrorSpace ;
|
|
|
|
// Arg1 may be array layout
|
|
typedef typename Impl::if_c< Arg1IsLayout , Arg1Verified ,
|
|
typename ExecutionSpace::array_layout
|
|
>::type ArrayLayout ;
|
|
|
|
// Arg1, Arg2, or Arg3 may be memory traits
|
|
typedef typename Impl::if_c< Arg1IsMemoryTraits , Arg1Verified ,
|
|
typename Impl::if_c< Arg2IsMemoryTraits , Arg2Verified ,
|
|
typename Impl::if_c< Arg3IsMemoryTraits , Arg3Verified ,
|
|
MemoryManaged
|
|
>::type >::type >::type MemoryTraits ;
|
|
|
|
typedef Impl::AnalyzeShape<DataType> analysis ;
|
|
|
|
public:
|
|
|
|
//------------------------------------
|
|
// Data type traits:
|
|
|
|
typedef DataType data_type ;
|
|
typedef typename analysis::const_type const_data_type ;
|
|
typedef typename analysis::non_const_type non_const_data_type ;
|
|
|
|
//------------------------------------
|
|
// Array of intrinsic scalar type traits:
|
|
|
|
typedef typename analysis::array_intrinsic_type array_intrinsic_type ;
|
|
typedef typename analysis::const_array_intrinsic_type const_array_intrinsic_type ;
|
|
typedef typename analysis::non_const_array_intrinsic_type non_const_array_intrinsic_type ;
|
|
|
|
//------------------------------------
|
|
// Value type traits:
|
|
|
|
typedef typename analysis::value_type value_type ;
|
|
typedef typename analysis::const_value_type const_value_type ;
|
|
typedef typename analysis::non_const_value_type non_const_value_type ;
|
|
|
|
//------------------------------------
|
|
// Layout and shape traits:
|
|
|
|
typedef ArrayLayout array_layout ;
|
|
typedef typename analysis::shape shape_type ;
|
|
|
|
enum { rank = shape_type::rank };
|
|
enum { rank_dynamic = shape_type::rank_dynamic };
|
|
|
|
//------------------------------------
|
|
// Execution space, memory space, memory access traits, and host mirror space.
|
|
|
|
typedef ExecutionSpace execution_space ;
|
|
typedef MemorySpace memory_space ;
|
|
typedef Device<ExecutionSpace,MemorySpace> device_type ;
|
|
typedef MemoryTraits memory_traits ;
|
|
typedef HostMirrorSpace host_mirror_space ;
|
|
|
|
typedef typename memory_space::size_type size_type ;
|
|
|
|
enum { is_hostspace = Impl::is_same< memory_space , HostSpace >::value };
|
|
enum { is_managed = memory_traits::Unmanaged == 0 };
|
|
enum { is_random_access = memory_traits::RandomAccess == 1 };
|
|
|
|
//------------------------------------
|
|
|
|
|
|
//------------------------------------
|
|
// Specialization tag:
|
|
|
|
typedef typename
|
|
Impl::ViewSpecialize< value_type
|
|
, typename analysis::specialize
|
|
, array_layout
|
|
, memory_space
|
|
, memory_traits
|
|
>::type specialize ;
|
|
};
|
|
|
|
} /* namespace Kokkos */
|
|
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
|
|
namespace Kokkos {
|
|
namespace Impl {
|
|
|
|
class ViewDefault {};
|
|
|
|
/** \brief Default view specialization has LayoutLeft, LayoutRight, or LayoutStride.
|
|
*/
|
|
template< class ValueType , class MemorySpace , class MemoryTraits >
|
|
struct ViewSpecialize< ValueType , void , LayoutLeft , MemorySpace , MemoryTraits >
|
|
{ typedef ViewDefault type ; };
|
|
|
|
template< class ValueType , class MemorySpace , class MemoryTraits >
|
|
struct ViewSpecialize< ValueType , void , LayoutRight , MemorySpace , MemoryTraits >
|
|
{ typedef ViewDefault type ; };
|
|
|
|
template< class ValueType , class MemorySpace , class MemoryTraits >
|
|
struct ViewSpecialize< ValueType , void , LayoutStride , MemorySpace , MemoryTraits >
|
|
{ typedef ViewDefault type ; };
|
|
|
|
} /* namespace Impl */
|
|
} /* namespace Kokkos */
|
|
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
|
|
namespace Kokkos {
|
|
namespace Impl {
|
|
|
|
/** \brief Types for compile-time detection of View usage errors */
|
|
namespace ViewError {
|
|
|
|
struct allocation_constructor_requires_managed {};
|
|
struct allocation_constructor_requires_nonconst {};
|
|
struct user_pointer_constructor_requires_unmanaged {};
|
|
struct device_shmem_constructor_requires_unmanaged {};
|
|
|
|
struct scalar_operator_called_from_non_scalar_view {};
|
|
|
|
} /* namespace ViewError */
|
|
|
|
//----------------------------------------------------------------------------
|
|
/** \brief Enable view parentheses operator for
|
|
* match of layout and integral arguments.
|
|
* If correct rank define type from traits,
|
|
* otherwise define type as an error message.
|
|
*/
|
|
template< class ReturnType , class Traits , class Layout , unsigned Rank ,
|
|
typename iType0 = int , typename iType1 = int ,
|
|
typename iType2 = int , typename iType3 = int ,
|
|
typename iType4 = int , typename iType5 = int ,
|
|
typename iType6 = int , typename iType7 = int ,
|
|
class Enable = void >
|
|
struct ViewEnableArrayOper ;
|
|
|
|
template< class ReturnType , class Traits , class Layout , unsigned Rank ,
|
|
typename iType0 , typename iType1 ,
|
|
typename iType2 , typename iType3 ,
|
|
typename iType4 , typename iType5 ,
|
|
typename iType6 , typename iType7 >
|
|
struct ViewEnableArrayOper<
|
|
ReturnType , Traits , Layout , Rank ,
|
|
iType0 , iType1 , iType2 , iType3 ,
|
|
iType4 , iType5 , iType6 , iType7 ,
|
|
typename enable_if<
|
|
iType0(0) == 0 && iType1(0) == 0 && iType2(0) == 0 && iType3(0) == 0 &&
|
|
iType4(0) == 0 && iType5(0) == 0 && iType6(0) == 0 && iType7(0) == 0 &&
|
|
is_same< typename Traits::array_layout , Layout >::value &&
|
|
( unsigned(Traits::rank) == Rank )
|
|
>::type >
|
|
{
|
|
typedef ReturnType type ;
|
|
};
|
|
|
|
} /* namespace Impl */
|
|
} /* namespace Kokkos */
|
|
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
|
|
namespace Kokkos {
|
|
|
|
/** \class View
|
|
* \brief View to an array of data.
|
|
*
|
|
* A View represents an array of one or more dimensions.
|
|
* For details, please refer to Kokkos' tutorial materials.
|
|
*
|
|
* \section Kokkos_View_TemplateParameters Template parameters
|
|
*
|
|
* This class has both required and optional template parameters. The
|
|
* \c DataType parameter must always be provided, and must always be
|
|
* first. The parameters \c Arg1Type, \c Arg2Type, and \c Arg3Type are
|
|
* placeholders for different template parameters. The default value
|
|
* of the fifth template parameter \c Specialize suffices for most use
|
|
* cases. When explaining the template parameters, we won't refer to
|
|
* \c Arg1Type, \c Arg2Type, and \c Arg3Type; instead, we will refer
|
|
* to the valid categories of template parameters, in whatever order
|
|
* they may occur.
|
|
*
|
|
* Valid ways in which template arguments may be specified:
|
|
* - View< DataType , Space >
|
|
* - View< DataType , Space , MemoryTraits >
|
|
* - View< DataType , Space , void , MemoryTraits >
|
|
* - View< DataType , Layout , Space >
|
|
* - View< DataType , Layout , Space , MemoryTraits >
|
|
*
|
|
* \tparam DataType (required) This indicates both the type of each
|
|
* entry of the array, and the combination of compile-time and
|
|
* run-time array dimension(s). For example, <tt>double*</tt>
|
|
* indicates a one-dimensional array of \c double with run-time
|
|
* dimension, and <tt>int*[3]</tt> a two-dimensional array of \c int
|
|
* with run-time first dimension and compile-time second dimension
|
|
* (of 3). In general, the run-time dimensions (if any) must go
|
|
* first, followed by zero or more compile-time dimensions. For
|
|
* more examples, please refer to the tutorial materials.
|
|
*
|
|
* \tparam Space (required) The memory space.
|
|
*
|
|
* \tparam Layout (optional) The array's layout in memory. For
|
|
* example, LayoutLeft indicates a column-major (Fortran style)
|
|
* layout, and LayoutRight a row-major (C style) layout. If not
|
|
* specified, this defaults to the preferred layout for the
|
|
* <tt>Space</tt>.
|
|
*
|
|
* \tparam MemoryTraits (optional) Assertion of the user's intended
|
|
* access behavior. For example, RandomAccess indicates read-only
|
|
* access with limited spatial locality, and Unmanaged lets users
|
|
* wrap externally allocated memory in a View without automatic
|
|
* deallocation.
|
|
*
|
|
* \section Kokkos_View_MT MemoryTraits discussion
|
|
*
|
|
* \subsection Kokkos_View_MT_Interp MemoryTraits interpretation depends on Space
|
|
*
|
|
* Some \c MemoryTraits options may have different interpretations for
|
|
* different \c Space types. For example, with the Cuda device,
|
|
* \c RandomAccess tells Kokkos to fetch the data through the texture
|
|
* cache, whereas the non-GPU devices have no such hardware construct.
|
|
*
|
|
* \subsection Kokkos_View_MT_PrefUse Preferred use of MemoryTraits
|
|
*
|
|
* Users should defer applying the optional \c MemoryTraits parameter
|
|
* until the point at which they actually plan to rely on it in a
|
|
* computational kernel. This minimizes the number of template
|
|
* parameters exposed in their code, which reduces the cost of
|
|
* compilation. Users may always assign a View without specified
|
|
* \c MemoryTraits to a compatible View with that specification.
|
|
* For example:
|
|
* \code
|
|
* // Pass in the simplest types of View possible.
|
|
* void
|
|
* doSomething (View<double*, Cuda> out,
|
|
* View<const double*, Cuda> in)
|
|
* {
|
|
* // Assign the "generic" View in to a RandomAccess View in_rr.
|
|
* // Note that RandomAccess View objects must have const data.
|
|
* View<const double*, Cuda, RandomAccess> in_rr = in;
|
|
* // ... do something with in_rr and out ...
|
|
* }
|
|
* \endcode
|
|
*/
|
|
template< class DataType ,
|
|
class Arg1Type = void , /* ArrayLayout, SpaceType, or MemoryTraits */
|
|
class Arg2Type = void , /* SpaceType or MemoryTraits */
|
|
class Arg3Type = void , /* MemoryTraits */
|
|
class Specialize =
|
|
typename ViewTraits<DataType,Arg1Type,Arg2Type,Arg3Type>::specialize >
|
|
class View ;
|
|
|
|
namespace Impl {
|
|
|
|
template< class C >
|
|
struct is_view : public bool_< false > {};
|
|
|
|
template< class D , class A1 , class A2 , class A3 , class S >
|
|
struct is_view< View< D , A1 , A2 , A3 , S > > : public bool_< true > {};
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
template< class DataType ,
|
|
class Arg1Type ,
|
|
class Arg2Type ,
|
|
class Arg3Type >
|
|
class View< DataType , Arg1Type , Arg2Type , Arg3Type , Impl::ViewDefault >
|
|
: public ViewTraits< DataType , Arg1Type , Arg2Type, Arg3Type >
|
|
{
|
|
public:
|
|
|
|
typedef ViewTraits< DataType , Arg1Type , Arg2Type, Arg3Type > traits ;
|
|
|
|
private:
|
|
|
|
// Assignment of compatible views requirement:
|
|
template< class , class , class , class , class > friend class View ;
|
|
|
|
// Assignment of compatible subview requirement:
|
|
template< class , class , class > friend struct Impl::ViewAssignment ;
|
|
|
|
// Dimensions, cardinality, capacity, and offset computation for
|
|
// multidimensional array view of contiguous memory.
|
|
// Inherits from Impl::Shape
|
|
typedef Impl::ViewOffset< typename traits::shape_type
|
|
, typename traits::array_layout
|
|
> offset_map_type ;
|
|
|
|
// Intermediary class for data management and access
|
|
typedef Impl::ViewDataManagement< traits > view_data_management ;
|
|
|
|
//----------------------------------------
|
|
// Data members:
|
|
|
|
typename view_data_management::handle_type m_ptr_on_device ;
|
|
offset_map_type m_offset_map ;
|
|
view_data_management m_management ;
|
|
Impl::AllocationTracker m_tracker ;
|
|
|
|
//----------------------------------------
|
|
|
|
public:
|
|
|
|
/** return type for all indexing operators */
|
|
typedef typename view_data_management::return_type reference_type ;
|
|
|
|
enum { reference_type_is_lvalue = view_data_management::ReturnTypeIsReference };
|
|
|
|
typedef View< typename traits::array_intrinsic_type ,
|
|
typename traits::array_layout ,
|
|
typename traits::device_type ,
|
|
typename traits::memory_traits > array_type ;
|
|
|
|
typedef View< typename traits::const_data_type ,
|
|
typename traits::array_layout ,
|
|
typename traits::device_type ,
|
|
typename traits::memory_traits > const_type ;
|
|
|
|
typedef View< typename traits::non_const_data_type ,
|
|
typename traits::array_layout ,
|
|
typename traits::device_type ,
|
|
typename traits::memory_traits > non_const_type ;
|
|
|
|
typedef View< typename traits::non_const_data_type ,
|
|
typename traits::array_layout ,
|
|
typename traits::host_mirror_space ,
|
|
void > HostMirror ;
|
|
|
|
//------------------------------------
|
|
// Shape
|
|
|
|
enum { Rank = traits::rank };
|
|
|
|
KOKKOS_INLINE_FUNCTION offset_map_type shape() const { return m_offset_map ; }
|
|
KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_0() const { return m_offset_map.N0 ; }
|
|
KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_1() const { return m_offset_map.N1 ; }
|
|
KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_2() const { return m_offset_map.N2 ; }
|
|
KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_3() const { return m_offset_map.N3 ; }
|
|
KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_4() const { return m_offset_map.N4 ; }
|
|
KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_5() const { return m_offset_map.N5 ; }
|
|
KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_6() const { return m_offset_map.N6 ; }
|
|
KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_7() const { return m_offset_map.N7 ; }
|
|
KOKKOS_INLINE_FUNCTION typename traits::size_type size() const { return m_offset_map.cardinality(); }
|
|
|
|
template< typename iType >
|
|
KOKKOS_INLINE_FUNCTION
|
|
typename traits::size_type dimension( const iType & i ) const
|
|
{ return Impl::dimension( m_offset_map , i ); }
|
|
|
|
//------------------------------------
|
|
// Destructor, constructors, assignment operators:
|
|
|
|
KOKKOS_INLINE_FUNCTION
|
|
~View() {}
|
|
|
|
KOKKOS_INLINE_FUNCTION
|
|
View()
|
|
: m_ptr_on_device()
|
|
, m_offset_map()
|
|
, m_management()
|
|
, m_tracker()
|
|
{ m_offset_map.assign(0, 0,0,0,0,0,0,0,0); }
|
|
|
|
KOKKOS_INLINE_FUNCTION
|
|
View( const View & rhs )
|
|
: m_ptr_on_device()
|
|
, m_offset_map()
|
|
, m_management()
|
|
, m_tracker()
|
|
{
|
|
(void) Impl::ViewAssignment<
|
|
typename traits::specialize ,
|
|
typename traits::specialize >( *this , rhs );
|
|
}
|
|
|
|
KOKKOS_INLINE_FUNCTION
|
|
View & operator = ( const View & rhs )
|
|
{
|
|
(void) Impl::ViewAssignment<
|
|
typename traits::specialize ,
|
|
typename traits::specialize >( *this , rhs );
|
|
return *this ;
|
|
}
|
|
|
|
//------------------------------------
|
|
// Construct or assign compatible view:
|
|
|
|
template< class RT , class RL , class RD , class RM , class RS >
|
|
KOKKOS_INLINE_FUNCTION
|
|
View( const View<RT,RL,RD,RM,RS> & rhs )
|
|
: m_ptr_on_device()
|
|
, m_offset_map()
|
|
, m_management()
|
|
, m_tracker()
|
|
{
|
|
(void) Impl::ViewAssignment<
|
|
typename traits::specialize , RS >( *this , rhs );
|
|
}
|
|
|
|
template< class RT , class RL , class RD , class RM , class RS >
|
|
KOKKOS_INLINE_FUNCTION
|
|
View & operator = ( const View<RT,RL,RD,RM,RS> & rhs )
|
|
{
|
|
(void) Impl::ViewAssignment<
|
|
typename traits::specialize , RS >( *this , rhs );
|
|
return *this ;
|
|
}
|
|
|
|
//------------------------------------
|
|
/**\brief Allocation of a managed view with possible alignment padding.
|
|
*
|
|
* Allocation properties for allocating and initializing to the default value_type:
|
|
* Kokkos::ViewAllocate()
|
|
* Kokkos::ViewAllocate("label") OR "label"
|
|
* Kokkos::ViewAllocate(std::string("label")) OR std::string("label")
|
|
*
|
|
* Allocation properties for allocating and bypassing initialization:
|
|
* Kokkos::ViewAllocateWithoutInitializing()
|
|
* Kokkos::ViewAllocateWithoutInitializing("label")
|
|
*/
|
|
|
|
template< class AllocationProperties >
|
|
explicit inline
|
|
View( const AllocationProperties & prop ,
|
|
// Impl::ViewAllocProp::size_type exists when the traits and allocation properties
|
|
// are valid for allocating viewed memory.
|
|
const typename Impl::ViewAllocProp< traits , AllocationProperties >::size_type n0 = 0 ,
|
|
const size_t n1 = 0 ,
|
|
const size_t n2 = 0 ,
|
|
const size_t n3 = 0 ,
|
|
const size_t n4 = 0 ,
|
|
const size_t n5 = 0 ,
|
|
const size_t n6 = 0 ,
|
|
const size_t n7 = 0 ,
|
|
const size_t n8 = 0 )
|
|
: m_ptr_on_device()
|
|
, m_offset_map()
|
|
, m_management()
|
|
, m_tracker()
|
|
{
|
|
typedef Impl::ViewAllocProp< traits , AllocationProperties > Alloc ;
|
|
|
|
static_assert(!std::is_same<typename traits::array_layout, LayoutStride>::value,
|
|
"LayoutStride does not support View constructor which takes dimensions directly!");
|
|
|
|
m_offset_map.assign( n0, n1, n2, n3, n4, n5, n6, n7, n8 );
|
|
if(Alloc::AllowPadding)
|
|
m_offset_map.set_padding();
|
|
|
|
m_ptr_on_device = view_data_management::template allocate< Alloc::Initialize >( Alloc::label(prop) , m_offset_map, m_tracker );
|
|
|
|
}
|
|
|
|
template< class AllocationProperties >
|
|
explicit inline
|
|
View( const AllocationProperties & prop ,
|
|
const typename traits::array_layout & layout ,
|
|
// Impl::ViewAllocProp::size_type exists when the traits and allocation properties
|
|
// are valid for allocating viewed memory.
|
|
const typename Impl::ViewAllocProp< traits , AllocationProperties >::size_type = 0 )
|
|
: m_ptr_on_device()
|
|
, m_offset_map()
|
|
, m_management()
|
|
, m_tracker()
|
|
{
|
|
typedef Impl::ViewAllocProp< traits , AllocationProperties > Alloc ;
|
|
|
|
m_offset_map.assign( layout );
|
|
if(Alloc::AllowPadding)
|
|
m_offset_map.set_padding();
|
|
|
|
m_ptr_on_device = view_data_management::template allocate< Alloc::Initialize >( Alloc::label(prop) , m_offset_map, m_tracker );
|
|
|
|
m_management.set_noncontiguous();
|
|
}
|
|
|
|
//------------------------------------
|
|
// Assign an unmanaged View from pointer, can be called in functors.
|
|
// No alignment padding is performed.
|
|
|
|
template< class Type >
|
|
explicit KOKKOS_INLINE_FUNCTION
|
|
View( Type * ptr ,
|
|
typename Impl::ViewRawPointerProp< traits , Type >::size_type n0 = 0 ,
|
|
const size_t n1 = 0 ,
|
|
const size_t n2 = 0 ,
|
|
const size_t n3 = 0 ,
|
|
const size_t n4 = 0 ,
|
|
const size_t n5 = 0 ,
|
|
const size_t n6 = 0 ,
|
|
const size_t n7 = 0 ,
|
|
const size_t n8 = 0 )
|
|
: m_ptr_on_device(ptr)
|
|
, m_offset_map()
|
|
, m_management()
|
|
, m_tracker()
|
|
{
|
|
m_offset_map.assign( n0, n1, n2, n3, n4, n5, n6, n7, n8 );
|
|
m_management.set_unmanaged();
|
|
}
|
|
|
|
template< class Type >
|
|
explicit KOKKOS_INLINE_FUNCTION
|
|
View( Type * ptr ,
|
|
typename traits::array_layout const & layout ,
|
|
typename Impl::ViewRawPointerProp< traits , Type >::size_type = 0 )
|
|
: m_ptr_on_device(ptr)
|
|
, m_offset_map()
|
|
, m_management()
|
|
, m_tracker()
|
|
{
|
|
m_offset_map.assign( layout );
|
|
m_management.set_unmanaged();
|
|
m_management.set_noncontiguous();
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------
|
|
// Assign a View from an AllocationTracker,
|
|
// The allocator used must be compatiable with the memory space of the view
|
|
// No alignment padding is performed.
|
|
// TODO: Should these allow padding??? DJS 01/15/15
|
|
explicit
|
|
View( Impl::AllocationTracker const &arg_tracker ,
|
|
const size_t n0 = 0 ,
|
|
const size_t n1 = 0 ,
|
|
const size_t n2 = 0 ,
|
|
const size_t n3 = 0 ,
|
|
const size_t n4 = 0 ,
|
|
const size_t n5 = 0 ,
|
|
const size_t n6 = 0 ,
|
|
const size_t n7 = 0 ,
|
|
const size_t n8 = 0 )
|
|
: m_ptr_on_device(reinterpret_cast<typename traits::value_type*>(arg_tracker.alloc_ptr()))
|
|
, m_offset_map()
|
|
, m_management()
|
|
, m_tracker(arg_tracker)
|
|
{
|
|
m_offset_map.assign( n0, n1, n2, n3, n4, n5, n6, n7, n8 );
|
|
|
|
const size_t req_size = m_offset_map.capacity() * sizeof(typename traits::value_type);
|
|
if ( m_tracker.alloc_size() < req_size ) {
|
|
Impl::throw_runtime_exception("Error: tracker.alloc_size() < req_size");
|
|
}
|
|
}
|
|
|
|
explicit
|
|
View( Impl::AllocationTracker const & arg_tracker
|
|
, typename traits::array_layout const & layout )
|
|
: m_ptr_on_device(reinterpret_cast<typename traits::value_type*>(arg_tracker.alloc_ptr()))
|
|
, m_offset_map()
|
|
, m_management()
|
|
, m_tracker(arg_tracker)
|
|
{
|
|
m_offset_map.assign( layout );
|
|
|
|
const size_t req_size = m_offset_map.capacity() * sizeof(typename traits::value_type);
|
|
if ( m_tracker.alloc_size() < req_size ) {
|
|
Impl::throw_runtime_exception("Error: tracker.alloc_size() < req_size");
|
|
}
|
|
|
|
m_management.set_noncontiguous();
|
|
}
|
|
|
|
//------------------------------------
|
|
/** \brief Constructors for subviews requires following
|
|
* type-compatibility condition, enforce via StaticAssert.
|
|
*
|
|
* Impl::is_same< View ,
|
|
* typename Impl::ViewSubview< View<D,A1,A2,A3,Impl::ViewDefault>
|
|
* , ArgType0 , ArgType1 , ArgType2 , ArgType3
|
|
* , ArgType4 , ArgType5 , ArgType6 , ArgType7
|
|
* >::type >::value
|
|
*/
|
|
template< class D , class A1 , class A2 , class A3
|
|
, class SubArg0_type , class SubArg1_type , class SubArg2_type , class SubArg3_type
|
|
, class SubArg4_type , class SubArg5_type , class SubArg6_type , class SubArg7_type
|
|
>
|
|
KOKKOS_INLINE_FUNCTION
|
|
View( const View<D,A1,A2,A3,Impl::ViewDefault> & src
|
|
, const SubArg0_type & arg0 , const SubArg1_type & arg1
|
|
, const SubArg2_type & arg2 , const SubArg3_type & arg3
|
|
, const SubArg4_type & arg4 , const SubArg5_type & arg5
|
|
, const SubArg6_type & arg6 , const SubArg7_type & arg7
|
|
);
|
|
|
|
template< class D , class A1 , class A2 , class A3
|
|
, class SubArg0_type , class SubArg1_type , class SubArg2_type , class SubArg3_type
|
|
, class SubArg4_type , class SubArg5_type , class SubArg6_type
|
|
>
|
|
KOKKOS_INLINE_FUNCTION
|
|
View( const View<D,A1,A2,A3,Impl::ViewDefault> & src
|
|
, const SubArg0_type & arg0 , const SubArg1_type & arg1
|
|
, const SubArg2_type & arg2 , const SubArg3_type & arg3
|
|
, const SubArg4_type & arg4 , const SubArg5_type & arg5
|
|
, const SubArg6_type & arg6
|
|
);
|
|
|
|
template< class D , class A1 , class A2 , class A3
|
|
, class SubArg0_type , class SubArg1_type , class SubArg2_type , class SubArg3_type
|
|
, class SubArg4_type , class SubArg5_type
|
|
>
|
|
KOKKOS_INLINE_FUNCTION
|
|
View( const View<D,A1,A2,A3,Impl::ViewDefault> & src
|
|
, const SubArg0_type & arg0 , const SubArg1_type & arg1
|
|
, const SubArg2_type & arg2 , const SubArg3_type & arg3
|
|
, const SubArg4_type & arg4 , const SubArg5_type & arg5
|
|
);
|
|
|
|
template< class D , class A1 , class A2 , class A3
|
|
, class SubArg0_type , class SubArg1_type , class SubArg2_type , class SubArg3_type
|
|
, class SubArg4_type
|
|
>
|
|
KOKKOS_INLINE_FUNCTION
|
|
View( const View<D,A1,A2,A3,Impl::ViewDefault> & src
|
|
, const SubArg0_type & arg0 , const SubArg1_type & arg1
|
|
, const SubArg2_type & arg2 , const SubArg3_type & arg3
|
|
, const SubArg4_type & arg4
|
|
);
|
|
|
|
template< class D , class A1 , class A2 , class A3
|
|
, class SubArg0_type , class SubArg1_type , class SubArg2_type , class SubArg3_type
|
|
>
|
|
KOKKOS_INLINE_FUNCTION
|
|
View( const View<D,A1,A2,A3,Impl::ViewDefault> & src
|
|
, const SubArg0_type & arg0 , const SubArg1_type & arg1
|
|
, const SubArg2_type & arg2 , const SubArg3_type & arg3
|
|
);
|
|
|
|
template< class D , class A1 , class A2 , class A3
|
|
, class SubArg0_type , class SubArg1_type , class SubArg2_type
|
|
>
|
|
KOKKOS_INLINE_FUNCTION
|
|
View( const View<D,A1,A2,A3,Impl::ViewDefault> & src
|
|
, const SubArg0_type & arg0 , const SubArg1_type & arg1
|
|
, const SubArg2_type & arg2
|
|
);
|
|
|
|
template< class D , class A1 , class A2 , class A3
|
|
, class SubArg0_type , class SubArg1_type
|
|
>
|
|
KOKKOS_INLINE_FUNCTION
|
|
View( const View<D,A1,A2,A3,Impl::ViewDefault> & src
|
|
, const SubArg0_type & arg0 , const SubArg1_type & arg1
|
|
);
|
|
|
|
template< class D , class A1 , class A2 , class A3
|
|
, class SubArg0_type
|
|
>
|
|
KOKKOS_INLINE_FUNCTION
|
|
View( const View<D,A1,A2,A3,Impl::ViewDefault> & src
|
|
, const SubArg0_type & arg0
|
|
);
|
|
|
|
//------------------------------------
|
|
// Assign unmanaged View to portion of execution space's shared memory
|
|
|
|
typedef Impl::if_c< ! traits::is_managed ,
|
|
const typename traits::execution_space::scratch_memory_space & ,
|
|
Impl::ViewError::device_shmem_constructor_requires_unmanaged >
|
|
if_scratch_memory_constructor ;
|
|
|
|
explicit KOKKOS_INLINE_FUNCTION
|
|
View( typename if_scratch_memory_constructor::type space ,
|
|
const unsigned n0 = 0 ,
|
|
const unsigned n1 = 0 ,
|
|
const unsigned n2 = 0 ,
|
|
const unsigned n3 = 0 ,
|
|
const unsigned n4 = 0 ,
|
|
const unsigned n5 = 0 ,
|
|
const unsigned n6 = 0 ,
|
|
const unsigned n7 = 0 )
|
|
: m_ptr_on_device()
|
|
, m_offset_map()
|
|
, m_management()
|
|
, m_tracker()
|
|
{
|
|
typedef typename traits::value_type value_type_ ;
|
|
|
|
enum { align = 8 };
|
|
enum { mask = align - 1 };
|
|
|
|
m_offset_map.assign( n0, n1, n2, n3, n4, n5, n6, n7 );
|
|
|
|
typedef Impl::if_c< ! traits::is_managed ,
|
|
value_type_ * ,
|
|
Impl::ViewError::device_shmem_constructor_requires_unmanaged >
|
|
if_device_shmem_pointer ;
|
|
|
|
// Select the first argument:
|
|
m_ptr_on_device = if_device_shmem_pointer::select(
|
|
(value_type_*) space.get_shmem( unsigned( sizeof(value_type_) * m_offset_map.capacity() + unsigned(mask) ) & ~unsigned(mask) ) );
|
|
}
|
|
|
|
explicit KOKKOS_INLINE_FUNCTION
|
|
View( typename if_scratch_memory_constructor::type space ,
|
|
typename traits::array_layout const & layout)
|
|
: m_ptr_on_device()
|
|
, m_offset_map()
|
|
, m_management()
|
|
, m_tracker()
|
|
{
|
|
typedef typename traits::value_type value_type_ ;
|
|
|
|
typedef Impl::if_c< ! traits::is_managed ,
|
|
value_type_ * ,
|
|
Impl::ViewError::device_shmem_constructor_requires_unmanaged >
|
|
if_device_shmem_pointer ;
|
|
|
|
m_offset_map.assign( layout );
|
|
m_management.set_unmanaged();
|
|
m_management.set_noncontiguous();
|
|
|
|
enum { align = 8 };
|
|
enum { mask = align - 1 };
|
|
|
|
// Select the first argument:
|
|
m_ptr_on_device = if_device_shmem_pointer::select(
|
|
(value_type_*) space.get_shmem( unsigned( sizeof(value_type_) * m_offset_map.capacity() + unsigned(mask) ) & ~unsigned(mask) ) );
|
|
}
|
|
|
|
static inline
|
|
unsigned shmem_size( const unsigned n0 = 0 ,
|
|
const unsigned n1 = 0 ,
|
|
const unsigned n2 = 0 ,
|
|
const unsigned n3 = 0 ,
|
|
const unsigned n4 = 0 ,
|
|
const unsigned n5 = 0 ,
|
|
const unsigned n6 = 0 ,
|
|
const unsigned n7 = 0 )
|
|
{
|
|
enum { align = 8 };
|
|
enum { mask = align - 1 };
|
|
|
|
typedef typename traits::value_type value_type_ ;
|
|
|
|
offset_map_type offset_map ;
|
|
|
|
offset_map.assign( n0, n1, n2, n3, n4, n5, n6, n7 );
|
|
|
|
return unsigned( sizeof(value_type_) * offset_map.capacity() + unsigned(mask) ) & ~unsigned(mask) ;
|
|
}
|
|
|
|
//------------------------------------
|
|
// Is not allocated
|
|
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
bool is_null() const { return 0 == ptr_on_device() ; }
|
|
|
|
//------------------------------------
|
|
// Operators for scalar (rank zero) views.
|
|
|
|
typedef Impl::if_c< traits::rank == 0 ,
|
|
typename traits::value_type ,
|
|
Impl::ViewError::scalar_operator_called_from_non_scalar_view >
|
|
if_scalar_operator ;
|
|
|
|
KOKKOS_INLINE_FUNCTION
|
|
const View & operator = ( const typename if_scalar_operator::type & rhs ) const
|
|
{
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
*m_ptr_on_device = if_scalar_operator::select( rhs );
|
|
return *this ;
|
|
}
|
|
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
operator typename if_scalar_operator::type & () const
|
|
{
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
return if_scalar_operator::select( *m_ptr_on_device );
|
|
}
|
|
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename if_scalar_operator::type & operator()() const
|
|
{
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
return if_scalar_operator::select( *m_ptr_on_device );
|
|
}
|
|
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename if_scalar_operator::type & operator*() const
|
|
{
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
return if_scalar_operator::select( *m_ptr_on_device );
|
|
}
|
|
|
|
//------------------------------------
|
|
// Array member access operators enabled if
|
|
// (1) a zero value of all argument types are compile-time comparable to zero
|
|
// (2) the rank matches the number of arguments
|
|
// (3) the memory space is valid for the access
|
|
//------------------------------------
|
|
// rank 1:
|
|
// Specialisation for LayoutLeft and LayoutRight since we know its stride 1
|
|
|
|
template< typename iType0 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type , traits, LayoutLeft, 1, iType0 >::type
|
|
operator[] ( const iType0 & i0 ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_1( m_offset_map, i0 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ i0 ];
|
|
}
|
|
|
|
template< typename iType0 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type , traits, LayoutLeft, 1, iType0 >::type
|
|
operator() ( const iType0 & i0 ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_1( m_offset_map, i0 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ i0 ];
|
|
}
|
|
|
|
template< typename iType0 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type , traits, LayoutLeft, 1, iType0 >::type
|
|
at( const iType0 & i0 , const int , const int , const int ,
|
|
const int , const int , const int , const int ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_1( m_offset_map, i0 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ i0 ];
|
|
}
|
|
|
|
template< typename iType0 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type , traits, LayoutRight, 1, iType0 >::type
|
|
operator[] ( const iType0 & i0 ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_1( m_offset_map, i0 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ i0 ];
|
|
}
|
|
|
|
template< typename iType0 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type , traits, LayoutRight, 1, iType0 >::type
|
|
operator() ( const iType0 & i0 ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_1( m_offset_map, i0 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ i0 ];
|
|
}
|
|
|
|
template< typename iType0 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type , traits, LayoutRight, 1, iType0 >::type
|
|
at( const iType0 & i0 , const int , const int , const int ,
|
|
const int , const int , const int , const int ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_1( m_offset_map, i0 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ i0 ];
|
|
}
|
|
|
|
template< typename iType0 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type , traits,
|
|
typename Impl::if_c<
|
|
Impl::is_same<typename traits::array_layout, LayoutRight>::value ||
|
|
Impl::is_same<typename traits::array_layout, LayoutLeft>::value ,
|
|
void, typename traits::array_layout>::type,
|
|
1, iType0 >::type
|
|
operator[] ( const iType0 & i0 ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_1( m_offset_map, i0 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ m_offset_map(i0) ];
|
|
}
|
|
|
|
template< typename iType0 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type , traits,
|
|
typename Impl::if_c<
|
|
Impl::is_same<typename traits::array_layout, LayoutRight>::value ||
|
|
Impl::is_same<typename traits::array_layout, LayoutLeft>::value ,
|
|
void, typename traits::array_layout>::type,
|
|
1, iType0 >::type
|
|
operator() ( const iType0 & i0 ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_1( m_offset_map, i0 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ m_offset_map(i0) ];
|
|
}
|
|
|
|
template< typename iType0 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type , traits,
|
|
typename Impl::if_c<
|
|
Impl::is_same<typename traits::array_layout, LayoutRight>::value ||
|
|
Impl::is_same<typename traits::array_layout, LayoutLeft>::value ,
|
|
void, typename traits::array_layout>::type,
|
|
1, iType0 >::type
|
|
at( const iType0 & i0 , const int , const int , const int ,
|
|
const int , const int , const int , const int ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_1( m_offset_map, i0 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ m_offset_map(i0) ];
|
|
}
|
|
|
|
// rank 2:
|
|
|
|
template< typename iType0 , typename iType1 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type ,
|
|
traits, typename traits::array_layout, 2, iType0, iType1 >::type
|
|
operator() ( const iType0 & i0 , const iType1 & i1 ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_2( m_offset_map, i0,i1 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ m_offset_map(i0,i1) ];
|
|
}
|
|
|
|
template< typename iType0 , typename iType1 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type ,
|
|
traits, typename traits::array_layout, 2, iType0, iType1 >::type
|
|
at( const iType0 & i0 , const iType1 & i1 , const int , const int ,
|
|
const int , const int , const int , const int ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_2( m_offset_map, i0,i1 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ m_offset_map(i0,i1) ];
|
|
}
|
|
|
|
// rank 3:
|
|
|
|
template< typename iType0 , typename iType1 , typename iType2 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type ,
|
|
traits, typename traits::array_layout, 3, iType0, iType1, iType2 >::type
|
|
operator() ( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_3( m_offset_map, i0,i1,i2 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ m_offset_map(i0,i1,i2) ];
|
|
}
|
|
|
|
template< typename iType0 , typename iType1 , typename iType2 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type ,
|
|
traits, typename traits::array_layout, 3, iType0, iType1, iType2 >::type
|
|
at( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const int ,
|
|
const int , const int , const int , const int ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_3( m_offset_map, i0,i1,i2 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ m_offset_map(i0,i1,i2) ];
|
|
}
|
|
|
|
// rank 4:
|
|
|
|
template< typename iType0 , typename iType1 , typename iType2 , typename iType3 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type ,
|
|
traits, typename traits::array_layout, 4, iType0, iType1, iType2, iType3 >::type
|
|
operator() ( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_4( m_offset_map, i0,i1,i2,i3 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ m_offset_map(i0,i1,i2,i3) ];
|
|
}
|
|
|
|
template< typename iType0 , typename iType1 , typename iType2 , typename iType3 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type ,
|
|
traits, typename traits::array_layout, 4, iType0, iType1, iType2, iType3 >::type
|
|
at( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ,
|
|
const int , const int , const int , const int ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_4( m_offset_map, i0,i1,i2,i3 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ m_offset_map(i0,i1,i2,i3) ];
|
|
}
|
|
|
|
// rank 5:
|
|
|
|
template< typename iType0 , typename iType1 , typename iType2 , typename iType3 ,
|
|
typename iType4 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type ,
|
|
traits, typename traits::array_layout, 5, iType0, iType1, iType2, iType3 , iType4 >::type
|
|
operator() ( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ,
|
|
const iType4 & i4 ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_5( m_offset_map, i0,i1,i2,i3,i4 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ m_offset_map(i0,i1,i2,i3,i4) ];
|
|
}
|
|
|
|
template< typename iType0 , typename iType1 , typename iType2 , typename iType3 ,
|
|
typename iType4 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type ,
|
|
traits, typename traits::array_layout, 5, iType0, iType1, iType2, iType3 , iType4 >::type
|
|
at( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ,
|
|
const iType4 & i4 , const int , const int , const int ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_5( m_offset_map, i0,i1,i2,i3,i4 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ m_offset_map(i0,i1,i2,i3,i4) ];
|
|
}
|
|
|
|
// rank 6:
|
|
|
|
template< typename iType0 , typename iType1 , typename iType2 , typename iType3 ,
|
|
typename iType4 , typename iType5 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type ,
|
|
traits, typename traits::array_layout, 6,
|
|
iType0, iType1, iType2, iType3 , iType4, iType5 >::type
|
|
operator() ( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ,
|
|
const iType4 & i4 , const iType5 & i5 ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_6( m_offset_map, i0,i1,i2,i3,i4,i5 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ m_offset_map(i0,i1,i2,i3,i4,i5) ];
|
|
}
|
|
|
|
template< typename iType0 , typename iType1 , typename iType2 , typename iType3 ,
|
|
typename iType4 , typename iType5 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type ,
|
|
traits, typename traits::array_layout, 6,
|
|
iType0, iType1, iType2, iType3 , iType4, iType5 >::type
|
|
at( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ,
|
|
const iType4 & i4 , const iType5 & i5 , const int , const int ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_6( m_offset_map, i0,i1,i2,i3,i4,i5 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ m_offset_map(i0,i1,i2,i3,i4,i5) ];
|
|
}
|
|
|
|
// rank 7:
|
|
|
|
template< typename iType0 , typename iType1 , typename iType2 , typename iType3 ,
|
|
typename iType4 , typename iType5 , typename iType6 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type ,
|
|
traits, typename traits::array_layout, 7,
|
|
iType0, iType1, iType2, iType3 , iType4, iType5, iType6 >::type
|
|
operator() ( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ,
|
|
const iType4 & i4 , const iType5 & i5 , const iType6 & i6 ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_7( m_offset_map, i0,i1,i2,i3,i4,i5,i6 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ m_offset_map(i0,i1,i2,i3,i4,i5,i6) ];
|
|
}
|
|
|
|
template< typename iType0 , typename iType1 , typename iType2 , typename iType3 ,
|
|
typename iType4 , typename iType5 , typename iType6 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type ,
|
|
traits, typename traits::array_layout, 7,
|
|
iType0, iType1, iType2, iType3 , iType4, iType5, iType6 >::type
|
|
at( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ,
|
|
const iType4 & i4 , const iType5 & i5 , const iType6 & i6 , const int ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_7( m_offset_map, i0,i1,i2,i3,i4,i5,i6 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ m_offset_map(i0,i1,i2,i3,i4,i5,i6) ];
|
|
}
|
|
|
|
// rank 8:
|
|
|
|
template< typename iType0 , typename iType1 , typename iType2 , typename iType3 ,
|
|
typename iType4 , typename iType5 , typename iType6 , typename iType7 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type ,
|
|
traits, typename traits::array_layout, 8,
|
|
iType0, iType1, iType2, iType3 , iType4, iType5, iType6, iType7 >::type
|
|
operator() ( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ,
|
|
const iType4 & i4 , const iType5 & i5 , const iType6 & i6 , const iType7 & i7 ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_8( m_offset_map, i0,i1,i2,i3,i4,i5,i6,i7 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ m_offset_map(i0,i1,i2,i3,i4,i5,i6,i7) ];
|
|
}
|
|
|
|
template< typename iType0 , typename iType1 , typename iType2 , typename iType3 ,
|
|
typename iType4 , typename iType5 , typename iType6 , typename iType7 >
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename Impl::ViewEnableArrayOper< reference_type ,
|
|
traits, typename traits::array_layout, 8,
|
|
iType0, iType1, iType2, iType3 , iType4, iType5, iType6, iType7 >::type
|
|
at( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ,
|
|
const iType4 & i4 , const iType5 & i5 , const iType6 & i6 , const iType7 & i7 ) const
|
|
{
|
|
KOKKOS_ASSERT_SHAPE_BOUNDS_8( m_offset_map, i0,i1,i2,i3,i4,i5,i6,i7 );
|
|
KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , ptr_on_device() );
|
|
|
|
return m_ptr_on_device[ m_offset_map(i0,i1,i2,i3,i4,i5,i6,i7) ];
|
|
}
|
|
|
|
//------------------------------------
|
|
// Access to the underlying contiguous storage of this view specialization.
|
|
// These methods are specific to specialization of a view.
|
|
|
|
KOKKOS_FORCEINLINE_FUNCTION
|
|
typename traits::value_type * ptr_on_device() const
|
|
{ return (typename traits::value_type *) m_ptr_on_device ; }
|
|
|
|
// Stride of physical storage, dimensioned to at least Rank
|
|
template< typename iType >
|
|
KOKKOS_INLINE_FUNCTION
|
|
void stride( iType * const s ) const
|
|
{ m_offset_map.stride(s); }
|
|
|
|
// Count of contiguously allocated data members including padding.
|
|
KOKKOS_INLINE_FUNCTION
|
|
typename traits::size_type capacity() const
|
|
{ return m_offset_map.capacity(); }
|
|
|
|
// If the view data can be treated (deep copied)
|
|
// as a contiguous block of memory.
|
|
KOKKOS_INLINE_FUNCTION
|
|
bool is_contiguous() const
|
|
{ return m_management.is_contiguous(); }
|
|
|
|
const Impl::AllocationTracker & tracker() const { return m_tracker; }
|
|
};
|
|
|
|
} /* namespace Kokkos */
|
|
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
|
|
namespace Kokkos {
|
|
|
|
template< class LT , class LL , class LD , class LM , class LS ,
|
|
class RT , class RL , class RD , class RM , class RS >
|
|
KOKKOS_INLINE_FUNCTION
|
|
typename Impl::enable_if<( Impl::is_same< LS , RS >::value ), bool >::type
|
|
operator == ( const View<LT,LL,LD,LM,LS> & lhs ,
|
|
const View<RT,RL,RD,RM,RS> & rhs )
|
|
{
|
|
// Same data, layout, dimensions
|
|
typedef ViewTraits<LT,LL,LD,LM> lhs_traits ;
|
|
typedef ViewTraits<RT,RL,RD,RM> rhs_traits ;
|
|
|
|
return
|
|
Impl::is_same< typename lhs_traits::const_data_type ,
|
|
typename rhs_traits::const_data_type >::value &&
|
|
Impl::is_same< typename lhs_traits::array_layout ,
|
|
typename rhs_traits::array_layout >::value &&
|
|
Impl::is_same< typename lhs_traits::memory_space ,
|
|
typename rhs_traits::memory_space >::value &&
|
|
Impl::is_same< typename lhs_traits::specialize ,
|
|
typename rhs_traits::specialize >::value &&
|
|
lhs.ptr_on_device() == rhs.ptr_on_device() &&
|
|
lhs.shape() == rhs.shape() ;
|
|
}
|
|
|
|
template< class LT , class LL , class LD , class LM , class LS ,
|
|
class RT , class RL , class RD , class RM , class RS >
|
|
KOKKOS_INLINE_FUNCTION
|
|
bool operator != ( const View<LT,LL,LD,LM,LS> & lhs ,
|
|
const View<RT,RL,RD,RM,RS> & rhs )
|
|
{
|
|
return ! operator==( lhs , rhs );
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
} // namespace Kokkos
|
|
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
|
|
namespace Kokkos {
|
|
|
|
//----------------------------------------------------------------------------
|
|
/** \brief Deep copy a value into a view.
|
|
*/
|
|
template< class DT , class DL , class DD , class DM , class DS >
|
|
inline
|
|
void deep_copy( const View<DT,DL,DD,DM,DS> & dst ,
|
|
typename Impl::enable_if<(
|
|
Impl::is_same< typename ViewTraits<DT,DL,DD,DM>::non_const_value_type ,
|
|
typename ViewTraits<DT,DL,DD,DM>::value_type >::value
|
|
), typename ViewTraits<DT,DL,DD,DM>::const_value_type >::type & value )
|
|
{
|
|
Impl::ViewFill< View<DT,DL,DD,DM,DS> >( dst , value );
|
|
}
|
|
|
|
template< class ST , class SL , class SD , class SM , class SS >
|
|
inline
|
|
typename Impl::enable_if<( ViewTraits<ST,SL,SD,SM>::rank == 0 )>::type
|
|
deep_copy( ST & dst , const View<ST,SL,SD,SM,SS> & src )
|
|
{
|
|
typedef ViewTraits<ST,SL,SD,SM> src_traits ;
|
|
typedef typename src_traits::memory_space src_memory_space ;
|
|
Impl::DeepCopy< HostSpace , src_memory_space >( & dst , src.ptr_on_device() , sizeof(ST) );
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
/** \brief A deep copy between views of compatible type, and rank zero.
|
|
*/
|
|
template< class DT , class DL , class DD , class DM , class DS ,
|
|
class ST , class SL , class SD , class SM , class SS >
|
|
inline
|
|
void deep_copy( const View<DT,DL,DD,DM,DS> & dst ,
|
|
const View<ST,SL,SD,SM,SS> & src ,
|
|
typename Impl::enable_if<(
|
|
// Same type and destination is not constant:
|
|
Impl::is_same< typename View<DT,DL,DD,DM,DS>::value_type ,
|
|
typename View<ST,SL,SD,SM,SS>::non_const_value_type >::value
|
|
&&
|
|
// Rank zero:
|
|
( unsigned(View<DT,DL,DD,DM,DS>::rank) == unsigned(0) ) &&
|
|
( unsigned(View<ST,SL,SD,SM,SS>::rank) == unsigned(0) )
|
|
)>::type * = 0 )
|
|
{
|
|
typedef View<DT,DL,DD,DM,DS> dst_type ;
|
|
typedef View<ST,SL,SD,SM,SS> src_type ;
|
|
|
|
typedef typename dst_type::memory_space dst_memory_space ;
|
|
typedef typename src_type::memory_space src_memory_space ;
|
|
typedef typename src_type::value_type value_type ;
|
|
|
|
if ( dst.ptr_on_device() != src.ptr_on_device() ) {
|
|
Impl::DeepCopy< dst_memory_space , src_memory_space >( dst.ptr_on_device() , src.ptr_on_device() , sizeof(value_type) );
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
/** \brief A deep copy between views of the default specialization, compatible type,
|
|
* same non-zero rank, same contiguous layout.
|
|
*/
|
|
template< class DT , class DL , class DD , class DM ,
|
|
class ST , class SL , class SD , class SM >
|
|
inline
|
|
void deep_copy( const View<DT,DL,DD,DM,Impl::ViewDefault> & dst ,
|
|
const View<ST,SL,SD,SM,Impl::ViewDefault> & src ,
|
|
typename Impl::enable_if<(
|
|
// Same type and destination is not constant:
|
|
Impl::is_same< typename View<DT,DL,DD,DM,Impl::ViewDefault>::value_type ,
|
|
typename View<ST,SL,SD,SM,Impl::ViewDefault>::non_const_value_type >::value
|
|
&&
|
|
// Same non-zero rank:
|
|
( unsigned(View<DT,DL,DD,DM,Impl::ViewDefault>::rank) ==
|
|
unsigned(View<ST,SL,SD,SM,Impl::ViewDefault>::rank) )
|
|
&&
|
|
( 0 < unsigned(View<DT,DL,DD,DM,Impl::ViewDefault>::rank) )
|
|
&&
|
|
// Same layout:
|
|
Impl::is_same< typename View<DT,DL,DD,DM,Impl::ViewDefault>::array_layout ,
|
|
typename View<ST,SL,SD,SM,Impl::ViewDefault>::array_layout >::value
|
|
)>::type * = 0 )
|
|
{
|
|
typedef View<DT,DL,DD,DM,Impl::ViewDefault> dst_type ;
|
|
typedef View<ST,SL,SD,SM,Impl::ViewDefault> src_type ;
|
|
|
|
typedef typename dst_type::memory_space dst_memory_space ;
|
|
typedef typename src_type::memory_space src_memory_space ;
|
|
|
|
enum { is_contiguous = // Contiguous (e.g., non-strided, non-tiled) layout
|
|
Impl::is_same< typename View<DT,DL,DD,DM,Impl::ViewDefault>::array_layout , LayoutLeft >::value ||
|
|
Impl::is_same< typename View<DT,DL,DD,DM,Impl::ViewDefault>::array_layout , LayoutRight >::value };
|
|
|
|
if ( dst.ptr_on_device() != src.ptr_on_device() ) {
|
|
|
|
// Same shape (dimensions)
|
|
|
|
const bool shapes_are_equal = dst.shape() == src.shape();
|
|
|
|
if ( shapes_are_equal && is_contiguous && dst.capacity() == src.capacity() ) {
|
|
|
|
// Views span equal length contiguous range.
|
|
// Assuming can perform a straight memory copy over this range.
|
|
|
|
const size_t nbytes = sizeof(typename dst_type::value_type) * dst.capacity();
|
|
|
|
Impl::DeepCopy< dst_memory_space , src_memory_space >( dst.ptr_on_device() , src.ptr_on_device() , nbytes );
|
|
}
|
|
else {
|
|
// Destination view's execution space must be able to directly access source memory space
|
|
// in order for the ViewRemap functor run in the destination memory space's execution space.
|
|
size_t stride[8];
|
|
src.stride(stride);
|
|
size_t size_stride = stride[0]*src.dimension_0();
|
|
size_t size_dim = src.dimension_0();
|
|
for(int i = 1; i<src.rank; i++) {
|
|
if(stride[i]*src.dimension(i)>size_stride)
|
|
size_stride = stride[i]*src.dimension(i);
|
|
size_dim*=src.dimension(i);
|
|
}
|
|
|
|
if( shapes_are_equal && size_stride == size_dim) {
|
|
const size_t nbytes = sizeof(typename dst_type::value_type) * dst.capacity();
|
|
|
|
Impl::DeepCopy< dst_memory_space , src_memory_space >( dst.ptr_on_device() , src.ptr_on_device() , nbytes );
|
|
} else {
|
|
Impl::ViewRemap< dst_type , src_type >( dst , src );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/** \brief Deep copy equal dimension arrays in the same space which
|
|
* have different layouts or specializations.
|
|
*/
|
|
template< class DT , class DL , class DD , class DM , class DS ,
|
|
class ST , class SL , class SD , class SM , class SS >
|
|
inline
|
|
void deep_copy( const View< DT, DL, DD, DM, DS > & dst ,
|
|
const View< ST, SL, SD, SM, SS > & src ,
|
|
const typename Impl::enable_if<(
|
|
// Same type and destination is not constant:
|
|
Impl::is_same< typename View<DT,DL,DD,DM,DS>::value_type ,
|
|
typename View<DT,DL,DD,DM,DS>::non_const_value_type >::value
|
|
&&
|
|
// Source memory space is accessible to destination memory space
|
|
Impl::VerifyExecutionCanAccessMemorySpace< typename View<DT,DL,DD,DM,DS>::memory_space
|
|
, typename View<ST,SL,SD,SM,SS>::memory_space >::value
|
|
&&
|
|
// Same non-zero rank
|
|
( unsigned( View<DT,DL,DD,DM,DS>::rank ) ==
|
|
unsigned( View<ST,SL,SD,SM,SS>::rank ) )
|
|
&&
|
|
( 0 < unsigned( View<DT,DL,DD,DM,DS>::rank ) )
|
|
&&
|
|
// Different layout or different specialization:
|
|
( ( ! Impl::is_same< typename View<DT,DL,DD,DM,DS>::array_layout ,
|
|
typename View<ST,SL,SD,SM,SS>::array_layout >::value )
|
|
||
|
|
( ! Impl::is_same< DS , SS >::value )
|
|
)
|
|
)>::type * = 0 )
|
|
{
|
|
typedef View< DT, DL, DD, DM, DS > dst_type ;
|
|
typedef View< ST, SL, SD, SM, SS > src_type ;
|
|
|
|
assert_shapes_equal_dimension( dst.shape() , src.shape() );
|
|
|
|
Impl::ViewRemap< dst_type , src_type >( dst , src );
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
|
|
template< class T , class L , class D , class M , class S >
|
|
typename Impl::enable_if<(
|
|
View<T,L,D,M,S>::is_managed &&
|
|
!Impl::is_same<L,LayoutStride>::value
|
|
), typename View<T,L,D,M,S>::HostMirror >::type
|
|
inline
|
|
create_mirror( const View<T,L,D,M,S> & src )
|
|
{
|
|
typedef View<T,L,D,M,S> view_type ;
|
|
typedef typename view_type::HostMirror host_view_type ;
|
|
|
|
// 'view' is managed therefore we can allocate a
|
|
// compatible host_view through the ordinary constructor.
|
|
|
|
std::string label = src.tracker().label();
|
|
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 Impl::enable_if<(
|
|
View<T,L,D,M,S>::is_managed &&
|
|
Impl::is_same<L,LayoutStride>::value
|
|
), typename View<T,L,D,M,S>::HostMirror >::type
|
|
inline
|
|
create_mirror( const View<T,L,D,M,S> & src )
|
|
{
|
|
typedef View<T,L,D,M,S> view_type ;
|
|
typedef typename view_type::HostMirror host_view_type ;
|
|
|
|
// 'view' is managed therefore we can allocate a
|
|
// compatible host_view through the ordinary constructor.
|
|
|
|
std::string label = src.tracker().label();
|
|
label.append("_mirror");
|
|
LayoutStride layout;
|
|
src.stride(layout.stride);
|
|
layout.dimension[0] = src.dimension_0();
|
|
layout.dimension[1] = src.dimension_1();
|
|
layout.dimension[2] = src.dimension_2();
|
|
layout.dimension[3] = src.dimension_3();
|
|
layout.dimension[4] = src.dimension_4();
|
|
layout.dimension[5] = src.dimension_5();
|
|
layout.dimension[6] = src.dimension_6();
|
|
layout.dimension[7] = src.dimension_7();
|
|
|
|
return host_view_type( label , layout );
|
|
}
|
|
template< class T , class L , class D , class M , class S >
|
|
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 )
|
|
{
|
|
return src ;
|
|
}
|
|
|
|
template< class T , class L , class D , class M , class S >
|
|
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 )
|
|
{
|
|
return create_mirror( src );
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
/** \brief Resize a view with copying old data to new data at the corresponding indices. */
|
|
template< class T , class L , class D , class M , class S >
|
|
inline
|
|
void resize( View<T,L,D,M,S> & v ,
|
|
const typename Impl::enable_if< ViewTraits<T,L,D,M>::is_managed , size_t >::type n0 ,
|
|
const size_t n1 = 0 ,
|
|
const size_t n2 = 0 ,
|
|
const size_t n3 = 0 ,
|
|
const size_t n4 = 0 ,
|
|
const size_t n5 = 0 ,
|
|
const size_t n6 = 0 ,
|
|
const size_t n7 = 0 )
|
|
{
|
|
typedef View<T,L,D,M,S> view_type ;
|
|
|
|
const std::string label = v.tracker().label();
|
|
|
|
view_type v_resized( label, n0, n1, n2, n3, n4, n5, n6, n7 );
|
|
|
|
Impl::ViewRemap< view_type , view_type >( v_resized , v );
|
|
|
|
v = v_resized ;
|
|
}
|
|
|
|
/** \brief Reallocate a view without copying old data to new data */
|
|
template< class T , class L , class D , class M , class S >
|
|
inline
|
|
void realloc( View<T,L,D,M,S> & v ,
|
|
const typename Impl::enable_if< ViewTraits<T,L,D,M>::is_managed , size_t >::type n0 ,
|
|
const size_t n1 = 0 ,
|
|
const size_t n2 = 0 ,
|
|
const size_t n3 = 0 ,
|
|
const size_t n4 = 0 ,
|
|
const size_t n5 = 0 ,
|
|
const size_t n6 = 0 ,
|
|
const size_t n7 = 0 )
|
|
{
|
|
typedef View<T,L,D,M,S> view_type ;
|
|
|
|
// Query the current label and reuse it.
|
|
const std::string label = v.tracker().label();
|
|
|
|
v = view_type(); // deallocate first, if the only view to memory.
|
|
v = view_type( label, n0, n1, n2, n3, n4, n5, n6, n7 );
|
|
}
|
|
|
|
} // namespace Kokkos
|
|
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
|
|
namespace Kokkos {
|
|
|
|
/** \brief Tag denoting that a subview should capture all of a dimension */
|
|
struct ALL { KOKKOS_INLINE_FUNCTION ALL(){} };
|
|
|
|
template< class D , class A1 , class A2 , class A3 , class S ,
|
|
class ArgType0 , class ArgType1 , class ArgType2 , class ArgType3 ,
|
|
class ArgType4 , class ArgType5 , class ArgType6 , class ArgType7 >
|
|
KOKKOS_INLINE_FUNCTION
|
|
typename Impl::ViewSubview< View<D,A1,A2,A3,S>
|
|
, ArgType0 , ArgType1 , ArgType2 , ArgType3
|
|
, ArgType4 , ArgType5 , ArgType6 , ArgType7
|
|
>::type
|
|
subview( const View<D,A1,A2,A3,S> & src ,
|
|
const ArgType0 & arg0 ,
|
|
const ArgType1 & arg1 ,
|
|
const ArgType2 & arg2 ,
|
|
const ArgType3 & arg3 ,
|
|
const ArgType4 & arg4 ,
|
|
const ArgType5 & arg5 ,
|
|
const ArgType6 & arg6 ,
|
|
const ArgType7 & arg7 )
|
|
{
|
|
typedef typename
|
|
Impl::ViewSubview< View<D,A1,A2,A3,S>
|
|
, ArgType0 , ArgType1 , ArgType2 , ArgType3
|
|
, ArgType4 , ArgType5 , ArgType6 , ArgType7
|
|
>::type
|
|
DstViewType ;
|
|
|
|
return DstViewType( src, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 );
|
|
}
|
|
|
|
template< class D , class A1 , class A2 , class A3 , class S ,
|
|
class ArgType0 , class ArgType1 , class ArgType2 , class ArgType3 ,
|
|
class ArgType4 , class ArgType5 , class ArgType6 >
|
|
KOKKOS_INLINE_FUNCTION
|
|
typename Impl::ViewSubview< View<D,A1,A2,A3,S>
|
|
, ArgType0 , ArgType1 , ArgType2 , ArgType3
|
|
, ArgType4 , ArgType5 , ArgType6 , void
|
|
>::type
|
|
subview( const View<D,A1,A2,A3,S> & src ,
|
|
const ArgType0 & arg0 ,
|
|
const ArgType1 & arg1 ,
|
|
const ArgType2 & arg2 ,
|
|
const ArgType3 & arg3 ,
|
|
const ArgType4 & arg4 ,
|
|
const ArgType5 & arg5 ,
|
|
const ArgType6 & arg6 )
|
|
{
|
|
typedef typename
|
|
Impl::ViewSubview< View<D,A1,A2,A3,S>
|
|
, ArgType0 , ArgType1 , ArgType2 , ArgType3
|
|
, ArgType4 , ArgType5 , ArgType6 , void
|
|
>::type
|
|
DstViewType ;
|
|
|
|
return DstViewType( src, arg0, arg1, arg2, arg3, arg4, arg5, arg6 );
|
|
}
|
|
|
|
template< class D , class A1 , class A2 , class A3 , class S ,
|
|
class ArgType0 , class ArgType1 , class ArgType2 , class ArgType3 ,
|
|
class ArgType4 , class ArgType5 >
|
|
KOKKOS_INLINE_FUNCTION
|
|
typename Impl::ViewSubview< View<D,A1,A2,A3,S>
|
|
, ArgType0 , ArgType1 , ArgType2 , ArgType3
|
|
, ArgType4 , ArgType5 , void , void
|
|
>::type
|
|
subview( const View<D,A1,A2,A3,S> & src ,
|
|
const ArgType0 & arg0 ,
|
|
const ArgType1 & arg1 ,
|
|
const ArgType2 & arg2 ,
|
|
const ArgType3 & arg3 ,
|
|
const ArgType4 & arg4 ,
|
|
const ArgType5 & arg5 )
|
|
{
|
|
typedef typename
|
|
Impl::ViewSubview< View<D,A1,A2,A3,S>
|
|
, ArgType0 , ArgType1 , ArgType2 , ArgType3
|
|
, ArgType4 , ArgType5 , void , void
|
|
>::type
|
|
DstViewType ;
|
|
|
|
return DstViewType( src, arg0, arg1, arg2, arg3, arg4, arg5 );
|
|
}
|
|
|
|
template< class D , class A1 , class A2 , class A3 , class S ,
|
|
class ArgType0 , class ArgType1 , class ArgType2 , class ArgType3 ,
|
|
class ArgType4 >
|
|
KOKKOS_INLINE_FUNCTION
|
|
typename Impl::ViewSubview< View<D,A1,A2,A3,S>
|
|
, ArgType0 , ArgType1 , ArgType2 , ArgType3
|
|
, ArgType4 , void , void , void
|
|
>::type
|
|
subview( const View<D,A1,A2,A3,S> & src ,
|
|
const ArgType0 & arg0 ,
|
|
const ArgType1 & arg1 ,
|
|
const ArgType2 & arg2 ,
|
|
const ArgType3 & arg3 ,
|
|
const ArgType4 & arg4 )
|
|
{
|
|
typedef typename
|
|
Impl::ViewSubview< View<D,A1,A2,A3,S>
|
|
, ArgType0 , ArgType1 , ArgType2 , ArgType3
|
|
, ArgType4 , void , void , void
|
|
>::type
|
|
DstViewType ;
|
|
|
|
return DstViewType( src, arg0, arg1, arg2, arg3, arg4 );
|
|
}
|
|
|
|
template< class D , class A1 , class A2 , class A3 , class S ,
|
|
class ArgType0 , class ArgType1 , class ArgType2 , class ArgType3 >
|
|
KOKKOS_INLINE_FUNCTION
|
|
typename Impl::ViewSubview< View<D,A1,A2,A3,S>
|
|
, ArgType0 , ArgType1 , ArgType2 , ArgType3
|
|
, void , void , void , void
|
|
>::type
|
|
subview( const View<D,A1,A2,A3,S> & src ,
|
|
const ArgType0 & arg0 ,
|
|
const ArgType1 & arg1 ,
|
|
const ArgType2 & arg2 ,
|
|
const ArgType3 & arg3 )
|
|
{
|
|
typedef typename
|
|
Impl::ViewSubview< View<D,A1,A2,A3,S>
|
|
, ArgType0 , ArgType1 , ArgType2 , ArgType3
|
|
, void , void , void , void
|
|
>::type
|
|
DstViewType ;
|
|
|
|
return DstViewType( src, arg0, arg1, arg2, arg3 );
|
|
}
|
|
|
|
template< class D , class A1 , class A2 , class A3 , class S ,
|
|
class ArgType0 , class ArgType1 , class ArgType2 >
|
|
KOKKOS_INLINE_FUNCTION
|
|
typename Impl::ViewSubview< View<D,A1,A2,A3,S>
|
|
, ArgType0 , ArgType1 , ArgType2 , void
|
|
, void , void , void , void
|
|
>::type
|
|
subview( const View<D,A1,A2,A3,S> & src ,
|
|
const ArgType0 & arg0 ,
|
|
const ArgType1 & arg1 ,
|
|
const ArgType2 & arg2 )
|
|
{
|
|
typedef typename
|
|
Impl::ViewSubview< View<D,A1,A2,A3,S>
|
|
, ArgType0 , ArgType1 , ArgType2 , void
|
|
, void , void , void , void
|
|
>::type
|
|
DstViewType ;
|
|
|
|
return DstViewType( src, arg0, arg1, arg2 );
|
|
}
|
|
|
|
template< class D , class A1 , class A2 , class A3 , class S ,
|
|
class ArgType0 , class ArgType1 >
|
|
KOKKOS_INLINE_FUNCTION
|
|
typename Impl::ViewSubview< View<D,A1,A2,A3,S>
|
|
, ArgType0 , ArgType1 , void , void
|
|
, void , void , void , void
|
|
>::type
|
|
subview( const View<D,A1,A2,A3,S> & src ,
|
|
const ArgType0 & arg0 ,
|
|
const ArgType1 & arg1 )
|
|
{
|
|
typedef typename
|
|
Impl::ViewSubview< View<D,A1,A2,A3,S>
|
|
, ArgType0 , ArgType1 , void , void
|
|
, void , void , void , void
|
|
>::type
|
|
DstViewType ;
|
|
|
|
return DstViewType( src, arg0, arg1 );
|
|
}
|
|
|
|
template< class D , class A1 , class A2 , class A3 , class S ,
|
|
class ArgType0 >
|
|
KOKKOS_INLINE_FUNCTION
|
|
typename Impl::ViewSubview< View<D,A1,A2,A3,S>
|
|
, ArgType0 , void , void , void
|
|
, void , void , void , void
|
|
>::type
|
|
subview( const View<D,A1,A2,A3,S> & src ,
|
|
const ArgType0 & arg0 )
|
|
{
|
|
typedef typename
|
|
Impl::ViewSubview< View<D,A1,A2,A3,S>
|
|
, ArgType0 , void , void , void
|
|
, void , void , void , void
|
|
>::type
|
|
DstViewType ;
|
|
|
|
return DstViewType( src, arg0 );
|
|
}
|
|
|
|
} // namespace Kokkos
|
|
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include <impl/Kokkos_ViewDefault.hpp>
|
|
#include <impl/Kokkos_Atomic_View.hpp>
|
|
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
|
|
#else
|
|
|
|
#include <impl/Kokkos_ViewOffset.hpp>
|
|
#include <impl/Kokkos_ViewSupport.hpp>
|
|
|
|
#endif /* #if defined( KOKKOS_USING_EXPERIMENTAL_VIEW ) */
|
|
|
|
#include <KokkosExp_View.hpp>
|
|
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
|
|
#endif
|
|
|