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 PolicyType, 
class FunctorType, 
class ReturnType>
 
 1496 struct ParallelReduceAdaptor {
 
 1497   using return_value_adapter =
 
 1498       Impl::ParallelReduceReturnValue<void, ReturnType, FunctorType>;
 
 1501   template <
bool B, 
class T1, 
class T2>
 
 1502   static KOKKOS_FUNCTION std::conditional_t<B, T1&&, T2&&> forwarding_switch(
 
 1505       return static_cast<T1&&>(v1);
 
 1507       return static_cast<T2&&>(v2);
 
 1510   static inline 
void execute_impl(const std::
string& label,
 
 1511                                   const PolicyType& policy,
 
 1512                                   const FunctorType& functor,
 
 1514     using PassedReducerType = 
typename return_value_adapter::reducer_type;
 
 1517     constexpr 
bool passed_reducer_type_is_invalid =
 
 1518         std::is_same_v<InvalidType, PassedReducerType>;
 
 1519     using TheReducerType = std::conditional_t<passed_reducer_type_is_invalid,
 
 1520                                               FunctorType, PassedReducerType>;
 
 1522     using Analysis = FunctorAnalysis<FunctorPatternInterface::REDUCE,
 
 1523                                      PolicyType, TheReducerType,
 
 1524                                      typename return_value_adapter::value_type>;
 
 1525     using CombinedFunctorReducerType =
 
 1526         CombinedFunctorReducer<FunctorType, typename Analysis::Reducer>;
 
 1528     CombinedFunctorReducerType functor_reducer(
 
 1529         functor, 
typename Analysis::Reducer(
 
 1530                      forwarding_switch<passed_reducer_type_is_invalid>(
 
 1531                          functor, return_value)));
 
 1532     const auto& response = Kokkos::Tools::Impl::begin_parallel_reduce<
 
 1533         typename return_value_adapter::reducer_type>(policy, functor_reducer,
 
 1535     const auto& inner_policy = response.policy;
 
 1537     auto closure = construct_with_shared_allocation_tracking_disabled<
 
 1538         Impl::ParallelReduce<CombinedFunctorReducerType, PolicyType,
 
 1539                              typename Impl::FunctorPolicyExecutionSpace<
 
 1540                                  FunctorType, PolicyType>::execution_space>>(
 
 1541         functor_reducer, inner_policy,
 
 1542         return_value_adapter::return_value(return_value, functor));
 
 1545     Kokkos::Tools::Impl::end_parallel_reduce<PassedReducerType>(
 
 1546         inner_policy, functor, label, kpID);
 
 1549   static constexpr 
bool is_array_reduction =
 
 1550       Impl::FunctorAnalysis<
 
 1551           Impl::FunctorPatternInterface::REDUCE, PolicyType, FunctorType,
 
 1552           typename return_value_adapter::value_type>::StaticValueSize == 0;
 
 1554   template <
typename Dummy = ReturnType>
 
 1555   static inline std::enable_if_t<!(is_array_reduction &&
 
 1556                                    std::is_pointer_v<Dummy>)>
 
 1557   execute(
const std::string& label, 
const PolicyType& policy,
 
 1558           const FunctorType& functor, 
ReturnType& return_value) {
 
 1559     execute_impl(label, policy, functor, return_value);
 
 1580 template <
typename T>
 
 1581 struct ReducerHasTestReferenceFunction {
 
 1582   template <
typename E>
 
 1583   static std::true_type test_func(decltype(&E::references_scalar));
 
 1584   template <
typename E>
 
 1585   static std::false_type test_func(...);
 
 1588     value = std::is_same_v<std::true_type, decltype(test_func<T>(
nullptr))>
 
 1592 template <
class ExecutionSpace, 
class Arg>
 
 1593 constexpr std::enable_if_t<
 
 1595     !ReducerHasTestReferenceFunction<Arg>::value &&
 
 1596         !Kokkos::is_view<Arg>::value,
 
 1599 parallel_reduce_needs_fence(ExecutionSpace 
const&, Arg 
const&) {
 
 1603 template <
class ExecutionSpace, 
class Reducer>
 
 1604 constexpr std::enable_if_t<
 
 1609     ReducerHasTestReferenceFunction<Reducer>::value,
 
 1612 parallel_reduce_needs_fence(ExecutionSpace 
const&, Reducer 
const& reducer) {
 
 1613   return reducer.references_scalar();
 
 1616 template <
class ExecutionSpace, 
class ViewLike>
 
 1617 constexpr std::enable_if_t<
 
 1619     Kokkos::is_view<ViewLike>::value,
 
 1622 parallel_reduce_needs_fence(ExecutionSpace 
const&, ViewLike 
const&) {
 
 1626 template <
class ExecutionSpace, 
class... Args>
 
 1627 struct ParallelReduceFence {
 
 1628   template <
class... ArgsDeduced>
 
 1629   static void fence(
const ExecutionSpace& ex, 
const std::string& name,
 
 1630                     ArgsDeduced&&... args) {
 
 1631     if (Impl::parallel_reduce_needs_fence(ex, (ArgsDeduced&&)args...)) {
 
 1679 template <
class PolicyType, 
class FunctorType, 
class ReturnType>
 
 1680 inline std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value &&
 
 1681                         !(Kokkos::is_view<ReturnType>::value ||
 
 1682                           Kokkos::is_reducer<ReturnType>::value ||
 
 1683                           std::is_pointer_v<ReturnType>)>
 
 1684 parallel_reduce(
const std::string& label, 
const PolicyType& policy,
 
 1685                 const FunctorType& functor, 
ReturnType& return_value) {
 
 1687       !std::is_const_v<ReturnType>,
 
 1688       "A const reduction result type is only allowed for a View, pointer or " 
 1689       "reducer return type!");
 
 1691   Impl::ParallelReduceAdaptor<PolicyType, FunctorType, ReturnType>::execute(
 
 1692       label, policy, functor, return_value);
 
 1693   Impl::ParallelReduceFence<typename PolicyType::execution_space, ReturnType>::
 
 1696           "Kokkos::parallel_reduce: fence due to result being value, not view",
 
 1700 template <
class PolicyType, 
class FunctorType, 
class ReturnType>
 
 1701 inline std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value &&
 
 1702                         !(Kokkos::is_view<ReturnType>::value ||
 
 1703                           Kokkos::is_reducer<ReturnType>::value ||
 
 1704                           std::is_pointer_v<ReturnType>)>
 
 1705 parallel_reduce(
const PolicyType& policy, 
const FunctorType& functor,
 
 1707   parallel_reduce(
"", policy, functor, return_value);
 
 1710 template <
class FunctorType, 
class ReturnType>
 
 1711 inline std::enable_if_t<!(Kokkos::is_view<ReturnType>::value ||
 
 1712                           Kokkos::is_reducer<ReturnType>::value ||
 
 1713                           std::is_pointer_v<ReturnType>)>
 
 1714 parallel_reduce(
const std::string& label, 
const size_t& work_count,
 
 1715                 const FunctorType& functor, 
ReturnType& return_value) {
 
 1717       typename Impl::ParallelReducePolicyType<void, size_t,
 
 1718                                               FunctorType>::policy_type;
 
 1720   parallel_reduce(label, policy_type(0, work_count), functor, return_value);
 
 1723 template <
class FunctorType, 
class ReturnType>
 
 1724 inline std::enable_if_t<!(Kokkos::is_view<ReturnType>::value ||
 
 1725                           Kokkos::is_reducer<ReturnType>::value ||
 
 1726                           std::is_pointer_v<ReturnType>)>
 
 1727 parallel_reduce(
const size_t& work_count, 
const FunctorType& functor,
 
 1729   parallel_reduce(
"", work_count, functor, return_value);
 
 1734 template <
class PolicyType, 
class FunctorType, 
class ReturnType>
 
 1735 inline std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value &&
 
 1736                         (Kokkos::is_view<ReturnType>::value ||
 
 1737                          Kokkos::is_reducer<ReturnType>::value ||
 
 1738                          std::is_pointer_v<ReturnType>)>
 
 1739 parallel_reduce(
const std::string& label, 
const PolicyType& policy,
 
 1740                 const FunctorType& functor, 
const ReturnType& return_value) {
 
 1742   Impl::ParallelReduceAdaptor<PolicyType, FunctorType, ReturnType>::execute(
 
 1743       label, policy, functor, return_value_impl);
 
 1744   Impl::ParallelReduceFence<typename PolicyType::execution_space, ReturnType>::
 
 1747           "Kokkos::parallel_reduce: fence due to result being value, not view",
 
 1751 template <
class PolicyType, 
class FunctorType, 
class ReturnType>
 
 1752 inline std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value &&
 
 1753                         (Kokkos::is_view<ReturnType>::value ||
 
 1754                          Kokkos::is_reducer<ReturnType>::value ||
 
 1755                          std::is_pointer_v<ReturnType>)>
 
 1756 parallel_reduce(
const PolicyType& policy, 
const FunctorType& functor,
 
 1758   parallel_reduce(
"", policy, functor, return_value);
 
 1761 template <
class FunctorType, 
class ReturnType>
 
 1762 inline std::enable_if_t<Kokkos::is_view<ReturnType>::value ||
 
 1763                         Kokkos::is_reducer<ReturnType>::value ||
 
 1764                         std::is_pointer_v<ReturnType>>
 
 1765 parallel_reduce(
const std::string& label, 
const size_t& work_count,
 
 1766                 const FunctorType& functor, 
const ReturnType& return_value) {
 
 1768       typename Impl::ParallelReducePolicyType<void, size_t,
 
 1769                                               FunctorType>::policy_type;
 
 1771   parallel_reduce(label, policy_type(0, work_count), functor, return_value);
 
 1774 template <
class FunctorType, 
class ReturnType>
 
 1775 inline std::enable_if_t<Kokkos::is_view<ReturnType>::value ||
 
 1776                         Kokkos::is_reducer<ReturnType>::value ||
 
 1777                         std::is_pointer_v<ReturnType>>
 
 1778 parallel_reduce(
const size_t& work_count, 
const FunctorType& functor,
 
 1780   parallel_reduce(
"", work_count, functor, return_value);
 
 1785 template <
class PolicyType, 
class FunctorType>
 
 1786 inline void parallel_reduce(
 
 1787     const std::string& label, 
const PolicyType& policy,
 
 1788     const FunctorType& functor,
 
 1789     std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value>* =
 
 1791   using FunctorAnalysis =
 
 1792       Impl::FunctorAnalysis<Impl::FunctorPatternInterface::REDUCE, PolicyType,
 
 1794   using value_type = std::conditional_t<(FunctorAnalysis::StaticValueSize != 0),
 
 1795                                         typename FunctorAnalysis::value_type,
 
 1796                                         typename FunctorAnalysis::pointer_type>;
 
 1799       FunctorAnalysis::has_final_member_function,
 
 1800       "Calling parallel_reduce without either return value or final function.");
 
 1802   using result_view_type =
 
 1803       Kokkos::View<value_type, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>;
 
 1804   result_view_type result_view;
 
 1806   Impl::ParallelReduceAdaptor<PolicyType, FunctorType,
 
 1807                               result_view_type>::execute(label, policy, functor,
 
 1811 template <
class PolicyType, 
class FunctorType>
 
 1812 inline void parallel_reduce(
 
 1813     const PolicyType& policy, 
const FunctorType& functor,
 
 1814     std::enable_if_t<Kokkos::is_execution_policy<PolicyType>::value>* =
 
 1816   parallel_reduce(
"", policy, functor);
 
 1819 template <
class FunctorType>
 
 1820 inline void parallel_reduce(
const std::string& label, 
const size_t& work_count,
 
 1821                             const FunctorType& functor) {
 
 1823       typename Impl::ParallelReducePolicyType<void, size_t,
 
 1824                                               FunctorType>::policy_type;
 
 1826   parallel_reduce(label, policy_type(0, work_count), functor);
 
 1829 template <
class FunctorType>
 
 1830 inline void parallel_reduce(
const size_t& work_count,
 
 1831                             const FunctorType& functor) {
 
 1832   parallel_reduce(
"", work_count, functor);
 
 1837 #endif  // KOKKOS_PARALLEL_REDUCE_HPP 
Memory management for host memory. 
 
Execution policy for work over a range of an integral type.