|
Kokkos Core Kernels Package
Version of the Day
|
00001 00002 /* 00003 //@HEADER 00004 // ************************************************************************ 00005 // 00006 // Kokkos: Manycore Performance-Portable Multidimensional Arrays 00007 // Copyright (2012) Sandia Corporation 00008 // 00009 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 00010 // the U.S. Government retains certain rights in this software. 00011 // 00012 // Redistribution and use in source and binary forms, with or without 00013 // modification, are permitted provided that the following conditions are 00014 // met: 00015 // 00016 // 1. Redistributions of source code must retain the above copyright 00017 // notice, this list of conditions and the following disclaimer. 00018 // 00019 // 2. Redistributions in binary form must reproduce the above copyright 00020 // notice, this list of conditions and the following disclaimer in the 00021 // documentation and/or other materials provided with the distribution. 00022 // 00023 // 3. Neither the name of the Corporation nor the names of the 00024 // contributors may be used to endorse or promote products derived from 00025 // this software without specific prior written permission. 00026 // 00027 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00028 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00029 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00030 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00031 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00032 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00033 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00034 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00035 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00036 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00037 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00038 // 00039 // Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) 00040 // 00041 // ************************************************************************ 00042 //@HEADER 00043 */ 00044 00045 // Experimental unified task-data parallel manycore LDRD 00046 00047 #ifndef KOKKOS_TASKPOLICY_HPP 00048 #define KOKKOS_TASKPOLICY_HPP 00049 00050 #include <Kokkos_Core_fwd.hpp> 00051 #include <impl/Kokkos_Traits.hpp> 00052 #include <impl/Kokkos_Tags.hpp> 00053 #include <impl/Kokkos_StaticAssert.hpp> 00054 00055 //---------------------------------------------------------------------------- 00056 00057 namespace Kokkos { 00058 namespace Impl { 00059 00060 struct FutureValueTypeIsVoidError {}; 00061 00062 template< class ExecSpace > 00063 class TaskManager ; 00064 00065 template < class Policy , class ResultType = void , class Functor = void > 00066 class TaskMember ; 00067 00068 template< class ExecPolicy > 00069 struct TaskDepends { typedef typename ExecPolicy::execution_space execution_space ; }; 00070 00071 template< class ExecPolicy > 00072 struct TaskForEach { typedef typename ExecPolicy::execution_space execution_space ; }; 00073 00074 template< class ExecPolicy > 00075 struct TaskReduce { typedef typename ExecPolicy::execution_space execution_space ; }; 00076 00077 template< class ExecPolicy > 00078 struct TaskScan { typedef typename ExecPolicy::execution_space execution_space ; }; 00079 00080 } /* namespace Impl */ 00081 } /* namespace Kokkos */ 00082 00083 //---------------------------------------------------------------------------- 00084 00085 namespace Kokkos { 00086 00094 template< class Arg1 = void , class Arg2 = void > 00095 class Future { 00096 private: 00097 00098 template< class > friend class Impl::TaskManager ; 00099 template< class , class > friend class Future ; 00100 00101 // Argument #2, if not void, must be the space. 00102 enum { Arg1_is_space = Impl::is_execution_space< Arg1 >::value }; 00103 enum { Arg2_is_space = Impl::is_execution_space< Arg2 >::value }; 00104 enum { Arg2_is_void = Impl::is_same< Arg2 , void >::value }; 00105 00106 struct ErrorNoExecutionSpace {}; 00107 00108 enum { Opt1 = Arg1_is_space && Arg2_is_void 00109 , Opt2 = ! Arg1_is_space && Arg2_is_void 00110 , Opt3 = ! Arg1_is_space && Arg2_is_space 00111 , OptOK = Impl::StaticAssert< Opt1 || Opt2 || Opt3 , ErrorNoExecutionSpace >::value 00112 }; 00113 00114 typedef typename 00115 Impl::if_c< Opt2 || Opt3 , Arg1 , void >::type 00116 ValueType ; 00117 00118 typedef typename 00119 Impl::if_c< Opt1 , Arg1 , typename 00120 Impl::if_c< Opt2 , Kokkos::DefaultExecutionSpace , typename 00121 Impl::if_c< Opt3 , Arg2 , void 00122 >::type >::type >::type 00123 ExecutionSpace ; 00124 00125 typedef Impl::TaskManager< ExecutionSpace > TaskManager ; 00126 typedef Impl::TaskMember< ExecutionSpace > TaskRoot ; 00127 typedef Impl::TaskMember< ExecutionSpace , ValueType > TaskValue ; 00128 00129 TaskRoot * m_task ; 00130 00131 public: 00132 00133 typedef ValueType value_type; 00134 typedef ExecutionSpace execution_space ; 00135 00136 //---------------------------------------- 00137 00138 explicit 00139 Future( TaskRoot * task ) 00140 : m_task(0) 00141 { TaskManager::assign( & m_task , TaskValue::verify_type( task ) ); } 00142 00143 //---------------------------------------- 00144 00145 KOKKOS_INLINE_FUNCTION 00146 ~Future() { TaskManager::assign( & m_task , 0 ); } 00147 00148 //---------------------------------------- 00149 00150 KOKKOS_INLINE_FUNCTION 00151 Future() : m_task(0) {} 00152 00153 KOKKOS_INLINE_FUNCTION 00154 Future( const Future & rhs ) 00155 : m_task(0) 00156 { TaskManager::assign( & m_task , rhs.m_task ); } 00157 00158 KOKKOS_INLINE_FUNCTION 00159 Future & operator = ( const Future & rhs ) 00160 { TaskManager::assign( & m_task , rhs.m_task ); return *this ; } 00161 00162 //---------------------------------------- 00163 00164 template< class A1 , class A2 > 00165 KOKKOS_INLINE_FUNCTION 00166 Future( const Future<A1,A2> & rhs ) 00167 : m_task(0) 00168 { TaskManager::assign( & m_task , TaskValue::verify_type( rhs.m_task ) ); } 00169 00170 template< class A1 , class A2 > 00171 KOKKOS_INLINE_FUNCTION 00172 Future & operator = ( const Future<A1,A2> & rhs ) 00173 { TaskManager::assign( & m_task , TaskValue::verify_type( rhs.m_task ) ); return *this ; } 00174 00175 //---------------------------------------- 00176 00177 typedef typename TaskValue::get_result_type get_result_type ; 00178 00179 KOKKOS_INLINE_FUNCTION 00180 typename TaskValue::get_result_type get() const 00181 { return static_cast<TaskValue*>( m_task )->get(); } 00182 }; 00183 00184 } /* namespace Kokkos */ 00185 00186 //---------------------------------------------------------------------------- 00187 00188 namespace Kokkos { 00189 00191 template< class Arg0 = Kokkos::DefaultExecutionSpace > 00192 class TaskPolicy { 00193 public: 00194 00195 typedef typename Arg0::execution_space execution_space ; 00196 00197 template< class A1 , class A2 > 00198 void wait( const Future<A1,A2> & ) const ; 00199 00200 template< class FunctorType > 00201 Future< typename FunctorType::value_type , execution_space > 00202 spawn( const FunctorType & ) const ; 00203 00204 template< class FunctorType > 00205 void respawn( FunctorType * ) const ; 00206 00207 template< class FunctorType > 00208 Future< void , execution_space > 00209 get_dependence( FunctorType * ) const ; 00210 00211 template< class ValueType > 00212 TaskPolicy< void /* ... */ > 00213 depends( const Future< ValueType , execution_space > * const , const int ); 00214 00215 template< class ExecPolicy > 00216 TaskPolicy< void /* ... */ > foreach( const ExecPolicy & ); 00217 00218 template< class ExecPolicy > 00219 TaskPolicy< void /* ... */ > reduce( const ExecPolicy & ); 00220 00221 template< class ExecPolicy > 00222 TaskPolicy< void /* ... */ > scan( const ExecPolicy & ); 00223 }; 00224 00225 // spawn( M.depends(n,d).foreach(K) , functor ); 00226 // M.depends(n,d).foreach(K).spawn( functor ); 00227 00228 template< class Arg0 , class FunctorType > 00229 Future< typename FunctorType::value_type 00230 , typename Arg0::execution_space > 00231 inline 00232 spawn( const TaskPolicy< Arg0 > & policy 00233 , const FunctorType & functor ) 00234 { return policy.spawn( functor ); } 00235 00236 template< class Arg0 , class A1 , class A2 > 00237 void wait( const TaskPolicy< Arg0 > & policy 00238 , const Future<A1,A2> & future 00239 , typename Impl::enable_if< 00240 Impl::is_same< typename Arg0::execution_space 00241 , typename Future<A1,A2>::execution_space >::value 00242 >::type * = 0 ) 00243 { policy.wait( future ); } 00244 00245 } /* namespace Kokkos */ 00246 00247 //---------------------------------------------------------------------------- 00248 00249 #endif /* #define KOKKOS_TASKPOLICY_HPP */ 00250
1.7.6.1