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))... ); }