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>
34template <
class Scalar,
class Space>
38 using reducer = Sum<Scalar, Space>;
39 using value_type = std::remove_cv_t<Scalar>;
40 static_assert(!std::is_pointer_v<value_type> && !std::is_array_v<value_type>);
42 using result_view_type = Kokkos::View<value_type, Space>;
45 result_view_type value;
46 bool references_scalar_v;
49 KOKKOS_INLINE_FUNCTION
50 Sum(value_type& value_) : value(&value_), references_scalar_v(true) {}
52 KOKKOS_INLINE_FUNCTION
53 Sum(
const result_view_type& value_)
54 : value(value_), references_scalar_v(false) {}
57 KOKKOS_INLINE_FUNCTION
58 void join(value_type& dest,
const value_type& src)
const { dest += src; }
60 KOKKOS_INLINE_FUNCTION
61 void init(value_type& val)
const {
62 val = reduction_identity<value_type>::sum();
65 KOKKOS_INLINE_FUNCTION
66 value_type& reference()
const {
return *value.data(); }
68 KOKKOS_INLINE_FUNCTION
69 result_view_type view()
const {
return value; }
71 KOKKOS_INLINE_FUNCTION
72 bool references_scalar()
const {
return references_scalar_v; }
75template <
typename Scalar,
typename... Properties>
77 ->Sum<Scalar,
typename View<Scalar, Properties...>::memory_space>;
79template <
class Scalar,
class Space>
83 using reducer = Prod<Scalar, Space>;
84 using value_type = std::remove_cv_t<Scalar>;
85 static_assert(!std::is_pointer_v<value_type> && !std::is_array_v<value_type>);
87 using result_view_type = Kokkos::View<value_type, Space>;
90 result_view_type value;
91 bool references_scalar_v;
94 KOKKOS_INLINE_FUNCTION
95 Prod(value_type& value_) : value(&value_), references_scalar_v(true) {}
97 KOKKOS_INLINE_FUNCTION
98 Prod(
const result_view_type& value_)
99 : value(value_), references_scalar_v(false) {}
102 KOKKOS_INLINE_FUNCTION
103 void join(value_type& dest,
const value_type& src)
const { dest *= src; }
105 KOKKOS_INLINE_FUNCTION
106 void init(value_type& val)
const {
107 val = reduction_identity<value_type>::prod();
110 KOKKOS_INLINE_FUNCTION
111 value_type& reference()
const {
return *value.data(); }
113 KOKKOS_INLINE_FUNCTION
114 result_view_type view()
const {
return value; }
116 KOKKOS_INLINE_FUNCTION
117 bool references_scalar()
const {
return references_scalar_v; }
120template <
typename Scalar,
typename... Properties>
122 ->Prod<Scalar,
typename View<Scalar, Properties...>::memory_space>;
124template <
class Scalar,
class Space>
128 using reducer = Min<Scalar, Space>;
129 using value_type = std::remove_cv_t<Scalar>;
130 static_assert(!std::is_pointer_v<value_type> && !std::is_array_v<value_type>);
132 using result_view_type = Kokkos::View<value_type, Space>;
135 result_view_type value;
136 bool references_scalar_v;
139 KOKKOS_INLINE_FUNCTION
140 Min(value_type& value_) : value(&value_), references_scalar_v(true) {}
142 KOKKOS_INLINE_FUNCTION
143 Min(
const result_view_type& value_)
144 : value(value_), references_scalar_v(false) {}
147 KOKKOS_INLINE_FUNCTION
148 void join(value_type& dest,
const value_type& src)
const {
149 if (src < dest) dest = src;
152 KOKKOS_INLINE_FUNCTION
153 void init(value_type& val)
const {
154 val = reduction_identity<value_type>::min();
157 KOKKOS_INLINE_FUNCTION
158 value_type& reference()
const {
return *value.data(); }
160 KOKKOS_INLINE_FUNCTION
161 result_view_type view()
const {
return value; }
163 KOKKOS_INLINE_FUNCTION
164 bool references_scalar()
const {
return references_scalar_v; }
167template <
typename Scalar,
typename... Properties>
169 ->Min<Scalar,
typename View<Scalar, Properties...>::memory_space>;
171template <
class Scalar,
class Space>
175 using reducer = Max<Scalar, Space>;
176 using value_type = std::remove_cv_t<Scalar>;
177 static_assert(!std::is_pointer_v<value_type> && !std::is_array_v<value_type>);
179 using result_view_type = Kokkos::View<value_type, Space>;
182 result_view_type value;
183 bool references_scalar_v;
186 KOKKOS_INLINE_FUNCTION
187 Max(value_type& value_) : value(&value_), references_scalar_v(true) {}
189 KOKKOS_INLINE_FUNCTION
190 Max(
const result_view_type& value_)
191 : value(value_), references_scalar_v(false) {}
194 KOKKOS_INLINE_FUNCTION
195 void join(value_type& dest,
const value_type& src)
const {
196 if (src > dest) dest = src;
200 KOKKOS_INLINE_FUNCTION
201 void init(value_type& val)
const {
202 val = reduction_identity<value_type>::max();
205 KOKKOS_INLINE_FUNCTION
206 value_type& reference()
const {
return *value.data(); }
208 KOKKOS_INLINE_FUNCTION
209 result_view_type view()
const {
return value; }
211 KOKKOS_INLINE_FUNCTION
212 bool references_scalar()
const {
return references_scalar_v; }
215template <
typename Scalar,
typename... Properties>
217 ->Max<Scalar,
typename View<Scalar, Properties...>::memory_space>;
219template <
class Scalar,
class Space>
223 using reducer = LAnd<Scalar, Space>;
224 using value_type = std::remove_cv_t<Scalar>;
225 static_assert(!std::is_pointer_v<value_type> && !std::is_array_v<value_type>);
227 using result_view_type = Kokkos::View<value_type, Space>;
230 result_view_type value;
231 bool references_scalar_v;
234 KOKKOS_INLINE_FUNCTION
235 LAnd(value_type& value_) : value(&value_), references_scalar_v(true) {}
237 KOKKOS_INLINE_FUNCTION
238 LAnd(
const result_view_type& value_)
239 : value(value_), references_scalar_v(false) {}
241 KOKKOS_INLINE_FUNCTION
242 void join(value_type& dest,
const value_type& src)
const {
246 KOKKOS_INLINE_FUNCTION
247 void init(value_type& val)
const {
248 val = reduction_identity<value_type>::land();
251 KOKKOS_INLINE_FUNCTION
252 value_type& reference()
const {
return *value.data(); }
254 KOKKOS_INLINE_FUNCTION
255 result_view_type view()
const {
return value; }
257 KOKKOS_INLINE_FUNCTION
258 bool references_scalar()
const {
return references_scalar_v; }
261template <
typename Scalar,
typename... Properties>
263 ->LAnd<Scalar,
typename View<Scalar, Properties...>::memory_space>;
265template <
class Scalar,
class Space>
269 using reducer = LOr<Scalar, Space>;
270 using value_type = std::remove_cv_t<Scalar>;
271 static_assert(!std::is_pointer_v<value_type> && !std::is_array_v<value_type>);
273 using result_view_type = Kokkos::View<value_type, Space>;
276 result_view_type value;
277 bool references_scalar_v;
280 KOKKOS_INLINE_FUNCTION
281 LOr(value_type& value_) : value(&value_), references_scalar_v(true) {}
283 KOKKOS_INLINE_FUNCTION
284 LOr(
const result_view_type& value_)
285 : value(value_), references_scalar_v(false) {}
288 KOKKOS_INLINE_FUNCTION
289 void join(value_type& dest,
const value_type& src)
const {
293 KOKKOS_INLINE_FUNCTION
294 void init(value_type& val)
const {
295 val = reduction_identity<value_type>::lor();
298 KOKKOS_INLINE_FUNCTION
299 value_type& reference()
const {
return *value.data(); }
301 KOKKOS_INLINE_FUNCTION
302 result_view_type view()
const {
return value; }
304 KOKKOS_INLINE_FUNCTION
305 bool references_scalar()
const {
return references_scalar_v; }
308template <
typename Scalar,
typename... Properties>
310 ->LOr<Scalar,
typename View<Scalar, Properties...>::memory_space>;
312template <
class Scalar,
class Space>
316 using reducer = BAnd<Scalar, Space>;
317 using value_type = std::remove_cv_t<Scalar>;
318 static_assert(!std::is_pointer_v<value_type> && !std::is_array_v<value_type>);
320 using result_view_type = Kokkos::View<value_type, Space>;
323 result_view_type value;
324 bool references_scalar_v;
327 KOKKOS_INLINE_FUNCTION
328 BAnd(value_type& value_) : value(&value_), references_scalar_v(true) {}
330 KOKKOS_INLINE_FUNCTION
331 BAnd(
const result_view_type& value_)
332 : value(value_), references_scalar_v(false) {}
335 KOKKOS_INLINE_FUNCTION
336 void join(value_type& dest,
const value_type& src)
const {
340 KOKKOS_INLINE_FUNCTION
341 void init(value_type& val)
const {
342 val = reduction_identity<value_type>::band();
345 KOKKOS_INLINE_FUNCTION
346 value_type& reference()
const {
return *value.data(); }
348 KOKKOS_INLINE_FUNCTION
349 result_view_type view()
const {
return value; }
351 KOKKOS_INLINE_FUNCTION
352 bool references_scalar()
const {
return references_scalar_v; }
355template <
typename Scalar,
typename... Properties>
357 ->BAnd<Scalar,
typename View<Scalar, Properties...>::memory_space>;
359template <
class Scalar,
class Space>
363 using reducer = BOr<Scalar, Space>;
364 using value_type = std::remove_cv_t<Scalar>;
365 static_assert(!std::is_pointer_v<value_type> && !std::is_array_v<value_type>);
367 using result_view_type = Kokkos::View<value_type, Space>;
370 result_view_type value;
371 bool references_scalar_v;
374 KOKKOS_INLINE_FUNCTION
375 BOr(value_type& value_) : value(&value_), references_scalar_v(true) {}
377 KOKKOS_INLINE_FUNCTION
378 BOr(
const result_view_type& value_)
379 : value(value_), references_scalar_v(false) {}
382 KOKKOS_INLINE_FUNCTION
383 void join(value_type& dest,
const value_type& src)
const {
387 KOKKOS_INLINE_FUNCTION
388 void init(value_type& val)
const {
389 val = reduction_identity<value_type>::bor();
392 KOKKOS_INLINE_FUNCTION
393 value_type& reference()
const {
return *value.data(); }
395 KOKKOS_INLINE_FUNCTION
396 result_view_type view()
const {
return value; }
398 KOKKOS_INLINE_FUNCTION
399 bool references_scalar()
const {
return references_scalar_v; }
402template <
typename Scalar,
typename... Properties>
404 ->BOr<Scalar,
typename View<Scalar, Properties...>::memory_space>;
406template <
class Scalar,
class Index>
412template <
class Scalar,
class Index,
class Space>
415 using scalar_type = std::remove_cv_t<Scalar>;
416 using index_type = std::remove_cv_t<Index>;
417 static_assert(!std::is_pointer_v<scalar_type> &&
418 !std::is_array_v<scalar_type>);
422 using reducer = MinLoc<Scalar, Index, Space>;
423 using value_type = ValLocScalar<scalar_type, index_type>;
425 using result_view_type = Kokkos::View<value_type, Space>;
428 result_view_type value;
429 bool references_scalar_v;
432 KOKKOS_INLINE_FUNCTION
433 MinLoc(value_type& value_) : value(&value_), references_scalar_v(true) {}
435 KOKKOS_INLINE_FUNCTION
436 MinLoc(
const result_view_type& value_)
437 : value(value_), references_scalar_v(false) {}
440 KOKKOS_INLINE_FUNCTION
441 void join(value_type& dest,
const value_type& src)
const {
442 if (src.val < dest.val) dest = src;
445 KOKKOS_INLINE_FUNCTION
446 void init(value_type& val)
const {
447 val.val = reduction_identity<scalar_type>::min();
448 val.loc = reduction_identity<index_type>::min();
451 KOKKOS_INLINE_FUNCTION
452 value_type& reference()
const {
return *value.data(); }
454 KOKKOS_INLINE_FUNCTION
455 result_view_type view()
const {
return value; }
457 KOKKOS_INLINE_FUNCTION
458 bool references_scalar()
const {
return references_scalar_v; }
461template <
typename Scalar,
typename Index,
typename... Properties>
462MinLoc(
View<ValLocScalar<Scalar, Index>, Properties...>
const&)
463 ->MinLoc<Scalar, Index,
465 Properties...>::memory_space>;
467template <
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>;
480 using result_view_type = Kokkos::View<value_type, Space>;
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; }
516template <
typename Scalar,
typename Index,
typename... Properties>
517MaxLoc(
View<ValLocScalar<Scalar, Index>, Properties...>
const&)
518 ->MaxLoc<Scalar, Index,
520 Properties...>::memory_space>;
522template <
class Scalar>
524 Scalar min_val, max_val;
527template <
class Scalar,
class Space>
530 using scalar_type = std::remove_cv_t<Scalar>;
531 static_assert(!std::is_pointer_v<scalar_type> &&
532 !std::is_array_v<scalar_type>);
536 using reducer = MinMax<Scalar, Space>;
537 using value_type = MinMaxScalar<scalar_type>;
539 using result_view_type = Kokkos::View<value_type, Space>;
542 result_view_type value;
543 bool references_scalar_v;
546 KOKKOS_INLINE_FUNCTION
547 MinMax(value_type& value_) : value(&value_), references_scalar_v(true) {}
549 KOKKOS_INLINE_FUNCTION
550 MinMax(
const result_view_type& value_)
551 : value(value_), references_scalar_v(false) {}
554 KOKKOS_INLINE_FUNCTION
555 void join(value_type& dest,
const value_type& src)
const {
556 if (src.min_val < dest.min_val) {
557 dest.min_val = src.min_val;
559 if (src.max_val > dest.max_val) {
560 dest.max_val = src.max_val;
564 KOKKOS_INLINE_FUNCTION
565 void init(value_type& val)
const {
566 val.max_val = reduction_identity<scalar_type>::max();
567 val.min_val = reduction_identity<scalar_type>::min();
570 KOKKOS_INLINE_FUNCTION
571 value_type& reference()
const {
return *value.data(); }
573 KOKKOS_INLINE_FUNCTION
574 result_view_type view()
const {
return value; }
576 KOKKOS_INLINE_FUNCTION
577 bool references_scalar()
const {
return references_scalar_v; }
580template <
typename Scalar,
typename... Properties>
581MinMax(
View<MinMaxScalar<Scalar>, Properties...>
const&)
585template <
class Scalar,
class Index>
586struct MinMaxLocScalar {
587 Scalar min_val, max_val;
588 Index min_loc, max_loc;
591template <
class Scalar,
class Index,
class Space>
594 using scalar_type = std::remove_cv_t<Scalar>;
595 using index_type = std::remove_cv_t<Index>;
596 static_assert(!std::is_pointer_v<scalar_type> &&
597 !std::is_array_v<scalar_type>);
601 using reducer = MinMaxLoc<Scalar, Index, Space>;
602 using value_type = MinMaxLocScalar<scalar_type, index_type>;
604 using result_view_type = Kokkos::View<value_type, Space>;
607 result_view_type value;
608 bool references_scalar_v;
611 KOKKOS_INLINE_FUNCTION
612 MinMaxLoc(value_type& value_) : value(&value_), references_scalar_v(true) {}
614 KOKKOS_INLINE_FUNCTION
615 MinMaxLoc(
const result_view_type& value_)
616 : value(value_), references_scalar_v(false) {}
619 KOKKOS_INLINE_FUNCTION
620 void join(value_type& dest,
const value_type& src)
const {
621 if (src.min_val < dest.min_val) {
622 dest.min_val = src.min_val;
623 dest.min_loc = src.min_loc;
625 if (src.max_val > dest.max_val) {
626 dest.max_val = src.max_val;
627 dest.max_loc = src.max_loc;
631 KOKKOS_INLINE_FUNCTION
632 void init(value_type& val)
const {
633 val.max_val = reduction_identity<scalar_type>::max();
634 val.min_val = reduction_identity<scalar_type>::min();
635 val.max_loc = reduction_identity<index_type>::min();
636 val.min_loc = reduction_identity<index_type>::min();
639 KOKKOS_INLINE_FUNCTION
640 value_type& reference()
const {
return *value.data(); }
642 KOKKOS_INLINE_FUNCTION
643 result_view_type view()
const {
return value; }
645 KOKKOS_INLINE_FUNCTION
646 bool references_scalar()
const {
return references_scalar_v; }
649template <
typename Scalar,
typename Index,
typename... Properties>
650MinMaxLoc(
View<MinMaxLocScalar<Scalar, Index>, Properties...>
const&)
651 ->MinMaxLoc<Scalar, Index,
653 Properties...>::memory_space>;
662template <
class Scalar,
class Index,
class Space>
665 using scalar_type = std::remove_cv_t<Scalar>;
666 using index_type = std::remove_cv_t<Index>;
667 static_assert(!std::is_pointer_v<scalar_type> &&
668 !std::is_array_v<scalar_type>);
669 static_assert(std::is_integral_v<index_type>);
673 using reducer = MaxFirstLoc<Scalar, Index, Space>;
674 using value_type = ::Kokkos::ValLocScalar<scalar_type, index_type>;
676 using result_view_type = ::Kokkos::View<value_type, Space>;
679 result_view_type value;
680 bool references_scalar_v;
683 KOKKOS_INLINE_FUNCTION
684 MaxFirstLoc(value_type& value_) : value(&value_), references_scalar_v(true) {}
686 KOKKOS_INLINE_FUNCTION
687 MaxFirstLoc(
const result_view_type& value_)
688 : value(value_), references_scalar_v(false) {}
691 KOKKOS_INLINE_FUNCTION
692 void join(value_type& dest,
const value_type& src)
const {
693 if (dest.val < src.val) {
695 }
else if (!(src.val < dest.val)) {
696 dest.loc = (src.loc < dest.loc) ? src.loc : dest.loc;
700 KOKKOS_INLINE_FUNCTION
701 void init(value_type& val)
const {
702 val.val = reduction_identity<scalar_type>::max();
703 val.loc = reduction_identity<index_type>::min();
706 KOKKOS_INLINE_FUNCTION
707 value_type& reference()
const {
return *value.data(); }
709 KOKKOS_INLINE_FUNCTION
710 result_view_type view()
const {
return value; }
712 KOKKOS_INLINE_FUNCTION
713 bool references_scalar()
const {
return references_scalar_v; }
716template <
typename Scalar,
typename Index,
typename... Properties>
717MaxFirstLoc(
View<ValLocScalar<Scalar, Index>, Properties...>
const&)
718 ->MaxFirstLoc<Scalar, Index,
720 Properties...>::memory_space>;
726template <
class Scalar,
class Index,
class ComparatorType,
class Space>
727struct MaxFirstLocCustomComparator {
729 using scalar_type = std::remove_cv_t<Scalar>;
730 using index_type = std::remove_cv_t<Index>;
731 static_assert(!std::is_pointer_v<scalar_type> &&
732 !std::is_array_v<scalar_type>);
733 static_assert(std::is_integral_v<index_type>);
738 MaxFirstLocCustomComparator<Scalar, Index, ComparatorType, Space>;
739 using value_type = ::Kokkos::ValLocScalar<scalar_type, index_type>;
741 using result_view_type = ::Kokkos::View<value_type, Space>;
744 result_view_type value;
745 bool references_scalar_v;
746 ComparatorType m_comp;
749 KOKKOS_INLINE_FUNCTION
750 MaxFirstLocCustomComparator(value_type& value_, ComparatorType comp_)
751 : value(&value_), references_scalar_v(true), m_comp(comp_) {}
753 KOKKOS_INLINE_FUNCTION
754 MaxFirstLocCustomComparator(
const result_view_type& value_,
755 ComparatorType comp_)
756 : value(value_), references_scalar_v(false), m_comp(comp_) {}
759 KOKKOS_INLINE_FUNCTION
760 void join(value_type& dest,
const value_type& src)
const {
761 if (m_comp(dest.val, src.val)) {
763 }
else if (!m_comp(src.val, dest.val)) {
764 dest.loc = (src.loc < dest.loc) ? src.loc : dest.loc;
768 KOKKOS_INLINE_FUNCTION
769 void init(value_type& val)
const {
770 val.val = reduction_identity<scalar_type>::max();
771 val.loc = reduction_identity<index_type>::min();
774 KOKKOS_INLINE_FUNCTION
775 value_type& reference()
const {
return *value.data(); }
777 KOKKOS_INLINE_FUNCTION
778 result_view_type view()
const {
return value; }
780 KOKKOS_INLINE_FUNCTION
781 bool references_scalar()
const {
return references_scalar_v; }
784template <
typename Scalar,
typename Index,
typename ComparatorType,
785 typename... Properties>
786MaxFirstLocCustomComparator(
787 View<ValLocScalar<Scalar, Index>, Properties...>
const&, ComparatorType)
788 ->MaxFirstLocCustomComparator<Scalar, Index, ComparatorType,
790 Properties...>::memory_space>;
795template <
class Scalar,
class Index,
class Space>
798 using scalar_type = std::remove_cv_t<Scalar>;
799 using index_type = std::remove_cv_t<Index>;
800 static_assert(!std::is_pointer_v<scalar_type> &&
801 !std::is_array_v<scalar_type>);
802 static_assert(std::is_integral_v<index_type>);
806 using reducer = MinFirstLoc<Scalar, Index, Space>;
807 using value_type = ::Kokkos::ValLocScalar<scalar_type, index_type>;
809 using result_view_type = ::Kokkos::View<value_type, Space>;
812 result_view_type value;
813 bool references_scalar_v;
816 KOKKOS_INLINE_FUNCTION
817 MinFirstLoc(value_type& value_) : value(&value_), references_scalar_v(true) {}
819 KOKKOS_INLINE_FUNCTION
820 MinFirstLoc(
const result_view_type& value_)
821 : value(value_), references_scalar_v(false) {}
824 KOKKOS_INLINE_FUNCTION
825 void join(value_type& dest,
const value_type& src)
const {
826 if (src.val < dest.val) {
828 }
else if (!(dest.val < src.val)) {
829 dest.loc = (src.loc < dest.loc) ? src.loc : dest.loc;
833 KOKKOS_INLINE_FUNCTION
834 void init(value_type& val)
const {
835 val.val = reduction_identity<scalar_type>::min();
836 val.loc = reduction_identity<index_type>::min();
839 KOKKOS_INLINE_FUNCTION
840 value_type& reference()
const {
return *value.data(); }
842 KOKKOS_INLINE_FUNCTION
843 result_view_type view()
const {
return value; }
845 KOKKOS_INLINE_FUNCTION
846 bool references_scalar()
const {
return references_scalar_v; }
849template <
typename Scalar,
typename Index,
typename... Properties>
850MinFirstLoc(
View<ValLocScalar<Scalar, Index>, Properties...>
const&)
851 ->MinFirstLoc<Scalar, Index,
853 Properties...>::memory_space>;
859template <
class Scalar,
class Index,
class ComparatorType,
class Space>
860struct MinFirstLocCustomComparator {
862 using scalar_type = std::remove_cv_t<Scalar>;
863 using index_type = std::remove_cv_t<Index>;
864 static_assert(!std::is_pointer_v<scalar_type> &&
865 !std::is_array_v<scalar_type>);
866 static_assert(std::is_integral_v<index_type>);
871 MinFirstLocCustomComparator<Scalar, Index, ComparatorType, Space>;
872 using value_type = ::Kokkos::ValLocScalar<scalar_type, index_type>;
874 using result_view_type = ::Kokkos::View<value_type, Space>;
877 result_view_type value;
878 bool references_scalar_v;
879 ComparatorType m_comp;
882 KOKKOS_INLINE_FUNCTION
883 MinFirstLocCustomComparator(value_type& value_, ComparatorType comp_)
884 : value(&value_), references_scalar_v(true), m_comp(comp_) {}
886 KOKKOS_INLINE_FUNCTION
887 MinFirstLocCustomComparator(
const result_view_type& value_,
888 ComparatorType comp_)
889 : value(value_), references_scalar_v(false), m_comp(comp_) {}
892 KOKKOS_INLINE_FUNCTION
893 void join(value_type& dest,
const value_type& src)
const {
894 if (m_comp(src.val, dest.val)) {
896 }
else if (!m_comp(dest.val, src.val)) {
897 dest.loc = (src.loc < dest.loc) ? src.loc : dest.loc;
901 KOKKOS_INLINE_FUNCTION
902 void init(value_type& val)
const {
903 val.val = reduction_identity<scalar_type>::min();
904 val.loc = reduction_identity<index_type>::min();
907 KOKKOS_INLINE_FUNCTION
908 value_type& reference()
const {
return *value.data(); }
910 KOKKOS_INLINE_FUNCTION
911 result_view_type view()
const {
return value; }
913 KOKKOS_INLINE_FUNCTION
914 bool references_scalar()
const {
return references_scalar_v; }
917template <
typename Scalar,
typename Index,
typename ComparatorType,
918 typename... Properties>
919MinFirstLocCustomComparator(
920 View<ValLocScalar<Scalar, Index>, Properties...>
const&, ComparatorType)
921 ->MinFirstLocCustomComparator<Scalar, Index, ComparatorType,
923 Properties...>::memory_space>;
928template <
class Scalar,
class Index,
class Space>
929struct MinMaxFirstLastLoc {
931 using scalar_type = std::remove_cv_t<Scalar>;
932 using index_type = std::remove_cv_t<Index>;
933 static_assert(!std::is_pointer_v<scalar_type> &&
934 !std::is_array_v<scalar_type>);
935 static_assert(std::is_integral_v<index_type>);
939 using reducer = MinMaxFirstLastLoc<Scalar, Index, Space>;
940 using value_type = ::Kokkos::MinMaxLocScalar<scalar_type, index_type>;
942 using result_view_type = ::Kokkos::View<value_type, Space>;
945 result_view_type value;
946 bool references_scalar_v;
949 KOKKOS_INLINE_FUNCTION
950 MinMaxFirstLastLoc(value_type& value_)
951 : value(&value_), references_scalar_v(true) {}
953 KOKKOS_INLINE_FUNCTION
954 MinMaxFirstLastLoc(
const result_view_type& value_)
955 : value(value_), references_scalar_v(false) {}
958 KOKKOS_INLINE_FUNCTION
959 void join(value_type& dest,
const value_type& src)
const {
960 if (src.min_val < dest.min_val) {
961 dest.min_val = src.min_val;
962 dest.min_loc = src.min_loc;
963 }
else if (!(dest.min_val < src.min_val)) {
964 dest.min_loc = (src.min_loc < dest.min_loc) ? src.min_loc : dest.min_loc;
967 if (dest.max_val < src.max_val) {
968 dest.max_val = src.max_val;
969 dest.max_loc = src.max_loc;
970 }
else if (!(src.max_val < dest.max_val)) {
971 dest.max_loc = (src.max_loc > dest.max_loc) ? src.max_loc : dest.max_loc;
975 KOKKOS_INLINE_FUNCTION
976 void init(value_type& val)
const {
977 val.max_val = ::Kokkos::reduction_identity<scalar_type>::max();
978 val.min_val = ::Kokkos::reduction_identity<scalar_type>::min();
979 val.max_loc = ::Kokkos::reduction_identity<index_type>::max();
980 val.min_loc = ::Kokkos::reduction_identity<index_type>::min();
983 KOKKOS_INLINE_FUNCTION
984 value_type& reference()
const {
return *value.data(); }
986 KOKKOS_INLINE_FUNCTION
987 result_view_type view()
const {
return value; }
989 KOKKOS_INLINE_FUNCTION
990 bool references_scalar()
const {
return references_scalar_v; }
993template <
typename Scalar,
typename Index,
typename... Properties>
994MinMaxFirstLastLoc(
View<MinMaxLocScalar<Scalar, Index>, Properties...>
const&)
995 ->MinMaxFirstLastLoc<Scalar, Index,
997 Properties...>::memory_space>;
1003template <
class Scalar,
class Index,
class ComparatorType,
class Space>
1004struct MinMaxFirstLastLocCustomComparator {
1006 using scalar_type = std::remove_cv_t<Scalar>;
1007 using index_type = std::remove_cv_t<Index>;
1008 static_assert(!std::is_pointer_v<scalar_type> &&
1009 !std::is_array_v<scalar_type>);
1010 static_assert(std::is_integral_v<index_type>);
1015 MinMaxFirstLastLocCustomComparator<Scalar, Index, ComparatorType, Space>;
1016 using value_type = ::Kokkos::MinMaxLocScalar<scalar_type, index_type>;
1018 using result_view_type = ::Kokkos::View<value_type, Space>;
1021 result_view_type value;
1022 bool references_scalar_v;
1023 ComparatorType m_comp;
1026 KOKKOS_INLINE_FUNCTION
1027 MinMaxFirstLastLocCustomComparator(value_type& value_, ComparatorType comp_)
1028 : value(&value_), references_scalar_v(true), m_comp(comp_) {}
1030 KOKKOS_INLINE_FUNCTION
1031 MinMaxFirstLastLocCustomComparator(
const result_view_type& value_,
1032 ComparatorType comp_)
1033 : value(value_), references_scalar_v(false), m_comp(comp_) {}
1036 KOKKOS_INLINE_FUNCTION
1037 void join(value_type& dest,
const value_type& src)
const {
1038 if (m_comp(src.min_val, dest.min_val)) {
1039 dest.min_val = src.min_val;
1040 dest.min_loc = src.min_loc;
1041 }
else if (!m_comp(dest.min_val, src.min_val)) {
1042 dest.min_loc = (src.min_loc < dest.min_loc) ? src.min_loc : dest.min_loc;
1045 if (m_comp(dest.max_val, src.max_val)) {
1046 dest.max_val = src.max_val;
1047 dest.max_loc = src.max_loc;
1048 }
else if (!m_comp(src.max_val, dest.max_val)) {
1049 dest.max_loc = (src.max_loc > dest.max_loc) ? src.max_loc : dest.max_loc;
1053 KOKKOS_INLINE_FUNCTION
1054 void init(value_type& val)
const {
1055 val.max_val = ::Kokkos::reduction_identity<scalar_type>::max();
1056 val.min_val = ::Kokkos::reduction_identity<scalar_type>::min();
1057 val.max_loc = ::Kokkos::reduction_identity<index_type>::max();
1058 val.min_loc = ::Kokkos::reduction_identity<index_type>::min();
1061 KOKKOS_INLINE_FUNCTION
1062 value_type& reference()
const {
return *value.data(); }
1064 KOKKOS_INLINE_FUNCTION
1065 result_view_type view()
const {
return value; }
1067 KOKKOS_INLINE_FUNCTION
1068 bool references_scalar()
const {
return references_scalar_v; }
1071template <
typename Scalar,
typename Index,
typename ComparatorType,
1072 typename... Properties>
1073MinMaxFirstLastLocCustomComparator(
1074 View<MinMaxLocScalar<Scalar, Index>, Properties...>
const&, ComparatorType)
1075 ->MinMaxFirstLastLocCustomComparator<
1076 Scalar, Index, ComparatorType,
1078 Properties...>::memory_space>;
1083template <
class Index>
1084struct FirstLocScalar {
1088template <
class Index,
class Space>
1091 using index_type = std::remove_cv_t<Index>;
1092 static_assert(std::is_integral_v<index_type>);
1096 using reducer = FirstLoc<Index, Space>;
1097 using value_type = FirstLocScalar<index_type>;
1099 using result_view_type = ::Kokkos::View<value_type, Space>;
1102 result_view_type value;
1103 bool references_scalar_v;
1106 KOKKOS_INLINE_FUNCTION
1107 FirstLoc(value_type& value_) : value(&value_), references_scalar_v(true) {}
1109 KOKKOS_INLINE_FUNCTION
1110 FirstLoc(
const result_view_type& value_)
1111 : value(value_), references_scalar_v(false) {}
1114 KOKKOS_INLINE_FUNCTION
1115 void join(value_type& dest,
const value_type& src)
const {
1116 dest.min_loc_true = (src.min_loc_true < dest.min_loc_true)
1118 : dest.min_loc_true;
1121 KOKKOS_INLINE_FUNCTION
1122 void init(value_type& val)
const {
1123 val.min_loc_true = ::Kokkos::reduction_identity<index_type>::min();
1126 KOKKOS_INLINE_FUNCTION
1127 value_type& reference()
const {
return *value.data(); }
1129 KOKKOS_INLINE_FUNCTION
1130 result_view_type view()
const {
return value; }
1132 KOKKOS_INLINE_FUNCTION
1133 bool references_scalar()
const {
return references_scalar_v; }
1136template <
typename Index,
typename... Properties>
1137FirstLoc(
View<FirstLocScalar<Index>, Properties...>
const&)
1139 Properties...>::memory_space>;
1144template <
class Index>
1145struct LastLocScalar {
1149template <
class Index,
class Space>
1152 using index_type = std::remove_cv_t<Index>;
1153 static_assert(std::is_integral_v<index_type>);
1157 using reducer = LastLoc<Index, Space>;
1158 using value_type = LastLocScalar<index_type>;
1160 using result_view_type = ::Kokkos::View<value_type, Space>;
1163 result_view_type value;
1164 bool references_scalar_v;
1167 KOKKOS_INLINE_FUNCTION
1168 LastLoc(value_type& value_) : value(&value_), references_scalar_v(true) {}
1170 KOKKOS_INLINE_FUNCTION
1171 LastLoc(
const result_view_type& value_)
1172 : value(value_), references_scalar_v(false) {}
1175 KOKKOS_INLINE_FUNCTION
1176 void join(value_type& dest,
const value_type& src)
const {
1177 dest.max_loc_true = (src.max_loc_true > dest.max_loc_true)
1179 : dest.max_loc_true;
1182 KOKKOS_INLINE_FUNCTION
1183 void init(value_type& val)
const {
1184 val.max_loc_true = ::Kokkos::reduction_identity<index_type>::max();
1187 KOKKOS_INLINE_FUNCTION
1188 value_type& reference()
const {
return *value.data(); }
1190 KOKKOS_INLINE_FUNCTION
1191 result_view_type view()
const {
return value; }
1193 KOKKOS_INLINE_FUNCTION
1194 bool references_scalar()
const {
return references_scalar_v; }
1197template <
typename Index,
typename... Properties>
1198LastLoc(
View<LastLocScalar<Index>, Properties...>
const&)
1202template <
class Index>
1203struct StdIsPartScalar {
1204 Index max_loc_true, min_loc_false;
1210template <
class Index,
class Space>
1211struct StdIsPartitioned {
1213 using index_type = std::remove_cv_t<Index>;
1214 static_assert(std::is_integral_v<index_type>);
1218 using reducer = StdIsPartitioned<Index, Space>;
1219 using value_type = StdIsPartScalar<index_type>;
1221 using result_view_type = ::Kokkos::View<value_type, Space>;
1224 result_view_type value;
1225 bool references_scalar_v;
1228 KOKKOS_INLINE_FUNCTION
1229 StdIsPartitioned(value_type& value_)
1230 : value(&value_), references_scalar_v(true) {}
1232 KOKKOS_INLINE_FUNCTION
1233 StdIsPartitioned(
const result_view_type& value_)
1234 : value(value_), references_scalar_v(false) {}
1237 KOKKOS_INLINE_FUNCTION
1238 void join(value_type& dest,
const value_type& src)
const {
1239 dest.max_loc_true = (dest.max_loc_true < src.max_loc_true)
1241 : dest.max_loc_true;
1243 dest.min_loc_false = (dest.min_loc_false < src.min_loc_false)
1244 ? dest.min_loc_false
1245 : src.min_loc_false;
1248 KOKKOS_INLINE_FUNCTION
1249 void init(value_type& val)
const {
1250 val.max_loc_true = ::Kokkos::reduction_identity<index_type>::max();
1251 val.min_loc_false = ::Kokkos::reduction_identity<index_type>::min();
1254 KOKKOS_INLINE_FUNCTION
1255 value_type& reference()
const {
return *value.data(); }
1257 KOKKOS_INLINE_FUNCTION
1258 result_view_type view()
const {
return value; }
1260 KOKKOS_INLINE_FUNCTION
1261 bool references_scalar()
const {
return references_scalar_v; }
1264template <
typename Index,
typename... Properties>
1265StdIsPartitioned(
View<StdIsPartScalar<Index>, Properties...>
const&)
1267 Properties...>::memory_space>;
1269template <
class Index>
1270struct StdPartPointScalar {
1271 Index min_loc_false;
1277template <
class Index,
class Space>
1278struct StdPartitionPoint {
1280 using index_type = std::remove_cv_t<Index>;
1281 static_assert(std::is_integral_v<index_type>);
1285 using reducer = StdPartitionPoint<Index, Space>;
1286 using value_type = StdPartPointScalar<index_type>;
1288 using result_view_type = ::Kokkos::View<value_type, Space>;
1291 result_view_type value;
1292 bool references_scalar_v;
1295 KOKKOS_INLINE_FUNCTION
1296 StdPartitionPoint(value_type& value_)
1297 : value(&value_), references_scalar_v(true) {}
1299 KOKKOS_INLINE_FUNCTION
1300 StdPartitionPoint(
const result_view_type& value_)
1301 : value(value_), references_scalar_v(false) {}
1304 KOKKOS_INLINE_FUNCTION
1305 void join(value_type& dest,
const value_type& src)
const {
1306 dest.min_loc_false = (dest.min_loc_false < src.min_loc_false)
1307 ? dest.min_loc_false
1308 : src.min_loc_false;
1311 KOKKOS_INLINE_FUNCTION
1312 void init(value_type& val)
const {
1313 val.min_loc_false = ::Kokkos::reduction_identity<index_type>::min();
1316 KOKKOS_INLINE_FUNCTION
1317 value_type& reference()
const {
return *value.data(); }
1319 KOKKOS_INLINE_FUNCTION
1320 result_view_type view()
const {
return value; }
1322 KOKKOS_INLINE_FUNCTION
1323 bool references_scalar()
const {
return references_scalar_v; }
1326template <
typename Index,
typename... Properties>
1327StdPartitionPoint(
View<StdPartPointScalar<Index>, Properties...>
const&)
1329 Properties...>::memory_space>;
1335template <
typename FunctorType,
typename FunctorAnalysisReducerType,
1337class CombinedFunctorReducer {
1339 using functor_type = FunctorType;
1340 using reducer_type = FunctorAnalysisReducerType;
1341 CombinedFunctorReducer(
const FunctorType& functor,
1342 const FunctorAnalysisReducerType& reducer)
1343 : m_functor(functor), m_reducer(reducer) {}
1344 KOKKOS_FUNCTION
const FunctorType& get_functor()
const {
return m_functor; }
1345 KOKKOS_FUNCTION
const FunctorAnalysisReducerType& get_reducer()
const {
1350 FunctorType m_functor;
1351 FunctorAnalysisReducerType m_reducer;
1353template <
typename FunctorType,
typename FunctorAnalysisReducerType>
1354class CombinedFunctorReducer<
1355 FunctorType, FunctorAnalysisReducerType,
1356 std::enable_if_t<std::is_same_v<
1357 FunctorType, typename FunctorAnalysisReducerType::functor_type>>> {
1359 using functor_type = FunctorType;
1360 using reducer_type = FunctorAnalysisReducerType;
1361 CombinedFunctorReducer(
const FunctorType& functor,
1362 const FunctorAnalysisReducerType&)
1363 : m_reducer(functor) {}
1364 KOKKOS_FUNCTION
const FunctorType& get_functor()
const {
1365 return m_reducer.get_functor();
1367 KOKKOS_FUNCTION
const FunctorAnalysisReducerType& get_reducer()
const {
1372 FunctorAnalysisReducerType m_reducer;
1375template <
class T,
class ReturnType,
class ValueTraits>
1376struct ParallelReduceReturnValue;
1378template <
class ReturnType,
class FunctorType>
1379struct ParallelReduceReturnValue<
1380 std::enable_if_t<Kokkos::is_view<ReturnType>::value>,
ReturnType,
1383 using reducer_type = InvalidType;
1385 using value_type_scalar =
typename return_type::value_type;
1386 using value_type_array =
typename return_type::value_type*
const;
1388 using value_type = std::conditional_t<return_type::rank == 0,
1389 value_type_scalar, value_type_array>;
1391 static return_type& return_value(ReturnType& return_val,
const FunctorType&) {
1396template <
class ReturnType,
class FunctorType>
1397struct ParallelReduceReturnValue<
1398 std::enable_if_t<!Kokkos::is_view<ReturnType>::value &&
1399 (!std::is_array<ReturnType>::value &&
1400 !std::is_pointer<ReturnType>::value) &&
1401 !Kokkos::is_reducer<ReturnType>::value>,
1404 Kokkos::View<ReturnType, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>;
1406 using reducer_type = InvalidType;
1408 using value_type =
typename return_type::value_type;
1410 static return_type return_value(ReturnType& return_val,
const FunctorType&) {
1411 return return_type(&return_val);
1415template <
class ReturnType,
class FunctorType>
1416struct ParallelReduceReturnValue<
1417 std::enable_if_t<(std::is_array<ReturnType>::value ||
1418 std::is_pointer<ReturnType>::value)>,
1420 using return_type = Kokkos::View<std::remove_const_t<ReturnType>,
1421 Kokkos::HostSpace, Kokkos::MemoryUnmanaged>;
1423 using reducer_type = InvalidType;
1425 using value_type =
typename return_type::value_type[];
1427 static return_type return_value(ReturnType& return_val,
1428 const FunctorType& functor) {
1429 if (std::is_array<ReturnType>::value)
1430 return return_type(return_val);
1432 return return_type(return_val, functor.value_count);
1436template <
class ReturnType,
class FunctorType>
1437struct ParallelReduceReturnValue<
1438 std::enable_if_t<Kokkos::is_reducer<ReturnType>::value>,
ReturnType,
1440 using return_type =
typename ReturnType::result_view_type;
1442 using value_type =
typename return_type::value_type;
1444 static auto return_value(ReturnType& return_val,
const FunctorType&) {
1445 return return_val.view();
1449template <
class T,
class ReturnType,
class FunctorType>
1450struct ParallelReducePolicyType;
1452template <
class PolicyType,
class FunctorType>
1453struct ParallelReducePolicyType<
1454 std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value>,
1455 PolicyType, FunctorType> {
1456 using policy_type = PolicyType;
1457 static PolicyType policy(
const PolicyType& policy_) {
return policy_; }
1460template <
class PolicyType,
class FunctorType>
1461struct ParallelReducePolicyType<
1462 std::enable_if_t<std::is_integral<PolicyType>::value>, PolicyType,
1464 using execution_space =
1465 typename Impl::FunctorPolicyExecutionSpace<FunctorType,
1466 void>::execution_space;
1468 using policy_type = Kokkos::RangePolicy<execution_space>;
1470 static policy_type policy(
const PolicyType& policy_) {
1471 return policy_type(0, policy_);
1475template <
class FunctorType,
class ExecPolicy,
class ValueType,
1476 class ExecutionSpace>
1477struct ParallelReduceFunctorType {
1478 using functor_type = FunctorType;
1479 static const functor_type& functor(
const functor_type& functor) {
1484template <
class PolicyType,
class FunctorType,
class ReturnType>
1485struct ParallelReduceAdaptor {
1486 using return_value_adapter =
1487 Impl::ParallelReduceReturnValue<void, ReturnType, FunctorType>;
1489 static inline void execute_impl(
const std::string& label,
1490 const PolicyType& policy,
1491 const FunctorType& functor,
1492 ReturnType& return_value) {
1493 using PassedReducerType =
typename return_value_adapter::reducer_type;
1496 PolicyType inner_policy = policy;
1497 Kokkos::Tools::Impl::begin_parallel_reduce<PassedReducerType>(
1498 inner_policy, functor, label, kpID);
1500 using ReducerSelector =
1501 Kokkos::Impl::if_c<std::is_same<InvalidType, PassedReducerType>::value,
1502 FunctorType, PassedReducerType>;
1503 using Analysis = FunctorAnalysis<FunctorPatternInterface::REDUCE,
1504 PolicyType,
typename ReducerSelector::type,
1505 typename return_value_adapter::value_type>;
1506 Kokkos::Impl::shared_allocation_tracking_disable();
1507 CombinedFunctorReducer functor_reducer(
1508 functor,
typename Analysis::Reducer(
1509 ReducerSelector::select(functor, return_value)));
1512 Impl::ParallelReduce<
decltype(functor_reducer), PolicyType,
1513 typename Impl::FunctorPolicyExecutionSpace<
1514 FunctorType, PolicyType>::execution_space>
1515 closure(functor_reducer, inner_policy,
1516 return_value_adapter::return_value(return_value, functor));
1517 Kokkos::Impl::shared_allocation_tracking_enable();
1520 Kokkos::Tools::Impl::end_parallel_reduce<PassedReducerType>(
1521 inner_policy, functor, label, kpID);
1524 static constexpr bool is_array_reduction =
1525 Impl::FunctorAnalysis<
1526 Impl::FunctorPatternInterface::REDUCE, PolicyType, FunctorType,
1527 typename return_value_adapter::value_type>::StaticValueSize == 0;
1529 template <
typename Dummy = ReturnType>
1530 static inline std::enable_if_t<!(is_array_reduction &&
1531 std::is_pointer<Dummy>::value)>
1532 execute(
const std::string& label,
const PolicyType& policy,
1533 const FunctorType& functor, ReturnType& return_value) {
1534 execute_impl(label, policy, functor, return_value);
1555template <
typename T>
1556struct ReducerHasTestReferenceFunction {
1557 template <
typename E>
1558 static std::true_type test_func(
decltype(&E::references_scalar));
1559 template <
typename E>
1560 static std::false_type test_func(...);
1563 value = std::is_same<std::true_type, decltype(test_func<T>(
nullptr))>::value
1567template <
class ExecutionSpace,
class Arg>
1568constexpr std::enable_if_t<
1570 !ReducerHasTestReferenceFunction<Arg>::value &&
1571 !Kokkos::is_view<Arg>::value,
1574parallel_reduce_needs_fence(ExecutionSpace
const&, Arg
const&) {
1578template <
class ExecutionSpace,
class Reducer>
1579constexpr std::enable_if_t<
1584 ReducerHasTestReferenceFunction<Reducer>::value,
1587parallel_reduce_needs_fence(ExecutionSpace
const&, Reducer
const& reducer) {
1588 return reducer.references_scalar();
1591template <
class ExecutionSpace,
class ViewLike>
1592constexpr std::enable_if_t<
1594 Kokkos::is_view<ViewLike>::value,
1597parallel_reduce_needs_fence(ExecutionSpace
const&, ViewLike
const&) {
1601template <
class ExecutionSpace,
class... Args>
1602struct ParallelReduceFence {
1603 template <
class... ArgsDeduced>
1604 static void fence(
const ExecutionSpace& ex,
const std::string& name,
1605 ArgsDeduced&&... args) {
1606 if (Impl::parallel_reduce_needs_fence(ex, (ArgsDeduced &&) args...)) {
1654template <
class PolicyType,
class FunctorType,
class ReturnType>
1655inline std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value &&
1656 !(Kokkos::is_view<ReturnType>::value ||
1657 Kokkos::is_reducer<ReturnType>::value ||
1658 std::is_pointer<ReturnType>::value)>
1659parallel_reduce(
const std::string& label,
const PolicyType& policy,
1660 const FunctorType& functor, ReturnType& return_value) {
1662 !std::is_const<ReturnType>::value,
1663 "A const reduction result type is only allowed for a View, pointer or "
1664 "reducer return type!");
1666 Impl::ParallelReduceAdaptor<PolicyType, FunctorType, ReturnType>::execute(
1667 label, policy, functor, return_value);
1668 Impl::ParallelReduceFence<typename PolicyType::execution_space, ReturnType>::
1671 "Kokkos::parallel_reduce: fence due to result being value, not view",
1675template <
class PolicyType,
class FunctorType,
class ReturnType>
1676inline 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<ReturnType>::value)>
1680parallel_reduce(
const PolicyType& policy,
const FunctorType& functor,
1681 ReturnType& return_value) {
1683 !std::is_const<ReturnType>::value,
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 "", policy, functor, return_value);
1689 Impl::ParallelReduceFence<typename PolicyType::execution_space, ReturnType>::
1692 "Kokkos::parallel_reduce: fence due to result being value, not view",
1696template <
class FunctorType,
class ReturnType>
1697inline std::enable_if_t<!(Kokkos::is_view<ReturnType>::value ||
1698 Kokkos::is_reducer<ReturnType>::value ||
1699 std::is_pointer<ReturnType>::value)>
1700parallel_reduce(
const size_t& policy,
const FunctorType& functor,
1701 ReturnType& return_value) {
1703 !std::is_const<ReturnType>::value,
1704 "A const reduction result type is only allowed for a View, pointer or "
1705 "reducer return type!");
1708 typename Impl::ParallelReducePolicyType<void, size_t,
1709 FunctorType>::policy_type;
1711 Impl::ParallelReduceAdaptor<policy_type, FunctorType, ReturnType>::execute(
1712 "", policy_type(0, policy), functor, return_value);
1713 Impl::ParallelReduceFence<typename policy_type::execution_space, ReturnType>::
1715 typename policy_type::execution_space(),
1716 "Kokkos::parallel_reduce: fence due to result being value, not view",
1720template <
class FunctorType,
class ReturnType>
1721inline std::enable_if_t<!(Kokkos::is_view<ReturnType>::value ||
1722 Kokkos::is_reducer<ReturnType>::value ||
1723 std::is_pointer<ReturnType>::value)>
1724parallel_reduce(
const std::string& label,
const size_t& policy,
1725 const FunctorType& functor, ReturnType& return_value) {
1727 !std::is_const<ReturnType>::value,
1728 "A const reduction result type is only allowed for a View, pointer or "
1729 "reducer return type!");
1732 typename Impl::ParallelReducePolicyType<void, size_t,
1733 FunctorType>::policy_type;
1734 Impl::ParallelReduceAdaptor<policy_type, FunctorType, ReturnType>::execute(
1735 label, policy_type(0, policy), functor, return_value);
1736 Impl::ParallelReduceFence<typename policy_type::execution_space, ReturnType>::
1738 typename policy_type::execution_space(),
1739 "Kokkos::parallel_reduce: fence due to result being value, not view",
1745template <
class PolicyType,
class FunctorType,
class ReturnType>
1746inline std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value &&
1747 (Kokkos::is_view<ReturnType>::value ||
1748 Kokkos::is_reducer<ReturnType>::value ||
1749 std::is_pointer<ReturnType>::value)>
1750parallel_reduce(
const std::string& label,
const PolicyType& policy,
1751 const FunctorType& functor,
const ReturnType& return_value) {
1753 Impl::ParallelReduceAdaptor<PolicyType, FunctorType, ReturnType>::execute(
1754 label, policy, functor, return_value_impl);
1755 Impl::ParallelReduceFence<typename PolicyType::execution_space, ReturnType>::
1758 "Kokkos::parallel_reduce: fence due to result being value, not view",
1762template <
class PolicyType,
class FunctorType,
class ReturnType>
1763inline std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value &&
1764 (Kokkos::is_view<ReturnType>::value ||
1765 Kokkos::is_reducer<ReturnType>::value ||
1766 std::is_pointer<ReturnType>::value)>
1767parallel_reduce(
const PolicyType& policy,
const FunctorType& functor,
1768 const ReturnType& return_value) {
1770 Impl::ParallelReduceAdaptor<PolicyType, FunctorType, ReturnType>::execute(
1771 "", policy, functor, return_value_impl);
1772 Impl::ParallelReduceFence<typename PolicyType::execution_space, ReturnType>::
1775 "Kokkos::parallel_reduce: fence due to result being value, not view",
1779template <
class FunctorType,
class ReturnType>
1780inline std::enable_if_t<Kokkos::is_view<ReturnType>::value ||
1781 Kokkos::is_reducer<ReturnType>::value ||
1782 std::is_pointer<ReturnType>::value>
1783parallel_reduce(
const size_t& policy,
const FunctorType& functor,
1784 const ReturnType& return_value) {
1786 typename Impl::ParallelReducePolicyType<void, size_t,
1787 FunctorType>::policy_type;
1789 Impl::ParallelReduceAdaptor<policy_type, FunctorType, ReturnType>::execute(
1790 "", policy_type(0, policy), functor, return_value_impl);
1791 Impl::ParallelReduceFence<typename policy_type::execution_space, ReturnType>::
1793 typename policy_type::execution_space(),
1794 "Kokkos::parallel_reduce: fence due to result being value, not view",
1798template <
class FunctorType,
class ReturnType>
1799inline std::enable_if_t<Kokkos::is_view<ReturnType>::value ||
1800 Kokkos::is_reducer<ReturnType>::value ||
1801 std::is_pointer<ReturnType>::value>
1802parallel_reduce(
const std::string& label,
const size_t& policy,
1803 const FunctorType& functor,
const ReturnType& return_value) {
1805 typename Impl::ParallelReducePolicyType<void, size_t,
1806 FunctorType>::policy_type;
1808 Impl::ParallelReduceAdaptor<policy_type, FunctorType, ReturnType>::execute(
1809 label, policy_type(0, policy), functor, return_value_impl);
1810 Impl::ParallelReduceFence<typename policy_type::execution_space, ReturnType>::
1812 typename policy_type::execution_space(),
1813 "Kokkos::parallel_reduce: fence due to result being value, not view",
1819template <
class PolicyType,
class FunctorType>
1820inline void parallel_reduce(
1821 const std::string& label,
const PolicyType& policy,
1822 const FunctorType& functor,
1823 std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value>* =
1825 using FunctorAnalysis =
1826 Impl::FunctorAnalysis<Impl::FunctorPatternInterface::REDUCE, PolicyType,
1828 using value_type = std::conditional_t<(FunctorAnalysis::StaticValueSize != 0),
1829 typename FunctorAnalysis::value_type,
1830 typename FunctorAnalysis::pointer_type>;
1833 FunctorAnalysis::has_final_member_function,
1834 "Calling parallel_reduce without either return value or final function.");
1836 using result_view_type =
1837 Kokkos::View<value_type, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>;
1838 result_view_type result_view;
1840 Impl::ParallelReduceAdaptor<PolicyType, FunctorType,
1841 result_view_type>::execute(label, policy, functor,
1845template <
class PolicyType,
class FunctorType>
1846inline void parallel_reduce(
1847 const PolicyType& policy,
const FunctorType& functor,
1848 std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value>* =
1850 using FunctorAnalysis =
1851 Impl::FunctorAnalysis<Impl::FunctorPatternInterface::REDUCE, PolicyType,
1853 using value_type = std::conditional_t<(FunctorAnalysis::StaticValueSize != 0),
1854 typename FunctorAnalysis::value_type,
1855 typename FunctorAnalysis::pointer_type>;
1858 FunctorAnalysis::has_final_member_function,
1859 "Calling parallel_reduce without either return value or final function.");
1861 using result_view_type =
1862 Kokkos::View<value_type, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>;
1863 result_view_type result_view;
1865 Impl::ParallelReduceAdaptor<PolicyType, FunctorType,
1866 result_view_type>::execute(
"", policy, functor,
1870template <
class FunctorType>
1871inline void parallel_reduce(
const size_t& policy,
const FunctorType& functor) {
1873 typename Impl::ParallelReducePolicyType<void, size_t,
1874 FunctorType>::policy_type;
1875 using FunctorAnalysis =
1876 Impl::FunctorAnalysis<Impl::FunctorPatternInterface::REDUCE, policy_type,
1878 using value_type = std::conditional_t<(FunctorAnalysis::StaticValueSize != 0),
1879 typename FunctorAnalysis::value_type,
1880 typename FunctorAnalysis::pointer_type>;
1883 FunctorAnalysis::has_final_member_function,
1884 "Calling parallel_reduce without either return value or final function.");
1886 using result_view_type =
1887 Kokkos::View<value_type, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>;
1888 result_view_type result_view;
1890 Impl::ParallelReduceAdaptor<policy_type, FunctorType,
1891 result_view_type>::execute(
"",
1892 policy_type(0, policy),
1893 functor, result_view);
1896template <
class FunctorType>
1897inline void parallel_reduce(
const std::string& label,
const size_t& policy,
1898 const FunctorType& functor) {
1900 typename Impl::ParallelReducePolicyType<void, size_t,
1901 FunctorType>::policy_type;
1902 using FunctorAnalysis =
1903 Impl::FunctorAnalysis<Impl::FunctorPatternInterface::REDUCE, policy_type,
1905 using value_type = std::conditional_t<(FunctorAnalysis::StaticValueSize != 0),
1906 typename FunctorAnalysis::value_type,
1907 typename FunctorAnalysis::pointer_type>;
1910 FunctorAnalysis::has_final_member_function,
1911 "Calling parallel_reduce without either return value or final function.");
1913 using result_view_type =
1914 Kokkos::View<value_type, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>;
1915 result_view_type result_view;
1917 Impl::ParallelReduceAdaptor<policy_type, FunctorType,
1918 result_view_type>::execute(label,
1919 policy_type(0, policy),
1920 functor, result_view);
View to an array of data.
ScopeGuard Some user scope issues have been identified with some Kokkos::finalize calls; ScopeGuard a...