Kokkos Core Kernels Package  Version of the Day
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 
86 template< unsigned int maxT = 0 /* Max threads per block */
87  , unsigned int minB = 0 /* Min blocks per SM */
88  >
90 {
93  static unsigned int constexpr maxTperB {maxT};
94  static unsigned int constexpr minBperSM {minB};
95 };
96 
97 } // namespace Kokkos
98 
99 //----------------------------------------------------------------------------
100 //----------------------------------------------------------------------------
101 
102 namespace Kokkos {
103 
104 #define KOKKOS_IMPL_IS_CONCEPT( CONCEPT ) \
105  template< typename T > struct is_ ## CONCEPT { \
106  private: \
107  template< typename , typename = std::true_type > struct have : std::false_type {}; \
108  template< typename U > struct have<U,typename std::is_same<U,typename U:: CONCEPT >::type> : std::true_type {}; \
109  public: \
110  enum { value = is_ ## CONCEPT::template have<T>::value }; \
111  };
112 
113 // Public concept:
114 
115 KOKKOS_IMPL_IS_CONCEPT( memory_space )
116 KOKKOS_IMPL_IS_CONCEPT( memory_traits )
117 KOKKOS_IMPL_IS_CONCEPT( execution_space )
118 KOKKOS_IMPL_IS_CONCEPT( execution_policy )
119 KOKKOS_IMPL_IS_CONCEPT( array_layout )
120 KOKKOS_IMPL_IS_CONCEPT( reducer )
121 
122 namespace Impl {
123 
124 // For backward compatibility:
125 
126 using Kokkos::is_memory_space ;
127 using Kokkos::is_memory_traits ;
128 using Kokkos::is_execution_space ;
129 using Kokkos::is_execution_policy ;
130 using Kokkos::is_array_layout ;
131 
132 // Implementation concept:
133 
134 KOKKOS_IMPL_IS_CONCEPT( iteration_pattern )
135 KOKKOS_IMPL_IS_CONCEPT( schedule_type )
136 KOKKOS_IMPL_IS_CONCEPT( index_type )
137 KOKKOS_IMPL_IS_CONCEPT( launch_bounds )
138 
139 }
140 
141 #undef KOKKOS_IMPL_IS_CONCEPT
142 
143 } // namespace Kokkos
144 
145 //----------------------------------------------------------------------------
146 
147 namespace Kokkos {
148 
149 template< class ExecutionSpace , class MemorySpace >
150 struct Device {
151  static_assert( Kokkos::is_execution_space<ExecutionSpace>::value
152  , "Execution space is not valid" );
153  static_assert( Kokkos::is_memory_space<MemorySpace>::value
154  , "Memory space is not valid" );
155  typedef ExecutionSpace execution_space;
156  typedef MemorySpace memory_space;
157  typedef Device<execution_space,memory_space> device_type;
158 };
159 
160 
161 template< typename T >
162 struct is_space {
163 private:
164 
165  template< typename , typename = void >
166  struct exe : std::false_type { typedef void space ; };
167 
168  template< typename , typename = void >
169  struct mem : std::false_type { typedef void space ; };
170 
171  template< typename , typename = void >
172  struct dev : std::false_type { typedef void space ; };
173 
174  template< typename U >
175  struct exe<U,typename std::conditional<true,void,typename U::execution_space>::type>
176  : std::is_same<U,typename U::execution_space>::type
177  { typedef typename U::execution_space space ; };
178 
179  template< typename U >
180  struct mem<U,typename std::conditional<true,void,typename U::memory_space>::type>
181  : std::is_same<U,typename U::memory_space>::type
182  { typedef typename U::memory_space space ; };
183 
184  template< typename U >
185  struct dev<U,typename std::conditional<true,void,typename U::device_type>::type>
186  : std::is_same<U,typename U::device_type>::type
187  { typedef typename U::device_type space ; };
188 
189  typedef typename is_space::template exe<T> is_exe ;
190  typedef typename is_space::template mem<T> is_mem ;
191  typedef typename is_space::template dev<T> is_dev ;
192 
193 public:
194 
195  enum { value = is_exe::value || is_mem::value || is_dev::value };
196 
197  typedef typename is_exe::space execution_space ;
198  typedef typename is_mem::space memory_space ;
199 
200  // For backward compatibility, deprecated in favor of
201  // Kokkos::Impl::HostMirror<S>::host_mirror_space
202 
203  typedef typename std::conditional
204  < std::is_same< memory_space , Kokkos::HostSpace >::value
205 #if defined( KOKKOS_ENABLE_CUDA )
206  || std::is_same< memory_space , Kokkos::CudaUVMSpace >::value
207  || std::is_same< memory_space , Kokkos::CudaHostPinnedSpace >::value
208 #endif /* #if defined( KOKKOS_ENABLE_CUDA ) */
209  , memory_space
211  >::type host_memory_space ;
212 
213 #if defined( KOKKOS_ENABLE_CUDA )
214  typedef typename std::conditional
215  < std::is_same< execution_space , Kokkos::Cuda >::value
216  , Kokkos::DefaultHostExecutionSpace , execution_space
217  >::type host_execution_space ;
218 #else
219  #if defined( KOKKOS_ENABLE_OPENMPTARGET )
220  typedef typename std::conditional
221  < std::is_same< execution_space , Kokkos::Experimental::OpenMPTarget >::value
222  , Kokkos::DefaultHostExecutionSpace , execution_space
223  >::type host_execution_space ;
224  #else
225  typedef execution_space host_execution_space ;
226  #endif
227 #endif
228 
229  typedef typename std::conditional
230  < std::is_same< execution_space , host_execution_space >::value &&
231  std::is_same< memory_space , host_memory_space >::value
232  , T , Kokkos::Device< host_execution_space , host_memory_space >
233  >::type host_mirror_space ;
234 };
235 
236 // For backward compatiblity
237 
238 namespace Impl {
239 
240 using Kokkos::is_space ;
241 
242 }
243 
244 } // namespace Kokkos
245 
246 //----------------------------------------------------------------------------
247 
248 namespace Kokkos {
249 namespace Impl {
250 
256 template< typename DstMemorySpace , typename SrcMemorySpace >
258 
259  static_assert( Kokkos::is_memory_space< DstMemorySpace >::value &&
260  Kokkos::is_memory_space< SrcMemorySpace >::value
261  , "template arguments must be memory spaces" );
262 
270  enum { assignable = std::is_same<DstMemorySpace,SrcMemorySpace>::value };
271 
275  enum { accessible = assignable };
276 
280  enum { deepcopy = assignable };
281 };
282 
283 }} // namespace Kokkos::Impl
284 
285 namespace Kokkos {
286 
306 template< typename AccessSpace , typename MemorySpace >
308 private:
309 
310  static_assert( Kokkos::is_space< AccessSpace >::value
311  , "template argument #1 must be a Kokkos space" );
312 
313  static_assert( Kokkos::is_memory_space< MemorySpace >::value
314  , "template argument #2 must be a Kokkos memory space" );
315 
316  // The input AccessSpace may be a Device<ExecSpace,MemSpace>
317  // verify that it is a valid combination of spaces.
318  static_assert( Kokkos::Impl::MemorySpaceAccess
319  < typename AccessSpace::execution_space::memory_space
320  , typename AccessSpace::memory_space
321  >::accessible
322  , "template argument #1 is an invalid space" );
323 
325  < typename AccessSpace::execution_space::memory_space , MemorySpace >
326  exe_access ;
327 
329  < typename AccessSpace::memory_space , MemorySpace >
330  mem_access ;
331 
332 public:
333 
339  enum { accessible = exe_access::accessible };
340 
346  enum { assignable =
347  is_memory_space< AccessSpace >::value && mem_access::assignable };
348 
350  enum { deepcopy = mem_access::deepcopy };
351 
352  // What intercessory space for AccessSpace::execution_space
353  // to be able to access MemorySpace?
354  // If same memory space or not accessible use the AccessSpace
355  // else construct a device with execution space and memory space.
356  typedef typename std::conditional
357  < std::is_same<typename AccessSpace::memory_space,MemorySpace>::value ||
358  ! exe_access::accessible
359  , AccessSpace
360  , Kokkos::Device< typename AccessSpace::execution_space , MemorySpace >
361  >::type space ;
362 };
363 
364 } // namespace Kokkos
365 
366 namespace Kokkos {
367 namespace Impl {
368 
369 using Kokkos::SpaceAccessibility ; // For backward compatibility
370 
371 }} // namespace Kokkos::Impl
372 
373 //----------------------------------------------------------------------------
374 
375 #endif // KOKKOS_CORE_CONCEPTS_HPP
376 
Can AccessSpace access MemorySpace ?
Memory management for host memory.
Specify Launch Bounds for CUDA execution.
Access relationship between DstMemorySpace and SrcMemorySpace.