Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends
Kokkos_View.hpp
00001 /*
00002 //@HEADER
00003 // ************************************************************************
00004 //
00005 //   Kokkos: Manycore Performance-Portable Multidimensional Arrays
00006 //              Copyright (2012) Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact  H. Carter Edwards (hcedwar@sandia.gov)
00039 //
00040 // ************************************************************************
00041 //@HEADER
00042 */
00043 
00044 #ifndef KOKKOS_VIEW_HPP
00045 #define KOKKOS_VIEW_HPP
00046 
00047 #include <string>
00048 #include <Kokkos_Core_fwd.hpp>
00049 #include <Kokkos_HostSpace.hpp>
00050 #include <Kokkos_MemoryTraits.hpp>
00051 
00052 #include <impl/Kokkos_StaticAssert.hpp>
00053 #include <impl/Kokkos_Traits.hpp>
00054 #include <impl/Kokkos_Shape.hpp>
00055 #include <impl/Kokkos_AnalyzeShape.hpp>
00056 #include <impl/Kokkos_ViewSupport.hpp>
00057 #include <impl/Kokkos_ViewOffset.hpp>
00058 #include <impl/Kokkos_Tags.hpp>
00059 
00060 //----------------------------------------------------------------------------
00061 //----------------------------------------------------------------------------
00062 
00063 namespace Kokkos {
00064 namespace Impl {
00065 
00067 template< class ValueType ,
00068           class ArraySpecialize ,
00069           class ArrayLayout ,
00070           class MemorySpace ,
00071           class MemoryTraits >
00072 struct ViewSpecialize ;
00073 
00074 template< class DstViewSpecialize ,
00075           class SrcViewSpecialize = void ,
00076           class Enable = void >
00077 struct ViewAssignment ;
00078 
00079 template< class DstMemorySpace , class SrcMemorySpace >
00080 struct DeepCopy ;
00081 
00082 } /* namespace Impl */
00083 } // namespace Kokkos
00084 
00085 //----------------------------------------------------------------------------
00086 //----------------------------------------------------------------------------
00087 
00088 namespace Kokkos {
00089 
00108 template< class DataType ,
00109           class Arg1 ,
00110           class Arg2 ,
00111           class Arg3 >
00112 class ViewTraits {
00113 private:
00114 
00115   // Layout, Space, and MemoryTraits are optional
00116   // but need to appear in that order. That means Layout
00117   // can only be Arg1, Space can be Arg1 or Arg2, and
00118   // MemoryTraits can be Arg1, Arg2 or Arg3
00119 
00120   enum { Arg1IsLayout = Impl::is_layout<Arg1>::value };
00121 
00122   enum { Arg1IsExecSpace = Impl::is_execution_space<Arg1>::value };
00123   enum { Arg2IsExecSpace = Impl::is_execution_space<Arg2>::value };
00124 
00125   enum { Arg1IsMemorySpace = Impl::is_memory_space<Arg1>::value };
00126   enum { Arg2IsMemorySpace = Impl::is_memory_space<Arg2>::value };
00127 
00128   enum { Arg1IsMemoryTraits = Impl::is_memorytraits<Arg1>::value };
00129   enum { Arg2IsMemoryTraits = Impl::is_memorytraits<Arg2>::value };
00130   enum { Arg3IsMemoryTraits = Impl::is_memorytraits<Arg3>::value };
00131 
00132   // Arg1 or Arg2 may be either execution space or memory space
00133 
00134   typedef typename Impl::if_c<( Arg1IsExecSpace || Arg1IsMemorySpace ), Arg1 ,
00135           typename Impl::if_c<( Arg2IsExecSpace || Arg2IsMemorySpace ), Arg2 ,
00136           Kokkos::DefaultExecutionSpace 
00137           >::type >::type::execution_space  ExecutionSpace ;
00138 
00139   typedef typename Impl::if_c<( Arg1IsExecSpace || Arg1IsMemorySpace ), Arg1 ,
00140           typename Impl::if_c<( Arg2IsExecSpace || Arg2IsMemorySpace ), Arg2 ,
00141           Kokkos::DefaultExecutionSpace 
00142           >::type >::type::memory_space  MemorySpace ;
00143 
00144   // Arg1 may be array layout
00145   typedef typename Impl::if_c< Arg1IsLayout , Arg1 ,
00146           typename ExecutionSpace::array_layout
00147           >::type ArrayLayout ;
00148 
00149   // Arg1, Arg2, or Arg3 may be memory traits
00150   typedef typename Impl::if_c< Arg1IsMemoryTraits , Arg1 ,
00151           typename Impl::if_c< Arg2IsMemoryTraits , Arg2 ,
00152           typename Impl::if_c< Arg3IsMemoryTraits , Arg3 , MemoryManaged
00153           >::type >::type >::type  MemoryTraits ;
00154 
00155   typedef Impl::AnalyzeShape<DataType> analysis ;
00156 
00157 public:
00158 
00159   //------------------------------------
00160   // Data type traits:
00161 
00162   typedef DataType                            data_type ;
00163   typedef typename analysis::const_type       const_data_type ;
00164   typedef typename analysis::non_const_type   non_const_data_type ;
00165 
00166   //------------------------------------
00167   // Array of intrinsic scalar type traits:
00168 
00169   typedef typename analysis::array_type            array_type ;
00170   typedef typename analysis::const_array_type      const_array_type ;
00171   typedef typename analysis::non_const_array_type  non_const_array_type ;
00172 
00173   //------------------------------------
00174   // Value type traits:
00175 
00176   typedef typename analysis::value_type            value_type ;
00177   typedef typename analysis::const_value_type      const_value_type ;
00178   typedef typename analysis::non_const_value_type  non_const_value_type ;
00179 
00180   //------------------------------------
00181   // Layout and shape traits:
00182 
00183   typedef ArrayLayout                array_layout ;
00184   typedef typename analysis::shape   shape_type ;
00185 
00186   enum { rank         = shape_type::rank };
00187   enum { rank_dynamic = shape_type::rank_dynamic };
00188 
00189   //------------------------------------
00190   // Execution space, memory space, and memory traits:
00191 
00192   typedef ExecutionSpace  device_type ; // for backward compatibility
00193 
00194   typedef ExecutionSpace  execution_space ;
00195   typedef MemorySpace     memory_space ;
00196   typedef MemoryTraits    memory_traits ;
00197 
00198   typedef typename device_type::size_type  size_type ;
00199 
00200   enum { is_hostspace      = Impl::is_same< memory_space , HostSpace >::value };
00201   enum { is_managed        = memory_traits::Unmanaged == 0 };
00202   enum { is_random_access  = memory_traits::RandomAccess == 1 };
00203 
00204   //------------------------------------
00205   // Specialization tag:
00206 
00207   typedef typename
00208     Impl::ViewSpecialize< value_type
00209                         , typename analysis::specialize
00210                         , array_layout
00211                         , memory_space
00212                         , memory_traits
00213                         >::type specialize ;
00214 };
00215 
00216 } /* namespace Kokkos */
00217 
00218 //----------------------------------------------------------------------------
00219 //----------------------------------------------------------------------------
00220 
00221 namespace Kokkos {
00222 namespace Impl {
00223 
00236 template<class ViewTraits , class Enable = void>
00237 class ViewDataHandle {
00238 public:
00239   enum {ReferenceAble = 1};
00240   typedef typename ViewTraits::value_type* type;
00241   typedef typename ViewTraits::value_type& return_type;
00242 
00243   static type allocate(std::string label, size_t count) {
00244     return (type) ViewTraits::memory_space::allocate( label ,
00245                 typeid(typename ViewTraits::value_type) ,
00246                 sizeof(typename ViewTraits::value_type) ,
00247                 count );
00248   }
00249 
00250   KOKKOS_INLINE_FUNCTION
00251   static typename ViewTraits::value_type* get_raw_ptr(type ptr) {
00252     return ptr;
00253   }
00254 };
00255 
00256 }
00257 }
00258 
00259 //----------------------------------------------------------------------------
00260 //----------------------------------------------------------------------------
00261 
00262 namespace Kokkos {
00263 namespace Impl {
00264 
00265 class ViewDefault {};
00266 
00269 template< class ValueType , class MemorySpace , class MemoryTraits >
00270 struct ViewSpecialize< ValueType , void , LayoutLeft , MemorySpace , MemoryTraits >
00271 { typedef ViewDefault type ; };
00272 
00273 template< class ValueType , class MemorySpace , class MemoryTraits >
00274 struct ViewSpecialize< ValueType , void , LayoutRight , MemorySpace , MemoryTraits >
00275 { typedef ViewDefault type ; };
00276 
00277 template< class ValueType , class MemorySpace , class MemoryTraits >
00278 struct ViewSpecialize< ValueType , void , LayoutStride , MemorySpace , MemoryTraits >
00279 { typedef ViewDefault type ; };
00280 
00281 } /* namespace Impl */
00282 } /* namespace Kokkos */
00283 
00284 //----------------------------------------------------------------------------
00285 //----------------------------------------------------------------------------
00286 
00287 namespace Kokkos {
00288 namespace Impl {
00289 
00291 namespace ViewError {
00292 
00293 struct allocation_constructor_requires_managed {};
00294 struct allocation_constructor_requires_nonconst {};
00295 struct user_pointer_constructor_requires_unmanaged {};
00296 struct device_shmem_constructor_requires_unmanaged {};
00297 
00298 struct scalar_operator_called_from_non_scalar_view {};
00299 
00300 } /* namespace ViewError */
00301 
00302 //----------------------------------------------------------------------------
00303 
00304 template< class Type >
00305 struct IsViewLabel : public Kokkos::Impl::false_type {};
00306 
00307 template<>
00308 struct IsViewLabel<std::string> : public Kokkos::Impl::true_type {};
00309 
00310 template< unsigned N >
00311 struct IsViewLabel<char[N]> : public Kokkos::Impl::true_type {};
00312 
00313 //----------------------------------------------------------------------------
00319 template< class ReturnType , class Traits , class Layout , unsigned Rank ,
00320           typename iType0 = int , typename iType1 = int ,
00321           typename iType2 = int , typename iType3 = int ,
00322           typename iType4 = int , typename iType5 = int ,
00323           typename iType6 = int , typename iType7 = int ,
00324           class Enable = void >
00325 struct ViewEnableArrayOper ;
00326 
00327 template< class ReturnType , class Traits , class Layout , unsigned Rank ,
00328           typename iType0 , typename iType1 ,
00329           typename iType2 , typename iType3 ,
00330           typename iType4 , typename iType5 ,
00331           typename iType6 , typename iType7 >
00332 struct ViewEnableArrayOper<
00333    ReturnType , Traits , Layout , Rank ,
00334    iType0 , iType1 , iType2 , iType3 ,
00335    iType4 , iType5 , iType6 , iType7 ,
00336    typename enable_if<
00337      iType0(0) == 0 && iType1(0) == 0 && iType2(0) == 0 && iType3(0) == 0 &&
00338      iType4(0) == 0 && iType5(0) == 0 && iType6(0) == 0 && iType7(0) == 0 &&
00339      is_same< typename Traits::array_layout , Layout >::value &&
00340      ( unsigned(Traits::rank) == Rank )
00341    >::type >
00342 {
00343   typedef ReturnType type ;
00344 };
00345 
00346 } /* namespace Impl */
00347 } /* namespace Kokkos */
00348 
00349 //----------------------------------------------------------------------------
00350 //----------------------------------------------------------------------------
00351 
00352 namespace Kokkos {
00353 
00354 struct AllocateWithoutInitializing {};
00355 struct ViewWithoutManaging {};
00356 
00357 namespace {
00358 const AllocateWithoutInitializing allocate_without_initializing = AllocateWithoutInitializing();
00359 const ViewWithoutManaging view_without_managing = ViewWithoutManaging();
00360 }
00361 
00443 template< class DataType ,
00444           class Arg1Type = void , /* ArrayLayout, SpaceType or MemoryTraits*/
00445           class Arg2Type = void , /* SpaceType or MemoryTraits */
00446           class Arg3Type = void , /* MemoryTraits */
00447           class Specialize =
00448             typename ViewTraits<DataType,Arg1Type,Arg2Type,Arg3Type>::specialize >
00449 class View ;
00450 
00451 namespace Impl {
00452 
00453 template< class C >
00454 struct is_view : public bool_< false > {};
00455 
00456 template< class D , class A1 , class A2 , class A3 , class S >
00457 struct is_view< View< D , A1 , A2 , A3 , S > > : public bool_< true > {};
00458 
00459 }
00460 
00461 //----------------------------------------------------------------------------
00462 
00463 template< class DataType ,
00464           class Arg1Type ,
00465           class Arg2Type ,
00466           class Arg3Type >
00467 class View< DataType , Arg1Type , Arg2Type , Arg3Type , Impl::ViewDefault >
00468   : public ViewTraits< DataType , Arg1Type , Arg2Type, Arg3Type >
00469 {
00470 public:
00471 
00472   typedef ViewTraits< DataType , Arg1Type , Arg2Type, Arg3Type > traits ;
00473 
00474 private:
00475 
00476   // Assignment of compatible views requirement:
00477   template< class , class , class , class , class > friend class View ;
00478 
00479   // Assignment of compatible subview requirement:
00480   template< class , class , class > friend struct Impl::ViewAssignment ;
00481 
00482   // Dimensions, cardinality, capacity, and offset computation for
00483   // multidimensional array view of contiguous memory.
00484   // Inherits from Impl::Shape
00485   typedef Impl::ViewOffset< typename traits::shape_type
00486                           , typename traits::array_layout
00487                           > offset_map_type ;
00488 
00489   typedef Impl::ViewDataHandle< traits > data_handle_type;
00490 
00491   typename data_handle_type::type m_ptr_on_device ;
00492 
00493   typedef typename data_handle_type::return_type return_type;
00494 
00495   offset_map_type               m_offset_map ;
00496   Impl::ViewTracking< traits >  m_tracking ;
00497 
00498 public:
00499 
00500   typedef View< typename traits::array_type ,
00501                 typename traits::array_layout ,
00502                 typename traits::device_type ,
00503                 typename traits::memory_traits > array_type ;
00504 
00505   typedef View< typename traits::const_data_type ,
00506                 typename traits::array_layout ,
00507                 typename traits::device_type ,
00508                 typename traits::memory_traits > const_type ;
00509 
00510   typedef View< typename traits::non_const_data_type ,
00511                 typename traits::array_layout ,
00512                 typename traits::device_type ,
00513                 typename traits::memory_traits > non_const_type ;
00514 
00515   typedef View< typename traits::non_const_data_type ,
00516                 typename traits::array_layout ,
00517                 typename Impl::if_c< traits::is_hostspace ,
00518                   typename traits::execution_space , HostSpace>::type ,
00519                 void > HostMirror ;
00520 
00521   //------------------------------------
00522   // Shape
00523 
00524   enum { Rank = traits::rank };
00525 
00526   KOKKOS_INLINE_FUNCTION offset_map_type shape() const { return m_offset_map ; }
00527   KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_0() const { return m_offset_map.N0 ; }
00528   KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_1() const { return m_offset_map.N1 ; }
00529   KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_2() const { return m_offset_map.N2 ; }
00530   KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_3() const { return m_offset_map.N3 ; }
00531   KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_4() const { return m_offset_map.N4 ; }
00532   KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_5() const { return m_offset_map.N5 ; }
00533   KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_6() const { return m_offset_map.N6 ; }
00534   KOKKOS_INLINE_FUNCTION typename traits::size_type dimension_7() const { return m_offset_map.N7 ; }
00535   KOKKOS_INLINE_FUNCTION typename traits::size_type size() const { return m_offset_map.cardinality(); }
00536 
00537   template< typename iType >
00538   KOKKOS_INLINE_FUNCTION
00539   typename traits::size_type dimension( const iType & i ) const
00540     { return Impl::dimension( m_offset_map , i ); }
00541 
00542   //------------------------------------
00543   // Destructor, constructors, assignment operators:
00544 
00545   KOKKOS_INLINE_FUNCTION
00546   ~View() { m_tracking.decrement( data_handle_type::get_raw_ptr(m_ptr_on_device) ); }
00547 
00548   KOKKOS_INLINE_FUNCTION
00549   View() : m_ptr_on_device((typename traits::value_type*) NULL)
00550     { m_offset_map.assign(0, 0,0,0,0,0,0,0,0); }
00551 
00552   KOKKOS_INLINE_FUNCTION
00553   View( const View & rhs ) : m_ptr_on_device((typename traits::value_type*) NULL)
00554     {
00555       (void) Impl::ViewAssignment<
00556          typename traits::specialize ,
00557          typename traits::specialize >( *this , rhs );
00558     }
00559 
00560   KOKKOS_INLINE_FUNCTION
00561   View & operator = ( const View & rhs )
00562     {
00563       (void) Impl::ViewAssignment<
00564          typename traits::specialize ,
00565          typename traits::specialize >( *this , rhs );
00566       return *this ;
00567     }
00568 
00569   //------------------------------------
00570   // Construct or assign compatible view:
00571 
00572   template< class RT , class RL , class RD , class RM , class RS >
00573   KOKKOS_INLINE_FUNCTION
00574   View( const View<RT,RL,RD,RM,RS> & rhs )
00575     : m_ptr_on_device((typename traits::value_type*) NULL)
00576     {
00577       (void) Impl::ViewAssignment<
00578          typename traits::specialize , RS >( *this , rhs );
00579     }
00580 
00581   template< class RT , class RL , class RD , class RM , class RS >
00582   KOKKOS_INLINE_FUNCTION
00583   View & operator = ( const View<RT,RL,RD,RM,RS> & rhs )
00584     {
00585       (void) Impl::ViewAssignment<
00586          typename traits::specialize , RS >( *this , rhs );
00587       return *this ;
00588     }
00589 
00590   //------------------------------------
00591   // Allocation of a managed view with possible alignment padding.
00592   // Allocation constructor enabled for managed and non-const values
00593 
00594   template< class LabelType >
00595   explicit inline
00596   View( const LabelType & label ,
00597         const size_t n0 = 0 ,
00598         const size_t n1 = 0 ,
00599         const size_t n2 = 0 ,
00600         const size_t n3 = 0 ,
00601         const size_t n4 = 0 ,
00602         const size_t n5 = 0 ,
00603         const size_t n6 = 0 ,
00604         const size_t n7 = 0 ,
00605         typename Impl::enable_if<(
00606           Impl::IsViewLabel< LabelType >::value &&
00607           ( ! Impl::is_const< typename traits::value_type >::value ) &&
00608           traits::is_managed ),
00609         const size_t >::type n8 = 0 )
00610     : m_ptr_on_device(0)
00611     {
00612       // typedef typename traits::memory_space  memory_space_ ; // unused
00613       // typedef typename traits::value_type    value_type_ ; // unused
00614 
00615       m_offset_map.assign( n0, n1, n2, n3, n4, n5, n6, n7, n8 );
00616       m_offset_map.set_padding();
00617 
00618       m_ptr_on_device = data_handle_type::allocate( label , m_offset_map.capacity() );
00619 
00620       (void) Impl::ViewFill< View >( *this , typename traits::value_type() );
00621     }
00622 
00623   template< class LabelType >
00624   explicit inline
00625   View( const AllocateWithoutInitializing & ,
00626         const LabelType & label ,
00627         const size_t n0 = 0 ,
00628         const size_t n1 = 0 ,
00629         const size_t n2 = 0 ,
00630         const size_t n3 = 0 ,
00631         const size_t n4 = 0 ,
00632         const size_t n5 = 0 ,
00633         const size_t n6 = 0 ,
00634         const size_t n7 = 0 ,
00635         typename Impl::enable_if<(
00636           Impl::IsViewLabel< LabelType >::value &&
00637           ( ! Impl::is_const< typename traits::value_type >::value ) &&
00638           traits::is_managed ),
00639         const size_t >::type n8 = 0 )
00640     : m_ptr_on_device(0)
00641     {
00642       // typedef typename traits::memory_space  memory_space_ ; // unused
00643       // typedef typename traits::value_type    value_type_ ; // unused
00644 
00645       m_offset_map.assign( n0, n1, n2, n3, n4, n5, n6, n7, n8 );
00646       m_offset_map.set_padding();
00647 
00648       m_ptr_on_device = data_handle_type::allocate( label , m_offset_map.capacity() );
00649     }
00650 
00651   template< class LabelType >
00652   explicit inline
00653   View( const AllocateWithoutInitializing & ,
00654         const LabelType & label ,
00655         typename Impl::enable_if<(
00656           Impl::IsViewLabel< LabelType >::value &&
00657           ( ! Impl::is_const< typename traits::value_type >::value ) &&
00658           traits::is_managed ),
00659         const typename traits::array_layout >::type layout )
00660     : m_ptr_on_device(0)
00661     {
00662       // typedef typename traits::memory_space  memory_space_ ; // unused
00663       // typedef typename traits::value_type    value_type_ ; // unused
00664 
00665       m_offset_map.assign( layout );
00666       m_offset_map.set_padding();
00667 
00668       m_ptr_on_device = data_handle_type::allocate( label , m_offset_map.capacity() );
00669     }
00670 
00671   template< class LabelType >
00672   explicit inline
00673   View( const LabelType & label ,
00674         typename Impl::enable_if<(
00675           Impl::IsViewLabel< LabelType >::value &&
00676           ( ! Impl::is_const< typename traits::value_type >::value ) &&
00677           traits::is_managed
00678         ), typename traits::array_layout const & >::type layout )
00679     : m_ptr_on_device(0)
00680     {
00681       // typedef typename traits::memory_space  memory_space_ ; // unused
00682       // typedef typename traits::value_type    value_type_ ; // unused
00683 
00684       m_offset_map.assign( layout );
00685       m_offset_map.set_padding();
00686 
00687       m_ptr_on_device = data_handle_type::allocate( label , m_offset_map.capacity() );
00688 
00689       (void) Impl::ViewFill< View >( *this , typename traits::value_type() );
00690     }
00691 
00692   //------------------------------------
00693   // Assign an unmanaged View from pointer, can be called in functors.
00694   // No alignment padding is performed.
00695 
00696   template< typename T >
00697   explicit KOKKOS_INLINE_FUNCTION
00698   View( T * ptr ,
00699         const size_t n0 = 0 ,
00700         const size_t n1 = 0 ,
00701         const size_t n2 = 0 ,
00702         const size_t n3 = 0 ,
00703         const size_t n4 = 0 ,
00704         const size_t n5 = 0 ,
00705         const size_t n6 = 0 ,
00706         const size_t n7 = 0 ,
00707         typename Impl::enable_if<(
00708           ( Impl::is_same<T,typename traits::value_type>::value ||
00709             Impl::is_same<T,typename traits::const_value_type>::value )
00710           &&
00711           ( ! traits::is_managed )
00712         ), const size_t >::type n8 = 0 )
00713     : m_ptr_on_device(ptr)
00714     {
00715       m_offset_map.assign( n0, n1, n2, n3, n4, n5, n6, n7, n8 );
00716       m_tracking = false ;
00717     }
00718 
00719   template< typename T >
00720   explicit KOKKOS_INLINE_FUNCTION
00721   View( T * ptr ,
00722         typename Impl::enable_if<(
00723           ( Impl::is_same<T,typename traits::value_type>::value ||
00724             Impl::is_same<T,typename traits::const_value_type>::value )
00725           &&
00726           ( ! traits::is_managed )
00727         ), typename traits::array_layout const & >::type layout )
00728     : m_ptr_on_device(ptr)
00729     {
00730       m_offset_map.assign( layout );
00731       m_tracking = false ;
00732     }
00733 
00734   explicit inline
00735   View( const ViewWithoutManaging & ,
00736         typename traits::value_type * ptr ,
00737         const size_t n0 = 0 ,
00738         const size_t n1 = 0 ,
00739         const size_t n2 = 0 ,
00740         const size_t n3 = 0 ,
00741         const size_t n4 = 0 ,
00742         const size_t n5 = 0 ,
00743         const size_t n6 = 0 ,
00744         const size_t n7 = 0 ,
00745         const size_t n8 = 0 )
00746     : m_ptr_on_device(ptr)
00747     {
00748       m_offset_map.assign( n0, n1, n2, n3, n4, n5, n6, n7, n8 );
00749       m_tracking = false ;
00750     }
00751 
00752   explicit KOKKOS_INLINE_FUNCTION
00753   View( const ViewWithoutManaging &
00754       , typename traits::value_type * ptr
00755       , typename traits::array_layout const & layout )
00756     : m_ptr_on_device(ptr)
00757     {
00758       m_offset_map.assign( layout );
00759       m_tracking = false ;
00760     }
00761 
00762   //------------------------------------
00763   // Assign unmanaged View to portion of execution space's shared memory
00764 
00765   typedef Impl::if_c< ! traits::is_managed ,
00766                       const typename traits::device_type::scratch_memory_space & ,
00767                       Impl::ViewError::device_shmem_constructor_requires_unmanaged >
00768       if_scratch_memory_constructor ;
00769 
00770   explicit KOKKOS_INLINE_FUNCTION
00771   View( typename if_scratch_memory_constructor::type space ,
00772         const unsigned n0 = 0 ,
00773         const unsigned n1 = 0 ,
00774         const unsigned n2 = 0 ,
00775         const unsigned n3 = 0 ,
00776         const unsigned n4 = 0 ,
00777         const unsigned n5 = 0 ,
00778         const unsigned n6 = 0 ,
00779         const unsigned n7 = 0 )
00780     : m_ptr_on_device(0)
00781     {
00782       typedef typename traits::value_type  value_type_ ;
00783 
00784       enum { align = 8 };
00785       enum { mask  = align - 1 };
00786 
00787       m_offset_map.assign( n0, n1, n2, n3, n4, n5, n6, n7 );
00788 
00789       typedef Impl::if_c< ! traits::is_managed ,
00790                           value_type_ * ,
00791                           Impl::ViewError::device_shmem_constructor_requires_unmanaged >
00792         if_device_shmem_pointer ;
00793 
00794       // Select the first argument:
00795       m_ptr_on_device = if_device_shmem_pointer::select(
00796        (value_type_*) space.get_shmem( unsigned( sizeof(value_type_) * m_offset_map.capacity() + unsigned(mask) ) & ~unsigned(mask) ) );
00797     }
00798 
00799   explicit KOKKOS_INLINE_FUNCTION
00800   View( typename if_scratch_memory_constructor::type space ,
00801         typename traits::array_layout const & layout)
00802     : m_ptr_on_device(0)
00803     {
00804       typedef typename traits::value_type  value_type_ ;
00805 
00806       typedef Impl::if_c< ! traits::is_managed ,
00807                           value_type_ * ,
00808                           Impl::ViewError::device_shmem_constructor_requires_unmanaged >
00809         if_device_shmem_pointer ;
00810 
00811       m_offset_map.assign( layout );
00812       m_tracking = false ;
00813 
00814       enum { align = 8 };
00815       enum { mask  = align - 1 };
00816 
00817       // Select the first argument:
00818       m_ptr_on_device = if_device_shmem_pointer::select(
00819        (value_type_*) space.get_shmem( unsigned( sizeof(value_type_) * m_offset_map.capacity() + unsigned(mask) ) & ~unsigned(mask) ) );
00820     }
00821 
00822   static inline
00823   unsigned shmem_size( const unsigned n0 = 0 ,
00824                        const unsigned n1 = 0 ,
00825                        const unsigned n2 = 0 ,
00826                        const unsigned n3 = 0 ,
00827                        const unsigned n4 = 0 ,
00828                        const unsigned n5 = 0 ,
00829                        const unsigned n6 = 0 ,
00830                        const unsigned n7 = 0 )
00831   {
00832     enum { align = 8 };
00833     enum { mask  = align - 1 };
00834 
00835     typedef typename traits::value_type  value_type_ ;
00836 
00837     offset_map_type offset_map ;
00838 
00839     offset_map.assign( n0, n1, n2, n3, n4, n5, n6, n7 );
00840 
00841     return unsigned( sizeof(value_type_) * offset_map.capacity() + unsigned(mask) ) & ~unsigned(mask) ;
00842   }
00843 
00844   //------------------------------------
00845   // Is not allocated
00846 
00847   KOKKOS_FORCEINLINE_FUNCTION
00848   bool is_null() const { return 0 == data_handle_type::get_raw_ptr(m_ptr_on_device) ; }
00849 
00850   //------------------------------------
00851   // Operators for scalar (rank zero) views.
00852 
00853   typedef Impl::if_c< traits::rank == 0 ,
00854                       typename traits::value_type ,
00855                       Impl::ViewError::scalar_operator_called_from_non_scalar_view >
00856     if_scalar_operator ;
00857 
00858   KOKKOS_INLINE_FUNCTION
00859   const View & operator = ( const typename if_scalar_operator::type & rhs ) const
00860     {
00861       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
00862       *m_ptr_on_device = if_scalar_operator::select( rhs );
00863       return *this ;
00864     }
00865 
00866   KOKKOS_FORCEINLINE_FUNCTION
00867   operator typename if_scalar_operator::type & () const
00868     {
00869       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
00870       return if_scalar_operator::select( *m_ptr_on_device );
00871     }
00872 
00873   KOKKOS_FORCEINLINE_FUNCTION
00874   typename if_scalar_operator::type & operator()() const
00875     {
00876       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
00877       return if_scalar_operator::select( *m_ptr_on_device );
00878     }
00879 
00880   KOKKOS_FORCEINLINE_FUNCTION
00881   typename if_scalar_operator::type & operator*() const
00882     {
00883       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
00884       return if_scalar_operator::select( *m_ptr_on_device );
00885     }
00886 
00887   //------------------------------------
00888   // Array member access operators enabled if
00889   // (1) a zero value of all argument types are compile-time comparable to zero
00890   // (2) the rank matches the number of arguments
00891   // (3) the memory space is valid for the access
00892   //------------------------------------
00893   // rank 1:
00894 
00895   template< typename iType0 >
00896   KOKKOS_FORCEINLINE_FUNCTION
00897   typename Impl::ViewEnableArrayOper< return_type , traits, typename traits::array_layout, 1, iType0 >::type
00898     operator[] ( const iType0 & i0 ) const
00899     {
00900       KOKKOS_ASSERT_SHAPE_BOUNDS_1( m_offset_map, i0 );
00901       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
00902 
00903       return m_ptr_on_device[ i0 ];
00904     }
00905 
00906   template< typename iType0 >
00907   KOKKOS_FORCEINLINE_FUNCTION
00908   typename Impl::ViewEnableArrayOper< return_type , traits, typename traits::array_layout, 1, iType0 >::type
00909     operator() ( const iType0 & i0 ) const
00910     {
00911       KOKKOS_ASSERT_SHAPE_BOUNDS_1( m_offset_map, i0 );
00912       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
00913 
00914       return m_ptr_on_device[ i0 ];
00915     }
00916 
00917   template< typename iType0 >
00918   KOKKOS_FORCEINLINE_FUNCTION
00919   typename Impl::ViewEnableArrayOper< return_type , traits, typename traits::array_layout, 1, iType0 >::type
00920     at( const iType0 & i0 , const int , const int , const int ,
00921         const int , const int , const int , const int ) const
00922     {
00923       KOKKOS_ASSERT_SHAPE_BOUNDS_1( m_offset_map, i0 );
00924       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
00925 
00926       return m_ptr_on_device[ i0 ];
00927     }
00928 
00929   // rank 2:
00930 
00931   template< typename iType0 , typename iType1 >
00932   KOKKOS_FORCEINLINE_FUNCTION
00933   typename Impl::ViewEnableArrayOper< return_type ,
00934                                       traits, typename traits::array_layout, 2, iType0, iType1 >::type
00935     operator() ( const iType0 & i0 , const iType1 & i1 ) const
00936     {
00937       KOKKOS_ASSERT_SHAPE_BOUNDS_2( m_offset_map, i0,i1 );
00938       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
00939 
00940       return m_ptr_on_device[ m_offset_map(i0,i1) ];
00941     }
00942 
00943   template< typename iType0 , typename iType1 >
00944   KOKKOS_FORCEINLINE_FUNCTION
00945   typename Impl::ViewEnableArrayOper< return_type ,
00946                                       traits, typename traits::array_layout, 2, iType0, iType1 >::type
00947     at( const iType0 & i0 , const iType1 & i1 , const int , const int ,
00948         const int , const int , const int , const int ) const
00949     {
00950       KOKKOS_ASSERT_SHAPE_BOUNDS_2( m_offset_map, i0,i1 );
00951       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
00952 
00953       return m_ptr_on_device[ m_offset_map(i0,i1) ];
00954     }
00955 
00956   // rank 3:
00957 
00958   template< typename iType0 , typename iType1 , typename iType2 >
00959   KOKKOS_FORCEINLINE_FUNCTION
00960   typename Impl::ViewEnableArrayOper< return_type ,
00961                                       traits, typename traits::array_layout, 3, iType0, iType1, iType2 >::type
00962     operator() ( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 ) const
00963     {
00964       KOKKOS_ASSERT_SHAPE_BOUNDS_3( m_offset_map, i0,i1,i2 );
00965       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
00966 
00967       return m_ptr_on_device[ m_offset_map(i0,i1,i2) ];
00968     }
00969 
00970   template< typename iType0 , typename iType1 , typename iType2 >
00971   KOKKOS_FORCEINLINE_FUNCTION
00972   typename Impl::ViewEnableArrayOper< return_type ,
00973                                       traits, typename traits::array_layout, 3, iType0, iType1, iType2 >::type
00974     at( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const int ,
00975         const int , const int , const int , const int ) const
00976     {
00977       KOKKOS_ASSERT_SHAPE_BOUNDS_3( m_offset_map, i0,i1,i2 );
00978       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
00979 
00980       return m_ptr_on_device[ m_offset_map(i0,i1,i2) ];
00981     }
00982 
00983   // rank 4:
00984 
00985   template< typename iType0 , typename iType1 , typename iType2 , typename iType3 >
00986   KOKKOS_FORCEINLINE_FUNCTION
00987   typename Impl::ViewEnableArrayOper< return_type ,
00988                                       traits, typename traits::array_layout, 4, iType0, iType1, iType2, iType3 >::type
00989     operator() ( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ) const
00990     {
00991       KOKKOS_ASSERT_SHAPE_BOUNDS_4( m_offset_map, i0,i1,i2,i3 );
00992       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
00993 
00994       return m_ptr_on_device[ m_offset_map(i0,i1,i2,i3) ];
00995     }
00996 
00997   template< typename iType0 , typename iType1 , typename iType2 , typename iType3 >
00998   KOKKOS_FORCEINLINE_FUNCTION
00999   typename Impl::ViewEnableArrayOper< return_type ,
01000                                       traits, typename traits::array_layout, 4, iType0, iType1, iType2, iType3 >::type
01001     at( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ,
01002         const int , const int , const int , const int ) const
01003     {
01004       KOKKOS_ASSERT_SHAPE_BOUNDS_4( m_offset_map, i0,i1,i2,i3 );
01005       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
01006 
01007       return m_ptr_on_device[ m_offset_map(i0,i1,i2,i3) ];
01008     }
01009 
01010   // rank 5:
01011 
01012   template< typename iType0 , typename iType1 , typename iType2 , typename iType3 ,
01013             typename iType4 >
01014   KOKKOS_FORCEINLINE_FUNCTION
01015   typename Impl::ViewEnableArrayOper< return_type ,
01016                                       traits, typename traits::array_layout, 5, iType0, iType1, iType2, iType3 , iType4 >::type
01017     operator() ( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ,
01018                  const iType4 & i4 ) const
01019     {
01020       KOKKOS_ASSERT_SHAPE_BOUNDS_5( m_offset_map, i0,i1,i2,i3,i4 );
01021       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
01022 
01023       return m_ptr_on_device[ m_offset_map(i0,i1,i2,i3,i4) ];
01024     }
01025 
01026   template< typename iType0 , typename iType1 , typename iType2 , typename iType3 ,
01027             typename iType4 >
01028   KOKKOS_FORCEINLINE_FUNCTION
01029   typename Impl::ViewEnableArrayOper< return_type ,
01030                                       traits, typename traits::array_layout, 5, iType0, iType1, iType2, iType3 , iType4 >::type
01031     at( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ,
01032         const iType4 & i4 , const int , const int , const int ) const
01033     {
01034       KOKKOS_ASSERT_SHAPE_BOUNDS_5( m_offset_map, i0,i1,i2,i3,i4 );
01035       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
01036 
01037       return m_ptr_on_device[ m_offset_map(i0,i1,i2,i3,i4) ];
01038     }
01039 
01040   // rank 6:
01041 
01042   template< typename iType0 , typename iType1 , typename iType2 , typename iType3 ,
01043             typename iType4 , typename iType5 >
01044   KOKKOS_FORCEINLINE_FUNCTION
01045   typename Impl::ViewEnableArrayOper< return_type ,
01046                                       traits, typename traits::array_layout, 6,
01047                                       iType0, iType1, iType2, iType3 , iType4, iType5 >::type
01048     operator() ( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ,
01049                  const iType4 & i4 , const iType5 & i5 ) const
01050     {
01051       KOKKOS_ASSERT_SHAPE_BOUNDS_6( m_offset_map, i0,i1,i2,i3,i4,i5 );
01052       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
01053 
01054       return m_ptr_on_device[ m_offset_map(i0,i1,i2,i3,i4,i5) ];
01055     }
01056 
01057   template< typename iType0 , typename iType1 , typename iType2 , typename iType3 ,
01058             typename iType4 , typename iType5 >
01059   KOKKOS_FORCEINLINE_FUNCTION
01060   typename Impl::ViewEnableArrayOper< return_type ,
01061                                       traits, typename traits::array_layout, 6,
01062                                       iType0, iType1, iType2, iType3 , iType4, iType5 >::type
01063     at( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ,
01064         const iType4 & i4 , const iType5 & i5 , const int , const int ) const
01065     {
01066       KOKKOS_ASSERT_SHAPE_BOUNDS_6( m_offset_map, i0,i1,i2,i3,i4,i5 );
01067       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
01068 
01069       return m_ptr_on_device[ m_offset_map(i0,i1,i2,i3,i4,i5) ];
01070     }
01071 
01072   // rank 7:
01073 
01074   template< typename iType0 , typename iType1 , typename iType2 , typename iType3 ,
01075             typename iType4 , typename iType5 , typename iType6 >
01076   KOKKOS_FORCEINLINE_FUNCTION
01077   typename Impl::ViewEnableArrayOper< return_type ,
01078                                       traits, typename traits::array_layout, 7,
01079                                       iType0, iType1, iType2, iType3 , iType4, iType5, iType6 >::type
01080     operator() ( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ,
01081                  const iType4 & i4 , const iType5 & i5 , const iType6 & i6 ) const
01082     {
01083       KOKKOS_ASSERT_SHAPE_BOUNDS_7( m_offset_map, i0,i1,i2,i3,i4,i5,i6 );
01084       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
01085 
01086       return m_ptr_on_device[ m_offset_map(i0,i1,i2,i3,i4,i5,i6) ];
01087     }
01088 
01089   template< typename iType0 , typename iType1 , typename iType2 , typename iType3 ,
01090             typename iType4 , typename iType5 , typename iType6 >
01091   KOKKOS_FORCEINLINE_FUNCTION
01092   typename Impl::ViewEnableArrayOper< return_type ,
01093                                       traits, typename traits::array_layout, 7,
01094                                       iType0, iType1, iType2, iType3 , iType4, iType5, iType6 >::type
01095     at( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ,
01096         const iType4 & i4 , const iType5 & i5 , const iType6 & i6 , const int ) const
01097     {
01098       KOKKOS_ASSERT_SHAPE_BOUNDS_7( m_offset_map, i0,i1,i2,i3,i4,i5,i6 );
01099       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
01100 
01101       return m_ptr_on_device[ m_offset_map(i0,i1,i2,i3,i4,i5,i6) ];
01102     }
01103 
01104   // rank 8:
01105 
01106   template< typename iType0 , typename iType1 , typename iType2 , typename iType3 ,
01107             typename iType4 , typename iType5 , typename iType6 , typename iType7 >
01108   KOKKOS_FORCEINLINE_FUNCTION
01109   typename Impl::ViewEnableArrayOper< return_type ,
01110                                       traits, typename traits::array_layout, 8,
01111                                       iType0, iType1, iType2, iType3 , iType4, iType5, iType6, iType7 >::type
01112     operator() ( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ,
01113                  const iType4 & i4 , const iType5 & i5 , const iType6 & i6 , const iType7 & i7 ) const
01114     {
01115       KOKKOS_ASSERT_SHAPE_BOUNDS_8( m_offset_map, i0,i1,i2,i3,i4,i5,i6,i7 );
01116       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
01117 
01118       return m_ptr_on_device[ m_offset_map(i0,i1,i2,i3,i4,i5,i6,i7) ];
01119     }
01120 
01121   template< typename iType0 , typename iType1 , typename iType2 , typename iType3 ,
01122             typename iType4 , typename iType5 , typename iType6 , typename iType7 >
01123   KOKKOS_FORCEINLINE_FUNCTION
01124   typename Impl::ViewEnableArrayOper< return_type ,
01125                                       traits, typename traits::array_layout, 8,
01126                                       iType0, iType1, iType2, iType3 , iType4, iType5, iType6, iType7 >::type
01127     at( const iType0 & i0 , const iType1 & i1 , const iType2 & i2 , const iType3 & i3 ,
01128         const iType4 & i4 , const iType5 & i5 , const iType6 & i6 , const iType7 & i7 ) const
01129     {
01130       KOKKOS_ASSERT_SHAPE_BOUNDS_8( m_offset_map, i0,i1,i2,i3,i4,i5,i6,i7 );
01131       KOKKOS_RESTRICT_EXECUTION_TO_DATA( typename traits::memory_space , data_handle_type::get_raw_ptr( m_ptr_on_device ) );
01132 
01133       return m_ptr_on_device[ m_offset_map(i0,i1,i2,i3,i4,i5,i6,i7) ];
01134     }
01135 
01136   //------------------------------------
01137   // Access to the underlying contiguous storage of this view specialization.
01138   // These methods are specific to specialization of a view.
01139 
01140   KOKKOS_FORCEINLINE_FUNCTION
01141   typename traits::value_type * ptr_on_device() const {
01142     return data_handle_type::get_raw_ptr(m_ptr_on_device);
01143   }
01144 
01145   // Stride of physical storage, dimensioned to at least Rank
01146   template< typename iType >
01147   KOKKOS_INLINE_FUNCTION
01148   void stride( iType * const s ) const
01149   { m_offset_map.stride(s); }
01150 
01151   // Count of contiguously allocated data members including padding.
01152   KOKKOS_INLINE_FUNCTION
01153   typename traits::size_type capacity() const
01154   { return m_offset_map.capacity(); }
01155 };
01156 
01157 } /* namespace Kokkos */
01158 
01159 //----------------------------------------------------------------------------
01160 //----------------------------------------------------------------------------
01161 
01162 namespace Kokkos {
01163 
01164 template< class LT , class LL , class LD , class LM , class LS ,
01165           class RT , class RL , class RD , class RM , class RS >
01166 KOKKOS_INLINE_FUNCTION
01167 typename Impl::enable_if<( Impl::is_same< LS , RS >::value ), bool >::type
01168 operator == ( const View<LT,LL,LD,LM,LS> & lhs ,
01169               const View<RT,RL,RD,RM,RS> & rhs )
01170 {
01171   // Same data, layout, dimensions
01172   typedef ViewTraits<LT,LL,LD,LM> lhs_traits ;
01173   typedef ViewTraits<RT,RL,RD,RM> rhs_traits ;
01174 
01175   return
01176     Impl::is_same< typename lhs_traits::const_data_type ,
01177                    typename rhs_traits::const_data_type >::value &&
01178     Impl::is_same< typename lhs_traits::array_layout ,
01179                    typename rhs_traits::array_layout >::value &&
01180     Impl::is_same< typename lhs_traits::memory_space ,
01181                    typename rhs_traits::memory_space >::value &&
01182     Impl::is_same< typename lhs_traits::specialize ,
01183                    typename rhs_traits::specialize >::value &&
01184     lhs.ptr_on_device() == rhs.ptr_on_device() &&
01185     lhs.shape()         == rhs.shape() ;
01186 }
01187 
01188 template< class LT , class LL , class LD , class LM , class LS ,
01189           class RT , class RL , class RD , class RM , class RS >
01190 KOKKOS_INLINE_FUNCTION
01191 bool operator != ( const View<LT,LL,LD,LM,LS> & lhs ,
01192                    const View<RT,RL,RD,RM,RS> & rhs )
01193 {
01194   return ! operator==( lhs , rhs );
01195 }
01196 
01197 //----------------------------------------------------------------------------
01198 
01199 
01200 } // namespace Kokkos
01201 
01202 //----------------------------------------------------------------------------
01203 //----------------------------------------------------------------------------
01204 
01205 namespace Kokkos {
01206 
01207 //----------------------------------------------------------------------------
01210 template< class DT , class DL , class DD , class DM , class DS >
01211 inline
01212 void deep_copy( const View<DT,DL,DD,DM,DS> & dst ,
01213                 typename Impl::enable_if<(
01214                   Impl::is_same< typename ViewTraits<DT,DL,DD,DM>::non_const_value_type ,
01215                                  typename ViewTraits<DT,DL,DD,DM>::value_type >::value
01216                 ), typename ViewTraits<DT,DL,DD,DM>::const_value_type >::type & value )
01217 {
01218   Impl::ViewFill< View<DT,DL,DD,DM,DS> >( dst , value );
01219 }
01220 
01221 template< class ST , class SL , class SD , class SM , class SS >
01222 inline
01223 typename Impl::enable_if<( ViewTraits<ST,SL,SD,SM>::rank == 0 )>::type
01224 deep_copy( ST & dst , const View<ST,SL,SD,SM,SS> & src )
01225 {
01226   typedef  ViewTraits<ST,SL,SD,SM>  src_traits ;
01227   typedef typename src_traits::memory_space  src_memory_space ;
01228   Impl::DeepCopy< HostSpace , src_memory_space >( & dst , src.ptr_on_device() , sizeof(ST) );
01229 }
01230 
01231 //----------------------------------------------------------------------------
01234 template< class DT , class DL , class DD , class DM , class DS ,
01235           class ST , class SL , class SD , class SM , class SS >
01236 inline
01237 void deep_copy( const View<DT,DL,DD,DM,DS> & dst ,
01238                 const View<ST,SL,SD,SM,SS> & src ,
01239                 typename Impl::enable_if<(
01240                   // Same type and destination is not constant:
01241                   Impl::is_same< typename View<DT,DL,DD,DM,DS>::value_type ,
01242                                  typename View<ST,SL,SD,SM,SS>::non_const_value_type >::value
01243                   &&
01244                   // Rank zero:
01245                   ( unsigned(View<DT,DL,DD,DM,DS>::rank) == unsigned(0) ) &&
01246                   ( unsigned(View<ST,SL,SD,SM,SS>::rank) == unsigned(0) )
01247                 )>::type * = 0 )
01248 {
01249   typedef  View<DT,DL,DD,DM,DS>  dst_type ;
01250   typedef  View<ST,SL,SD,SM,SS>  src_type ;
01251 
01252   typedef typename dst_type::memory_space  dst_memory_space ;
01253   typedef typename src_type::memory_space  src_memory_space ;
01254   typedef typename src_type::value_type    value_type ;
01255 
01256   if ( dst.ptr_on_device() != src.ptr_on_device() ) {
01257     Impl::DeepCopy< dst_memory_space , src_memory_space >( dst.ptr_on_device() , src.ptr_on_device() , sizeof(value_type) );
01258   }
01259 }
01260 
01261 //----------------------------------------------------------------------------
01265 template< class DT , class DL , class DD , class DM ,
01266           class ST , class SL , class SD , class SM >
01267 inline
01268 void deep_copy( const View<DT,DL,DD,DM,Impl::ViewDefault> & dst ,
01269                 const View<ST,SL,SD,SM,Impl::ViewDefault> & src ,
01270                 typename Impl::enable_if<(
01271                   // Same type and destination is not constant:
01272                   Impl::is_same< typename View<DT,DL,DD,DM,Impl::ViewDefault>::value_type ,
01273                                  typename View<ST,SL,SD,SM,Impl::ViewDefault>::non_const_value_type >::value
01274                   &&
01275                   // Same non-zero rank:
01276                   ( unsigned(View<DT,DL,DD,DM,Impl::ViewDefault>::rank) ==
01277                     unsigned(View<ST,SL,SD,SM,Impl::ViewDefault>::rank) )
01278                   &&
01279                   ( 0 < unsigned(View<DT,DL,DD,DM,Impl::ViewDefault>::rank) )
01280                   &&
01281                   // Same layout:
01282                   Impl::is_same< typename View<DT,DL,DD,DM,Impl::ViewDefault>::array_layout ,
01283                                  typename View<ST,SL,SD,SM,Impl::ViewDefault>::array_layout >::value
01284                 )>::type * = 0 )
01285 {
01286   typedef  View<DT,DL,DD,DM,Impl::ViewDefault>  dst_type ;
01287   typedef  View<ST,SL,SD,SM,Impl::ViewDefault>  src_type ;
01288 
01289   typedef typename dst_type::memory_space  dst_memory_space ;
01290   typedef typename src_type::memory_space  src_memory_space ;
01291 
01292   enum { is_contiguous = // Contiguous (e.g., non-strided, non-tiled) layout
01293            Impl::is_same< typename View<DT,DL,DD,DM,Impl::ViewDefault>::array_layout , LayoutLeft >::value ||
01294            Impl::is_same< typename View<DT,DL,DD,DM,Impl::ViewDefault>::array_layout , LayoutRight >::value };
01295 
01296   if ( dst.ptr_on_device() != src.ptr_on_device() ) {
01297 
01298     // Same shape (dimensions)
01299     Impl::assert_shapes_are_equal( dst.shape() , src.shape() );
01300 
01301     if ( is_contiguous && dst.capacity() == src.capacity() ) {
01302 
01303       // Views span equal length contiguous range.
01304       // Assuming can perform a straight memory copy over this range.
01305 
01306       const size_t nbytes = sizeof(typename dst_type::value_type) * dst.capacity();
01307 
01308       Impl::DeepCopy< dst_memory_space , src_memory_space >( dst.ptr_on_device() , src.ptr_on_device() , nbytes );
01309     }
01310     else {
01311       // Destination view's execution space must be able to directly access source memory space
01312       // in order for the ViewRemap functor run in the destination memory space's execution space.
01313       Kokkos::Impl::VerifyExecutionCanAccessMemorySpace< dst_memory_space , src_memory_space >::verify();
01314 
01315       Impl::ViewRemap< dst_type , src_type >( dst , src );
01316     }
01317   }
01318 }
01319 
01320 
01324 template< class DT , class DL , class DD , class DM , class DS ,
01325           class ST , class SL , class SD , class SM , class SS >
01326 inline
01327 void deep_copy( const View< DT, DL, DD, DM, DS > & dst ,
01328                 const View< ST, SL, SD, SM, SS > & src ,
01329                 const typename Impl::enable_if<(
01330                   // Same type and destination is not constant:
01331                   Impl::is_same< typename View<DT,DL,DD,DM,DS>::value_type ,
01332                                  typename View<DT,DL,DD,DM,DS>::non_const_value_type >::value
01333                   &&
01334                   // Source memory space is accessible to destination memory space
01335                   Impl::VerifyExecutionCanAccessMemorySpace< typename View<DT,DL,DD,DM,DS>::memory_space
01336                                                            , typename View<ST,SL,SD,SM,SS>::memory_space >::value
01337                   &&
01338                   // Same non-zero rank
01339                   ( unsigned( View<DT,DL,DD,DM,DS>::rank ) ==
01340                     unsigned( View<ST,SL,SD,SM,SS>::rank ) )
01341                   &&
01342                   ( 0 < unsigned( View<DT,DL,DD,DM,DS>::rank ) )
01343                   &&
01344                   // Different layout or different specialization:
01345                   ( ( ! Impl::is_same< typename View<DT,DL,DD,DM,DS>::array_layout ,
01346                                        typename View<ST,SL,SD,SM,SS>::array_layout >::value )
01347                     ||
01348                     ( ! Impl::is_same< DS , SS >::value )
01349                   )
01350                 )>::type * = 0 )
01351 {
01352   typedef View< DT, DL, DD, DM, DS > dst_type ;
01353   typedef View< ST, SL, SD, SM, SS > src_type ;
01354 
01355   assert_shapes_equal_dimension( dst.shape() , src.shape() );
01356 
01357   Impl::ViewRemap< dst_type , src_type >( dst , src );
01358 }
01359 
01360 //----------------------------------------------------------------------------
01361 
01362 template< class T , class L , class D , class M , class S >
01363 typename Impl::enable_if<(
01364     View<T,L,D,M,S>::is_managed
01365   ), typename View<T,L,D,M,S>::HostMirror >::type
01366 inline
01367 create_mirror( const View<T,L,D,M,S> & src )
01368 {
01369   typedef View<T,L,D,M,S>                  view_type ;
01370   typedef typename view_type::HostMirror    host_view_type ;
01371   typedef typename view_type::memory_space  memory_space ;
01372 
01373   // 'view' is managed therefore we can allocate a
01374   // compatible host_view through the ordinary constructor.
01375 
01376   std::string label = memory_space::query_label( src.ptr_on_device() );
01377   label.append("_mirror");
01378 
01379   return host_view_type( label ,
01380                          src.dimension_0() ,
01381                          src.dimension_1() ,
01382                          src.dimension_2() ,
01383                          src.dimension_3() ,
01384                          src.dimension_4() ,
01385                          src.dimension_5() ,
01386                          src.dimension_6() ,
01387                          src.dimension_7() );
01388 }
01389 
01390 template< class T , class L , class D , class M , class S >
01391 typename Impl::enable_if<(
01392     View<T,L,D,M,S>::is_managed &&
01393     Impl::ViewAssignable< typename View<T,L,D,M,S>::HostMirror , View<T,L,D,M,S> >::value
01394   ), typename View<T,L,D,M,S>::HostMirror >::type
01395 inline
01396 create_mirror_view( const View<T,L,D,M,S> & src )
01397 {
01398   return src ;
01399 }
01400 
01401 template< class T , class L , class D , class M , class S >
01402 typename Impl::enable_if<(
01403     View<T,L,D,M,S>::is_managed &&
01404     ! Impl::ViewAssignable< typename View<T,L,D,M,S>::HostMirror , View<T,L,D,M,S> >::value
01405   ), typename View<T,L,D,M,S>::HostMirror >::type
01406 inline
01407 create_mirror_view( const View<T,L,D,M,S> & src )
01408 {
01409   return create_mirror( src );
01410 }
01411 
01412 //----------------------------------------------------------------------------
01413 
01415 template< class T , class L , class D , class M , class S >
01416 inline
01417 void resize( View<T,L,D,M,S> & v ,
01418              const typename Impl::enable_if< ViewTraits<T,L,D,M>::is_managed , size_t >::type n0 ,
01419              const size_t n1 = 0 ,
01420              const size_t n2 = 0 ,
01421              const size_t n3 = 0 ,
01422              const size_t n4 = 0 ,
01423              const size_t n5 = 0 ,
01424              const size_t n6 = 0 ,
01425              const size_t n7 = 0 )
01426 {
01427   typedef View<T,L,D,M,S> view_type ;
01428   typedef typename view_type::memory_space memory_space ;
01429 
01430   const std::string label = memory_space::query_label( v.ptr_on_device() );
01431 
01432   view_type v_resized( label, n0, n1, n2, n3, n4, n5, n6, n7 );
01433 
01434   Impl::ViewRemap< view_type , view_type >( v_resized , v );
01435 
01436   v = v_resized ;
01437 }
01438 
01440 template< class T , class L , class D , class M , class S >
01441 inline
01442 void realloc( View<T,L,D,M,S> & v ,
01443               const typename Impl::enable_if< ViewTraits<T,L,D,M>::is_managed , size_t >::type n0 ,
01444               const size_t n1 = 0 ,
01445               const size_t n2 = 0 ,
01446               const size_t n3 = 0 ,
01447               const size_t n4 = 0 ,
01448               const size_t n5 = 0 ,
01449               const size_t n6 = 0 ,
01450               const size_t n7 = 0 )
01451 {
01452   typedef View<T,L,D,M,S> view_type ;
01453   typedef typename view_type::memory_space memory_space ;
01454 
01455   // Query the current label and reuse it.
01456   const std::string label = memory_space::query_label( v.ptr_on_device() );
01457 
01458   v = view_type(); // deallocate first, if the only view to memory.
01459   v = view_type( label, n0, n1, n2, n3, n4, n5, n6, n7 );
01460 }
01461 
01462 } // namespace Kokkos
01463 
01464 //----------------------------------------------------------------------------
01465 //----------------------------------------------------------------------------
01466 
01467 namespace Kokkos {
01468 
01469 struct ALL { KOKKOS_INLINE_FUNCTION ALL(){} };
01470 
01471 template< class DstViewType ,
01472           class T , class L , class D , class M , class S ,
01473           class ArgType0 >
01474 KOKKOS_INLINE_FUNCTION
01475 DstViewType
01476 subview( const View<T,L,D,M,S> & src ,
01477          const ArgType0 & arg0 )
01478 {
01479   DstViewType dst ;
01480 
01481   Impl::ViewAssignment<typename DstViewType::specialize,S>( dst , src , arg0 );
01482 
01483   return dst ;
01484 }
01485 
01486 template< class DstViewType ,
01487           class T , class L , class D , class M , class S ,
01488           class ArgType0 , class ArgType1 >
01489 KOKKOS_INLINE_FUNCTION
01490 DstViewType
01491 subview( const View<T,L,D,M,S> & src ,
01492          const ArgType0 & arg0 ,
01493          const ArgType1 & arg1 )
01494 {
01495   DstViewType dst ;
01496 
01497   Impl::ViewAssignment<typename DstViewType::specialize,S>( dst, src, arg0, arg1 );
01498 
01499   return dst ;
01500 }
01501 
01502 template< class DstViewType ,
01503           class T , class L , class D , class M , class S ,
01504           class ArgType0 , class ArgType1 , class ArgType2 >
01505 KOKKOS_INLINE_FUNCTION
01506 DstViewType
01507 subview( const View<T,L,D,M,S> & src ,
01508          const ArgType0 & arg0 ,
01509          const ArgType1 & arg1 ,
01510          const ArgType2 & arg2 )
01511 {
01512   DstViewType dst ;
01513 
01514   Impl::ViewAssignment<typename DstViewType::specialize,S>( dst, src, arg0, arg1, arg2 );
01515 
01516   return dst ;
01517 }
01518 
01519 template< class DstViewType ,
01520           class T , class L , class D , class M , class S ,
01521           class ArgType0 , class ArgType1 , class ArgType2 , class ArgType3 >
01522 KOKKOS_INLINE_FUNCTION
01523 DstViewType
01524 subview( const View<T,L,D,M,S> & src ,
01525          const ArgType0 & arg0 ,
01526          const ArgType1 & arg1 ,
01527          const ArgType2 & arg2 ,
01528          const ArgType3 & arg3 )
01529 {
01530   DstViewType dst ;
01531 
01532   Impl::ViewAssignment<typename DstViewType::specialize,S>( dst, src, arg0, arg1, arg2, arg3 );
01533 
01534   return dst ;
01535 }
01536 
01537 template< class DstViewType ,
01538           class T , class L , class D , class M , class S ,
01539           class ArgType0 , class ArgType1 , class ArgType2 , class ArgType3 ,
01540           class ArgType4 >
01541 KOKKOS_INLINE_FUNCTION
01542 DstViewType
01543 subview( const View<T,L,D,M,S> & src ,
01544          const ArgType0 & arg0 ,
01545          const ArgType1 & arg1 ,
01546          const ArgType2 & arg2 ,
01547          const ArgType3 & arg3 ,
01548          const ArgType4 & arg4 )
01549 {
01550   DstViewType dst ;
01551 
01552   Impl::ViewAssignment<typename DstViewType::specialize,S>( dst, src, arg0, arg1, arg2, arg3, arg4 );
01553 
01554   return dst ;
01555 }
01556 
01557 template< class DstViewType ,
01558           class T , class L , class D , class M , class S ,
01559           class ArgType0 , class ArgType1 , class ArgType2 , class ArgType3 ,
01560           class ArgType4 , class ArgType5 >
01561 KOKKOS_INLINE_FUNCTION
01562 DstViewType
01563 subview( const View<T,L,D,M,S> & src ,
01564          const ArgType0 & arg0 ,
01565          const ArgType1 & arg1 ,
01566          const ArgType2 & arg2 ,
01567          const ArgType3 & arg3 ,
01568          const ArgType4 & arg4 ,
01569          const ArgType5 & arg5 )
01570 {
01571   DstViewType dst ;
01572 
01573   Impl::ViewAssignment<typename DstViewType::specialize,S>( dst, src, arg0, arg1, arg2, arg3, arg4, arg5 );
01574 
01575   return dst ;
01576 }
01577 
01578 template< class DstViewType ,
01579           class T , class L , class D , class M , class S ,
01580           class ArgType0 , class ArgType1 , class ArgType2 , class ArgType3 ,
01581           class ArgType4 , class ArgType5 , class ArgType6 >
01582 KOKKOS_INLINE_FUNCTION
01583 DstViewType
01584 subview( const View<T,L,D,M,S> & src ,
01585          const ArgType0 & arg0 ,
01586          const ArgType1 & arg1 ,
01587          const ArgType2 & arg2 ,
01588          const ArgType3 & arg3 ,
01589          const ArgType4 & arg4 ,
01590          const ArgType5 & arg5 ,
01591          const ArgType6 & arg6 )
01592 {
01593   DstViewType dst ;
01594 
01595   Impl::ViewAssignment<typename DstViewType::specialize,S>( dst, src, arg0, arg1, arg2, arg3, arg4, arg5, arg6 );
01596 
01597   return dst ;
01598 }
01599 
01600 template< class DstViewType ,
01601           class T , class L , class D , class M , class S ,
01602           class ArgType0 , class ArgType1 , class ArgType2 , class ArgType3 ,
01603           class ArgType4 , class ArgType5 , class ArgType6 , class ArgType7 >
01604 KOKKOS_INLINE_FUNCTION
01605 DstViewType
01606 subview( const View<T,L,D,M,S> & src ,
01607          const ArgType0 & arg0 ,
01608          const ArgType1 & arg1 ,
01609          const ArgType2 & arg2 ,
01610          const ArgType3 & arg3 ,
01611          const ArgType4 & arg4 ,
01612          const ArgType5 & arg5 ,
01613          const ArgType6 & arg6 ,
01614          const ArgType7 & arg7 )
01615 {
01616   DstViewType dst ;
01617 
01618   Impl::ViewAssignment<typename DstViewType::specialize,S>( dst, src, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 );
01619 
01620   return dst ;
01621 }
01622 
01623 } // namespace Kokkos
01624 
01625 //----------------------------------------------------------------------------
01626 //----------------------------------------------------------------------------
01627 
01628 #include <impl/Kokkos_ViewDefault.hpp>
01629 #include <impl/Kokkos_Atomic_View.hpp>
01630 
01631 //----------------------------------------------------------------------------
01632 //----------------------------------------------------------------------------
01633 
01634 #endif
01635 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends