typename std::enable_if< std::is_same< agency::detail::execution_policy_execution_category_t<ExecutionPolicy>, parallel_execution_tag >::value, cuda::parallel_execution_policy >::type replace_executor(const ExecutionPolicy& policy, const cuda::parallel_executor& exec) { return cuda::parallel_execution_policy(policy.param(), exec); }
basic_execution_policy< typename ExecutionPolicy::execution_agent_type, Executor > replace_executor(const ExecutionPolicy& policy, const Executor& exec) { using policy_category = detail::execution_policy_execution_category_t<ExecutionPolicy>; using executor_category = executor_execution_category_t<Executor>; static_assert(detail::is_weaker_than<policy_category, executor_category>::value, "replace_executor(): Execution policy's forward progress requirements cannot be satisfied by executor's guarantees."); using result_type = basic_execution_policy< typename ExecutionPolicy::execution_agent_type, Executor >; return result_type(policy.param(), exec); }
bulk_async_execution_policy_result_t< ExecutionPolicy, Function, Args... > bulk_async_execution_policy(index_sequence<UserArgIndices...>, index_sequence<SharedArgIndices...>, ExecutionPolicy& policy, Function f, Args&&... args) { using agent_type = typename ExecutionPolicy::execution_agent_type; using agent_traits = execution_agent_traits<agent_type>; using execution_category = typename agent_traits::execution_category; // get the parameters of the agent auto param = policy.param(); auto agent_shape = agent_traits::domain(param).shape(); // this is a tuple of factories // each factory in the tuple creates the execution agent's shared parameter at the corresponding hierarchy level auto agent_shared_parameter_factory_tuple = detail::make_agent_shared_parameter_factory_tuple<agent_type>(param); using executor_type = typename ExecutionPolicy::executor_type; // convert the shape of the agent into the type of the executor's shape using executor_shape_type = executor_shape_t<executor_type>; executor_shape_type executor_shape = detail::shape_cast<executor_shape_type>(agent_shape); // create the function that will marshal parameters received from bulk_invoke(executor) and execute the agent auto lambda = execute_agent_functor<executor_type,agent_traits,Function,UserArgIndices...>{param, agent_shape, executor_shape, f}; return detail::bulk_async_executor( policy.executor(), executor_shape, lambda, std::forward<Args>(args)..., agency::share_at_scope_from_factory<SharedArgIndices>(detail::get<SharedArgIndices>(agent_shared_parameter_factory_tuple))... ); }
void test(ExecutionPolicy policy) { using agent = typename ExecutionPolicy::execution_agent_type; using agent_traits = agency::execution_agent_traits<agent>; { // bulk_async with no parameters auto f = agency::bulk_async(policy, [](agent& self) { return 7; }); auto result = f.get(); using executor_type = typename ExecutionPolicy::executor_type; using container_type = agency::executor_container_t<executor_type,int>; auto shape = agent_traits::domain(policy.param()).shape(); assert(container_type(shape,7) == result); } { // bulk_async with one parameter int val = 13; auto f = agency::bulk_async(policy, [](agent& self, int val) { return val; }, val ); auto result = f.get(); using executor_type = typename ExecutionPolicy::executor_type; using container_type = agency::executor_container_t<executor_type,int>; auto shape = agent_traits::domain(policy.param()).shape(); assert(container_type(shape,val) == result); } { // bulk_async with one shared parameter int val = 13; auto f = agency::bulk_async(policy, [](agent& self, int& val) { return val; }, agency::share(val) ); auto result = f.get(); using executor_type = typename ExecutionPolicy::executor_type; using container_type = agency::executor_container_t<executor_type,int>; auto shape = agent_traits::domain(policy.param()).shape(); assert(container_type(shape,val) == result); } }