Skip to content

Commit 2768de5

Browse files
Tsung-Wei HuangTsung-Wei Huang
authored andcommitted
added reduce example
1 parent 93ef312 commit 2768de5

5 files changed

Lines changed: 384 additions & 78 deletions

File tree

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ target_link_libraries(debug ${EXAMPLE_EXE_LINKER_FLAGS})
6363
add_executable(emplace example/emplace.cpp)
6464
target_link_libraries(emplace ${EXAMPLE_EXE_LINKER_FLAGS})
6565

66+
add_executable(reduce example/reduce.cpp)
67+
target_link_libraries(reduce ${EXAMPLE_EXE_LINKER_FLAGS})
68+
6669
add_executable(matrix example/matrix.cpp)
6770
target_compile_options(matrix PRIVATE ${EXAMPLE_CXX_FLAGS})
6871
target_link_libraries(matrix ${EXAMPLE_EXE_LINKER_FLAGS})
@@ -86,6 +89,8 @@ add_test(builder ${PROJECT_SOURCE_DIR}/unittest/taskflow -tc=Taskflow.Builder)
8689
add_test(dispatch ${PROJECT_SOURCE_DIR}/unittest/taskflow -tc=Taskflow.Dispatch)
8790
add_test(parallel_for ${PROJECT_SOURCE_DIR}/unittest/taskflow -tc=Taskflow.ParallelFor)
8891
add_test(reduce ${PROJECT_SOURCE_DIR}/unittest/taskflow -tc=Taskflow.Reduce)
92+
add_test(reduce_min ${PROJECT_SOURCE_DIR}/unittest/taskflow -tc=Taskflow.ReduceMin)
93+
add_test(reduce_max ${PROJECT_SOURCE_DIR}/unittest/taskflow -tc=Taskflow.ReduceMax)
8994
#add_test(parallel_range ${PROJECT_SOURCE_DIR}/unittest/taskflow -tc=Taskflow.ParallelRange)
9095

9196

example/parallel_for.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ void taskflow(int N) {
3232
tf::Taskflow tf;
3333
tf.parallel_for(range, [&] (const int i) {
3434
printf("fib[%d]=%d\n", i, fib(i));
35-
});
35+
}, 1);
3636
tf.wait_for_all();
3737

3838
auto tend = std::chrono::steady_clock::now();

example/reduce.cpp

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// This example demonstrates how to use 'reduce' method.
2+
3+
#include "taskflow.hpp"
4+
5+
#include <chrono>
6+
#include <limits.h>
7+
8+
struct Data {
9+
int a {::rand()};
10+
int b {::rand()};
11+
int transform() const {
12+
return a*a + 2*a*b + b*b;
13+
}
14+
};
15+
16+
// Procedure: reduce
17+
// This procedure demonstrates
18+
void reduce() {
19+
20+
std::vector<int> data;
21+
for(int i=0; i<40000000; ++i) {
22+
data.push_back(::rand());
23+
}
24+
25+
// sequential method
26+
std::cout << "running sequential method ..." << std::endl;
27+
auto sbeg = std::chrono::steady_clock::now();
28+
auto smin = std::numeric_limits<int>::max();
29+
for(auto& d : data) {
30+
smin = std::min(smin, d);
31+
}
32+
auto send = std::chrono::steady_clock::now();
33+
std::cout << "[sequential] reduce: "
34+
<< std::chrono::duration_cast<std::chrono::milliseconds>(send - sbeg).count()
35+
<< std::endl;
36+
37+
// taskflow
38+
std::cout << "running taskflow method ..." << std::endl;
39+
auto tbeg = std::chrono::steady_clock::now();
40+
tf::Taskflow tf;
41+
auto tmin = std::numeric_limits<int>::max();
42+
tf.reduce(data.begin(), data.end(), tmin, [] (const auto& l, const auto& r) {
43+
return std::min(l, r);
44+
});
45+
tf.wait_for_all();
46+
auto tend = std::chrono::steady_clock::now();
47+
std::cout << "[taskflow] reduce: "
48+
<< std::chrono::duration_cast<std::chrono::milliseconds>(tend - tbeg).count()
49+
<< std::endl;
50+
51+
// assertion
52+
assert(tmin == smin);
53+
}
54+
55+
// Procedure: transform_reduce
56+
void transform_reduce() {
57+
58+
std::cout << "Benchmark: transform_reduce" << std::endl;
59+
60+
std::vector<Data> data(40000000);
61+
62+
// sequential method
63+
auto sbeg = std::chrono::steady_clock::now();
64+
auto smin = std::numeric_limits<int>::max();
65+
for(auto& d : data) {
66+
smin = std::min(smin, d.transform());
67+
}
68+
auto send = std::chrono::steady_clock::now();
69+
std::cout << "[sequential] transform_reduce "
70+
<< std::chrono::duration_cast<std::chrono::milliseconds>(send - sbeg).count()
71+
<< std::endl;
72+
73+
// taskflow
74+
auto tbeg = std::chrono::steady_clock::now();
75+
tf::Taskflow tf;
76+
auto tmin = std::numeric_limits<int>::max();
77+
tf.transform_reduce(data.begin(), data.end(), tmin,
78+
[] (float l, float r) { return std::min(l, r); },
79+
[] (const Data& d) { return d.transform(); }
80+
);
81+
tf.wait_for_all();
82+
auto tend = std::chrono::steady_clock::now();
83+
std::cout << "[taskflow] transform_reduce "
84+
<< std::chrono::duration_cast<std::chrono::milliseconds>(tend - tbeg).count()
85+
<< std::endl;
86+
87+
// assertion
88+
assert(tmin == smin);
89+
}
90+
91+
// ------------------------------------------------------------------------------------------------
92+
93+
// Function: main
94+
int main(int argc, char* argv[]) {
95+
96+
if(argc != 2) {
97+
std::cerr << "usage: ./reduce [reduce|transform_reduce]" << std::endl;
98+
std::exit(EXIT_FAILURE);
99+
}
100+
101+
if(std::string_view method(argv[1]); method == "reduce") {
102+
reduce();
103+
}
104+
else if(method == "transform_reduce") {
105+
transform_reduce();
106+
}
107+
else {
108+
std::cerr << "invalid method " << method << std::endl;
109+
std::exit(EXIT_FAILURE);
110+
}
111+
112+
return 0;
113+
}

0 commit comments

Comments
 (0)