21 #ifndef GRPPI_TBB_DIVIDECONQUER_H 22 #define GRPPI_TBB_DIVIDECONQUER_H 32 template <
typename Input,
typename Div
ider,
typename Solver,
typename Combiner>
33 typename std::result_of<Solver(Input)>::type
36 Divider && divide_op, Solver && solve_op,
37 Combiner && combine_op,
38 std::atomic<int>& num_threads)
43 if (num_threads.load()<=0) {
44 return divide_conquer(seq, input, std::forward<Divider>(divide_op),
45 std::forward<Solver>(solve_op), std::forward<Combiner>(combine_op));
48 auto subproblems = divide_op(input);
50 if (subproblems.size()<=1) {
51 return solve_op(input);
54 using Output =
typename std::result_of<Solver(Input)>::type;
55 std::vector<Output> partials(subproblems.size()-1);
58 auto i = subproblems.begin()+1;
59 for(i; i!=subproblems.end() && num_threads.load()>0; i++, division++) {
62 [&ex, i, &partials, division, ÷_op, &solve_op, &combine_op,
66 std::forward<Divider>(divide_op), std::forward<Solver>(solve_op),
67 std::forward<Combiner>(combine_op), num_threads);
75 for(i; i != subproblems.end(); i++){
77 std::forward<Divider>(divide_op), std::forward<Solver>(solve_op),
78 std::forward<Combiner>(combine_op));
82 std::forward<Divider>(divide_op), std::forward<Solver>(solve_op),
83 std::forward<Combiner>(combine_op), num_threads);
87 for (
auto && p : partials) { out = combine_op(out,p); }
113 template <
typename Input,
typename Div
ider,
typename Solver,
typename Combiner>
114 typename std::result_of<Solver(Input)>::type
117 Divider && divide_op, Solver && solve_op,
118 Combiner && combine_op)
125 if (num_threads.load()<=0) {
126 return divide_conquer(seq, input, std::forward<Divider>(divide_op),
127 std::forward<Solver>(solve_op), std::forward<Combiner>(combine_op));
130 auto subproblems = divide_op(input);
131 if (subproblems.size()<=1) {
132 return solve_op(input);
135 using Output =
typename std::result_of<Solver(Input)>::type;
136 std::vector<Output> partials(subproblems.size()-1);
140 auto i = subproblems.begin()+1;
141 for (i ; i!=subproblems.end() && num_threads.load()>0; i++, division++) {
144 [&ex, i, &partials, division, ÷_op, &solve_op, &combine_op,
148 std::forward<Divider>(divide_op), std::forward<Solver>(solve_op),
149 std::forward<Combiner>(combine_op), num_threads);
155 for(i; i != subproblems.end(); i++){
157 std::forward<Divider>(divide_op), std::forward<Solver>(solve_op),
158 std::forward<Combiner>(combine_op));
163 if (num_threads.load()>0) {
165 std::forward<Divider>(divide_op), std::forward<Solver>(solve_op),
166 std::forward<Combiner>(combine_op), num_threads);
170 std::forward<Divider>(divide_op), std::forward<Solver>(solve_op),
171 std::forward<Combiner>(combine_op));
176 for (
int i=0; i<partials.size(); i++){
177 out = combine_op(out , partials[i]);
Definition: callable_traits.h:24
std::result_of< Solver(Input)>::type divide_conquer(parallel_execution_native &ex, Input &problem, Divider &÷_op, Solver &&solve_op, Combiner &&combine_op)
Invoke Divide/conquer pattern with native parallel execution.
Definition: native/divideconquer.h:124
TBB parallel execution policy.
Definition: parallel_execution_tbb.h:37
int concurrency_degree() const noexcept
Get number of grppi trheads.
Definition: parallel_execution_tbb.h:73
Sequential execution policy.
Definition: sequential_execution.h:31
std::result_of< Solver(Input)>::type internal_divide_conquer(parallel_execution_native &p, Input &input, Divider &÷_op, Solver &&solve_op, Combiner &&combine_op, std::atomic< int > &num_threads)
Definition: native/divideconquer.h:33