Kokkos Core Kernels Package Version of the Day
Loading...
Searching...
No Matches
Kokkos_OpenMPTargetSpace.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_OPENMPTARGETSPACE_HPP
23#define KOKKOS_OPENMPTARGETSPACE_HPP
24
25#include <cstring>
26#include <string>
27#include <iosfwd>
28#include <typeinfo>
29
30#include <Kokkos_Core_fwd.hpp>
31
32#ifdef KOKKOS_ENABLE_OPENMPTARGET
33
34#include <OpenMPTarget/Kokkos_OpenMPTarget_Error.hpp>
35#include <Kokkos_HostSpace.hpp>
36#include <omp.h>
37
38/*--------------------------------------------------------------------------*/
39
40namespace Kokkos {
41namespace Impl {
42
49// void init_lock_array_host_space();
50
56// bool lock_address_host_space(void* ptr);
57
64// void unlock_address_host_space(void* ptr);
65
66} // namespace Impl
67} // namespace Kokkos
68
69namespace Kokkos {
70namespace Impl {
71
72//----------------------------------------
73
74template <>
75struct MemorySpaceAccess<Kokkos::HostSpace,
76 Kokkos::Experimental::OpenMPTargetSpace> {
77 enum : bool { assignable = false };
78 enum : bool { accessible = false };
79 enum : bool { deepcopy = true };
80};
81
82//----------------------------------------
83
84template <>
85struct MemorySpaceAccess<Kokkos::Experimental::OpenMPTargetSpace,
87 enum : bool { assignable = false };
88 enum : bool { accessible = false };
89 enum : bool { deepcopy = true };
90};
91
92//----------------------------------------
93} // namespace Impl
94} // namespace Kokkos
95
96namespace Kokkos {
97namespace Experimental {
98
104class OpenMPTargetSpace {
105 public:
107 using memory_space = OpenMPTargetSpace;
108 using size_type = unsigned;
109
116 using execution_space = Kokkos::Experimental::OpenMPTarget;
117
120
121 /*--------------------------------*/
122
124 OpenMPTargetSpace();
125 OpenMPTargetSpace(OpenMPTargetSpace&& rhs) = default;
126 OpenMPTargetSpace(const OpenMPTargetSpace& rhs) = default;
127 OpenMPTargetSpace& operator=(OpenMPTargetSpace&&) = default;
128 OpenMPTargetSpace& operator=(const OpenMPTargetSpace&) = default;
129 ~OpenMPTargetSpace() = default;
130
132 void* allocate(const size_t arg_alloc_size) const;
133 void* allocate(const char* arg_label, const size_t arg_alloc_size,
134 const size_t arg_logical_size = 0) const;
135
137 void deallocate(void* const arg_alloc_ptr,
138 const std::size_t arg_alloc_size) const;
139 void deallocate(const char* arg_label, void* const arg_alloc_ptr,
140 const size_t arg_alloc_size,
141 const size_t arg_logical_size = 0) const;
142
143 static constexpr const char* name() { return "OpenMPTargetSpace"; }
144
145 private:
146 void* impl_allocate(const char* arg_label, const size_t arg_alloc_size,
147 const size_t arg_logical_size = 0,
148 const Kokkos::Tools::SpaceHandle =
149 Kokkos::Tools::make_space_handle(name())) const;
150 void impl_deallocate(const char* arg_label, void* const arg_alloc_ptr,
151 const size_t arg_alloc_size,
152 const size_t arg_logical_size = 0,
153 const Kokkos::Tools::SpaceHandle =
154 Kokkos::Tools::make_space_handle(name())) const;
155
156 friend class Kokkos::Impl::SharedAllocationRecord<
157 Kokkos::Experimental::OpenMPTargetSpace, void>;
158};
159} // namespace Experimental
160} // namespace Kokkos
161
162//----------------------------------------------------------------------------
163//----------------------------------------------------------------------------
164
165namespace Kokkos {
166namespace Impl {
167
168template <>
169class SharedAllocationRecord<Kokkos::Experimental::OpenMPTargetSpace, void>
170 : public HostInaccessibleSharedAllocationRecordCommon<
171 Kokkos::Experimental::OpenMPTargetSpace> {
172 private:
173 friend class HostInaccessibleSharedAllocationRecordCommon<
174 Kokkos::Experimental::OpenMPTargetSpace>;
175 friend class SharedAllocationRecordCommon<
176 Kokkos::Experimental::OpenMPTargetSpace>;
177 friend Kokkos::Experimental::OpenMPTargetSpace;
178
179 using base_t = HostInaccessibleSharedAllocationRecordCommon<
180 Kokkos::Experimental::OpenMPTargetSpace>;
181 using RecordBase = SharedAllocationRecord<void, void>;
182
183 SharedAllocationRecord(const SharedAllocationRecord&) = delete;
184 SharedAllocationRecord& operator=(const SharedAllocationRecord&) = delete;
185
188 static RecordBase s_root_record;
189
190 const Kokkos::Experimental::OpenMPTargetSpace m_space;
191
192 protected:
193 ~SharedAllocationRecord();
194 SharedAllocationRecord() = default;
195
196 template <typename ExecutionSpace>
197 SharedAllocationRecord(
198 const ExecutionSpace& /*exec_space*/,
199 const Kokkos::Experimental::OpenMPTargetSpace& arg_space,
200 const std::string& arg_label, const size_t arg_alloc_size,
201 const RecordBase::function_type arg_dealloc = &deallocate)
202 : SharedAllocationRecord(arg_space, arg_label, arg_alloc_size,
203 arg_dealloc) {}
204
205 SharedAllocationRecord(
206 const Kokkos::Experimental::OpenMPTargetSpace& arg_space,
207 const std::string& arg_label, const size_t arg_alloc_size,
208 const RecordBase::function_type arg_dealloc = &deallocate);
209
210 public:
211 KOKKOS_INLINE_FUNCTION static SharedAllocationRecord* allocate(
212 const Kokkos::Experimental::OpenMPTargetSpace& arg_space,
213 const std::string& arg_label, const size_t arg_alloc) {
214 KOKKOS_IF_ON_HOST(
215 (return new SharedAllocationRecord(arg_space, arg_label, arg_alloc);))
216 KOKKOS_IF_ON_DEVICE(
217 ((void)arg_space; (void)arg_label; (void)arg_alloc; return nullptr;))
218 }
219};
220
221} // namespace Impl
222} // namespace Kokkos
223
224//----------------------------------------------------------------------------
225//----------------------------------------------------------------------------
226
227namespace Kokkos {
228namespace Impl {
229
230// TODO: implement all possible deep_copies
231template <class ExecutionSpace>
232struct DeepCopy<Kokkos::Experimental::OpenMPTargetSpace,
233 Kokkos::Experimental::OpenMPTargetSpace, ExecutionSpace> {
234 DeepCopy(void* dst, const void* src, size_t n) {
235 // In the Release and RelWithDebInfo builds, the size of the memcpy should
236 // be greater than zero to avoid error. omp_target_memcpy returns zero on
237 // success.
238 if (n > 0)
239 KOKKOS_IMPL_OMPT_SAFE_CALL(omp_target_memcpy(
240 dst, const_cast<void*>(src), n, 0, 0, omp_get_default_device(),
241 omp_get_default_device()));
242 }
243 DeepCopy(const ExecutionSpace& exec, void* dst, const void* src, size_t n) {
244 exec.fence(
245 "Kokkos::Impl::DeepCopy<OpenMPTargetSpace, OpenMPTargetSpace>: fence "
246 "before "
247 "copy");
248 if (n > 0)
249 KOKKOS_IMPL_OMPT_SAFE_CALL(omp_target_memcpy(
250 dst, const_cast<void*>(src), n, 0, 0, omp_get_default_device(),
251 omp_get_default_device()));
252 }
253};
254
255template <class ExecutionSpace>
256struct DeepCopy<Kokkos::Experimental::OpenMPTargetSpace, HostSpace,
257 ExecutionSpace> {
258 DeepCopy(void* dst, const void* src, size_t n) {
259 if (n > 0)
260 KOKKOS_IMPL_OMPT_SAFE_CALL(omp_target_memcpy(
261 dst, const_cast<void*>(src), n, 0, 0, omp_get_default_device(),
262 omp_get_initial_device()));
263 }
264 DeepCopy(const ExecutionSpace& exec, void* dst, const void* src, size_t n) {
265 exec.fence(
266 "Kokkos::Impl::DeepCopy<OpenMPTargetSpace, HostSpace>: fence before "
267 "copy");
268 if (n > 0)
269 KOKKOS_IMPL_OMPT_SAFE_CALL(omp_target_memcpy(
270 dst, const_cast<void*>(src), n, 0, 0, omp_get_default_device(),
271 omp_get_initial_device()));
272 }
273};
274
275template <class ExecutionSpace>
276struct DeepCopy<HostSpace, Kokkos::Experimental::OpenMPTargetSpace,
277 ExecutionSpace> {
278 DeepCopy(void* dst, const void* src, size_t n) {
279 if (n > 0)
280 KOKKOS_IMPL_OMPT_SAFE_CALL(omp_target_memcpy(
281 dst, const_cast<void*>(src), n, 0, 0, omp_get_initial_device(),
282 omp_get_default_device()));
283 }
284 DeepCopy(const ExecutionSpace& exec, void* dst, const void* src, size_t n) {
285 exec.fence(
286 "Kokkos::Impl::DeepCopy<HostSpace, OpenMPTargetSpace>: fence before "
287 "copy");
288 if (n > 0)
289 KOKKOS_IMPL_OMPT_SAFE_CALL(omp_target_memcpy(
290 dst, const_cast<void*>(src), n, 0, 0, omp_get_initial_device(),
291 omp_get_default_device()));
292 }
293};
294
295} // namespace Impl
296} // namespace Kokkos
297
298#endif
299#endif /* #define KOKKOS_OPENMPTARGETSPACE_HPP */
A thread safe view to a bitset.
Memory management for host memory.