Skip to content

Commit a0d49f9

Browse files
Tsung-Wei HuangTsung-Wei Huang
authored andcommitted
added emplace.cpp example
1 parent 97fc39d commit a0d49f9

4 files changed

Lines changed: 68 additions & 28 deletions

File tree

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ target_link_libraries(simple ${EXAMPLE_EXE_LINKER_FLAGS})
6060
add_executable(debug example/debug.cpp)
6161
target_link_libraries(debug ${EXAMPLE_EXE_LINKER_FLAGS})
6262

63+
add_executable(emplace example/emplace.cpp)
64+
target_link_libraries(emplace ${EXAMPLE_EXE_LINKER_FLAGS})
65+
6366
add_executable(matrix example/matrix.cpp)
6467
target_compile_options(matrix PRIVATE ${EXAMPLE_CXX_FLAGS})
6568
target_link_libraries(matrix ${EXAMPLE_EXE_LINKER_FLAGS})

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,9 +469,11 @@ The folder `example/` contains several examples and is a great place to learn to
469469
| Example | Description |
470470
| ------- | ----------- |
471471
| [simple.cpp](./example/simple.cpp) | use basic task building blocks to create a trivial taskflow graph |
472+
| [debug.cpp](./example/debug.cpp)| inspect a taskflow through the dump method |
473+
| [emplace.cpp](./example/emplace.cpp)| demonstrate the difference between the emplace method and the silent_emplace method |
472474
| [matrix.cpp](./example/matrix.cpp) | create two set of matrices and multiply each individually in parallel |
473475
| [parallel_for.cpp](./example/parallel_for.cpp)| parallelize a for loop with unbalanced workload |
474-
| [debug.cpp](./example/debug.cpp)| inspect a taskflow through the dump method |
476+
475477

476478
# Get Involved
477479
+ Report bugs/issues by submitting a [Github issue][Github issues].

example/emplace.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// This example shows how to create task using either 'emplace'
2+
// or 'silent_emplace'.
3+
4+
#include <cassert>
5+
#include "taskflow.hpp"
6+
7+
int main(){
8+
9+
tf::Taskflow tf;
10+
11+
// The method emplace gives you a future to retrieve the result.
12+
// You may pass this future to another thread or program context
13+
// to enable more asynchronous control flows.
14+
auto [A, fuA] = tf.emplace([] () {
15+
std::cout << "Task A\n";
16+
return 1;
17+
});
18+
19+
A.name("A");
20+
21+
// The method silent_emplace won't give you a future.
22+
// Therefore, you won't be able to get the return value of the callable.
23+
// Typically, silent_emplace is used for callables with no return values.
24+
auto B = tf.silent_emplace([] () {
25+
std::cout << "Task B\n";
26+
return "no one can get me";
27+
});
28+
29+
B.name("B");
30+
31+
// The future of A won't be ready until you execute the taskflow.
32+
tf.wait_for_all();
33+
34+
assert(fuA.get() == 1);
35+
36+
return 0;
37+
}

