Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Kokkos_HBWSpace.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_HBWSPACE_HPP
46 #define KOKKOS_HBWSPACE_HPP
47 
48 #include <Kokkos_Macros.hpp>
49 #ifdef KOKKOS_ENABLE_HBWSPACE
50 
51 #include <Kokkos_HostSpace.hpp>
52 
53 namespace Kokkos {
54 
55 namespace Experimental {
56 
57 namespace Impl {
58 
65 void init_lock_array_hbw_space();
66 
72 bool lock_address_hbw_space(void* ptr);
73 
80 void unlock_address_hbw_space(void* ptr);
81 
82 } // namespace Impl
83 
84 } // namespace Experimental
85 
86 } // namespace Kokkos
87 
88 namespace Kokkos {
89 
90 namespace Experimental {
91 
97 class HBWSpace {
98  public:
100  typedef HBWSpace memory_space;
101  typedef size_t size_type;
102 
109 #if defined(KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_OPENMP)
110  typedef Kokkos::OpenMP execution_space;
111 #elif defined(KOKKOS_ENABLE_DEFAULT_DEVICE_TYPE_THREADS)
112  typedef Kokkos::Threads execution_space;
113 #elif defined(KOKKOS_ENABLE_OPENMP)
114  typedef Kokkos::OpenMP execution_space;
115 #elif defined(KOKKOS_ENABLE_THREADS)
116  typedef Kokkos::Threads execution_space;
117 #elif defined(KOKKOS_ENABLE_SERIAL)
118  typedef Kokkos::Serial execution_space;
119 #else
120 #error \
121  "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."
122 #endif
123 
125  typedef Kokkos::Device<execution_space, memory_space> device_type;
126 
128  HBWSpace();
129  HBWSpace(const HBWSpace& rhs) = default;
130  HBWSpace& operator=(const HBWSpace&) = default;
131  ~HBWSpace() = default;
132 
136  enum AllocationMechanism {
137  STD_MALLOC,
138  POSIX_MEMALIGN,
139  POSIX_MMAP,
140  INTEL_MM_ALLOC
141  };
142 
143  explicit HBWSpace(const AllocationMechanism&);
144 
146  void* allocate(const size_t arg_alloc_size) const;
147 
149  void deallocate(void* const arg_alloc_ptr, const size_t arg_alloc_size) const;
150 
152  static constexpr const char* name() { return "HBW"; }
153 
154  private:
155  AllocationMechanism m_alloc_mech;
156  friend class Kokkos::Impl::SharedAllocationRecord<
157  Kokkos::Experimental::HBWSpace, void>;
158 };
159 
160 } // namespace Experimental
161 
162 } // namespace Kokkos
163 
164 //----------------------------------------------------------------------------
165 
166 namespace Kokkos {
167 
168 namespace Impl {
169 
170 template <>
171 class SharedAllocationRecord<Kokkos::Experimental::HBWSpace, void>
172  : public SharedAllocationRecord<void, void> {
173  private:
174  friend Kokkos::Experimental::HBWSpace;
175 
176  typedef SharedAllocationRecord<void, void> RecordBase;
177 
178  SharedAllocationRecord(const SharedAllocationRecord&) = delete;
179  SharedAllocationRecord& operator=(const SharedAllocationRecord&) = delete;
180 
181  static void deallocate(RecordBase*);
182 
183 #ifdef KOKKOS_DEBUG
184 
185  static RecordBase s_root_record;
186 #endif
187 
188  const Kokkos::Experimental::HBWSpace m_space;
189 
190  protected:
191  ~SharedAllocationRecord()
192 #if defined( \
193  KOKKOS_IMPL_INTEL_WORKAROUND_NOEXCEPT_SPECIFICATION_VIRTUAL_FUNCTION)
194  noexcept
195 #endif
196  ;
197  SharedAllocationRecord() = default;
198 
199  SharedAllocationRecord(
200  const Kokkos::Experimental::HBWSpace& arg_space,
201  const std::string& arg_label, const size_t arg_alloc_size,
202  const RecordBase::function_type arg_dealloc = &deallocate);
203 
204  public:
205  inline std::string get_label() const {
206  return std::string(RecordBase::head()->m_label);
207  }
208 
209  KOKKOS_INLINE_FUNCTION static SharedAllocationRecord* allocate(
210  const Kokkos::Experimental::HBWSpace& arg_space,
211  const std::string& arg_label, const size_t arg_alloc_size) {
212 #if defined(KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST)
213  return new SharedAllocationRecord(arg_space, arg_label, arg_alloc_size);
214 #else
215  return (SharedAllocationRecord*)0;
216 #endif
217  }
218 
220  static void* allocate_tracked(const Kokkos::Experimental::HBWSpace& arg_space,
221  const std::string& arg_label,
222  const size_t arg_alloc_size);
223 
225  static void* reallocate_tracked(void* const arg_alloc_ptr,
226  const size_t arg_alloc_size);
227 
229  static void deallocate_tracked(void* const arg_alloc_ptr);
230 
231  static SharedAllocationRecord* get_record(void* arg_alloc_ptr);
232 
233  static void print_records(std::ostream&,
234  const Kokkos::Experimental::HBWSpace&,
235  bool detail = false);
236 };
237 
238 } // namespace Impl
239 
240 } // namespace Kokkos
241 
242 //----------------------------------------------------------------------------
243 
244 namespace Kokkos {
245 
246 namespace Impl {
247 
248 static_assert(
249  Kokkos::Impl::MemorySpaceAccess<Kokkos::Experimental::HBWSpace,
250  Kokkos::Experimental::HBWSpace>::assignable,
251  "");
252 
253 template <>
254 struct MemorySpaceAccess<Kokkos::HostSpace, Kokkos::Experimental::HBWSpace> {
255  enum { assignable = true };
256  enum { accessible = true };
257  enum { deepcopy = true };
258 };
259 
260 template <>
261 struct MemorySpaceAccess<Kokkos::Experimental::HBWSpace, Kokkos::HostSpace> {
262  enum { assignable = false };
263  enum { accessible = true };
264  enum { deepcopy = true };
265 };
266 
267 } // namespace Impl
268 
269 } // namespace Kokkos
270 
271 //----------------------------------------------------------------------------
272 
273 namespace Kokkos {
274 
275 namespace Impl {
276 
277 template <class ExecutionSpace>
278 struct DeepCopy<Kokkos::Experimental::HBWSpace, Kokkos::Experimental::HBWSpace,
279  ExecutionSpace> {
280  DeepCopy(void* dst, const void* src, size_t n) { memcpy(dst, src, n); }
281 
282  DeepCopy(const ExecutionSpace& exec, void* dst, const void* src, size_t n) {
283  exec.fence();
284  memcpy(dst, src, n);
285  }
286 };
287 
288 template <class ExecutionSpace>
289 struct DeepCopy<HostSpace, Kokkos::Experimental::HBWSpace, ExecutionSpace> {
290  DeepCopy(void* dst, const void* src, size_t n) { memcpy(dst, src, n); }
291 
292  DeepCopy(const ExecutionSpace& exec, void* dst, const void* src, size_t n) {
293  exec.fence();
294  memcpy(dst, src, n);
295  }
296 };
297 
298 template <class ExecutionSpace>
299 struct DeepCopy<Kokkos::Experimental::HBWSpace, HostSpace, ExecutionSpace> {
300  DeepCopy(void* dst, const void* src, size_t n) { memcpy(dst, src, n); }
301 
302  DeepCopy(const ExecutionSpace& exec, void* dst, const void* src, size_t n) {
303  exec.fence();
304  memcpy(dst, src, n);
305  }
306 };
307 
308 } // namespace Impl
309 
310 } // namespace Kokkos
311 
312 namespace Kokkos {
313 
314 namespace Impl {
315 
316 template <>
317 struct VerifyExecutionCanAccessMemorySpace<Kokkos::HostSpace,
318  Kokkos::Experimental::HBWSpace> {
319  enum { value = true };
320  inline static void verify(void) {}
321  inline static void verify(const void*) {}
322 };
323 
324 template <>
325 struct VerifyExecutionCanAccessMemorySpace<Kokkos::Experimental::HBWSpace,
327  enum { value = true };
328  inline static void verify(void) {}
329  inline static void verify(const void*) {}
330 };
331 
332 } // namespace Impl
333 
334 } // namespace Kokkos
335 
336 #endif
337 #endif // #define KOKKOS_HBWSPACE_HPP
Memory management for host memory.
Access relationship between DstMemorySpace and SrcMemorySpace.