|
Kokkos Core Kernels Package
Version of the Day
|
00001 /* 00002 //@HEADER 00003 // ************************************************************************ 00004 // 00005 // Kokkos: Manycore Performance-Portable Multidimensional Arrays 00006 // Copyright (2012) Sandia Corporation 00007 // 00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 00009 // the U.S. Government retains certain rights in this software. 00010 // 00011 // Redistribution and use in source and binary forms, with or without 00012 // modification, are permitted provided that the following conditions are 00013 // met: 00014 // 00015 // 1. Redistributions of source code must retain the above copyright 00016 // notice, this list of conditions and the following disclaimer. 00017 // 00018 // 2. Redistributions in binary form must reproduce the above copyright 00019 // notice, this list of conditions and the following disclaimer in the 00020 // documentation and/or other materials provided with the distribution. 00021 // 00022 // 3. Neither the name of the Corporation nor the names of the 00023 // contributors may be used to endorse or promote products derived from 00024 // this software without specific prior written permission. 00025 // 00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00037 // 00038 // Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) 00039 // 00040 // ************************************************************************ 00041 //@HEADER 00042 */ 00043 00044 #ifndef KOKKOS_EXECPOLICY_HPP 00045 #define KOKKOS_EXECPOLICY_HPP 00046 00047 #include <Kokkos_Core_fwd.hpp> 00048 #include <impl/Kokkos_Traits.hpp> 00049 #include <impl/Kokkos_StaticAssert.hpp> 00050 #include <impl/Kokkos_Tags.hpp> 00051 00052 //---------------------------------------------------------------------------- 00053 00054 namespace Kokkos { 00055 00077 template< class Arg0 = void , class Arg1 = void , class Arg2 = void 00078 , class ExecSpace = 00079 // The first argument is the execution space, 00080 // otherwise use the default execution space. 00081 typename Impl::if_c< Impl::is_execution_space< Arg0 >::value , Arg0 00082 , Kokkos::DefaultExecutionSpace >::type 00083 > 00084 class RangePolicy { 00085 private: 00086 00087 // Default integral type and blocking factor: 00088 typedef int DefaultIntType ; 00089 enum { DefaultIntValue = 8 }; 00090 00091 enum { Arg0_Void = Impl::is_same< Arg0 , void >::value }; 00092 enum { Arg1_Void = Impl::is_same< Arg1 , void >::value }; 00093 enum { Arg2_Void = Impl::is_same< Arg2 , void >::value }; 00094 00095 enum { Arg0_ExecSpace = Impl::is_execution_space< Arg0 >::value }; 00096 00097 enum { Arg0_IntConst = Impl::is_integral_constant< Arg0 >::value }; 00098 enum { Arg1_IntConst = Impl::is_integral_constant< Arg1 >::value }; 00099 enum { Arg2_IntConst = Impl::is_integral_constant< Arg2 >::value }; 00100 00101 enum { Arg0_IntType = Impl::is_integral< Arg0 >::value }; 00102 enum { Arg1_IntType = Impl::is_integral< Arg1 >::value }; 00103 enum { Arg2_IntType = Impl::is_integral< Arg2 >::value }; 00104 00105 enum { Arg0_WorkTag = ! Arg0_ExecSpace && ! Arg0_IntConst && ! Arg0_IntType && ! Arg0_Void }; 00106 enum { Arg1_WorkTag = Arg0_ExecSpace && ! Arg1_IntConst && ! Arg1_IntType && ! Arg1_Void }; 00107 00108 enum { ArgOption_OK = Impl::StaticAssert< ( 00109 ( Arg0_ExecSpace && Arg1_WorkTag && ( Arg2_IntConst || Arg2_IntType ) ) || 00110 ( Arg0_ExecSpace && Arg1_WorkTag && Arg2_Void ) || 00111 ( Arg0_ExecSpace && ( Arg1_IntConst || Arg2_IntType ) && Arg2_Void ) || 00112 ( Arg0_ExecSpace && Arg1_Void && Arg2_Void ) || 00113 ( Arg0_WorkTag && ( Arg1_IntConst || Arg2_IntType ) && Arg2_Void ) || 00114 ( Arg0_WorkTag && Arg1_Void && Arg2_Void ) || 00115 ( ( Arg0_IntConst || Arg0_IntType ) && Arg1_Void && Arg2_Void ) || 00116 ( Arg0_Void && Arg1_Void && Arg2_Void ) 00117 ) >::value }; 00118 00119 // The work argument tag is the first or second argument 00120 typedef typename Impl::if_c< Arg0_WorkTag , Arg0 , 00121 typename Impl::if_c< Arg1_WorkTag , Arg1 , void 00122 >::type >::type 00123 WorkTag ; 00124 00125 enum { Granularity = Arg0_IntConst ? unsigned(Impl::is_integral_constant<Arg0>::integral_value) : ( 00126 Arg1_IntConst ? unsigned(Impl::is_integral_constant<Arg1>::integral_value) : ( 00127 Arg2_IntConst ? unsigned(Impl::is_integral_constant<Arg2>::integral_value) : ( 00128 unsigned(DefaultIntValue) ))) }; 00129 00130 // Only accept the integral type if the blocking is a power of two 00131 typedef typename Impl::enable_if< Impl::is_power_of_two< Granularity >::value , 00132 typename Impl::if_c< Arg0_IntType , Arg0 , 00133 typename Impl::if_c< Arg1_IntType , Arg1 , 00134 typename Impl::if_c< Arg2_IntType , Arg2 , 00135 typename Impl::if_c< Arg0_IntConst , typename Impl::is_integral_constant<Arg0>::integral_type , 00136 typename Impl::if_c< Arg1_IntConst , typename Impl::is_integral_constant<Arg1>::integral_type , 00137 typename Impl::if_c< Arg2_IntConst , typename Impl::is_integral_constant<Arg2>::integral_type , 00138 DefaultIntType 00139 >::type >::type >::type 00140 >::type >::type >::type 00141 >::type 00142 IntType ; 00143 00144 enum { GranularityMask = IntType(Granularity) - 1 }; 00145 00146 IntType m_begin ; 00147 IntType m_end ; 00148 00149 public: 00150 00151 typedef Impl::ExecutionPolicyTag kokkos_tag ; 00152 typedef ExecSpace execution_space ; 00153 typedef RangePolicy execution_policy ; 00154 typedef IntType member_type ; 00155 typedef WorkTag work_tag ; 00156 00157 KOKKOS_INLINE_FUNCTION member_type begin() const { return m_begin ; } 00158 KOKKOS_INLINE_FUNCTION member_type end() const { return m_end ; } 00159 00160 KOKKOS_INLINE_FUNCTION RangePolicy() : m_begin(0), m_end(0) {} 00161 00163 KOKKOS_INLINE_FUNCTION 00164 RangePolicy( const member_type work_begin 00165 , const member_type work_end 00166 ) 00167 : m_begin( work_begin < work_end ? work_begin : 0 ) 00168 , m_end( work_begin < work_end ? work_end : 0 ) 00169 {} 00170 00175 KOKKOS_INLINE_FUNCTION 00176 RangePolicy( const RangePolicy & range 00177 , const int part_rank 00178 , const int part_size 00179 ) 00180 : m_begin(0), m_end(0) 00181 { 00182 if ( part_size ) { 00183 00184 // Split evenly among partitions, then round up to the granularity. 00185 const member_type work_part = 00186 ( ( ( ( range.m_end - range.m_begin ) + ( part_size - 1 ) ) / part_size ) + GranularityMask ) & ~member_type(GranularityMask); 00187 00188 m_begin = range.m_begin + work_part * part_rank ; 00189 m_end = m_begin + work_part ; 00190 00191 if ( range.m_end < m_begin ) m_begin = range.m_end ; 00192 if ( range.m_end < m_end ) m_end = range.m_end ; 00193 } 00194 } 00195 }; 00196 00197 } // namespace Kokkos 00198 00199 //---------------------------------------------------------------------------- 00200 //---------------------------------------------------------------------------- 00201 00202 namespace Kokkos { 00203 00224 template< class Arg0 = void 00225 , class Arg1 = void 00226 , class ExecSpace = 00227 // If the first argument is not an execution 00228 // then use the default execution space. 00229 typename Impl::if_c< Impl::is_execution_space< Arg0 >::value , Arg0 00230 , Kokkos::DefaultExecutionSpace >::type 00231 > 00232 class TeamPolicy { 00233 private: 00234 00235 enum { Arg0_ExecSpace = Impl::is_execution_space< Arg0 >::value }; 00236 enum { Arg1_Void = Impl::is_same< Arg1 , void >::value }; 00237 enum { ArgOption_OK = Impl::StaticAssert< ( Arg0_ExecSpace || Arg1_Void ) >::value }; 00238 00239 typedef typename Impl::if_c< Arg0_ExecSpace , Arg1 , Arg0 >::type WorkTag ; 00240 00241 public: 00242 00243 typedef Impl::ExecutionPolicyTag kokkos_tag ; 00244 typedef ExecSpace execution_space ; 00245 typedef TeamPolicy execution_policy ; 00246 typedef WorkTag work_tag ; 00247 00254 template< class FunctorType > 00255 static int team_size_max( const FunctorType & ); 00256 00258 TeamPolicy( execution_space & , int league_size_request , int team_size_request ); 00259 00261 TeamPolicy( int league_size_request , int team_size_request ); 00262 00268 KOKKOS_INLINE_FUNCTION int league_size() const ; 00269 00275 KOKKOS_INLINE_FUNCTION int team_size() const ; 00276 00280 struct member_type { 00281 00283 KOKKOS_INLINE_FUNCTION 00284 typename execution_space::scratch_memory_space team_shmem() const ; 00285 00287 KOKKOS_INLINE_FUNCTION int league_rank() const ; 00288 00290 KOKKOS_INLINE_FUNCTION int league_size() const ; 00291 00293 KOKKOS_INLINE_FUNCTION int team_rank() const ; 00294 00296 KOKKOS_INLINE_FUNCTION int team_size() const ; 00297 00299 KOKKOS_INLINE_FUNCTION void team_barrier() const ; 00300 00302 template< class JoinOp > 00303 KOKKOS_INLINE_FUNCTION 00304 typename JoinOp::value_type team_reduce( const typename JoinOp::value_type 00305 , const JoinOp & ) const ; 00306 00312 template< typename Type > 00313 KOKKOS_INLINE_FUNCTION Type team_scan( const Type & value ) const ; 00314 00324 template< typename Type > 00325 KOKKOS_INLINE_FUNCTION Type team_scan( const Type & value , Type * const global_accum ) const ; 00326 }; 00327 }; 00328 00329 } // namespace Kokkos 00330 00331 //---------------------------------------------------------------------------- 00332 //---------------------------------------------------------------------------- 00333 00334 namespace Kokkos { 00335 00349 template< unsigned VectorLength 00350 , class Arg0 = void 00351 , class Arg1 = void 00352 , class ExecSpace = 00353 // If the second argument is not an execution 00354 // then use the default execution space. 00355 typename Impl::if_c< Impl::is_execution_space< Arg0 >::value , Arg0 00356 , Kokkos::DefaultExecutionSpace >::type 00357 > 00358 class TeamVectorPolicy { 00359 private: 00360 enum { Arg0_ExecSpace = Impl::is_execution_space< Arg0 >::value }; 00361 enum { Arg1_Void = Impl::is_same< Arg1 , void >::value }; 00362 enum { ArgOption_OK = Impl::StaticAssert< ( Arg0_ExecSpace || Arg1_Void ) >::value }; 00363 00364 typedef typename Impl::if_c< Arg0_ExecSpace , Arg1 , Arg0 >::type WorkTag ; 00365 00366 public: 00367 00368 typedef Impl::ExecutionPolicyTag kokkos_tag ; 00369 typedef ExecSpace execution_space ; 00370 typedef TeamVectorPolicy execution_policy ; 00371 typedef WorkTag work_tag ; 00372 00379 template< class FunctorType > 00380 static int team_size_max( const FunctorType & ); 00381 00383 TeamVectorPolicy( execution_space & , int league_size_request , int team_size_request ); 00384 00386 TeamVectorPolicy( int league_size_request , int team_size_request ); 00387 00393 KOKKOS_INLINE_FUNCTION int league_size() const ; 00394 00400 KOKKOS_INLINE_FUNCTION int team_size() const ; 00401 00405 struct member_type { 00406 00408 KOKKOS_INLINE_FUNCTION 00409 typename execution_space::scratch_memory_space team_shmem() const ; 00410 00412 KOKKOS_INLINE_FUNCTION int league_rank() const ; 00413 00415 KOKKOS_INLINE_FUNCTION int league_size() const ; 00416 00418 KOKKOS_INLINE_FUNCTION int team_rank() const ; 00419 00421 KOKKOS_INLINE_FUNCTION int team_size() const ; 00422 00424 KOKKOS_INLINE_FUNCTION void team_barrier() const ; 00425 00427 template< class JoinOp > 00428 KOKKOS_INLINE_FUNCTION 00429 typename JoinOp::value_type team_reduce( const typename JoinOp::value_type 00430 , const JoinOp & ) const ; 00431 00437 template< typename Type > 00438 KOKKOS_INLINE_FUNCTION Type team_scan( const Type & value ) const ; 00439 00449 template< typename Type > 00450 KOKKOS_INLINE_FUNCTION Type team_scan( const Type & value , Type * const global_accum ) const ; 00451 00452 #ifdef KOKKOS_HAVE_CXX11 00453 00457 //template< typename iType, class Operation, typename ValueType > 00458 //KOKKOS_INLINE_FUNCTION void team_par_for(const iType n, const Operation & op) const ; 00459 00464 //template< typename iType, class Operation, typename ValueType > 00465 //KOKKOS_INLINE_FUNCTION void team_par_reduce(const iType n, const Operation & op, ValueType& result) const ; 00466 00471 //template< typename iType, class Operation, typename ValueType, class JoinType > 00472 //KOKKOS_INLINE_FUNCTION void team_par_reduce(const iType n, const Operation & op, ValueType& result, const JoinType & join) const ; 00473 00484 //template< typename iType, class Operation, typename ValueType > 00485 //KOKKOS_INLINE_FUNCTION void team_par_scan(const iType n, const Operation & op, ValueType& scan_val) const ; 00486 00488 template< class Operation > 00489 KOKKOS_INLINE_FUNCTION void vector_single(const Operation & op) const ; 00490 00495 template< typename iType, class Operation> 00496 KOKKOS_INLINE_FUNCTION void vector_par_for(const iType n, const Operation & op) const ; 00497 00502 template< typename iType, class Operation, typename ValueType > 00503 KOKKOS_INLINE_FUNCTION void vector_par_reduce(const iType n, const Operation & op, ValueType& result) const ; 00504 00512 template< typename iType, class Operation, typename ValueType, class JoinType > 00513 KOKKOS_INLINE_FUNCTION void vector_par_reduce(const iType n, const Operation & op, ValueType& init_result, const JoinType & join) const ; 00514 00525 template< typename iType, class Operation, typename ValueType > 00526 KOKKOS_INLINE_FUNCTION void vector_par_scan(const iType n, const Operation & op, ValueType& scan_val) const ; 00527 #endif 00528 }; 00529 }; 00530 00531 } // namespace Kokkos 00532 00533 #endif /* #define KOKKOS_EXECPOLICY_HPP */ 00534 00535 //---------------------------------------------------------------------------- 00536 //---------------------------------------------------------------------------- 00537
1.7.6.1