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. 2.0
6 // Copyright (2014) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Christian R. Trott (crtrott@sandia.gov)
39 //
40 // ************************************************************************
41 //@HEADER
42 */
43 
44 #ifndef KOKKOS_CORE_CONCEPTS_HPP
45 #define KOKKOS_CORE_CONCEPTS_HPP
46 
47 #include <type_traits>
48 
49 // Needed for 'is_space<S>::host_mirror_space
50 #include <Kokkos_Core_fwd.hpp>
51 
52 //----------------------------------------------------------------------------
53 //----------------------------------------------------------------------------
54 
55 namespace Kokkos {
56 
57 //Schedules for Execution Policies
58 struct Static {};
59 struct Dynamic {};
60 
61 //Schedule Wrapper Type
62 template<class T>
63 struct Schedule
64 {
65  static_assert( std::is_same<T,Static>::value
66  || std::is_same<T,Dynamic>::value
67  , "Kokkos: Invalid Schedule<> type."
68  );
69  using schedule_type = Schedule ;
70  using type = T;
71 };
72 
73 //Specify Iteration Index Type
74 template<typename T>
75 struct IndexType
76 {
77  static_assert(std::is_integral<T>::value,"Kokkos: Invalid IndexType<>.");
78  using index_type = IndexType ;
79  using type = T;
80 };
81 
82 namespace Experimental {
83  struct WorkItemProperty {
84  template<unsigned long Property>
85  struct ImplWorkItemProperty {
86  static const unsigned value = Property;
87  using work_item_property = ImplWorkItemProperty<Property>;
88  };
89 
90  constexpr static const ImplWorkItemProperty<0> None = ImplWorkItemProperty<0>();
91  constexpr static const ImplWorkItemProperty<1> HintLightWeight = ImplWorkItemProperty<1>();
92  constexpr static const ImplWorkItemProperty<2> HintHeavyWeight = ImplWorkItemProperty<2>();
93  constexpr static const ImplWorkItemProperty<4> HintRegular = ImplWorkItemProperty<4>();
94  constexpr static const ImplWorkItemProperty<8> HintIrregular = ImplWorkItemProperty<8>();
95  typedef ImplWorkItemProperty<0> None_t;
96  typedef ImplWorkItemProperty<1> HintLightWeight_t;
97  typedef ImplWorkItemProperty<2> HintHeavyWeight_t;
98  typedef ImplWorkItemProperty<4> HintRegular_t;
99  typedef ImplWorkItemProperty<8> HintIrregular_t;
100  };
101 
102 template<unsigned long pv1, unsigned long pv2>
103 inline constexpr WorkItemProperty::ImplWorkItemProperty<pv1|pv2> operator |
104  (WorkItemProperty::ImplWorkItemProperty<pv1>, WorkItemProperty::ImplWorkItemProperty<pv2>) {
105  return WorkItemProperty::ImplWorkItemProperty<pv1|pv2>();
106 }
107 
108 template<unsigned long pv1, unsigned long pv2>
109 inline constexpr WorkItemProperty::ImplWorkItemProperty<pv1&pv2> operator &
110  (WorkItemProperty::ImplWorkItemProperty<pv1>, WorkItemProperty::ImplWorkItemProperty<pv2>) {
111  return WorkItemProperty::ImplWorkItemProperty<pv1&pv2>();
112 }
113 
114 template<unsigned long pv1, unsigned long pv2>
115 inline constexpr bool operator == (WorkItemProperty::ImplWorkItemProperty<pv1>, WorkItemProperty::ImplWorkItemProperty<pv2>) {
116  return pv1 == pv2;
117 }
118 
119 }
120 
125 template< unsigned int maxT = 0 /* Max threads per block */
126  , unsigned int minB = 0 /* Min blocks per SM */
127  >
129 {
130  using launch_bounds = LaunchBounds;
132  static unsigned int constexpr maxTperB {maxT};
133  static unsigned int constexpr minBperSM {minB};
134 };
135 
136 } // namespace Kokkos
137 
138 //----------------------------------------------------------------------------
139 //----------------------------------------------------------------------------
140 
141 namespace Kokkos {
142 
143 #define KOKKOS_IMPL_IS_CONCEPT( CONCEPT ) \
144  template< typename T > struct is_ ## CONCEPT { \
145  private: \
146  template< typename , typename = std::true_type > struct have : std::false_type {}; \
147  template< typename U > struct have<U,typename std::is_base_of< \
148  typename std::remove_cv<typename U:: CONCEPT>::type, \
149  typename std::remove_cv<U>::type \
150  >::type> : std::true_type {}; \
151  template< typename U > struct have<U,typename std::is_base_of< \
152  typename std::remove_cv<typename U:: CONCEPT ## _type>::type, \
153  typename std::remove_cv<U>::type \
154  >::type> : std::true_type {}; \
155  public: \
156  enum { value = is_ ## CONCEPT::template have<T>::value }; \
157  };
158 
159 // Public concept:
160 
161 KOKKOS_IMPL_IS_CONCEPT( memory_space )
162 KOKKOS_IMPL_IS_CONCEPT( memory_traits )
163 KOKKOS_IMPL_IS_CONCEPT( execution_space )
164 KOKKOS_IMPL_IS_CONCEPT( execution_policy )
165 KOKKOS_IMPL_IS_CONCEPT( array_layout )
166 KOKKOS_IMPL_IS_CONCEPT( reducer )
167 namespace Experimental {
168 KOKKOS_IMPL_IS_CONCEPT( work_item_property )
169 }
170 
171 namespace Impl {
172 
173 // For backward compatibility:
174 
175 using Kokkos::is_memory_space ;
176 using Kokkos::is_memory_traits ;
177 using Kokkos::is_execution_space ;
178 using Kokkos::is_execution_policy ;
179 using Kokkos::is_array_layout ;
180 
181 // Implementation concept:
182 
183 KOKKOS_IMPL_IS_CONCEPT( iteration_pattern )
184 KOKKOS_IMPL_IS_CONCEPT( schedule_type )
185 KOKKOS_IMPL_IS_CONCEPT( index_type )
186 KOKKOS_IMPL_IS_CONCEPT( launch_bounds )
187 KOKKOS_IMPL_IS_CONCEPT( thread_team_member )
188 KOKKOS_IMPL_IS_CONCEPT( host_thread_team_member )
189 
190 }
191 
192 #undef KOKKOS_IMPL_IS_CONCEPT
193 
194 } // namespace Kokkos
195 
196 //----------------------------------------------------------------------------
197 
198 namespace Kokkos {
199 
200 template< class ExecutionSpace , class MemorySpace >
201 struct Device {
202  static_assert( Kokkos::is_execution_space<ExecutionSpace>::value
203  , "Execution space is not valid" );
204  static_assert( Kokkos::is_memory_space<MemorySpace>::value
205  , "Memory space is not valid" );
206  typedef ExecutionSpace execution_space;
207  typedef MemorySpace memory_space;
208  typedef Device<execution_space,memory_space> device_type;
209 };
210 
211 
212 template< typename T >
213 struct is_space {
214 private:
215 
216  template< typename , typename = void >
217  struct exe : std::false_type { typedef void space ; };
218 
219  template< typename , typename = void >
220  struct mem : std::false_type { typedef void space ; };
221 
222  template< typename , typename = void >
223  struct dev : std::false_type { typedef void space ; };
224 
225  template< typename U >
226  struct exe<U,typename std::conditional<true,void,typename U::execution_space>::type>
227  : std::is_same<U,typename U::execution_space>::type
228  { typedef typename U::execution_space space ; };
229 
230  template< typename U >
231  struct mem<U,typename std::conditional<true,void,typename U::memory_space>::type>
232  : std::is_same<U,typename U::memory_space>::type
233  { typedef typename U::memory_space space ; };
234 
235  template< typename U >
236  struct dev<U,typename std::conditional<true,void,typename U::device_type>::type>
237  : std::is_same<U,typename U::device_type>::type
238  { typedef typename U::device_type space ; };
239 
240  typedef typename is_space::template exe<T> is_exe ;
241  typedef typename is_space::template mem<T> is_mem ;
242  typedef typename is_space::template dev<T> is_dev ;
243 
244 public:
245 
246  enum { value = is_exe::value || is_mem::value || is_dev::value };
247 
248  typedef typename is_exe::space execution_space ;
249  typedef typename is_mem::space memory_space ;
250 
251  // For backward compatibility, deprecated in favor of
252  // Kokkos::Impl::HostMirror<S>::host_mirror_space
253 
254  typedef typename std::conditional
255  < std::is_same< memory_space , Kokkos::HostSpace >::value
256 #if defined( KOKKOS_ENABLE_CUDA )
257  || std::is_same< memory_space , Kokkos::CudaUVMSpace >::value
258  || std::is_same< memory_space , Kokkos::CudaHostPinnedSpace >::value
259 #endif /* #if defined( KOKKOS_ENABLE_CUDA ) */
260  , memory_space
262  >::type host_memory_space ;
263 
264 #if defined( KOKKOS_ENABLE_CUDA )
265  typedef typename std::conditional
266  < std::is_same< execution_space , Kokkos::Cuda >::value
267  , Kokkos::DefaultHostExecutionSpace , execution_space
268  >::type host_execution_space ;
269 #else
270  #if defined( KOKKOS_ENABLE_OPENMPTARGET )
271  typedef typename std::conditional
272  < std::is_same< execution_space , Kokkos::Experimental::OpenMPTarget >::value
273  , Kokkos::DefaultHostExecutionSpace , execution_space
274  >::type host_execution_space ;
275  #else
276  typedef execution_space host_execution_space ;
277  #endif
278 #endif
279 
280  typedef typename std::conditional
281  < std::is_same< execution_space , host_execution_space >::value &&
282  std::is_same< memory_space , host_memory_space >::value
283  , T , Kokkos::Device< host_execution_space , host_memory_space >
284  >::type host_mirror_space ;
285 };
286 
287 // For backward compatiblity
288 
289 namespace Impl {
290 
291 using Kokkos::is_space ;
292 
293 }
294 
295 } // namespace Kokkos
296 
297 //----------------------------------------------------------------------------
298 
299 namespace Kokkos {
300 namespace Impl {
301 
307 template< typename DstMemorySpace , typename SrcMemorySpace >
309 
310  static_assert( Kokkos::is_memory_space< DstMemorySpace >::value &&
311  Kokkos::is_memory_space< SrcMemorySpace >::value
312  , "template arguments must be memory spaces" );
313 
321  enum { assignable = std::is_same<DstMemorySpace,SrcMemorySpace>::value };
322 
326  enum { accessible = assignable };
327 
331  enum { deepcopy = assignable };
332 };
333 
334 }} // namespace Kokkos::Impl
335 
336 namespace Kokkos {
337 
357 template< typename AccessSpace , typename MemorySpace >
359 private:
360 
361  static_assert( Kokkos::is_space< AccessSpace >::value
362  , "template argument #1 must be a Kokkos space" );
363 
364  static_assert( Kokkos::is_memory_space< MemorySpace >::value
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.
369  static_assert( Kokkos::Impl::MemorySpaceAccess
370  < typename AccessSpace::execution_space::memory_space
371  , typename AccessSpace::memory_space
372  >::accessible
373  , "template argument #1 is an invalid space" );
374 
376  < typename AccessSpace::execution_space::memory_space , MemorySpace >
377  exe_access ;
378 
380  < typename AccessSpace::memory_space , MemorySpace >
381  mem_access ;
382 
383 public:
384 
390  enum { accessible = exe_access::accessible };
391 
397  enum { assignable =
398  is_memory_space< AccessSpace >::value && mem_access::assignable };
399 
401  enum { deepcopy = mem_access::deepcopy };
402 
403  // What intercessory space for AccessSpace::execution_space
404  // to be able to access MemorySpace?
405  // If same memory space or not accessible use the AccessSpace
406  // else construct a device with execution space and memory space.
407  typedef typename std::conditional
408  < std::is_same<typename AccessSpace::memory_space,MemorySpace>::value ||
409  ! exe_access::accessible
410  , AccessSpace
411  , Kokkos::Device< typename AccessSpace::execution_space , MemorySpace >
412  >::type space ;
413 };
414 
415 } // namespace Kokkos
416 
417 namespace Kokkos {
418 namespace Impl {
419 
420 using Kokkos::SpaceAccessibility ; // For backward compatibility
421 
422 }} // namespace Kokkos::Impl
423 
424 //----------------------------------------------------------------------------
425 
426 #endif // KOKKOS_CORE_CONCEPTS_HPP
427 
KOKKOS_INLINE_FUNCTION bool operator==(const complex< RealType1 > &x, const complex< RealType2 > &y)
Equality operator for two complex numbers.
Can AccessSpace access MemorySpace ?
Memory management for host memory.
Specify Launch Bounds for CUDA execution.
Access relationship between DstMemorySpace and SrcMemorySpace.