36 std::enable_if_t<is_static_task_v<C>,
Task>
emplace(C&& callable);
48 std::enable_if_t<is_dynamic_task_v<C>,
Task>
emplace(C&& callable);
60 std::enable_if_t<is_condition_task_v<C>,
Task>
emplace(C&& callable);
73 std::enable_if_t<is_cudaflow_task_v<C>,
Task>
emplace(C&& callable);
85 template <
typename... C, std::enable_if_t<(
sizeof...(C)>1),
void>* =
nullptr>
113 template <
typename I,
typename C>
136 std::enable_if_t<std::is_integral<std::decay_t<I>>::value,
void>* =
nullptr 139 I beg, I end, I step, C&& callable,
size_t chunk = 1
162 std::enable_if_t<std::is_floating_point<std::decay_t<I>>::value,
void>* =
nullptr 165 I beg, I end, I step, C&& callable,
size_t chunk = 1
185 template <
typename I,
typename T,
typename B>
203 template <
typename I,
typename T>
221 template <
typename I,
typename T>
245 template <
typename I,
typename T,
typename B,
typename U>
272 template <
typename I,
typename T,
typename B,
typename P,
typename U>
274 I beg, I end, T& result, B&& bop1, P&& bop2, U&& uop
342 template <
typename L>
365 template <
typename... Args>
390 bool _detached {
false};
394 template <
typename... Args>
424 template <
typename... C, std::enable_if_t<(
sizeof...(C)>1),
void>*>
431 template <
typename C>
433 auto n = _graph.emplace_back(
434 nstd::in_place_type_t<Node::StaticWork>{}, std::forward<C>(c)
441 template <
typename C>
443 auto n = _graph.emplace_back(nstd::in_place_type_t<Node::DynamicWork>{},
444 [c=std::forward<C>(c)] (
Subflow& fb)
mutable {
446 if(fb._graph.empty()) {
455 template <
typename C>
457 auto n = _graph.emplace_back(
458 nstd::in_place_type_t<Node::ConditionWork>{}, std::forward<C>(c)
463 #ifdef TF_ENABLE_CUDA 466 template <
typename C>
468 auto n = _graph.emplace_back(
469 nstd::in_place_type_t<Node::cudaFlowWork>{}, std::forward<C>(c)
511 auto node = _graph.emplace_back(
512 nstd::in_place_type_t<Node::ModuleWork>{}, &taskflow
519 from._node->_precede(to._node);
538 for(
auto from : froms) {
545 for(
auto from : froms) {
552 auto node = _graph.emplace_back();
557 template <
typename I,
typename C>
559 I beg, I end, C&& c,
size_t chunk
583 auto task =
emplace([beg, e, c] ()
mutable {
595 if(S.num_successors() == 0) {
606 std::enable_if_t<std::is_integral<std::decay_t<I>>::value,
void>*
610 if((s == 0) || (beg < end && s <= 0) || (beg > end && s >=0) ) {
611 TF_THROW(
"invalid range [", beg,
", ", end,
") with step size ", s);
625 auto o =
static_cast<I
>(chunk) * s;
627 auto task =
emplace([=] ()
mutable {
628 for(
auto i=beg; i<e; i+=s) {
632 source.precede(task);
633 task.precede(target);
640 auto o =
static_cast<I
>(chunk) * s;
642 auto task =
emplace([=] ()
mutable {
643 for(
auto i=beg; i>e; i+=s) {
647 source.precede(task);
648 task.precede(target);
653 if(source.num_successors() == 0) {
654 source.precede(target);
661 template <
typename I,
typename C,
662 std::enable_if_t<std::is_floating_point<std::decay_t<I>>::value,
void>*
666 if((s == 0) || (beg < end && s <= 0) || (beg > end && s >=0) ) {
667 TF_THROW(
"invalid range [", beg,
", ", end,
") with step size ", s);
682 for(I e=beg; e<
end; e+=s) {
684 auto task =
emplace([=] ()
mutable {
685 for(
size_t i=0; i<N; ++i, b+=s) {
689 source.precede(task);
690 task.precede(target);
697 auto task =
emplace([=] ()
mutable {
698 for(
size_t i=0; i<N; ++i, b+=s) {
702 source.precede(task);
703 task.precede(target);
709 for(I e=beg; e>
end; e+=s) {
711 auto task =
emplace([=] ()
mutable {
712 for(
size_t i=0; i<N; ++i, b+=s) {
716 source.precede(task);
717 task.precede(target);
724 auto task =
emplace([=] ()
mutable {
725 for(
size_t i=0; i<N; ++i, b+=s) {
729 source.precede(task);
730 task.precede(target);
734 if(source.num_successors() == 0) {
735 source.precede(target);
743 template <
typename I,
typename T>
745 return reduce(beg, end, result, [] (
const auto& l,
const auto& r) {
752 template <
typename I,
typename T>
754 return reduce(beg, end, result, [] (
const auto& l,
const auto& r) {
760 template <
typename I,
typename T,
typename B,
typename U>
762 I beg, I end, T& result, B&& bop, U&& uop
770 size_t g =
std::max((d + w - 1) / w,
size_t{2});
776 auto g_results = std::make_unique<T[]>(w);
790 auto task =
emplace([beg, e, bop, uop, res=&(g_results[
id])] ()
mutable {
792 for(++beg; beg != e; ++beg) {
797 source.precede(task);
798 task.precede(target);
806 target.work([&result, bop, res=make_moc(
std::move(g_results)), w=
id] () {
807 for(
auto i=0u; i<w; i++) {
808 result = bop(
std::move(result), res.object[i]);
816 template <
typename I,
typename T,
typename B,
typename P,
typename U>
818 I beg, I end, T& result, B&& bop, P&& pop, U&& uop
826 size_t g =
std::max((d + w - 1) / w,
size_t{2});
831 auto g_results = std::make_unique<T[]>(w);
845 auto task =
emplace([beg, e, uop, pop, res= &g_results[
id]] ()
mutable {
847 for(++beg; beg != e; ++beg) {
851 source.precede(task);
852 task.precede(target);
860 target.work([&result, bop, g_results=make_moc(
std::move(g_results)), w=
id] () {
861 for(
auto i=0u; i<w; i++) {
870 template <
typename L>
871 void FlowBuilder::_linearize(L& keys) {
873 auto itr = keys.begin();
874 auto end = keys.end();
882 for(++nxt; nxt != end; ++nxt, ++itr) {
883 itr->_node->_precede(nxt->_node);
898 template <
typename I,
typename T,
typename B>
905 size_t g =
std::max((d + w - 1) / w,
size_t{2});
911 auto g_results = std::make_unique<T[]>(w);
927 auto task =
emplace([beg, e, op, res = &g_results[
id]] ()
mutable {
929 for(++beg; beg != e; ++beg) {
938 source.precede(task);
939 task.precede(target);
953 target.work([g_results=make_moc(
std::move(g_results)), &result, op, w=
id] () {
954 for(
auto i=0u; i<w; i++) {
955 result = op(
std::move(result), g_results.object[i]);
968 template <
typename C>
970 _node->_handle.emplace<Node::StaticWork>(std::forward<C>(c));
976 template <
typename C>
978 _node->_handle.emplace<Node::DynamicWork>(
979 [c=std::forward<C>(c)] (
Subflow& fb)
mutable {
981 if(fb._graph.empty()) {
990 template <
typename C>
992 _node->_handle.emplace<Node::ConditionWork>(std::forward<C>(c));
void linearize(std::vector< Task > &tasks)
adds adjacent dependency links to a linear list of tasks
Definition: flow_builder.hpp:888
void broadcast(Task A, std::vector< Task > &others)
adds dependency links from one task A to many tasks
Definition: flow_builder.hpp:523
std::pair< Task, Task > transform_reduce(I beg, I end, T &result, B &&bop, U &&uop)
constructs a task dependency graph of parallel transformation and reduction
Definition: flow_builder.hpp:761
T hardware_concurrency(T... args)
std::enable_if_t< is_static_task_v< C >, Task > & work(C &&callable)
assigns a static task
Definition: flow_builder.hpp:969
Task placeholder()
creates an empty task
Definition: flow_builder.hpp:551
Subflow(Args &&... args)
constructs a subflow builder object
Definition: flow_builder.hpp:395
void detach()
enables the subflow to detach from its parent task
Definition: flow_builder.hpp:405
bool detached() const
queries if the subflow will be detached from its parent task
Definition: flow_builder.hpp:410
std::pair< Task, Task > reduce_max(I beg, I end, T &result)
constructs a task dependency graph of parallel reduction through std::max
Definition: flow_builder.hpp:753
Task & succeed(Ts &&... tasks)
adds precedence links from other tasks to this
Definition: task.hpp:276
std::enable_if_t< is_static_task_v< C >, Task > emplace(C &&callable)
creates a static task from a given callable object
Definition: flow_builder.hpp:432
std::pair< Task, Task > parallel_for(I beg, I end, C &&callable, size_t chunk=1)
constructs a task dependency graph of range-based parallel_for
Definition: flow_builder.hpp:558
Task composed_of(Taskflow &taskflow)
creates a module task from a taskflow
Definition: flow_builder.hpp:510
void precede(Task A, Task B)
adds a dependency link from task A to task B
Definition: flow_builder.hpp:518
the class to create a task dependency graph
Definition: taskflow.hpp:18
void gather(std::vector< Task > &others, Task A)
adds dependency links from many tasks to one task A
Definition: flow_builder.hpp:537
FlowBuilder(Graph &graph)
constructs a flow builder object
Definition: flow_builder.hpp:347
Building methods of a task dependency graph.
Definition: flow_builder.hpp:13
bool joined() const
queries if the subflow will join its parent task
Definition: flow_builder.hpp:415
handle to a node in a task dependency graph
Definition: task.hpp:51
Task & precede(Ts &&... tasks)
adds precedence links from this to other tasks
Definition: task.hpp:253
std::pair< Task, Task > reduce(I beg, I end, T &result, B &&bop)
construct a task dependency graph of parallel reduction
Definition: flow_builder.hpp:899
The building blocks of dynamic tasking.
Definition: flow_builder.hpp:358
void join()
enables the subflow to join its parent task
Definition: flow_builder.hpp:400
std::pair< Task, Task > reduce_min(I beg, I end, T &result)
constructs a task dependency graph of parallel reduction through std::min
Definition: flow_builder.hpp:744