taskflow.hpp

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// MIT License
22
//
3-
// Copyright (c) 2018 Dr. Tsung-Wei Huang, Chun-Xun Lin, and Martin Wong
3+
// Copyright (c) 2018 Tsung-Wei Huang, Chun-Xun Lin, and Martin Wong
44
//
55
// Permission is hereby granted, free of charge, to any person obtaining a copy
66
// of this software and associated documentation files (the "Software"), to deal
@@ -199,12 +199,12 @@ inline void Threadpool::spawn(unsigned N) {
199199
while(!stop) {
200200
decltype(_task_queue)::value_type task;
201201

202-
{ // Acquire lock. --------------------------------------------------------------------------
202+
{ // Acquire lock. --------------------------------
203203
std::unique_lock<std::mutex> lock(_mutex);
204204
_worker_signal.wait(lock, [this] () { return _task_queue.size() != 0; });
205205
task = std::move(_task_queue.front());
206206
_task_queue.pop_front();
207-
} // Release lock. --------------------------------------------------------------------------
207+
} // Release lock. --------------------------------
208208

209209
// Execute the task and react to the returned signal.
210210
switch(task()) {
@@ -275,7 +275,7 @@ auto Threadpool::async(C&& c, Signal sig) {
275275
else {
276276
{
277277
std::unique_lock lock(_mutex);
278-
278+
279279
if constexpr(std::is_same_v<void, R>) {
280280
_task_queue.emplace_back(
281281
[p = MoveOnCopy(std::move(p)), c = std::forward<C>(c), ret = sig]() mutable {
@@ -293,7 +293,8 @@ auto Threadpool::async(C&& c, Signal sig) {
293293
}
294294
);
295295
}
296-
296+
297+
// This can cause MSVS not to compile ...
297298
/*_task_queue.emplace_back(
298299
[p=MoveOnCopy(std::move(p)), c=std::forward<C>(c), ret=sig] () mutable {
299300
if constexpr(std::is_same_v<void, R>) {
@@ -339,9 +340,6 @@ inline void Threadpool::shutdown() {
339340
template <typename F>
340341
class BasicTaskflow {
341342

342-
//template <typename G>
343-
//friend std::ostream& operator << (std::ostream&, const BasicTaskflow<G>&);
344-
345343
// Struct: Node
346344
struct Node {
347345

@@ -450,7 +448,6 @@ class BasicTaskflow {
450448
template <typename I, typename T, class O>
451449
auto reduce(I, I, T&, O&&, size_t = 1);
452450

453-
454451
auto placeholder();
455452
auto precede(Task, Task);
456453
auto linearize(std::vector<Task>&);
@@ -488,7 +485,7 @@ class BasicTaskflow {
488485
void _linearize(L&);
489486

490487
template <typename I, class O>
491-
auto _reduce_impl(I, O, const size_t, const size_t, const size_t, const int, Task&);
488+
auto _reduce(I, O, const size_t, const size_t, const size_t, const int, Task&);
492489
};
493490

494491
// Constructor
@@ -914,36 +911,37 @@ auto BasicTaskflow<F>::parallel_for(T& t, C&& c, size_t group) {
914911
}
915912

916913

917-
// Function: _reduce_impl
914+
// Function: _reduce
918915
template <typename F>
919916
template <typename I, class O>
920-
auto BasicTaskflow<F>::_reduce_impl(
917+
auto BasicTaskflow<F>::_reduce(
921918
I beg,
922919
O op,
923920
const size_t start,
924921
const size_t group,
925-
const size_t num_chunks,
922+
const size_t num_groups,
926923
const int total,
927924
Task& source
928925
) {
929-
if(num_chunks == 1){
926+
927+
if(num_groups == 1){
930928
// Base case
931929
const auto len {std::min(group, total-start)};
932-
auto kvp = emplace([op, b=beg, len]() mutable{
933-
auto e = b;
934-
std::advance(e, len);
935-
return std::accumulate(std::next(b), e, *b, op);
936-
});
930+
auto kvp = emplace([op, b=beg, len]() mutable {
931+
auto e = b;
932+
std::advance(e, len);
933+
return std::accumulate(std::next(b), e, *b, op);
934+
});
937935
source.precede(std::get<Task>(kvp));
938936
return kvp;
939937
}
940-
else{
938+
else {
941939
// Recursion
942-
const auto l_length {num_chunks/2};
943-
const auto r_length {num_chunks-l_length};
944-
const auto rbeg {l_length*group};
945-
auto [L, lfu] = _reduce_impl(beg , op, start , group, l_length, total, source);
946-
auto [R, rfu] = _reduce_impl(std::next(beg, rbeg), op, start+rbeg, group, r_length, total, source);
940+
const auto l_len {num_groups/2};
941+
const auto r_len {num_groups-l_len};
942+
const auto rbeg {l_len*group};
943+
auto [L, lfu] = _reduce(beg, op, start, group, l_len, total, source);
944+
auto [R, rfu] = _reduce(std::next(beg, rbeg), op, start+rbeg, group, r_len, total, source);
947945
auto kvp {emplace(
948946
[op, l=MoveOnCopy{std::move(lfu)}, r=MoveOnCopy{std::move(rfu)}] () {
949947
return op(l.object.get(), r.object.get());
@@ -965,9 +963,9 @@ auto BasicTaskflow<F>::reduce(I beg, I end, T& result, O&& op, size_t group) {
965963
}
966964

967965
const auto length = std::distance(beg, end);
968-
const size_t num_chunks = length%group == 0 ? length/group : length/group+1;
966+
const size_t num_groups = length%group == 0 ? length/group : length/group+1;
969967
auto source = placeholder();
970-
auto [root, fu] = _reduce_impl(beg, op, 0, group, num_chunks, length, source);
968+
auto [root, fu] = _reduce(beg, op, 0, group, num_groups, length, source);
971969
auto target = silent_emplace([op, fu=MoveOnCopy{std::move(fu)}, &result]() {
972970
result = op(result, fu.object.get());
973971
});

0 commit comments

Comments
 (0)