21 #ifndef GRPPI_OMP_DIVIDECONQUER_H 22 #define GRPPI_OMP_DIVIDECONQUER_H 30 template <
typename Input,
typename Div
ider,
typename Solver,
typename Combiner>
31 typename std::result_of<Solver(Input)>::type
34 Divider && divide_op, Solver && solve_op,
35 Combiner && combine_op,
36 std::atomic<int> & num_threads)
39 using Output =
typename std::result_of<Solver(Input)>::type;
42 if(num_threads.load()>0) {
43 auto subproblems = divide_op(input);
46 if(subproblems.size()>1) {
47 std::vector<Output> partials(subproblems.size()-1);
49 auto i = subproblems.begin()+1;
50 for(i; i!=subproblems.end() && num_threads.load()>0; i++, division++){
52 #pragma omp task firstprivate(i, division) shared(divide_op, solve_op, \ 53 combine_op, partials, num_threads) 56 std::forward<Divider>(divide_op),
57 std::forward<Solver>(solve_op),
58 std::forward<Combiner>(combine_op), num_threads);
64 for(i; i != subproblems.end(); i++){
66 std::forward<Divider>(divide_op),
67 std::forward<Solver>(solve_op),
68 std::forward<Combiner>(combine_op));
73 std::forward<Divider>(divide_op),
74 std::forward<Solver>(solve_op),
75 std::forward<Combiner>(combine_op), num_threads);
79 for(
int i = 0; i<partials.size();i++){
80 out = combine_op(out,partials[i]);
84 out = solve_op(input);
88 return divide_conquer(seq, input, std::forward<Divider>(divide_op),
89 std::forward<Solver>(solve_op), std::forward<Combiner>(combine_op));
115 template <
typename Input,
typename Div
ider,
typename Solver,
typename Combiner>
116 typename std::result_of<Solver(Input)>::type
119 Divider && divide_op, Solver && solve_op,
120 Combiner && combine_op)
126 using Output =
typename std::result_of<Solver(Input)>::type;
128 if (num_threads.load()<=0) {
130 std::forward<Divider>(divide_op),
131 std::forward<Solver>(solve_op),
132 std::forward<Combiner>(combine_op));
135 auto subproblems = divide_op(input);
136 if (subproblems.size()<=1) {
137 return solve_op(input);
140 std::vector<Output> partials(subproblems.size()-1);
147 #pragma omp single nowait 149 auto i = subproblems.begin() + 1;
150 for (i; i!=subproblems.end() && num_threads.load()>0; i++, division++) {
152 #pragma omp task firstprivate(i,division) \ 153 shared(partials,divide_op,solve_op,combine_op,num_threads) 156 std::forward<Divider>(divide_op),
157 std::forward<Solver>(solve_op),
158 std::forward<Combiner>(combine_op), num_threads);
164 for (i; i!=subproblems.end(); i++) {
166 std::forward<Divider>(divide_op),
167 std::forward<Solver>(solve_op),
168 std::forward<Combiner>(combine_op));
172 if (num_threads.load()>0) {
174 std::forward<Divider>(divide_op),
175 std::forward<Solver>(solve_op),
176 std::forward<Combiner>(combine_op), num_threads);
180 std::forward<Divider>(divide_op),
181 std::forward<Solver>(solve_op),
182 std::forward<Combiner>(combine_op));
188 for (
auto && p : partials) { out = combine_op(out,p); }
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
OpenMP parallel execution policy.
Definition: parallel_execution_omp.h:40
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
int concurrency_degree() const noexcept
Get number of grppi trheads.
Definition: parallel_execution_omp.h:85