Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends
Kokkos_ExecPolicy.hpp
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends