21 #ifndef GRPPI_TBB_PARALLEL_EXECUTION_TBB_H 22 #define GRPPI_TBB_PARALLEL_EXECUTION_TBB_H 26 #include "../common/mpmc_queue.h" 27 #include "../common/iterator.h" 28 #include "../common/patterns.h" 29 #include "../common/farm_pattern.h" 30 #include "../common/execution_traits.h" 32 #include <type_traits> 68 concurrency_degree_{concurrency_degree},
111 template <
typename T>
113 return {queue_size_, queue_mode_};
119 int tokens() const noexcept {
return num_tokens_; }
135 template <
typename ... InputIterators,
typename OutputIterator,
136 typename Transformer>
137 void map(std::tuple<InputIterators...> firsts,
138 OutputIterator first_out,
139 std::size_t sequence_size, Transformer transform_op)
const;
154 template <
typename InputIterator,
typename Identity,
typename Combiner>
155 auto reduce(InputIterator first, std::size_t sequence_size,
156 Identity && identity, Combiner && combine_op)
const;
172 template <
typename ... InputIterators,
typename Identity,
173 typename Transformer,
typename Combiner>
174 auto map_reduce(std::tuple<InputIterators...> firsts,
175 std::size_t sequence_size,
176 Identity && identity,
177 Transformer && transform_op, Combiner && combine_op)
const;
193 template <
typename ... InputIterators,
typename OutputIterator,
194 typename StencilTransformer,
typename Neighbourhood>
195 void stencil(std::tuple<InputIterators...> firsts, OutputIterator first_out,
196 std::size_t sequence_size,
197 StencilTransformer && transform_op,
198 Neighbourhood && neighbour_op)
const;
212 template <
typename Input,
typename Div
ider,
typename Solver,
typename Combiner>
213 [[deprecated(
"Use new interface with predicate argument")]]
215 Divider && divide_op,
217 Combiner && combine_op)
const;
234 template <
typename Input,
typename Div
ider,
typename Predicate,
typename Solver,
typename Combiner>
236 Divider && divide_op,
237 Predicate && predicate_op,
239 Combiner && combine_op)
const;
248 template <
typename Generator,
typename ... Transformers>
249 void pipeline(Generator && generate_op,
250 Transformers && ... transform_op)
const;
262 template <
typename InputType,
typename Transformer,
typename OutputType>
266 ::std::atomic<long> order {0};
269 auto item = input_queue.
pop();
270 if(!item.first) input_queue.
push(item);
273 std::forward<Transformer>(transform_op),
275 output_queue.
push(make_pair(
typename OutputType::first_type{item}, order.load()));
279 output_queue.
push(make_pair(
typename OutputType::first_type{}, order.load()));
287 template <
typename Input,
typename Div
ider,
typename Solver,
typename Combiner>
289 Divider && divide_op,
291 Combiner && combine_op,
292 std::atomic<int> & num_threads)
const;
294 template <
typename Input,
typename Div
ider,
typename Predicate,
typename Solver,
typename Combiner>
296 Divider && divide_op,
297 Predicate && predicate_op,
299 Combiner && combine_op,
300 std::atomic<int> & num_threads)
const;
302 template <
typename Input,
typename Transformer,
304 auto make_filter(Transformer && transform_op)
const;
306 template <
typename Input,
typename Transformer,
typename ... OtherTransformers,
307 requires_no_pattern<Transformer> = 0>
308 auto make_filter(Transformer && transform_op,
309 OtherTransformers && ... other_transform_ops)
const;
311 template <
typename Input,
typename FarmTransformer,
312 template <
typename>
class Farm,
314 auto make_filter(Farm<FarmTransformer> & farm_obj)
const 316 return this->
template make_filter<Input>(std::move(farm_obj));
319 template <
typename Input,
typename FarmTransformer,
320 template <
typename>
class Farm,
321 requires_farm<Farm<FarmTransformer>> = 0>
322 auto make_filter(Farm<FarmTransformer> && farm_obj)
const;
324 template <
typename Input,
typename Execution,
typename Transformer,
325 template <
typename,
typename>
class Context,
326 typename ... OtherTransformers,
328 auto make_filter(Context<Execution,Transformer> && context_op,
329 OtherTransformers &&... other_ops)
const 331 return this->
template make_filter<Input>(std::forward<Transformer>(context_op.transformer()),
332 std::forward<OtherTransformers>(other_ops)...);
335 template <
typename Input,
typename Execution,
typename Transformer,
336 template <
typename,
typename>
class Context,
337 typename ... OtherTransformers,
338 requires_context<Context<Execution,Transformer>> = 0>
339 auto make_filter(Context<Execution,Transformer> & context_op,
340 OtherTransformers &&... other_ops)
const 342 return this->
template make_filter<Input>(std::move(context_op),
343 std::forward<OtherTransformers>(other_ops)...);
347 template <
typename Input,
typename FarmTransformer,
348 template <
typename>
class Farm,
349 typename ... OtherTransformers,
350 requires_farm<Farm<FarmTransformer>> = 0>
351 auto make_filter(Farm<FarmTransformer> & filter_obj,
352 OtherTransformers && ... other_transform_ops)
const 354 return this->
template make_filter<Input>(std::move(filter_obj),
355 std::forward<OtherTransformers>(other_transform_ops)...);
358 template <
typename Input,
typename FarmTransformer,
359 template <
typename>
class Farm,
360 typename ... OtherTransformers,
361 requires_farm<Farm<FarmTransformer>> = 0>
362 auto make_filter(Farm<FarmTransformer> && filter_obj,
363 OtherTransformers && ... other_transform_ops)
const;
365 template <
typename Input,
typename Predicate,
366 template <
typename>
class Filter,
368 auto make_filter(Filter<Predicate> & filter_obj)
const 370 return this->
template make_filter<Input>(std::move(filter_obj));
373 template <
typename Input,
typename Predicate,
374 template <
typename>
class Filter,
375 requires_filter<Filter<Predicate>> = 0>
376 auto make_filter(Filter<Predicate> && filter_obj)
const;
378 template <
typename Input,
typename Predicate,
379 template <
typename>
class Filter,
380 typename ... OtherTransformers,
381 requires_filter<Filter<Predicate>> = 0>
382 auto make_filter(Filter<Predicate> & filter_obj,
383 OtherTransformers && ... other_transform_ops)
const 385 return this->
template make_filter<Input>(std::move(filter_obj),
386 std::forward<OtherTransformers>(other_transform_ops)...);
389 template <
typename Input,
typename Predicate,
390 template <
typename>
class Filter,
391 typename ... OtherTransformers,
392 requires_filter<Filter<Predicate>> = 0>
393 auto make_filter(Filter<Predicate> && filter_obj,
394 OtherTransformers && ... other_transform_ops)
const;
396 template <
typename Input,
typename Combiner,
typename Identity,
397 template <
typename C,
typename I>
class Reduce,
398 typename ... OtherTransformers,
400 auto make_filter(Reduce<Combiner,Identity> & reduce_obj,
401 OtherTransformers && ... other_transform_ops)
const 403 return this->
template make_filter<Input>(std::move(reduce_obj),
404 std::forward<OtherTransformers>(other_transform_ops)...);
407 template <
typename Input,
typename Combiner,
typename Identity,
408 template <
typename C,
typename I>
class Reduce,
409 typename ... OtherTransformers,
410 requires_reduce<Reduce<Combiner,Identity>> = 0>
411 auto make_filter(Reduce<Combiner,Identity> && reduce_obj,
412 OtherTransformers && ... other_transform_ops)
const;
414 template <
typename Input,
typename Transformer,
typename Predicate,
415 template <
typename T,
typename P>
class Iteration,
416 typename ... OtherTransformers,
418 requires_no_pattern<Transformer> =0>
419 auto make_filter(Iteration<Transformer,Predicate> & iteration_obj,
420 OtherTransformers && ... other_transform_ops)
const 422 return this->
template make_filter<Input>(std::move(iteration_obj),
423 std::forward<OtherTransformers>(other_transform_ops)...);
426 template <
typename Input,
typename Transformer,
typename Predicate,
427 template <
typename T,
typename P>
class Iteration,
428 typename ... OtherTransformers,
429 requires_iteration<Iteration<Transformer,Predicate>> =0,
430 requires_no_pattern<Transformer> =0>
431 auto make_filter(Iteration<Transformer,Predicate> && iteration_obj,
432 OtherTransformers && ... other_transform_ops)
const;
434 template <
typename Input,
typename Transformer,
typename Predicate,
435 template <
typename T,
typename P>
class Iteration,
436 typename ... OtherTransformers,
437 requires_iteration<Iteration<Transformer,Predicate>> =0,
439 auto make_filter(Iteration<Transformer,Predicate> && iteration_obj,
440 OtherTransformers && ... other_transform_ops)
const;
442 template <
typename Input,
typename ... Transformers,
443 template <
typename...>
class Pipeline,
444 typename ... OtherTransformers,
446 auto make_filter(Pipeline<Transformers...> & pipeline_obj,
447 OtherTransformers && ... other_transform_ops)
const 449 return this->
template make_filter<Input>(std::move(pipeline_obj),
450 std::forward<OtherTransformers>(other_transform_ops)...);
453 template <
typename Input,
typename ... Transformers,
454 template <
typename...>
class Pipeline,
455 typename ... OtherTransformers,
457 auto make_filter(Pipeline<Transformers...> && pipeline_obj,
458 OtherTransformers && ... other_transform_ops)
const;
460 template <
typename Input,
typename ... Transformers,
462 auto make_filter_nested(std::tuple<Transformers...> && transform_ops,
463 std::index_sequence<I...>)
const;
467 constexpr
static int default_concurrency_degree = 4;
468 int concurrency_degree_ = default_concurrency_degree;
470 bool ordering_ =
true;
472 constexpr
static int default_queue_size = 100;
473 int queue_size_ = default_queue_size;
475 constexpr
static int default_num_tokens_ = 100;
476 int num_tokens_ = default_num_tokens_;
485 template <
typename E>
487 return std::is_same<E, parallel_execution_tbb>::value;
539 template <
typename ... InputIterators,
typename OutputIterator,
540 typename Transformer>
542 std::tuple<InputIterators...> firsts,
543 OutputIterator first_out,
544 std::size_t sequence_size, Transformer transform_op)
const 547 std::size_t{0}, sequence_size,
548 [&] (std::size_t index){
555 template <
typename InputIterator,
typename Identity,
typename Combiner>
558 std::size_t sequence_size,
559 Identity && identity,
560 Combiner && combine_op)
const 563 return tbb::parallel_reduce(
564 tbb::blocked_range<InputIterator>(first, std::next(first,sequence_size)),
566 [combine_op,seq](
const auto & range,
auto value) {
567 return seq.reduce(range.begin(), range.size(), value, combine_op);
572 template <
typename ... InputIterators,
typename Identity,
573 typename Transformer,
typename Combiner>
575 std::tuple<InputIterators...> firsts,
576 std::size_t sequence_size,
577 Identity && identity,
578 Transformer && transform_op, Combiner && combine_op)
const 584 std::vector<result_type> partial_results(concurrency_degree_);
586 auto process_chunk = [&](
auto fins, std::size_t sz, std::size_t i) {
587 partial_results[i] = seq.map_reduce(fins, sz,
588 std::forward<result_type>(partial_results[i]),
589 std::forward<Transformer>(transform_op),
590 std::forward<Combiner>(combine_op));
593 const auto chunk_size = sequence_size/concurrency_degree_;
595 for(
int i=0; i<concurrency_degree_-1;++i) {
596 const auto delta = chunk_size * i;
598 const auto chunk_last = std::next(std::get<0>(chunk_firsts), chunk_size);
600 g.run([&, chunk_firsts, chunk_last, i]() {
601 process_chunk(chunk_firsts, chunk_size, i);
605 const auto delta = chunk_size * (concurrency_degree_ - 1);
607 process_chunk(chunk_firsts, sequence_size - delta, concurrency_degree_-1);
611 return seq.reduce(std::next(partial_results.begin()),
612 partial_results.size()-1, std::forward<result_type>(partial_results[0]),
613 std::forward<Combiner>(combine_op));
616 template <
typename ... InputIterators,
typename OutputIterator,
617 typename StencilTransformer,
typename Neighbourhood>
619 std::tuple<InputIterators...> firsts, OutputIterator first_out,
620 std::size_t sequence_size,
621 StencilTransformer && transform_op,
622 Neighbourhood && neighbour_op)
const 625 const auto chunk_size = sequence_size / concurrency_degree_;
626 auto process_chunk = [&](
auto f, std::size_t sz, std::size_t delta) {
627 seq.stencil(f, std::next(first_out,delta), sz,
628 std::forward<StencilTransformer>(transform_op),
629 std::forward<Neighbourhood>(neighbour_op));
633 for (
int i=0; i<concurrency_degree_-1; ++i) {
635 const auto delta = chunk_size * i;
637 process_chunk(chunk_firsts, chunk_size, delta);
641 const auto delta = chunk_size * (concurrency_degree_ - 1);
643 const auto chunk_last = std::next(std::get<0>(firsts), sequence_size);
644 process_chunk(chunk_firsts,
645 std::distance(std::get<0>(chunk_firsts), chunk_last), delta);
650 template <
typename Input,
typename Div
ider,
typename Solver,
typename Combiner>
653 Divider && divide_op,
655 Combiner && combine_op)
const 657 std::atomic<int> num_threads{concurrency_degree_-1};
659 std::forward<Divider>(divide_op), std::forward<Solver>(solve_op),
660 std::forward<Combiner>(combine_op), num_threads);
663 template <
typename Input,
typename Div
ider,
typename Predicate,
typename Solver,
typename Combiner>
666 Divider && divide_op,
667 Predicate && predicate_op,
669 Combiner && combine_op)
const 671 std::atomic<int> num_threads{concurrency_degree_-1};
673 std::forward<Divider>(divide_op), std::forward<Predicate>(predicate_op),
674 std::forward<Solver>(solve_op),
675 std::forward<Combiner>(combine_op), num_threads);
679 template <
typename Generator,
typename ... Transformers>
681 Generator && generate_op,
682 Transformers && ... transform_ops)
const 685 using namespace experimental;
687 using result_type = decay_t<typename result_of<Generator()>::type>;
689 using output_type = optional<output_value_type>;
691 auto generator = tbb::make_filter<void, output_type>(
692 tbb::filter::serial_in_order,
693 [&](tbb::flow_control & fc) -> output_type {
694 auto item = generate_op();
706 this->
template make_filter<output_value_type>(forward<Transformers>(transform_ops)...);
709 tbb::task_group_context context;
710 tbb::parallel_pipeline(
tokens(),
718 template <
typename Input,
typename Div
ider,
typename Solver,
typename Combiner>
721 Divider && divide_op,
723 Combiner && combine_op,
724 std::atomic<int> & num_threads)
const 728 if (num_threads.load()<=0) {
730 std::forward<Divider>(divide_op), std::forward<Solver>(solve_op),
731 std::forward<Combiner>(combine_op));
734 auto subproblems = divide_op(std::forward<Input>(input));
736 if (subproblems.size()<=1) {
return solve_op(std::forward<Input>(input)); }
738 using subresult_type = std::decay_t<typename std::result_of<Solver(Input)>::type>;
739 std::vector<subresult_type> partials(subproblems.size()-1);
743 auto i = subproblems.begin()+1;
744 while (i!=subproblems.end() && num_threads.load()>0) {
745 g.run([&,
this,it=i++,div=division++]() {
747 std::forward<Divider>(divide_op), std::forward<Solver>(solve_op),
748 std::forward<Combiner>(combine_op), num_threads);
754 while (i != subproblems.end()){
755 partials[division] = seq.divide_conquer(std::forward<Input>(*i++),
756 std::forward<Divider>(divide_op), std::forward<Solver>(solve_op),
757 std::forward<Combiner>(combine_op));
760 auto out =
divide_conquer(std::forward<Input>(*subproblems.begin()),
761 std::forward<Divider>(divide_op), std::forward<Solver>(solve_op),
762 std::forward<Combiner>(combine_op), num_threads);
766 return seq.reduce(partials.begin(), partials.size(),
767 std::forward<subresult_type>(out), std::forward<Combiner>(combine_op));
770 template <
typename Input,
typename Div
ider,
typename Predicate,
typename Solver,
typename Combiner>
773 Divider && divide_op,
774 Predicate && predicate_op,
776 Combiner && combine_op,
777 std::atomic<int> & num_threads)
const 781 if (num_threads.load()<=0) {
783 std::forward<Divider>(divide_op),std::forward<Predicate>(predicate_op),
784 std::forward<Solver>(solve_op),
785 std::forward<Combiner>(combine_op));
789 if (predicate_op(input)) {
return solve_op(std::forward<Input>(input)); }
790 auto subproblems = divide_op(std::forward<Input>(input));
792 using subresult_type = std::decay_t<typename std::result_of<Solver(Input)>::type>;
793 std::vector<subresult_type> partials(subproblems.size()-1);
797 auto i = subproblems.begin()+1;
798 while (i!=subproblems.end() && num_threads.load()>0) {
799 g.run([&,
this,it=i++,div=division++]() {
801 std::forward<Divider>(divide_op), std::forward<Predicate>(predicate_op),
802 std::forward<Solver>(solve_op),
803 std::forward<Combiner>(combine_op), num_threads);
809 while (i != subproblems.end()){
810 partials[division] = seq.divide_conquer(std::forward<Input>(*i++),
811 std::forward<Divider>(divide_op), std::forward<Predicate>(predicate_op),
812 std::forward<Solver>(solve_op),
813 std::forward<Combiner>(combine_op));
816 auto out =
divide_conquer(std::forward<Input>(*subproblems.begin()),
817 std::forward<Divider>(divide_op), std::forward<Predicate>(predicate_op), std::forward<Solver>(solve_op),
818 std::forward<Combiner>(combine_op), num_threads);
822 return seq.reduce(partials.begin(), partials.size(),
823 std::forward<subresult_type>(out), std::forward<Combiner>(combine_op));
826 template <
typename Input,
typename Transformer,
828 auto parallel_execution_tbb::make_filter(
829 Transformer && transform_op)
const 832 using namespace experimental;
834 using input_value_type = Input;
835 using gen_value_type = optional<input_value_type>;
837 return tbb::make_filter<gen_value_type, void>(
838 tbb::filter::serial_in_order,
839 [=](gen_value_type item) {
840 if (item) transform_op(*item);
844 template <
typename Input,
typename Transformer,
typename ... OtherTransformers,
846 auto parallel_execution_tbb::make_filter(
847 Transformer && transform_op,
848 OtherTransformers && ... other_transform_ops)
const 851 using namespace experimental;
853 using input_value_type = Input;
854 static_assert(!is_void<input_value_type>::value,
855 "Transformer must take non-void argument");
856 using gen_value_type = optional<input_value_type>;
858 decay_t<typename result_of<Transformer(input_value_type)>::type>;
859 static_assert(!is_void<output_value_type>::value,
860 "Transformer must return a non-void result");
861 using output_type = optional<output_value_type>;
865 tbb::make_filter<gen_value_type, output_type>(
866 tbb::filter::serial_in_order,
867 [=](gen_value_type item) -> output_type {
868 if (item)
return transform_op(*item);
872 this->
template make_filter<output_value_type>(
873 std::forward<OtherTransformers>(other_transform_ops)...);
876 template <
typename Input,
typename FarmTransformer,
877 template <
typename>
class Farm,
879 auto parallel_execution_tbb::make_filter(
880 Farm<FarmTransformer> && farm_obj)
const 883 using namespace experimental;
885 using input_value_type = Input;
886 using gen_value_type = optional<input_value_type>;
888 return tbb::make_filter<gen_value_type, void>(
889 tbb::filter::parallel,
890 [=](gen_value_type item) {
891 if (item) farm_obj(*item);
895 template <
typename Input,
typename FarmTransformer,
896 template <
typename>
class Farm,
897 typename ... OtherTransformers,
899 auto parallel_execution_tbb::make_filter(
900 Farm<FarmTransformer> && farm_obj,
901 OtherTransformers && ... other_transform_ops)
const 904 using namespace experimental;
906 using input_value_type = Input;
907 static_assert(!is_void<input_value_type>::value,
908 "Farm must take non-void argument");
909 using gen_value_type = optional<input_value_type>;
910 using output_value_type = decay_t<typename result_of<FarmTransformer(input_value_type)>::type>;
911 static_assert(!is_void<output_value_type>::value,
912 "Farm must return a non-void result");
913 using output_type = optional<output_value_type>;
915 return tbb::make_filter<gen_value_type, output_type>(
916 tbb::filter::parallel,
917 [&](gen_value_type item) -> output_type {
918 if (item)
return farm_obj(*item);
922 this->
template make_filter<output_value_type>(
923 std::forward<OtherTransformers>(other_transform_ops)...);
926 template <
typename Input,
typename Predicate,
927 template <
typename>
class Filter,
929 auto parallel_execution_tbb::make_filter(
930 Filter<Predicate> && farm_obj)
const 933 using namespace experimental;
935 using input_value_type = Input;
936 using gen_value_type = optional<input_value_type>;
938 return tbb::make_filter<gen_value_type, void>(
939 tbb::filter::parallel,
940 [=](gen_value_type item) {
941 if (item) filter_obj(*item);
945 template <
typename Input,
typename Predicate,
946 template <
typename>
class Filter,
947 typename ... OtherTransformers,
949 auto parallel_execution_tbb::make_filter(
950 Filter<Predicate> && filter_obj,
951 OtherTransformers && ... other_transform_ops)
const 954 using namespace experimental;
956 using input_value_type = Input;
957 static_assert(!is_void<input_value_type>::value,
958 "Filter must take non-void argument");
959 using gen_value_type = optional<input_value_type>;
961 return tbb::make_filter<gen_value_type, gen_value_type>(
962 tbb::filter::parallel,
963 [&](gen_value_type item) -> gen_value_type {
964 if (item && filter_obj(*item))
return item;
968 this->
template make_filter<input_value_type>(
969 std::forward<OtherTransformers>(other_transform_ops)...);
972 template <
typename Input,
typename Combiner,
typename Identity,
973 template <
typename C,
typename I>
class Reduce,
974 typename ... OtherTransformers,
976 auto parallel_execution_tbb::make_filter(
977 Reduce<Combiner,Identity> && reduce_obj,
978 OtherTransformers && ... other_transform_ops)
const 981 using namespace experimental;
983 using input_value_type = Input;
984 using gen_value_type = optional<input_value_type>;
986 std::atomic<long int> order{0};
987 return tbb::make_filter<gen_value_type, gen_value_type>(
989 [&, it=std::vector<input_value_type>(), rem=0](gen_value_type item) -> gen_value_type {
990 if (!item)
return {};
991 reduce_obj.add_item(std::forward<Identity>(*item));
992 if (reduce_obj.reduction_needed()) {
994 return reduce_obj.reduce_window(seq);
999 this->
template make_filter<input_value_type>(
1000 std::forward<OtherTransformers>(other_transform_ops)...);
1003 template <
typename Input,
typename Transformer,
typename Predicate,
1004 template <
typename T,
typename P>
class Iteration,
1005 typename ... OtherTransformers,
1008 auto parallel_execution_tbb::make_filter(
1009 Iteration<Transformer,Predicate> && iteration_obj,
1010 OtherTransformers && ... other_transform_ops)
const 1012 using namespace std;
1013 using namespace experimental;
1015 using input_value_type = Input;
1016 using gen_value_type = optional<input_value_type>;
1018 return tbb::make_filter<gen_value_type, gen_value_type>(
1019 tbb::filter::serial,
1020 [&](gen_value_type item) -> gen_value_type {
1021 if (!item)
return {};
1023 item = iteration_obj.transform(*item);
1024 }
while (!iteration_obj.predicate(*item));
1028 this->
template make_filter<input_value_type>(
1029 std::forward<OtherTransformers>(other_transform_ops)...);
1032 template <
typename Input,
typename Transformer,
typename Predicate,
1033 template <
typename T,
typename P>
class Iteration,
1034 typename ... OtherTransformers,
1035 requires_iteration<Iteration<Transformer,Predicate>>,
1037 auto parallel_execution_tbb::make_filter(
1038 Iteration<Transformer,Predicate> && iteration_obj,
1039 OtherTransformers && ... other_transform_ops)
const 1041 static_assert(!is_pipeline<Transformer>,
"Not implemented");
1046 template <
typename Input,
typename ... Transformers,
1047 template <
typename...>
class Pipeline,
1048 typename ... OtherTransformers,
1050 auto parallel_execution_tbb::make_filter(
1051 Pipeline<Transformers...> && pipeline_obj,
1052 OtherTransformers && ... other_transform_ops)
const 1054 return this->
template make_filter_nested<Input>(
1055 std::tuple_cat(pipeline_obj.transformers(),
1056 std::forward_as_tuple(other_transform_ops...)),
1057 std::make_index_sequence<
sizeof...(Transformers)+
sizeof...(OtherTransformers)>());
1060 template <
typename Input,
typename ... Transformers,
1062 auto parallel_execution_tbb::make_filter_nested(
1063 std::tuple<Transformers...> && transform_ops,
1064 std::index_sequence<I...>)
const 1066 return this->
template make_filter<Input>(
1067 std::forward<Transformers>(std::get<I>(transform_ops))...);
1073 #else // GRPPI_TBB not defined 1086 template <
typename E>
Definition: callable_traits.h:26
std::enable_if_t< is_reduce< T >, int > requires_reduce
Definition: reduce_pattern.h:135
constexpr bool supports_reduce< parallel_execution_tbb >()
Determines if an execution policy supports the reduce pattern.
Definition: parallel_execution_tbb.h:509
constexpr bool is_supported< parallel_execution_tbb >()
Determines if an execution policy is supported in the current compilation.
Definition: parallel_execution_tbb.h:495
int tokens() const noexcept
Definition: parallel_execution_tbb.h:119
typename std::enable_if_t< is_iteration< T >, int > requires_iteration
Definition: iteration_pattern.h:88
void disable_ordering() noexcept
Disable ordering.
Definition: parallel_execution_tbb.h:90
constexpr bool is_parallel_execution_tbb()
Metafunction that determines if type E is parallel_execution_tbb.
Definition: parallel_execution_tbb.h:486
void pipeline(mpmc_queue< InputType > &input_queue, Transformer &&transform_op, mpmc_queue< OutputType > &output_queue) const
Invoke Pipeline pattern comming from another context that uses mpmc_queues as communication channels...
Definition: parallel_execution_tbb.h:263
auto iterators_next(T &&t, int n)
Computes next n steps from a tuple of iterators.
Definition: iterator.h:175
decltype(auto) apply_iterators_indexed(F &&f, T &&t, std::size_t i)
Applies a callable object to the values obtained from the iterators in a tuple by indexing...
Definition: iterator.h:147
typename internal::output_value_type< I, T >::type output_value_type
Definition: pipeline_pattern.h:132
queue_mode
Definition: mpmc_queue.h:35
void set_concurrency_degree(int degree) noexcept
Set number of grppi threads.
Definition: parallel_execution_tbb.h:75
constexpr bool supports_map< parallel_execution_tbb >()
Determines if an execution policy supports the map pattern.
Definition: parallel_execution_tbb.h:502
void set_queue_attributes(int size, queue_mode mode, int tokens) noexcept
Sets the attributes for the queues built through make_queue<T>()
Definition: parallel_execution_tbb.h:100
Definition: mpmc_queue.h:38
mpmc_queue< T > make_queue() const
Makes a communication queue for elements of type T. Constructs a queue using the attributes that can ...
Definition: parallel_execution_tbb.h:112
parallel_execution_tbb() noexcept
Default construct a TBB parallel execution policy.
Definition: parallel_execution_tbb.h:55
parallel_execution_tbb(int concurrency_degree, bool order=true) noexcept
Constructs a TBB parallel execution policy.
Definition: parallel_execution_tbb.h:67
void map(std::tuple< InputIterators... > firsts, OutputIterator first_out, std::size_t sequence_size, Transformer transform_op) const
Applies a trasnformation to multiple sequences leaving the result in another sequence using available...
Definition: parallel_execution_tbb.h:541
TBB parallel execution policy.
Definition: parallel_execution_tbb.h:44
std::enable_if_t< is_no_pattern< T >, int > requires_no_pattern
Definition: patterns.h:92
typename std::enable_if_t< is_pipeline< T >, int > requires_pipeline
Definition: pipeline_pattern.h:111
void pipeline(Generator &&generate_op, Transformers &&...transform_op) const
Invoke Pipeline pattern.
Definition: parallel_execution_tbb.h:680
int concurrency_degree() const noexcept
Get number of grppi trheads.
Definition: parallel_execution_tbb.h:80
typename std::enable_if_t< is_filter< T >, int > requires_filter
Definition: filter_pattern.h:70
constexpr bool supports_divide_conquer< parallel_execution_tbb >()
Determines if an execution policy supports the divide/conquer pattern.
Definition: parallel_execution_tbb.h:530
Sequential execution policy.
Definition: sequential_execution.h:41
auto divide_conquer(Input &&input, Divider &÷_op, Solver &&solve_op, Combiner &&combine_op) const
Invoke Divide/conquer pattern.
Definition: sequential_execution.h:543
typename std::result_of< Transformer(Input)>::type result_type
Determines the return type of appliying a function on a input type.
Definition: patterns.h:110
auto divide_conquer(Input &&input, Divider &÷_op, Solver &&solve_op, Combiner &&combine_op) const
Invoke Divide/conquer pattern.
Definition: parallel_execution_tbb.h:651
bool is_ordered() const noexcept
Is execution ordered.
Definition: parallel_execution_tbb.h:95
void enable_ordering() noexcept
Enable ordering.
Definition: parallel_execution_tbb.h:85
void stencil(std::tuple< InputIterators... > firsts, OutputIterator first_out, std::size_t sequence_size, StencilTransformer &&transform_op, Neighbourhood &&neighbour_op) const
Applies a trasnformation to multiple sequences leaving the result in another sequence.
Definition: parallel_execution_tbb.h:618
auto map_reduce(std::tuple< InputIterators... > firsts, std::size_t sequence_size, Identity &&identity, Transformer &&transform_op, Combiner &&combine_op) const
Applies a map/reduce operation to a sequence of data items.
Definition: parallel_execution_tbb.h:574
constexpr bool supports_map_reduce< parallel_execution_tbb >()
Determines if an execution policy supports the map-reduce pattern.
Definition: parallel_execution_tbb.h:516
auto reduce(InputIterator first, std::size_t sequence_size, Identity &&identity, Combiner &&combine_op) const
Applies a reduction to a sequence of data items.
Definition: parallel_execution_tbb.h:556
constexpr bool supports_pipeline< parallel_execution_tbb >()
Determines if an execution policy supports the pipeline pattern.
Definition: parallel_execution_tbb.h:537
T pop()
Definition: mpmc_queue.h:93
typename std::enable_if_t< is_context< T >, int > requires_context
Definition: common/context.h:95
bool push(T item)
Definition: mpmc_queue.h:128
typename std::enable_if_t< is_farm< T >, int > requires_farm
Definition: farm_pattern.h:89
constexpr bool supports_stencil< parallel_execution_tbb >()
Determines if an execution policy supports the stencil pattern.
Definition: parallel_execution_tbb.h:523