Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Kokkos_HostSpace.hpp
1 /*
2 //@HEADER
3 // ************************************************************************
4 //
5 // Kokkos v. 3.0
6 // Copyright (2020) National Technology & Engineering
7 // Solutions of Sandia, LLC (NTESS).
8 //
9 // Under the terms of Contract DE-NA0003525 with NTESS,
10 // the U.S. Government retains certain rights in this software.
11 //
12 // Redistribution and use in source and binary forms, with or without
13 // modification, are permitted provided that the following conditions are
14 // met:
15 //
16 // 1. Redistributions of source code must retain the above copyright
17 // notice, this list of conditions and the following disclaimer.
18 //
19 // 2. Redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution.
22 //
23 // 3. Neither the name of the Corporation nor the names of the
24 // contributors may be used to endorse or promote products derived from
25 // this software without specific prior written permission.
26 //
27 // THIS SOFTWARE IS PROVIDED BY NTESS "AS IS" AND ANY
28 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NTESS OR THE
31 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 //
39 // Questions? Contact Christian R. Trott (crtrott@sandia.gov)
40 //
41 // ************************************************************************
42 //@HEADER
43 */
44 
45 #ifndef KOKKOS_HOSTSPACE_HPP
46 #define KOKKOS_HOSTSPACE_HPP
47 
48 #include <cstring>
49 #include <string>
50 #include <iosfwd>
51 #include <typeinfo>
52 
53 #include <Kokkos_Core_fwd.hpp>
54 #include <Kokkos_Concepts.hpp>
55 #include <Kokkos_MemoryTraits.hpp>
56 
57 #include <impl/Kokkos_Traits.hpp>
58 #include <impl/Kokkos_Error.hpp>
59 #include <impl/Kokkos_SharedAlloc.hpp>
60 
61 #include "impl/Kokkos_HostSpace_deepcopy.hpp"
62 
63 /*--------------------------------------------------------------------------*/
64 
65 namespace Kokkos {
66 
67 namespace Impl {
68 
75 void init_lock_array_host_space();
76 
82 bool lock_address_host_space(void* ptr);
83 
90 void unlock_address_host_space(void* ptr);
91 
92 } // namespace Impl
93 
94 } // namespace Kokkos
95 
96 namespace Kokkos {
97 
103 class HostSpace {
104  public:
107  typedef size_t size_type;
108 
115 #if defined(KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_OPENMP)
116  typedef Kokkos::OpenMP execution_space;
117 #elif defined(KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_THREADS)
118  typedef Kokkos::Threads execution_space;
119 #elif defined(KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_HPX)
120  typedef Kokkos::Experimental::HPX execution_space;
121 #elif defined(KOKKOS_ENABLE_OPENMP)
122  typedef Kokkos::OpenMP execution_space;
123 #elif defined(KOKKOS_ENABLE_THREADS)
124  typedef Kokkos::Threads execution_space;
125 #elif defined(KOKKOS_ENABLE_HPX)
126  typedef Kokkos::Experimental::HPX execution_space;
127 #elif defined(KOKKOS_ENABLE_SERIAL)
128  typedef Kokkos::Serial execution_space;
129 #else
130 #error \
131  "At least one of the following host execution spaces must be defined: Kokkos::OpenMP, Kokkos::Threads, or Kokkos::Serial. 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."
132 #endif
133 
135  typedef Kokkos::Device<execution_space, memory_space> device_type;
136 
138  HostSpace();
139  HostSpace(HostSpace&& rhs) = default;
140  HostSpace(const HostSpace& rhs) = default;
141  HostSpace& operator=(HostSpace&&) = default;
142  HostSpace& operator=(const HostSpace&) = default;
143  ~HostSpace() = default;
144 
149  STD_MALLOC,
150  POSIX_MEMALIGN,
151  POSIX_MMAP,
152  INTEL_MM_ALLOC
153  };
154 
155  explicit HostSpace(const AllocationMechanism&);
156 
158  void* allocate(const size_t arg_alloc_size) const;
159 
161  void deallocate(void* const arg_alloc_ptr, const size_t arg_alloc_size) const;
162 
164  static constexpr const char* name() { return m_name; }
165 
166  private:
167  AllocationMechanism m_alloc_mech;
168  static constexpr const char* m_name = "Host";
169  friend class Kokkos::Impl::SharedAllocationRecord<Kokkos::HostSpace, void>;
170 };
171 
172 } // namespace Kokkos
173 
174 //----------------------------------------------------------------------------
175 
176 namespace Kokkos {
177 
178 namespace Impl {
179 
181  Kokkos::HostSpace>::assignable,
182  "");
183 
184 template <typename S>
185 struct HostMirror {
186  private:
187  // If input execution space can access HostSpace then keep it.
188  // Example: Kokkos::OpenMP can access, Kokkos::Cuda cannot
189  enum {
191  typename S::execution_space::memory_space,
192  Kokkos::HostSpace>::accessible
193  };
194 
195  // If HostSpace can access memory space then keep it.
196  // Example: Cannot access Kokkos::CudaSpace, can access Kokkos::CudaUVMSpace
197  enum {
198  keep_mem =
200  typename S::memory_space>::accessible
201  };
202 
203  public:
204  typedef typename std::conditional<
205  keep_exe && keep_mem /* Can keep whole space */
206  ,
207  S,
208  typename std::conditional<
209  keep_mem /* Can keep memory space, use default Host execution space */
210  ,
211  Kokkos::Device<Kokkos::HostSpace::execution_space,
212  typename S::memory_space>,
213  Kokkos::HostSpace>::type>::type Space;
214 };
215 
216 } // namespace Impl
217 
218 } // namespace Kokkos
219 
220 //----------------------------------------------------------------------------
221 
222 namespace Kokkos {
223 
224 namespace Impl {
225 
226 template <>
227 class SharedAllocationRecord<Kokkos::HostSpace, void>
228  : public SharedAllocationRecord<void, void> {
229  private:
230  friend Kokkos::HostSpace;
231 
232  typedef SharedAllocationRecord<void, void> RecordBase;
233 
234  SharedAllocationRecord(const SharedAllocationRecord&) = delete;
235  SharedAllocationRecord& operator=(const SharedAllocationRecord&) = delete;
236 
237  static void deallocate(RecordBase*);
238 
239 #ifdef KOKKOS_DEBUG
240 
241  static RecordBase s_root_record;
242 #endif
243 
244  const Kokkos::HostSpace m_space;
245 
246  protected:
247  ~SharedAllocationRecord()
248 #if defined( \
249  KOKKOS_IMPL_INTEL_WORKAROUND_NOEXCEPT_SPECIFICATION_VIRTUAL_FUNCTION)
250  noexcept
251 #endif
252  ;
253  SharedAllocationRecord() = default;
254 
255  SharedAllocationRecord(
256  const Kokkos::HostSpace& arg_space, const std::string& arg_label,
257  const size_t arg_alloc_size,
258  const RecordBase::function_type arg_dealloc = &deallocate);
259 
260  public:
261  inline std::string get_label() const {
262  return std::string(RecordBase::head()->m_label);
263  }
264 
265  KOKKOS_INLINE_FUNCTION static SharedAllocationRecord* allocate(
266  const Kokkos::HostSpace& arg_space, const std::string& arg_label,
267  const size_t arg_alloc_size) {
268 #if defined(KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST)
269  return new SharedAllocationRecord(arg_space, arg_label, arg_alloc_size);
270 #else
271  (void)arg_space;
272  (void)arg_label;
273  (void)arg_alloc_size;
274  return (SharedAllocationRecord*)0;
275 #endif
276  }
277 
279  static void* allocate_tracked(const Kokkos::HostSpace& arg_space,
280  const std::string& arg_label,
281  const size_t arg_alloc_size);
282 
284  static void* reallocate_tracked(void* const arg_alloc_ptr,
285  const size_t arg_alloc_size);
286 
288  static void deallocate_tracked(void* const arg_alloc_ptr);
289 
290  static SharedAllocationRecord* get_record(void* arg_alloc_ptr);
291 
292  static void print_records(std::ostream&, const Kokkos::HostSpace&,
293  bool detail = false);
294 };
295 
296 } // namespace Impl
297 
298 } // namespace Kokkos
299 
300 //----------------------------------------------------------------------------
301 
302 namespace Kokkos {
303 
304 namespace Impl {
305 
306 template <class ExecutionSpace>
307 struct DeepCopy<HostSpace, HostSpace, ExecutionSpace> {
308  DeepCopy(void* dst, const void* src, size_t n) {
309  hostspace_parallel_deepcopy(dst, src, n);
310  }
311 
312  DeepCopy(const ExecutionSpace& exec, void* dst, const void* src, size_t n) {
313  exec.fence();
314  hostspace_parallel_deepcopy(dst, src, n);
315  exec.fence();
316  }
317 };
318 
319 } // namespace Impl
320 
321 } // namespace Kokkos
322 
323 #endif // #define KOKKOS_HOSTSPACE_HPP
void * allocate(const size_t arg_alloc_size) const
Allocate untracked memory in the space.
Kokkos::Device< execution_space, memory_space > device_type
This memory space preferred device_type.
AllocationMechanism
Non-default memory space instance to choose allocation mechansim, if available.
void deallocate(void *const arg_alloc_ptr, const size_t arg_alloc_size) const
Deallocate untracked memory in the space.
Memory management for host memory.
static constexpr const char * name()
Return Name of the MemorySpace.
HostSpace()
Default memory space instance.
HostSpace memory_space
Tag this class as a kokkos memory space.
Access relationship between DstMemorySpace and SrcMemorySpace.