Skip to content

Commit 1a9860a

Browse files
update taskflow.hpp
1 parent 316f472 commit 1a9860a

5 files changed

Lines changed: 102 additions & 21 deletions

File tree

README.md

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,55 @@
1-
# Taskflow
2-
Fast C++ Taskflow Executor
1+
# Cpp-Taskflow
2+
An easy-to-use and fast header-only library written in C++17 for task-based parallel programming.
3+
4+
# Scale up Your Program with Cpp-Taskflow
5+
6+
The following example contains most of the syntax you need to use Cpp-Taskflow.
7+
8+
```cpp
9+
#include <taskflow.hpp>
10+
11+
// A simple example to capture the following task dependencies.
12+
//
13+
// TaskA---->TaskB---->TaskD
14+
// TaskA---->TaskC---->TaskD
15+
//
16+
int main(){
17+
18+
tf::Taskflow<> tf(std::thread::hardware_concurrency());
19+
20+
auto [A, B, C, D] = tf.silent_emplace(
21+
[] () { std::cout << "TaskA\n"; },
22+
[] () { std::cout << "TaskB\n"; },
23+
[] () { std::cout << "TaskC\n"; },
24+
[] () { std::cout << "TaskD\n"; }
25+
);
26+
27+
A.precede(B);
28+
A.precede(C);
29+
B.precede(D);
30+
C.precede(D);
31+
32+
tf.wait_for_all();
33+
34+
return 0;
35+
}
36+
37+
```
38+
39+
# System Requirements
40+
To use Cpp-Taskflow, you only need a C++17 compiler:
41+
- GNU C++ Compiler G++ v7.2 with -std=c++1z
42+
43+
# Get Involved
44+
+ Report bugs/issues by submitting a <a href="https://github.com/twhuang-uiuc/cpp-taskflow/issues">GitHub issue</a>.
45+
+ Submit contributions using <a href="https://github.com/twhuang-uiuc/cpp-taskflow/pulls">pull requests<a>.
46+
47+
# Contributors
48+
+ Tsung-Wei Huang
49+
+ Chun-Xun Lin
50+
+ You!
51+
52+
# License
53+
54+
Copyright © 2018, [Tsung-Wei Huang](http://web.engr.illinois.edu/~thuang19/) and Chun-Xun Lin.
55+
Released under the [MIT license](https://github.com/twhuang-uiuc/cpp-taskflow/blob/master/LICENSE).

example/matrix.cpp

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ auto func2(const matrix_t& a, auto&& b) {
120120
return dummy;
121121
}
122122

123-
// Procedure: sequential
124-
void sequential(size_t N) {
123+
// Procedure: baseline
124+
void baseline(size_t N) {
125125

126126
generate_test(N);
127127

@@ -148,13 +148,13 @@ void sequential(size_t N) {
148148

149149
auto tend = std::chrono::steady_clock::now();
150150

151-
std::cout << "sequential version takes "
151+
std::cout << "Baseline takes "
152152
<< std::chrono::duration_cast<std::chrono::seconds>(tend-tbeg).count()
153153
<< " seconds\n";
154154
}
155155

156-
// Procedure: naive_parallel
157-
void naive_parallel(size_t N, size_t num_threads = std::thread::hardware_concurrency()) {
156+
// Procedure: openmp_parallel
157+
void openmp_parallel(size_t N, size_t num_threads = std::thread::hardware_concurrency()) {
158158

159159
generate_test(N);
160160

@@ -184,13 +184,13 @@ void naive_parallel(size_t N, size_t num_threads = std::thread::hardware_concurr
184184

185185
auto tend = std::chrono::steady_clock::now();
186186

187-
std::cout << "naive parallel version takes "
187+
std::cout << "OpenMP takes "
188188
<< std::chrono::duration_cast<std::chrono::seconds>(tend-tbeg).count()
189189
<< " seconds\n";
190190
}
191191

192-
// Procedure: parallel
193-
void parallel(size_t N, size_t num_threads = std::thread::hardware_concurrency()) {
192+
// Procedure: taskflow_parallel
193+
void taskflow_parallel(size_t N, size_t num_threads = std::thread::hardware_concurrency()) {
194194

195195
generate_test(N);
196196

@@ -279,7 +279,7 @@ void parallel(size_t N, size_t num_threads = std::thread::hardware_concurrency()
279279
tf.wait_for_all();
280280

281281
auto tend = std::chrono::steady_clock::now();
282-
std::cout << "parallel version takes "
282+
std::cout << "Taskflow takes "
283283
<< std::chrono::duration_cast<std::chrono::seconds>(tend-tbeg).count()
284284
<< " seconds\n";
285285
}
@@ -290,21 +290,21 @@ void parallel(size_t N, size_t num_threads = std::thread::hardware_concurrency()
290290
int main(int argc, char* argv[]) {
291291

292292
if(argc != 3) {
293-
std::cerr << "usage: ./matrix N [seq|naive|taskflow]\n";
293+
std::cerr << "usage: ./matrix N [baseline|openmp|taskflow]\n";
294294
std::exit(EXIT_FAILURE);
295295
}
296296

297-
if(std::strcmp(argv[2], "seq") == 0) {
298-
sequential(std::stoi(argv[1]));
297+
if(std::string_view method(argv[2]); method == "baseline") {
298+
baseline(std::stoi(argv[1]));
299299
}
300-
else if(std::strcmp(argv[2], "naive") == 0) {
301-
naive_parallel(std::stoi(argv[1]));
300+
else if(method == "openmp") {
301+
openmp_parallel(std::stoi(argv[1]));
302302
}
303-
else if(std::strcmp(argv[2], "taskflow") == 0) {
304-
parallel(std::stof(argv[1]));
303+
else if(method == "taskflow") {
304+
taskflow_parallel(std::stof(argv[1]));
305305
}
306306
else {
307-
std::cerr << "wrong method\n";
307+
std::cerr << "wrong method, shoud be [baseline|openmp|taskflow]\n";
308308
}
309309

310310
return 0;

example/simple.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,28 @@
1-
#include <iostream>
21
#include <taskflow.hpp>
32

3+
// A simple example to capture the following task dependencies.
4+
//
5+
// TaskA---->TaskB---->TaskD
6+
// TaskA---->TaskC---->TaskD
7+
//
48
int main(){
59

10+
tf::Taskflow<> tf(std::thread::hardware_concurrency());
11+
12+
auto [A, B, C, D] = tf.silent_emplace(
13+
[] () { std::cout << "TaskA\n"; },
14+
[] () { std::cout << "TaskB\n"; },
15+
[] () { std::cout << "TaskC\n"; },
16+
[] () { std::cout << "TaskD\n"; }
17+
);
18+
19+
A.precede(B);
20+
A.precede(C);
21+
B.precede(D);
22+
C.precede(D);
23+
24+
tf.wait_for_all();
25+
26+
return 0;
627
}
728

taskflow.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ class Taskflow {
426426

427427

428428
Taskflow(unsigned);
429+
~Taskflow();
429430

430431
template <typename C>
431432
auto emplace(C&&);
@@ -499,7 +500,7 @@ Taskflow<F>::TaskBuilder::TaskBuilder(const TaskBuilder& rhs) : _task{rhs._task}
499500

500501
template <typename F>
501502
typename Taskflow<F>::TaskBuilder& Taskflow<F>::TaskBuilder::precede(TaskBuilder tgt) {
502-
_task->precede(tgt._task);
503+
_task->precede(*(tgt._task));
503504
return *this;
504505
}
505506

@@ -582,6 +583,12 @@ template <typename F>
582583
Taskflow<F>::Taskflow(unsigned N) : _threadpool{N} {
583584
}
584585

586+
// Destructor
587+
template <typename F>
588+
Taskflow<F>::~Taskflow() {
589+
wait_for_all();
590+
}
591+
585592
// Function: num_tasks
586593
template <typename F>
587594
size_t Taskflow<F>::num_tasks() const {

unittest/taskflow

0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)