Skip to content

Commit bb2db89

Browse files
code review on decomposition
1 parent 3febc22 commit bb2db89

4 files changed

Lines changed: 38 additions & 29 deletions

File tree

example/composition.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// 2019/03/12 - created by Chun-Xun Lin
2+
// - added an example showing how to use framework decomposition
3+
14
#include <taskflow/taskflow.hpp> // the only include you need
25

36
void composition_example_1(tf::Taskflow& tf) {
@@ -6,20 +9,18 @@ void composition_example_1(tf::Taskflow& tf) {
69

710
// f1 has two independent tasks
811
tf::Framework f1;
9-
auto [f1A, f1B] = f1.name("F1")
10-
.emplace(
12+
auto [f1A, f1B] = f1.name("F1").emplace(
1113
[&](){ std::cout << "F1 TaskA\n"; },
1214
[&](){ std::cout << "F1 TaskB\n"; }
1315
);
1416
f1A.name("f1A");
1517
f1B.name("f1B");
1618

17-
// f2A ---
18-
// |----> f2C ----> f1_module_task
19-
// f2B ---
19+
// f2A ---
20+
// |----> f2C ----> f1_module_task
21+
// f2B ---
2022
tf::Framework f2;
21-
auto [f2A, f2B, f2C] = f2.name("F2")
22-
.emplace(
23+
auto [f2A, f2B, f2C] = f2.name("F2").emplace(
2324
[&](){ std::cout << " F2 TaskA\n"; },
2425
[&](){ std::cout << " F2 TaskB\n"; },
2526
[&](){ std::cout << " F2 TaskC\n"; }
@@ -37,16 +38,13 @@ void composition_example_1(tf::Taskflow& tf) {
3738
tf.run_n(f2, 3).get();
3839
}
3940

40-
41-
4241
void composition_example_2(tf::Taskflow& tf) {
4342
std::cout << '\n';
4443
std::cout << "Composition example 2\n";
4544

4645
// f1 has two independent tasks
4746
tf::Framework f1;
48-
auto [f1A, f1B] = f1.name("F1")
49-
.emplace(
47+
auto [f1A, f1B] = f1.name("F1").emplace(
5048
[&](){ std::cout << "F1 TaskA\n"; },
5149
[&](){ std::cout << "F1 TaskB\n"; }
5250
);
@@ -56,10 +54,10 @@ void composition_example_2(tf::Taskflow& tf) {
5654
// f2A ---
5755
// |----> f2C
5856
// f2B ---
57+
//
5958
// f1_module_task
6059
tf::Framework f2;
61-
auto [f2A, f2B, f2C] = f2.name("F2")
62-
.emplace(
60+
auto [f2A, f2B, f2C] = f2.name("F2").emplace(
6361
[&](){ std::cout << " F2 TaskA\n"; },
6462
[&](){ std::cout << " F2 TaskB\n"; },
6563
[&](){ std::cout << " F2 TaskC\n"; }
@@ -78,14 +76,15 @@ void composition_example_2(tf::Taskflow& tf) {
7876
f3.composed_of(f2);
7977
f3.emplace([](){ std::cout << " F3 TaskA\n"; }).name("f3A");
8078

81-
8279
// f4: f3_module_task -> f2_module_task
8380
tf::Framework f4;
8481
f4.name("F4");
8582
auto f3_module_task = f4.composed_of(f3);
8683
auto f2_module_task = f4.composed_of(f2);
8784
f3_module_task.precede(f2_module_task);
8885

86+
std::cout << f4.dump() << std::endl;
87+
8988
tf.run_until(f4, [iter = 1] () mutable { std::cout << '\n'; return iter-- == 0; }, [](){
9089
std::cout << "First run_until finished\n";
9190
}).get();
@@ -101,6 +100,7 @@ int main(){
101100
tf::Taskflow taskflow;
102101
composition_example_1(taskflow);
103102
composition_example_2(taskflow);
103+
return 0;
104104
}
105105

106106

taskflow/graph/basic_taskflow.hpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// 2019/03/12 - modified by Chun-Xun Lin
2+
// - added framework
3+
//
14
// 2019/02/11 - modified by Tsung-Wei Huang
25
// - refactored run_until
36
// - added allocator to topologies
@@ -247,7 +250,7 @@ class BasicTaskflow : public FlowBuilder {
247250

248251
void _schedule(Node&);
249252
void _schedule(PassiveVector<Node*>&);
250-
void _set_module_node(Node*, Framework*);
253+
void _set_module_node(Node&);
251254
};
252255

253256
// ============================================================================
@@ -632,7 +635,7 @@ void BasicTaskflow<E>::wait_for_topologies() {
632635
template <template <typename...> typename E>
633636
void BasicTaskflow<E>::_schedule(Node& node) {
634637
if(node.is_module() && !node.is_spawned()) {
635-
_set_module_node(&node, node._module);
638+
_set_module_node(node);
636639
assert(node._work.index() == 0);
637640
}
638641
_executor->emplace(*this, node);
@@ -647,9 +650,10 @@ void BasicTaskflow<E>::_schedule(PassiveVector<Node*>& nodes) {
647650
std::vector<Closure> closures;
648651
closures.reserve(nodes.size());
649652
for(auto src : nodes) {
653+
// TODO: remove the assert?
650654
if(src->is_module() && !src->is_spawned()) {
651655
assert(src->_module != nullptr);
652-
_set_module_node(src, src->_module);
656+
_set_module_node(*src);
653657
assert(src->_work.index() == 0);
654658
}
655659
closures.emplace_back(*this, *src);
@@ -659,30 +663,31 @@ void BasicTaskflow<E>::_schedule(PassiveVector<Node*>& nodes) {
659663

660664

661665
template <template <typename...> typename E>
662-
void BasicTaskflow<E>::_set_module_node(Node* n, Framework* f) {
666+
void BasicTaskflow<E>::_set_module_node(Node& node) {
663667

664-
n->_work = [node=n, this, tgt {PassiveVector<Node*>()}] () mutable {
668+
node._work = [&node, this, tgt{PassiveVector<Node*>()}] () mutable {
665669

666670
// second time to enter this context
667-
if(node->is_spawned()) {
668-
node->_dependents.resize(node->_dependents.size()-tgt.size());
671+
if(node.is_spawned()) {
672+
node._dependents.resize(node._dependents.size()-tgt.size());
669673
for(auto& t: tgt) {
670674
t->_successors.clear();
671675
}
672676
return ;
673677
}
678+
674679
// first time to enter this context
675-
node->set_spawned();
680+
node.set_spawned();
676681

677682
PassiveVector<Node*> src;
678683

679-
for(auto &n: node->_module->_graph) {
680-
n._topology = node->_topology;
684+
for(auto &n: node._module->_graph) {
685+
n._topology = node._topology;
681686
if(n.num_dependents() == 0) {
682687
src.push_back(&n);
683688
}
684689
if(n.num_successors() == 0) {
685-
n.precede(*node);
690+
n.precede(node);
686691
tgt.push_back(&n);
687692
}
688693
}

taskflow/graph/framework.hpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,18 @@ class Framework : public FlowBuilder {
5050
*/
5151
size_t num_nodes() const;
5252

53-
// TODO: add doc
5453
/**
55-
@brief create a module task from a framework
54+
@brief creates a module task from a framework
5655
*/
5756
tf::Task composed_of(Framework& framework);
5857

5958
/**
60-
@brief set the name of the framework
59+
@brief sets the name of the framework
6160
*/
6261
auto& name(const std::string&) ;
6362

6463
/**
65-
@brief get the name of the framework
64+
@brief gets the name of the framework
6665
*/
6766
const std::string& name() const ;
6867

@@ -129,6 +128,9 @@ inline void Framework::dump(std::ostream& os) const {
129128
os << "}\n";
130129
}
131130

131+
// TODO:
132+
// 1. check the bug from your composition_1 example?
133+
// 2. use the format: F2 (pointer value)
132134

133135
// Procedure: dump
134136
inline void Framework::_dump(

taskflow/graph/graph.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ using Graph = std::list<Node, tf::SingularAllocator<Node>>;
2121

2222
// ----------------------------------------------------------------------------
2323

24+
// TODO: do we need the flag module now?
25+
2426
// Class: Node
2527
class Node {
2628

0 commit comments

Comments
 (0)