Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Kokkos_View.hpp
1 //@HEADER
2 // ************************************************************************
3 //
4 // Kokkos v. 4.0
5 // Copyright (2022) National Technology & Engineering
6 // Solutions of Sandia, LLC (NTESS).
7 //
8 // Under the terms of Contract DE-NA0003525 with NTESS,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions.
12 // See https://kokkos.org/LICENSE for license information.
13 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 //
15 //@HEADER
16 
17 #ifndef KOKKOS_IMPL_PUBLIC_INCLUDE
18 #include <Kokkos_Macros.hpp>
19 static_assert(false,
20  "Including non-public Kokkos header files is not allowed.");
21 #endif
22 #ifndef KOKKOS_VIEW_HPP
23 #define KOKKOS_VIEW_HPP
24 
25 #include <type_traits>
26 #include <string>
27 #include <algorithm>
28 #include <initializer_list>
29 
30 #include <Kokkos_Core_fwd.hpp>
31 #include <Kokkos_HostSpace.hpp>
32 #include <Kokkos_MemoryTraits.hpp>
33 #include <Kokkos_ExecPolicy.hpp>
34 #include <View/Hooks/Kokkos_ViewHooks.hpp>
35 
36 #include <impl/Kokkos_Tools.hpp>
37 #include <impl/Kokkos_Utilities.hpp>
38 
39 #ifdef KOKKOS_ENABLE_IMPL_MDSPAN
40 #include <View/MDSpan/Kokkos_MDSpan_Extents.hpp>
41 #endif
42 #include <Kokkos_MinMax.hpp>
43 
44 //----------------------------------------------------------------------------
45 //----------------------------------------------------------------------------
46 
47 namespace Kokkos {
48 namespace Impl {
49 
50 template <class DataType>
51 struct ViewArrayAnalysis;
52 
53 template <class DataType, class ArrayLayout,
54  typename ValueType =
55  typename ViewArrayAnalysis<DataType>::non_const_value_type>
56 struct ViewDataAnalysis;
57 
58 template <class, class...>
59 class ViewMapping {
60  public:
61  enum : bool { is_assignable_data_type = false };
62  enum : bool { is_assignable = false };
63 };
64 
65 template <typename IntType>
66 constexpr KOKKOS_INLINE_FUNCTION std::size_t count_valid_integers(
67  const IntType i0, const IntType i1, const IntType i2, const IntType i3,
68  const IntType i4, const IntType i5, const IntType i6, const IntType i7) {
69  static_assert(std::is_integral<IntType>::value,
70  "count_valid_integers() must have integer arguments.");
71 
72  return (i0 != KOKKOS_INVALID_INDEX) + (i1 != KOKKOS_INVALID_INDEX) +
73  (i2 != KOKKOS_INVALID_INDEX) + (i3 != KOKKOS_INVALID_INDEX) +
74  (i4 != KOKKOS_INVALID_INDEX) + (i5 != KOKKOS_INVALID_INDEX) +
75  (i6 != KOKKOS_INVALID_INDEX) + (i7 != KOKKOS_INVALID_INDEX);
76 }
77 
78 // FIXME Ideally, we would not instantiate this function for every possible View
79 // type. We should be able to only pass "extent" when we use mdspan.
80 template <typename View>
81 KOKKOS_INLINE_FUNCTION void runtime_check_rank(
82  const View&, const bool is_void_spec, const size_t i0, const size_t i1,
83  const size_t i2, const size_t i3, const size_t i4, const size_t i5,
84  const size_t i6, const size_t i7, const char* label) {
85  (void)(label);
86 
87  if (is_void_spec) {
88  const size_t num_passed_args =
89  count_valid_integers(i0, i1, i2, i3, i4, i5, i6, i7);
90  // We either allow to pass as many extents as the dynamic rank is, or
91  // as many extents as the total rank is. In the latter case, the given
92  // extents for the static dimensions must match the
93  // compile-time extents.
94  constexpr int rank = View::rank();
95  constexpr int dyn_rank = View::rank_dynamic();
96  const bool n_args_is_dyn_rank = num_passed_args == dyn_rank;
97  const bool n_args_is_rank = num_passed_args == rank;
98 
99  if constexpr (rank != dyn_rank) {
100  if (n_args_is_rank) {
101  size_t new_extents[8] = {i0, i1, i2, i3, i4, i5, i6, i7};
102  for (int i = dyn_rank; i < rank; ++i)
103  if (new_extents[i] != View::static_extent(i)) {
104  KOKKOS_IF_ON_HOST(
105  const std::string message =
106  "The specified run-time extent for Kokkos::View '" +
107  std::string(label) +
108  "' does not match the compile-time extent in dimension " +
109  std::to_string(i) + ". The given extent is " +
110  std::to_string(new_extents[i]) + " but should be " +
111  std::to_string(View::static_extent(i)) + ".\n";
112  Kokkos::abort(message.c_str());)
113  KOKKOS_IF_ON_DEVICE(
114  Kokkos::abort(
115  "The specified run-time extents for a Kokkos::View "
116  "do not match the compile-time extents.");)
117  }
118  }
119  }
120 
121  if (!n_args_is_dyn_rank && !n_args_is_rank) {
122  KOKKOS_IF_ON_HOST(
123  const std::string message =
124  "Constructor for Kokkos::View '" + std::string(label) +
125  "' has mismatched number of arguments. The number "
126  "of arguments = " +
127  std::to_string(num_passed_args) +
128  " neither matches the dynamic rank = " +
129  std::to_string(dyn_rank) +
130  " nor the total rank = " + std::to_string(rank) + "\n";
131  Kokkos::abort(message.c_str());)
132  KOKKOS_IF_ON_DEVICE(Kokkos::abort("Constructor for Kokkos View has "
133  "mismatched number of arguments.");)
134  }
135  }
136 }
137 
138 } /* namespace Impl */
139 } /* namespace Kokkos */
140 
141 // Class to provide a uniform type
142 namespace Kokkos {
143 namespace Impl {
144 template <class ViewType, int Traits = 0>
145 struct ViewUniformType;
146 }
147 } // namespace Kokkos
148 
149 //----------------------------------------------------------------------------
150 //----------------------------------------------------------------------------
151 
152 namespace Kokkos {
153 
171 template <class DataType, class... Properties>
172 struct ViewTraits;
173 
174 template <>
175 struct ViewTraits<void> {
176  using execution_space = void;
177  using memory_space = void;
178  using HostMirrorSpace = void;
179  using array_layout = void;
180  using memory_traits = void;
181  using specialize = void;
182  using hooks_policy = void;
183 };
184 
185 template <class... Prop>
186 struct ViewTraits<void, void, Prop...> {
187  // Ignore an extraneous 'void'
188  using execution_space = typename ViewTraits<void, Prop...>::execution_space;
189  using memory_space = typename ViewTraits<void, Prop...>::memory_space;
190  using HostMirrorSpace = typename ViewTraits<void, Prop...>::HostMirrorSpace;
191  using array_layout = typename ViewTraits<void, Prop...>::array_layout;
192  using memory_traits = typename ViewTraits<void, Prop...>::memory_traits;
193  using specialize = typename ViewTraits<void, Prop...>::specialize;
194  using hooks_policy = typename ViewTraits<void, Prop...>::hooks_policy;
195 };
196 
197 template <class HooksPolicy, class... Prop>
198 struct ViewTraits<
199  std::enable_if_t<Kokkos::Experimental::is_hooks_policy<HooksPolicy>::value>,
200  HooksPolicy, Prop...> {
201  using execution_space = typename ViewTraits<void, Prop...>::execution_space;
202  using memory_space = typename ViewTraits<void, Prop...>::memory_space;
203  using HostMirrorSpace = typename ViewTraits<void, Prop...>::HostMirrorSpace;
204  using array_layout = typename ViewTraits<void, Prop...>::array_layout;
205  using memory_traits = typename ViewTraits<void, Prop...>::memory_traits;
206  using specialize = typename ViewTraits<void, Prop...>::specialize;
207  using hooks_policy = HooksPolicy;
208 };
209 
210 template <class ArrayLayout, class... Prop>
211 struct ViewTraits<std::enable_if_t<Kokkos::is_array_layout<ArrayLayout>::value>,
212  ArrayLayout, Prop...> {
213  // Specify layout, keep subsequent space and memory traits arguments
214 
215  using execution_space = typename ViewTraits<void, Prop...>::execution_space;
216  using memory_space = typename ViewTraits<void, Prop...>::memory_space;
217  using HostMirrorSpace = typename ViewTraits<void, Prop...>::HostMirrorSpace;
218  using array_layout = ArrayLayout;
219  using memory_traits = typename ViewTraits<void, Prop...>::memory_traits;
220  using specialize = typename ViewTraits<void, Prop...>::specialize;
221  using hooks_policy = typename ViewTraits<void, Prop...>::hooks_policy;
222 };
223 
224 template <class Space, class... Prop>
225 struct ViewTraits<std::enable_if_t<Kokkos::is_space<Space>::value>, Space,
226  Prop...> {
227  // Specify Space, memory traits should be the only subsequent argument.
228 
229  static_assert(
230  std::is_same<typename ViewTraits<void, Prop...>::execution_space,
231  void>::value &&
232  std::is_same<typename ViewTraits<void, Prop...>::memory_space,
233  void>::value &&
234  std::is_same<typename ViewTraits<void, Prop...>::HostMirrorSpace,
235  void>::value &&
236  std::is_same<typename ViewTraits<void, Prop...>::array_layout,
237  void>::value,
238  "Only one View Execution or Memory Space template argument");
239 
240  using execution_space = typename Space::execution_space;
241  using memory_space = typename Space::memory_space;
242  using HostMirrorSpace =
243  typename Kokkos::Impl::HostMirror<Space>::Space::memory_space;
244  using array_layout = typename execution_space::array_layout;
245  using memory_traits = typename ViewTraits<void, Prop...>::memory_traits;
246  using specialize = typename ViewTraits<void, Prop...>::specialize;
247  using hooks_policy = typename ViewTraits<void, Prop...>::hooks_policy;
248 };
249 
250 template <class MemoryTraits, class... Prop>
251 struct ViewTraits<
252  std::enable_if_t<Kokkos::is_memory_traits<MemoryTraits>::value>,
253  MemoryTraits, Prop...> {
254  // Specify memory trait, should not be any subsequent arguments
255 
256  static_assert(
257  std::is_same<typename ViewTraits<void, Prop...>::execution_space,
258  void>::value &&
259  std::is_same<typename ViewTraits<void, Prop...>::memory_space,
260  void>::value &&
261  std::is_same<typename ViewTraits<void, Prop...>::array_layout,
262  void>::value &&
263  std::is_same<typename ViewTraits<void, Prop...>::memory_traits,
264  void>::value &&
265  std::is_same<typename ViewTraits<void, Prop...>::hooks_policy,
266  void>::value,
267  "MemoryTrait is the final optional template argument for a View");
268 
269  using execution_space = void;
270  using memory_space = void;
271  using HostMirrorSpace = void;
272  using array_layout = void;
273  using memory_traits = MemoryTraits;
274  using specialize = void;
275  using hooks_policy = void;
276 };
277 
278 template <class DataType, class... Properties>
279 struct ViewTraits {
280  private:
281  // Unpack the properties arguments
282  using prop = ViewTraits<void, Properties...>;
283 
284  using ExecutionSpace =
285  std::conditional_t<!std::is_void<typename prop::execution_space>::value,
286  typename prop::execution_space,
287  Kokkos::DefaultExecutionSpace>;
288 
289  using MemorySpace =
290  std::conditional_t<!std::is_void<typename prop::memory_space>::value,
291  typename prop::memory_space,
292  typename ExecutionSpace::memory_space>;
293 
294  using ArrayLayout =
295  std::conditional_t<!std::is_void<typename prop::array_layout>::value,
296  typename prop::array_layout,
297  typename ExecutionSpace::array_layout>;
298 
299  using HostMirrorSpace = std::conditional_t<
300  !std::is_void<typename prop::HostMirrorSpace>::value,
301  typename prop::HostMirrorSpace,
302  typename Kokkos::Impl::HostMirror<ExecutionSpace>::Space>;
303 
304  using MemoryTraits =
305  std::conditional_t<!std::is_void<typename prop::memory_traits>::value,
306  typename prop::memory_traits,
307  typename Kokkos::MemoryManaged>;
308 
309  using HooksPolicy =
310  std::conditional_t<!std::is_void<typename prop::hooks_policy>::value,
311  typename prop::hooks_policy,
312  Kokkos::Experimental::DefaultViewHooks>;
313 
314  // Analyze data type's properties,
315  // May be specialized based upon the layout and value type
316  using data_analysis = Kokkos::Impl::ViewDataAnalysis<DataType, ArrayLayout>;
317 
318  public:
319  //------------------------------------
320  // Data type traits:
321 
322  using data_type = typename data_analysis::type;
323  using const_data_type = typename data_analysis::const_type;
324  using non_const_data_type = typename data_analysis::non_const_type;
325 
326  //------------------------------------
327  // Compatible array of trivial type traits:
328 
329  using scalar_array_type = typename data_analysis::scalar_array_type;
330  using const_scalar_array_type =
331  typename data_analysis::const_scalar_array_type;
332  using non_const_scalar_array_type =
333  typename data_analysis::non_const_scalar_array_type;
334 
335  //------------------------------------
336  // Value type traits:
337 
338  using value_type = typename data_analysis::value_type;
339  using const_value_type = typename data_analysis::const_value_type;
340  using non_const_value_type = typename data_analysis::non_const_value_type;
341 
342  //------------------------------------
343  // Mapping traits:
344 
345  using array_layout = ArrayLayout;
346  using dimension = typename data_analysis::dimension;
347 
348  using specialize = std::conditional_t<
349  std::is_void<typename data_analysis::specialize>::value,
350  typename prop::specialize,
351  typename data_analysis::specialize>; /* mapping specialization tag */
352 
353  static constexpr unsigned rank = dimension::rank;
354  static constexpr unsigned rank_dynamic = dimension::rank_dynamic;
355 
356  //------------------------------------
357  // Execution space, memory space, memory access traits, and host mirror space.
358 
359  using execution_space = ExecutionSpace;
360  using memory_space = MemorySpace;
361  using device_type = Kokkos::Device<ExecutionSpace, MemorySpace>;
362  using memory_traits = MemoryTraits;
363  using host_mirror_space = HostMirrorSpace;
364  using hooks_policy = HooksPolicy;
365 
366  using size_type = typename MemorySpace::size_type;
367 
368  enum { is_hostspace = std::is_same<MemorySpace, HostSpace>::value };
369  enum { is_managed = MemoryTraits::is_unmanaged == 0 };
370  enum { is_random_access = MemoryTraits::is_random_access == 1 };
371 
372  //------------------------------------
373 };
374 
459 } // namespace Kokkos
460 
461 namespace Kokkos {
462 
463 template <class T1, class T2>
464 struct is_always_assignable_impl;
465 
466 template <class... ViewTDst, class... ViewTSrc>
467 struct is_always_assignable_impl<Kokkos::View<ViewTDst...>,
468  Kokkos::View<ViewTSrc...>> {
469  using mapping_type = Kokkos::Impl::ViewMapping<
470  typename Kokkos::View<ViewTDst...>::traits,
471  typename Kokkos::View<ViewTSrc...>::traits,
472  typename Kokkos::View<ViewTDst...>::traits::specialize>;
473 
474  constexpr static bool value =
475  mapping_type::is_assignable &&
476  static_cast<int>(Kokkos::View<ViewTDst...>::rank_dynamic) >=
477  static_cast<int>(Kokkos::View<ViewTSrc...>::rank_dynamic);
478 };
479 
480 template <class View1, class View2>
481 using is_always_assignable = is_always_assignable_impl<
482  std::remove_reference_t<View1>,
483  std::remove_const_t<std::remove_reference_t<View2>>>;
484 
485 template <class T1, class T2>
486 inline constexpr bool is_always_assignable_v =
487  is_always_assignable<T1, T2>::value;
488 
489 template <class... ViewTDst, class... ViewTSrc>
490 constexpr bool is_assignable(const Kokkos::View<ViewTDst...>& dst,
491  const Kokkos::View<ViewTSrc...>& src) {
492  using DstTraits = typename Kokkos::View<ViewTDst...>::traits;
493  using SrcTraits = typename Kokkos::View<ViewTSrc...>::traits;
494  using mapping_type =
495  Kokkos::Impl::ViewMapping<DstTraits, SrcTraits,
496  typename DstTraits::specialize>;
497 
498  return is_always_assignable_v<Kokkos::View<ViewTDst...>,
499  Kokkos::View<ViewTSrc...>> ||
500  (mapping_type::is_assignable &&
501  ((DstTraits::dimension::rank_dynamic >= 1) ||
502  (dst.static_extent(0) == src.extent(0))) &&
503  ((DstTraits::dimension::rank_dynamic >= 2) ||
504  (dst.static_extent(1) == src.extent(1))) &&
505  ((DstTraits::dimension::rank_dynamic >= 3) ||
506  (dst.static_extent(2) == src.extent(2))) &&
507  ((DstTraits::dimension::rank_dynamic >= 4) ||
508  (dst.static_extent(3) == src.extent(3))) &&
509  ((DstTraits::dimension::rank_dynamic >= 5) ||
510  (dst.static_extent(4) == src.extent(4))) &&
511  ((DstTraits::dimension::rank_dynamic >= 6) ||
512  (dst.static_extent(5) == src.extent(5))) &&
513  ((DstTraits::dimension::rank_dynamic >= 7) ||
514  (dst.static_extent(6) == src.extent(6))) &&
515  ((DstTraits::dimension::rank_dynamic >= 8) ||
516  (dst.static_extent(7) == src.extent(7))));
517 }
518 
519 } /* namespace Kokkos */
520 
521 //----------------------------------------------------------------------------
522 //----------------------------------------------------------------------------
523 
524 #include <impl/Kokkos_ViewMapping.hpp>
525 #include <impl/Kokkos_ViewArray.hpp>
526 
527 //----------------------------------------------------------------------------
528 //----------------------------------------------------------------------------
529 
530 namespace Kokkos {
531 
532 // FIXME_OPENMPTARGET - The `declare target` is needed for the Intel GPUs with
533 // the OpenMPTarget backend
534 #if defined(KOKKOS_ENABLE_OPENMPTARGET) && defined(KOKKOS_COMPILER_INTEL_LLVM)
535 #pragma omp declare target
536 #endif
537 
538 inline constexpr Kokkos::ALL_t ALL{};
539 
540 #if defined(KOKKOS_ENABLE_OPENMPTARGET) && defined(KOKKOS_COMPILER_INTEL_LLVM)
541 #pragma omp end declare target
542 #endif
543 
544 inline constexpr Kokkos::Impl::WithoutInitializing_t WithoutInitializing{};
545 
546 inline constexpr Kokkos::Impl::AllowPadding_t AllowPadding{};
547 
558 template <class... Args>
559 inline Impl::ViewCtorProp<typename Impl::ViewCtorProp<void, Args>::type...>
560 view_alloc(Args const&... args) {
561  using return_type =
562  Impl::ViewCtorProp<typename Impl::ViewCtorProp<void, Args>::type...>;
563 
564  static_assert(!return_type::has_pointer,
565  "Cannot give pointer-to-memory for view allocation");
566 
567  return return_type(args...);
568 }
569 
570 template <class... Args>
571 KOKKOS_INLINE_FUNCTION
572  Impl::ViewCtorProp<typename Impl::ViewCtorProp<void, Args>::type...>
573  view_wrap(Args const&... args) {
574  using return_type =
575  Impl::ViewCtorProp<typename Impl::ViewCtorProp<void, Args>::type...>;
576 
577  static_assert(!return_type::has_memory_space &&
578  !return_type::has_execution_space &&
579  !return_type::has_label && return_type::has_pointer,
580  "Must only give pointer-to-memory for view wrapping");
581 
582  return return_type(args...);
583 }
584 
585 } /* namespace Kokkos */
586 
587 //----------------------------------------------------------------------------
588 //----------------------------------------------------------------------------
589 
590 namespace Kokkos {
591 
592 template <class DataType, class... Properties>
593 class View;
594 
595 template <class>
596 struct is_view : public std::false_type {};
597 
598 template <class D, class... P>
599 struct is_view<View<D, P...>> : public std::true_type {};
600 
601 template <class D, class... P>
602 struct is_view<const View<D, P...>> : public std::true_type {};
603 
604 template <class T>
605 inline constexpr bool is_view_v = is_view<T>::value;
606 
607 template <class DataType, class... Properties>
608 class View : public ViewTraits<DataType, Properties...> {
609  private:
610  template <class, class...>
611  friend class View;
612  template <class, class...>
613  friend class Kokkos::Impl::ViewMapping;
614 
615  using view_tracker_type = Kokkos::Impl::ViewTracker<View>;
616 
617  public:
618  using traits = ViewTraits<DataType, Properties...>;
619 
620  private:
621  using map_type =
622  Kokkos::Impl::ViewMapping<traits, typename traits::specialize>;
623  template <typename V>
624  friend struct Kokkos::Impl::ViewTracker;
625  using hooks_policy = typename traits::hooks_policy;
626 
627  view_tracker_type m_track;
628  map_type m_map;
629 
630  public:
631  //----------------------------------------
633  using array_type =
634  View<typename traits::scalar_array_type, typename traits::array_layout,
635  typename traits::device_type, typename traits::hooks_policy,
636  typename traits::memory_traits>;
637 
639  using const_type =
640  View<typename traits::const_data_type, typename traits::array_layout,
641  typename traits::device_type, typename traits::hooks_policy,
642  typename traits::memory_traits>;
643 
645  using non_const_type =
646  View<typename traits::non_const_data_type, typename traits::array_layout,
647  typename traits::device_type, typename traits::hooks_policy,
648  typename traits::memory_traits>;
649 
651  using HostMirror =
652  View<typename traits::non_const_data_type, typename traits::array_layout,
653  Device<DefaultHostExecutionSpace,
654  typename traits::host_mirror_space::memory_space>,
655  typename traits::hooks_policy>;
656 
658  using host_mirror_type =
659  View<typename traits::non_const_data_type, typename traits::array_layout,
660  typename traits::host_mirror_space, typename traits::hooks_policy>;
661 
663  using uniform_type = typename Impl::ViewUniformType<View, 0>::type;
664  using uniform_const_type =
665  typename Impl::ViewUniformType<View, 0>::const_type;
666  using uniform_runtime_type =
667  typename Impl::ViewUniformType<View, 0>::runtime_type;
668  using uniform_runtime_const_type =
669  typename Impl::ViewUniformType<View, 0>::runtime_const_type;
670  using uniform_nomemspace_type =
671  typename Impl::ViewUniformType<View, 0>::nomemspace_type;
672  using uniform_const_nomemspace_type =
673  typename Impl::ViewUniformType<View, 0>::const_nomemspace_type;
674  using uniform_runtime_nomemspace_type =
675  typename Impl::ViewUniformType<View, 0>::runtime_nomemspace_type;
676  using uniform_runtime_const_nomemspace_type =
677  typename Impl::ViewUniformType<View, 0>::runtime_const_nomemspace_type;
678 
679  //----------------------------------------
680  // Domain rank and extents
681 
682  static constexpr Impl::integral_constant<size_t, traits::dimension::rank>
683  rank = {};
684  static constexpr Impl::integral_constant<size_t,
685  traits::dimension::rank_dynamic>
686  rank_dynamic = {};
687 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
688  enum {Rank KOKKOS_DEPRECATED_WITH_COMMENT("Use rank instead.") =
689  map_type::Rank};
690 #endif
691 
692  template <typename iType>
693  KOKKOS_INLINE_FUNCTION constexpr std::enable_if_t<
694  std::is_integral<iType>::value, size_t>
695  extent(const iType& r) const noexcept {
696  return m_map.extent(r);
697  }
698 
699  static KOKKOS_INLINE_FUNCTION constexpr size_t static_extent(
700  const unsigned r) noexcept {
701  return map_type::static_extent(r);
702  }
703 
704  template <typename iType>
705  KOKKOS_INLINE_FUNCTION constexpr std::enable_if_t<
706  std::is_integral<iType>::value, int>
707  extent_int(const iType& r) const noexcept {
708  return static_cast<int>(m_map.extent(r));
709  }
710 
711  KOKKOS_INLINE_FUNCTION constexpr typename traits::array_layout layout()
712  const {
713  return m_map.layout();
714  }
715 
716  //----------------------------------------
717  /* Deprecate all 'dimension' functions in favor of
718  * ISO/C++ vocabulary 'extent'.
719  */
720 
721  KOKKOS_INLINE_FUNCTION constexpr size_t size() const {
722  return m_map.dimension_0() * m_map.dimension_1() * m_map.dimension_2() *
723  m_map.dimension_3() * m_map.dimension_4() * m_map.dimension_5() *
724  m_map.dimension_6() * m_map.dimension_7();
725  }
726 
727  KOKKOS_INLINE_FUNCTION constexpr size_t stride_0() const {
728  return m_map.stride_0();
729  }
730  KOKKOS_INLINE_FUNCTION constexpr size_t stride_1() const {
731  return m_map.stride_1();
732  }
733  KOKKOS_INLINE_FUNCTION constexpr size_t stride_2() const {
734  return m_map.stride_2();
735  }
736  KOKKOS_INLINE_FUNCTION constexpr size_t stride_3() const {
737  return m_map.stride_3();
738  }
739  KOKKOS_INLINE_FUNCTION constexpr size_t stride_4() const {
740  return m_map.stride_4();
741  }
742  KOKKOS_INLINE_FUNCTION constexpr size_t stride_5() const {
743  return m_map.stride_5();
744  }
745  KOKKOS_INLINE_FUNCTION constexpr size_t stride_6() const {
746  return m_map.stride_6();
747  }
748  KOKKOS_INLINE_FUNCTION constexpr size_t stride_7() const {
749  return m_map.stride_7();
750  }
751 
752  template <typename iType>
753  KOKKOS_INLINE_FUNCTION constexpr std::enable_if_t<
754  std::is_integral<iType>::value, size_t>
755  stride(iType r) const {
756  return (
757  r == 0
758  ? m_map.stride_0()
759  : (r == 1
760  ? m_map.stride_1()
761  : (r == 2
762  ? m_map.stride_2()
763  : (r == 3
764  ? m_map.stride_3()
765  : (r == 4
766  ? m_map.stride_4()
767  : (r == 5
768  ? m_map.stride_5()
769  : (r == 6
770  ? m_map.stride_6()
771  : m_map.stride_7())))))));
772  }
773 
774  template <typename iType>
775  KOKKOS_INLINE_FUNCTION void stride(iType* const s) const {
776  m_map.stride(s);
777  }
778 
779  //----------------------------------------
780  // Range span is the span which contains all members.
781 
782  using reference_type = typename map_type::reference_type;
783  using pointer_type = typename map_type::pointer_type;
784 
785  enum {
786  reference_type_is_lvalue_reference =
787  std::is_lvalue_reference<reference_type>::value
788  };
789 
790  KOKKOS_INLINE_FUNCTION constexpr size_t span() const { return m_map.span(); }
791  KOKKOS_INLINE_FUNCTION bool span_is_contiguous() const {
792  return m_map.span_is_contiguous();
793  }
794  KOKKOS_INLINE_FUNCTION constexpr bool is_allocated() const {
795  return m_map.data() != nullptr;
796  }
797  KOKKOS_INLINE_FUNCTION constexpr pointer_type data() const {
798  return m_map.data();
799  }
800 
801  //----------------------------------------
802  // Allow specializations to query their specialized map
803 
804  KOKKOS_INLINE_FUNCTION
805  const Kokkos::Impl::ViewMapping<traits, typename traits::specialize>&
806  impl_map() const {
807  return m_map;
808  }
809  KOKKOS_INLINE_FUNCTION
810  const Kokkos::Impl::SharedAllocationTracker& impl_track() const {
811  return m_track.m_tracker;
812  }
813  //----------------------------------------
814 
815  private:
816  static constexpr bool is_layout_left =
817  std::is_same<typename traits::array_layout, Kokkos::LayoutLeft>::value;
818 
819  static constexpr bool is_layout_right =
820  std::is_same<typename traits::array_layout, Kokkos::LayoutRight>::value;
821 
822  static constexpr bool is_layout_stride =
823  std::is_same<typename traits::array_layout, Kokkos::LayoutStride>::value;
824 
825  static constexpr bool is_default_map =
826  std::is_void<typename traits::specialize>::value &&
827  (is_layout_left || is_layout_right || is_layout_stride);
828 
829 #if defined(KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK)
830 
831 #define KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(...) \
832  Kokkos::Impl::runtime_check_memory_access_violation< \
833  typename traits::memory_space>( \
834  "Kokkos::View ERROR: attempt to access inaccessible memory space", \
835  __VA_ARGS__); \
836  Kokkos::Impl::view_verify_operator_bounds<typename traits::memory_space>( \
837  __VA_ARGS__);
838 
839 #else
840 
841 #define KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(...) \
842  Kokkos::Impl::runtime_check_memory_access_violation< \
843  typename traits::memory_space>( \
844  "Kokkos::View ERROR: attempt to access inaccessible memory space", \
845  __VA_ARGS__);
846 
847 #endif
848 
849  template <typename... Is>
850  static KOKKOS_FUNCTION void check_access_member_function_valid_args(Is...) {
851  static_assert(rank <= sizeof...(Is));
852  static_assert(sizeof...(Is) <= 8);
853  static_assert(Kokkos::Impl::are_integral<Is...>::value);
854  }
855 
856  template <typename... Is>
857  static KOKKOS_FUNCTION void check_operator_parens_valid_args(Is...) {
858  static_assert(rank == sizeof...(Is));
859  static_assert(Kokkos::Impl::are_integral<Is...>::value);
860  }
861 
862  public:
863  //------------------------------
864  // Rank 1 default map operator()
865 
866  template <typename I0>
867  KOKKOS_FORCEINLINE_FUNCTION
868  std::enable_if_t<(Kokkos::Impl::always_true<I0>::value && //
869  (1 == rank) && is_default_map && !is_layout_stride),
870  reference_type>
871  operator()(I0 i0) const {
872  check_operator_parens_valid_args(i0);
873  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0)
874  return m_map.m_impl_handle[i0];
875  }
876 
877  template <typename I0>
878  KOKKOS_FORCEINLINE_FUNCTION
879  std::enable_if_t<(Kokkos::Impl::always_true<I0>::value && //
880  (1 == rank) && is_default_map && is_layout_stride),
881  reference_type>
882  operator()(I0 i0) const {
883  check_operator_parens_valid_args(i0);
884  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0)
885  return m_map.m_impl_handle[m_map.m_impl_offset.m_stride.S0 * i0];
886  }
887 
888  //------------------------------
889  // Rank 1 operator[]
890 
891  template <typename I0>
892  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
893  ((1 == rank) && Kokkos::Impl::are_integral<I0>::value && !is_default_map),
894  reference_type>
895  operator[](I0 i0) const {
896  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0)
897  return m_map.reference(i0);
898  }
899 
900  template <typename I0>
901  KOKKOS_FORCEINLINE_FUNCTION
902  std::enable_if_t<((1 == rank) && Kokkos::Impl::are_integral<I0>::value &&
903  is_default_map && !is_layout_stride),
904  reference_type>
905  operator[](I0 i0) const {
906  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0)
907  return m_map.m_impl_handle[i0];
908  }
909 
910  template <typename I0>
911  KOKKOS_FORCEINLINE_FUNCTION
912  std::enable_if_t<((1 == rank) && Kokkos::Impl::are_integral<I0>::value &&
913  is_default_map && is_layout_stride),
914  reference_type>
915  operator[](I0 i0) const {
916  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0)
917  return m_map.m_impl_handle[m_map.m_impl_offset.m_stride.S0 * i0];
918  }
919 
920  //------------------------------
921  // Rank 2 default map operator()
922 
923  template <typename I0, typename I1>
924  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
925  (Kokkos::Impl::always_true<I0, I1>::value && //
926  (2 == rank) && is_default_map && is_layout_left && (rank_dynamic == 0)),
927  reference_type>
928  operator()(I0 i0, I1 i1) const {
929  check_operator_parens_valid_args(i0, i1);
930  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1)
931  return m_map.m_impl_handle[i0 + m_map.m_impl_offset.m_dim.N0 * i1];
932  }
933 
934  template <typename I0, typename I1>
935  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
936  (Kokkos::Impl::always_true<I0, I1>::value && //
937  (2 == rank) && is_default_map && is_layout_left && (rank_dynamic != 0)),
938  reference_type>
939  operator()(I0 i0, I1 i1) const {
940  check_operator_parens_valid_args(i0, i1);
941  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1)
942  return m_map.m_impl_handle[i0 + m_map.m_impl_offset.m_stride * i1];
943  }
944 
945  template <typename I0, typename I1>
946  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
947  (Kokkos::Impl::always_true<I0, I1>::value && //
948  (2 == rank) && is_default_map && is_layout_right && (rank_dynamic == 0)),
949  reference_type>
950  operator()(I0 i0, I1 i1) const {
951  check_operator_parens_valid_args(i0, i1);
952  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1)
953  return m_map.m_impl_handle[i1 + m_map.m_impl_offset.m_dim.N1 * i0];
954  }
955 
956  template <typename I0, typename I1>
957  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
958  (Kokkos::Impl::always_true<I0, I1>::value && //
959  (2 == rank) && is_default_map && is_layout_right && (rank_dynamic != 0)),
960  reference_type>
961  operator()(I0 i0, I1 i1) const {
962  check_operator_parens_valid_args(i0, i1);
963  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1)
964  return m_map.m_impl_handle[i1 + m_map.m_impl_offset.m_stride * i0];
965  }
966 
967  template <typename I0, typename I1>
968  KOKKOS_FORCEINLINE_FUNCTION
969  std::enable_if_t<(Kokkos::Impl::always_true<I0, I1>::value && //
970  (2 == rank) && is_default_map && is_layout_stride),
971  reference_type>
972  operator()(I0 i0, I1 i1) const {
973  check_operator_parens_valid_args(i0, i1);
974  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1)
975  return m_map.m_impl_handle[i0 * m_map.m_impl_offset.m_stride.S0 +
976  i1 * m_map.m_impl_offset.m_stride.S1];
977  }
978 
979  // Rank 0 -> 8 operator() except for rank-1 and rank-2 with default map which
980  // have "inlined" versions above
981 
982  template <typename... Is>
983  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
984  (Kokkos::Impl::always_true<Is...>::value && //
985  (2 != rank) && (1 != rank) && (0 != rank) && is_default_map),
986  reference_type>
987  operator()(Is... indices) const {
988  check_operator_parens_valid_args(indices...);
989  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, indices...)
990  return m_map.m_impl_handle[m_map.m_impl_offset(indices...)];
991  }
992 
993  template <typename... Is>
994  KOKKOS_FORCEINLINE_FUNCTION
995  std::enable_if_t<(Kokkos::Impl::always_true<Is...>::value && //
996  ((0 == rank) || !is_default_map)),
997  reference_type>
998  operator()(Is... indices) const {
999  check_operator_parens_valid_args(indices...);
1000  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, indices...)
1001  return m_map.reference(indices...);
1002  }
1003 
1004  //------------------------------
1005  // Rank 0
1006 
1007  template <typename... Is>
1008  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1009  (Kokkos::Impl::always_true<Is...>::value && (0 == rank)), reference_type>
1010  access(Is... extra) const {
1011  check_access_member_function_valid_args(extra...);
1012  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, extra...)
1013  return m_map.reference();
1014  }
1015 
1016  //------------------------------
1017  // Rank 1
1018 
1019  template <typename I0, typename... Is>
1020  KOKKOS_FORCEINLINE_FUNCTION
1021  std::enable_if_t<(Kokkos::Impl::always_true<I0, Is...>::value &&
1022  (1 == rank) && !is_default_map),
1023  reference_type>
1024  access(I0 i0, Is... extra) const {
1025  check_access_member_function_valid_args(i0, extra...);
1026  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, extra...)
1027  return m_map.reference(i0);
1028  }
1029 
1030  template <typename I0, typename... Is>
1031  KOKKOS_FORCEINLINE_FUNCTION
1032  std::enable_if_t<(Kokkos::Impl::always_true<I0, Is...>::value &&
1033  (1 == rank) && is_default_map && !is_layout_stride),
1034  reference_type>
1035  access(I0 i0, Is... extra) const {
1036  check_access_member_function_valid_args(i0, extra...);
1037  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, extra...)
1038  return m_map.m_impl_handle[i0];
1039  }
1040 
1041  template <typename I0, typename... Is>
1042  KOKKOS_FORCEINLINE_FUNCTION
1043  std::enable_if_t<(Kokkos::Impl::always_true<I0, Is...>::value &&
1044  (1 == rank) && is_default_map && is_layout_stride),
1045  reference_type>
1046  access(I0 i0, Is... extra) const {
1047  check_access_member_function_valid_args(i0, extra...);
1048  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, extra...)
1049  return m_map.m_impl_handle[m_map.m_impl_offset.m_stride.S0 * i0];
1050  }
1051 
1052  //------------------------------
1053  // Rank 2
1054 
1055  template <typename I0, typename I1, typename... Is>
1056  KOKKOS_FORCEINLINE_FUNCTION
1057  std::enable_if_t<(Kokkos::Impl::always_true<I0, I1, Is...>::value &&
1058  (2 == rank) && !is_default_map),
1059  reference_type>
1060  access(I0 i0, I1 i1, Is... extra) const {
1061  check_access_member_function_valid_args(i0, i1, extra...);
1062  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, extra...)
1063  return m_map.reference(i0, i1);
1064  }
1065 
1066  template <typename I0, typename I1, typename... Is>
1067  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1068  (Kokkos::Impl::always_true<I0, I1, Is...>::value && (2 == rank) &&
1069  is_default_map && is_layout_left && (rank_dynamic == 0)),
1070  reference_type>
1071  access(I0 i0, I1 i1, Is... extra) const {
1072  check_access_member_function_valid_args(i0, i1, extra...);
1073  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, extra...)
1074  return m_map.m_impl_handle[i0 + m_map.m_impl_offset.m_dim.N0 * i1];
1075  }
1076 
1077  template <typename I0, typename I1, typename... Is>
1078  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1079  (Kokkos::Impl::always_true<I0, I1, Is...>::value && (2 == rank) &&
1080  is_default_map && is_layout_left && (rank_dynamic != 0)),
1081  reference_type>
1082  access(I0 i0, I1 i1, Is... extra) const {
1083  check_access_member_function_valid_args(i0, i1, extra...);
1084  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, extra...)
1085  return m_map.m_impl_handle[i0 + m_map.m_impl_offset.m_stride * i1];
1086  }
1087 
1088  template <typename I0, typename I1, typename... Is>
1089  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1090  (Kokkos::Impl::always_true<I0, I1, Is...>::value && (2 == rank) &&
1091  is_default_map && is_layout_right && (rank_dynamic == 0)),
1092  reference_type>
1093  access(I0 i0, I1 i1, Is... extra) const {
1094  check_access_member_function_valid_args(i0, i1, extra...);
1095  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, extra...)
1096  return m_map.m_impl_handle[i1 + m_map.m_impl_offset.m_dim.N1 * i0];
1097  }
1098 
1099  template <typename I0, typename I1, typename... Is>
1100  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1101  (Kokkos::Impl::always_true<I0, I1, Is...>::value && (2 == rank) &&
1102  is_default_map && is_layout_right && (rank_dynamic != 0)),
1103  reference_type>
1104  access(I0 i0, I1 i1, Is... extra) const {
1105  check_access_member_function_valid_args(i0, i1, extra...);
1106  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, extra...)
1107  return m_map.m_impl_handle[i1 + m_map.m_impl_offset.m_stride * i0];
1108  }
1109 
1110  template <typename I0, typename I1, typename... Is>
1111  KOKKOS_FORCEINLINE_FUNCTION
1112  std::enable_if_t<(Kokkos::Impl::always_true<I0, I1, Is...>::value &&
1113  (2 == rank) && is_default_map && is_layout_stride),
1114  reference_type>
1115  access(I0 i0, I1 i1, Is... extra) const {
1116  check_access_member_function_valid_args(i0, i1, extra...);
1117  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, extra...)
1118  return m_map.m_impl_handle[i0 * m_map.m_impl_offset.m_stride.S0 +
1119  i1 * m_map.m_impl_offset.m_stride.S1];
1120  }
1121 
1122  //------------------------------
1123  // Rank 3
1124 
1125  template <typename I0, typename I1, typename I2, typename... Is>
1126  KOKKOS_FORCEINLINE_FUNCTION
1127  std::enable_if_t<(Kokkos::Impl::always_true<I0, I1, I2, Is...>::value &&
1128  (3 == rank) && is_default_map),
1129  reference_type>
1130  access(I0 i0, I1 i1, I2 i2, Is... extra) const {
1131  check_access_member_function_valid_args(i0, i1, i2, extra...);
1132  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, extra...)
1133  return m_map.m_impl_handle[m_map.m_impl_offset(i0, i1, i2)];
1134  }
1135 
1136  template <typename I0, typename I1, typename I2, typename... Is>
1137  KOKKOS_FORCEINLINE_FUNCTION
1138  std::enable_if_t<(Kokkos::Impl::always_true<I0, I1, I2, Is...>::value &&
1139  (3 == rank) && !is_default_map),
1140  reference_type>
1141  access(I0 i0, I1 i1, I2 i2, Is... extra) const {
1142  check_access_member_function_valid_args(i0, i1, i2, extra...);
1143  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, extra...)
1144  return m_map.reference(i0, i1, i2);
1145  }
1146 
1147  //------------------------------
1148  // Rank 4
1149 
1150  template <typename I0, typename I1, typename I2, typename I3, typename... Is>
1151  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1152  (Kokkos::Impl::always_true<I0, I1, I2, I3, Is...>::value && (4 == rank) &&
1153  is_default_map),
1154  reference_type>
1155  access(I0 i0, I1 i1, I2 i2, I3 i3, Is... extra) const {
1156  check_access_member_function_valid_args(i0, i1, i2, i3, extra...);
1157  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, i3, extra...)
1158  return m_map.m_impl_handle[m_map.m_impl_offset(i0, i1, i2, i3)];
1159  }
1160 
1161  template <typename I0, typename I1, typename I2, typename I3, typename... Is>
1162  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1163  (Kokkos::Impl::always_true<I0, I1, I2, I3, Is...>::value && (4 == rank) &&
1164  !is_default_map),
1165  reference_type>
1166  access(I0 i0, I1 i1, I2 i2, I3 i3, Is... extra) const {
1167  check_access_member_function_valid_args(i0, i1, i2, i3, extra...);
1168  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, i3, extra...)
1169  return m_map.reference(i0, i1, i2, i3);
1170  }
1171 
1172  //------------------------------
1173  // Rank 5
1174 
1175  template <typename I0, typename I1, typename I2, typename I3, typename I4,
1176  typename... Is>
1177  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1178  (Kokkos::Impl::always_true<I0, I1, I2, I3, I4, Is...>::value &&
1179  (5 == rank) && is_default_map),
1180  reference_type>
1181  access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, Is... extra) const {
1182  check_access_member_function_valid_args(i0, i1, i2, i3, i4, extra...);
1183  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, i3, i4,
1184  extra...)
1185  return m_map.m_impl_handle[m_map.m_impl_offset(i0, i1, i2, i3, i4)];
1186  }
1187 
1188  template <typename I0, typename I1, typename I2, typename I3, typename I4,
1189  typename... Is>
1190  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1191  (Kokkos::Impl::always_true<I0, I1, I2, I3, I4, Is...>::value &&
1192  (5 == rank) && !is_default_map),
1193  reference_type>
1194  access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, Is... extra) const {
1195  check_access_member_function_valid_args(i0, i1, i2, i3, i4, extra...);
1196  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, i3, i4,
1197  extra...)
1198  return m_map.reference(i0, i1, i2, i3, i4);
1199  }
1200 
1201  //------------------------------
1202  // Rank 6
1203 
1204  template <typename I0, typename I1, typename I2, typename I3, typename I4,
1205  typename I5, typename... Is>
1206  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1207  (Kokkos::Impl::always_true<I0, I1, I2, I3, I4, I5, Is...>::value &&
1208  (6 == rank) && is_default_map),
1209  reference_type>
1210  access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, I5 i5, Is... extra) const {
1211  check_access_member_function_valid_args(i0, i1, i2, i3, i4, i5, extra...);
1212  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, i3, i4, i5,
1213  extra...)
1214  return m_map.m_impl_handle[m_map.m_impl_offset(i0, i1, i2, i3, i4, i5)];
1215  }
1216 
1217  template <typename I0, typename I1, typename I2, typename I3, typename I4,
1218  typename I5, typename... Is>
1219  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1220  (Kokkos::Impl::always_true<I0, I1, I2, I3, I4, I5, Is...>::value &&
1221  (6 == rank) && !is_default_map),
1222  reference_type>
1223  access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, I5 i5, Is... extra) const {
1224  check_access_member_function_valid_args(i0, i1, i2, i3, i4, i5, extra...);
1225  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, i3, i4, i5,
1226  extra...)
1227  return m_map.reference(i0, i1, i2, i3, i4, i5);
1228  }
1229 
1230  //------------------------------
1231  // Rank 7
1232 
1233  template <typename I0, typename I1, typename I2, typename I3, typename I4,
1234  typename I5, typename I6, typename... Is>
1235  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1236  (Kokkos::Impl::always_true<I0, I1, I2, I3, I4, I5, I6, Is...>::value &&
1237  (7 == rank) && is_default_map),
1238  reference_type>
1239  access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, I5 i5, I6 i6, Is... extra) const {
1240  check_access_member_function_valid_args(i0, i1, i2, i3, i4, i5, i6,
1241  extra...);
1242  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, i3, i4, i5, i6,
1243  extra...)
1244  return m_map.m_impl_handle[m_map.m_impl_offset(i0, i1, i2, i3, i4, i5, i6)];
1245  }
1246 
1247  template <typename I0, typename I1, typename I2, typename I3, typename I4,
1248  typename I5, typename I6, typename... Is>
1249  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
1250  (Kokkos::Impl::always_true<I0, I1, I2, I3, I4, I5, I6, Is...>::value &&
1251  (7 == rank) && !is_default_map),
1252  reference_type>
1253  access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, I5 i5, I6 i6, Is... extra) const {
1254  check_access_member_function_valid_args(i0, i1, i2, i3, i4, i5, i6,
1255  extra...);
1256  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, i3, i4, i5, i6,
1257  extra...)
1258  return m_map.reference(i0, i1, i2, i3, i4, i5, i6);
1259  }
1260 
1261  //------------------------------
1262  // Rank 8
1263 
1264  template <typename I0, typename I1, typename I2, typename I3, typename I4,
1265  typename I5, typename I6, typename I7, typename... Is>
1266  KOKKOS_FORCEINLINE_FUNCTION
1267  std::enable_if_t<(Kokkos::Impl::always_true<I0, I1, I2, I3, I4, I5, I6,
1268  I7, Is...>::value &&
1269  (8 == rank) && is_default_map),
1270  reference_type>
1271  access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, I5 i5, I6 i6, I7 i7,
1272  Is... extra) const {
1273  check_access_member_function_valid_args(i0, i1, i2, i3, i4, i5, i6, i7,
1274  extra...);
1275  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, i3, i4, i5, i6,
1276  i7, extra...)
1277  return m_map
1278  .m_impl_handle[m_map.m_impl_offset(i0, i1, i2, i3, i4, i5, i6, i7)];
1279  }
1280 
1281  template <typename I0, typename I1, typename I2, typename I3, typename I4,
1282  typename I5, typename I6, typename I7, typename... Is>
1283  KOKKOS_FORCEINLINE_FUNCTION
1284  std::enable_if_t<(Kokkos::Impl::always_true<I0, I1, I2, I3, I4, I5, I6,
1285  I7, Is...>::value &&
1286  (8 == rank) && !is_default_map),
1287  reference_type>
1288  access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, I5 i5, I6 i6, I7 i7,
1289  Is... extra) const {
1290  check_access_member_function_valid_args(i0, i1, i2, i3, i4, i5, i6, i7,
1291  extra...);
1292  KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(m_track, m_map, i0, i1, i2, i3, i4, i5, i6,
1293  i7, extra...)
1294  return m_map.reference(i0, i1, i2, i3, i4, i5, i6, i7);
1295  }
1296 
1297 #undef KOKKOS_IMPL_VIEW_OPERATOR_VERIFY
1298 
1299  //----------------------------------------
1300  // Standard destructor, constructors, and assignment operators
1301 
1302  KOKKOS_DEFAULTED_FUNCTION
1303  ~View() = default;
1304 
1305  KOKKOS_DEFAULTED_FUNCTION
1306  View() = default;
1307 
1308  KOKKOS_FUNCTION
1309  View(const View& other) : m_track(other.m_track), m_map(other.m_map) {
1310  KOKKOS_IF_ON_HOST((hooks_policy::copy_construct(*this, other);))
1311  }
1312 
1313  KOKKOS_FUNCTION
1314  View(View&& other)
1315  : m_track{std::move(other.m_track)}, m_map{std::move(other.m_map)} {
1316  KOKKOS_IF_ON_HOST((hooks_policy::move_construct(*this, other);))
1317  }
1318 
1319  KOKKOS_FUNCTION
1320  View& operator=(const View& other) {
1321  m_map = other.m_map;
1322  m_track = other.m_track;
1323 
1324  KOKKOS_IF_ON_HOST((hooks_policy::copy_assign(*this, other);))
1325 
1326  return *this;
1327  }
1328 
1329  KOKKOS_FUNCTION
1330  View& operator=(View&& other) {
1331  m_map = std::move(other.m_map);
1332  m_track = std::move(other.m_track);
1333 
1334  KOKKOS_IF_ON_HOST((hooks_policy::move_assign(*this, other);))
1335 
1336  return *this;
1337  }
1338 
1339  //----------------------------------------
1340  // Compatible view copy constructor and assignment
1341  // may assign unmanaged from managed.
1342 
1343  template <class RT, class... RP>
1344  KOKKOS_INLINE_FUNCTION View(
1345  const View<RT, RP...>& rhs,
1346  std::enable_if_t<Kokkos::Impl::ViewMapping<
1347  traits, typename View<RT, RP...>::traits,
1348  typename traits::specialize>::is_assignable_data_type>* = nullptr)
1349  : m_track(rhs), m_map() {
1350  using SrcTraits = typename View<RT, RP...>::traits;
1351  using Mapping = Kokkos::Impl::ViewMapping<traits, SrcTraits,
1352  typename traits::specialize>;
1353  static_assert(Mapping::is_assignable,
1354  "Incompatible View copy construction");
1355  Mapping::assign(m_map, rhs.m_map, rhs.m_track.m_tracker);
1356  }
1357 
1358  template <class RT, class... RP>
1359  KOKKOS_INLINE_FUNCTION std::enable_if_t<
1360  Kokkos::Impl::ViewMapping<
1361  traits, typename View<RT, RP...>::traits,
1362  typename traits::specialize>::is_assignable_data_type,
1363  View>&
1364  operator=(const View<RT, RP...>& rhs) {
1365  using SrcTraits = typename View<RT, RP...>::traits;
1366  using Mapping = Kokkos::Impl::ViewMapping<traits, SrcTraits,
1367  typename traits::specialize>;
1368  static_assert(Mapping::is_assignable, "Incompatible View copy assignment");
1369  Mapping::assign(m_map, rhs.m_map, rhs.m_track.m_tracker);
1370  m_track.assign(rhs);
1371  return *this;
1372  }
1373 
1374  //----------------------------------------
1375  // Compatible subview constructor
1376  // may assign unmanaged from managed.
1377 
1378  template <class RT, class... RP, class Arg0, class... Args>
1379  KOKKOS_INLINE_FUNCTION View(const View<RT, RP...>& src_view, const Arg0 arg0,
1380  Args... args)
1381  : m_track(src_view), m_map() {
1382  using SrcType = View<RT, RP...>;
1383 
1384  using Mapping = Kokkos::Impl::ViewMapping<void, typename SrcType::traits,
1385  Arg0, Args...>;
1386 
1387  using DstType = typename Mapping::type;
1388 
1389  static_assert(
1390  Kokkos::Impl::ViewMapping<traits, typename DstType::traits,
1391  typename traits::specialize>::is_assignable,
1392  "Subview construction requires compatible view and subview arguments");
1393 
1394  Mapping::assign(m_map, src_view.m_map, arg0, args...);
1395  }
1396 
1397  //----------------------------------------
1398  // Allocation tracking properties
1399 
1400  KOKKOS_INLINE_FUNCTION
1401  int use_count() const { return m_track.m_tracker.use_count(); }
1402 
1403  inline const std::string label() const {
1404  return m_track.m_tracker
1405  .template get_label<typename traits::memory_space>();
1406  }
1407 
1408  public:
1409  //----------------------------------------
1410  // Allocation according to allocation properties and array layout
1411 
1412  template <class... P>
1413  explicit inline View(
1414  const Impl::ViewCtorProp<P...>& arg_prop,
1415  std::enable_if_t<!Impl::ViewCtorProp<P...>::has_pointer,
1416  typename traits::array_layout> const& arg_layout)
1417  : m_track(), m_map() {
1418  // Copy the input allocation properties with possibly defaulted properties
1419  // We need to split it in two to avoid MSVC compiler errors
1420  auto prop_copy_tmp =
1421  Impl::with_properties_if_unset(arg_prop, std::string{});
1422  auto prop_copy = Impl::with_properties_if_unset(
1423  prop_copy_tmp, typename traits::device_type::memory_space{},
1424  typename traits::device_type::execution_space{});
1425  using alloc_prop = decltype(prop_copy);
1426 
1427  static_assert(traits::is_managed,
1428  "View allocation constructor requires managed memory");
1429 
1430  if (alloc_prop::initialize &&
1431  !alloc_prop::execution_space::impl_is_initialized()) {
1432  // If initializing view data then
1433  // the execution space must be initialized.
1434  Kokkos::Impl::throw_runtime_exception(
1435  "Constructing View and initializing data with uninitialized "
1436  "execution space");
1437  }
1438 
1439 #ifdef KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK
1440  if constexpr (std::is_same_v<typename traits::array_layout,
1441  Kokkos::LayoutLeft> ||
1442  std::is_same_v<typename traits::array_layout,
1444  std::is_same_v<typename traits::array_layout,
1446  is_layouttiled<typename traits::array_layout>::value) {
1447  size_t i0 = arg_layout.dimension[0];
1448  size_t i1 = arg_layout.dimension[1];
1449  size_t i2 = arg_layout.dimension[2];
1450  size_t i3 = arg_layout.dimension[3];
1451  size_t i4 = arg_layout.dimension[4];
1452  size_t i5 = arg_layout.dimension[5];
1453  size_t i6 = arg_layout.dimension[6];
1454  size_t i7 = arg_layout.dimension[7];
1455 
1456  const std::string& alloc_name =
1457  Impl::get_property<Impl::LabelTag>(prop_copy);
1458  Impl::runtime_check_rank(
1459  *this, std::is_same<typename traits::specialize, void>::value, i0, i1,
1460  i2, i3, i4, i5, i6, i7, alloc_name.c_str());
1461  }
1462 #endif
1463 
1464  Kokkos::Impl::SharedAllocationRecord<>* record = m_map.allocate_shared(
1465  prop_copy, arg_layout, Impl::ViewCtorProp<P...>::has_execution_space);
1466 
1467  // Setup and initialization complete, start tracking
1468  m_track.m_tracker.assign_allocated_record_to_uninitialized(record);
1469  }
1470 
1471  KOKKOS_INLINE_FUNCTION
1472  void assign_data(pointer_type arg_data) {
1473  m_track.m_tracker.clear();
1474  m_map.assign_data(arg_data);
1475  }
1476 
1477  // Wrap memory according to properties and array layout
1478  template <class... P>
1479  explicit KOKKOS_INLINE_FUNCTION View(
1480  const Impl::ViewCtorProp<P...>& arg_prop,
1481  std::enable_if_t<Impl::ViewCtorProp<P...>::has_pointer,
1482  typename traits::array_layout> const& arg_layout)
1483  : m_track() // No memory tracking
1484  ,
1485  m_map(arg_prop, arg_layout) {
1486  static_assert(
1487  std::is_same<pointer_type,
1488  typename Impl::ViewCtorProp<P...>::pointer_type>::value,
1489  "Constructing View to wrap user memory must supply matching pointer "
1490  "type");
1491 
1492 #ifdef KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK
1493  if constexpr (std::is_same_v<typename traits::array_layout,
1494  Kokkos::LayoutLeft> ||
1495  std::is_same_v<typename traits::array_layout,
1497  std::is_same_v<typename traits::array_layout,
1499  is_layouttiled<typename traits::array_layout>::value) {
1500  size_t i0 = arg_layout.dimension[0];
1501  size_t i1 = arg_layout.dimension[1];
1502  size_t i2 = arg_layout.dimension[2];
1503  size_t i3 = arg_layout.dimension[3];
1504  size_t i4 = arg_layout.dimension[4];
1505  size_t i5 = arg_layout.dimension[5];
1506  size_t i6 = arg_layout.dimension[6];
1507  size_t i7 = arg_layout.dimension[7];
1508 
1509  Impl::runtime_check_rank(
1510  *this, std::is_same<typename traits::specialize, void>::value, i0, i1,
1511  i2, i3, i4, i5, i6, i7, "UNMANAGED");
1512  }
1513 #endif
1514  }
1515 
1516  // Simple dimension-only layout
1517  template <class... P>
1518  explicit inline View(
1519  const Impl::ViewCtorProp<P...>& arg_prop,
1520  std::enable_if_t<!Impl::ViewCtorProp<P...>::has_pointer, size_t> const
1521  arg_N0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1522  const size_t arg_N1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1523  const size_t arg_N2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1524  const size_t arg_N3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1525  const size_t arg_N4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1526  const size_t arg_N5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1527  const size_t arg_N6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1528  const size_t arg_N7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
1529  : View(arg_prop,
1530  typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3,
1531  arg_N4, arg_N5, arg_N6, arg_N7)) {
1532  static_assert(traits::array_layout::is_extent_constructible,
1533  "Layout is not constructible from extent arguments. Use "
1534  "overload taking a layout object instead.");
1535  }
1536 
1537  template <class... P>
1538  explicit KOKKOS_INLINE_FUNCTION View(
1539  const Impl::ViewCtorProp<P...>& arg_prop,
1540  std::enable_if_t<Impl::ViewCtorProp<P...>::has_pointer, size_t> const
1541  arg_N0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1542  const size_t arg_N1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1543  const size_t arg_N2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1544  const size_t arg_N3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1545  const size_t arg_N4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1546  const size_t arg_N5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1547  const size_t arg_N6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1548  const size_t arg_N7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
1549  : View(arg_prop,
1550  typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3,
1551  arg_N4, arg_N5, arg_N6, arg_N7)) {
1552  static_assert(traits::array_layout::is_extent_constructible,
1553  "Layout is not constructible from extent arguments. Use "
1554  "overload taking a layout object instead.");
1555  }
1556 
1557  // Allocate with label and layout
1558  template <typename Label>
1559  explicit inline View(
1560  const Label& arg_label,
1561  std::enable_if_t<Kokkos::Impl::is_view_label<Label>::value,
1562  typename traits::array_layout> const& arg_layout)
1563  : View(Impl::ViewCtorProp<std::string>(arg_label), arg_layout) {}
1564 
1565  // Allocate label and layout, must disambiguate from subview constructor.
1566  template <typename Label>
1567  explicit inline View(
1568  const Label& arg_label,
1569  std::enable_if_t<Kokkos::Impl::is_view_label<Label>::value, const size_t>
1570  arg_N0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1571  const size_t arg_N1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1572  const size_t arg_N2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1573  const size_t arg_N3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1574  const size_t arg_N4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1575  const size_t arg_N5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1576  const size_t arg_N6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1577  const size_t arg_N7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
1578  : View(Impl::ViewCtorProp<std::string>(arg_label),
1579  typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3,
1580  arg_N4, arg_N5, arg_N6, arg_N7)) {
1581  static_assert(traits::array_layout::is_extent_constructible,
1582  "Layout is not constructible from extent arguments. Use "
1583  "overload taking a layout object instead.");
1584  }
1585 
1586  // Construct view from ViewTracker and map
1587  // This should be the preferred method because future extensions may need to
1588  // use the ViewTracker class.
1589  template <class Traits>
1590  KOKKOS_INLINE_FUNCTION View(
1591  const view_tracker_type& track,
1592  const Kokkos::Impl::ViewMapping<Traits, typename Traits::specialize>& map)
1593  : m_track(track), m_map() {
1594  using Mapping =
1595  Kokkos::Impl::ViewMapping<traits, Traits, typename traits::specialize>;
1596  static_assert(Mapping::is_assignable,
1597  "Incompatible View copy construction");
1598  Mapping::assign(m_map, map, track.m_tracker);
1599  }
1600 
1601  // Construct View from internal shared allocation tracker object and map
1602  // This is here for backwards compatibility for classes that derive from
1603  // Kokkos::View
1604  template <class Traits>
1605  KOKKOS_INLINE_FUNCTION View(
1606  const typename view_tracker_type::track_type& track,
1607  const Kokkos::Impl::ViewMapping<Traits, typename Traits::specialize>& map)
1608  : m_track(track), m_map() {
1609  using Mapping =
1610  Kokkos::Impl::ViewMapping<traits, Traits, typename traits::specialize>;
1611  static_assert(Mapping::is_assignable,
1612  "Incompatible View copy construction");
1613  Mapping::assign(m_map, map, track);
1614  }
1615 
1616  //----------------------------------------
1617  // Memory span required to wrap these dimensions.
1618  static constexpr size_t required_allocation_size(
1619  typename traits::array_layout const& layout) {
1620  return map_type::memory_span(layout);
1621  }
1622 
1623  static constexpr size_t required_allocation_size(
1624  const size_t arg_N0 = 0, const size_t arg_N1 = 0, const size_t arg_N2 = 0,
1625  const size_t arg_N3 = 0, const size_t arg_N4 = 0, const size_t arg_N5 = 0,
1626  const size_t arg_N6 = 0, const size_t arg_N7 = 0) {
1627  static_assert(traits::array_layout::is_extent_constructible,
1628  "Layout is not constructible from extent arguments. Use "
1629  "overload taking a layout object instead.");
1630  return map_type::memory_span(typename traits::array_layout(
1631  arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7));
1632  }
1633 
1634  explicit KOKKOS_INLINE_FUNCTION View(
1635  pointer_type arg_ptr, const size_t arg_N0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1636  const size_t arg_N1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1637  const size_t arg_N2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1638  const size_t arg_N3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1639  const size_t arg_N4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1640  const size_t arg_N5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1641  const size_t arg_N6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1642  const size_t arg_N7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
1643  : View(Impl::ViewCtorProp<pointer_type>(arg_ptr),
1644  typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3,
1645  arg_N4, arg_N5, arg_N6, arg_N7)) {
1646  static_assert(traits::array_layout::is_extent_constructible,
1647  "Layout is not constructible from extent arguments. Use "
1648  "overload taking a layout object instead.");
1649  }
1650 
1651  explicit KOKKOS_INLINE_FUNCTION View(
1652  pointer_type arg_ptr, const typename traits::array_layout& arg_layout)
1653  : View(Impl::ViewCtorProp<pointer_type>(arg_ptr), arg_layout) {}
1654 
1655  //----------------------------------------
1656  // Shared scratch memory constructor
1657 
1658  static KOKKOS_INLINE_FUNCTION size_t
1659  shmem_size(const size_t arg_N0 = KOKKOS_INVALID_INDEX,
1660  const size_t arg_N1 = KOKKOS_INVALID_INDEX,
1661  const size_t arg_N2 = KOKKOS_INVALID_INDEX,
1662  const size_t arg_N3 = KOKKOS_INVALID_INDEX,
1663  const size_t arg_N4 = KOKKOS_INVALID_INDEX,
1664  const size_t arg_N5 = KOKKOS_INVALID_INDEX,
1665  const size_t arg_N6 = KOKKOS_INVALID_INDEX,
1666  const size_t arg_N7 = KOKKOS_INVALID_INDEX) {
1667  static_assert(traits::array_layout::is_extent_constructible,
1668  "Layout is not constructible from extent arguments. Use "
1669  "overload taking a layout object instead.");
1670  const size_t num_passed_args = Impl::count_valid_integers(
1671  arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7);
1672 
1673  if (std::is_void<typename traits::specialize>::value &&
1674  num_passed_args != rank_dynamic) {
1675  Kokkos::abort(
1676  "Kokkos::View::shmem_size() rank_dynamic != number of arguments.\n");
1677  }
1678 
1679  return View::shmem_size(typename traits::array_layout(
1680  arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7));
1681  }
1682 
1683  private:
1684  // Want to be able to align to minimum scratch alignment or sizeof or alignof
1685  // elements
1686  static constexpr size_t scratch_value_alignment =
1687  max({sizeof(typename traits::value_type),
1688  alignof(typename traits::value_type),
1689  static_cast<size_t>(
1690  traits::execution_space::scratch_memory_space::ALIGN)});
1691 
1692  public:
1693  static KOKKOS_INLINE_FUNCTION size_t
1694  shmem_size(typename traits::array_layout const& arg_layout) {
1695  return map_type::memory_span(arg_layout) + scratch_value_alignment;
1696  }
1697 
1698  explicit KOKKOS_INLINE_FUNCTION View(
1699  const typename traits::execution_space::scratch_memory_space& arg_space,
1700  const typename traits::array_layout& arg_layout)
1701  : View(Impl::ViewCtorProp<pointer_type>(reinterpret_cast<pointer_type>(
1702  arg_space.get_shmem_aligned(map_type::memory_span(arg_layout),
1703  scratch_value_alignment))),
1704  arg_layout) {}
1705 
1706  explicit KOKKOS_INLINE_FUNCTION View(
1707  const typename traits::execution_space::scratch_memory_space& arg_space,
1708  const size_t arg_N0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1709  const size_t arg_N1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1710  const size_t arg_N2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1711  const size_t arg_N3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1712  const size_t arg_N4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1713  const size_t arg_N5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1714  const size_t arg_N6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1715  const size_t arg_N7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
1716  : View(Impl::ViewCtorProp<pointer_type>(
1717  reinterpret_cast<pointer_type>(arg_space.get_shmem_aligned(
1718  map_type::memory_span(typename traits::array_layout(
1719  arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6,
1720  arg_N7)),
1721  scratch_value_alignment))),
1722  typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3,
1723  arg_N4, arg_N5, arg_N6, arg_N7)) {
1724  static_assert(traits::array_layout::is_extent_constructible,
1725  "Layout is not constructible from extent arguments. Use "
1726  "overload taking a layout object instead.");
1727  }
1728 };
1729 
1730 template <typename D, class... P>
1731 KOKKOS_INLINE_FUNCTION constexpr unsigned rank(const View<D, P...>&) {
1732  return View<D, P...>::rank();
1733 }
1734 
1735 namespace Impl {
1736 
1737 template <typename ValueType, unsigned int Rank>
1738 struct RankDataType {
1739  using type = typename RankDataType<ValueType, Rank - 1>::type*;
1740 };
1741 
1742 template <typename ValueType>
1743 struct RankDataType<ValueType, 0> {
1744  using type = ValueType;
1745 };
1746 
1747 template <unsigned N, typename... Args>
1748 KOKKOS_FUNCTION std::enable_if_t<
1749  N == View<Args...>::rank() &&
1750  std::is_same<typename ViewTraits<Args...>::specialize, void>::value,
1751  View<Args...>>
1752 as_view_of_rank_n(View<Args...> v) {
1753  return v;
1754 }
1755 
1756 // Placeholder implementation to compile generic code for DynRankView; should
1757 // never be called
1758 template <unsigned N, typename T, typename... Args>
1759 KOKKOS_FUNCTION std::enable_if_t<
1760  N != View<T, Args...>::rank() &&
1761  std::is_same<typename ViewTraits<T, Args...>::specialize, void>::value,
1762  View<typename RankDataType<typename View<T, Args...>::value_type, N>::type,
1763  Args...>>
1764 as_view_of_rank_n(View<T, Args...>) {
1765  Kokkos::abort("Trying to get at a View of the wrong rank");
1766  return {};
1767 }
1768 
1769 template <typename Function, typename... Args>
1770 void apply_to_view_of_static_rank(Function&& f, View<Args...> a) {
1771  f(a);
1772 }
1773 
1774 } // namespace Impl
1775 //----------------------------------------------------------------------------
1776 //----------------------------------------------------------------------------
1777 
1778 namespace Impl {
1779 template <class ValueType, class TypeList>
1780 struct TypeListToViewTraits;
1781 
1782 template <class ValueType, class... Properties>
1783 struct TypeListToViewTraits<ValueType, Kokkos::Impl::type_list<Properties...>> {
1784  using type = ViewTraits<ValueType, Properties...>;
1785 };
1786 
1787 // It is not safe to assume that subviews of views with the Aligned memory trait
1788 // are also aligned. Hence, just remove that attribute for subviews.
1789 template <class D, class... P>
1790 struct RemoveAlignedMemoryTrait {
1791  private:
1792  using type_list_in = Kokkos::Impl::type_list<P...>;
1793  using memory_traits = typename ViewTraits<D, P...>::memory_traits;
1794  using type_list_in_wo_memory_traits =
1795  typename Kokkos::Impl::type_list_remove_first<memory_traits,
1796  type_list_in>::type;
1797  using new_memory_traits =
1798  Kokkos::MemoryTraits<memory_traits::impl_value & ~Kokkos::Aligned>;
1799  using new_type_list = typename Kokkos::Impl::concat_type_list<
1800  type_list_in_wo_memory_traits,
1801  Kokkos::Impl::type_list<new_memory_traits>>::type;
1802 
1803  public:
1804  using type = typename TypeListToViewTraits<D, new_type_list>::type;
1805 };
1806 } // namespace Impl
1807 
1808 template <class D, class... P, class... Args>
1809 KOKKOS_INLINE_FUNCTION auto subview(const View<D, P...>& src, Args... args) {
1810  static_assert(View<D, P...>::rank == sizeof...(Args),
1811  "subview requires one argument for each source View rank");
1812 
1813  return typename Kokkos::Impl::ViewMapping<
1814  void /* deduce subview type from source view traits */
1815  ,
1816  typename Impl::RemoveAlignedMemoryTrait<D, P...>::type,
1817  Args...>::type(src, args...);
1818 }
1819 
1820 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
1821 template <class MemoryTraits, class D, class... P, class... Args>
1822 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION auto subview(const View<D, P...>& src,
1823  Args... args) {
1824  static_assert(View<D, P...>::rank == sizeof...(Args),
1825  "subview requires one argument for each source View rank");
1826  static_assert(Kokkos::is_memory_traits<MemoryTraits>::value);
1827 
1828  return typename Kokkos::Impl::ViewMapping<
1829  void /* deduce subview type from source view traits */
1830  ,
1831  typename Impl::RemoveAlignedMemoryTrait<D, P..., MemoryTraits>::type,
1832  Args...>::type(src, args...);
1833 }
1834 #endif
1835 
1836 template <class V, class... Args>
1837 using Subview = decltype(subview(std::declval<V>(), std::declval<Args>()...));
1838 
1839 } /* namespace Kokkos */
1840 
1841 //----------------------------------------------------------------------------
1842 //----------------------------------------------------------------------------
1843 
1844 namespace Kokkos {
1845 
1846 template <class LT, class... LP, class RT, class... RP>
1847 KOKKOS_INLINE_FUNCTION bool operator==(const View<LT, LP...>& lhs,
1848  const View<RT, RP...>& rhs) {
1849  // Same data, layout, dimensions
1850  using lhs_traits = ViewTraits<LT, LP...>;
1851  using rhs_traits = ViewTraits<RT, RP...>;
1852 
1853  return std::is_same<typename lhs_traits::const_value_type,
1854  typename rhs_traits::const_value_type>::value &&
1855  std::is_same<typename lhs_traits::array_layout,
1856  typename rhs_traits::array_layout>::value &&
1857  std::is_same<typename lhs_traits::memory_space,
1858  typename rhs_traits::memory_space>::value &&
1859  View<LT, LP...>::rank() == View<RT, RP...>::rank() &&
1860  lhs.data() == rhs.data() && lhs.span() == rhs.span() &&
1861  lhs.extent(0) == rhs.extent(0) && lhs.extent(1) == rhs.extent(1) &&
1862  lhs.extent(2) == rhs.extent(2) && lhs.extent(3) == rhs.extent(3) &&
1863  lhs.extent(4) == rhs.extent(4) && lhs.extent(5) == rhs.extent(5) &&
1864  lhs.extent(6) == rhs.extent(6) && lhs.extent(7) == rhs.extent(7);
1865 }
1866 
1867 template <class LT, class... LP, class RT, class... RP>
1868 KOKKOS_INLINE_FUNCTION bool operator!=(const View<LT, LP...>& lhs,
1869  const View<RT, RP...>& rhs) {
1870  return !(operator==(lhs, rhs));
1871 }
1872 
1873 } /* namespace Kokkos */
1874 
1875 //----------------------------------------------------------------------------
1876 //----------------------------------------------------------------------------
1877 
1878 namespace Kokkos {
1879 namespace Impl {
1880 
1881 inline void shared_allocation_tracking_disable() {
1882  Kokkos::Impl::SharedAllocationRecord<void, void>::tracking_disable();
1883 }
1884 
1885 inline void shared_allocation_tracking_enable() {
1886  Kokkos::Impl::SharedAllocationRecord<void, void>::tracking_enable();
1887 }
1888 
1889 } /* namespace Impl */
1890 } /* namespace Kokkos */
1891 
1892 //----------------------------------------------------------------------------
1893 //----------------------------------------------------------------------------
1894 
1895 namespace Kokkos {
1896 namespace Impl {
1897 
1898 template <class Specialize, typename A, typename B>
1899 struct CommonViewValueType;
1900 
1901 template <typename A, typename B>
1902 struct CommonViewValueType<void, A, B> {
1903  using value_type = std::common_type_t<A, B>;
1904 };
1905 
1906 template <class Specialize, class ValueType>
1907 struct CommonViewAllocProp;
1908 
1909 template <class ValueType>
1910 struct CommonViewAllocProp<void, ValueType> {
1911  using value_type = ValueType;
1912  using scalar_array_type = ValueType;
1913 
1914  template <class... Views>
1915  KOKKOS_INLINE_FUNCTION CommonViewAllocProp(const Views&...) {}
1916 };
1917 
1918 template <class... Views>
1919 struct DeduceCommonViewAllocProp;
1920 
1921 // Base case must provide types for:
1922 // 1. specialize 2. value_type 3. is_view 4. prop_type
1923 template <class FirstView>
1924 struct DeduceCommonViewAllocProp<FirstView> {
1925  using specialize = typename FirstView::traits::specialize;
1926 
1927  using value_type = typename FirstView::traits::value_type;
1928 
1929  enum : bool { is_view = is_view<FirstView>::value };
1930 
1931  using prop_type = CommonViewAllocProp<specialize, value_type>;
1932 };
1933 
1934 template <class FirstView, class... NextViews>
1935 struct DeduceCommonViewAllocProp<FirstView, NextViews...> {
1936  using NextTraits = DeduceCommonViewAllocProp<NextViews...>;
1937 
1938  using first_specialize = typename FirstView::traits::specialize;
1939  using first_value_type = typename FirstView::traits::value_type;
1940 
1941  enum : bool { first_is_view = is_view<FirstView>::value };
1942 
1943  using next_specialize = typename NextTraits::specialize;
1944  using next_value_type = typename NextTraits::value_type;
1945 
1946  enum : bool { next_is_view = NextTraits::is_view };
1947 
1948  // common types
1949 
1950  // determine specialize type
1951  // if first and next specialize differ, but are not the same specialize, error
1952  // out
1953  static_assert(!(!std::is_same<first_specialize, next_specialize>::value &&
1954  !std::is_void<first_specialize>::value &&
1955  !std::is_void<next_specialize>::value),
1956  "Kokkos DeduceCommonViewAllocProp ERROR: Only one non-void "
1957  "specialize trait allowed");
1958 
1959  // otherwise choose non-void specialize if either/both are non-void
1960  using specialize = std::conditional_t<
1961  std::is_same<first_specialize, next_specialize>::value, first_specialize,
1962  std::conditional_t<(std::is_void<first_specialize>::value &&
1963  !std::is_void<next_specialize>::value),
1964  next_specialize, first_specialize>>;
1965 
1966  using value_type = typename CommonViewValueType<specialize, first_value_type,
1967  next_value_type>::value_type;
1968 
1969  enum : bool { is_view = (first_is_view && next_is_view) };
1970 
1971  using prop_type = CommonViewAllocProp<specialize, value_type>;
1972 };
1973 
1974 } // end namespace Impl
1975 
1976 template <class... Views>
1977 using DeducedCommonPropsType =
1978  typename Impl::DeduceCommonViewAllocProp<Views...>::prop_type;
1979 
1980 // This function is required in certain scenarios where users customize
1981 // Kokkos View internals. One example are dynamic length embedded ensemble
1982 // types. The function is used to propagate necessary information
1983 // (like the ensemble size) when creating new views.
1984 // However, most of the time it is called with a single view.
1985 // Furthermore, the propagated information is not just for view allocations.
1986 // From what I can tell, the type of functionality provided by
1987 // common_view_alloc_prop is the equivalent of propagating accessors in mdspan,
1988 // a mechanism we will eventually use to replace this clunky approach here, when
1989 // we are finally mdspan based.
1990 // TODO: get rid of this when we have mdspan
1991 template <class... Views>
1992 KOKKOS_INLINE_FUNCTION DeducedCommonPropsType<Views...> common_view_alloc_prop(
1993  Views const&... views) {
1994  return DeducedCommonPropsType<Views...>(views...);
1995 }
1996 
1997 } // namespace Kokkos
1998 
1999 #include <impl/Kokkos_ViewUniformType.hpp>
2000 #include <impl/Kokkos_Atomic_View.hpp>
2001 
2002 //----------------------------------------------------------------------------
2003 //----------------------------------------------------------------------------
2004 
2005 #endif /* #ifndef KOKKOS_VIEW_HPP */
Memory layout tag indicating left-to-right (Fortran scheme) striding of multi-indices.
typename Impl::ViewUniformType< View, 0 >::type uniform_type
Unified types.
Memory layout tag indicated arbitrarily strided multi-index mapping into contiguous memory...
View to an array of data.
Memory layout tag indicating right-to-left (C or lexigraphical scheme) striding of multi-indices...
Traits class for accessing attributes of a View.