47 #ifndef KOKKOS_TASKPOLICY_HPP 48 #define KOKKOS_TASKPOLICY_HPP 50 #include <Kokkos_Core_fwd.hpp> 51 #include <impl/Kokkos_Traits.hpp> 52 #include <impl/Kokkos_Tags.hpp> 53 #include <impl/Kokkos_StaticAssert.hpp> 54 #include <impl/Kokkos_AllocationTracker.hpp> 62 struct FutureValueTypeIsVoidError {};
64 template <
class ExecSpace ,
class ResultType ,
class FunctorType >
67 template<
class ExecPolicy ,
class ResultType ,
class FunctorType >
70 template<
class ExecPolicy ,
class ResultType ,
class FunctorType >
73 template<
class ExecPolicy ,
class ResultType ,
class FunctorType >
88 , TASK_STATE_CONSTRUCTING = 1
89 , TASK_STATE_WAITING = 2
90 , TASK_STATE_EXECUTING = 4
91 , TASK_STATE_COMPLETE = 8
101 template<
class Arg1 =
void ,
class Arg2 =
void >
105 template<
class ,
class ,
class >
friend class Impl::TaskMember ;
107 template<
class ,
class >
friend class Future ;
110 enum { Arg1_is_space = Kokkos::Impl::is_execution_space< Arg1 >::value };
111 enum { Arg2_is_space = Kokkos::Impl::is_execution_space< Arg2 >::value };
112 enum { Arg2_is_void = Kokkos::Impl::is_same< Arg2 , void >::value };
114 struct ErrorNoExecutionSpace {};
116 enum { Opt1 = Arg1_is_space && Arg2_is_void
117 , Opt2 = ! Arg1_is_space && Arg2_is_void
118 , Opt3 = ! Arg1_is_space && Arg2_is_space
119 , OptOK = Kokkos::Impl::StaticAssert< Opt1 || Opt2 || Opt3 , ErrorNoExecutionSpace >::value
123 Kokkos::Impl::if_c< Opt2 || Opt3 , Arg1 , void >::type
127 Kokkos::Impl::if_c< Opt1 , Arg1 ,
typename 128 Kokkos::Impl::if_c< Opt2 , Kokkos::DefaultExecutionSpace ,
typename 129 Kokkos::Impl::if_c< Opt3 , Arg2 ,
void 130 >::type >::type >::type
133 typedef Impl::TaskMember< ExecutionSpace , void , void > TaskRoot ;
134 typedef Impl::TaskMember< ExecutionSpace , ValueType , void > TaskValue ;
140 typedef ValueType value_type;
141 typedef ExecutionSpace execution_space ;
145 KOKKOS_INLINE_FUNCTION
146 TaskState get_task_state()
const 147 {
return 0 != m_task ? m_task->get_state() : TASK_STATE_NULL ; }
154 { TaskRoot::assign( & m_task , TaskRoot::template verify_type< value_type >( task ) ); }
158 KOKKOS_INLINE_FUNCTION
159 ~
Future() { TaskRoot::assign( & m_task , 0 ); }
163 KOKKOS_INLINE_FUNCTION
166 KOKKOS_INLINE_FUNCTION
167 Future(
const Future & rhs )
169 { TaskRoot::assign( & m_task , rhs.m_task ); }
171 KOKKOS_INLINE_FUNCTION
172 Future & operator = (
const Future & rhs )
173 { TaskRoot::assign( & m_task , rhs.m_task );
return *this ; }
177 template<
class A1 ,
class A2 >
178 KOKKOS_INLINE_FUNCTION
181 { TaskRoot::assign( & m_task , TaskRoot::template verify_type< value_type >( rhs.m_task ) ); }
183 template<
class A1 ,
class A2 >
184 KOKKOS_INLINE_FUNCTION
186 { TaskRoot::assign( & m_task , TaskRoot::template verify_type< value_type >( rhs.m_task ) );
return *this ; }
190 typedef typename TaskValue::get_result_type get_result_type ;
192 KOKKOS_INLINE_FUNCTION
193 get_result_type
get()
const 194 {
return static_cast<TaskValue*
>( m_task )->
get(); }
200 struct is_future :
public Kokkos::Impl::bool_< false > {};
202 template<
class Arg0 ,
class Arg1 >
203 struct is_future< Kokkos::
Experimental::Future<Arg0,Arg1> > :
public Kokkos::Impl::bool_< true > {};
216 template<
class Arg0 = Kokkos::DefaultExecutionSpace >
220 typedef typename Arg0::execution_space execution_space ;
227 template<
class FunctorType >
229 create(
const FunctorType & functor
230 ,
const unsigned dependence_capacity )
const ;
233 template<
class ExecPolicy ,
class FunctorType >
235 create_foreach(
const ExecPolicy & policy
236 ,
const FunctorType & functor
237 ,
const unsigned dependence_capacity )
const ;
240 template<
class ExecPolicy ,
class FunctorType >
242 create_reduce(
const ExecPolicy & policy
243 ,
const FunctorType & functor
244 ,
const unsigned dependence_capacity )
const ;
247 template<
class ExecPolicy ,
class FunctorType >
249 create_scan(
const ExecPolicy & policy
250 ,
const FunctorType & functor
251 ,
const unsigned dependence_capacity )
const ;
258 template<
class TA ,
class TB >
274 template<
class FunctorType >
276 get_dependence( FunctorType * ,
const int )
const ;
285 template<
class FunctorType >
286 void clear_dependence( FunctorType * )
const ;
293 template<
class FunctorType ,
class TB >
294 void set_dependence( FunctorType * after
300 template<
class FunctorType >
301 void respawn( FunctorType * )
const ;
306 template<
class ExecSpace ,
class FunctorType >
310 {
return policy.
spawn( policy.
create( functor ) ); }
313 template<
class ExecSpace ,
class FunctorType ,
class Arg0 ,
class Arg1 >
317 ,
const FunctorType & functor
322 f = policy.
create( functor , 2 );
323 policy.add_dependence( f , before_0 );
324 policy.add_dependence( f , before_1 );
331 template<
class ExecSpace ,
class ParallelPolicyType ,
class FunctorType >
335 ,
const ParallelPolicyType & parallel_policy
336 ,
const FunctorType & functor )
340 template<
class ExecSpace ,
class ParallelPolicyType ,
class FunctorType >
344 ,
const ParallelPolicyType & parallel_policy
345 ,
const FunctorType & functor )
346 {
return task_policy.
spawn( task_policy.
create_reduce( parallel_policy , functor ) ); }
350 template<
class ExecSpace ,
class FunctorType ,
class Arg0 ,
class Arg1 >
353 , FunctorType * functor
359 policy.add_dependence( functor , before_0 );
360 policy.add_dependence( functor , before_1 );
366 template<
class ExecSpace >
Future< typename FunctorType::value_type, execution_space > create(const FunctorType &functor, const unsigned dependence_capacity) const
Create a serial task with storage for dependences.
void respawn(FunctorType *) const
Respawn (reschedule) an executing task to be called again after all dependences have completed...
Future< typename FunctorType::value_type, execution_space > create_foreach(const ExecPolicy &policy, const FunctorType &functor, const unsigned dependence_capacity) const
Create a foreach task with storage for dependences.
void clear_dependence(FunctorType *) const
Clear current dependences of an executing task in preparation for setting new dependences and respawn...
const Future< T, execution_space > & spawn(const Future< T, execution_space > &) const
Spawn a task in the 'Constructing' state.
If the argument is an execution space then a serial task in that space.
Future< typename FunctorType::value_type, execution_space > create_reduce(const ExecPolicy &policy, const FunctorType &functor, const unsigned dependence_capacity) const
Create a reduce task with storage for dependences.