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