Kokkos Core Kernels Package Version of the Day
Loading...
Searching...
No Matches
Kokkos_HostSpace.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>
19static_assert(false,
20 "Including non-public Kokkos header files is not allowed.");
21#endif
22#ifndef KOKKOS_HOSTSPACE_HPP
23#define KOKKOS_HOSTSPACE_HPP
24
25#include <cstring>
26#include <string>
27#include <iosfwd>
28#include <typeinfo>
29
30#include <Kokkos_Core_fwd.hpp>
31#include <Kokkos_Concepts.hpp>
32#include <Kokkos_MemoryTraits.hpp>
33
34#include <impl/Kokkos_Traits.hpp>
35#include <impl/Kokkos_Error.hpp>
36#include <impl/Kokkos_SharedAlloc.hpp>
37#include <impl/Kokkos_Tools.hpp>
38
39#include "impl/Kokkos_HostSpace_deepcopy.hpp"
40#include <impl/Kokkos_MemorySpace.hpp>
41
42/*--------------------------------------------------------------------------*/
43
44namespace Kokkos {
45
46namespace Impl {
47
55
62
70
71} // namespace Impl
72
73} // namespace Kokkos
74
75namespace Kokkos {
81class HostSpace {
82 public:
85 using size_type = size_t;
86
93 using execution_space = DefaultHostExecutionSpace;
94
96 using device_type = Kokkos::Device<execution_space, memory_space>;
97
100 HostSpace(HostSpace&& rhs) = default;
101 HostSpace(const HostSpace& rhs) = default;
102 HostSpace& operator=(HostSpace&&) = default;
103 HostSpace& operator=(const HostSpace&) = default;
104 ~HostSpace() = default;
105
110 STD_MALLOC,
111 POSIX_MEMALIGN,
112 POSIX_MMAP,
113 INTEL_MM_ALLOC
114 };
115
116 explicit HostSpace(const AllocationMechanism&);
117
119 void* allocate(const size_t arg_alloc_size) const;
120 void* allocate(const char* arg_label, const size_t arg_alloc_size,
121 const size_t arg_logical_size = 0) const;
122
124 void deallocate(void* const arg_alloc_ptr, const size_t arg_alloc_size) const;
125 void deallocate(const char* arg_label, void* const arg_alloc_ptr,
126 const size_t arg_alloc_size,
127 const size_t arg_logical_size = 0) const;
128
129 private:
130 template <class, class, class, class>
132
133 void* impl_allocate(const char* arg_label, const size_t arg_alloc_size,
134 const size_t arg_logical_size = 0,
135 const Kokkos::Tools::SpaceHandle =
136 Kokkos::Tools::make_space_handle(name())) const;
137 void impl_deallocate(const char* arg_label, void* const arg_alloc_ptr,
138 const size_t arg_alloc_size,
139 const size_t arg_logical_size = 0,
140 const Kokkos::Tools::SpaceHandle =
141 Kokkos::Tools::make_space_handle(name())) const;
142
143 public:
145 static constexpr const char* name() { return m_name; }
146
147 private:
148 AllocationMechanism m_alloc_mech;
149 static constexpr const char* m_name = "Host";
150 friend class Kokkos::Impl::SharedAllocationRecord<Kokkos::HostSpace, void>;
151};
152
153} // namespace Kokkos
154
155//----------------------------------------------------------------------------
156
157namespace Kokkos {
158
159namespace Impl {
160
162 Kokkos::HostSpace>::assignable,
163 "");
164
165template <typename S>
166struct HostMirror {
167 private:
168 // If input execution space can access HostSpace then keep it.
169 // Example: Kokkos::OpenMP can access, Kokkos::Cuda cannot
170 enum {
172 typename S::execution_space::memory_space,
173 Kokkos::HostSpace>::accessible
174 };
175
176 // If HostSpace can access memory space then keep it.
177 // Example: Cannot access Kokkos::CudaSpace, can access Kokkos::CudaUVMSpace
178 enum {
179 keep_mem =
181 typename S::memory_space>::accessible
182 };
183
184 public:
185 using Space = std::conditional_t<
186 keep_exe && keep_mem, S,
187 std::conditional_t<keep_mem,
189 typename S::memory_space>,
191};
192
193} // namespace Impl
194
195} // namespace Kokkos
196
197//----------------------------------------------------------------------------
198
199namespace Kokkos {
200
201namespace Impl {
202
203template <>
204class SharedAllocationRecord<Kokkos::HostSpace, void>
205 : public SharedAllocationRecordCommon<Kokkos::HostSpace> {
206 private:
207 friend Kokkos::HostSpace;
208 friend class SharedAllocationRecordCommon<Kokkos::HostSpace>;
209
210 using base_t = SharedAllocationRecordCommon<Kokkos::HostSpace>;
211 using RecordBase = SharedAllocationRecord<void, void>;
212
213 SharedAllocationRecord(const SharedAllocationRecord&) = delete;
214 SharedAllocationRecord& operator=(const SharedAllocationRecord&) = delete;
215
216#ifdef KOKKOS_ENABLE_DEBUG
218 static RecordBase s_root_record;
219#endif
220
221 const Kokkos::HostSpace m_space;
222
223 protected:
224 ~SharedAllocationRecord();
225 SharedAllocationRecord() = default;
226
227 // This constructor does not forward to the one without exec_space arg
228 // in order to work around https://github.com/kokkos/kokkos/issues/5258
229 // This constructor is templated so I can't just put it into the cpp file
230 // like the other constructor.
231 template <typename ExecutionSpace>
232 SharedAllocationRecord(
233 const ExecutionSpace& /* exec_space*/, const Kokkos::HostSpace& arg_space,
234 const std::string& arg_label, const size_t arg_alloc_size,
235 const RecordBase::function_type arg_dealloc = &deallocate)
236 : base_t(
237#ifdef KOKKOS_ENABLE_DEBUG
238 &SharedAllocationRecord<Kokkos::HostSpace, void>::s_root_record,
239#endif
240 Impl::checked_allocation_with_header(arg_space, arg_label,
241 arg_alloc_size),
242 sizeof(SharedAllocationHeader) + arg_alloc_size, arg_dealloc,
243 arg_label),
244 m_space(arg_space) {
245 this->base_t::_fill_host_accessible_header_info(*RecordBase::m_alloc_ptr,
246 arg_label);
247 }
248
249 SharedAllocationRecord(
250 const Kokkos::HostSpace& arg_space, const std::string& arg_label,
251 const size_t arg_alloc_size,
252 const RecordBase::function_type arg_dealloc = &deallocate);
253
254 public:
255 KOKKOS_INLINE_FUNCTION static SharedAllocationRecord* allocate(
256 const Kokkos::HostSpace& arg_space, const std::string& arg_label,
257 const size_t arg_alloc_size) {
258 KOKKOS_IF_ON_HOST((return new SharedAllocationRecord(arg_space, arg_label,
259 arg_alloc_size);))
260 KOKKOS_IF_ON_DEVICE(((void)arg_space; (void)arg_label; (void)arg_alloc_size;
261 return nullptr;))
262 }
263};
264
265} // namespace Impl
266
267} // namespace Kokkos
268
269//----------------------------------------------------------------------------
270
271namespace Kokkos {
272
273namespace Impl {
274
275template <class DT, class... DP>
276struct ZeroMemset<typename HostSpace::execution_space, DT, DP...> {
277 ZeroMemset(const typename HostSpace::execution_space& exec,
278 const View<DT, DP...>& dst,
279 typename View<DT, DP...>::const_value_type&) {
280 // Host spaces, except for HPX, are synchronous and we need to fence for HPX
281 // since we can't properly enqueue a std::memset otherwise.
282 // We can't use exec.fence() directly since we don't have a full definition
283 // of HostSpace here.
284 hostspace_fence(exec);
285 using ValueType = typename View<DT, DP...>::value_type;
286 std::memset(dst.data(), 0, sizeof(ValueType) * dst.size());
287 }
288
289 ZeroMemset(const View<DT, DP...>& dst,
290 typename View<DT, DP...>::const_value_type&) {
291 using ValueType = typename View<DT, DP...>::value_type;
292 std::memset(dst.data(), 0, sizeof(ValueType) * dst.size());
293 }
294};
295
296template <>
297struct DeepCopy<HostSpace, HostSpace, DefaultHostExecutionSpace> {
298 DeepCopy(void* dst, const void* src, size_t n) {
299 hostspace_parallel_deepcopy(dst, src, n);
300 }
301
302 DeepCopy(const DefaultHostExecutionSpace& exec, void* dst, const void* src,
303 size_t n) {
304 hostspace_parallel_deepcopy_async(exec, dst, src, n);
305 }
306};
307
308template <class ExecutionSpace>
309struct DeepCopy<HostSpace, HostSpace, ExecutionSpace> {
310 DeepCopy(void* dst, const void* src, size_t n) {
311 hostspace_parallel_deepcopy(dst, src, n);
312 }
313
314 DeepCopy(const ExecutionSpace& exec, void* dst, const void* src, size_t n) {
315 exec.fence(
316 "Kokkos::Impl::DeepCopy<HostSpace, HostSpace, "
317 "ExecutionSpace>::DeepCopy: fence before copy");
318 hostspace_parallel_deepcopy_async(dst, src, n);
319 }
320};
321
322} // namespace Impl
323
324} // namespace Kokkos
325
326#endif // #define KOKKOS_HOSTSPACE_HPP
View
LogicalMemorySpace is a space that is identical to another space, but differentiable by name and temp...
Memory management for host memory.
HostSpace()
Default memory space instance.
static constexpr const char * name()
Return Name of the MemorySpace.
void deallocate(void *const arg_alloc_ptr, const size_t arg_alloc_size) const
Deallocate untracked memory in the space.
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.
Kokkos::Device< execution_space, memory_space > device_type
This memory space preferred device_type.
DefaultHostExecutionSpace execution_space
Default execution space for this memory space.
void unlock_address_host_space(void *ptr)
Release lock for the address.
void init_lock_array_host_space()
Initialize lock array for arbitrary size atomics.
bool lock_address_host_space(void *ptr)
Acquire a lock for the address.
Access relationship between DstMemorySpace and SrcMemorySpace.