Kokkos Core Kernels Package Version of the Day
Kokkos_OpenMPTargetSpace.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_OPENMPTARGETSPACE_HPP
46#define KOKKOS_OPENMPTARGETSPACE_HPP
47
48#include <cstring>
49#include <string>
50#include <iosfwd>
51#include <typeinfo>
52
53#include <Kokkos_Core_fwd.hpp>
54
55#ifdef KOKKOS_ENABLE_OPENMPTARGET
56
57#include <OpenMPTarget/Kokkos_OpenMPTarget_Error.hpp>
58#include <Kokkos_HostSpace.hpp>
59#include <omp.h>
60
61/*--------------------------------------------------------------------------*/
62
63namespace Kokkos {
64namespace Impl {
65
72// void init_lock_array_host_space();
73
79// bool lock_address_host_space(void* ptr);
80
87// void unlock_address_host_space(void* ptr);
88
89} // namespace Impl
90} // namespace Kokkos
91
92namespace Kokkos {
93namespace Experimental {
94
100class OpenMPTargetSpace {
101 public:
103 using memory_space = OpenMPTargetSpace;
104 using size_type = size_t;
105
112 using execution_space = Kokkos::Experimental::OpenMPTarget;
113
115 using device_type = Kokkos::Device<execution_space, memory_space>;
116
117 /*--------------------------------*/
118
120 OpenMPTargetSpace();
121 OpenMPTargetSpace(OpenMPTargetSpace&& rhs) = default;
122 OpenMPTargetSpace(const OpenMPTargetSpace& rhs) = default;
123 OpenMPTargetSpace& operator=(OpenMPTargetSpace&&) = default;
124 OpenMPTargetSpace& operator=(const OpenMPTargetSpace&) = default;
125 ~OpenMPTargetSpace() = default;
126
128 void* allocate(const size_t arg_alloc_size) const;
129
131 void deallocate(void* const arg_alloc_ptr, const size_t arg_alloc_size) const;
132
133 static constexpr const char* name() { return "OpenMPTargetSpace"; }
134
135 private:
136 friend class Kokkos::Impl::SharedAllocationRecord<
137 Kokkos::Experimental::OpenMPTargetSpace, void>;
138};
139} // namespace Experimental
140} // namespace Kokkos
141
142//----------------------------------------------------------------------------
143//----------------------------------------------------------------------------
144
145namespace Kokkos {
146namespace Impl {
147
148template <>
149class SharedAllocationRecord<Kokkos::Experimental::OpenMPTargetSpace, void>
150 : public HostInaccessibleSharedAllocationRecordCommon<
151 Kokkos::Experimental::OpenMPTargetSpace> {
152 private:
153 friend class HostInaccessibleSharedAllocationRecordCommon<
154 Kokkos::Experimental::OpenMPTargetSpace>;
155 friend class SharedAllocationRecordCommon<
156 Kokkos::Experimental::OpenMPTargetSpace>;
157 friend Kokkos::Experimental::OpenMPTargetSpace;
158
159 using base_t = HostInaccessibleSharedAllocationRecordCommon<
160 Kokkos::Experimental::OpenMPTargetSpace>;
161 using RecordBase = SharedAllocationRecord<void, void>;
162
163 SharedAllocationRecord(const SharedAllocationRecord&) = delete;
164 SharedAllocationRecord& operator=(const SharedAllocationRecord&) = delete;
165
168 static RecordBase s_root_record;
169
170 const Kokkos::Experimental::OpenMPTargetSpace m_space;
171
172 protected:
173 ~SharedAllocationRecord();
174 SharedAllocationRecord() = default;
175
176 SharedAllocationRecord(
177 const Kokkos::Experimental::OpenMPTargetSpace& arg_space,
178 const std::string& arg_label, const size_t arg_alloc_size,
179 const RecordBase::function_type arg_dealloc = &deallocate);
180
181 public:
182 KOKKOS_INLINE_FUNCTION static SharedAllocationRecord* allocate(
183 const Kokkos::Experimental::OpenMPTargetSpace& arg_space,
184 const std::string& arg_label, const size_t arg_alloc_size) {
185#if defined(KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST)
186 return new SharedAllocationRecord(arg_space, arg_label, arg_alloc_size);
187#else
188 return nullptr;
189#endif
190 }
191};
192
193} // namespace Impl
194} // namespace Kokkos
195
196//----------------------------------------------------------------------------
197//----------------------------------------------------------------------------
198
199namespace Kokkos {
200namespace Impl {
201
202// TODO: implement all possible deep_copies
203template <class ExecutionSpace>
204struct DeepCopy<Kokkos::Experimental::OpenMPTargetSpace,
205 Kokkos::Experimental::OpenMPTargetSpace, ExecutionSpace> {
206 DeepCopy(void* dst, const void* src, size_t n) {
207 // In the Release and RelWithDebInfo builds, the size of the memcpy should
208 // be greater than zero to avoid error. omp_target_memcpy returns zero on
209 // success.
210 if (n > 0)
211 OMPT_SAFE_CALL(omp_target_memcpy(dst, const_cast<void*>(src), n, 0, 0,
212 omp_get_default_device(),
213 omp_get_default_device()));
214 }
215 DeepCopy(const ExecutionSpace& exec, void* dst, const void* src, size_t n) {
216 exec.fence();
217 if (n > 0)
218 OMPT_SAFE_CALL(omp_target_memcpy(dst, const_cast<void*>(src), n, 0, 0,
219 omp_get_default_device(),
220 omp_get_default_device()));
221 }
222};
223
224template <class ExecutionSpace>
225struct DeepCopy<Kokkos::Experimental::OpenMPTargetSpace, HostSpace,
226 ExecutionSpace> {
227 DeepCopy(void* dst, const void* src, size_t n) {
228 if (n > 0)
229 OMPT_SAFE_CALL(omp_target_memcpy(dst, const_cast<void*>(src), n, 0, 0,
230 omp_get_default_device(),
231 omp_get_initial_device()));
232 }
233 DeepCopy(const ExecutionSpace& exec, void* dst, const void* src, size_t n) {
234 exec.fence();
235 if (n > 0)
236 OMPT_SAFE_CALL(omp_target_memcpy(dst, const_cast<void*>(src), n, 0, 0,
237 omp_get_default_device(),
238 omp_get_initial_device()));
239 }
240};
241
242template <class ExecutionSpace>
243struct DeepCopy<HostSpace, Kokkos::Experimental::OpenMPTargetSpace,
244 ExecutionSpace> {
245 DeepCopy(void* dst, const void* src, size_t n) {
246 if (n > 0)
247 OMPT_SAFE_CALL(omp_target_memcpy(dst, const_cast<void*>(src), n, 0, 0,
248 omp_get_initial_device(),
249 omp_get_default_device()));
250 }
251 DeepCopy(const ExecutionSpace& exec, void* dst, const void* src, size_t n) {
252 exec.fence();
253 if (n > 0)
254 OMPT_SAFE_CALL(omp_target_memcpy(dst, const_cast<void*>(src), n, 0, 0,
255 omp_get_initial_device(),
256 omp_get_default_device()));
257 }
258};
259
260} // namespace Impl
261} // namespace Kokkos
262
263#endif
264#endif /* #define KOKKOS_OPENMPTARGETSPACE_HPP */