Kokkos Core Kernels Package Version of the Day
Loading...
Searching...
No Matches
Kokkos_Concepts.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_CORE_CONCEPTS_HPP
23#define KOKKOS_CORE_CONCEPTS_HPP
24
25#include <type_traits>
26
27// Needed for 'is_space<S>::host_mirror_space
28#include <Kokkos_Core_fwd.hpp>
29
30#include <Kokkos_DetectionIdiom.hpp>
31
32//----------------------------------------------------------------------------
33//----------------------------------------------------------------------------
34
35namespace Kokkos {
36
37// Schedules for Execution Policies
38struct Static {};
39struct Dynamic {};
40
41// Schedule Wrapper Type
42template <class T>
43struct Schedule {
44 static_assert(std::is_same_v<T, Static> || std::is_same_v<T, Dynamic>,
45 "Kokkos: Invalid Schedule<> type.");
46 using schedule_type = Schedule;
47 using type = T;
48};
49
50// Specify Iteration Index Type
51template <typename T>
52struct IndexType {
53 static_assert(std::is_integral_v<T>, "Kokkos: Invalid IndexType<>.");
54 using index_type = IndexType;
55 using type = T;
56};
57
58namespace Experimental {
59struct WorkItemProperty {
60 template <unsigned long Property>
61 struct ImplWorkItemProperty {
62 static const unsigned value = Property;
63 using work_item_property = ImplWorkItemProperty<Property>;
64 };
65
66 constexpr static const ImplWorkItemProperty<0> None =
67 ImplWorkItemProperty<0>();
68 constexpr static const ImplWorkItemProperty<1> HintLightWeight =
69 ImplWorkItemProperty<1>();
70 constexpr static const ImplWorkItemProperty<2> HintHeavyWeight =
71 ImplWorkItemProperty<2>();
72 constexpr static const ImplWorkItemProperty<4> HintRegular =
73 ImplWorkItemProperty<4>();
74 constexpr static const ImplWorkItemProperty<8> HintIrregular =
75 ImplWorkItemProperty<8>();
76 constexpr static const ImplWorkItemProperty<16> ImplForceGlobalLaunch =
77 ImplWorkItemProperty<16>();
78 using None_t = ImplWorkItemProperty<0>;
79 using HintLightWeight_t = ImplWorkItemProperty<1>;
80 using HintHeavyWeight_t = ImplWorkItemProperty<2>;
81 using HintRegular_t = ImplWorkItemProperty<4>;
82 using HintIrregular_t = ImplWorkItemProperty<8>;
83 using ImplForceGlobalLaunch_t = ImplWorkItemProperty<16>;
84};
85
86template <unsigned long pv1, unsigned long pv2>
87inline constexpr WorkItemProperty::ImplWorkItemProperty<pv1 | pv2> operator|(
88 WorkItemProperty::ImplWorkItemProperty<pv1>,
89 WorkItemProperty::ImplWorkItemProperty<pv2>) {
90 return WorkItemProperty::ImplWorkItemProperty<pv1 | pv2>();
91}
92
93template <unsigned long pv1, unsigned long pv2>
94inline constexpr WorkItemProperty::ImplWorkItemProperty<pv1 & pv2> operator&(
95 WorkItemProperty::ImplWorkItemProperty<pv1>,
96 WorkItemProperty::ImplWorkItemProperty<pv2>) {
97 return WorkItemProperty::ImplWorkItemProperty<pv1 & pv2>();
98}
99
100template <unsigned long pv1, unsigned long pv2>
101inline constexpr bool operator==(WorkItemProperty::ImplWorkItemProperty<pv1>,
102 WorkItemProperty::ImplWorkItemProperty<pv2>) {
103 return pv1 == pv2;
104}
105
106} // namespace Experimental
107
112template <unsigned int maxT = 0 /* Max threads per block */
113 ,
114 unsigned int minB = 0 /* Min blocks per SM */
115 >
119 static constexpr unsigned int maxTperB{maxT};
120 static constexpr unsigned int minBperSM{minB};
121};
122
123} // namespace Kokkos
124
125//----------------------------------------------------------------------------
126//----------------------------------------------------------------------------
127
128namespace Kokkos {
129
130#define KOKKOS_IMPL_IS_CONCEPT(CONCEPT) \
131 template <typename T> \
132 struct is_##CONCEPT { \
133 private: \
134 template <typename U> \
135 using have_t = typename U::CONCEPT; \
136 template <typename U> \
137 using have_type_t = typename U::CONCEPT##_type; \
138 \
139 public: \
140 static constexpr bool value = \
141 std::is_base_of_v<detected_t<have_t, T>, T> || \
142 std::is_base_of_v<detected_t<have_type_t, T>, T>; \
143 constexpr operator bool() const noexcept { return value; } \
144 }; \
145 template <typename T> \
146 inline constexpr bool is_##CONCEPT##_v = is_##CONCEPT<T>::value;
147
148// Public concept:
149
150KOKKOS_IMPL_IS_CONCEPT(memory_space)
151KOKKOS_IMPL_IS_CONCEPT(memory_traits)
152KOKKOS_IMPL_IS_CONCEPT(execution_space)
153KOKKOS_IMPL_IS_CONCEPT(execution_policy)
154KOKKOS_IMPL_IS_CONCEPT(array_layout)
155KOKKOS_IMPL_IS_CONCEPT(reducer)
156KOKKOS_IMPL_IS_CONCEPT(team_handle)
157namespace Experimental {
158KOKKOS_IMPL_IS_CONCEPT(work_item_property)
159KOKKOS_IMPL_IS_CONCEPT(hooks_policy)
160} // namespace Experimental
161
162namespace Impl {
163
164// Implementation concept:
165
166KOKKOS_IMPL_IS_CONCEPT(thread_team_member)
167KOKKOS_IMPL_IS_CONCEPT(host_thread_team_member)
168KOKKOS_IMPL_IS_CONCEPT(graph_kernel)
169
170} // namespace Impl
171
172#undef KOKKOS_IMPL_IS_CONCEPT
173
174} // namespace Kokkos
175
176namespace Kokkos {
177namespace Impl {
178
179template <class Object>
180class has_member_team_shmem_size {
181 template <typename T>
182 static int32_t test_for_member(decltype(&T::team_shmem_size)) {
183 return int32_t(0);
184 }
185 template <typename T>
186 static int64_t test_for_member(...) {
187 return int64_t(0);
188 }
189
190 public:
191 constexpr static bool value =
192 sizeof(test_for_member<Object>(nullptr)) == sizeof(int32_t);
193};
194
195template <class Object>
196class has_member_shmem_size {
197 template <typename T>
198 static int32_t test_for_member(decltype(&T::shmem_size_me)) {
199 return int32_t(0);
200 }
201 template <typename T>
202 static int64_t test_for_member(...) {
203 return int64_t(0);
204 }
205
206 public:
207 constexpr static bool value =
208 sizeof(test_for_member<Object>(0)) == sizeof(int32_t);
209};
210
211} // namespace Impl
212} // namespace Kokkos
213//----------------------------------------------------------------------------
214
215namespace Kokkos {
216
217template <class ExecutionSpace, class MemorySpace>
218struct Device {
220 "Execution space is not valid");
222 "Memory space is not valid");
223 using execution_space = ExecutionSpace;
224 using memory_space = MemorySpace;
225 using device_type = Device<execution_space, memory_space>;
226};
227
228namespace Impl {
229
230template <typename T>
231struct is_device_helper : std::false_type {};
232
233template <typename ExecutionSpace, typename MemorySpace>
234struct is_device_helper<Device<ExecutionSpace, MemorySpace>> : std::true_type {
235};
236
237} // namespace Impl
238
239template <typename T>
240using is_device = typename Impl::is_device_helper<std::remove_cv_t<T>>::type;
241
242template <typename T>
243inline constexpr bool is_device_v = is_device<T>::value;
244
245//----------------------------------------------------------------------------
246
247template <typename T>
248struct is_space {
249 private:
250 template <typename, typename = void>
251 struct exe : std::false_type {
252 using space = void;
253 };
254
255 template <typename, typename = void>
256 struct mem : std::false_type {
257 using space = void;
258 };
259
260 template <typename, typename = void>
261 struct dev : std::false_type {
262 using space = void;
263 };
264
265 template <typename U>
266 struct exe<U, std::conditional_t<true, void, typename U::execution_space>>
267 : std::is_same<U, typename U::execution_space>::type {
268 using space = typename U::execution_space;
269 };
270
271 template <typename U>
272 struct mem<U, std::conditional_t<true, void, typename U::memory_space>>
273 : std::is_same<U, typename U::memory_space>::type {
274 using space = typename U::memory_space;
275 };
276
277 template <typename U>
278 struct dev<U, std::conditional_t<true, void, typename U::device_type>>
279 : std::is_same<U, typename U::device_type>::type {
280 using space = typename U::device_type;
281 };
282
283 using is_exe = typename is_space<T>::template exe<std::remove_cv_t<T>>;
284 using is_mem = typename is_space<T>::template mem<std::remove_cv_t<T>>;
285 using is_dev = typename is_space<T>::template dev<std::remove_cv_t<T>>;
286
287 public:
288 static constexpr bool value = is_exe::value || is_mem::value || is_dev::value;
289
290 constexpr operator bool() const noexcept { return value; }
291
292 using execution_space = typename is_exe::space;
293 using memory_space = typename is_mem::space;
294};
295
296} // namespace Kokkos
297
298//----------------------------------------------------------------------------
299
300namespace Kokkos {
301namespace Impl {
302
308template <typename DstMemorySpace, typename SrcMemorySpace>
312 "template arguments must be memory spaces");
313
321 enum { assignable = std::is_same_v<DstMemorySpace, SrcMemorySpace> };
322
326 enum { accessible = assignable };
327
331 enum { deepcopy = assignable };
332};
333
334} // namespace Impl
335} // namespace Kokkos
336
337namespace Kokkos {
338
358template <typename AccessSpace, typename MemorySpace>
360 private:
361 static_assert(Kokkos::is_space<AccessSpace>::value,
362 "template argument #1 must be a Kokkos space");
363
365 "template argument #2 must be a Kokkos memory space");
366
367 // The input AccessSpace may be a Device<ExecSpace,MemSpace>
368 // verify that it is a valid combination of spaces.
370 typename AccessSpace::execution_space::memory_space,
371 typename AccessSpace::memory_space>::accessible,
372 "template argument #1 is an invalid space");
373
375 typename AccessSpace::execution_space::memory_space, MemorySpace>;
376
377 using mem_access =
378 Kokkos::Impl::MemorySpaceAccess<typename AccessSpace::memory_space,
380
381 public:
387 enum { accessible = exe_access::accessible };
388
394 enum {
395 assignable = is_memory_space<AccessSpace>::value && mem_access::assignable
396 };
397
399 enum { deepcopy = mem_access::deepcopy };
400
401 // What intercessory space for AccessSpace::execution_space
402 // to be able to access MemorySpace?
403 // If same memory space or not accessible use the AccessSpace
404 // else construct a device with execution space and memory space.
405 using space = std::conditional_t<
406 std::is_same_v<typename AccessSpace::memory_space, MemorySpace> ||
407 !exe_access::accessible,
410};
411
412} // namespace Kokkos
413
414//----------------------------------------------------------------------------
415
416#endif // KOKKOS_CORE_CONCEPTS_HPP
A thread safe view to a bitset.
None
Access relationship between DstMemorySpace and SrcMemorySpace.
Specify Launch Bounds for CUDA execution.
Can AccessSpace access MemorySpace ?