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