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>);
41 using result_view_type = Kokkos::View<value_type, Space>;
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>);
86 using result_view_type = Kokkos::View<value_type, Space>;
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>);
131 using result_view_type = Kokkos::View<value_type, Space>;
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>);
178 using result_view_type = Kokkos::View<value_type, Space>;
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>);
226 using result_view_type = Kokkos::View<value_type, Space>;
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>);
272 using result_view_type = Kokkos::View<value_type, Space>;
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>);
319 using result_view_type = Kokkos::View<value_type, Space>;
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>);
366 using result_view_type = Kokkos::View<value_type, Space>;
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>;
424 using result_view_type = Kokkos::View<value_type, Space>;
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)
443 else if (src.val == dest.val &&
444 dest.loc == reduction_identity<index_type>::min()) {
449 KOKKOS_INLINE_FUNCTION
450 void init(value_type& val)
const {
451 val.val = reduction_identity<scalar_type>::min();
452 val.loc = reduction_identity<index_type>::min();
455 KOKKOS_INLINE_FUNCTION
456 value_type& reference()
const {
return *value.data(); }
458 KOKKOS_INLINE_FUNCTION
459 result_view_type view()
const {
return value; }
461 KOKKOS_INLINE_FUNCTION
462 bool references_scalar()
const {
return references_scalar_v; }
465 template <
typename Scalar,
typename Index,
typename... Properties>
466 KOKKOS_DEDUCTION_GUIDE
467 MinLoc(View<ValLocScalar<Scalar, Index>, Properties...>
const&) -> MinLoc<
469 typename View<ValLocScalar<Scalar, Index>, Properties...>::memory_space>;
471 template <
class Scalar,
class Index,
class Space>
474 using scalar_type = std::remove_cv_t<Scalar>;
475 using index_type = std::remove_cv_t<Index>;
476 static_assert(!std::is_pointer_v<scalar_type> &&
477 !std::is_array_v<scalar_type>);
481 using reducer = MaxLoc<Scalar, Index, Space>;
482 using value_type = ValLocScalar<scalar_type, index_type>;
484 using result_view_type = Kokkos::View<value_type, Space>;
487 result_view_type value;
488 bool references_scalar_v;
491 KOKKOS_INLINE_FUNCTION
492 MaxLoc(value_type& value_) : value(&value_), references_scalar_v(true) {}
494 KOKKOS_INLINE_FUNCTION
495 MaxLoc(
const result_view_type& value_)
496 : value(value_), references_scalar_v(false) {}
499 KOKKOS_INLINE_FUNCTION
500 void join(value_type& dest,
const value_type& src)
const {
501 if (src.val > dest.val)
503 else if (src.val == dest.val &&
504 dest.loc == reduction_identity<index_type>::min()) {
509 KOKKOS_INLINE_FUNCTION
510 void init(value_type& val)
const {
511 val.val = reduction_identity<scalar_type>::max();
512 val.loc = reduction_identity<index_type>::min();
515 KOKKOS_INLINE_FUNCTION
516 value_type& reference()
const {
return *value.data(); }
518 KOKKOS_INLINE_FUNCTION
519 result_view_type view()
const {
return value; }
521 KOKKOS_INLINE_FUNCTION
522 bool references_scalar()
const {
return references_scalar_v; }
525 template <
typename Scalar,
typename Index,
typename... Properties>
526 KOKKOS_DEDUCTION_GUIDE
527 MaxLoc(View<ValLocScalar<Scalar, Index>, Properties...>
const&) -> MaxLoc<
529 typename View<ValLocScalar<Scalar, Index>, Properties...>::memory_space>;
531 template <
class Scalar>
532 struct MinMaxScalar {
533 Scalar min_val, max_val;
536 template <
class Scalar,
class Space>
539 using scalar_type = std::remove_cv_t<Scalar>;
540 static_assert(!std::is_pointer_v<scalar_type> &&
541 !std::is_array_v<scalar_type>);
545 using reducer = MinMax<Scalar, Space>;
546 using value_type = MinMaxScalar<scalar_type>;
548 using result_view_type = Kokkos::View<value_type, Space>;
551 result_view_type value;
552 bool references_scalar_v;
555 KOKKOS_INLINE_FUNCTION
556 MinMax(value_type& value_) : value(&value_), references_scalar_v(true) {}
558 KOKKOS_INLINE_FUNCTION
559 MinMax(
const result_view_type& value_)
560 : value(value_), references_scalar_v(false) {}
563 KOKKOS_INLINE_FUNCTION
564 void join(value_type& dest,
const value_type& src)
const {
565 if (src.min_val < dest.min_val) {
566 dest.min_val = src.min_val;
568 if (src.max_val > dest.max_val) {
569 dest.max_val = src.max_val;
573 KOKKOS_INLINE_FUNCTION
574 void init(value_type& val)
const {
575 val.max_val = reduction_identity<scalar_type>::max();
576 val.min_val = reduction_identity<scalar_type>::min();
579 KOKKOS_INLINE_FUNCTION
580 value_type& reference()
const {
return *value.data(); }
582 KOKKOS_INLINE_FUNCTION
583 result_view_type view()
const {
return value; }
585 KOKKOS_INLINE_FUNCTION
586 bool references_scalar()
const {
return references_scalar_v; }
589 template <
typename Scalar,
typename... Properties>
590 KOKKOS_DEDUCTION_GUIDE MinMax(View<MinMaxScalar<Scalar>, Properties...>
const&)
592 typename View<MinMaxScalar<Scalar>, Properties...>::memory_space>;
594 template <
class Scalar,
class Index>
595 struct MinMaxLocScalar {
596 Scalar min_val, max_val;
597 Index min_loc, max_loc;
600 template <
class Scalar,
class Index,
class Space>
603 using scalar_type = std::remove_cv_t<Scalar>;
604 using index_type = std::remove_cv_t<Index>;
605 static_assert(!std::is_pointer_v<scalar_type> &&
606 !std::is_array_v<scalar_type>);
610 using reducer = MinMaxLoc<Scalar, Index, Space>;
611 using value_type = MinMaxLocScalar<scalar_type, index_type>;
613 using result_view_type = Kokkos::View<value_type, Space>;
616 result_view_type value;
617 bool references_scalar_v;
620 KOKKOS_INLINE_FUNCTION
621 MinMaxLoc(value_type& value_) : value(&value_), references_scalar_v(true) {}
623 KOKKOS_INLINE_FUNCTION
624 MinMaxLoc(
const result_view_type& value_)
625 : value(value_), references_scalar_v(false) {}
628 KOKKOS_INLINE_FUNCTION
629 void join(value_type& dest,
const value_type& src)
const {
630 if (src.min_val < dest.min_val) {
631 dest.min_val = src.min_val;
632 dest.min_loc = src.min_loc;
633 }
else if (dest.min_val == src.min_val &&
634 dest.min_loc == reduction_identity<index_type>::min()) {
635 dest.min_loc = src.min_loc;
637 if (src.max_val > dest.max_val) {
638 dest.max_val = src.max_val;
639 dest.max_loc = src.max_loc;
640 }
else if (dest.max_val == src.max_val &&
641 dest.max_loc == reduction_identity<index_type>::min()) {
642 dest.max_loc = src.max_loc;
646 KOKKOS_INLINE_FUNCTION
647 void init(value_type& val)
const {
648 val.max_val = reduction_identity<scalar_type>::max();
649 val.min_val = reduction_identity<scalar_type>::min();
650 val.max_loc = reduction_identity<index_type>::min();
651 val.min_loc = reduction_identity<index_type>::min();
654 KOKKOS_INLINE_FUNCTION
655 value_type& reference()
const {
return *value.data(); }
657 KOKKOS_INLINE_FUNCTION
658 result_view_type view()
const {
return value; }
660 KOKKOS_INLINE_FUNCTION
661 bool references_scalar()
const {
return references_scalar_v; }
664 template <
typename Scalar,
typename Index,
typename... Properties>
665 KOKKOS_DEDUCTION_GUIDE MinMaxLoc(
666 View<MinMaxLocScalar<Scalar, Index>, Properties...>
const&)
667 -> MinMaxLoc<Scalar, Index,
668 typename View<MinMaxLocScalar<Scalar, Index>,
669 Properties...>::memory_space>;
678 template <
class Scalar,
class Index,
class Space>
681 using scalar_type = std::remove_cv_t<Scalar>;
682 using index_type = std::remove_cv_t<Index>;
683 static_assert(!std::is_pointer_v<scalar_type> &&
684 !std::is_array_v<scalar_type>);
685 static_assert(std::is_integral_v<index_type>);
689 using reducer = MaxFirstLoc<Scalar, Index, Space>;
690 using value_type = ::Kokkos::ValLocScalar<scalar_type, index_type>;
692 using result_view_type = ::Kokkos::View<value_type, Space>;
695 result_view_type value;
696 bool references_scalar_v;
699 KOKKOS_INLINE_FUNCTION
700 MaxFirstLoc(value_type& value_) : value(&value_), references_scalar_v(true) {}
702 KOKKOS_INLINE_FUNCTION
703 MaxFirstLoc(
const result_view_type& value_)
704 : value(value_), references_scalar_v(false) {}
707 KOKKOS_INLINE_FUNCTION
708 void join(value_type& dest,
const value_type& src)
const {
709 if (dest.val < src.val) {
711 }
else if (!(src.val < dest.val)) {
712 dest.loc = (src.loc < dest.loc) ? src.loc : dest.loc;
716 KOKKOS_INLINE_FUNCTION
717 void init(value_type& val)
const {
718 val.val = reduction_identity<scalar_type>::max();
719 val.loc = reduction_identity<index_type>::min();
722 KOKKOS_INLINE_FUNCTION
723 value_type& reference()
const {
return *value.data(); }
725 KOKKOS_INLINE_FUNCTION
726 result_view_type view()
const {
return value; }
728 KOKKOS_INLINE_FUNCTION
729 bool references_scalar()
const {
return references_scalar_v; }
732 template <
typename Scalar,
typename Index,
typename... Properties>
733 KOKKOS_DEDUCTION_GUIDE MaxFirstLoc(
734 View<ValLocScalar<Scalar, Index>, Properties...>
const&)
735 -> MaxFirstLoc<Scalar, Index,
736 typename View<ValLocScalar<Scalar, Index>,
737 Properties...>::memory_space>;
743 template <
class Scalar,
class Index,
class ComparatorType,
class Space>
744 struct MaxFirstLocCustomComparator {
746 using scalar_type = std::remove_cv_t<Scalar>;
747 using index_type = std::remove_cv_t<Index>;
748 static_assert(!std::is_pointer_v<scalar_type> &&
749 !std::is_array_v<scalar_type>);
750 static_assert(std::is_integral_v<index_type>);
755 MaxFirstLocCustomComparator<Scalar, Index, ComparatorType, Space>;
756 using value_type = ::Kokkos::ValLocScalar<scalar_type, index_type>;
758 using result_view_type = ::Kokkos::View<value_type, Space>;
761 result_view_type value;
762 bool references_scalar_v;
763 ComparatorType m_comp;
766 KOKKOS_INLINE_FUNCTION
767 MaxFirstLocCustomComparator(value_type& value_, ComparatorType comp_)
768 : value(&value_), references_scalar_v(true), m_comp(comp_) {}
770 KOKKOS_INLINE_FUNCTION
771 MaxFirstLocCustomComparator(
const result_view_type& value_,
772 ComparatorType comp_)
773 : value(value_), references_scalar_v(false), m_comp(comp_) {}
776 KOKKOS_INLINE_FUNCTION
777 void join(value_type& dest,
const value_type& src)
const {
778 if (m_comp(dest.val, src.val)) {
780 }
else if (!m_comp(src.val, dest.val)) {
781 dest.loc = (src.loc < dest.loc) ? src.loc : dest.loc;
785 KOKKOS_INLINE_FUNCTION
786 void init(value_type& val)
const {
787 val.val = reduction_identity<scalar_type>::max();
788 val.loc = reduction_identity<index_type>::min();
791 KOKKOS_INLINE_FUNCTION
792 value_type& reference()
const {
return *value.data(); }
794 KOKKOS_INLINE_FUNCTION
795 result_view_type view()
const {
return value; }
797 KOKKOS_INLINE_FUNCTION
798 bool references_scalar()
const {
return references_scalar_v; }
801 template <
typename Scalar,
typename Index,
typename ComparatorType,
802 typename... Properties>
803 KOKKOS_DEDUCTION_GUIDE MaxFirstLocCustomComparator(
804 View<ValLocScalar<Scalar, Index>, Properties...>
const&, ComparatorType)
805 -> MaxFirstLocCustomComparator<Scalar, Index, ComparatorType,
806 typename View<ValLocScalar<Scalar, Index>,
807 Properties...>::memory_space>;
812 template <
class Scalar,
class Index,
class Space>
815 using scalar_type = std::remove_cv_t<Scalar>;
816 using index_type = std::remove_cv_t<Index>;
817 static_assert(!std::is_pointer_v<scalar_type> &&
818 !std::is_array_v<scalar_type>);
819 static_assert(std::is_integral_v<index_type>);
823 using reducer = MinFirstLoc<Scalar, Index, Space>;
824 using value_type = ::Kokkos::ValLocScalar<scalar_type, index_type>;
826 using result_view_type = ::Kokkos::View<value_type, Space>;
829 result_view_type value;
830 bool references_scalar_v;
833 KOKKOS_INLINE_FUNCTION
834 MinFirstLoc(value_type& value_) : value(&value_), references_scalar_v(true) {}
836 KOKKOS_INLINE_FUNCTION
837 MinFirstLoc(
const result_view_type& value_)
838 : value(value_), references_scalar_v(false) {}
841 KOKKOS_INLINE_FUNCTION
842 void join(value_type& dest,
const value_type& src)
const {
843 if (src.val < dest.val) {
845 }
else if (!(dest.val < src.val)) {
846 dest.loc = (src.loc < dest.loc) ? src.loc : dest.loc;
850 KOKKOS_INLINE_FUNCTION
851 void init(value_type& val)
const {
852 val.val = reduction_identity<scalar_type>::min();
853 val.loc = reduction_identity<index_type>::min();
856 KOKKOS_INLINE_FUNCTION
857 value_type& reference()
const {
return *value.data(); }
859 KOKKOS_INLINE_FUNCTION
860 result_view_type view()
const {
return value; }
862 KOKKOS_INLINE_FUNCTION
863 bool references_scalar()
const {
return references_scalar_v; }
866 template <
typename Scalar,
typename Index,
typename... Properties>
867 KOKKOS_DEDUCTION_GUIDE MinFirstLoc(
868 View<ValLocScalar<Scalar, Index>, Properties...>
const&)
869 -> MinFirstLoc<Scalar, Index,
870 typename View<ValLocScalar<Scalar, Index>,
871 Properties...>::memory_space>;
877 template <
class Scalar,
class Index,
class ComparatorType,
class Space>
878 struct MinFirstLocCustomComparator {
880 using scalar_type = std::remove_cv_t<Scalar>;
881 using index_type = std::remove_cv_t<Index>;
882 static_assert(!std::is_pointer_v<scalar_type> &&
883 !std::is_array_v<scalar_type>);
884 static_assert(std::is_integral_v<index_type>);
889 MinFirstLocCustomComparator<Scalar, Index, ComparatorType, Space>;
890 using value_type = ::Kokkos::ValLocScalar<scalar_type, index_type>;
892 using result_view_type = ::Kokkos::View<value_type, Space>;
895 result_view_type value;
896 bool references_scalar_v;
897 ComparatorType m_comp;
900 KOKKOS_INLINE_FUNCTION
901 MinFirstLocCustomComparator(value_type& value_, ComparatorType comp_)
902 : value(&value_), references_scalar_v(true), m_comp(comp_) {}
904 KOKKOS_INLINE_FUNCTION
905 MinFirstLocCustomComparator(
const result_view_type& value_,
906 ComparatorType comp_)
907 : value(value_), references_scalar_v(false), m_comp(comp_) {}
910 KOKKOS_INLINE_FUNCTION
911 void join(value_type& dest,
const value_type& src)
const {
912 if (m_comp(src.val, dest.val)) {
914 }
else if (!m_comp(dest.val, src.val)) {
915 dest.loc = (src.loc < dest.loc) ? src.loc : dest.loc;
919 KOKKOS_INLINE_FUNCTION
920 void init(value_type& val)
const {
921 val.val = reduction_identity<scalar_type>::min();
922 val.loc = reduction_identity<index_type>::min();
925 KOKKOS_INLINE_FUNCTION
926 value_type& reference()
const {
return *value.data(); }
928 KOKKOS_INLINE_FUNCTION
929 result_view_type view()
const {
return value; }
931 KOKKOS_INLINE_FUNCTION
932 bool references_scalar()
const {
return references_scalar_v; }
935 template <
typename Scalar,
typename Index,
typename ComparatorType,
936 typename... Properties>
937 KOKKOS_DEDUCTION_GUIDE MinFirstLocCustomComparator(
938 View<ValLocScalar<Scalar, Index>, Properties...>
const&, ComparatorType)
939 -> MinFirstLocCustomComparator<Scalar, Index, ComparatorType,
940 typename View<ValLocScalar<Scalar, Index>,
941 Properties...>::memory_space>;
946 template <
class Scalar,
class Index,
class Space>
947 struct MinMaxFirstLastLoc {
949 using scalar_type = std::remove_cv_t<Scalar>;
950 using index_type = std::remove_cv_t<Index>;
951 static_assert(!std::is_pointer_v<scalar_type> &&
952 !std::is_array_v<scalar_type>);
953 static_assert(std::is_integral_v<index_type>);
957 using reducer = MinMaxFirstLastLoc<Scalar, Index, Space>;
958 using value_type = ::Kokkos::MinMaxLocScalar<scalar_type, index_type>;
960 using result_view_type = ::Kokkos::View<value_type, Space>;
963 result_view_type value;
964 bool references_scalar_v;
967 KOKKOS_INLINE_FUNCTION
968 MinMaxFirstLastLoc(value_type& value_)
969 : value(&value_), references_scalar_v(true) {}
971 KOKKOS_INLINE_FUNCTION
972 MinMaxFirstLastLoc(
const result_view_type& value_)
973 : value(value_), references_scalar_v(false) {}
976 KOKKOS_INLINE_FUNCTION
977 void join(value_type& dest,
const value_type& src)
const {
978 if (src.min_val < dest.min_val) {
979 dest.min_val = src.min_val;
980 dest.min_loc = src.min_loc;
981 }
else if (!(dest.min_val < src.min_val)) {
982 dest.min_loc = (src.min_loc < dest.min_loc) ? src.min_loc : dest.min_loc;
985 if (dest.max_val < src.max_val) {
986 dest.max_val = src.max_val;
987 dest.max_loc = src.max_loc;
988 }
else if (!(src.max_val < dest.max_val)) {
989 dest.max_loc = (src.max_loc > dest.max_loc) ? src.max_loc : dest.max_loc;
993 KOKKOS_INLINE_FUNCTION
994 void init(value_type& val)
const {
995 val.max_val = ::Kokkos::reduction_identity<scalar_type>::max();
996 val.min_val = ::Kokkos::reduction_identity<scalar_type>::min();
997 val.max_loc = ::Kokkos::reduction_identity<index_type>::max();
998 val.min_loc = ::Kokkos::reduction_identity<index_type>::min();
1001 KOKKOS_INLINE_FUNCTION
1002 value_type& reference()
const {
return *value.data(); }
1004 KOKKOS_INLINE_FUNCTION
1005 result_view_type view()
const {
return value; }
1007 KOKKOS_INLINE_FUNCTION
1008 bool references_scalar()
const {
return references_scalar_v; }
1011 template <
typename Scalar,
typename Index,
typename... Properties>
1012 KOKKOS_DEDUCTION_GUIDE MinMaxFirstLastLoc(
1013 View<MinMaxLocScalar<Scalar, Index>, Properties...>
const&)
1014 -> MinMaxFirstLastLoc<Scalar, Index,
1015 typename View<MinMaxLocScalar<Scalar, Index>,
1016 Properties...>::memory_space>;
1022 template <
class Scalar,
class Index,
class ComparatorType,
class Space>
1023 struct MinMaxFirstLastLocCustomComparator {
1025 using scalar_type = std::remove_cv_t<Scalar>;
1026 using index_type = std::remove_cv_t<Index>;
1027 static_assert(!std::is_pointer_v<scalar_type> &&
1028 !std::is_array_v<scalar_type>);
1029 static_assert(std::is_integral_v<index_type>);
1034 MinMaxFirstLastLocCustomComparator<Scalar, Index, ComparatorType, Space>;
1035 using value_type = ::Kokkos::MinMaxLocScalar<scalar_type, index_type>;
1037 using result_view_type = ::Kokkos::View<value_type, Space>;
1040 result_view_type value;
1041 bool references_scalar_v;
1042 ComparatorType m_comp;
1045 KOKKOS_INLINE_FUNCTION
1046 MinMaxFirstLastLocCustomComparator(value_type& value_, ComparatorType comp_)
1047 : value(&value_), references_scalar_v(true), m_comp(comp_) {}
1049 KOKKOS_INLINE_FUNCTION
1050 MinMaxFirstLastLocCustomComparator(
const result_view_type& value_,
1051 ComparatorType comp_)
1052 : value(value_), references_scalar_v(false), m_comp(comp_) {}
1055 KOKKOS_INLINE_FUNCTION
1056 void join(value_type& dest,
const value_type& src)
const {
1057 if (m_comp(src.min_val, dest.min_val)) {
1058 dest.min_val = src.min_val;
1059 dest.min_loc = src.min_loc;
1060 }
else if (!m_comp(dest.min_val, src.min_val)) {
1061 dest.min_loc = (src.min_loc < dest.min_loc) ? src.min_loc : dest.min_loc;
1064 if (m_comp(dest.max_val, src.max_val)) {
1065 dest.max_val = src.max_val;
1066 dest.max_loc = src.max_loc;
1067 }
else if (!m_comp(src.max_val, dest.max_val)) {
1068 dest.max_loc = (src.max_loc > dest.max_loc) ? src.max_loc : dest.max_loc;
1072 KOKKOS_INLINE_FUNCTION
1073 void init(value_type& val)
const {
1074 val.max_val = ::Kokkos::reduction_identity<scalar_type>::max();
1075 val.min_val = ::Kokkos::reduction_identity<scalar_type>::min();
1076 val.max_loc = ::Kokkos::reduction_identity<index_type>::max();
1077 val.min_loc = ::Kokkos::reduction_identity<index_type>::min();
1080 KOKKOS_INLINE_FUNCTION
1081 value_type& reference()
const {
return *value.data(); }
1083 KOKKOS_INLINE_FUNCTION
1084 result_view_type view()
const {
return value; }
1086 KOKKOS_INLINE_FUNCTION
1087 bool references_scalar()
const {
return references_scalar_v; }
1090 template <
typename Scalar,
typename Index,
typename ComparatorType,
1091 typename... Properties>
1092 KOKKOS_DEDUCTION_GUIDE MinMaxFirstLastLocCustomComparator(
1093 View<MinMaxLocScalar<Scalar, Index>, Properties...>
const&, ComparatorType)
1094 -> MinMaxFirstLastLocCustomComparator<
1095 Scalar, Index, ComparatorType,
1096 typename View<MinMaxLocScalar<Scalar, Index>,
1097 Properties...>::memory_space>;
1102 template <
class Index>
1103 struct FirstLocScalar {
1107 template <
class Index,
class Space>
1110 using index_type = std::remove_cv_t<Index>;
1111 static_assert(std::is_integral_v<index_type>);
1115 using reducer = FirstLoc<Index, Space>;
1116 using value_type = FirstLocScalar<index_type>;
1118 using result_view_type = ::Kokkos::View<value_type, Space>;
1121 result_view_type value;
1122 bool references_scalar_v;
1125 KOKKOS_INLINE_FUNCTION
1126 FirstLoc(value_type& value_) : value(&value_), references_scalar_v(true) {}
1128 KOKKOS_INLINE_FUNCTION
1129 FirstLoc(
const result_view_type& value_)
1130 : value(value_), references_scalar_v(false) {}
1133 KOKKOS_INLINE_FUNCTION
1134 void join(value_type& dest,
const value_type& src)
const {
1135 dest.min_loc_true = (src.min_loc_true < dest.min_loc_true)
1137 : dest.min_loc_true;
1140 KOKKOS_INLINE_FUNCTION
1141 void init(value_type& val)
const {
1142 val.min_loc_true = ::Kokkos::reduction_identity<index_type>::min();
1145 KOKKOS_INLINE_FUNCTION
1146 value_type& reference()
const {
return *value.data(); }
1148 KOKKOS_INLINE_FUNCTION
1149 result_view_type view()
const {
return value; }
1151 KOKKOS_INLINE_FUNCTION
1152 bool references_scalar()
const {
return references_scalar_v; }
1155 template <
typename Index,
typename... Properties>
1156 KOKKOS_DEDUCTION_GUIDE
1157 FirstLoc(View<FirstLocScalar<Index>, Properties...>
const&) -> FirstLoc<
1158 Index,
typename View<FirstLocScalar<Index>, Properties...>::memory_space>;
1163 template <
class Index>
1164 struct LastLocScalar {
1168 template <
class Index,
class Space>
1171 using index_type = std::remove_cv_t<Index>;
1172 static_assert(std::is_integral_v<index_type>);
1176 using reducer = LastLoc<Index, Space>;
1177 using value_type = LastLocScalar<index_type>;
1179 using result_view_type = ::Kokkos::View<value_type, Space>;
1182 result_view_type value;
1183 bool references_scalar_v;
1186 KOKKOS_INLINE_FUNCTION
1187 LastLoc(value_type& value_) : value(&value_), references_scalar_v(true) {}
1189 KOKKOS_INLINE_FUNCTION
1190 LastLoc(
const result_view_type& value_)
1191 : value(value_), references_scalar_v(false) {}
1194 KOKKOS_INLINE_FUNCTION
1195 void join(value_type& dest,
const value_type& src)
const {
1196 dest.max_loc_true = (src.max_loc_true > dest.max_loc_true)
1198 : dest.max_loc_true;
1201 KOKKOS_INLINE_FUNCTION
1202 void init(value_type& val)
const {
1203 val.max_loc_true = ::Kokkos::reduction_identity<index_type>::max();
1206 KOKKOS_INLINE_FUNCTION
1207 value_type& reference()
const {
return *value.data(); }
1209 KOKKOS_INLINE_FUNCTION
1210 result_view_type view()
const {
return value; }
1212 KOKKOS_INLINE_FUNCTION
1213 bool references_scalar()
const {
return references_scalar_v; }
1216 template <
typename Index,
typename... Properties>
1217 KOKKOS_DEDUCTION_GUIDE LastLoc(View<LastLocScalar<Index>, Properties...>
const&)
1218 -> LastLoc<Index, typename View<LastLocScalar<Index>,
1219 Properties...>::memory_space>;
1221 template <
class Index>
1222 struct StdIsPartScalar {
1223 Index max_loc_true, min_loc_false;
1229 template <
class Index,
class Space>
1230 struct StdIsPartitioned {
1232 using index_type = std::remove_cv_t<Index>;
1233 static_assert(std::is_integral_v<index_type>);
1237 using reducer = StdIsPartitioned<Index, Space>;
1238 using value_type = StdIsPartScalar<index_type>;
1240 using result_view_type = ::Kokkos::View<value_type, Space>;
1243 result_view_type value;
1244 bool references_scalar_v;
1247 KOKKOS_INLINE_FUNCTION
1248 StdIsPartitioned(value_type& value_)
1249 : value(&value_), references_scalar_v(true) {}
1251 KOKKOS_INLINE_FUNCTION
1252 StdIsPartitioned(
const result_view_type& value_)
1253 : value(value_), references_scalar_v(false) {}
1256 KOKKOS_INLINE_FUNCTION
1257 void join(value_type& dest,
const value_type& src)
const {
1258 dest.max_loc_true = (dest.max_loc_true < src.max_loc_true)
1260 : dest.max_loc_true;
1262 dest.min_loc_false = (dest.min_loc_false < src.min_loc_false)
1263 ? dest.min_loc_false
1264 : src.min_loc_false;
1267 KOKKOS_INLINE_FUNCTION
1268 void init(value_type& val)
const {
1269 val.max_loc_true = ::Kokkos::reduction_identity<index_type>::max();
1270 val.min_loc_false = ::Kokkos::reduction_identity<index_type>::min();
1273 KOKKOS_INLINE_FUNCTION
1274 value_type& reference()
const {
return *value.data(); }
1276 KOKKOS_INLINE_FUNCTION
1277 result_view_type view()
const {
return value; }
1279 KOKKOS_INLINE_FUNCTION
1280 bool references_scalar()
const {
return references_scalar_v; }
1283 template <
typename Index,
typename... Properties>
1284 KOKKOS_DEDUCTION_GUIDE StdIsPartitioned(
1285 View<StdIsPartScalar<Index>, Properties...>
const&)
1286 -> StdIsPartitioned<Index, typename View<StdIsPartScalar<Index>,
1287 Properties...>::memory_space>;
1289 template <
class Index>
1290 struct StdPartPointScalar {
1291 Index min_loc_false;
1297 template <
class Index,
class Space>
1298 struct StdPartitionPoint {
1300 using index_type = std::remove_cv_t<Index>;
1301 static_assert(std::is_integral_v<index_type>);
1305 using reducer = StdPartitionPoint<Index, Space>;
1306 using value_type = StdPartPointScalar<index_type>;
1308 using result_view_type = ::Kokkos::View<value_type, Space>;
1311 result_view_type value;
1312 bool references_scalar_v;
1315 KOKKOS_INLINE_FUNCTION
1316 StdPartitionPoint(value_type& value_)
1317 : value(&value_), references_scalar_v(true) {}
1319 KOKKOS_INLINE_FUNCTION
1320 StdPartitionPoint(
const result_view_type& value_)
1321 : value(value_), references_scalar_v(false) {}
1324 KOKKOS_INLINE_FUNCTION
1325 void join(value_type& dest,
const value_type& src)
const {
1326 dest.min_loc_false = (dest.min_loc_false < src.min_loc_false)
1327 ? dest.min_loc_false
1328 : src.min_loc_false;
1331 KOKKOS_INLINE_FUNCTION
1332 void init(value_type& val)
const {
1333 val.min_loc_false = ::Kokkos::reduction_identity<index_type>::min();
1336 KOKKOS_INLINE_FUNCTION
1337 value_type& reference()
const {
return *value.data(); }
1339 KOKKOS_INLINE_FUNCTION
1340 result_view_type view()
const {
return value; }
1342 KOKKOS_INLINE_FUNCTION
1343 bool references_scalar()
const {
return references_scalar_v; }
1346 template <
typename Index,
typename... Properties>
1347 KOKKOS_DEDUCTION_GUIDE StdPartitionPoint(
1348 View<StdPartPointScalar<Index>, Properties...>
const&)
1349 -> StdPartitionPoint<Index, typename View<StdPartPointScalar<Index>,
1350 Properties...>::memory_space>;
1356 template <
typename FunctorType,
typename FunctorAnalysisReducerType,
1358 class CombinedFunctorReducer {
1360 using functor_type = FunctorType;
1361 using reducer_type = FunctorAnalysisReducerType;
1362 CombinedFunctorReducer(
const FunctorType& functor,
1363 const FunctorAnalysisReducerType& reducer)
1364 : m_functor(functor), m_reducer(reducer) {}
1365 KOKKOS_FUNCTION
const FunctorType& get_functor()
const {
return m_functor; }
1366 KOKKOS_FUNCTION
const FunctorAnalysisReducerType& get_reducer()
const {
1371 FunctorType m_functor;
1372 FunctorAnalysisReducerType m_reducer;
1374 template <
typename FunctorType,
typename FunctorAnalysisReducerType>
1375 class CombinedFunctorReducer<
1376 FunctorType, FunctorAnalysisReducerType,
1377 std::enable_if_t<std::is_same_v<
1378 FunctorType, typename FunctorAnalysisReducerType::functor_type>>> {
1380 using functor_type = FunctorType;
1381 using reducer_type = FunctorAnalysisReducerType;
1382 CombinedFunctorReducer(
const FunctorType& functor,
1383 const FunctorAnalysisReducerType&)
1384 : m_reducer(functor) {}
1385 KOKKOS_FUNCTION
const FunctorType& get_functor()
const {
1386 return m_reducer.get_functor();
1388 KOKKOS_FUNCTION
const FunctorAnalysisReducerType& get_reducer()
const {
1393 FunctorAnalysisReducerType m_reducer;
1396 template <
class T,
class ReturnType,
class ValueTraits>
1397 struct ParallelReduceReturnValue;
1399 template <
class ReturnType,
class FunctorType>
1400 struct ParallelReduceReturnValue<
1401 std::enable_if_t<Kokkos::is_view<ReturnType>::value>,
ReturnType,
1404 using reducer_type = InvalidType;
1406 using value_type_scalar =
typename return_type::value_type;
1407 using value_type_array =
typename return_type::value_type*
const;
1409 using value_type = std::conditional_t<return_type::rank == 0,
1410 value_type_scalar, value_type_array>;
1412 static return_type& return_value(
ReturnType& return_val,
const FunctorType&) {
1417 template <
class ReturnType,
class FunctorType>
1418 struct ParallelReduceReturnValue<
1419 std::enable_if_t<!Kokkos::is_view<ReturnType>::value &&
1420 (!std::is_array_v<ReturnType> &&
1422 ReturnType>)&&!Kokkos::is_reducer<ReturnType>::value>,
1425 Kokkos::View<ReturnType, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>;
1427 using reducer_type = InvalidType;
1429 using value_type =
typename return_type::value_type;
1431 static return_type return_value(
ReturnType& return_val,
const FunctorType&) {
1432 return return_type(&return_val);
1436 template <
class ReturnType,
class FunctorType>
1437 struct ParallelReduceReturnValue<
1438 std::enable_if_t<(std::is_array_v<ReturnType> ||
1439 std::is_pointer_v<ReturnType>)>,
1441 using return_type = Kokkos::View<std::remove_const_t<ReturnType>,
1444 using reducer_type = InvalidType;
1446 using value_type =
typename return_type::value_type[];
1448 static return_type return_value(
ReturnType& return_val,
1449 const FunctorType& functor) {
1450 if (std::is_array_v<ReturnType>)
1451 return return_type(return_val);
1453 return return_type(return_val, functor.value_count);
1457 template <
class ReturnType,
class FunctorType>
1458 struct ParallelReduceReturnValue<
1459 std::enable_if_t<Kokkos::is_reducer<ReturnType>::value>,
ReturnType,
1461 using return_type =
typename ReturnType::result_view_type;
1463 using value_type =
typename return_type::value_type;
1465 static auto return_value(
ReturnType& return_val,
const FunctorType&) {
1466 return return_val.view();
1470 template <
class T,
class ReturnType,
class FunctorType>
1471 struct ParallelReducePolicyType;
1473 template <
class PolicyType,
class FunctorType>
1474 struct ParallelReducePolicyType<
1475 std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value>,
1476 PolicyType, FunctorType> {
1477 using policy_type = PolicyType;
1478 static PolicyType policy(
const PolicyType& policy_) {
return policy_; }
1481 template <
class PolicyType,
class FunctorType>
1482 struct ParallelReducePolicyType<
1483 std::enable_if_t<std::is_integral_v<PolicyType>>, PolicyType, FunctorType> {
1484 using execution_space =
1485 typename Impl::FunctorPolicyExecutionSpace<FunctorType,
1486 void>::execution_space;
1490 static policy_type policy(
const PolicyType& policy_) {
1491 return policy_type(0, policy_);
1495 template <
class FunctorType,
class ExecPolicy,
class ValueType,
1496 class ExecutionSpace>
1497 struct ParallelReduceFunctorType {
1498 using functor_type = FunctorType;
1499 static const functor_type& functor(
const functor_type& functor) {
1504 template <
class PolicyType,
class FunctorType,
class ReturnType>
1505 struct ParallelReduceAdaptor {
1506 using return_value_adapter =
1507 Impl::ParallelReduceReturnValue<void, ReturnType, FunctorType>;
1509 static inline void execute_impl(
const std::string& label,
1510 const PolicyType& policy,
1511 const FunctorType& functor,
1513 using PassedReducerType =
typename return_value_adapter::reducer_type;
1516 using ReducerSelector =
1517 Kokkos::Impl::if_c<std::is_same_v<InvalidType, PassedReducerType>,
1518 FunctorType, PassedReducerType>;
1519 using Analysis = FunctorAnalysis<FunctorPatternInterface::REDUCE,
1520 PolicyType,
typename ReducerSelector::type,
1521 typename return_value_adapter::value_type>;
1522 using CombinedFunctorReducerType =
1523 CombinedFunctorReducer<FunctorType, typename Analysis::Reducer>;
1525 CombinedFunctorReducerType functor_reducer(
1526 functor,
typename Analysis::Reducer(
1527 ReducerSelector::select(functor, return_value)));
1528 const auto& response = Kokkos::Tools::Impl::begin_parallel_reduce<
1529 typename return_value_adapter::reducer_type>(policy, functor_reducer,
1531 const auto& inner_policy = response.policy;
1533 auto closure = construct_with_shared_allocation_tracking_disabled<
1534 Impl::ParallelReduce<CombinedFunctorReducerType, PolicyType,
1535 typename Impl::FunctorPolicyExecutionSpace<
1536 FunctorType, PolicyType>::execution_space>>(
1537 functor_reducer, inner_policy,
1538 return_value_adapter::return_value(return_value, functor));
1541 Kokkos::Tools::Impl::end_parallel_reduce<PassedReducerType>(
1542 inner_policy, functor, label, kpID);
1545 static constexpr
bool is_array_reduction =
1546 Impl::FunctorAnalysis<
1547 Impl::FunctorPatternInterface::REDUCE, PolicyType, FunctorType,
1548 typename return_value_adapter::value_type>::StaticValueSize == 0;
1550 template <
typename Dummy = ReturnType>
1551 static inline std::enable_if_t<!(is_array_reduction &&
1552 std::is_pointer_v<Dummy>)>
1553 execute(
const std::string& label,
const PolicyType& policy,
1554 const FunctorType& functor,
ReturnType& return_value) {
1555 execute_impl(label, policy, functor, return_value);
1576 template <
typename T>
1577 struct ReducerHasTestReferenceFunction {
1578 template <
typename E>
1579 static std::true_type test_func(decltype(&E::references_scalar));
1580 template <
typename E>
1581 static std::false_type test_func(...);
1584 value = std::is_same_v<std::true_type, decltype(test_func<T>(
nullptr))>
1588 template <
class ExecutionSpace,
class Arg>
1589 constexpr std::enable_if_t<
1591 !ReducerHasTestReferenceFunction<Arg>::value &&
1592 !Kokkos::is_view<Arg>::value,
1595 parallel_reduce_needs_fence(ExecutionSpace
const&, Arg
const&) {
1599 template <
class ExecutionSpace,
class Reducer>
1600 constexpr std::enable_if_t<
1605 ReducerHasTestReferenceFunction<Reducer>::value,
1608 parallel_reduce_needs_fence(ExecutionSpace
const&, Reducer
const& reducer) {
1609 return reducer.references_scalar();
1612 template <
class ExecutionSpace,
class ViewLike>
1613 constexpr std::enable_if_t<
1615 Kokkos::is_view<ViewLike>::value,
1618 parallel_reduce_needs_fence(ExecutionSpace
const&, ViewLike
const&) {
1622 template <
class ExecutionSpace,
class... Args>
1623 struct ParallelReduceFence {
1624 template <
class... ArgsDeduced>
1625 static void fence(
const ExecutionSpace& ex,
const std::string& name,
1626 ArgsDeduced&&... args) {
1627 if (Impl::parallel_reduce_needs_fence(ex, (ArgsDeduced&&)args...)) {
1675 template <
class PolicyType,
class FunctorType,
class ReturnType>
1676 inline std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value &&
1677 !(Kokkos::is_view<ReturnType>::value ||
1678 Kokkos::is_reducer<ReturnType>::value ||
1679 std::is_pointer_v<ReturnType>)>
1680 parallel_reduce(
const std::string& label,
const PolicyType& policy,
1681 const FunctorType& functor,
ReturnType& return_value) {
1683 !std::is_const_v<ReturnType>,
1684 "A const reduction result type is only allowed for a View, pointer or "
1685 "reducer return type!");
1687 Impl::ParallelReduceAdaptor<PolicyType, FunctorType, ReturnType>::execute(
1688 label, policy, functor, return_value);
1689 Impl::ParallelReduceFence<typename PolicyType::execution_space, ReturnType>::
1692 "Kokkos::parallel_reduce: fence due to result being value, not view",
1696 template <
class PolicyType,
class FunctorType,
class ReturnType>
1697 inline std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value &&
1698 !(Kokkos::is_view<ReturnType>::value ||
1699 Kokkos::is_reducer<ReturnType>::value ||
1700 std::is_pointer_v<ReturnType>)>
1701 parallel_reduce(
const PolicyType& policy,
const FunctorType& functor,
1704 !std::is_const_v<ReturnType>,
1705 "A const reduction result type is only allowed for a View, pointer or "
1706 "reducer return type!");
1708 Impl::ParallelReduceAdaptor<PolicyType, FunctorType, ReturnType>::execute(
1709 "", policy, functor, return_value);
1710 Impl::ParallelReduceFence<typename PolicyType::execution_space, ReturnType>::
1713 "Kokkos::parallel_reduce: fence due to result being value, not view",
1717 template <
class FunctorType,
class ReturnType>
1718 inline std::enable_if_t<!(Kokkos::is_view<ReturnType>::value ||
1719 Kokkos::is_reducer<ReturnType>::value ||
1720 std::is_pointer_v<ReturnType>)>
1721 parallel_reduce(
const size_t& policy,
const FunctorType& functor,
1724 !std::is_const_v<ReturnType>,
1725 "A const reduction result type is only allowed for a View, pointer or "
1726 "reducer return type!");
1729 typename Impl::ParallelReducePolicyType<void, size_t,
1730 FunctorType>::policy_type;
1732 Impl::ParallelReduceAdaptor<policy_type, FunctorType, ReturnType>::execute(
1733 "", policy_type(0, policy), functor, return_value);
1734 Impl::ParallelReduceFence<typename policy_type::execution_space, ReturnType>::
1736 typename policy_type::execution_space(),
1737 "Kokkos::parallel_reduce: fence due to result being value, not view",
1741 template <
class FunctorType,
class ReturnType>
1742 inline std::enable_if_t<!(Kokkos::is_view<ReturnType>::value ||
1743 Kokkos::is_reducer<ReturnType>::value ||
1744 std::is_pointer_v<ReturnType>)>
1745 parallel_reduce(
const std::string& label,
const size_t& policy,
1746 const FunctorType& functor,
ReturnType& return_value) {
1748 !std::is_const_v<ReturnType>,
1749 "A const reduction result type is only allowed for a View, pointer or "
1750 "reducer return type!");
1753 typename Impl::ParallelReducePolicyType<void, size_t,
1754 FunctorType>::policy_type;
1755 Impl::ParallelReduceAdaptor<policy_type, FunctorType, ReturnType>::execute(
1756 label, policy_type(0, policy), functor, return_value);
1757 Impl::ParallelReduceFence<typename policy_type::execution_space, ReturnType>::
1759 typename policy_type::execution_space(),
1760 "Kokkos::parallel_reduce: fence due to result being value, not view",
1766 template <
class PolicyType,
class FunctorType,
class ReturnType>
1767 inline std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value &&
1768 (Kokkos::is_view<ReturnType>::value ||
1769 Kokkos::is_reducer<ReturnType>::value ||
1770 std::is_pointer_v<ReturnType>)>
1771 parallel_reduce(
const std::string& label,
const PolicyType& policy,
1772 const FunctorType& functor,
const ReturnType& return_value) {
1774 Impl::ParallelReduceAdaptor<PolicyType, FunctorType, ReturnType>::execute(
1775 label, policy, functor, return_value_impl);
1776 Impl::ParallelReduceFence<typename PolicyType::execution_space, ReturnType>::
1779 "Kokkos::parallel_reduce: fence due to result being value, not view",
1783 template <
class PolicyType,
class FunctorType,
class ReturnType>
1784 inline std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value &&
1785 (Kokkos::is_view<ReturnType>::value ||
1786 Kokkos::is_reducer<ReturnType>::value ||
1787 std::is_pointer_v<ReturnType>)>
1788 parallel_reduce(
const PolicyType& policy,
const FunctorType& functor,
1791 Impl::ParallelReduceAdaptor<PolicyType, FunctorType, ReturnType>::execute(
1792 "", policy, functor, return_value_impl);
1793 Impl::ParallelReduceFence<typename PolicyType::execution_space, ReturnType>::
1796 "Kokkos::parallel_reduce: fence due to result being value, not view",
1800 template <
class FunctorType,
class ReturnType>
1801 inline std::enable_if_t<Kokkos::is_view<ReturnType>::value ||
1802 Kokkos::is_reducer<ReturnType>::value ||
1803 std::is_pointer_v<ReturnType>>
1804 parallel_reduce(
const size_t& policy,
const FunctorType& functor,
1807 typename Impl::ParallelReducePolicyType<void, size_t,
1808 FunctorType>::policy_type;
1810 Impl::ParallelReduceAdaptor<policy_type, FunctorType, ReturnType>::execute(
1811 "", policy_type(0, policy), functor, return_value_impl);
1812 Impl::ParallelReduceFence<typename policy_type::execution_space, ReturnType>::
1814 typename policy_type::execution_space(),
1815 "Kokkos::parallel_reduce: fence due to result being value, not view",
1819 template <
class FunctorType,
class ReturnType>
1820 inline std::enable_if_t<Kokkos::is_view<ReturnType>::value ||
1821 Kokkos::is_reducer<ReturnType>::value ||
1822 std::is_pointer_v<ReturnType>>
1823 parallel_reduce(
const std::string& label,
const size_t& policy,
1824 const FunctorType& functor,
const ReturnType& return_value) {
1826 typename Impl::ParallelReducePolicyType<void, size_t,
1827 FunctorType>::policy_type;
1829 Impl::ParallelReduceAdaptor<policy_type, FunctorType, ReturnType>::execute(
1830 label, policy_type(0, policy), functor, return_value_impl);
1831 Impl::ParallelReduceFence<typename policy_type::execution_space, ReturnType>::
1833 typename policy_type::execution_space(),
1834 "Kokkos::parallel_reduce: fence due to result being value, not view",
1840 template <
class PolicyType,
class FunctorType>
1841 inline void parallel_reduce(
1842 const std::string& label,
const PolicyType& policy,
1843 const FunctorType& functor,
1844 std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value>* =
1846 using FunctorAnalysis =
1847 Impl::FunctorAnalysis<Impl::FunctorPatternInterface::REDUCE, PolicyType,
1849 using value_type = std::conditional_t<(FunctorAnalysis::StaticValueSize != 0),
1850 typename FunctorAnalysis::value_type,
1851 typename FunctorAnalysis::pointer_type>;
1854 FunctorAnalysis::has_final_member_function,
1855 "Calling parallel_reduce without either return value or final function.");
1857 using result_view_type =
1858 Kokkos::View<value_type, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>;
1859 result_view_type result_view;
1861 Impl::ParallelReduceAdaptor<PolicyType, FunctorType,
1862 result_view_type>::execute(label, policy, functor,
1866 template <
class PolicyType,
class FunctorType>
1867 inline void parallel_reduce(
1868 const PolicyType& policy,
const FunctorType& functor,
1869 std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value>* =
1871 using FunctorAnalysis =
1872 Impl::FunctorAnalysis<Impl::FunctorPatternInterface::REDUCE, PolicyType,
1874 using value_type = std::conditional_t<(FunctorAnalysis::StaticValueSize != 0),
1875 typename FunctorAnalysis::value_type,
1876 typename FunctorAnalysis::pointer_type>;
1879 FunctorAnalysis::has_final_member_function,
1880 "Calling parallel_reduce without either return value or final function.");
1882 using result_view_type =
1883 Kokkos::View<value_type, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>;
1884 result_view_type result_view;
1886 Impl::ParallelReduceAdaptor<PolicyType, FunctorType,
1887 result_view_type>::execute(
"", policy, functor,
1891 template <
class FunctorType>
1892 inline void parallel_reduce(
const size_t& policy,
const FunctorType& functor) {
1894 typename Impl::ParallelReducePolicyType<void, size_t,
1895 FunctorType>::policy_type;
1896 using FunctorAnalysis =
1897 Impl::FunctorAnalysis<Impl::FunctorPatternInterface::REDUCE, policy_type,
1899 using value_type = std::conditional_t<(FunctorAnalysis::StaticValueSize != 0),
1900 typename FunctorAnalysis::value_type,
1901 typename FunctorAnalysis::pointer_type>;
1904 FunctorAnalysis::has_final_member_function,
1905 "Calling parallel_reduce without either return value or final function.");
1907 using result_view_type =
1908 Kokkos::View<value_type, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>;
1909 result_view_type result_view;
1911 Impl::ParallelReduceAdaptor<policy_type, FunctorType,
1912 result_view_type>::execute(
"",
1913 policy_type(0, policy),
1914 functor, result_view);
1917 template <
class FunctorType>
1918 inline void parallel_reduce(
const std::string& label,
const size_t& policy,
1919 const FunctorType& functor) {
1921 typename Impl::ParallelReducePolicyType<void, size_t,
1922 FunctorType>::policy_type;
1923 using FunctorAnalysis =
1924 Impl::FunctorAnalysis<Impl::FunctorPatternInterface::REDUCE, policy_type,
1926 using value_type = std::conditional_t<(FunctorAnalysis::StaticValueSize != 0),
1927 typename FunctorAnalysis::value_type,
1928 typename FunctorAnalysis::pointer_type>;
1931 FunctorAnalysis::has_final_member_function,
1932 "Calling parallel_reduce without either return value or final function.");
1934 using result_view_type =
1935 Kokkos::View<value_type, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>;
1936 result_view_type result_view;
1938 Impl::ParallelReduceAdaptor<policy_type, FunctorType,
1939 result_view_type>::execute(label,
1940 policy_type(0, policy),
1941 functor, result_view);
1946 #endif // KOKKOS_PARALLEL_REDUCE_HPP
Memory management for host memory.
Execution policy for work over a range of an integral type.