Kokkos Core Kernels Package  Version of the Day
Kokkos_HostSpace.hpp
1 /*
2 //@HEADER
3 // ************************************************************************
4 //
5 // Kokkos v. 2.0
6 // Copyright (2014) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
39 //
40 // ************************************************************************
41 //@HEADER
42 */
43 
44 #ifndef KOKKOS_HOSTSPACE_HPP
45 #define KOKKOS_HOSTSPACE_HPP
46 
47 #include <cstring>
48 #include <string>
49 #include <iosfwd>
50 #include <typeinfo>
51 
52 #include <Kokkos_Core_fwd.hpp>
53 #include <Kokkos_Concepts.hpp>
54 #include <Kokkos_MemoryTraits.hpp>
55 
56 #include <impl/Kokkos_Traits.hpp>
57 #include <impl/Kokkos_Error.hpp>
58 #include <impl/Kokkos_SharedAlloc.hpp>
59 
60 /*--------------------------------------------------------------------------*/
61 
62 namespace Kokkos {
63 namespace Impl {
64 
71 void init_lock_array_host_space();
72 
78 bool lock_address_host_space(void* ptr);
79 
86 void unlock_address_host_space(void* ptr);
87 
88 } // namespace Impl
89 } // namespace Kokkos
90 
91 namespace Kokkos {
92 
98 class HostSpace {
99 public:
100 
103  typedef size_t size_type ;
104 
111 #if defined( KOKKOS_HAVE_DEFAULT_DEVICE_TYPE_OPENMP )
112  typedef Kokkos::OpenMP execution_space ;
113 #elif defined( KOKKOS_HAVE_DEFAULT_DEVICE_TYPE_THREADS )
114  typedef Kokkos::Threads execution_space ;
115 #elif defined( KOKKOS_HAVE_OPENMP )
116  typedef Kokkos::OpenMP execution_space ;
117 #elif defined( KOKKOS_HAVE_PTHREAD )
118  typedef Kokkos::Threads execution_space ;
119 #elif defined( KOKKOS_HAVE_SERIAL )
120  typedef Kokkos::Serial execution_space ;
121 #else
122 # error "At least one of the following host execution spaces must be defined: Kokkos::OpenMP, Kokkos::Serial, or Kokkos::Threads. You might be seeing this message if you disabled the Kokkos::Serial device explicitly using the Kokkos_ENABLE_Serial:BOOL=OFF CMake option, but did not enable any of the other host execution space devices."
123 #endif
124 
127 
128  /*--------------------------------*/
129  /* Functions unique to the HostSpace */
130  static int in_parallel();
131 
132  static void register_in_parallel( int (*)() );
133 
134  /*--------------------------------*/
135 
137  HostSpace();
138  HostSpace( HostSpace && rhs ) = default ;
139  HostSpace( const HostSpace & rhs ) = default ;
140  HostSpace & operator = ( HostSpace && ) = default ;
141  HostSpace & operator = ( const HostSpace & ) = default ;
142  ~HostSpace() = default ;
143 
146  enum AllocationMechanism { STD_MALLOC , POSIX_MEMALIGN , POSIX_MMAP , INTEL_MM_ALLOC };
147 
148  explicit
149  HostSpace( const AllocationMechanism & );
150 
152  void * allocate( const size_t arg_alloc_size ) const ;
153 
155  void deallocate( void * const arg_alloc_ptr
156  , const size_t arg_alloc_size ) const ;
157 
158 private:
159 
160  AllocationMechanism m_alloc_mech ;
161 
162  friend class Kokkos::Impl::SharedAllocationRecord< Kokkos::HostSpace , void > ;
163 };
164 
165 } // namespace Kokkos
166 
167 //----------------------------------------------------------------------------
168 //----------------------------------------------------------------------------
169 
170 namespace Kokkos {
171 namespace Impl {
172 
174 
175 
176 template< typename S >
177 struct HostMirror {
178 private:
179 
180  // If input execution space can access HostSpace then keep it.
181  // Example: Kokkos::OpenMP can access, Kokkos::Cuda cannot
182  enum { keep_exe = Kokkos::Impl::MemorySpaceAccess
183  < typename S::execution_space::memory_space , Kokkos::HostSpace >
184  ::accessible };
185 
186  // If HostSpace can access memory space then keep it.
187  // Example: Cannot access Kokkos::CudaSpace, can access Kokkos::CudaUVMSpace
188  enum { keep_mem = Kokkos::Impl::MemorySpaceAccess
189  < Kokkos::HostSpace , typename S::memory_space >::accessible };
190 
191 public:
192 
193  typedef typename std::conditional
194  < keep_exe && keep_mem /* Can keep whole space */
195  , S
196  , typename std::conditional
197  < keep_mem /* Can keep memory space, use default Host execution space */
198  , Kokkos::Device< Kokkos::HostSpace::execution_space
199  , typename S::memory_space >
201  >::type
202  >::type Space ;
203 };
204 
205 } // namespace Impl
206 } // namespace Kokkos
207 
208 //----------------------------------------------------------------------------
209 //----------------------------------------------------------------------------
210 
211 namespace Kokkos {
212 namespace Impl {
213 
214 template<>
215 class SharedAllocationRecord< Kokkos::HostSpace , void >
216  : public SharedAllocationRecord< void , void >
217 {
218 private:
219 
220  friend Kokkos::HostSpace ;
221 
222  typedef SharedAllocationRecord< void , void > RecordBase ;
223 
224  SharedAllocationRecord( const SharedAllocationRecord & ) = delete ;
225  SharedAllocationRecord & operator = ( const SharedAllocationRecord & ) = delete ;
226 
227  static void deallocate( RecordBase * );
228 
230  static RecordBase s_root_record ;
231 
232  const Kokkos::HostSpace m_space ;
233 
234 protected:
235 
236  ~SharedAllocationRecord();
237  SharedAllocationRecord() = default ;
238 
239  SharedAllocationRecord( const Kokkos::HostSpace & arg_space
240  , const std::string & arg_label
241  , const size_t arg_alloc_size
242  , const RecordBase::function_type arg_dealloc = & deallocate
243  );
244 
245 public:
246 
247  inline
248  std::string get_label() const
249  {
250  return std::string( RecordBase::head()->m_label );
251  }
252 
253  KOKKOS_INLINE_FUNCTION static
254  SharedAllocationRecord * allocate( const Kokkos::HostSpace & arg_space
255  , const std::string & arg_label
256  , const size_t arg_alloc_size
257  )
258  {
259 #if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST )
260  return new SharedAllocationRecord( arg_space , arg_label , arg_alloc_size );
261 #else
262  return (SharedAllocationRecord *) 0 ;
263 #endif
264  }
265 
267  static
268  void * allocate_tracked( const Kokkos::HostSpace & arg_space
269  , const std::string & arg_label
270  , const size_t arg_alloc_size );
271 
273  static
274  void * reallocate_tracked( void * const arg_alloc_ptr
275  , const size_t arg_alloc_size );
276 
278  static
279  void deallocate_tracked( void * const arg_alloc_ptr );
280 
281 
282  static SharedAllocationRecord * get_record( void * arg_alloc_ptr );
283 
284  static void print_records( std::ostream & , const Kokkos::HostSpace & , bool detail = false );
285 };
286 
287 } // namespace Impl
288 } // namespace Kokkos
289 
290 //----------------------------------------------------------------------------
291 //----------------------------------------------------------------------------
292 
293 namespace Kokkos {
294 namespace Impl {
295 
296 template< class DstSpace, class SrcSpace, class ExecutionSpace = typename DstSpace::execution_space> struct DeepCopy ;
297 
298 template<class ExecutionSpace>
299 struct DeepCopy<HostSpace,HostSpace,ExecutionSpace> {
300  DeepCopy( void * dst , const void * src , size_t n ) {
301  memcpy( dst , src , n );
302  }
303  DeepCopy( const ExecutionSpace& exec, void * dst , const void * src , size_t n ) {
304  exec.fence();
305  memcpy( dst , src , n );
306  }
307 };
308 
309 } // namespace Impl
310 } // namespace Kokkos
311 
312 
313 #endif /* #define KOKKOS_HOSTSPACE_HPP */
314 
AllocationMechanism
Non-default memory space instance to choose allocation mechansim, if available.
void * allocate(const size_t arg_alloc_size) const
Allocate untracked memory in the space.
Memory space for main process and CPU execution spaces.
Memory management for host memory.
Kokkos::Device< execution_space, memory_space > device_type
This memory space preferred device_type.
HostSpace()
Default memory space instance.
HostSpace memory_space
Tag this class as a kokkos memory space.
void deallocate(void *const arg_alloc_ptr, const size_t arg_alloc_size) const
Deallocate untracked memory in the space.
Access relationship between DstMemorySpace and SrcMemorySpace.