Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
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 
56 namespace Kokkos {
57 
58 // Schedules for Execution Policies
59 struct Static {};
60 struct Dynamic {};
61 
62 // Schedule Wrapper Type
63 template <class T>
64 struct 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
73 template <typename T>
74 struct IndexType {
75  static_assert(std::is_integral<T>::value, "Kokkos: Invalid IndexType<>.");
76  using index_type = IndexType;
77  using type = T;
78 };
79 
80 namespace Experimental {
81 struct 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  typedef ImplWorkItemProperty<0> None_t;
99  typedef ImplWorkItemProperty<1> HintLightWeight_t;
100  typedef ImplWorkItemProperty<2> HintHeavyWeight_t;
101  typedef ImplWorkItemProperty<4> HintRegular_t;
102  typedef ImplWorkItemProperty<8> HintIrregular_t;
103 };
104 
105 template <unsigned long pv1, unsigned long pv2>
106 inline constexpr WorkItemProperty::ImplWorkItemProperty<pv1 | pv2> operator|(
107  WorkItemProperty::ImplWorkItemProperty<pv1>,
108  WorkItemProperty::ImplWorkItemProperty<pv2>) {
109  return WorkItemProperty::ImplWorkItemProperty<pv1 | pv2>();
110 }
111 
112 template <unsigned long pv1, unsigned long pv2>
113 inline constexpr WorkItemProperty::ImplWorkItemProperty<pv1 & pv2> operator&(
114  WorkItemProperty::ImplWorkItemProperty<pv1>,
115  WorkItemProperty::ImplWorkItemProperty<pv2>) {
116  return WorkItemProperty::ImplWorkItemProperty<pv1 & pv2>();
117 }
118 
119 template <unsigned long pv1, unsigned long pv2>
120 inline constexpr bool operator==(WorkItemProperty::ImplWorkItemProperty<pv1>,
121  WorkItemProperty::ImplWorkItemProperty<pv2>) {
122  return pv1 == pv2;
123 }
124 
125 } // namespace Experimental
126 
131 template <unsigned int maxT = 0 /* Max threads per block */
132  ,
133  unsigned int minB = 0 /* Min blocks per SM */
134  >
135 struct LaunchBounds {
136  using launch_bounds = LaunchBounds;
138  static unsigned int constexpr maxTperB{maxT};
139  static unsigned int constexpr minBperSM{minB};
140 };
141 
142 } // namespace Kokkos
143 
144 //----------------------------------------------------------------------------
145 //----------------------------------------------------------------------------
146 
147 namespace 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 
171 KOKKOS_IMPL_IS_CONCEPT(memory_space)
172 KOKKOS_IMPL_IS_CONCEPT(memory_traits)
173 KOKKOS_IMPL_IS_CONCEPT(execution_space)
174 KOKKOS_IMPL_IS_CONCEPT(execution_policy)
175 KOKKOS_IMPL_IS_CONCEPT(array_layout)
176 KOKKOS_IMPL_IS_CONCEPT(reducer)
177 namespace Experimental {
178 KOKKOS_IMPL_IS_CONCEPT(work_item_property)
179 }
180 
181 namespace Impl {
182 
183 // For backward compatibility:
184 
185 using Kokkos::is_array_layout;
186 using Kokkos::is_execution_policy;
187 using Kokkos::is_execution_space;
188 using Kokkos::is_memory_space;
189 using Kokkos::is_memory_traits;
190 
191 // Implementation concept:
192 
193 KOKKOS_IMPL_IS_CONCEPT(iteration_pattern)
194 KOKKOS_IMPL_IS_CONCEPT(schedule_type)
195 KOKKOS_IMPL_IS_CONCEPT(index_type)
196 KOKKOS_IMPL_IS_CONCEPT(launch_bounds)
197 KOKKOS_IMPL_IS_CONCEPT(thread_team_member)
198 KOKKOS_IMPL_IS_CONCEPT(host_thread_team_member)
199 
200 } // namespace Impl
201 
202 #undef KOKKOS_IMPL_IS_CONCEPT
203 
204 } // namespace Kokkos
205 
206 namespace Kokkos {
207 namespace Impl {
208 
209 template <class Object>
210 class has_member_team_shmem_size {
211  template <typename T>
212  static int32_t test_for_member(decltype(&T::team_shmem_size)) {
213  return int32_t(0);
214  }
215  template <typename T>
216  static int64_t test_for_member(...) {
217  return int64_t(0);
218  }
219 
220  public:
221  constexpr static bool value =
222  sizeof(test_for_member<Object>(0)) == sizeof(int32_t);
223 };
224 
225 template <class Object>
226 class has_member_shmem_size {
227  template <typename T>
228  static int32_t test_for_member(decltype(&T::shmem_size_me)) {
229  return int32_t(0);
230  }
231  template <typename T>
232  static int64_t test_for_member(...) {
233  return int64_t(0);
234  }
235 
236  public:
237  constexpr static bool value =
238  sizeof(test_for_member<Object>(0)) == sizeof(int32_t);
239 };
240 
241 } // namespace Impl
242 } // namespace Kokkos
243 //----------------------------------------------------------------------------
244 
245 namespace Kokkos {
246 
247 template <class ExecutionSpace, class MemorySpace>
248 struct Device {
249  static_assert(Kokkos::is_execution_space<ExecutionSpace>::value,
250  "Execution space is not valid");
251  static_assert(Kokkos::is_memory_space<MemorySpace>::value,
252  "Memory space is not valid");
253  typedef ExecutionSpace execution_space;
254  typedef MemorySpace memory_space;
255  typedef Device<execution_space, memory_space> device_type;
256 };
257 
258 namespace Impl {
259 
260 template <typename T>
261 struct is_device_helper : std::false_type {};
262 
263 template <typename ExecutionSpace, typename MemorySpace>
264 struct is_device_helper<Device<ExecutionSpace, MemorySpace>> : std::true_type {
265 };
266 
267 } // namespace Impl
268 
269 template <typename T>
270 using is_device =
271  typename Impl::is_device_helper<typename std::remove_cv<T>::type>::type;
272 
273 //----------------------------------------------------------------------------
274 
275 template <typename T>
276 struct is_space {
277  private:
278  template <typename, typename = void>
279  struct exe : std::false_type {
280  typedef void space;
281  };
282 
283  template <typename, typename = void>
284  struct mem : std::false_type {
285  typedef void space;
286  };
287 
288  template <typename, typename = void>
289  struct dev : std::false_type {
290  typedef void space;
291  };
292 
293  template <typename U>
294  struct exe<U, typename std::conditional<true, void,
295  typename U::execution_space>::type>
296  : std::is_same<U, typename U::execution_space>::type {
297  typedef typename U::execution_space space;
298  };
299 
300  template <typename U>
301  struct mem<
302  U, typename std::conditional<true, void, typename U::memory_space>::type>
303  : std::is_same<U, typename U::memory_space>::type {
304  typedef typename U::memory_space space;
305  };
306 
307  template <typename U>
308  struct dev<
309  U, typename std::conditional<true, void, typename U::device_type>::type>
310  : std::is_same<U, typename U::device_type>::type {
311  typedef typename U::device_type space;
312  };
313 
314  typedef typename is_space::template exe<typename std::remove_cv<T>::type>
315  is_exe;
316  typedef typename is_space::template mem<typename std::remove_cv<T>::type>
317  is_mem;
318  typedef typename is_space::template dev<typename std::remove_cv<T>::type>
319  is_dev;
320 
321  public:
322  static constexpr bool value = is_exe::value || is_mem::value || is_dev::value;
323 
324  constexpr operator bool() const noexcept { return value; }
325 
326  typedef typename is_exe::space execution_space;
327  typedef typename is_mem::space memory_space;
328 
329  // For backward compatibility, deprecated in favor of
330  // Kokkos::Impl::HostMirror<S>::host_mirror_space
331 
332  typedef typename std::conditional<
333  std::is_same<memory_space, Kokkos::HostSpace>::value
334 #if defined(KOKKOS_ENABLE_CUDA)
335  || std::is_same<memory_space, Kokkos::CudaUVMSpace>::value ||
336  std::is_same<memory_space, Kokkos::CudaHostPinnedSpace>::value
337 #endif /* #if defined( KOKKOS_ENABLE_CUDA ) */
338  ,
339  memory_space, Kokkos::HostSpace>::type host_memory_space;
340 
341 #if defined(KOKKOS_ENABLE_CUDA)
342  typedef typename std::conditional<
343  std::is_same<execution_space, Kokkos::Cuda>::value,
344  Kokkos::DefaultHostExecutionSpace, execution_space>::type
345  host_execution_space;
346 #else
347 #if defined(KOKKOS_ENABLE_OPENMPTARGET)
348  typedef typename std::conditional<
349  std::is_same<execution_space, Kokkos::Experimental::OpenMPTarget>::value,
350  Kokkos::DefaultHostExecutionSpace, execution_space>::type
351  host_execution_space;
352 #else
353  typedef execution_space host_execution_space;
354 #endif
355 #endif
356 
357  typedef typename std::conditional<
358  std::is_same<execution_space, host_execution_space>::value &&
359  std::is_same<memory_space, host_memory_space>::value,
360  T, Kokkos::Device<host_execution_space, host_memory_space>>::type
361  host_mirror_space;
362 };
363 
364 // For backward compatibility
365 
366 namespace Impl {
367 
368 using Kokkos::is_space;
369 
370 }
371 
372 } // namespace Kokkos
373 
374 //----------------------------------------------------------------------------
375 
376 namespace Kokkos {
377 namespace Impl {
378 
384 template <typename DstMemorySpace, typename SrcMemorySpace>
386  static_assert(Kokkos::is_memory_space<DstMemorySpace>::value &&
387  Kokkos::is_memory_space<SrcMemorySpace>::value,
388  "template arguments must be memory spaces");
389 
397  enum { assignable = std::is_same<DstMemorySpace, SrcMemorySpace>::value };
398 
402  enum { accessible = assignable };
403 
407  enum { deepcopy = assignable };
408 };
409 
410 } // namespace Impl
411 } // namespace Kokkos
412 
413 namespace Kokkos {
414 
434 template <typename AccessSpace, typename MemorySpace>
436  private:
437  static_assert(Kokkos::is_space<AccessSpace>::value,
438  "template argument #1 must be a Kokkos space");
439 
440  static_assert(Kokkos::is_memory_space<MemorySpace>::value,
441  "template argument #2 must be a Kokkos memory space");
442 
443  // The input AccessSpace may be a Device<ExecSpace,MemSpace>
444  // verify that it is a valid combination of spaces.
445  static_assert(Kokkos::Impl::MemorySpaceAccess<
446  typename AccessSpace::execution_space::memory_space,
447  typename AccessSpace::memory_space>::accessible,
448  "template argument #1 is an invalid space");
449 
451  typename AccessSpace::execution_space::memory_space, MemorySpace>
452  exe_access;
453 
454  typedef Kokkos::Impl::MemorySpaceAccess<typename AccessSpace::memory_space,
455  MemorySpace>
456  mem_access;
457 
458  public:
464  enum { accessible = exe_access::accessible };
465 
471  enum {
472  assignable = is_memory_space<AccessSpace>::value && mem_access::assignable
473  };
474 
476  enum { deepcopy = mem_access::deepcopy };
477 
478  // What intercessory space for AccessSpace::execution_space
479  // to be able to access MemorySpace?
480  // If same memory space or not accessible use the AccessSpace
481  // else construct a device with execution space and memory space.
482  typedef typename std::conditional<
483  std::is_same<typename AccessSpace::memory_space, MemorySpace>::value ||
484  !exe_access::accessible,
485  AccessSpace,
486  Kokkos::Device<typename AccessSpace::execution_space, MemorySpace>>::type
487  space;
488 };
489 
490 } // namespace Kokkos
491 
492 namespace Kokkos {
493 namespace Impl {
494 
495 using Kokkos::SpaceAccessibility; // For backward compatibility
496 
497 }
498 } // namespace Kokkos
499 
500 //----------------------------------------------------------------------------
501 
502 #endif // KOKKOS_CORE_CONCEPTS_HPP
KOKKOS_INLINE_FUNCTION bool operator==(complex< RealType1 > const &x, complex< RealType2 > const &y) noexcept
Binary == operator for complex complex.
Can AccessSpace access MemorySpace ?
Memory management for host memory.
Specify Launch Bounds for CUDA execution.
Access relationship between DstMemorySpace and SrcMemorySpace.