Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends
Kokkos_CudaSpace.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_CUDASPACE_HPP
00045 #define KOKKOS_CUDASPACE_HPP
00046 
00047 #if defined( KOKKOS_HAVE_CUDA )
00048 
00049 #include <iosfwd>
00050 #include <typeinfo>
00051 #include <string>
00052 
00053 #include <Kokkos_Core_fwd.hpp>
00054 #include <Kokkos_HostSpace.hpp>
00055 #include <Cuda/Kokkos_Cuda_abort.hpp>
00056 
00057 /*--------------------------------------------------------------------------*/
00058 
00059 namespace Kokkos {
00060 
00063 class CudaSpace {
00064 public:
00065 
00066   typedef Impl::MemorySpaceTag  kokkos_tag ;
00067   typedef CudaSpace             memory_space ;
00068   typedef unsigned int          size_type ;
00069   typedef Kokkos::Cuda          execution_space ;
00070 
00080   static void * allocate( const std::string    & label ,
00081                           const std::type_info & scalar_type ,
00082                           const size_t           scalar_size ,
00083                           const size_t           scalar_count );
00084 
00090   static void increment( const void * );
00091 
00098   static void decrement( const void * );
00099 
00106   static int count( const void * );
00107 
00109   static void print_memory_view( std::ostream & );
00110 
00112   static std::string query_label( const void * );
00113 
00114   /*--------------------------------*/
00118 #if defined( __CUDACC__ )
00119   static void texture_object_attach( const void            * const arg_ptr
00120                                    , ::cudaChannelFormatDesc const & arg_desc
00121                                    , ::cudaTextureObject_t * const arg_tex_obj
00122                                    , void const           ** const arg_alloc_ptr
00123                                    , int                   * const arg_offset
00124                                    );
00125 #endif
00126 
00127   /*--------------------------------*/
00129   static void access_error();
00130   static void access_error( const void * const );
00131 };
00132 
00133 } // namespace Kokkos
00134 
00135 /*--------------------------------------------------------------------------*/
00136 /*--------------------------------------------------------------------------*/
00137 
00138 namespace Kokkos {
00139 
00143 class CudaUVMSpace {
00144 public:
00145 
00146   typedef Impl::MemorySpaceTag  kokkos_tag ;
00147   typedef CudaUVMSpace          memory_space ;
00148   typedef unsigned int          size_type ;
00149   typedef Cuda                  execution_space ;
00150 
00160   static void * allocate( const std::string    & label ,
00161                           const std::type_info & scalar_type ,
00162                           const size_t           scalar_size ,
00163                           const size_t           scalar_count );
00164 
00170   static void increment( const void * );
00171 
00178   static void decrement( const void * );
00179 
00186   static int count( const void * );
00187 
00189   static void print_memory_view( std::ostream & );
00190 
00192   static std::string query_label( const void * );
00193 
00197 #if defined( __CUDACC__ )
00198   static void texture_object_attach( const void            * const arg_ptr
00199                                    , ::cudaChannelFormatDesc const & arg_desc
00200                                    , ::cudaTextureObject_t * const arg_tex_obj
00201                                    , void const           ** const arg_alloc_ptr
00202                                    , int                   * const arg_offset
00203                                    );
00204 #endif
00205 };
00206 
00207 } // namespace Kokkos
00208 
00209 /*--------------------------------------------------------------------------*/
00210 /*--------------------------------------------------------------------------*/
00211 
00212 namespace Kokkos {
00213 
00217 class CudaHostPinnedSpace {
00218 public:
00219 
00220   typedef Impl::MemorySpaceTag        kokkos_tag ;
00221   typedef CudaHostPinnedSpace         memory_space ;
00222   typedef unsigned int                size_type ;
00223 
00225   typedef HostSpace::execution_space  execution_space ;
00226 
00236   static void * allocate( const std::string    & label ,
00237                           const std::type_info & scalar_type ,
00238                           const size_t           scalar_size ,
00239                           const size_t           scalar_count );
00240 
00246   static void increment( const void * );
00247 
00254   static int count( const void * );
00255 
00262   static void decrement( const void * );
00263 
00265   static void print_memory_view( std::ostream & );
00266 
00268   static std::string query_label( const void * );
00269 };
00270 
00271 } // namespace Kokkos
00272 
00273 /*--------------------------------------------------------------------------*/
00274 /*--------------------------------------------------------------------------*/
00275 
00276 namespace Kokkos {
00277 namespace Impl {
00278 
00279 template<> struct DeepCopy< CudaSpace , CudaSpace > { DeepCopy( void * dst , const void * src , size_t ); };
00280 template<> struct DeepCopy< CudaSpace , HostSpace > { DeepCopy( void * dst , const void * src , size_t ); };
00281 template<> struct DeepCopy< HostSpace , CudaSpace > { DeepCopy( void * dst , const void * src , size_t ); };
00282 
00283 template<> struct DeepCopy< CudaSpace , CudaUVMSpace >
00284 {
00285   inline
00286   DeepCopy( void * dst , const void * src , size_t n )
00287   { (void) DeepCopy< CudaSpace , CudaSpace >( dst , src , n ); }
00288 };
00289 
00290 template<> struct DeepCopy< CudaSpace , CudaHostPinnedSpace >
00291 {
00292   inline
00293   DeepCopy( void * dst , const void * src , size_t n )
00294   { (void) DeepCopy< CudaSpace , HostSpace >( dst , src , n ); }
00295 };
00296 
00297 
00298 template<> struct DeepCopy< CudaUVMSpace , CudaSpace >
00299 {
00300   inline
00301   DeepCopy( void * dst , const void * src , size_t n )
00302   { (void) DeepCopy< CudaSpace , CudaSpace >( dst , src , n ); }
00303 };
00304 
00305 template<> struct DeepCopy< CudaUVMSpace , CudaUVMSpace >
00306 {
00307   inline
00308   DeepCopy( void * dst , const void * src , size_t n )
00309   { (void) DeepCopy< CudaSpace , CudaSpace >( dst , src , n ); }
00310 };
00311 
00312 template<> struct DeepCopy< CudaUVMSpace , CudaHostPinnedSpace >
00313 {
00314   inline
00315   DeepCopy( void * dst , const void * src , size_t n )
00316   { (void) DeepCopy< CudaSpace , HostSpace >( dst , src , n ); }
00317 };
00318 
00319 template<> struct DeepCopy< CudaUVMSpace , HostSpace >
00320 {
00321   inline
00322   DeepCopy( void * dst , const void * src , size_t n )
00323   { (void) DeepCopy< CudaSpace , HostSpace >( dst , src , n ); }
00324 };
00325 
00326 
00327 template<> struct DeepCopy< CudaHostPinnedSpace , CudaSpace >
00328 {
00329   inline
00330   DeepCopy( void * dst , const void * src , size_t n )
00331   { (void) DeepCopy< HostSpace , CudaSpace >( dst , src , n ); }
00332 };
00333 
00334 template<> struct DeepCopy< CudaHostPinnedSpace , CudaUVMSpace >
00335 {
00336   inline
00337   DeepCopy( void * dst , const void * src , size_t n )
00338   { (void) DeepCopy< HostSpace , CudaSpace >( dst , src , n ); }
00339 };
00340 
00341 template<> struct DeepCopy< CudaHostPinnedSpace , CudaHostPinnedSpace >
00342 {
00343   inline
00344   DeepCopy( void * dst , const void * src , size_t n )
00345   { (void) DeepCopy< HostSpace , HostSpace >( dst , src , n ); }
00346 };
00347 
00348 template<> struct DeepCopy< CudaHostPinnedSpace , HostSpace >
00349 {
00350   inline
00351   DeepCopy( void * dst , const void * src , size_t n )
00352   { (void) DeepCopy< HostSpace , HostSpace >( dst , src , n ); }
00353 };
00354 
00355 
00356 template<> struct DeepCopy< HostSpace , CudaUVMSpace >
00357 {
00358   inline
00359   DeepCopy( void * dst , const void * src , size_t n )
00360   { (void) DeepCopy< HostSpace , CudaSpace >( dst , src , n ); }
00361 };
00362 
00363 template<> struct DeepCopy< HostSpace , CudaHostPinnedSpace >
00364 {
00365   inline
00366   DeepCopy( void * dst , const void * src , size_t n )
00367   { (void) DeepCopy< HostSpace , HostSpace >( dst , src , n ); }
00368 };
00369 
00370 } // namespace Impl
00371 } // namespace Kokkos
00372 
00373 //----------------------------------------------------------------------------
00374 //----------------------------------------------------------------------------
00375 
00376 namespace Kokkos {
00377 namespace Impl {
00378 
00380 template<>
00381 struct VerifyExecutionCanAccessMemorySpace< Kokkos::CudaSpace , Kokkos::HostSpace >
00382 {
00383   enum {value = 0};
00384   KOKKOS_INLINE_FUNCTION static void verify( void )
00385     { Kokkos::cuda_abort("Cuda code attempted to access HostSpace memory"); }
00386 
00387   KOKKOS_INLINE_FUNCTION static void verify( const void * )
00388     { Kokkos::cuda_abort("Cuda code attempted to access HostSpace memory"); }
00389 };
00390 
00392 template<>
00393 struct VerifyExecutionCanAccessMemorySpace< Kokkos::CudaSpace , Kokkos::CudaUVMSpace >
00394 {
00395   enum {value = 1};
00396   inline static void verify( void ) { }
00397   inline static void verify( const void * ) { }
00398 };
00399 
00401 template<>
00402 struct VerifyExecutionCanAccessMemorySpace< Kokkos::CudaSpace , Kokkos::CudaHostPinnedSpace >
00403 {
00404   enum {value = 1};
00405   inline static void verify( void ) { }
00406   inline static void verify( const void * ) { }
00407 };
00408 
00410 template< class OtherSpace >
00411 struct VerifyExecutionCanAccessMemorySpace<
00412   typename enable_if< ! is_same<Kokkos::CudaSpace,OtherSpace>::value , Kokkos::CudaSpace >::type ,
00413   OtherSpace >
00414 {
00415   enum {value = 0};
00416   KOKKOS_INLINE_FUNCTION static void verify( void )
00417     { Kokkos::cuda_abort("Cuda code attempted to access unknown Space memory"); }
00418 
00419   KOKKOS_INLINE_FUNCTION static void verify( const void * )
00420     { Kokkos::cuda_abort("Cuda code attempted to access unknown Space memory"); }
00421 };
00422 
00423 //----------------------------------------------------------------------------
00425 template<>
00426 struct VerifyExecutionCanAccessMemorySpace< Kokkos::HostSpace , Kokkos::CudaSpace >
00427 {
00428 #if defined( KOKKOS_USE_CUDA_UVM )
00429   enum {value = 1};
00430   inline static void verify( void ) { }
00431   inline static void verify( const void * ) { }
00432 #else
00433   enum {value = 0};
00434   inline static void verify( void ) { CudaSpace::access_error(); }
00435   inline static void verify( const void * p ) { CudaSpace::access_error(p); }
00436 #endif
00437 };
00438 
00440 template<>
00441 struct VerifyExecutionCanAccessMemorySpace< Kokkos::HostSpace , Kokkos::CudaUVMSpace >
00442 {
00443   enum {value = 1};
00444   inline static void verify( void ) { }
00445   inline static void verify( const void * ) { }
00446 };
00447 
00449 template<>
00450 struct VerifyExecutionCanAccessMemorySpace< Kokkos::HostSpace , Kokkos::CudaHostPinnedSpace >
00451 {
00452   enum {value = 1};
00453   KOKKOS_INLINE_FUNCTION static void verify( void ) {}
00454   KOKKOS_INLINE_FUNCTION static void verify( const void * ) {}
00455 };
00456 
00457 //----------------------------------------------------------------------------
00458 
00459 } // namespace Impl
00460 } // namespace Kokkos
00461 
00462 //----------------------------------------------------------------------------
00463 //----------------------------------------------------------------------------
00464 
00465 #endif /* #if defined( KOKKOS_HAVE_CUDA ) */
00466 #endif /* #define KOKKOS_CUDASPACE_HPP */
00467 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends