17 #ifndef KOKKOS_IMPL_PUBLIC_INCLUDE
18 #include <Kokkos_Macros.hpp>
20 "Including non-public Kokkos header files is not allowed.");
22 #ifndef KOKKOS_PARALLEL_REDUCE_HPP
23 #define KOKKOS_PARALLEL_REDUCE_HPP
25 #include <Kokkos_ReductionIdentity.hpp>
26 #include <Kokkos_View.hpp>
27 #include <impl/Kokkos_FunctorAnalysis.hpp>
28 #include <impl/Kokkos_Tools_Generic.hpp>
29 #include <type_traits>
33 template <
class Scalar,
class Space>
37 using reducer = Sum<Scalar, Space>;
38 using value_type = std::remove_cv_t<Scalar>;
39 static_assert(!std::is_pointer_v<value_type> && !std::is_array_v<value_type>);
44 result_view_type value;
45 bool references_scalar_v;
48 KOKKOS_INLINE_FUNCTION
49 Sum(value_type& value_) : value(&value_), references_scalar_v(true) {}
51 KOKKOS_INLINE_FUNCTION
52 Sum(
const result_view_type& value_)
53 : value(value_), references_scalar_v(false) {}
56 KOKKOS_INLINE_FUNCTION
57 void join(value_type& dest,
const value_type& src)
const { dest += src; }
59 KOKKOS_INLINE_FUNCTION
60 void init(value_type& val)
const {
61 val = reduction_identity<value_type>::sum();
64 KOKKOS_INLINE_FUNCTION
65 value_type& reference()
const {
return *value.data(); }
67 KOKKOS_INLINE_FUNCTION
68 result_view_type view()
const {
return value; }
70 KOKKOS_INLINE_FUNCTION
71 bool references_scalar()
const {
return references_scalar_v; }
74 template <
typename Scalar,
typename... Properties>
75 KOKKOS_DEDUCTION_GUIDE Sum(View<Scalar, Properties...>
const&)
76 ->Sum<Scalar,
typename View<Scalar, Properties...>::memory_space>;
78 template <
class Scalar,
class Space>
82 using reducer = Prod<Scalar, Space>;
83 using value_type = std::remove_cv_t<Scalar>;
84 static_assert(!std::is_pointer_v<value_type> && !std::is_array_v<value_type>);
89 result_view_type value;
90 bool references_scalar_v;
93 KOKKOS_INLINE_FUNCTION
94 Prod(value_type& value_) : value(&value_), references_scalar_v(true) {}
96 KOKKOS_INLINE_FUNCTION
97 Prod(
const result_view_type& value_)
98 : value(value_), references_scalar_v(false) {}
101 KOKKOS_INLINE_FUNCTION
102 void join(value_type& dest,
const value_type& src)
const { dest *= src; }
104 KOKKOS_INLINE_FUNCTION
105 void init(value_type& val)
const {
106 val = reduction_identity<value_type>::prod();
109 KOKKOS_INLINE_FUNCTION
110 value_type& reference()
const {
return *value.data(); }
112 KOKKOS_INLINE_FUNCTION
113 result_view_type view()
const {
return value; }
115 KOKKOS_INLINE_FUNCTION
116 bool references_scalar()
const {
return references_scalar_v; }
119 template <
typename Scalar,
typename... Properties>
120 KOKKOS_DEDUCTION_GUIDE Prod(View<Scalar, Properties...>
const&)
121 ->Prod<Scalar,
typename View<Scalar, Properties...>::memory_space>;
123 template <
class Scalar,
class Space>
127 using reducer = Min<Scalar, Space>;
128 using value_type = std::remove_cv_t<Scalar>;
129 static_assert(!std::is_pointer_v<value_type> && !std::is_array_v<value_type>);
134 result_view_type value;
135 bool references_scalar_v;
138 KOKKOS_INLINE_FUNCTION
139 Min(value_type& value_) : value(&value_), references_scalar_v(true) {}
141 KOKKOS_INLINE_FUNCTION
142 Min(
const result_view_type& value_)
143 : value(value_), references_scalar_v(false) {}
146 KOKKOS_INLINE_FUNCTION
147 void join(value_type& dest,
const value_type& src)
const {
148 if (src < dest) dest = src;
151 KOKKOS_INLINE_FUNCTION
152 void init(value_type& val)
const {
153 val = reduction_identity<value_type>::min();
156 KOKKOS_INLINE_FUNCTION
157 value_type& reference()
const {
return *value.data(); }
159 KOKKOS_INLINE_FUNCTION
160 result_view_type view()
const {
return value; }
162 KOKKOS_INLINE_FUNCTION
163 bool references_scalar()
const {
return references_scalar_v; }
166 template <
typename Scalar,
typename... Properties>
167 KOKKOS_DEDUCTION_GUIDE Min(View<Scalar, Properties...>
const&)
168 ->Min<Scalar,
typename View<Scalar, Properties...>::memory_space>;
170 template <
class Scalar,
class Space>
174 using reducer = Max<Scalar, Space>;
175 using value_type = std::remove_cv_t<Scalar>;
176 static_assert(!std::is_pointer_v<value_type> && !std::is_array_v<value_type>);
181 result_view_type value;
182 bool references_scalar_v;
185 KOKKOS_INLINE_FUNCTION
186 Max(value_type& value_) : value(&value_), references_scalar_v(true) {}
188 KOKKOS_INLINE_FUNCTION
189 Max(
const result_view_type& value_)
190 : value(value_), references_scalar_v(false) {}
193 KOKKOS_INLINE_FUNCTION
194 void join(value_type& dest,
const value_type& src)
const {
195 if (src > dest) dest = src;
199 KOKKOS_INLINE_FUNCTION
200 void init(value_type& val)
const {
201 val = reduction_identity<value_type>::max();
204 KOKKOS_INLINE_FUNCTION
205 value_type& reference()
const {
return *value.data(); }
207 KOKKOS_INLINE_FUNCTION
208 result_view_type view()
const {
return value; }
210 KOKKOS_INLINE_FUNCTION
211 bool references_scalar()
const {
return references_scalar_v; }
214 template <
typename Scalar,
typename... Properties>
215 KOKKOS_DEDUCTION_GUIDE Max(View<Scalar, Properties...>
const&)
216 ->Max<Scalar,
typename View<Scalar, Properties...>::memory_space>;
218 template <
class Scalar,
class Space>
222 using reducer = LAnd<Scalar, Space>;
223 using value_type = std::remove_cv_t<Scalar>;
224 static_assert(!std::is_pointer_v<value_type> && !std::is_array_v<value_type>);
229 result_view_type value;
230 bool references_scalar_v;
233 KOKKOS_INLINE_FUNCTION
234 LAnd(value_type& value_) : value(&value_), references_scalar_v(true) {}
236 KOKKOS_INLINE_FUNCTION
237 LAnd(
const result_view_type& value_)
238 : value(value_), references_scalar_v(false) {}
240 KOKKOS_INLINE_FUNCTION
241 void join(value_type& dest,
const value_type& src)
const {
245 KOKKOS_INLINE_FUNCTION
246 void init(value_type& val)
const {
247 val = reduction_identity<value_type>::land();
250 KOKKOS_INLINE_FUNCTION
251 value_type& reference()
const {
return *value.data(); }
253 KOKKOS_INLINE_FUNCTION
254 result_view_type view()
const {
return value; }
256 KOKKOS_INLINE_FUNCTION
257 bool references_scalar()
const {
return references_scalar_v; }
260 template <
typename Scalar,
typename... Properties>
261 KOKKOS_DEDUCTION_GUIDE LAnd(View<Scalar, Properties...>
const&)
262 ->LAnd<Scalar,
typename View<Scalar, Properties...>::memory_space>;
264 template <
class Scalar,
class Space>
268 using reducer = LOr<Scalar, Space>;
269 using value_type = std::remove_cv_t<Scalar>;
270 static_assert(!std::is_pointer_v<value_type> && !std::is_array_v<value_type>);
275 result_view_type value;
276 bool references_scalar_v;
279 KOKKOS_INLINE_FUNCTION
280 LOr(value_type& value_) : value(&value_), references_scalar_v(true) {}
282 KOKKOS_INLINE_FUNCTION
283 LOr(
const result_view_type& value_)
284 : value(value_), references_scalar_v(false) {}
287 KOKKOS_INLINE_FUNCTION
288 void join(value_type& dest,
const value_type& src)
const {
292 KOKKOS_INLINE_FUNCTION
293 void init(value_type& val)
const {
294 val = reduction_identity<value_type>::lor();
297 KOKKOS_INLINE_FUNCTION
298 value_type& reference()
const {
return *value.data(); }
300 KOKKOS_INLINE_FUNCTION
301 result_view_type view()
const {
return value; }
303 KOKKOS_INLINE_FUNCTION
304 bool references_scalar()
const {
return references_scalar_v; }
307 template <
typename Scalar,
typename... Properties>
308 KOKKOS_DEDUCTION_GUIDE LOr(View<Scalar, Properties...>
const&)
309 ->LOr<Scalar,
typename View<Scalar, Properties...>::memory_space>;
311 template <
class Scalar,
class Space>
315 using reducer = BAnd<Scalar, Space>;
316 using value_type = std::remove_cv_t<Scalar>;
317 static_assert(!std::is_pointer_v<value_type> && !std::is_array_v<value_type>);
322 result_view_type value;
323 bool references_scalar_v;
326 KOKKOS_INLINE_FUNCTION
327 BAnd(value_type& value_) : value(&value_), references_scalar_v(true) {}
329 KOKKOS_INLINE_FUNCTION
330 BAnd(
const result_view_type& value_)
331 : value(value_), references_scalar_v(false) {}
334 KOKKOS_INLINE_FUNCTION
335 void join(value_type& dest,
const value_type& src)
const {
339 KOKKOS_INLINE_FUNCTION
340 void init(value_type& val)
const {
341 val = reduction_identity<value_type>::band();
344 KOKKOS_INLINE_FUNCTION
345 value_type& reference()
const {
return *value.data(); }
347 KOKKOS_INLINE_FUNCTION
348 result_view_type view()
const {
return value; }
350 KOKKOS_INLINE_FUNCTION
351 bool references_scalar()
const {
return references_scalar_v; }
354 template <
typename Scalar,
typename... Properties>
355 KOKKOS_DEDUCTION_GUIDE BAnd(View<Scalar, Properties...>
const&)
356 ->BAnd<Scalar,
typename View<Scalar, Properties...>::memory_space>;
358 template <
class Scalar,
class Space>
362 using reducer = BOr<Scalar, Space>;
363 using value_type = std::remove_cv_t<Scalar>;
364 static_assert(!std::is_pointer_v<value_type> && !std::is_array_v<value_type>);
369 result_view_type value;
370 bool references_scalar_v;
373 KOKKOS_INLINE_FUNCTION
374 BOr(value_type& value_) : value(&value_), references_scalar_v(true) {}
376 KOKKOS_INLINE_FUNCTION
377 BOr(
const result_view_type& value_)
378 : value(value_), references_scalar_v(false) {}
381 KOKKOS_INLINE_FUNCTION
382 void join(value_type& dest,
const value_type& src)
const {
386 KOKKOS_INLINE_FUNCTION
387 void init(value_type& val)
const {
388 val = reduction_identity<value_type>::bor();
391 KOKKOS_INLINE_FUNCTION
392 value_type& reference()
const {
return *value.data(); }
394 KOKKOS_INLINE_FUNCTION
395 result_view_type view()
const {
return value; }
397 KOKKOS_INLINE_FUNCTION
398 bool references_scalar()
const {
return references_scalar_v; }
401 template <
typename Scalar,
typename... Properties>
402 KOKKOS_DEDUCTION_GUIDE BOr(View<Scalar, Properties...>
const&)
403 ->BOr<Scalar,
typename View<Scalar, Properties...>::memory_space>;
405 template <
class Scalar,
class Index>
406 struct ValLocScalar {
411 template <
class Scalar,
class Index,
class Space>
414 using scalar_type = std::remove_cv_t<Scalar>;
415 using index_type = std::remove_cv_t<Index>;
416 static_assert(!std::is_pointer_v<scalar_type> &&
417 !std::is_array_v<scalar_type>);
421 using reducer = MinLoc<Scalar, Index, Space>;
422 using value_type = ValLocScalar<scalar_type, index_type>;
427 result_view_type value;
428 bool references_scalar_v;
431 KOKKOS_INLINE_FUNCTION
432 MinLoc(value_type& value_) : value(&value_), references_scalar_v(true) {}
434 KOKKOS_INLINE_FUNCTION
435 MinLoc(
const result_view_type& value_)
436 : value(value_), references_scalar_v(false) {}
439 KOKKOS_INLINE_FUNCTION
440 void join(value_type& dest,
const value_type& src)
const {
441 if (src.val < dest.val) dest = src;
444 KOKKOS_INLINE_FUNCTION
445 void init(value_type& val)
const {
446 val.val = reduction_identity<scalar_type>::min();
447 val.loc = reduction_identity<index_type>::min();
450 KOKKOS_INLINE_FUNCTION
451 value_type& reference()
const {
return *value.data(); }
453 KOKKOS_INLINE_FUNCTION
454 result_view_type view()
const {
return value; }
456 KOKKOS_INLINE_FUNCTION
457 bool references_scalar()
const {
return references_scalar_v; }
460 template <
typename Scalar,
typename Index,
typename... Properties>
461 KOKKOS_DEDUCTION_GUIDE MinLoc(
462 View<ValLocScalar<Scalar, Index>, Properties...>
const&)
463 ->MinLoc<Scalar, Index,
464 typename View<ValLocScalar<Scalar, Index>,
465 Properties...>::memory_space>;
467 template <
class Scalar,
class Index,
class Space>
470 using scalar_type = std::remove_cv_t<Scalar>;
471 using index_type = std::remove_cv_t<Index>;
472 static_assert(!std::is_pointer_v<scalar_type> &&
473 !std::is_array_v<scalar_type>);
477 using reducer = MaxLoc<Scalar, Index, Space>;
478 using value_type = ValLocScalar<scalar_type, index_type>;
483 result_view_type value;
484 bool references_scalar_v;
487 KOKKOS_INLINE_FUNCTION
488 MaxLoc(value_type& value_) : value(&value_), references_scalar_v(true) {}
490 KOKKOS_INLINE_FUNCTION
491 MaxLoc(
const result_view_type& value_)
492 : value(value_), references_scalar_v(false) {}
495 KOKKOS_INLINE_FUNCTION
496 void join(value_type& dest,
const value_type& src)
const {
497 if (src.val > dest.val) dest = src;
500 KOKKOS_INLINE_FUNCTION
501 void init(value_type& val)
const {
502 val.val = reduction_identity<scalar_type>::max();
503 val.loc = reduction_identity<index_type>::min();
506 KOKKOS_INLINE_FUNCTION
507 value_type& reference()
const {
return *value.data(); }
509 KOKKOS_INLINE_FUNCTION
510 result_view_type view()
const {
return value; }
512 KOKKOS_INLINE_FUNCTION
513 bool references_scalar()
const {
return references_scalar_v; }
516 template <
typename Scalar,
typename Index,
typename... Properties>
517 KOKKOS_DEDUCTION_GUIDE MaxLoc(
518 View<ValLocScalar<Scalar, Index>, Properties...>
const&)
519 ->MaxLoc<Scalar, Index,
520 typename View<ValLocScalar<Scalar, Index>,
521 Properties...>::memory_space>;
523 template <
class Scalar>
524 struct MinMaxScalar {
525 Scalar min_val, max_val;
528 template <
class Scalar,
class Space>
531 using scalar_type = std::remove_cv_t<Scalar>;
532 static_assert(!std::is_pointer_v<scalar_type> &&
533 !std::is_array_v<scalar_type>);
537 using reducer = MinMax<Scalar, Space>;
538 using value_type = MinMaxScalar<scalar_type>;
543 result_view_type value;
544 bool references_scalar_v;
547 KOKKOS_INLINE_FUNCTION
548 MinMax(value_type& value_) : value(&value_), references_scalar_v(true) {}
550 KOKKOS_INLINE_FUNCTION
551 MinMax(
const result_view_type& value_)
552 : value(value_), references_scalar_v(false) {}
555 KOKKOS_INLINE_FUNCTION
556 void join(value_type& dest,
const value_type& src)
const {
557 if (src.min_val < dest.min_val) {
558 dest.min_val = src.min_val;
560 if (src.max_val > dest.max_val) {
561 dest.max_val = src.max_val;
565 KOKKOS_INLINE_FUNCTION
566 void init(value_type& val)
const {
567 val.max_val = reduction_identity<scalar_type>::max();
568 val.min_val = reduction_identity<scalar_type>::min();
571 KOKKOS_INLINE_FUNCTION
572 value_type& reference()
const {
return *value.data(); }
574 KOKKOS_INLINE_FUNCTION
575 result_view_type view()
const {
return value; }
577 KOKKOS_INLINE_FUNCTION
578 bool references_scalar()
const {
return references_scalar_v; }
581 template <
typename Scalar,
typename... Properties>
582 KOKKOS_DEDUCTION_GUIDE MinMax(View<MinMaxScalar<Scalar>, Properties...>
const&)
584 typename View<MinMaxScalar<Scalar>, Properties...>::memory_space>;
586 template <
class Scalar,
class Index>
587 struct MinMaxLocScalar {
588 Scalar min_val, max_val;
589 Index min_loc, max_loc;
592 template <
class Scalar,
class Index,
class Space>
595 using scalar_type = std::remove_cv_t<Scalar>;
596 using index_type = std::remove_cv_t<Index>;
597 static_assert(!std::is_pointer_v<scalar_type> &&
598 !std::is_array_v<scalar_type>);
602 using reducer = MinMaxLoc<Scalar, Index, Space>;
603 using value_type = MinMaxLocScalar<scalar_type, index_type>;
608 result_view_type value;
609 bool references_scalar_v;
612 KOKKOS_INLINE_FUNCTION
613 MinMaxLoc(value_type& value_) : value(&value_), references_scalar_v(true) {}
615 KOKKOS_INLINE_FUNCTION
616 MinMaxLoc(
const result_view_type& value_)
617 : value(value_), references_scalar_v(false) {}
620 KOKKOS_INLINE_FUNCTION
621 void join(value_type& dest,
const value_type& src)
const {
622 if (src.min_val < dest.min_val) {
623 dest.min_val = src.min_val;
624 dest.min_loc = src.min_loc;
626 if (src.max_val > dest.max_val) {
627 dest.max_val = src.max_val;
628 dest.max_loc = src.max_loc;
632 KOKKOS_INLINE_FUNCTION
633 void init(value_type& val)
const {
634 val.max_val = reduction_identity<scalar_type>::max();
635 val.min_val = reduction_identity<scalar_type>::min();
636 val.max_loc = reduction_identity<index_type>::min();
637 val.min_loc = reduction_identity<index_type>::min();
640 KOKKOS_INLINE_FUNCTION
641 value_type& reference()
const {
return *value.data(); }
643 KOKKOS_INLINE_FUNCTION
644 result_view_type view()
const {
return value; }
646 KOKKOS_INLINE_FUNCTION
647 bool references_scalar()
const {
return references_scalar_v; }
650 template <
typename Scalar,
typename Index,
typename... Properties>
651 KOKKOS_DEDUCTION_GUIDE MinMaxLoc(
652 View<MinMaxLocScalar<Scalar, Index>, Properties...>
const&)
653 ->MinMaxLoc<Scalar, Index,
654 typename View<MinMaxLocScalar<Scalar, Index>,
655 Properties...>::memory_space>;
664 template <
class Scalar,
class Index,
class Space>
667 using scalar_type = std::remove_cv_t<Scalar>;
668 using index_type = std::remove_cv_t<Index>;
669 static_assert(!std::is_pointer_v<scalar_type> &&
670 !std::is_array_v<scalar_type>);
671 static_assert(std::is_integral_v<index_type>);
675 using reducer = MaxFirstLoc<Scalar, Index, Space>;
676 using value_type = ::Kokkos::ValLocScalar<scalar_type, index_type>;
681 result_view_type value;
682 bool references_scalar_v;
685 KOKKOS_INLINE_FUNCTION
686 MaxFirstLoc(value_type& value_) : value(&value_), references_scalar_v(true) {}
688 KOKKOS_INLINE_FUNCTION
689 MaxFirstLoc(
const result_view_type& value_)
690 : value(value_), references_scalar_v(false) {}
693 KOKKOS_INLINE_FUNCTION
694 void join(value_type& dest,
const value_type& src)
const {
695 if (dest.val < src.val) {
697 }
else if (!(src.val < dest.val)) {
698 dest.loc = (src.loc < dest.loc) ? src.loc : dest.loc;
702 KOKKOS_INLINE_FUNCTION
703 void init(value_type& val)
const {
704 val.val = reduction_identity<scalar_type>::max();
705 val.loc = reduction_identity<index_type>::min();
708 KOKKOS_INLINE_FUNCTION
709 value_type& reference()
const {
return *value.data(); }
711 KOKKOS_INLINE_FUNCTION
712 result_view_type view()
const {
return value; }
714 KOKKOS_INLINE_FUNCTION
715 bool references_scalar()
const {
return references_scalar_v; }
718 template <
typename Scalar,
typename Index,
typename... Properties>
719 KOKKOS_DEDUCTION_GUIDE MaxFirstLoc(
720 View<ValLocScalar<Scalar, Index>, Properties...>
const&)
721 ->MaxFirstLoc<Scalar, Index,
722 typename View<ValLocScalar<Scalar, Index>,
723 Properties...>::memory_space>;
729 template <
class Scalar,
class Index,
class ComparatorType,
class Space>
730 struct MaxFirstLocCustomComparator {
732 using scalar_type = std::remove_cv_t<Scalar>;
733 using index_type = std::remove_cv_t<Index>;
734 static_assert(!std::is_pointer_v<scalar_type> &&
735 !std::is_array_v<scalar_type>);
736 static_assert(std::is_integral_v<index_type>);
741 MaxFirstLocCustomComparator<Scalar, Index, ComparatorType, Space>;
742 using value_type = ::Kokkos::ValLocScalar<scalar_type, index_type>;
747 result_view_type value;
748 bool references_scalar_v;
749 ComparatorType m_comp;
752 KOKKOS_INLINE_FUNCTION
753 MaxFirstLocCustomComparator(value_type& value_, ComparatorType comp_)
754 : value(&value_), references_scalar_v(true), m_comp(comp_) {}
756 KOKKOS_INLINE_FUNCTION
757 MaxFirstLocCustomComparator(
const result_view_type& value_,
758 ComparatorType comp_)
759 : value(value_), references_scalar_v(false), m_comp(comp_) {}
762 KOKKOS_INLINE_FUNCTION
763 void join(value_type& dest,
const value_type& src)
const {
764 if (m_comp(dest.val, src.val)) {
766 }
else if (!m_comp(src.val, dest.val)) {
767 dest.loc = (src.loc < dest.loc) ? src.loc : dest.loc;
771 KOKKOS_INLINE_FUNCTION
772 void init(value_type& val)
const {
773 val.val = reduction_identity<scalar_type>::max();
774 val.loc = reduction_identity<index_type>::min();
777 KOKKOS_INLINE_FUNCTION
778 value_type& reference()
const {
return *value.data(); }
780 KOKKOS_INLINE_FUNCTION
781 result_view_type view()
const {
return value; }
783 KOKKOS_INLINE_FUNCTION
784 bool references_scalar()
const {
return references_scalar_v; }
787 template <
typename Scalar,
typename Index,
typename ComparatorType,
788 typename... Properties>
789 KOKKOS_DEDUCTION_GUIDE MaxFirstLocCustomComparator(
790 View<ValLocScalar<Scalar, Index>, Properties...>
const&, ComparatorType)
791 ->MaxFirstLocCustomComparator<Scalar, Index, ComparatorType,
792 typename View<ValLocScalar<Scalar, Index>,
793 Properties...>::memory_space>;
798 template <
class Scalar,
class Index,
class Space>
801 using scalar_type = std::remove_cv_t<Scalar>;
802 using index_type = std::remove_cv_t<Index>;
803 static_assert(!std::is_pointer_v<scalar_type> &&
804 !std::is_array_v<scalar_type>);
805 static_assert(std::is_integral_v<index_type>);
809 using reducer = MinFirstLoc<Scalar, Index, Space>;
810 using value_type = ::Kokkos::ValLocScalar<scalar_type, index_type>;
815 result_view_type value;
816 bool references_scalar_v;
819 KOKKOS_INLINE_FUNCTION
820 MinFirstLoc(value_type& value_) : value(&value_), references_scalar_v(true) {}
822 KOKKOS_INLINE_FUNCTION
823 MinFirstLoc(
const result_view_type& value_)
824 : value(value_), references_scalar_v(false) {}
827 KOKKOS_INLINE_FUNCTION
828 void join(value_type& dest,
const value_type& src)
const {
829 if (src.val < dest.val) {
831 }
else if (!(dest.val < src.val)) {
832 dest.loc = (src.loc < dest.loc) ? src.loc : dest.loc;
836 KOKKOS_INLINE_FUNCTION
837 void init(value_type& val)
const {
838 val.val = reduction_identity<scalar_type>::min();
839 val.loc = reduction_identity<index_type>::min();
842 KOKKOS_INLINE_FUNCTION
843 value_type& reference()
const {
return *value.data(); }
845 KOKKOS_INLINE_FUNCTION
846 result_view_type view()
const {
return value; }
848 KOKKOS_INLINE_FUNCTION
849 bool references_scalar()
const {
return references_scalar_v; }
852 template <
typename Scalar,
typename Index,
typename... Properties>
853 KOKKOS_DEDUCTION_GUIDE MinFirstLoc(
854 View<ValLocScalar<Scalar, Index>, Properties...>
const&)
855 ->MinFirstLoc<Scalar, Index,
856 typename View<ValLocScalar<Scalar, Index>,
857 Properties...>::memory_space>;
863 template <
class Scalar,
class Index,
class ComparatorType,
class Space>
864 struct MinFirstLocCustomComparator {
866 using scalar_type = std::remove_cv_t<Scalar>;
867 using index_type = std::remove_cv_t<Index>;
868 static_assert(!std::is_pointer_v<scalar_type> &&
869 !std::is_array_v<scalar_type>);
870 static_assert(std::is_integral_v<index_type>);
875 MinFirstLocCustomComparator<Scalar, Index, ComparatorType, Space>;
876 using value_type = ::Kokkos::ValLocScalar<scalar_type, index_type>;
881 result_view_type value;
882 bool references_scalar_v;
883 ComparatorType m_comp;
886 KOKKOS_INLINE_FUNCTION
887 MinFirstLocCustomComparator(value_type& value_, ComparatorType comp_)
888 : value(&value_), references_scalar_v(true), m_comp(comp_) {}
890 KOKKOS_INLINE_FUNCTION
891 MinFirstLocCustomComparator(
const result_view_type& value_,
892 ComparatorType comp_)
893 : value(value_), references_scalar_v(false), m_comp(comp_) {}
896 KOKKOS_INLINE_FUNCTION
897 void join(value_type& dest,
const value_type& src)
const {
898 if (m_comp(src.val, dest.val)) {
900 }
else if (!m_comp(dest.val, src.val)) {
901 dest.loc = (src.loc < dest.loc) ? src.loc : dest.loc;
905 KOKKOS_INLINE_FUNCTION
906 void init(value_type& val)
const {
907 val.val = reduction_identity<scalar_type>::min();
908 val.loc = reduction_identity<index_type>::min();
911 KOKKOS_INLINE_FUNCTION
912 value_type& reference()
const {
return *value.data(); }
914 KOKKOS_INLINE_FUNCTION
915 result_view_type view()
const {
return value; }
917 KOKKOS_INLINE_FUNCTION
918 bool references_scalar()
const {
return references_scalar_v; }
921 template <
typename Scalar,
typename Index,
typename ComparatorType,
922 typename... Properties>
923 KOKKOS_DEDUCTION_GUIDE MinFirstLocCustomComparator(
924 View<ValLocScalar<Scalar, Index>, Properties...>
const&, ComparatorType)
925 ->MinFirstLocCustomComparator<Scalar, Index, ComparatorType,
926 typename View<ValLocScalar<Scalar, Index>,
927 Properties...>::memory_space>;
932 template <
class Scalar,
class Index,
class Space>
933 struct MinMaxFirstLastLoc {
935 using scalar_type = std::remove_cv_t<Scalar>;
936 using index_type = std::remove_cv_t<Index>;
937 static_assert(!std::is_pointer_v<scalar_type> &&
938 !std::is_array_v<scalar_type>);
939 static_assert(std::is_integral_v<index_type>);
943 using reducer = MinMaxFirstLastLoc<Scalar, Index, Space>;
944 using value_type = ::Kokkos::MinMaxLocScalar<scalar_type, index_type>;
949 result_view_type value;
950 bool references_scalar_v;
953 KOKKOS_INLINE_FUNCTION
954 MinMaxFirstLastLoc(value_type& value_)
955 : value(&value_), references_scalar_v(true) {}
957 KOKKOS_INLINE_FUNCTION
958 MinMaxFirstLastLoc(
const result_view_type& value_)
959 : value(value_), references_scalar_v(false) {}
962 KOKKOS_INLINE_FUNCTION
963 void join(value_type& dest,
const value_type& src)
const {
964 if (src.min_val < dest.min_val) {
965 dest.min_val = src.min_val;
966 dest.min_loc = src.min_loc;
967 }
else if (!(dest.min_val < src.min_val)) {
968 dest.min_loc = (src.min_loc < dest.min_loc) ? src.min_loc : dest.min_loc;
971 if (dest.max_val < src.max_val) {
972 dest.max_val = src.max_val;
973 dest.max_loc = src.max_loc;
974 }
else if (!(src.max_val < dest.max_val)) {
975 dest.max_loc = (src.max_loc > dest.max_loc) ? src.max_loc : dest.max_loc;
979 KOKKOS_INLINE_FUNCTION
980 void init(value_type& val)
const {
981 val.max_val = ::Kokkos::reduction_identity<scalar_type>::max();
982 val.min_val = ::Kokkos::reduction_identity<scalar_type>::min();
983 val.max_loc = ::Kokkos::reduction_identity<index_type>::max();
984 val.min_loc = ::Kokkos::reduction_identity<index_type>::min();
987 KOKKOS_INLINE_FUNCTION
988 value_type& reference()
const {
return *value.data(); }
990 KOKKOS_INLINE_FUNCTION
991 result_view_type view()
const {
return value; }
993 KOKKOS_INLINE_FUNCTION
994 bool references_scalar()
const {
return references_scalar_v; }
997 template <
typename Scalar,
typename Index,
typename... Properties>
998 KOKKOS_DEDUCTION_GUIDE MinMaxFirstLastLoc(
999 View<MinMaxLocScalar<Scalar, Index>, Properties...>
const&)
1000 ->MinMaxFirstLastLoc<Scalar, Index,
1001 typename View<MinMaxLocScalar<Scalar, Index>,
1002 Properties...>::memory_space>;
1008 template <
class Scalar,
class Index,
class ComparatorType,
class Space>
1009 struct MinMaxFirstLastLocCustomComparator {
1011 using scalar_type = std::remove_cv_t<Scalar>;
1012 using index_type = std::remove_cv_t<Index>;
1013 static_assert(!std::is_pointer_v<scalar_type> &&
1014 !std::is_array_v<scalar_type>);
1015 static_assert(std::is_integral_v<index_type>);
1020 MinMaxFirstLastLocCustomComparator<Scalar, Index, ComparatorType, Space>;
1021 using value_type = ::Kokkos::MinMaxLocScalar<scalar_type, index_type>;
1026 result_view_type value;
1027 bool references_scalar_v;
1028 ComparatorType m_comp;
1031 KOKKOS_INLINE_FUNCTION
1032 MinMaxFirstLastLocCustomComparator(value_type& value_, ComparatorType comp_)
1033 : value(&value_), references_scalar_v(true), m_comp(comp_) {}
1035 KOKKOS_INLINE_FUNCTION
1036 MinMaxFirstLastLocCustomComparator(
const result_view_type& value_,
1037 ComparatorType comp_)
1038 : value(value_), references_scalar_v(false), m_comp(comp_) {}
1041 KOKKOS_INLINE_FUNCTION
1042 void join(value_type& dest,
const value_type& src)
const {
1043 if (m_comp(src.min_val, dest.min_val)) {
1044 dest.min_val = src.min_val;
1045 dest.min_loc = src.min_loc;
1046 }
else if (!m_comp(dest.min_val, src.min_val)) {
1047 dest.min_loc = (src.min_loc < dest.min_loc) ? src.min_loc : dest.min_loc;
1050 if (m_comp(dest.max_val, src.max_val)) {
1051 dest.max_val = src.max_val;
1052 dest.max_loc = src.max_loc;
1053 }
else if (!m_comp(src.max_val, dest.max_val)) {
1054 dest.max_loc = (src.max_loc > dest.max_loc) ? src.max_loc : dest.max_loc;
1058 KOKKOS_INLINE_FUNCTION
1059 void init(value_type& val)
const {
1060 val.max_val = ::Kokkos::reduction_identity<scalar_type>::max();
1061 val.min_val = ::Kokkos::reduction_identity<scalar_type>::min();
1062 val.max_loc = ::Kokkos::reduction_identity<index_type>::max();
1063 val.min_loc = ::Kokkos::reduction_identity<index_type>::min();
1066 KOKKOS_INLINE_FUNCTION
1067 value_type& reference()
const {
return *value.data(); }
1069 KOKKOS_INLINE_FUNCTION
1070 result_view_type view()
const {
return value; }
1072 KOKKOS_INLINE_FUNCTION
1073 bool references_scalar()
const {
return references_scalar_v; }
1076 template <
typename Scalar,
typename Index,
typename ComparatorType,
1077 typename... Properties>
1078 KOKKOS_DEDUCTION_GUIDE MinMaxFirstLastLocCustomComparator(
1079 View<MinMaxLocScalar<Scalar, Index>, Properties...>
const&, ComparatorType)
1080 ->MinMaxFirstLastLocCustomComparator<
1081 Scalar, Index, ComparatorType,
1082 typename View<MinMaxLocScalar<Scalar, Index>,
1083 Properties...>::memory_space>;
1088 template <
class Index>
1089 struct FirstLocScalar {
1093 template <
class Index,
class Space>
1096 using index_type = std::remove_cv_t<Index>;
1097 static_assert(std::is_integral_v<index_type>);
1101 using reducer = FirstLoc<Index, Space>;
1102 using value_type = FirstLocScalar<index_type>;
1107 result_view_type value;
1108 bool references_scalar_v;
1111 KOKKOS_INLINE_FUNCTION
1112 FirstLoc(value_type& value_) : value(&value_), references_scalar_v(true) {}
1114 KOKKOS_INLINE_FUNCTION
1115 FirstLoc(
const result_view_type& value_)
1116 : value(value_), references_scalar_v(false) {}
1119 KOKKOS_INLINE_FUNCTION
1120 void join(value_type& dest,
const value_type& src)
const {
1121 dest.min_loc_true = (src.min_loc_true < dest.min_loc_true)
1123 : dest.min_loc_true;
1126 KOKKOS_INLINE_FUNCTION
1127 void init(value_type& val)
const {
1128 val.min_loc_true = ::Kokkos::reduction_identity<index_type>::min();
1131 KOKKOS_INLINE_FUNCTION
1132 value_type& reference()
const {
return *value.data(); }
1134 KOKKOS_INLINE_FUNCTION
1135 result_view_type view()
const {
return value; }
1137 KOKKOS_INLINE_FUNCTION
1138 bool references_scalar()
const {
return references_scalar_v; }
1141 template <
typename Index,
typename... Properties>
1142 KOKKOS_DEDUCTION_GUIDE FirstLoc(
1143 View<FirstLocScalar<Index>, Properties...>
const&)
1144 ->FirstLoc<Index,
typename View<FirstLocScalar<Index>,
1145 Properties...>::memory_space>;
1150 template <
class Index>
1151 struct LastLocScalar {
1155 template <
class Index,
class Space>
1158 using index_type = std::remove_cv_t<Index>;
1159 static_assert(std::is_integral_v<index_type>);
1163 using reducer = LastLoc<Index, Space>;
1164 using value_type = LastLocScalar<index_type>;
1169 result_view_type value;
1170 bool references_scalar_v;
1173 KOKKOS_INLINE_FUNCTION
1174 LastLoc(value_type& value_) : value(&value_), references_scalar_v(true) {}
1176 KOKKOS_INLINE_FUNCTION
1177 LastLoc(
const result_view_type& value_)
1178 : value(value_), references_scalar_v(false) {}
1181 KOKKOS_INLINE_FUNCTION
1182 void join(value_type& dest,
const value_type& src)
const {
1183 dest.max_loc_true = (src.max_loc_true > dest.max_loc_true)
1185 : dest.max_loc_true;
1188 KOKKOS_INLINE_FUNCTION
1189 void init(value_type& val)
const {
1190 val.max_loc_true = ::Kokkos::reduction_identity<index_type>::max();
1193 KOKKOS_INLINE_FUNCTION
1194 value_type& reference()
const {
return *value.data(); }
1196 KOKKOS_INLINE_FUNCTION
1197 result_view_type view()
const {
return value; }
1199 KOKKOS_INLINE_FUNCTION
1200 bool references_scalar()
const {
return references_scalar_v; }
1203 template <
typename Index,
typename... Properties>
1204 KOKKOS_DEDUCTION_GUIDE LastLoc(View<LastLocScalar<Index>, Properties...>
const&)
1206 typename View<LastLocScalar<Index>, Properties...>::memory_space>;
1208 template <
class Index>
1209 struct StdIsPartScalar {
1210 Index max_loc_true, min_loc_false;
1216 template <
class Index,
class Space>
1217 struct StdIsPartitioned {
1219 using index_type = std::remove_cv_t<Index>;
1220 static_assert(std::is_integral_v<index_type>);
1224 using reducer = StdIsPartitioned<Index, Space>;
1225 using value_type = StdIsPartScalar<index_type>;
1230 result_view_type value;
1231 bool references_scalar_v;
1234 KOKKOS_INLINE_FUNCTION
1235 StdIsPartitioned(value_type& value_)
1236 : value(&value_), references_scalar_v(true) {}
1238 KOKKOS_INLINE_FUNCTION
1239 StdIsPartitioned(
const result_view_type& value_)
1240 : value(value_), references_scalar_v(false) {}
1243 KOKKOS_INLINE_FUNCTION
1244 void join(value_type& dest,
const value_type& src)
const {
1245 dest.max_loc_true = (dest.max_loc_true < src.max_loc_true)
1247 : dest.max_loc_true;
1249 dest.min_loc_false = (dest.min_loc_false < src.min_loc_false)
1250 ? dest.min_loc_false
1251 : src.min_loc_false;
1254 KOKKOS_INLINE_FUNCTION
1255 void init(value_type& val)
const {
1256 val.max_loc_true = ::Kokkos::reduction_identity<index_type>::max();
1257 val.min_loc_false = ::Kokkos::reduction_identity<index_type>::min();
1260 KOKKOS_INLINE_FUNCTION
1261 value_type& reference()
const {
return *value.data(); }
1263 KOKKOS_INLINE_FUNCTION
1264 result_view_type view()
const {
return value; }
1266 KOKKOS_INLINE_FUNCTION
1267 bool references_scalar()
const {
return references_scalar_v; }
1270 template <
typename Index,
typename... Properties>
1271 KOKKOS_DEDUCTION_GUIDE StdIsPartitioned(
1272 View<StdIsPartScalar<Index>, Properties...>
const&)
1273 ->StdIsPartitioned<Index,
typename View<StdIsPartScalar<Index>,
1274 Properties...>::memory_space>;
1276 template <
class Index>
1277 struct StdPartPointScalar {
1278 Index min_loc_false;
1284 template <
class Index,
class Space>
1285 struct StdPartitionPoint {
1287 using index_type = std::remove_cv_t<Index>;
1288 static_assert(std::is_integral_v<index_type>);
1292 using reducer = StdPartitionPoint<Index, Space>;
1293 using value_type = StdPartPointScalar<index_type>;
1298 result_view_type value;
1299 bool references_scalar_v;
1302 KOKKOS_INLINE_FUNCTION
1303 StdPartitionPoint(value_type& value_)
1304 : value(&value_), references_scalar_v(true) {}
1306 KOKKOS_INLINE_FUNCTION
1307 StdPartitionPoint(
const result_view_type& value_)
1308 : value(value_), references_scalar_v(false) {}
1311 KOKKOS_INLINE_FUNCTION
1312 void join(value_type& dest,
const value_type& src)
const {
1313 dest.min_loc_false = (dest.min_loc_false < src.min_loc_false)
1314 ? dest.min_loc_false
1315 : src.min_loc_false;
1318 KOKKOS_INLINE_FUNCTION
1319 void init(value_type& val)
const {
1320 val.min_loc_false = ::Kokkos::reduction_identity<index_type>::min();
1323 KOKKOS_INLINE_FUNCTION
1324 value_type& reference()
const {
return *value.data(); }
1326 KOKKOS_INLINE_FUNCTION
1327 result_view_type view()
const {
return value; }
1329 KOKKOS_INLINE_FUNCTION
1330 bool references_scalar()
const {
return references_scalar_v; }
1333 template <
typename Index,
typename... Properties>
1334 KOKKOS_DEDUCTION_GUIDE StdPartitionPoint(
1335 View<StdPartPointScalar<Index>, Properties...>
const&)
1336 ->StdPartitionPoint<Index,
typename View<StdPartPointScalar<Index>,
1337 Properties...>::memory_space>;
1343 template <
typename FunctorType,
typename FunctorAnalysisReducerType,
1345 class CombinedFunctorReducer {
1347 using functor_type = FunctorType;
1348 using reducer_type = FunctorAnalysisReducerType;
1349 CombinedFunctorReducer(
const FunctorType& functor,
1350 const FunctorAnalysisReducerType& reducer)
1351 : m_functor(functor), m_reducer(reducer) {}
1352 KOKKOS_FUNCTION
const FunctorType& get_functor()
const {
return m_functor; }
1353 KOKKOS_FUNCTION
const FunctorAnalysisReducerType& get_reducer()
const {
1358 FunctorType m_functor;
1359 FunctorAnalysisReducerType m_reducer;
1361 template <
typename FunctorType,
typename FunctorAnalysisReducerType>
1362 class CombinedFunctorReducer<
1363 FunctorType, FunctorAnalysisReducerType,
1364 std::enable_if_t<std::is_same_v<
1365 FunctorType, typename FunctorAnalysisReducerType::functor_type>>> {
1367 using functor_type = FunctorType;
1368 using reducer_type = FunctorAnalysisReducerType;
1369 CombinedFunctorReducer(
const FunctorType& functor,
1370 const FunctorAnalysisReducerType&)
1371 : m_reducer(functor) {}
1372 KOKKOS_FUNCTION
const FunctorType& get_functor()
const {
1373 return m_reducer.get_functor();
1375 KOKKOS_FUNCTION
const FunctorAnalysisReducerType& get_reducer()
const {
1380 FunctorAnalysisReducerType m_reducer;
1383 template <
class T,
class ReturnType,
class ValueTraits>
1384 struct ParallelReduceReturnValue;
1386 template <
class ReturnType,
class FunctorType>
1387 struct ParallelReduceReturnValue<
1388 std::enable_if_t<Kokkos::is_view<ReturnType>::value>,
ReturnType,
1391 using reducer_type = InvalidType;
1393 using value_type_scalar =
typename return_type::value_type;
1394 using value_type_array =
typename return_type::value_type*
const;
1396 using value_type = std::conditional_t<return_type::rank == 0,
1397 value_type_scalar, value_type_array>;
1399 static return_type& return_value(
ReturnType& return_val,
const FunctorType&) {
1404 template <
class ReturnType,
class FunctorType>
1405 struct ParallelReduceReturnValue<
1406 std::enable_if_t<!Kokkos::is_view<ReturnType>::value &&
1407 (!std::is_array<ReturnType>::value &&
1408 !std::is_pointer<ReturnType>::value) &&
1409 !Kokkos::is_reducer<ReturnType>::value>,
1414 using reducer_type = InvalidType;
1416 using value_type =
typename return_type::value_type;
1418 static return_type return_value(
ReturnType& return_val,
const FunctorType&) {
1419 return return_type(&return_val);
1423 template <
class ReturnType,
class FunctorType>
1424 struct ParallelReduceReturnValue<
1425 std::enable_if_t<(std::is_array<ReturnType>::value ||
1426 std::is_pointer<ReturnType>::value)>,
1431 using reducer_type = InvalidType;
1433 using value_type =
typename return_type::value_type[];
1435 static return_type return_value(
ReturnType& return_val,
1436 const FunctorType& functor) {
1437 if (std::is_array<ReturnType>::value)
1438 return return_type(return_val);
1440 return return_type(return_val, functor.value_count);
1444 template <
class ReturnType,
class FunctorType>
1445 struct ParallelReduceReturnValue<
1446 std::enable_if_t<Kokkos::is_reducer<ReturnType>::value>,
ReturnType,
1448 using return_type =
typename ReturnType::result_view_type;
1450 using value_type =
typename return_type::value_type;
1452 static auto return_value(
ReturnType& return_val,
const FunctorType&) {
1453 return return_val.view();
1457 template <
class T,
class ReturnType,
class FunctorType>
1458 struct ParallelReducePolicyType;
1460 template <
class PolicyType,
class FunctorType>
1461 struct ParallelReducePolicyType<
1462 std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value>,
1463 PolicyType, FunctorType> {
1464 using policy_type = PolicyType;
1465 static PolicyType policy(
const PolicyType& policy_) {
return policy_; }
1468 template <
class PolicyType,
class FunctorType>
1469 struct ParallelReducePolicyType<
1470 std::enable_if_t<std::is_integral<PolicyType>::value>, PolicyType,
1472 using execution_space =
1473 typename Impl::FunctorPolicyExecutionSpace<FunctorType,
1474 void>::execution_space;
1478 static policy_type policy(
const PolicyType& policy_) {
1479 return policy_type(0, policy_);
1483 template <
class FunctorType,
class ExecPolicy,
class ValueType,
1484 class ExecutionSpace>
1485 struct ParallelReduceFunctorType {
1486 using functor_type = FunctorType;
1487 static const functor_type& functor(
const functor_type& functor) {
1492 template <
class PolicyType,
class FunctorType,
class ReturnType>
1493 struct ParallelReduceAdaptor {
1494 using return_value_adapter =
1495 Impl::ParallelReduceReturnValue<void, ReturnType, FunctorType>;
1497 static inline void execute_impl(
const std::string& label,
1498 const PolicyType& policy,
1499 const FunctorType& functor,
1501 using PassedReducerType =
typename return_value_adapter::reducer_type;
1504 PolicyType inner_policy = policy;
1505 Kokkos::Tools::Impl::begin_parallel_reduce<PassedReducerType>(
1506 inner_policy, functor, label, kpID);
1508 using ReducerSelector =
1509 Kokkos::Impl::if_c<std::is_same<InvalidType, PassedReducerType>::value,
1510 FunctorType, PassedReducerType>;
1511 using Analysis = FunctorAnalysis<FunctorPatternInterface::REDUCE,
1512 PolicyType,
typename ReducerSelector::type,
1513 typename return_value_adapter::value_type>;
1515 using CombinedFunctorReducerType =
1516 CombinedFunctorReducer<FunctorType, typename Analysis::Reducer>;
1517 auto closure = construct_with_shared_allocation_tracking_disabled<
1518 Impl::ParallelReduce<CombinedFunctorReducerType, PolicyType,
1519 typename Impl::FunctorPolicyExecutionSpace<
1520 FunctorType, PolicyType>::execution_space>>(
1521 CombinedFunctorReducerType(
1522 functor,
typename Analysis::Reducer(
1523 ReducerSelector::select(functor, return_value))),
1525 return_value_adapter::return_value(return_value, functor));
1528 Kokkos::Tools::Impl::end_parallel_reduce<PassedReducerType>(
1529 inner_policy, functor, label, kpID);
1532 static constexpr
bool is_array_reduction =
1533 Impl::FunctorAnalysis<
1534 Impl::FunctorPatternInterface::REDUCE, PolicyType, FunctorType,
1535 typename return_value_adapter::value_type>::StaticValueSize == 0;
1537 template <
typename Dummy = ReturnType>
1538 static inline std::enable_if_t<!(is_array_reduction &&
1539 std::is_pointer<Dummy>::value)>
1540 execute(
const std::string& label,
const PolicyType& policy,
1541 const FunctorType& functor,
ReturnType& return_value) {
1542 execute_impl(label, policy, functor, return_value);
1563 template <
typename T>
1564 struct ReducerHasTestReferenceFunction {
1565 template <
typename E>
1566 static std::true_type test_func(decltype(&E::references_scalar));
1567 template <
typename E>
1568 static std::false_type test_func(...);
1571 value = std::is_same<std::true_type, decltype(test_func<T>(
nullptr))>::value
1575 template <
class ExecutionSpace,
class Arg>
1576 constexpr std::enable_if_t<
1578 !ReducerHasTestReferenceFunction<Arg>::value &&
1579 !Kokkos::is_view<Arg>::value,
1582 parallel_reduce_needs_fence(ExecutionSpace
const&, Arg
const&) {
1586 template <
class ExecutionSpace,
class Reducer>
1587 constexpr std::enable_if_t<
1592 ReducerHasTestReferenceFunction<Reducer>::value,
1595 parallel_reduce_needs_fence(ExecutionSpace
const&, Reducer
const& reducer) {
1596 return reducer.references_scalar();
1599 template <
class ExecutionSpace,
class ViewLike>
1600 constexpr std::enable_if_t<
1602 Kokkos::is_view<ViewLike>::value,
1605 parallel_reduce_needs_fence(ExecutionSpace
const&, ViewLike
const&) {
1609 template <
class ExecutionSpace,
class... Args>
1610 struct ParallelReduceFence {
1611 template <
class... ArgsDeduced>
1612 static void fence(
const ExecutionSpace& ex,
const std::string& name,
1613 ArgsDeduced&&... args) {
1614 if (Impl::parallel_reduce_needs_fence(ex, (ArgsDeduced &&) args...)) {
1662 template <
class PolicyType,
class FunctorType,
class ReturnType>
1663 inline std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value &&
1664 !(Kokkos::is_view<ReturnType>::value ||
1665 Kokkos::is_reducer<ReturnType>::value ||
1666 std::is_pointer<ReturnType>::value)>
1667 parallel_reduce(
const std::string& label,
const PolicyType& policy,
1668 const FunctorType& functor,
ReturnType& return_value) {
1670 !std::is_const<ReturnType>::value,
1671 "A const reduction result type is only allowed for a View, pointer or "
1672 "reducer return type!");
1674 Impl::ParallelReduceAdaptor<PolicyType, FunctorType, ReturnType>::execute(
1675 label, policy, functor, return_value);
1676 Impl::ParallelReduceFence<typename PolicyType::execution_space, ReturnType>::
1679 "Kokkos::parallel_reduce: fence due to result being value, not view",
1683 template <
class PolicyType,
class FunctorType,
class ReturnType>
1684 inline std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value &&
1685 !(Kokkos::is_view<ReturnType>::value ||
1686 Kokkos::is_reducer<ReturnType>::value ||
1687 std::is_pointer<ReturnType>::value)>
1688 parallel_reduce(
const PolicyType& policy,
const FunctorType& functor,
1691 !std::is_const<ReturnType>::value,
1692 "A const reduction result type is only allowed for a View, pointer or "
1693 "reducer return type!");
1695 Impl::ParallelReduceAdaptor<PolicyType, FunctorType, ReturnType>::execute(
1696 "", policy, functor, return_value);
1697 Impl::ParallelReduceFence<typename PolicyType::execution_space, ReturnType>::
1700 "Kokkos::parallel_reduce: fence due to result being value, not view",
1704 template <
class FunctorType,
class ReturnType>
1705 inline std::enable_if_t<!(Kokkos::is_view<ReturnType>::value ||
1706 Kokkos::is_reducer<ReturnType>::value ||
1707 std::is_pointer<ReturnType>::value)>
1708 parallel_reduce(
const size_t& policy,
const FunctorType& functor,
1711 !std::is_const<ReturnType>::value,
1712 "A const reduction result type is only allowed for a View, pointer or "
1713 "reducer return type!");
1716 typename Impl::ParallelReducePolicyType<void, size_t,
1717 FunctorType>::policy_type;
1719 Impl::ParallelReduceAdaptor<policy_type, FunctorType, ReturnType>::execute(
1720 "", policy_type(0, policy), functor, return_value);
1721 Impl::ParallelReduceFence<typename policy_type::execution_space, ReturnType>::
1723 typename policy_type::execution_space(),
1724 "Kokkos::parallel_reduce: fence due to result being value, not view",
1728 template <
class FunctorType,
class ReturnType>
1729 inline std::enable_if_t<!(Kokkos::is_view<ReturnType>::value ||
1730 Kokkos::is_reducer<ReturnType>::value ||
1731 std::is_pointer<ReturnType>::value)>
1732 parallel_reduce(
const std::string& label,
const size_t& policy,
1733 const FunctorType& functor,
ReturnType& return_value) {
1735 !std::is_const<ReturnType>::value,
1736 "A const reduction result type is only allowed for a View, pointer or "
1737 "reducer return type!");
1740 typename Impl::ParallelReducePolicyType<void, size_t,
1741 FunctorType>::policy_type;
1742 Impl::ParallelReduceAdaptor<policy_type, FunctorType, ReturnType>::execute(
1743 label, policy_type(0, policy), functor, return_value);
1744 Impl::ParallelReduceFence<typename policy_type::execution_space, ReturnType>::
1746 typename policy_type::execution_space(),
1747 "Kokkos::parallel_reduce: fence due to result being value, not view",
1753 template <
class PolicyType,
class FunctorType,
class ReturnType>
1754 inline std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value &&
1755 (Kokkos::is_view<ReturnType>::value ||
1756 Kokkos::is_reducer<ReturnType>::value ||
1757 std::is_pointer<ReturnType>::value)>
1758 parallel_reduce(
const std::string& label,
const PolicyType& policy,
1759 const FunctorType& functor,
const ReturnType& return_value) {
1761 Impl::ParallelReduceAdaptor<PolicyType, FunctorType, ReturnType>::execute(
1762 label, policy, functor, return_value_impl);
1763 Impl::ParallelReduceFence<typename PolicyType::execution_space, ReturnType>::
1766 "Kokkos::parallel_reduce: fence due to result being value, not view",
1770 template <
class PolicyType,
class FunctorType,
class ReturnType>
1771 inline std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value &&
1772 (Kokkos::is_view<ReturnType>::value ||
1773 Kokkos::is_reducer<ReturnType>::value ||
1774 std::is_pointer<ReturnType>::value)>
1775 parallel_reduce(
const PolicyType& policy,
const FunctorType& functor,
1778 Impl::ParallelReduceAdaptor<PolicyType, FunctorType, ReturnType>::execute(
1779 "", policy, functor, return_value_impl);
1780 Impl::ParallelReduceFence<typename PolicyType::execution_space, ReturnType>::
1783 "Kokkos::parallel_reduce: fence due to result being value, not view",
1787 template <
class FunctorType,
class ReturnType>
1788 inline std::enable_if_t<Kokkos::is_view<ReturnType>::value ||
1789 Kokkos::is_reducer<ReturnType>::value ||
1790 std::is_pointer<ReturnType>::value>
1791 parallel_reduce(
const size_t& policy,
const FunctorType& functor,
1794 typename Impl::ParallelReducePolicyType<void, size_t,
1795 FunctorType>::policy_type;
1797 Impl::ParallelReduceAdaptor<policy_type, FunctorType, ReturnType>::execute(
1798 "", policy_type(0, policy), functor, return_value_impl);
1799 Impl::ParallelReduceFence<typename policy_type::execution_space, ReturnType>::
1801 typename policy_type::execution_space(),
1802 "Kokkos::parallel_reduce: fence due to result being value, not view",
1806 template <
class FunctorType,
class ReturnType>
1807 inline std::enable_if_t<Kokkos::is_view<ReturnType>::value ||
1808 Kokkos::is_reducer<ReturnType>::value ||
1809 std::is_pointer<ReturnType>::value>
1810 parallel_reduce(
const std::string& label,
const size_t& policy,
1811 const FunctorType& functor,
const ReturnType& return_value) {
1813 typename Impl::ParallelReducePolicyType<void, size_t,
1814 FunctorType>::policy_type;
1816 Impl::ParallelReduceAdaptor<policy_type, FunctorType, ReturnType>::execute(
1817 label, policy_type(0, policy), functor, return_value_impl);
1818 Impl::ParallelReduceFence<typename policy_type::execution_space, ReturnType>::
1820 typename policy_type::execution_space(),
1821 "Kokkos::parallel_reduce: fence due to result being value, not view",
1827 template <
class PolicyType,
class FunctorType>
1828 inline void parallel_reduce(
1829 const std::string& label,
const PolicyType& policy,
1830 const FunctorType& functor,
1831 std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value>* =
1833 using FunctorAnalysis =
1834 Impl::FunctorAnalysis<Impl::FunctorPatternInterface::REDUCE, PolicyType,
1836 using value_type = std::conditional_t<(FunctorAnalysis::StaticValueSize != 0),
1837 typename FunctorAnalysis::value_type,
1838 typename FunctorAnalysis::pointer_type>;
1841 FunctorAnalysis::has_final_member_function,
1842 "Calling parallel_reduce without either return value or final function.");
1844 using result_view_type =
1846 result_view_type result_view;
1848 Impl::ParallelReduceAdaptor<PolicyType, FunctorType,
1849 result_view_type>::execute(label, policy, functor,
1853 template <
class PolicyType,
class FunctorType>
1854 inline void parallel_reduce(
1855 const PolicyType& policy,
const FunctorType& functor,
1856 std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value>* =
1858 using FunctorAnalysis =
1859 Impl::FunctorAnalysis<Impl::FunctorPatternInterface::REDUCE, PolicyType,
1861 using value_type = std::conditional_t<(FunctorAnalysis::StaticValueSize != 0),
1862 typename FunctorAnalysis::value_type,
1863 typename FunctorAnalysis::pointer_type>;
1866 FunctorAnalysis::has_final_member_function,
1867 "Calling parallel_reduce without either return value or final function.");
1869 using result_view_type =
1871 result_view_type result_view;
1873 Impl::ParallelReduceAdaptor<PolicyType, FunctorType,
1874 result_view_type>::execute(
"", policy, functor,
1878 template <
class FunctorType>
1879 inline void parallel_reduce(
const size_t& policy,
const FunctorType& functor) {
1881 typename Impl::ParallelReducePolicyType<void, size_t,
1882 FunctorType>::policy_type;
1883 using FunctorAnalysis =
1884 Impl::FunctorAnalysis<Impl::FunctorPatternInterface::REDUCE, policy_type,
1886 using value_type = std::conditional_t<(FunctorAnalysis::StaticValueSize != 0),
1887 typename FunctorAnalysis::value_type,
1888 typename FunctorAnalysis::pointer_type>;
1891 FunctorAnalysis::has_final_member_function,
1892 "Calling parallel_reduce without either return value or final function.");
1894 using result_view_type =
1896 result_view_type result_view;
1898 Impl::ParallelReduceAdaptor<policy_type, FunctorType,
1899 result_view_type>::execute(
"",
1900 policy_type(0, policy),
1901 functor, result_view);
1904 template <
class FunctorType>
1905 inline void parallel_reduce(
const std::string& label,
const size_t& policy,
1906 const FunctorType& functor) {
1908 typename Impl::ParallelReducePolicyType<void, size_t,
1909 FunctorType>::policy_type;
1910 using FunctorAnalysis =
1911 Impl::FunctorAnalysis<Impl::FunctorPatternInterface::REDUCE, policy_type,
1913 using value_type = std::conditional_t<(FunctorAnalysis::StaticValueSize != 0),
1914 typename FunctorAnalysis::value_type,
1915 typename FunctorAnalysis::pointer_type>;
1918 FunctorAnalysis::has_final_member_function,
1919 "Calling parallel_reduce without either return value or final function.");
1921 using result_view_type =
1923 result_view_type result_view;
1925 Impl::ParallelReduceAdaptor<policy_type, FunctorType,
1926 result_view_type>::execute(label,
1927 policy_type(0, policy),
1928 functor, result_view);
1933 #endif // KOKKOS_PARALLEL_REDUCE_HPP
Memory management for host memory.
Execution policy for work over a range of an integral type.