23 #ifndef KOKKOS_SCATTER_VIEW_HPP 
   24 #define KOKKOS_SCATTER_VIEW_HPP 
   25 #ifndef KOKKOS_IMPL_PUBLIC_INCLUDE 
   26 #define KOKKOS_IMPL_PUBLIC_INCLUDE 
   27 #define KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_SCATTERVIEW 
   30 #include <Kokkos_Core.hpp> 
   34 namespace Experimental {
 
   42 struct ScatterProd {};
 
   46 struct ScatterNonDuplicated {};
 
   47 struct ScatterDuplicated {};
 
   49 struct ScatterNonAtomic {};
 
   50 struct ScatterAtomic {};
 
   57 namespace Experimental {
 
   59 template <
typename ExecSpace>
 
   60 struct DefaultDuplication;
 
   62 template <
typename ExecSpace, 
typename Duplication>
 
   63 struct DefaultContribution;
 
   65 #ifdef KOKKOS_ENABLE_SERIAL 
   67 struct DefaultDuplication<Kokkos::Serial> {
 
   68   using type = Kokkos::Experimental::ScatterNonDuplicated;
 
   72 struct DefaultContribution<Kokkos::Serial,
 
   73                            Kokkos::Experimental::ScatterNonDuplicated> {
 
   74   using type = Kokkos::Experimental::ScatterNonAtomic;
 
   77 struct DefaultContribution<Kokkos::Serial,
 
   78                            Kokkos::Experimental::ScatterDuplicated> {
 
   79   using type = Kokkos::Experimental::ScatterNonAtomic;
 
   83 #ifdef KOKKOS_ENABLE_OPENMP 
   85 struct DefaultDuplication<Kokkos::OpenMP> {
 
   86   using type = Kokkos::Experimental::ScatterDuplicated;
 
   89 struct DefaultContribution<Kokkos::OpenMP,
 
   90                            Kokkos::Experimental::ScatterNonDuplicated> {
 
   91   using type = Kokkos::Experimental::ScatterAtomic;
 
   94 struct DefaultContribution<Kokkos::OpenMP,
 
   95                            Kokkos::Experimental::ScatterDuplicated> {
 
   96   using type = Kokkos::Experimental::ScatterNonAtomic;
 
  100 #ifdef KOKKOS_ENABLE_OPENMPTARGET 
  102 struct DefaultDuplication<Kokkos::Experimental::OpenMPTarget> {
 
  103   using type = Kokkos::Experimental::ScatterNonDuplicated;
 
  106 struct DefaultContribution<Kokkos::Experimental::OpenMPTarget,
 
  107                            Kokkos::Experimental::ScatterNonDuplicated> {
 
  108   using type = Kokkos::Experimental::ScatterAtomic;
 
  111 struct DefaultContribution<Kokkos::Experimental::OpenMPTarget,
 
  112                            Kokkos::Experimental::ScatterDuplicated> {
 
  113   using type = Kokkos::Experimental::ScatterNonAtomic;
 
  117 #ifdef KOKKOS_ENABLE_HPX 
  119 struct DefaultDuplication<Kokkos::Experimental::HPX> {
 
  120   using type = Kokkos::Experimental::ScatterDuplicated;
 
  123 struct DefaultContribution<Kokkos::Experimental::HPX,
 
  124                            Kokkos::Experimental::ScatterNonDuplicated> {
 
  125   using type = Kokkos::Experimental::ScatterAtomic;
 
  128 struct DefaultContribution<Kokkos::Experimental::HPX,
 
  129                            Kokkos::Experimental::ScatterDuplicated> {
 
  130   using type = Kokkos::Experimental::ScatterNonAtomic;
 
  134 #ifdef KOKKOS_ENABLE_THREADS 
  136 struct DefaultDuplication<Kokkos::Threads> {
 
  137   using type = Kokkos::Experimental::ScatterDuplicated;
 
  140 struct DefaultContribution<Kokkos::Threads,
 
  141                            Kokkos::Experimental::ScatterNonDuplicated> {
 
  142   using type = Kokkos::Experimental::ScatterAtomic;
 
  145 struct DefaultContribution<Kokkos::Threads,
 
  146                            Kokkos::Experimental::ScatterDuplicated> {
 
  147   using type = Kokkos::Experimental::ScatterNonAtomic;
 
  151 #ifdef KOKKOS_ENABLE_CUDA 
  153 struct DefaultDuplication<Kokkos::Cuda> {
 
  154   using type = Kokkos::Experimental::ScatterNonDuplicated;
 
  157 struct DefaultContribution<Kokkos::Cuda,
 
  158                            Kokkos::Experimental::ScatterNonDuplicated> {
 
  159   using type = Kokkos::Experimental::ScatterAtomic;
 
  162 struct DefaultContribution<Kokkos::Cuda,
 
  163                            Kokkos::Experimental::ScatterDuplicated> {
 
  164   using type = Kokkos::Experimental::ScatterAtomic;
 
  168 #ifdef KOKKOS_ENABLE_HIP 
  170 struct DefaultDuplication<Kokkos::HIP> {
 
  171   using type = Kokkos::Experimental::ScatterNonDuplicated;
 
  174 struct DefaultContribution<Kokkos::HIP,
 
  175                            Kokkos::Experimental::ScatterNonDuplicated> {
 
  176   using type = Kokkos::Experimental::ScatterAtomic;
 
  179 struct DefaultContribution<Kokkos::HIP,
 
  180                            Kokkos::Experimental::ScatterDuplicated> {
 
  181   using type = Kokkos::Experimental::ScatterAtomic;
 
  185 #ifdef KOKKOS_ENABLE_SYCL 
  187 struct DefaultDuplication<Kokkos::SYCL> {
 
  188   using type = Kokkos::Experimental::ScatterNonDuplicated;
 
  191 struct DefaultContribution<Kokkos::SYCL,
 
  192                            Kokkos::Experimental::ScatterNonDuplicated> {
 
  193   using type = Kokkos::Experimental::ScatterAtomic;
 
  196 struct DefaultContribution<Kokkos::SYCL,
 
  197                            Kokkos::Experimental::ScatterDuplicated> {
 
  198   using type = Kokkos::Experimental::ScatterAtomic;
 
  207 template <
typename ValueType, 
typename Op, 
typename DeviceType,
 
  208           typename Contribution>
 
  217 template <
typename ValueType, 
typename DeviceType>
 
  218 struct ScatterValue<ValueType, Kokkos::Experimental::ScatterSum, DeviceType,
 
  219                     Kokkos::Experimental::ScatterNonAtomic> {
 
  223   KOKKOS_FORCEINLINE_FUNCTION ScatterValue(ValueType& value_in)
 
  225   KOKKOS_FORCEINLINE_FUNCTION ScatterValue(ScatterValue&& other)
 
  226       : value(other.value) {}
 
  227   KOKKOS_FORCEINLINE_FUNCTION 
void operator+=(ValueType 
const& rhs) {
 
  230   KOKKOS_FORCEINLINE_FUNCTION 
void operator++() { update(1); }
 
  231   KOKKOS_FORCEINLINE_FUNCTION 
void operator++(
int) { update(1); }
 
  232   KOKKOS_FORCEINLINE_FUNCTION 
void operator-=(ValueType 
const& rhs) {
 
  233     update(ValueType(-rhs));
 
  235   KOKKOS_FORCEINLINE_FUNCTION 
void operator--() { update(ValueType(-1)); }
 
  236   KOKKOS_FORCEINLINE_FUNCTION 
void operator--(
int) { update(ValueType(-1)); }
 
  237   KOKKOS_FORCEINLINE_FUNCTION 
void update(ValueType 
const& rhs) {
 
  240   KOKKOS_FORCEINLINE_FUNCTION 
void reset() {
 
  241     value = reduction_identity<ValueType>::sum();
 
  250 template <
typename ValueType, 
typename DeviceType>
 
  251 struct ScatterValue<ValueType, Kokkos::Experimental::ScatterSum, DeviceType,
 
  252                     Kokkos::Experimental::ScatterAtomic> {
 
  256   KOKKOS_FORCEINLINE_FUNCTION ScatterValue(ValueType& value_in)
 
  259   KOKKOS_FORCEINLINE_FUNCTION 
void operator+=(ValueType 
const& rhs) {
 
  260     this->join(value, rhs);
 
  262   KOKKOS_FORCEINLINE_FUNCTION 
void operator++() { this->join(value, 1); }
 
  263   KOKKOS_FORCEINLINE_FUNCTION 
void operator++(
int) { this->join(value, 1); }
 
  264   KOKKOS_FORCEINLINE_FUNCTION 
void operator-=(ValueType 
const& rhs) {
 
  265     this->join(value, ValueType(-rhs));
 
  267   KOKKOS_FORCEINLINE_FUNCTION 
void operator--() {
 
  268     this->join(value, ValueType(-1));
 
  270   KOKKOS_FORCEINLINE_FUNCTION 
void operator--(
int) {
 
  271     this->join(value, ValueType(-1));
 
  274   KOKKOS_INLINE_FUNCTION
 
  275   void join(ValueType& dest, 
const ValueType& src)
 const {
 
  276     Kokkos::atomic_add(&dest, src);
 
  279   KOKKOS_FORCEINLINE_FUNCTION 
void update(ValueType 
const& rhs) {
 
  280     this->join(value, rhs);
 
  283   KOKKOS_FORCEINLINE_FUNCTION 
void reset() {
 
  284     value = reduction_identity<ValueType>::sum();
 
  294 template <
typename ValueType, 
typename DeviceType>
 
  295 struct ScatterValue<ValueType, Kokkos::Experimental::ScatterProd, DeviceType,
 
  296                     Kokkos::Experimental::ScatterNonAtomic> {
 
  300   KOKKOS_FORCEINLINE_FUNCTION ScatterValue(ValueType& value_in)
 
  302   KOKKOS_FORCEINLINE_FUNCTION ScatterValue(ScatterValue&& other)
 
  303       : value(other.value) {}
 
  304   KOKKOS_FORCEINLINE_FUNCTION 
void operator*=(ValueType 
const& rhs) {
 
  307   KOKKOS_FORCEINLINE_FUNCTION 
void operator/=(ValueType 
const& rhs) {
 
  311   KOKKOS_FORCEINLINE_FUNCTION 
void update(ValueType 
const& rhs) {
 
  314   KOKKOS_FORCEINLINE_FUNCTION 
void reset() {
 
  315     value = reduction_identity<ValueType>::prod();
 
  325 template <
typename ValueType, 
typename DeviceType>
 
  326 struct ScatterValue<ValueType, Kokkos::Experimental::ScatterProd, DeviceType,
 
  327                     Kokkos::Experimental::ScatterAtomic> {
 
  331   KOKKOS_FORCEINLINE_FUNCTION ScatterValue(ValueType& value_in)
 
  333   KOKKOS_FORCEINLINE_FUNCTION ScatterValue(ScatterValue&& other)
 
  334       : value(other.value) {}
 
  336   KOKKOS_FORCEINLINE_FUNCTION 
void operator*=(ValueType 
const& rhs) {
 
  337     Kokkos::atomic_mul(&value, rhs);
 
  339   KOKKOS_FORCEINLINE_FUNCTION 
void operator/=(ValueType 
const& rhs) {
 
  340     Kokkos::atomic_div(&value, rhs);
 
  343   KOKKOS_INLINE_FUNCTION
 
  344   void join(ValueType& dest, 
const ValueType& src)
 const {
 
  345     atomic_prod(&dest, src);
 
  348   KOKKOS_FORCEINLINE_FUNCTION 
void update(ValueType 
const& rhs) {
 
  349     atomic_prod(&value, rhs);
 
  351   KOKKOS_FORCEINLINE_FUNCTION 
void reset() {
 
  352     value = reduction_identity<ValueType>::prod();
 
  362 template <
typename ValueType, 
typename DeviceType>
 
  363 struct ScatterValue<ValueType, Kokkos::Experimental::ScatterMin, DeviceType,
 
  364                     Kokkos::Experimental::ScatterNonAtomic> {
 
  366   KOKKOS_FORCEINLINE_FUNCTION ScatterValue(ValueType& value_in)
 
  368   KOKKOS_FORCEINLINE_FUNCTION ScatterValue(ScatterValue&& other)
 
  369       : value(other.value) {}
 
  372   KOKKOS_FORCEINLINE_FUNCTION 
void update(ValueType 
const& rhs) {
 
  373     value = rhs < value ? rhs : value;
 
  375   KOKKOS_FORCEINLINE_FUNCTION 
void reset() {
 
  376     value = reduction_identity<ValueType>::min();
 
  386 template <
typename ValueType, 
typename DeviceType>
 
  387 struct ScatterValue<ValueType, Kokkos::Experimental::ScatterMin, DeviceType,
 
  388                     Kokkos::Experimental::ScatterAtomic> {
 
  392   KOKKOS_FORCEINLINE_FUNCTION ScatterValue(ValueType& value_in)
 
  394   KOKKOS_FORCEINLINE_FUNCTION ScatterValue(ScatterValue&& other)
 
  395       : value(other.value) {}
 
  397   KOKKOS_INLINE_FUNCTION
 
  398   void join(ValueType& dest, 
const ValueType& src)
 const {
 
  399     atomic_min(&dest, src);
 
  402   KOKKOS_FORCEINLINE_FUNCTION 
void update(ValueType 
const& rhs) {
 
  403     this->join(value, rhs);
 
  405   KOKKOS_FORCEINLINE_FUNCTION 
void reset() {
 
  406     value = reduction_identity<ValueType>::min();
 
  416 template <
typename ValueType, 
typename DeviceType>
 
  417 struct ScatterValue<ValueType, Kokkos::Experimental::ScatterMax, DeviceType,
 
  418                     Kokkos::Experimental::ScatterNonAtomic> {
 
  422   KOKKOS_FORCEINLINE_FUNCTION ScatterValue(ValueType& value_in)
 
  424   KOKKOS_FORCEINLINE_FUNCTION ScatterValue(ScatterValue&& other)
 
  425       : value(other.value) {}
 
  426   KOKKOS_FORCEINLINE_FUNCTION 
void update(ValueType 
const& rhs) {
 
  427     value = rhs > value ? rhs : value;
 
  429   KOKKOS_FORCEINLINE_FUNCTION 
void reset() {
 
  430     value = reduction_identity<ValueType>::max();
 
  440 template <
typename ValueType, 
typename DeviceType>
 
  441 struct ScatterValue<ValueType, Kokkos::Experimental::ScatterMax, DeviceType,
 
  442                     Kokkos::Experimental::ScatterAtomic> {
 
  446   KOKKOS_FORCEINLINE_FUNCTION ScatterValue(ValueType& value_in)
 
  448   KOKKOS_FORCEINLINE_FUNCTION ScatterValue(ScatterValue&& other)
 
  449       : value(other.value) {}
 
  451   KOKKOS_INLINE_FUNCTION
 
  452   void join(ValueType& dest, 
const ValueType& src)
 const {
 
  453     atomic_max(&dest, src);
 
  456   KOKKOS_FORCEINLINE_FUNCTION 
void update(ValueType 
const& rhs) {
 
  457     this->join(value, rhs);
 
  459   KOKKOS_FORCEINLINE_FUNCTION 
void reset() {
 
  460     value = reduction_identity<ValueType>::max();
 
  469 template <
typename T, 
typename Layout>
 
  470 struct DuplicatedDataType;
 
  472 template <
typename T>
 
  473 struct DuplicatedDataType<T, Kokkos::LayoutRight> {
 
  474   using value_type = T*;  
 
  477 template <
typename T, 
size_t N>
 
  478 struct DuplicatedDataType<T[N], Kokkos::LayoutRight> {
 
  480       typename DuplicatedDataType<T, Kokkos::LayoutRight>::value_type[N];
 
  483 template <
typename T>
 
  484 struct DuplicatedDataType<T[], Kokkos::LayoutRight> {
 
  486       typename DuplicatedDataType<T, Kokkos::LayoutRight>::value_type[];
 
  489 template <
typename T>
 
  492       typename DuplicatedDataType<T, Kokkos::LayoutRight>::value_type*;
 
  495 template <
typename T>
 
  496 struct DuplicatedDataType<T, Kokkos::LayoutLeft> {
 
  497   using value_type = T*;
 
  500 template <
typename T, 
size_t N>
 
  501 struct DuplicatedDataType<T[N], Kokkos::LayoutLeft> {
 
  503       typename DuplicatedDataType<T, Kokkos::LayoutLeft>::value_type*;
 
  506 template <
typename T>
 
  507 struct DuplicatedDataType<T[], Kokkos::LayoutLeft> {
 
  509       typename DuplicatedDataType<T, Kokkos::LayoutLeft>::value_type*;
 
  512 template <
typename T>
 
  515       typename DuplicatedDataType<T, Kokkos::LayoutLeft>::value_type*;
 
  521 void args_to_array(
size_t* array, 
int pos, T dim0) {
 
  524 template <
class T, 
class... Dims>
 
  525 void args_to_array(
size_t* array, 
int pos, T dim0, Dims... dims) {
 
  527   args_to_array(array, pos + 1, dims...);
 
  533 template <
typename Layout, 
int rank, 
typename V, 
typename... Args>
 
  535   using next = Slice<Layout, rank - 1, V, Kokkos::ALL_t, Args...>;
 
  536   static auto get(V 
const& src, 
const size_t i, Args... args) {
 
  537     return next::get(src, i, Kokkos::ALL, args...);
 
  541 template <
typename V, 
typename... Args>
 
  542 struct Slice<Kokkos::LayoutRight, 1, V, Args...> {
 
  543   static auto get(V 
const& src, 
const size_t i, Args... args) {
 
  544     return Kokkos::subview(src, i, args...);
 
  548 template <
typename V, 
typename... Args>
 
  549 struct Slice<Kokkos::LayoutLeft, 1, V, Args...> {
 
  550   static auto get(V 
const& src, 
const size_t i, Args... args) {
 
  551     return Kokkos::subview(src, args..., i);
 
  555 #ifdef KOKKOS_ENABLE_IMPL_MDSPAN 
  556 template <
typename V, 
typename... Args>
 
  557 struct Slice<Kokkos::layout_right, 1, V, Args...> {
 
  558   static auto get(V 
const& src, 
const size_t i, Args... args) {
 
  559     return Kokkos::subview(src, i, args...);
 
  563 template <
typename V, 
typename... Args>
 
  564 struct Slice<Kokkos::layout_left, 1, V, Args...> {
 
  565   static auto get(V 
const& src, 
const size_t i, Args... args) {
 
  566     return Kokkos::subview(src, args..., i);
 
  570 template <
size_t Pad, 
typename V, 
typename... Args>
 
  571 struct Slice<Kokkos::Experimental::layout_right_padded<Pad>, 1, V, Args...> {
 
  572   static auto get(V 
const& src, 
const size_t i, Args... args) {
 
  573     return Kokkos::subview(src, i, args...);
 
  577 template <
size_t Pad, 
typename V, 
typename... Args>
 
  578 struct Slice<Kokkos::Experimental::layout_left_padded<Pad>, 1, V, Args...> {
 
  579   static auto get(V 
const& src, 
const size_t i, Args... args) {
 
  580     return Kokkos::subview(src, args..., i);
 
  585 template <
typename ExecSpace, 
typename ValueType, 
typename Op>
 
  586 struct ReduceDuplicates;
 
  588 template <
typename ExecSpace, 
typename ValueType, 
typename Op>
 
  589 struct ReduceDuplicatesBase {
 
  590   using Derived = ReduceDuplicates<ExecSpace, ValueType, Op>;
 
  591   ValueType 
const* src;
 
  596   ReduceDuplicatesBase(ExecSpace 
const& exec_space, ValueType 
const* src_in,
 
  597                        ValueType* dest_in, 
size_t stride_in, 
size_t start_in,
 
  598                        size_t n_in, std::string 
const& name)
 
  599       : src(src_in), dst(dest_in), stride(stride_in), start(start_in), n(n_in) {
 
  601         std::string(
"Kokkos::ScatterView::ReduceDuplicates [") + name + 
"]",
 
  602         RangePolicy<ExecSpace, size_t>(exec_space, 0, stride),
 
  603         static_cast<Derived const&>(*
this));
 
  610 template <
typename ExecSpace, 
typename ValueType, 
typename Op>
 
  611 struct ReduceDuplicates
 
  612     : 
public ReduceDuplicatesBase<ExecSpace, ValueType, Op> {
 
  613   using Base = ReduceDuplicatesBase<ExecSpace, ValueType, Op>;
 
  614   ReduceDuplicates(ExecSpace 
const& exec_space, ValueType 
const* src_in,
 
  615                    ValueType* dst_in, 
size_t stride_in, 
size_t start_in,
 
  616                    size_t n_in, std::string 
const& name)
 
  617       : Base(exec_space, src_in, dst_in, stride_in, start_in, n_in, name) {}
 
  618   KOKKOS_FORCEINLINE_FUNCTION 
void operator()(
size_t i)
 const {
 
  619     for (
size_t j = Base::start; j < Base::n; ++j) {
 
  620       ScatterValue<ValueType, Op, ExecSpace,
 
  621                    Kokkos::Experimental::ScatterNonAtomic>
 
  623       sv.update(Base::src[i + Base::stride * j]);
 
  628 template <
typename ExecSpace, 
typename ValueType, 
typename Op>
 
  629 struct ResetDuplicates;
 
  631 template <
typename ExecSpace, 
typename ValueType, 
typename Op>
 
  632 struct ResetDuplicatesBase {
 
  633   using Derived = ResetDuplicates<ExecSpace, ValueType, Op>;
 
  635   ResetDuplicatesBase(ExecSpace 
const& exec_space, ValueType* data_in,
 
  636                       size_t size_in, std::string 
const& name)
 
  639         std::string(
"Kokkos::ScatterView::ResetDuplicates [") + name + 
"]",
 
  640         RangePolicy<ExecSpace, size_t>(exec_space, 0, size_in),
 
  641         static_cast<Derived const&>(*
this));
 
  648 template <
typename ExecSpace, 
typename ValueType, 
typename Op>
 
  649 struct ResetDuplicates : 
public ResetDuplicatesBase<ExecSpace, ValueType, Op> {
 
  650   using Base = ResetDuplicatesBase<ExecSpace, ValueType, Op>;
 
  651   ResetDuplicates(ExecSpace 
const& exec_space, ValueType* data_in,
 
  652                   size_t size_in, std::string 
const& name)
 
  653       : Base(exec_space, data_in, size_in, name) {}
 
  654   KOKKOS_FORCEINLINE_FUNCTION 
void operator()(
size_t i)
 const {
 
  655     ScatterValue<ValueType, Op, ExecSpace,
 
  656                  Kokkos::Experimental::ScatterNonAtomic>
 
  662 template <
typename... P>
 
  663 void check_scatter_view_allocation_properties_argument(
 
  664     ViewCtorProp<P...> 
const&) {
 
  665   static_assert(ViewCtorProp<P...>::has_execution_space &&
 
  666                     ViewCtorProp<P...>::has_label &&
 
  667                     ViewCtorProp<P...>::initialize,
 
  668                 "Allocation property must have an execution name as well as a " 
  669                 "label, and must perform the view initialization");
 
  677 namespace Experimental {
 
  679 template <
typename DataType,
 
  680           typename Layout      = Kokkos::DefaultExecutionSpace::array_layout,
 
  681           typename DeviceType  = Kokkos::DefaultExecutionSpace,
 
  682           typename Op          = Kokkos::Experimental::ScatterSum,
 
  683           typename Duplication = 
typename Kokkos::Impl::Experimental::
 
  684               DefaultDuplication<typename DeviceType::execution_space>::type,
 
  685           typename Contribution =
 
  686               typename Kokkos::Impl::Experimental::DefaultContribution<
 
  687                   typename DeviceType::execution_space, Duplication>::type>
 
  691 struct is_scatter_view : 
public std::false_type {};
 
  693 template <
class D, 
class... P>
 
  694 struct is_scatter_view<ScatterView<D, P...>> : 
public std::true_type {};
 
  696 template <
class D, 
class... P>
 
  697 struct is_scatter_view<const ScatterView<D, P...>> : 
public std::true_type {};
 
  700 inline constexpr 
bool is_scatter_view_v = is_scatter_view<T>::value;
 
  702 template <
typename DataType, 
typename Op, 
typename DeviceType, 
typename Layout,
 
  703           typename Duplication, 
typename Contribution,
 
  704           typename OverrideContribution>
 
  708 template <
typename DataType, 
typename Op, 
typename DeviceType, 
typename Layout,
 
  709           typename Contribution>
 
  710 class ScatterView<DataType, Layout, DeviceType, Op, ScatterNonDuplicated,
 
  713   using execution_space         = 
typename DeviceType::execution_space;
 
  714   using memory_space            = 
typename DeviceType::memory_space;
 
  715   using device_type             = Kokkos::Device<execution_space, memory_space>;
 
  716   using original_view_type      = Kokkos::View<DataType, Layout, device_type>;
 
  717   using original_value_type     = 
typename original_view_type::value_type;
 
  718   using original_reference_type = 
typename original_view_type::reference_type;
 
  719   friend class ScatterAccess<DataType, Op, DeviceType, Layout,
 
  720                              ScatterNonDuplicated, Contribution,
 
  722   friend class ScatterAccess<DataType, Op, DeviceType, Layout,
 
  723                              ScatterNonDuplicated, Contribution, ScatterAtomic>;
 
  724   template <
class, 
class, 
class, 
class, 
class, 
class>
 
  725   friend class ScatterView;
 
  727   ScatterView() = 
default;
 
  729   template <
typename RT, 
typename... RP>
 
  730   ScatterView(View<RT, RP...> 
const& original_view)
 
  731       : internal_view(original_view) {}
 
  733   template <
typename RT, 
typename... P, 
typename... RP>
 
  734   ScatterView(execution_space 
const& ,
 
  735               View<RT, RP...> 
const& original_view)
 
  736       : internal_view(original_view) {}
 
  738   template <
typename... Dims>
 
  739   ScatterView(std::string 
const& name, Dims... dims)
 
  740       : internal_view(name, dims...) {}
 
  745   template <
typename... P, 
typename... Dims>
 
  746   ScatterView(::Kokkos::Impl::ViewCtorProp<P...> 
const& arg_prop, Dims... dims)
 
  747       : internal_view(arg_prop, dims...) {
 
  748     using ::Kokkos::Impl::Experimental::
 
  749         check_scatter_view_allocation_properties_argument;
 
  750     check_scatter_view_allocation_properties_argument(arg_prop);
 
  753   template <
typename OtherDataType, 
typename OtherDeviceType>
 
  754   KOKKOS_FUNCTION ScatterView(
 
  755       const ScatterView<OtherDataType, Layout, OtherDeviceType, Op,
 
  756                         ScatterNonDuplicated, Contribution>& other_view)
 
  757       : internal_view(other_view.internal_view) {}
 
  759   template <
typename OtherDataType, 
typename OtherDeviceType>
 
  760   KOKKOS_FUNCTION ScatterView& operator=(
 
  761       const ScatterView<OtherDataType, Layout, OtherDeviceType, Op,
 
  762                         ScatterNonDuplicated, Contribution>& other_view) {
 
  763     internal_view = other_view.internal_view;
 
  767   template <
typename Overr
ideContribution = Contribution>
 
  768   KOKKOS_FORCEINLINE_FUNCTION
 
  769       ScatterAccess<DataType, Op, DeviceType, Layout, ScatterNonDuplicated,
 
  770                     Contribution, OverrideContribution>
 
  772     return ScatterAccess<DataType, Op, DeviceType, Layout, ScatterNonDuplicated,
 
  773                          Contribution, OverrideContribution>(*this);
 
  776   original_view_type subview()
 const { 
return internal_view; }
 
  778   KOKKOS_INLINE_FUNCTION constexpr 
bool is_allocated()
 const {
 
  779     return internal_view.is_allocated();
 
  782   template <
typename DT, 
typename... RP>
 
  783   void contribute_into(View<DT, RP...> 
const& dest)
 const {
 
  784     contribute_into(execution_space(), dest);
 
  787   template <
typename DT, 
typename... RP>
 
  788   void contribute_into(execution_space 
const& exec_space,
 
  789                        View<DT, RP...> 
const& dest)
 const {
 
  790     using dest_type = 
View<DT, RP...>;
 
  791     static_assert(std::is_same_v<typename dest_type::array_layout, Layout>,
 
  792                   "ScatterView contribute destination has different layout");
 
  795             execution_space, 
typename dest_type::memory_space>::accessible,
 
  796         "ScatterView contribute destination memory space not accessible");
 
  797     if (dest.data() == internal_view.data()) 
return;
 
  798     Kokkos::Impl::Experimental::ReduceDuplicates<execution_space,
 
  799                                                  original_value_type, Op>(
 
  800         exec_space, internal_view.data(), dest.data(), 0, 0, 1,
 
  801         internal_view.label());
 
  804   void reset(execution_space 
const& exec_space = execution_space()) {
 
  805     Kokkos::Impl::Experimental::ResetDuplicates<execution_space,
 
  806                                                 original_value_type, Op>(
 
  807         exec_space, internal_view.data(), internal_view.size(),
 
  808         internal_view.label());
 
  810   template <
typename DT, 
typename... RP>
 
  811   void reset_except(View<DT, RP...> 
const& view) {
 
  812     reset_except(execution_space(), view);
 
  815   template <
typename DT, 
typename... RP>
 
  816   void reset_except(
const execution_space& exec_space,
 
  817                     View<DT, RP...> 
const& view) {
 
  818     if (view.data() != internal_view.data()) reset(exec_space);
 
  821   void resize(
const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  822               const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  823               const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  824               const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  825               const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  826               const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  827               const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  828               const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
 
  829     ::Kokkos::resize(internal_view, n0, n1, n2, n3, n4, n5, n6, n7);
 
  832   template <
class... ViewCtorArgs>
 
  833   void resize(const ::Kokkos::Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
 
  834               const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  835               const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  836               const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  837               const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  838               const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  839               const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  840               const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  841               const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
 
  842     ::Kokkos::resize(arg_prop, internal_view, n0, n1, n2, n3, n4, n5, n6, n7);
 
  846   std::enable_if_t<Kokkos::Impl::is_view_ctor_property<I>::value> resize(
 
  847       const I& arg_prop, 
const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  848       const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  849       const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  850       const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  851       const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  852       const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  853       const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  854       const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
 
  855     ::Kokkos::resize(arg_prop, internal_view, n0, n1, n2, n3, n4, n5, n6, n7);
 
  858   template <
class... ViewCtorArgs>
 
  859   void realloc(
const Kokkos::Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
 
  860                const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  861                const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  862                const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  863                const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  864                const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  865                const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  866                const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  867                const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
 
  868     ::Kokkos::realloc(arg_prop, internal_view, n0, n1, n2, n3, n4, n5, n6, n7);
 
  871   void realloc(
const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  872                const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  873                const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  874                const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  875                const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  876                const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  877                const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  878                const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
 
  879     ::Kokkos::realloc(internal_view, n0, n1, n2, n3, n4, n5, n6, n7);
 
  883   std::enable_if_t<Kokkos::Impl::is_view_ctor_property<I>::value> realloc(
 
  884       const I& arg_prop, 
const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  885       const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  886       const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  887       const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  888       const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  889       const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  890       const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  891       const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
 
  892     ::Kokkos::realloc(arg_prop, internal_view, n0, n1, n2, n3, n4, n5, n6, n7);
 
  896   template <
typename... Args>
 
  897   KOKKOS_FORCEINLINE_FUNCTION original_reference_type at(Args... args)
 const {
 
  898     return internal_view(args...);
 
  902   using internal_view_type = original_view_type;
 
  903   internal_view_type internal_view;
 
  906 template <
typename DataType, 
typename Op, 
typename DeviceType, 
typename Layout,
 
  907           typename Contribution, 
typename OverrideContribution>
 
  908 class ScatterAccess<DataType, Op, DeviceType, Layout, ScatterNonDuplicated,
 
  909                     Contribution, OverrideContribution> {
 
  911   using view_type           = ScatterView<DataType, Layout, DeviceType, Op,
 
  912                                 ScatterNonDuplicated, Contribution>;
 
  913   using original_value_type = 
typename view_type::original_value_type;
 
  914   using value_type          = Kokkos::Impl::Experimental::ScatterValue<
 
  915       original_value_type, Op, DeviceType, OverrideContribution>;
 
  917   KOKKOS_INLINE_FUNCTION
 
  918   ScatterAccess() : view(view_type()) {}
 
  920   KOKKOS_INLINE_FUNCTION
 
  921   ScatterAccess(view_type 
const& view_in) : view(view_in) {}
 
  922   KOKKOS_DEFAULTED_FUNCTION
 
  923   ~ScatterAccess() = 
default;
 
  925   template <
typename... Args>
 
  926   KOKKOS_FORCEINLINE_FUNCTION value_type operator()(Args... args)
 const {
 
  927     return view.at(args...);
 
  930   template <
typename Arg>
 
  931   KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
 
  932       std::is_integral_v<Arg> && view_type::original_view_type::rank == 1,
 
  934   operator[](Arg arg)
 const {
 
  939   view_type 
const& view;
 
  946 template <
typename DataType, 
typename Op, 
typename DeviceType,
 
  947           typename Contribution>
 
  948 class ScatterView<DataType, Kokkos::LayoutRight, DeviceType, Op,
 
  949                   ScatterDuplicated, Contribution> {
 
  951   using execution_space = 
typename DeviceType::execution_space;
 
  952   using memory_space    = 
typename DeviceType::memory_space;
 
  953   using device_type     = Kokkos::Device<execution_space, memory_space>;
 
  954   using original_view_type =
 
  955       Kokkos::View<DataType, Kokkos::LayoutRight, device_type>;
 
  956   using original_value_type     = 
typename original_view_type::value_type;
 
  957   using original_reference_type = 
typename original_view_type::reference_type;
 
  958   friend class ScatterAccess<DataType, Op, DeviceType, Kokkos::LayoutRight,
 
  959                              ScatterDuplicated, Contribution, ScatterNonAtomic>;
 
  960   friend class ScatterAccess<DataType, Op, DeviceType, Kokkos::LayoutRight,
 
  961                              ScatterDuplicated, Contribution, ScatterAtomic>;
 
  962   template <class, class, class, class, class, class>
 
  963   friend class ScatterView;
 
  965   using data_type_info =
 
  966       typename Kokkos::Impl::Experimental::DuplicatedDataType<
 
  967           DataType, Kokkos::LayoutRight>;
 
  968   using internal_data_type = typename data_type_info::value_type;
 
  969   using internal_view_type =
 
  970       Kokkos::View<internal_data_type, Kokkos::LayoutRight, device_type>;
 
  972   ScatterView() = default;
 
  974   template <typename OtherDataType, typename OtherDeviceType>
 
  975   KOKKOS_FUNCTION ScatterView(
 
  976       const ScatterView<OtherDataType, Kokkos::LayoutRight, OtherDeviceType, Op,
 
  977                         ScatterDuplicated, Contribution>& other_view)
 
  978       : unique_token(other_view.unique_token),
 
  979         internal_view(other_view.internal_view) {}
 
  981   template <
typename OtherDataType, 
typename OtherDeviceType>
 
  982   KOKKOS_FUNCTION ScatterView& operator=(
 
  984                         ScatterDuplicated, Contribution>& other_view) {
 
  985     unique_token  = other_view.unique_token;
 
  986     internal_view = other_view.internal_view;
 
  990   template <
typename RT, 
typename... RP>
 
  991   ScatterView(View<RT, RP...> 
const& original_view)
 
  992       : ScatterView(execution_space(), original_view) {}
 
  994   template <
typename RT, 
typename... P, 
typename... RP>
 
  995   ScatterView(execution_space 
const& exec_space,
 
  996               View<RT, RP...> 
const& original_view)
 
  999             view_alloc(WithoutInitializing,
 
 1000                        std::string(
"duplicated_") + original_view.label(),
 
 1002             unique_token.size(),
 
 1003             original_view.rank_dynamic > 0 ? original_view.extent(0)
 
 1004                                            : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1005             original_view.rank_dynamic > 1 ? original_view.extent(1)
 
 1006                                            : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1007             original_view.rank_dynamic > 2 ? original_view.extent(2)
 
 1008                                            : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1009             original_view.rank_dynamic > 3 ? original_view.extent(3)
 
 1010                                            : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1011             original_view.rank_dynamic > 4 ? original_view.extent(4)
 
 1012                                            : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1013             original_view.rank_dynamic > 5 ? original_view.extent(5)
 
 1014                                            : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1015             original_view.rank_dynamic > 6 ? original_view.extent(6)
 
 1016                                            : KOKKOS_IMPL_CTOR_DEFAULT_ARG)
 
 1022   template <
typename... Dims>
 
 1023   ScatterView(std::string 
const& name, Dims... dims)
 
 1024       : ScatterView(view_alloc(execution_space(), name), dims...) {}
 
 1029   template <
typename... P, 
typename... Dims>
 
 1030   ScatterView(::Kokkos::Impl::ViewCtorProp<P...> 
const& arg_prop, Dims... dims)
 
 1031       : internal_view(view_alloc(WithoutInitializing,
 
 1032                                  static_cast<::Kokkos::Impl::ViewCtorProp<
 
 1033                                      void, std::string> const&>(arg_prop)
 
 1035                       unique_token.size(), dims...) {
 
 1036     using ::Kokkos::Impl::Experimental::
 
 1037         check_scatter_view_allocation_properties_argument;
 
 1038     check_scatter_view_allocation_properties_argument(arg_prop);
 
 1040     auto const& exec_space =
 
 1041         Kokkos::Impl::get_property<Kokkos::Impl::ExecutionSpaceTag>(arg_prop);
 
 1045   template <
typename Overr
ideContribution = Contribution>
 
 1046   KOKKOS_FORCEINLINE_FUNCTION
 
 1048                     ScatterDuplicated, Contribution, OverrideContribution>
 
 1051                          ScatterDuplicated, Contribution, OverrideContribution>(
 
 1055   auto subview()
 const {
 
 1056     return Kokkos::Impl::Experimental::Slice<
 
 1058         internal_view_type>::get(internal_view, 0);
 
 1061   KOKKOS_INLINE_FUNCTION constexpr 
bool is_allocated()
 const {
 
 1062     return internal_view.is_allocated();
 
 1065   template <
typename DT, 
typename... RP>
 
 1066   void contribute_into(View<DT, RP...> 
const& dest)
 const {
 
 1067     contribute_into(execution_space(), dest);
 
 1070   template <
typename DT, 
typename... RP>
 
 1071   void contribute_into(execution_space 
const& exec_space,
 
 1072                        View<DT, RP...> 
const& dest)
 const {
 
 1073     using dest_type = 
View<DT, RP...>;
 
 1075         std::is_same_v<typename dest_type::array_layout, Kokkos::LayoutRight>,
 
 1076         "ScatterView deep_copy destination has different layout");
 
 1079             execution_space, 
typename dest_type::memory_space>::accessible,
 
 1080         "ScatterView deep_copy destination memory space not accessible");
 
 1081     bool is_equal = (dest.data() == internal_view.data());
 
 1082     size_t start  = is_equal ? 1 : 0;
 
 1083     Kokkos::Impl::Experimental::ReduceDuplicates<execution_space,
 
 1084                                                  original_value_type, Op>(
 
 1085         exec_space, internal_view.data(), dest.data(), internal_view.stride(0),
 
 1086         start, internal_view.extent(0), internal_view.label());
 
 1089   void reset(execution_space 
const& exec_space = execution_space()) {
 
 1090     Kokkos::Impl::Experimental::ResetDuplicates<execution_space,
 
 1091                                                 original_value_type, Op>(
 
 1092         exec_space, internal_view.data(), internal_view.size(),
 
 1093         internal_view.label());
 
 1096   template <
typename DT, 
typename... RP>
 
 1097   void reset_except(View<DT, RP...> 
const& view) {
 
 1098     reset_except(execution_space(), view);
 
 1101   template <
typename DT, 
typename... RP>
 
 1102   void reset_except(execution_space 
const& exec_space,
 
 1103                     View<DT, RP...> 
const& view) {
 
 1104     if (view.data() != internal_view.data()) {
 
 1108     Kokkos::Impl::Experimental::ResetDuplicates<execution_space,
 
 1109                                                 original_value_type, Op>(
 
 1110         exec_space, internal_view.data() + view.size(),
 
 1111         internal_view.size() - view.size(), internal_view.label());
 
 1114   void resize(
const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1115               const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1116               const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1117               const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1118               const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1119               const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1120               const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
 
 1121     ::Kokkos::resize(internal_view, unique_token.size(), n0, n1, n2, n3, n4, n5,
 
 1125   template <
class... ViewCtorArgs>
 
 1126   void resize(const ::Kokkos::Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
 
 1127               const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1128               const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1129               const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1130               const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1131               const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1132               const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1133               const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
 
 1134     ::Kokkos::resize(arg_prop, internal_view, unique_token.size(), n0, n1, n2,
 
 1139   std::enable_if_t<Kokkos::Impl::is_view_ctor_property<I>::value> resize(
 
 1140       const I& arg_prop, 
const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1141       const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1142       const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1143       const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1144       const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1145       const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1146       const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
 
 1147     ::Kokkos::resize(arg_prop, internal_view, unique_token.size(), n0, n1, n2,
 
 1151   template <
class... ViewCtorArgs>
 
 1152   void realloc(const ::Kokkos::Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
 
 1153                const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1154                const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1155                const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1156                const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1157                const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1158                const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1159                const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
 
 1160     ::Kokkos::realloc(arg_prop, internal_view, unique_token.size(), n0, n1, n2,
 
 1164   void realloc(
const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1165                const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1166                const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1167                const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1168                const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1169                const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1170                const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
 
 1171     ::Kokkos::realloc(internal_view, unique_token.size(), n0, n1, n2, n3, n4,
 
 1176   std::enable_if_t<Kokkos::Impl::is_view_ctor_property<I>::value> realloc(
 
 1177       const I& arg_prop, 
const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1178       const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1179       const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1180       const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1181       const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1182       const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1183       const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
 
 1184     ::Kokkos::realloc(arg_prop, internal_view, unique_token.size(), n0, n1, n2,
 
 1189   template <
typename... Args>
 
 1190   KOKKOS_FORCEINLINE_FUNCTION original_reference_type at(
int rank,
 
 1191                                                          Args... args)
 const {
 
 1192     return internal_view(rank, args...);
 
 1197       execution_space, Kokkos::Experimental::UniqueTokenScope::Global>;
 
 1199   unique_token_type unique_token;
 
 1200   internal_view_type internal_view;
 
 1203 template <
typename DataType, 
typename Op, 
typename DeviceType,
 
 1204           typename Contribution>
 
 1205 class ScatterView<DataType, Kokkos::LayoutLeft, DeviceType, Op,
 
 1206                   ScatterDuplicated, Contribution> {
 
 1208   using execution_space = 
typename DeviceType::execution_space;
 
 1209   using memory_space    = 
typename DeviceType::memory_space;
 
 1210   using device_type     = Kokkos::Device<execution_space, memory_space>;
 
 1211   using original_view_type =
 
 1212       Kokkos::View<DataType, Kokkos::LayoutLeft, device_type>;
 
 1213   using original_value_type     = 
typename original_view_type::value_type;
 
 1214   using original_reference_type = 
typename original_view_type::reference_type;
 
 1215   friend class ScatterAccess<DataType, Op, DeviceType, Kokkos::LayoutLeft,
 
 1216                              ScatterDuplicated, Contribution, ScatterNonAtomic>;
 
 1217   friend class ScatterAccess<DataType, Op, DeviceType, Kokkos::LayoutLeft,
 
 1218                              ScatterDuplicated, Contribution, ScatterAtomic>;
 
 1219   template <class, class, class, class, class, class>
 
 1220   friend class ScatterView;
 
 1222   using data_type_info =
 
 1223       typename Kokkos::Impl::Experimental::DuplicatedDataType<
 
 1224           DataType, Kokkos::LayoutLeft>;
 
 1225   using internal_data_type = typename data_type_info::value_type;
 
 1226   using internal_view_type =
 
 1227       Kokkos::View<internal_data_type, Kokkos::LayoutLeft, device_type>;
 
 1229   ScatterView() = default;
 
 1231   template <typename RT, typename... RP>
 
 1232   ScatterView(View<RT, RP...> const& original_view)
 
 1233       : ScatterView(execution_space(), original_view) {}
 
 1235   template <
typename RT, 
typename... P, 
typename... RP>
 
 1236   ScatterView(execution_space 
const& exec_space,
 
 1237               View<RT, RP...> 
const& original_view)
 
 1239     size_t arg_N[8] = {original_view.rank > 0 ? original_view.extent(0)
 
 1240                                               : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1241                        original_view.rank > 1 ? original_view.extent(1)
 
 1242                                               : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1243                        original_view.rank > 2 ? original_view.extent(2)
 
 1244                                               : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1245                        original_view.rank > 3 ? original_view.extent(3)
 
 1246                                               : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1247                        original_view.rank > 4 ? original_view.extent(4)
 
 1248                                               : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1249                        original_view.rank > 5 ? original_view.extent(5)
 
 1250                                               : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1251                        original_view.rank > 6 ? original_view.extent(6)
 
 1252                                               : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1253                        KOKKOS_IMPL_CTOR_DEFAULT_ARG};
 
 1254     arg_N[internal_view_type::rank - 1] = unique_token.size();
 
 1255     internal_view                       = internal_view_type(
 
 1256         view_alloc(WithoutInitializing,
 
 1257                                          std::string(
"duplicated_") + original_view.label(),
 
 1259         arg_N[0], arg_N[1], arg_N[2], arg_N[3], arg_N[4], arg_N[5], arg_N[6],
 
 1264   template <
typename... Dims>
 
 1265   ScatterView(std::string 
const& name, Dims... dims)
 
 1266       : ScatterView(view_alloc(execution_space(), name), dims...) {}
 
 1271   template <
typename... P, 
typename... Dims>
 
 1272   ScatterView(::Kokkos::Impl::ViewCtorProp<P...> 
const& arg_prop,
 
 1274     using ::Kokkos::Impl::Experimental::
 
 1275         check_scatter_view_allocation_properties_argument;
 
 1276     check_scatter_view_allocation_properties_argument(arg_prop);
 
 1278     original_view_type original_view;
 
 1279     size_t arg_N[8] = {original_view.rank > 0 ? original_view.static_extent(0)
 
 1280                                               : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1281                        original_view.rank > 1 ? original_view.static_extent(1)
 
 1282                                               : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1283                        original_view.rank > 2 ? original_view.static_extent(2)
 
 1284                                               : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1285                        original_view.rank > 3 ? original_view.static_extent(3)
 
 1286                                               : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1287                        original_view.rank > 4 ? original_view.static_extent(4)
 
 1288                                               : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1289                        original_view.rank > 5 ? original_view.static_extent(5)
 
 1290                                               : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1291                        original_view.rank > 6 ? original_view.static_extent(6)
 
 1292                                               : KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1293                        KOKKOS_IMPL_CTOR_DEFAULT_ARG};
 
 1294     Kokkos::Impl::Experimental::args_to_array(arg_N, 0, dims...);
 
 1295     arg_N[internal_view_type::rank - 1] = unique_token.size();
 
 1298         Kokkos::Impl::get_property<Kokkos::Impl::LabelTag>(arg_prop);
 
 1299     internal_view = internal_view_type(view_alloc(WithoutInitializing, name),
 
 1300                                        arg_N[0], arg_N[1], arg_N[2], arg_N[3],
 
 1301                                        arg_N[4], arg_N[5], arg_N[6], arg_N[7]);
 
 1303     auto const& exec_space =
 
 1304         Kokkos::Impl::get_property<Kokkos::Impl::ExecutionSpaceTag>(arg_prop);
 
 1308   template <
typename OtherDataType, 
typename OtherDeviceType>
 
 1309   KOKKOS_FUNCTION ScatterView(
 
 1311                         ScatterDuplicated, Contribution>& other_view)
 
 1312       : unique_token(other_view.unique_token),
 
 1313         internal_view(other_view.internal_view) {}
 
 1315   template <
typename OtherDataType, 
typename OtherDeviceType>
 
 1316   KOKKOS_FUNCTION ScatterView& operator=(
 
 1318                         ScatterDuplicated, Contribution>& other_view) {
 
 1319     unique_token  = other_view.unique_token;
 
 1320     internal_view = other_view.internal_view;
 
 1324   template <
typename Overr
ideContribution = Contribution>
 
 1325   KOKKOS_FORCEINLINE_FUNCTION
 
 1327                     ScatterDuplicated, Contribution, OverrideContribution>
 
 1330                          ScatterDuplicated, Contribution, OverrideContribution>(
 
 1334   auto subview()
 const {
 
 1335     return Kokkos::Impl::Experimental::Slice<
 
 1337         internal_view_type>::get(internal_view, 0);
 
 1340   KOKKOS_INLINE_FUNCTION constexpr 
bool is_allocated()
 const {
 
 1341     return internal_view.is_allocated();
 
 1344   template <
typename... RP>
 
 1345   void contribute_into(View<RP...> 
const& dest)
 const {
 
 1346     contribute_into(execution_space(), dest);
 
 1349   template <
typename... RP>
 
 1350   void contribute_into(execution_space 
const& exec_space,
 
 1351                        View<RP...> 
const& dest)
 const {
 
 1352     using dest_type = 
View<RP...>;
 
 1354         std::is_same_v<
typename dest_type::value_type,
 
 1355                        typename original_view_type::non_const_value_type>,
 
 1356         "ScatterView deep_copy destination has wrong value_type");
 
 1358         std::is_same_v<typename dest_type::array_layout, Kokkos::LayoutLeft>,
 
 1359         "ScatterView deep_copy destination has different layout");
 
 1362             execution_space, 
typename dest_type::memory_space>::accessible,
 
 1363         "ScatterView deep_copy destination memory space not accessible");
 
 1364     auto extent   = internal_view.extent(internal_view_type::rank - 1);
 
 1365     bool is_equal = (dest.data() == internal_view.data());
 
 1366     size_t start  = is_equal ? 1 : 0;
 
 1367     Kokkos::Impl::Experimental::ReduceDuplicates<execution_space,
 
 1368                                                  original_value_type, Op>(
 
 1369         exec_space, internal_view.data(), dest.data(),
 
 1370         internal_view.stride(internal_view_type::rank - 1), start, extent,
 
 1371         internal_view.label());
 
 1374   void reset(execution_space 
const& exec_space = execution_space()) {
 
 1375     Kokkos::Impl::Experimental::ResetDuplicates<execution_space,
 
 1376                                                 original_value_type, Op>(
 
 1377         exec_space, internal_view.data(), internal_view.size(),
 
 1378         internal_view.label());
 
 1381   template <
typename DT, 
typename... RP>
 
 1382   void reset_except(View<DT, RP...> 
const& view) {
 
 1383     reset_except(execution_space(), view);
 
 1386   template <
typename DT, 
typename... RP>
 
 1387   void reset_except(execution_space 
const& exec_space,
 
 1388                     View<DT, RP...> 
const& view) {
 
 1389     if (view.data() != internal_view.data()) {
 
 1393     Kokkos::Impl::Experimental::ResetDuplicates<execution_space,
 
 1394                                                 original_value_type, Op>(
 
 1395         exec_space, internal_view.data() + view.size(),
 
 1396         internal_view.size() - view.size(), internal_view.label());
 
 1399   void resize(
const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1400               const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1401               const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1402               const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1403               const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1404               const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1405               const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
 
 1406     size_t arg_N[8] = {n0, n1, n2, n3, n4, n5, n6, 0};
 
 1407     const int i     = internal_view.rank - 1;
 
 1408     arg_N[i]        = unique_token.size();
 
 1410     ::Kokkos::resize(internal_view, arg_N[0], arg_N[1], arg_N[2], arg_N[3],
 
 1411                      arg_N[4], arg_N[5], arg_N[6], arg_N[7]);
 
 1414   void realloc(
const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1415                const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1416                const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1417                const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1418                const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1419                const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1420                const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
 
 1421     size_t arg_N[8] = {n0, n1, n2, n3, n4, n5, n6, 0};
 
 1422     const int i     = internal_view.rank - 1;
 
 1423     arg_N[i]        = unique_token.size();
 
 1425     ::Kokkos::realloc(internal_view, arg_N[0], arg_N[1], arg_N[2], arg_N[3],
 
 1426                       arg_N[4], arg_N[5], arg_N[6], arg_N[7]);
 
 1430   template <
typename... Args>
 
 1431   KOKKOS_FORCEINLINE_FUNCTION original_reference_type at(
int thread_id,
 
 1432                                                          Args... args)
 const {
 
 1433     return internal_view(args..., thread_id);
 
 1438       execution_space, Kokkos::Experimental::UniqueTokenScope::Global>;
 
 1440   unique_token_type unique_token;
 
 1441   internal_view_type internal_view;
 
 1454 template <
typename DataType, 
typename Op, 
typename DeviceType, 
typename Layout,
 
 1455           typename Contribution, 
typename OverrideContribution>
 
 1456 class ScatterAccess<DataType, Op, DeviceType, Layout, ScatterDuplicated,
 
 1457                     Contribution, OverrideContribution> {
 
 1459   using view_type           = ScatterView<DataType, Layout, DeviceType, Op,
 
 1460                                 ScatterDuplicated, Contribution>;
 
 1461   using original_value_type = 
typename view_type::original_value_type;
 
 1462   using value_type          = Kokkos::Impl::Experimental::ScatterValue<
 
 1463       original_value_type, Op, DeviceType, OverrideContribution>;
 
 1465   KOKKOS_FORCEINLINE_FUNCTION
 
 1466   ScatterAccess(view_type 
const& view_in)
 
 1467       : view(view_in), thread_id(view_in.unique_token.acquire()) {}
 
 1469   KOKKOS_FORCEINLINE_FUNCTION
 
 1471     if (thread_id != ~thread_id_type(0)) view.unique_token.release(thread_id);
 
 1474   template <
typename... Args>
 
 1475   KOKKOS_FORCEINLINE_FUNCTION value_type operator()(Args... args)
 const {
 
 1476     return view.at(thread_id, args...);
 
 1479   template <
typename Arg>
 
 1480   KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
 
 1481       std::is_integral_v<Arg> && view_type::original_view_type::rank == 1,
 
 1483   operator[](Arg arg)
 const {
 
 1484     return view.at(thread_id, arg);
 
 1488   view_type 
const& view;
 
 1491   ScatterAccess(ScatterAccess 
const& other)            = 
delete;
 
 1492   ScatterAccess& operator=(ScatterAccess 
const& other) = 
delete;
 
 1493   ScatterAccess& operator=(ScatterAccess&& other)      = 
delete;
 
 1499   KOKKOS_FORCEINLINE_FUNCTION
 
 1500   ScatterAccess(ScatterAccess&& other)
 
 1501       : view(other.view), thread_id(other.thread_id) {
 
 1502     other.thread_id = ~thread_id_type(0);
 
 1506   using unique_token_type = 
typename view_type::unique_token_type;
 
 1507   using thread_id_type    = 
typename unique_token_type::size_type;
 
 1508   thread_id_type thread_id;
 
 1511 template <
typename Op          = Kokkos::Experimental::ScatterSum,
 
 1512           typename Duplication = void, 
typename Contribution = void,
 
 1513           typename RT, 
typename... RP>
 
 1515     RT, 
typename ViewTraits<RT, RP...>::array_layout,
 
 1516     typename ViewTraits<RT, RP...>::device_type, Op,
 
 1518         std::is_void_v<Duplication>,
 
 1519         typename Kokkos::Impl::Experimental::DefaultDuplication<
 
 1520             typename ViewTraits<RT, RP...>::execution_space>::type,
 
 1523         std::is_void_v<Contribution>,
 
 1524         typename Kokkos::Impl::Experimental::DefaultContribution<
 
 1525             typename ViewTraits<RT, RP...>::execution_space,
 
 1526             typename std::conditional_t<
 
 1527                 std::is_void_v<Duplication>,
 
 1528                 typename Kokkos::Impl::Experimental::DefaultDuplication<
 
 1529                     typename ViewTraits<RT, RP...>::execution_space>::type,
 
 1530                 Duplication>>::type,
 
 1532 create_scatter_view(View<RT, RP...> 
const& original_view) {
 
 1533   return original_view;  
 
 1536 template <
typename Op, 
typename RT, 
typename... RP>
 
 1538     RT, 
typename ViewTraits<RT, RP...>::array_layout,
 
 1539     typename ViewTraits<RT, RP...>::device_type, Op,
 
 1540     typename Kokkos::Impl::Experimental::DefaultDuplication<
 
 1541         typename ViewTraits<RT, RP...>::execution_space>::type,
 
 1542     typename Kokkos::Impl::Experimental::DefaultContribution<
 
 1543         typename ViewTraits<RT, RP...>::execution_space,
 
 1544         typename Kokkos::Impl::Experimental::DefaultDuplication<
 
 1545             typename ViewTraits<RT, RP...>::execution_space>::type>::type>
 
 1546 create_scatter_view(Op, View<RT, RP...> 
const& original_view) {
 
 1547   return original_view;  
 
 1550 template <
typename Op, 
typename Duplication, 
typename Contribution, 
typename RT,
 
 1552 ScatterView<RT, 
typename ViewTraits<RT, RP...>::array_layout,
 
 1553             typename ViewTraits<RT, RP...>::device_type, Op, Duplication,
 
 1555 create_scatter_view(Op, Duplication, Contribution,
 
 1556                     View<RT, RP...> 
const& original_view) {
 
 1557   return original_view;  
 
 1564 namespace Experimental {
 
 1566 template <
typename DT1, 
typename DT2, 
typename LY, 
typename ES, 
typename OP,
 
 1567           typename CT, 
typename DP, 
typename... VP>
 
 1569     typename ES::execution_space 
const& exec_space, View<DT1, VP...>& dest,
 
 1570     Kokkos::Experimental::ScatterView<DT2, LY, ES, OP, CT, DP> 
const& src) {
 
 1571   src.contribute_into(exec_space, dest);
 
 1574 template <
typename DT1, 
typename DT2, 
typename LY, 
typename ES, 
typename OP,
 
 1575           typename CT, 
typename DP, 
typename... VP>
 
 1577     View<DT1, VP...>& dest,
 
 1578     Kokkos::Experimental::ScatterView<DT2, LY, ES, OP, CT, DP> 
const& src) {
 
 1579   using execution_space = 
typename ES::execution_space;
 
 1580   contribute(execution_space{}, dest, src);
 
 1588 template <
typename DT, 
typename LY, 
typename ES, 
typename OP, 
typename CT,
 
 1589           typename DP, 
typename... IS, 
class... ViewCtorArgs>
 
 1591     const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
 
 1592     Kokkos::Experimental::ScatterView<DT, LY, ES, OP, CT, DP>& scatter_view,
 
 1594   scatter_view.realloc(arg_prop, is...);
 
 1597 template <
typename DT, 
typename LY, 
typename ES, 
typename OP, 
typename CT,
 
 1598           typename DP, 
typename... IS>
 
 1600     Kokkos::Experimental::ScatterView<DT, LY, ES, OP, CT, DP>& scatter_view,
 
 1602   scatter_view.realloc(is...);
 
 1605 template <
typename I, 
typename DT, 
typename LY, 
typename ES, 
typename OP,
 
 1606           typename CT, 
typename DP, 
typename... IS>
 
 1607 std::enable_if_t<Kokkos::Impl::is_view_ctor_property<I>::value> realloc(
 
 1609     Kokkos::Experimental::ScatterView<DT, LY, ES, OP, CT, DP>& scatter_view,
 
 1611   scatter_view.realloc(arg_prop, is...);
 
 1614 template <
typename DT, 
typename LY, 
typename ES, 
typename OP, 
typename CT,
 
 1615           typename DP, 
typename... IS>
 
 1617     Kokkos::Experimental::ScatterView<DT, LY, ES, OP, CT, DP>& scatter_view,
 
 1619   scatter_view.resize(is...);
 
 1622 template <
class... ViewCtorArgs, 
typename DT, 
typename LY, 
typename ES,
 
 1623           typename OP, 
typename CT, 
typename DP, 
typename... IS>
 
 1625     const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
 
 1626     Kokkos::Experimental::ScatterView<DT, LY, ES, OP, CT, DP>& scatter_view,
 
 1628   scatter_view.resize(arg_prop, is...);
 
 1631 template <
typename I, 
typename DT, 
typename LY, 
typename ES, 
typename OP,
 
 1632           typename CT, 
typename DP, 
typename... IS>
 
 1633 std::enable_if_t<Kokkos::Impl::is_view_ctor_property<I>::value> resize(
 
 1635     Kokkos::Experimental::ScatterView<DT, LY, ES, OP, CT, DP>& scatter_view,
 
 1637   scatter_view.resize(arg_prop, is...);
 
 1642 #ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_SCATTERVIEW 
 1643 #undef KOKKOS_IMPL_PUBLIC_INCLUDE 
 1644 #undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_SCATTERVIEW 
Memory layout tag indicating left-to-right (Fortran scheme) striding of multi-indices. 
 
Can AccessSpace access MemorySpace ? 
 
class to generate unique ids base on the required amount of concurrency 
 
Memory layout tag indicating right-to-left (C or lexigraphical scheme) striding of multi-indices...