void forkjoin(loop_by_eager_binary_splitting<Granularity_control_policy>& lpalgo, const Skel_cutoff_fct& skel_cutoff_fct, const Skel_complexity_measure_fct& skel_compl_fct, Input& input, Output& output, const Input_empty_fct& input_empty_fct, const Fork_input_fct& fork_input_fct, const Join_output_fct& join_output_fct, const Body& body) { auto seq_fct = [&] { body(input, output); }; if (input_empty_fct(input)) { seq_fct(); } else { auto cutoff_fct = [&] { return skel_cutoff_fct(input); }; auto compl_fct = [&] { return skel_compl_fct(input); }; Input input2; Output output2; fork_input_fct(input, input2); cstmt(lpalgo.gcpolicy, cutoff_fct, compl_fct, [&] { fork2([&] { forkjoin(lpalgo, skel_cutoff_fct, skel_compl_fct, input, output, input_empty_fct, fork_input_fct, join_output_fct, body); }, [&] { forkjoin(lpalgo, skel_cutoff_fct, skel_compl_fct, input2, output2, input_empty_fct, fork_input_fct, join_output_fct, body); }); }, seq_fct); join_output_fct(output, output2); } }
void forkjoin(Input& in, Output& out, const Cutoff& cutoff, const Fork_input& fork, const Join_output& join, const Body& body) { auto set_in_env = [] (Input&) { }; auto set_out_env = [] (Output&) { }; forkjoin(in, out, cutoff, fork, join, set_in_env, set_out_env, body); }
void forkjoin(Input& in, Output& out, const Cutoff& cutoff, const Fork_input& fork, const Join_output& join, const Set_in_env& set_in_env, const Set_out_env& set_out_env, const Body& body) { if (cutoff(in)) { body(in, out); } else { Input in2; Output out2; set_in_env(in2); set_out_env(out2); fork(in, in2); fork2([&] { forkjoin(in, out, cutoff, fork, join, set_in_env, set_out_env, body); }, [&] { forkjoin(in2, out2, cutoff, fork, join, set_in_env, set_out_env, body); }); join(out, out2); } }
void combine(Number lo, Number hi, Output& out, const Join_output& join, const Body& body, const Cutoff& cutoff) { using range_type = std::pair<Number, Number>; range_type in(lo, hi); auto fork = [] (range_type& src, range_type& dst) { Number mid = (src.first + src.second) / 2; dst.first = mid; dst.second = src.second; src.second = mid; }; auto _body = [&body] (range_type r, Output& out) { Number lo = r.first; Number hi = r.second; for (Number i = lo; i < hi; i++) body(i, out); }; forkjoin(in, out, cutoff, fork, join, _body); }
Output combine(Loop_algo& lpalgo, const Range_cutoff_fct& range_cutoff_fct, const Range_complexity_measure_fct& range_compl_fct, Number lo, Number hi, Output id, const Assoc_comb_op& assoc_comb_op, const Body& body) { using index_range_type = std::pair<Number, Number>; index_range_type input(lo, hi); Output output = id; auto input_empty_fct = [] (index_range_type r) { return r.second - r.first < 2; }; auto fork_input_fct = [] (index_range_type& src, index_range_type& dst) { Number mid = (src.first + src.second) / 2; dst.first = mid; dst.second = src.second; src.second = mid; }; auto body2 = [&] (index_range_type r, Output& output) { Number lo = r.first; Number hi = r.second; Output tmp = output; for (Number i = lo; i < hi; i++) tmp = assoc_comb_op(tmp, body(i)); output = tmp; }; auto join_output_fct = [&] (Output& output1, Output& output2) { output1 = assoc_comb_op(output1, output2); output2 = id; }; auto pair_cutoff_fct = [&] (index_range_type input) { return range_cutoff_fct(input.first, input.second); }; auto pair_compl_fct = [&] (index_range_type input) { return range_cutoff_fct(input.first, input.second); }; forkjoin(lpalgo, pair_cutoff_fct, pair_compl_fct, input, output, input_empty_fct, fork_input_fct, join_output_fct, body2); return output; }