Kokkos Core Kernels Package  Version of the Day
Kokkos_HBWSpace.hpp
1 //@HEADER
2 // ************************************************************************
3 //
4 // Kokkos v. 4.0
5 // Copyright (2022) National Technology & Engineering
6 // Solutions of Sandia, LLC (NTESS).
7 //
8 // Under the terms of Contract DE-NA0003525 with NTESS,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions.
12 // See https://kokkos.org/LICENSE for license information.
13 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 //
15 //@HEADER
16 
17 #ifndef KOKKOS_IMPL_PUBLIC_INCLUDE
18 #include <Kokkos_Macros.hpp>
19 static_assert(false,
20  "Including non-public Kokkos header files is not allowed.");
21 #endif
22 #ifndef KOKKOS_HBWSPACE_HPP
23 #define KOKKOS_HBWSPACE_HPP
24 
25 #include <Kokkos_Macros.hpp>
26 #ifdef KOKKOS_ENABLE_HBWSPACE
27 
28 #include <Kokkos_HostSpace.hpp>
29 
30 namespace Kokkos {
31 
32 namespace Experimental {
33 
34 namespace Impl {
35 
42 void init_lock_array_hbw_space();
43 
49 bool lock_address_hbw_space(void* ptr);
50 
57 void unlock_address_hbw_space(void* ptr);
58 
59 } // namespace Impl
60 
61 } // namespace Experimental
62 
63 } // namespace Kokkos
64 
65 namespace Kokkos {
66 
67 namespace Experimental {
68 
74 class HBWSpace {
75  public:
77  using memory_space = HBWSpace;
78  using size_type = size_t;
79 
86  using execution_space = Kokkos::DefaultHostExecutionSpace;
87 
89  using device_type = Kokkos::Device<execution_space, memory_space>;
90 
92  HBWSpace();
93  HBWSpace(const HBWSpace& rhs) = default;
94  HBWSpace& operator=(const HBWSpace&) = default;
95  ~HBWSpace() = default;
96 
100  enum AllocationMechanism {
101  STD_MALLOC,
102  POSIX_MEMALIGN,
103  POSIX_MMAP,
104  INTEL_MM_ALLOC
105  };
106 
107  explicit HBWSpace(const AllocationMechanism&);
108 
110  void* allocate(const size_t arg_alloc_size) const;
111  void* allocate(const char* arg_label, const size_t arg_alloc_size,
112  const size_t arg_logical_size = 0) const;
113 
115  void deallocate(void* const arg_alloc_ptr, const size_t arg_alloc_size) const;
116  void deallocate(const char* arg_label, void* const arg_alloc_ptr,
117  const size_t arg_alloc_size,
118  const size_t arg_logical_size = 0) const;
119 
120  private:
121  template <class, class, class, class>
122  friend class LogicalMemorySpace;
123 
124  void* impl_allocate(const char* arg_label, const size_t arg_alloc_size,
125  const size_t arg_logical_size = 0,
126  const Kokkos::Tools::SpaceHandle =
127  Kokkos::Tools::make_space_handle(name())) const;
128  void impl_deallocate(const char* arg_label, void* const arg_alloc_ptr,
129  const size_t arg_alloc_size,
130  const size_t arg_logical_size = 0,
131  const Kokkos::Tools::SpaceHandle =
132  Kokkos::Tools::make_space_handle(name())) const;
133 
134  public:
136  static constexpr const char* name() { return "HBW"; }
137 
138  private:
139  AllocationMechanism m_alloc_mech;
140  friend class Kokkos::Impl::SharedAllocationRecord<
141  Kokkos::Experimental::HBWSpace, void>;
142 };
143 
144 } // namespace Experimental
145 
146 } // namespace Kokkos
147 
148 //----------------------------------------------------------------------------
149 
150 namespace Kokkos {
151 
152 namespace Impl {
153 
154 template <>
155 class SharedAllocationRecord<Kokkos::Experimental::HBWSpace, void>
156  : public SharedAllocationRecord<void, void> {
157  private:
158  friend Kokkos::Experimental::HBWSpace;
159 
160  using RecordBase = SharedAllocationRecord<void, void>;
161 
162  SharedAllocationRecord(const SharedAllocationRecord&) = delete;
163  SharedAllocationRecord& operator=(const SharedAllocationRecord&) = delete;
164 
165  static void deallocate(RecordBase*);
166 
167 #ifdef KOKKOS_ENABLE_DEBUG
168 
169  static RecordBase s_root_record;
170 #endif
171 
172  const Kokkos::Experimental::HBWSpace m_space;
173 
174  protected:
175  ~SharedAllocationRecord();
176  SharedAllocationRecord() = default;
177 
178  SharedAllocationRecord(
179  const Kokkos::Experimental::HBWSpace& arg_space,
180  const std::string& arg_label, const size_t arg_alloc_size,
181  const RecordBase::function_type arg_dealloc = &deallocate);
182 
183  public:
184  inline std::string get_label() const {
185  return std::string(RecordBase::head()->m_label);
186  }
187 
188  KOKKOS_INLINE_FUNCTION static SharedAllocationRecord* allocate(
189  const Kokkos::Experimental::HBWSpace& arg_space,
190  const std::string& arg_label, const size_t arg_alloc_size) {
191  KOKKOS_IF_ON_HOST((return new SharedAllocationRecord(arg_space, arg_label,
192  arg_alloc_size);))
193  KOKKOS_IF_ON_DEVICE(((void)arg_space; (void)arg_label; (void)arg_alloc_size;
194  return nullptr;))
195  }
196 
198  static void* allocate_tracked(const Kokkos::Experimental::HBWSpace& arg_space,
199  const std::string& arg_label,
200  const size_t arg_alloc_size);
201 
203  static void* reallocate_tracked(void* const arg_alloc_ptr,
204  const size_t arg_alloc_size);
205 
207  static void deallocate_tracked(void* const arg_alloc_ptr);
208 
209  static SharedAllocationRecord* get_record(void* arg_alloc_ptr);
210 
211  static void print_records(std::ostream&,
212  const Kokkos::Experimental::HBWSpace&,
213  bool detail = false);
214 };
215 
216 } // namespace Impl
217 
218 } // namespace Kokkos
219 
220 //----------------------------------------------------------------------------
221 
222 namespace Kokkos {
223 
224 namespace Impl {
225 
226 static_assert(
227  Kokkos::Impl::MemorySpaceAccess<Kokkos::Experimental::HBWSpace,
228  Kokkos::Experimental::HBWSpace>::assignable,
229  "");
230 
231 template <>
232 struct MemorySpaceAccess<Kokkos::HostSpace, Kokkos::Experimental::HBWSpace> {
233  enum : bool { assignable = true };
234  enum : bool { accessible = true };
235  enum : bool { deepcopy = true };
236 };
237 
238 template <>
239 struct MemorySpaceAccess<Kokkos::Experimental::HBWSpace, Kokkos::HostSpace> {
240  enum : bool { assignable = false };
241  enum : bool { accessible = true };
242  enum : bool { deepcopy = true };
243 };
244 
245 } // namespace Impl
246 
247 } // namespace Kokkos
248 
249 //----------------------------------------------------------------------------
250 
251 namespace Kokkos {
252 
253 namespace Impl {
254 
255 template <>
256 struct DeepCopy<Kokkos::Experimental::HBWSpace, Kokkos::Experimental::HBWSpace,
257  DefaultHostExecutionSpace> {
258  DeepCopy(void* dst, const void* src, size_t n) {
259  hostspace_parallel_deepcopy(dst, src, n);
260  }
261 
262  DeepCopy(const DefaultHostExecutionSpace& exec, void* dst, const void* src,
263  size_t n) {
264  hostspace_parallel_deepcopy(exec, dst, src, n);
265  }
266 };
267 
268 template <class ExecutionSpace>
269 struct DeepCopy<Kokkos::Experimental::HBWSpace, Kokkos::Experimental::HBWSpace,
270  ExecutionSpace> {
271  DeepCopy(void* dst, const void* src, size_t n) {
272  hostspace_parallel_deepcopy(dst, src, n);
273  }
274 
275  DeepCopy(const ExecutionSpace& exec, void* dst, const void* src, size_t n) {
276  exec.fence(
277  "Kokkos::Impl::DeepCopy<Kokkos::Experimental::HBWSpace, "
278  "Kokkos::Experimental::HBWSpace,ExecutionSpace::DeepCopy: fence "
279  "before copy");
280  hostspace_parallel_deepcopy_async(dst, src, n);
281  }
282 };
283 
284 template <>
285 struct DeepCopy<HostSpace, Kokkos::Experimental::HBWSpace,
286  DefaultHostExecutionSpace> {
287  DeepCopy(void* dst, const void* src, size_t n) {
288  hostspace_parallel_deepcopy(dst, src, n);
289  }
290 
291  DeepCopy(const DefaultHostExecutionSpace& exec, void* dst, const void* src,
292  size_t n) {
293  hostspace_parallel_deepcopy(exec, dst, src, n);
294  }
295 };
296 
297 template <class ExecutionSpace>
298 struct DeepCopy<HostSpace, Kokkos::Experimental::HBWSpace, ExecutionSpace> {
299  DeepCopy(void* dst, const void* src, size_t n) {
300  hostspace_parallel_deepcopy(dst, src, n);
301  }
302 
303  DeepCopy(const ExecutionSpace& exec, void* dst, const void* src, size_t n) {
304  exec.fence(
305  "Kokkos::Impl::DeepCopy<HostSpace, Kokkos::Experimental::HBWSpace, "
306  "ExecutionSpace>::DeepCopy: fence before copy");
307  hostspace_parallel_deepcopy_async(copy_space, dst, src, n);
308  }
309 };
310 
311 template <>
312 struct DeepCopy<Kokkos::Experimental::HBWSpace, HostSpace,
313  DefaultHostExecutionSpace> {
314  DeepCopy(void* dst, const void* src, size_t n) {
315  hostspace_parallel_deepcopy(dst, src, n);
316  }
317 
318  DeepCopy(const DefaultHostExecutionSpace& exec, void* dst, const void* src,
319  size_t n) {
320  hostspace_parallel_deepcopy(exec, dst, src, n);
321  }
322 };
323 
324 template <class ExecutionSpace>
325 struct DeepCopy<Kokkos::Experimental::HBWSpace, HostSpace, ExecutionSpace> {
326  DeepCopy(void* dst, const void* src, size_t n) {
327  hostspace_parallel_deepcopy(dst, src, n);
328  }
329 
330  DeepCopy(const ExecutionSpace& exec, void* dst, const void* src, size_t n) {
331  exec.fence(
332  "Kokkos::Impl::DeepCopy<Kokkos::Experimental::HBWSpace, HostSpace, "
333  "ExecutionSpace>::DeepCopy: fence before copy");
334  hostspace_parallel_deepcopy_async(dst, src, n);
335  }
336 };
337 
338 } // namespace Impl
339 
340 } // namespace Kokkos
341 
342 #endif
343 #endif // #define KOKKOS_HBWSPACE_HPP
Memory management for host memory.
Definition: dummy.cpp:17
Access relationship between DstMemorySpace and SrcMemorySpace.