Taskflow  3.2.0-Master-Branch
Loading...
Searching...
No Matches
flow_builder.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "task.hpp"
4
10namespace tf {
11
22
23 friend class Executor;
24
25 public:
26
30 FlowBuilder(Graph& graph);
31
49 template <typename C,
51 >
52 Task emplace(C&& callable);
53
75 template <typename C,
77 >
78 Task emplace(C&& callable);
79
109 template <typename C,
111 >
112 Task emplace(C&& callable);
113
145 template <typename C,
147 >
148 Task emplace(C&& callable);
149
174 template <typename... C, std::enable_if_t<(sizeof...(C)>1), void>* = nullptr>
175 auto emplace(C&&... callables);
176
197 void erase(Task task);
198
250 template <typename T>
251 Task composed_of(T& object);
252
278
305 template <typename C,
307 >
308 Task emplace(C&& callable);
309
332 template <typename C, typename D,
334 >
335 Task emplace_on(C&& callable, D&& device);
336
360 template <typename C, std::enable_if_t<is_syclflow_task_v<C>, void>* = nullptr>
361 Task emplace(C&& callable);
362
388 template <typename C, typename Q,
390 >
391 Task emplace_on(C&& callable, Q&& queue);
392
414 template <typename C,
416 >
417 Task emplace(C&& callable);
418
436 void linearize(std::vector<Task>& tasks);
437
454
455 // ------------------------------------------------------------------------
456 // parallel iterations
457 // ------------------------------------------------------------------------
458
488 template <typename B, typename E, typename C>
489 Task for_each(B first, E last, C callable);
490
527 template <typename B, typename E, typename S, typename C>
528 Task for_each_index(B first, E last, S step, C callable);
529
530 // ------------------------------------------------------------------------
531 // transform
532 // ------------------------------------------------------------------------
533
563 template <typename B, typename E, typename O, typename C>
564 Task transform(B first1, E last1, O d_first, C c);
565
597 template <typename B1, typename E1, typename B2, typename O, typename C>
598 Task transform(B1 first1, E1 last1, B2 first2, O d_first, C c);
599
600 // ------------------------------------------------------------------------
601 // reduction
602 // ------------------------------------------------------------------------
603
634 template <typename B, typename E, typename T, typename O>
635 Task reduce(B first, E last, T& init, O bop);
636
637 // ------------------------------------------------------------------------
638 // transfrom and reduction
639 // ------------------------------------------------------------------------
640
673 template <typename B, typename E, typename T, typename BOP, typename UOP>
674 Task transform_reduce(B first, E last, T& init, BOP bop, UOP uop);
675
676 // ------------------------------------------------------------------------
677 // sort
678 // ------------------------------------------------------------------------
679
698 template <typename B, typename E, typename C>
699 Task sort(B first, E last, C cmp);
700
719 template <typename B, typename E>
720 Task sort(B first, E last);
721
722 protected:
723
728
729 private:
730
731 template <typename L>
732 void _linearize(L&);
733};
734
735// Constructor
737 _graph {graph} {
738}
739
740// Function: emplace
741template <typename C, std::enable_if_t<is_static_task_v<C>, void>*>
743 return Task(_graph._emplace_back(
745 ));
746}
747
748// Function: emplace
749template <typename C, std::enable_if_t<is_dynamic_task_v<C>, void>*>
751 return Task(_graph._emplace_back(
753 ));
754}
755
756// Function: emplace
757template <typename C, std::enable_if_t<is_condition_task_v<C>, void>*>
758Task FlowBuilder::emplace(C&& c) {
759 return Task(_graph._emplace_back(
761 ));
762}
763
764// Function: emplace
765template <typename C, std::enable_if_t<is_multi_condition_task_v<C>, void>*>
766Task FlowBuilder::emplace(C&& c) {
767 return Task(_graph._emplace_back(
769 ));
770}
771
772// Function: emplace
773template <typename C, std::enable_if_t<is_runtime_task_v<C>, void>*>
774Task FlowBuilder::emplace(C&& c) {
775 return Task(_graph._emplace_back(
777 ));
778}
779
780// Function: emplace
781template <typename... C, std::enable_if_t<(sizeof...(C)>1), void>*>
782auto FlowBuilder::emplace(C&&... cs) {
784}
785
786// Function: erase
787inline void FlowBuilder::erase(Task task) {
788
789 if (!task._node) {
790 return;
791 }
792
793 task.for_each_dependent([&] (Task dependent) {
794 auto& S = dependent._node->_successors;
795 if(auto I = std::find(S.begin(), S.end(), task._node); I != S.end()) {
796 S.erase(I);
797 }
798 });
799
800 task.for_each_successor([&] (Task dependent) {
801 auto& D = dependent._node->_dependents;
802 if(auto I = std::find(D.begin(), D.end(), task._node); I != D.end()) {
803 D.erase(I);
804 }
805 });
806
807 _graph._erase(task._node);
808}
809
810// Function: composed_of
811template <typename T>
813 auto node = _graph._emplace_back(
815 );
816 return Task(node);
817}
818
819// Function: placeholder
821 auto node = _graph._emplace_back();
822 return Task(node);
823}
824
825// Procedure: _linearize
826template <typename L>
827void FlowBuilder::_linearize(L& keys) {
828
829 auto itr = keys.begin();
830 auto end = keys.end();
831
832 if(itr == end) {
833 return;
834 }
835
836 auto nxt = itr;
837
838 for(++nxt; nxt != end; ++nxt, ++itr) {
839 itr->_node->_precede(nxt->_node);
840 }
841}
842
843// Procedure: linearize
845 _linearize(keys);
846}
847
848// Procedure: linearize
850 _linearize(keys);
851}
852
853// ----------------------------------------------------------------------------
854
889class Subflow : public FlowBuilder {
890
891 friend class Executor;
892 friend class FlowBuilder;
893 friend class Runtime;
894
895 public:
896
912 void join();
913
929 void detach();
930
937 void reset();
938
954 bool joinable() const noexcept;
955
993 template <typename F, typename... ArgsT>
994 auto async(F&& f, ArgsT&&... args);
995
1034 template <typename F, typename... ArgsT>
1035 auto named_async(const std::string& name, F&& f, ArgsT&&... args);
1036
1055 template <typename F, typename... ArgsT>
1056 void silent_async(F&& f, ArgsT&&... args);
1057
1076 template <typename F, typename... ArgsT>
1077 void named_silent_async(const std::string& name, F&& f, ArgsT&&... args);
1078
1082 inline Executor& executor();
1083
1084 private:
1085
1086 Executor& _executor;
1087 Worker& _worker;
1088 Node* _parent;
1089 bool _joinable {true};
1090
1091 Subflow(Executor&, Worker&, Node*, Graph&);
1092
1093 template <typename F, typename... ArgsT>
1094 auto _named_async(Worker& w, const std::string& name, F&& f, ArgsT&&... args);
1095
1096 template <typename F, typename... ArgsT>
1097 void _named_silent_async(Worker& w, const std::string& name, F&& f, ArgsT&&... args);
1098};
1099
1100// Constructor
1101inline Subflow::Subflow(
1102 Executor& executor, Worker& worker, Node* parent, Graph& graph
1103) :
1104 FlowBuilder {graph},
1105 _executor {executor},
1106 _worker {worker},
1107 _parent {parent} {
1108 // assert(_parent != nullptr);
1109}
1110
1111// Function: joined
1112inline bool Subflow::joinable() const noexcept {
1113 return _joinable;
1114}
1115
1116// Function: executor
1118 return _executor;
1119}
1120
1121// Procedure: reset
1122inline void Subflow::reset() {
1123 _graph._clear();
1124 _joinable = true;
1125}
1126
1127} // end of namespace tf. ---------------------------------------------------
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
class to create an executor for running a taskflow graph
Definition executor.hpp:50
class to build a task dependency graph
Definition flow_builder.hpp:21
Task transform_reduce(B first, E last, T &init, BOP bop, UOP uop)
constructs a STL-styled parallel transform-reduce task
Task sort(B first, E last, C cmp)
constructs a dynamic task to perform STL-styled parallel sort
Task for_each_index(B first, E last, S step, C callable)
constructs a parallel-transform task
void erase(Task task)
removes a task from a taskflow
Definition flow_builder.hpp:787
Task emplace(C &&callable)
creates a static task
Definition flow_builder.hpp:742
FlowBuilder(Graph &graph)
constructs a flow builder with a graph
Definition flow_builder.hpp:736
Task sort(B first, E last)
constructs a dynamic task to perform STL-styled parallel sort using the std::less<T> comparator,...
void linearize(std::vector< Task > &tasks)
adds adjacent dependency links to a linear list of tasks
Definition flow_builder.hpp:844
Graph & _graph
associated graph object
Definition flow_builder.hpp:727
Task transform(B1 first1, E1 last1, B2 first2, O d_first, C c)
constructs a parallel-transform task
Task reduce(B first, E last, T &init, O bop)
constructs a STL-styled parallel-reduce task
Task for_each(B first, E last, C callable)
constructs a STL-styled parallel-for task
Task transform(B first1, E last1, O d_first, C c)
constructs a parallel-transform task
Task composed_of(T &object)
creates a module task for the target object
Definition flow_builder.hpp:812
Task placeholder()
creates a placeholder task
Definition flow_builder.hpp:820
Task emplace_on(C &&callable, D &&device)
creates a cudaFlow task on the given device
Definition cudaflow.hpp:1666
class to create a graph object
Definition graph.hpp:56
class to create a runtime object used by a runtime task
Definition graph.hpp:150
class to construct a subflow graph from the execution of a dynamic task
Definition flow_builder.hpp:889
void reset()
resets the subflow to a clean graph of joinable state
Definition flow_builder.hpp:1122
void named_silent_async(const std::string &name, F &&f, ArgsT &&... args)
similar to tf::Subflow::named_async but does not return a future object
Definition executor.hpp:1936
void join()
enables the subflow to join its parent task
Definition executor.hpp:1826
auto async(F &&f, ArgsT &&... args)
runs a given function asynchronously
Definition executor.hpp:1908
bool joinable() const noexcept
queries if the subflow is joinable
Definition flow_builder.hpp:1112
Executor & executor()
returns the executor that runs this subflow
Definition flow_builder.hpp:1117
void detach()
enables the subflow to detach from its parent task
Definition executor.hpp:1839
auto named_async(const std::string &name, F &&f, ArgsT &&... args)
runs the given function asynchronously and assigns the task a name
Definition executor.hpp:1854
void silent_async(F &&f, ArgsT &&... args)
similar to tf::Subflow::async but does not return a future object
Definition executor.hpp:1944
class to create a task handle over a node in a taskflow graph
Definition task.hpp:187
void for_each_dependent(V &&visitor) const
applies an visitor callable to each dependents of the task
Definition task.hpp:561
void for_each_successor(V &&visitor) const
applies an visitor callable to each successor of the task
Definition task.hpp:553
T find(T... args)
T forward(T... args)
T make_tuple(T... args)
taskflow namespace
Definition small_vector.hpp:27
task include file