Back to Taskflow

Taskflow: A General

docs/task__group_8hpp_source.html

4.1.021.2 KB
Original Source

| | Taskflow: A General-purpose Task-parallel Programming System |

Loading...

Searching...

No Matches

task_group.hpp

1#pragma once

2

3#include "executor.hpp"

4

5namespace tf {

6

7// ------------------------------------------------------------------------------------------------

8// class: TaskGroup

9// ------------------------------------------------------------------------------------------------

10

61class TaskGroup {

62

63friend class Executor;

64

65public:

66

67// ----------------------------------------------------------------------------------------------

68// deleted members

69// ----------------------------------------------------------------------------------------------

70

74TaskGroup(const TaskGroup&) = delete;

75

79TaskGroup(TaskGroup&&) = delete;

80

84TaskGroup& operator =(TaskGroup&&) = delete;

85

89TaskGroup& operator =(const TaskGroup&) = delete;

90

103 Executor& executor();

104

105// ----------------------------------------------------------------------------------------------

106// async methods

107// ----------------------------------------------------------------------------------------------

108

141template <typename F>

142auto async(F&& f);

143

165template <typename P, typename F>

166auto async(P&& params, F&& f);

167

168// ----------------------------------------------------------------------------------------------

169// silent async methods

170// ----------------------------------------------------------------------------------------------

171

194template <typename F>

195void silent_async(F&& f);

196

215template <typename P, typename F>

216void silent_async(P&& params, F&& f);

217

218// ----------------------------------------------------------------------------------------------

219// dependent async methods

220// ----------------------------------------------------------------------------------------------

221

257template <typename F, typename... Tasks>

258requires (std::same_as<std::decay_t<Tasks>, AsyncTask> && ...)

259auto dependent_async(F&& func, Tasks&&... tasks);

260

300template <TaskParamsLike P, typename F, typename... Tasks>

301requires (std::same_as<std::decay_t<Tasks>, AsyncTask> && ...)

302auto dependent_async(P&& params, F&& func, Tasks&&... tasks);

303

342template <typename F, typename I>

343requires (!std::same_as<std::decay_t<I>, AsyncTask>)

344auto dependent_async(F&& func, I first, I last);

345

388template <TaskParamsLike P, typename F, typename I>

389requires (!std::same_as<std::decay_t<I>, AsyncTask>)

390auto dependent_async(P&& params, F&& func, I first, I last);

391

392

393// ----------------------------------------------------------------------------------------------

394// silent dependent async methods

395// ----------------------------------------------------------------------------------------------

396

425template <typename F, typename... Tasks>

426requires (std::same_as<std::decay_t<Tasks>, AsyncTask> && ...)

427tf::AsyncTask silent_dependent_async(F&& func, Tasks&&... tasks);

428

461template <TaskParamsLike P, typename F, typename... Tasks>

462requires (std::same_as<std::decay_t<Tasks>, AsyncTask> && ...)

463tf::AsyncTask silent_dependent_async(P&& params, F&& func, Tasks&&... tasks);

464

498template <typename F, typename I>

499requires (!std::same_as<std::decay_t<I>, AsyncTask>)

500tf::AsyncTask silent_dependent_async(F&& func, I first, I last);

501

537template <TaskParamsLike P, typename F, typename I>

538requires (!std::same_as<std::decay_t<I>, AsyncTask>)

539tf::AsyncTask silent_dependent_async(P&& params, F&& func, I first, I last);

540

541

542// ----------------------------------------------------------------------------------------------

543// cooperative execution methods

544// ----------------------------------------------------------------------------------------------

545

578void corun();

579

636void cancel();

637

661bool is_cancelled();

662

687size_t size() const;

688

689private:

690

694explicit TaskGroup(Executor&, Worker&);

695

699 Executor& _executor;

700

704Worker& _worker;

705

709 NodeBase _node_base;

710};

711

712// constructor

713inline TaskGroup::TaskGroup(Executor& executor, Worker& worker) :

714 _executor {executor},

715 _worker {worker},

716 _node_base {NSTATE::IMPLICITLY_ANCHORED, ESTATE::NONE, nullptr, 0} {

717}

718

719// Function: executor

720inline Executor& TaskGroup::executor() {

721return _executor;

722}

723

724// Function: corun

725inline void TaskGroup::corun() {

726 {

727 ExplicitAnchorGuard anchor(&_node_base);

728 _executor._corun_until(_worker, [this] () -> bool {

729return _node_base._join_counter.load(std::memory_order_acquire) == 0;

730 });

731 }

732 _node_base._rethrow_exception();

733}

734

735// Function: cancel

736inline void TaskGroup::cancel() {

737 _node_base._estate.fetch_or(ESTATE::CANCELLED, std::memory_order_relaxed);

738}

739

740// Function: is_cancelled

741inline bool TaskGroup::is_cancelled() {

742return _node_base._estate.load(std::memory_order_relaxed) & ESTATE::CANCELLED;

743}

744

745// Function: size

746inline size_t TaskGroup::size() const {

747return _node_base._join_counter.load(std::memory_order_relaxed);

748}

749

750// ------------------------------------------------------------------------------------------------

751// TaskGroup::silent_async

752// ------------------------------------------------------------------------------------------------

753

754// Function: silent_async

755template <typename F>

756void TaskGroup::silent_async(F&& f) {

757silent_async(DefaultTaskParams{}, std::forward<F>(f));

758}

759

760// Function: silent_async

761template <typename P, typename F>

762void TaskGroup::silent_async(P&& params, F&& f) {

763 _node_base._join_counter.fetch_add(1, std::memory_order_relaxed);

764 _executor._silent_async(

765 std::forward<P>(params), std::forward<F>(f), nullptr, &_node_base

766 );

767}

768

769// ------------------------------------------------------------------------------------------------

770// TaskGroup::async

771// ------------------------------------------------------------------------------------------------

772

773// Function: async

774template <typename F>

775auto TaskGroup::async(F&& f) {

776return async(DefaultTaskParams{}, std::forward<F>(f));

777}

778

779// Function: async

780template <typename P, typename F>

781auto TaskGroup::async(P&& params, F&& f) {

782 _node_base._join_counter.fetch_add(1, std::memory_order_relaxed);

783return _executor._async(

784 std::forward<P>(params), std::forward<F>(f), nullptr, &_node_base

785 );

786}

787

788// ------------------------------------------------------------------------------------------------

789// silent dependent async

790// ------------------------------------------------------------------------------------------------

791

792// Function: silent_dependent_async

793template <typename F, typename... Tasks>

794requires (std::same_as<std::decay_t<Tasks>, AsyncTask> && ...)

795tf::AsyncTask TaskGroup::silent_dependent_async(F&& func, Tasks&&... tasks) {

796return silent_dependent_async(

797DefaultTaskParams{}, std::forward<F>(func), std::forward<Tasks>(tasks)...

798 );

799}

800

801// Function: silent_dependent_async

802template <TaskParamsLike P, typename F, typename... Tasks>

803requires (std::same_as<std::decay_t<Tasks>, AsyncTask> && ...)

804tf::AsyncTask TaskGroup::silent_dependent_async(

805 P&& params, F&& func, Tasks&&... tasks

806){

807 std::array<AsyncTask, sizeof...(Tasks)> array = { std::forward<Tasks>(tasks)... };

808return silent_dependent_async(

809 std::forward<P>(params), std::forward<F>(func), array.begin(), array.end()

810 );

811}

812

813// Function: silent_dependent_async

814template <typename F, typename I>

815requires (!std::same_as<std::decay_t<I>, AsyncTask>)

816tf::AsyncTask TaskGroup::silent_dependent_async(F&& func, I first, I last) {

817return silent_dependent_async(DefaultTaskParams{}, std::forward<F>(func), first, last);

818}

819

820// Function: silent_dependent_async

821template <TaskParamsLike P, typename F, typename I>

822requires (!std::same_as<std::decay_t<I>, AsyncTask>)

823tf::AsyncTask TaskGroup::silent_dependent_async(

824 P&& params, F&& func, I first, I last

  1. {

826 _node_base._join_counter.fetch_add(1, std::memory_order_relaxed);

827return _executor._silent_dependent_async(

828 std::forward<P>(params), std::forward<F>(func), first, last, nullptr, &_node_base

829 );

830}

831

832// ------------------------------------------------------------------------------------------------

833// dependent async

834// ------------------------------------------------------------------------------------------------

835

836// Function: dependent_async

837template <typename F, typename... Tasks>

838requires (std::same_as<std::decay_t<Tasks>, AsyncTask> && ...)

839auto TaskGroup::dependent_async(F&& func, Tasks&&... tasks) {

840return dependent_async(DefaultTaskParams{}, std::forward<F>(func), std::forward<Tasks>(tasks)...);

841}

842

843// Function: dependent_async

844template <TaskParamsLike P, typename F, typename... Tasks>

845requires (std::same_as<std::decay_t<Tasks>, AsyncTask> && ...)

846auto TaskGroup::dependent_async(P&& params, F&& func, Tasks&&... tasks) {

847 std::array<AsyncTask, sizeof...(Tasks)> array = { std::forward<Tasks>(tasks)... };

848return dependent_async(

849 std::forward<P>(params), std::forward<F>(func), array.begin(), array.end()

850 );

851}

852

853// Function: dependent_async

854template <typename F, typename I>

855requires (!std::same_as<std::decay_t<I>, AsyncTask>)

856auto TaskGroup::dependent_async(F&& func, I first, I last) {

857return dependent_async(DefaultTaskParams{}, std::forward<F>(func), first, last);

858}

859

860// Function: dependent_async

861template <TaskParamsLike P, typename F, typename I>

862requires (!std::same_as<std::decay_t<I>, AsyncTask>)

863auto TaskGroup::dependent_async(P&& params, F&& func, I first, I last) {

864 _node_base._join_counter.fetch_add(1, std::memory_order_relaxed);

865return _executor._dependent_async(

866 std::forward<P>(params), std::forward<F>(func), first, last, nullptr, &_node_base

867 );

868}

869

870// ----------------------------------------------------------------------------

871// Executor Forward Declaration

872// ----------------------------------------------------------------------------

873

874// Procedure: task_group

875inline TaskGroup Executor::task_group() {

876Worker* w = this_worker();

877if(w == nullptr) {

878 TF_THROW("task_group can only created by a worker of the executor");

879 }

880return TaskGroup(*this, *w);

881}

882

883

884} // end of namespace tf -----------------------------------------------------

tf::AsyncTask

class to hold a dependent asynchronous task with shared ownership

Definition async_task.hpp:45

tf::DefaultTaskParams

class to create an empty task parameter for compile-time optimization

Definition graph.hpp:191

tf::Executor

class to create an executor

Definition executor.hpp:62

tf::Executor::task_group

TaskGroup task_group()

creates a task group that executes a collection of asynchronous tasks

Definition task_group.hpp:875

tf::Executor::this_worker

Worker * this_worker()

queries pointer to the calling worker if it belongs to this executor, otherwise returns nullptr

tf::TaskGroup::corun

void corun()

corun all tasks spawned by this task group with other workers

Definition task_group.hpp:725

tf::TaskGroup::cancel

void cancel()

cancel all tasks in this task group

Definition task_group.hpp:736

tf::TaskGroup::size

size_t size() const

queries the number of tasks currently in this task group

Definition task_group.hpp:746

tf::TaskGroup::silent_dependent_async

tf::AsyncTask silent_dependent_async(F &&func, Tasks &&... tasks)

runs the given function asynchronously when the given predecessors finish

Definition task_group.hpp:795

tf::TaskGroup::async

auto async(F &&f)

runs the given callable asynchronously

Definition task_group.hpp:775

tf::TaskGroup::operator=

TaskGroup & operator=(TaskGroup &&)=delete

disabled copy assignment

tf::TaskGroup::is_cancelled

bool is_cancelled()

queries if the task group has been cancelled

Definition task_group.hpp:741

tf::TaskGroup::TaskGroup

TaskGroup(TaskGroup &&)=delete

disabled move constructor

tf::TaskGroup::dependent_async

auto dependent_async(F &&func, Tasks &&... tasks)

runs the given function asynchronously when the given predecessors finish

Definition task_group.hpp:839

tf::TaskGroup::TaskGroup

TaskGroup(const TaskGroup &)=delete

disabled copy constructor

tf::TaskGroup::executor

Executor & executor()

obtains the executor that creates this task group

Definition task_group.hpp:720

tf::TaskGroup::silent_async

void silent_async(F &&f)

runs the given function asynchronously without returning any future object

Definition task_group.hpp:756

tf::Worker

class to create a worker in an executor

Definition worker.hpp:55

tf::TaskParamsLike

determines if a type is a task parameter type

Definition graph.hpp:202

tf

taskflow namespace

Definition small_vector.hpp:20