Kokkos Core Kernels Package Version of the Day
Kokkos_Concepts.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_CORE_CONCEPTS_HPP
46#define KOKKOS_CORE_CONCEPTS_HPP
47
48#include <type_traits>
49
50// Needed for 'is_space<S>::host_mirror_space
51#include <Kokkos_Core_fwd.hpp>
52
53//----------------------------------------------------------------------------
54//----------------------------------------------------------------------------
55
56namespace Kokkos {
57
58// Schedules for Execution Policies
59struct Static {};
60struct Dynamic {};
61
62// Schedule Wrapper Type
63template <class T>
64struct Schedule {
65 static_assert(std::is_same<T, Static>::value ||
66 std::is_same<T, Dynamic>::value,
67 "Kokkos: Invalid Schedule<> type.");
68 using schedule_type = Schedule;
69 using type = T;
70};
71
72// Specify Iteration Index Type
73template <typename T>
74struct IndexType {
75 static_assert(std::is_integral<T>::value, "Kokkos: Invalid IndexType<>.");
76 using index_type = IndexType;
77 using type = T;
78};
79
80namespace Experimental {
81struct WorkItemProperty {
82 template <unsigned long Property>
83 struct ImplWorkItemProperty {
84 static const unsigned value = Property;
85 using work_item_property = ImplWorkItemProperty<Property>;
86 };
87
88 constexpr static const ImplWorkItemProperty<0> None =
89 ImplWorkItemProperty<0>();
90 constexpr static const ImplWorkItemProperty<1> HintLightWeight =
91 ImplWorkItemProperty<1>();
92 constexpr static const ImplWorkItemProperty<2> HintHeavyWeight =
93 ImplWorkItemProperty<2>();
94 constexpr static const ImplWorkItemProperty<4> HintRegular =
95 ImplWorkItemProperty<4>();
96 constexpr static const ImplWorkItemProperty<8> HintIrregular =
97 ImplWorkItemProperty<8>();
98 using None_t = ImplWorkItemProperty<0>;
99 using HintLightWeight_t = ImplWorkItemProperty<1>;
100 using HintHeavyWeight_t = ImplWorkItemProperty<2>;
101 using HintRegular_t = ImplWorkItemProperty<4>;
102 using HintIrregular_t = ImplWorkItemProperty<8>;
103};
104
105template <unsigned long pv1, unsigned long pv2>
106inline constexpr WorkItemProperty::ImplWorkItemProperty<pv1 | pv2> operator|(
107 WorkItemProperty::ImplWorkItemProperty<pv1>,
108 WorkItemProperty::ImplWorkItemProperty<pv2>) {
109 return WorkItemProperty::ImplWorkItemProperty<pv1 | pv2>();
110}
111
112template <unsigned long pv1, unsigned long pv2>
113inline constexpr WorkItemProperty::ImplWorkItemProperty<pv1 & pv2> operator&(
114 WorkItemProperty::ImplWorkItemProperty<pv1>,
115 WorkItemProperty::ImplWorkItemProperty<pv2>) {
116 return WorkItemProperty::ImplWorkItemProperty<pv1 & pv2>();
117}
118
119template <unsigned long pv1, unsigned long pv2>
120inline constexpr bool operator==(WorkItemProperty::ImplWorkItemProperty<pv1>,
121 WorkItemProperty::ImplWorkItemProperty<pv2>) {
122 return pv1 == pv2;
123}
124
125} // namespace Experimental
126
131template <unsigned int maxT = 0 /* Max threads per block */
132 ,
133 unsigned int minB = 0 /* Min blocks per SM */
134 >
138 static unsigned int constexpr maxTperB{maxT};
139 static unsigned int constexpr minBperSM{minB};
140};
141
142} // namespace Kokkos
143
144//----------------------------------------------------------------------------
145//----------------------------------------------------------------------------
146
147namespace Kokkos {
148
149#define KOKKOS_IMPL_IS_CONCEPT(CONCEPT) \
150 template <typename T> \
151 struct is_##CONCEPT { \
152 private: \
153 template <typename, typename = std::true_type> \
154 struct have : std::false_type {}; \
155 template <typename U> \
156 struct have<U, typename std::is_base_of<typename U::CONCEPT, U>::type> \
157 : std::true_type {}; \
158 template <typename U> \
159 struct have<U, \
160 typename std::is_base_of<typename U::CONCEPT##_type, U>::type> \
161 : std::true_type {}; \
162 \
163 public: \
164 static constexpr bool value = \
165 is_##CONCEPT::template have<typename std::remove_cv<T>::type>::value; \
166 constexpr operator bool() const noexcept { return value; } \
167 };
168
169// Public concept:
170
171KOKKOS_IMPL_IS_CONCEPT(memory_space)
172KOKKOS_IMPL_IS_CONCEPT(memory_traits)
173KOKKOS_IMPL_IS_CONCEPT(execution_space)
174KOKKOS_IMPL_IS_CONCEPT(execution_policy)
175KOKKOS_IMPL_IS_CONCEPT(array_layout)
176KOKKOS_IMPL_IS_CONCEPT(reducer)
177namespace Experimental {
178KOKKOS_IMPL_IS_CONCEPT(work_item_property)
179}
180
181namespace Impl {
182
183// For backward compatibility:
184
185using Kokkos::is_array_layout;
186using Kokkos::is_execution_policy;
187using Kokkos::is_execution_space;
188using Kokkos::is_memory_space;
189using Kokkos::is_memory_traits;
190
191// Implementation concept:
192
193KOKKOS_IMPL_IS_CONCEPT(iteration_pattern)
194KOKKOS_IMPL_IS_CONCEPT(schedule_type)
195KOKKOS_IMPL_IS_CONCEPT(index_type)
196KOKKOS_IMPL_IS_CONCEPT(launch_bounds)
197KOKKOS_IMPL_IS_CONCEPT(thread_team_member)
198KOKKOS_IMPL_IS_CONCEPT(host_thread_team_member)
199KOKKOS_IMPL_IS_CONCEPT(graph_kernel)
200
201} // namespace Impl
202
203#undef KOKKOS_IMPL_IS_CONCEPT
204
205} // namespace Kokkos
206
207namespace Kokkos {
208namespace Impl {
209
210template <class Object>
211class has_member_team_shmem_size {
212 template <typename T>
213 static int32_t test_for_member(decltype(&T::team_shmem_size)) {
214 return int32_t(0);
215 }
216 template <typename T>
217 static int64_t test_for_member(...) {
218 return int64_t(0);
219 }
220
221 public:
222 constexpr static bool value =
223 sizeof(test_for_member<Object>(nullptr)) == sizeof(int32_t);
224};
225
226template <class Object>
227class has_member_shmem_size {
228 template <typename T>
229 static int32_t test_for_member(decltype(&T::shmem_size_me)) {
230 return int32_t(0);
231 }
232 template <typename T>
233 static int64_t test_for_member(...) {
234 return int64_t(0);
235 }
236
237 public:
238 constexpr static bool value =
239 sizeof(test_for_member<Object>(0)) == sizeof(int32_t);
240};
241
242} // namespace Impl
243} // namespace Kokkos
244//----------------------------------------------------------------------------
245
246namespace Kokkos {
247
248template <class ExecutionSpace, class MemorySpace>
249struct Device {
250 static_assert(Kokkos::is_execution_space<ExecutionSpace>::value,
251 "Execution space is not valid");
252 static_assert(Kokkos::is_memory_space<MemorySpace>::value,
253 "Memory space is not valid");
254 using execution_space = ExecutionSpace;
255 using memory_space = MemorySpace;
256 using device_type = Device<execution_space, memory_space>;
257};
258
259namespace Impl {
260
261template <typename T>
262struct is_device_helper : std::false_type {};
263
264template <typename ExecutionSpace, typename MemorySpace>
265struct is_device_helper<Device<ExecutionSpace, MemorySpace>> : std::true_type {
266};
267
268} // namespace Impl
269
270template <typename T>
271using is_device =
272 typename Impl::is_device_helper<typename std::remove_cv<T>::type>::type;
273
274//----------------------------------------------------------------------------
275
276template <typename T>
277struct is_space {
278 private:
279 template <typename, typename = void>
280 struct exe : std::false_type {
281 using space = void;
282 };
283
284 template <typename, typename = void>
285 struct mem : std::false_type {
286 using space = void;
287 };
288
289 template <typename, typename = void>
290 struct dev : std::false_type {
291 using space = void;
292 };
293
294 template <typename U>
295 struct exe<U, typename std::conditional<true, void,
296 typename U::execution_space>::type>
297 : std::is_same<U, typename U::execution_space>::type {
298 using space = typename U::execution_space;
299 };
300
301 template <typename U>
302 struct mem<
303 U, typename std::conditional<true, void, typename U::memory_space>::type>
304 : std::is_same<U, typename U::memory_space>::type {
305 using space = typename U::memory_space;
306 };
307
308 template <typename U>
309 struct dev<
310 U, typename std::conditional<true, void, typename U::device_type>::type>
311 : std::is_same<U, typename U::device_type>::type {
312 using space = typename U::device_type;
313 };
314
315 using is_exe =
316 typename is_space<T>::template exe<typename std::remove_cv<T>::type>;
317 using is_mem =
318 typename is_space<T>::template mem<typename std::remove_cv<T>::type>;
319 using is_dev =
320 typename is_space<T>::template dev<typename std::remove_cv<T>::type>;
321
322 public:
323 static constexpr bool value = is_exe::value || is_mem::value || is_dev::value;
324
325 constexpr operator bool() const noexcept { return value; }
326
327 using execution_space = typename is_exe::space;
328 using memory_space = typename is_mem::space;
329
330 // For backward compatibility, deprecated in favor of
331 // Kokkos::Impl::HostMirror<S>::host_mirror_space
332
333 using host_memory_space = typename std::conditional<
334 std::is_same<memory_space, Kokkos::HostSpace>::value
335#if defined(KOKKOS_ENABLE_CUDA)
336 || std::is_same<memory_space, Kokkos::CudaUVMSpace>::value ||
337 std::is_same<memory_space, Kokkos::CudaHostPinnedSpace>::value
338#endif /* #if defined( KOKKOS_ENABLE_CUDA ) */
339 ,
340 memory_space, Kokkos::HostSpace>::type;
341
342#if defined(KOKKOS_ENABLE_CUDA)
343 using host_execution_space = typename std::conditional<
344 std::is_same<execution_space, Kokkos::Cuda>::value,
345 Kokkos::DefaultHostExecutionSpace, execution_space>::type;
346#else
347#if defined(KOKKOS_ENABLE_OPENMPTARGET)
348 using host_execution_space = typename std::conditional<
349 std::is_same<execution_space, Kokkos::Experimental::OpenMPTarget>::value,
350 Kokkos::DefaultHostExecutionSpace, execution_space>::type;
351#else
352 using host_execution_space = execution_space;
353#endif
354#endif
355
356 using host_mirror_space = typename std::conditional<
357 std::is_same<execution_space, host_execution_space>::value &&
358 std::is_same<memory_space, host_memory_space>::value,
359 T, Kokkos::Device<host_execution_space, host_memory_space>>::type;
360};
361
362// For backward compatibility
363
364namespace Impl {
365
366using Kokkos::is_space;
367
368}
369
370} // namespace Kokkos
371
372//----------------------------------------------------------------------------
373
374namespace Kokkos {
375namespace Impl {
376
382template <typename DstMemorySpace, typename SrcMemorySpace>
384 static_assert(Kokkos::is_memory_space<DstMemorySpace>::value &&
385 Kokkos::is_memory_space<SrcMemorySpace>::value,
386 "template arguments must be memory spaces");
387
395 enum { assignable = std::is_same<DstMemorySpace, SrcMemorySpace>::value };
396
400 enum { accessible = assignable };
401
405 enum { deepcopy = assignable };
406};
407
408} // namespace Impl
409} // namespace Kokkos
410
411namespace Kokkos {
412
432template <typename AccessSpace, typename MemorySpace>
434 private:
435 static_assert(Kokkos::is_space<AccessSpace>::value,
436 "template argument #1 must be a Kokkos space");
437
438 static_assert(Kokkos::is_memory_space<MemorySpace>::value,
439 "template argument #2 must be a Kokkos memory space");
440
441 // The input AccessSpace may be a Device<ExecSpace,MemSpace>
442 // verify that it is a valid combination of spaces.
444 typename AccessSpace::execution_space::memory_space,
445 typename AccessSpace::memory_space>::accessible,
446 "template argument #1 is an invalid space");
447
449 typename AccessSpace::execution_space::memory_space, MemorySpace>;
450
451 using mem_access =
452 Kokkos::Impl::MemorySpaceAccess<typename AccessSpace::memory_space,
453 MemorySpace>;
454
455 public:
461 enum { accessible = exe_access::accessible };
462
468 enum {
469 assignable = is_memory_space<AccessSpace>::value && mem_access::assignable
470 };
471
473 enum { deepcopy = mem_access::deepcopy };
474
475 // What intercessory space for AccessSpace::execution_space
476 // to be able to access MemorySpace?
477 // If same memory space or not accessible use the AccessSpace
478 // else construct a device with execution space and memory space.
479 using space = typename std::conditional<
480 std::is_same<typename AccessSpace::memory_space, MemorySpace>::value ||
481 !exe_access::accessible,
482 AccessSpace,
483 Kokkos::Device<typename AccessSpace::execution_space, MemorySpace>>::type;
484};
485
486} // namespace Kokkos
487
488namespace Kokkos {
489namespace Impl {
490
491using Kokkos::SpaceAccessibility; // For backward compatibility
492
493}
494} // namespace Kokkos
495
496//----------------------------------------------------------------------------
497
498#endif // KOKKOS_CORE_CONCEPTS_HPP
Memory management for host memory.
None
Access relationship between DstMemorySpace and SrcMemorySpace.
Specify Launch Bounds for CUDA execution.
Can AccessSpace access MemorySpace ?