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 
23 #ifndef KOKKOS_VIEW_HPP
24 #define KOKKOS_VIEW_HPP
25 
26 #include <Kokkos_Macros.hpp>
27 #ifdef KOKKOS_ENABLE_IMPL_MDSPAN
28 #include <View/Kokkos_BasicView.hpp>
29 #endif
30 #ifdef KOKKOS_ENABLE_IMPL_VIEW_LEGACY
31 #include <View/Kokkos_ViewLegacy.hpp>
32 #else
33 
34 #include <View/Kokkos_ViewTraits.hpp>
35 #include <Kokkos_MemoryTraits.hpp>
36 
37 // FIXME: This will eventually be removed
38 namespace Kokkos::Impl {
39 template <class, class...>
40 class ViewMapping;
41 }
42 #include <View/Kokkos_ViewMapping.hpp>
43 #include <Kokkos_MinMax.hpp>
44 
45 // Class to provide a uniform type
46 namespace Kokkos {
47 namespace Impl {
48 template <class ViewType, int Traits>
49 struct ViewUniformType;
50 
51 template <class ParentView>
52 struct ViewTracker;
53 } /* namespace Impl */
54 
55 template <class T1, class T2>
56 struct is_always_assignable_impl;
57 
58 template <class... ViewTDst, class... ViewTSrc>
59 struct is_always_assignable_impl<Kokkos::View<ViewTDst...>,
60  Kokkos::View<ViewTSrc...> > {
61  using dst_mdspan = typename Kokkos::View<ViewTDst...>::mdspan_type;
62  using src_mdspan = typename Kokkos::View<ViewTSrc...>::mdspan_type;
63 
64  constexpr static bool value =
65  std::is_constructible_v<dst_mdspan, src_mdspan> &&
66  static_cast<int>(Kokkos::View<ViewTDst...>::rank_dynamic) >=
67  static_cast<int>(Kokkos::View<ViewTSrc...>::rank_dynamic);
68 };
69 
70 template <class View1, class View2>
71 using is_always_assignable = is_always_assignable_impl<
72  std::remove_reference_t<View1>,
73  std::remove_const_t<std::remove_reference_t<View2> > >;
74 
75 template <class T1, class T2>
76 inline constexpr bool is_always_assignable_v =
77  is_always_assignable<T1, T2>::value;
78 
79 template <class... ViewTDst, class... ViewTSrc>
80 constexpr bool is_assignable(const Kokkos::View<ViewTDst...>& dst,
81  const Kokkos::View<ViewTSrc...>& src) {
82  using dst_mdspan = typename Kokkos::View<ViewTDst...>::mdspan_type;
83  using src_mdspan = typename Kokkos::View<ViewTSrc...>::mdspan_type;
84 
85  return is_always_assignable_v<Kokkos::View<ViewTDst...>,
86  Kokkos::View<ViewTSrc...> > ||
87  (std::is_constructible_v<dst_mdspan, src_mdspan> &&
88  ((dst_mdspan::rank_dynamic() >= 1) ||
89  (dst.static_extent(0) == src.extent(0))) &&
90  ((dst_mdspan::rank_dynamic() >= 2) ||
91  (dst.static_extent(1) == src.extent(1))) &&
92  ((dst_mdspan::rank_dynamic() >= 3) ||
93  (dst.static_extent(2) == src.extent(2))) &&
94  ((dst_mdspan::rank_dynamic() >= 4) ||
95  (dst.static_extent(3) == src.extent(3))) &&
96  ((dst_mdspan::rank_dynamic() >= 5) ||
97  (dst.static_extent(4) == src.extent(4))) &&
98  ((dst_mdspan::rank_dynamic() >= 6) ||
99  (dst.static_extent(5) == src.extent(5))) &&
100  ((dst_mdspan::rank_dynamic() >= 7) ||
101  (dst.static_extent(6) == src.extent(6))) &&
102  ((dst_mdspan::rank_dynamic() == 8) ||
103  (dst.static_extent(7) == src.extent(7))));
104 }
105 
106 namespace Impl {
107 template <class... Properties>
108 struct BasicViewFromTraits {
109  using view_traits = ViewTraits<Properties...>;
110  using mdspan_view_traits = MDSpanViewTraits<view_traits>;
111  using element_type = typename view_traits::value_type;
112  using extents_type = typename mdspan_view_traits::extents_type;
113  using layout_type = typename mdspan_view_traits::mdspan_layout_type;
114  using accessor_type = typename mdspan_view_traits::accessor_type;
115 
116  using type =
117  BV::BasicView<element_type, extents_type, layout_type, accessor_type>;
118 };
119 
120 // Helper function to deal with cases where the data handle is
121 // not convertible to element_type* such as in Sacado.
122 // An overload for our reference counted data handle is next to its
123 // implementation. This one covers Unmanaged views with raw pointers.
124 template <class HandleType>
125 KOKKOS_INLINE_FUNCTION constexpr auto ptr_from_data_handle(
126  const HandleType& handle) {
127  // This should only be internally invoked in Kokkos with raw pointers.
128  static_assert(std::is_pointer_v<HandleType>);
129  return handle;
130 }
131 } // namespace Impl
132 
133 template <class DataType, class... Properties>
134 struct ViewTraits;
135 
136 template <class DataType, class... Properties>
137 class View;
138 
139 template <class>
140 struct is_view : public std::false_type {};
141 
142 template <class D, class... P>
143 struct is_view<View<D, P...> > : public std::true_type {};
144 
145 template <class D, class... P>
146 struct is_view<const View<D, P...> > : public std::true_type {};
147 
148 template <class T>
149 inline constexpr bool is_view_v = is_view<T>::value;
150 
151 template <class DataType, class... Properties>
152 class View : public Impl::BasicViewFromTraits<DataType, Properties...>::type {
153  // We are deriving from BasicView, but need a helper to translate
154  // View template parameters to BasicView template parameters
155  private:
156  template <class, class...>
157  friend class View;
158  template <typename V>
159  friend struct Kokkos::Impl::ViewTracker;
160 
161  using base_t =
162  typename Impl::BasicViewFromTraits<DataType, Properties...>::type;
163 
164  public:
165  using base_t::base_t;
166 
167  // typedefs originally from ViewTraits
168  using traits = ViewTraits<DataType, Properties...>;
169  using const_value_type = typename traits::const_value_type;
170  using non_const_value_type = typename traits::non_const_value_type;
171  using data_type = DataType;
172  using const_data_type = typename traits::const_data_type;
173  using non_const_data_type = typename traits::non_const_data_type;
174  using view_tracker_type = Impl::ViewTracker<View>;
175  using array_layout = typename traits::array_layout;
176  using device_type = typename traits::device_type;
177  using execution_space = typename traits::execution_space;
178  using memory_space = typename traits::memory_space;
179  using memory_traits = typename traits::memory_traits;
180  using host_mirror_space = typename traits::host_mirror_space;
181  using typename base_t::index_type;
182 
183  // aliases from BasicView
184 
185  // FIXME: Should be unsigned
186  // FIXME: these are overriden so that their types are identical when using
187  // BasicView or Legacy we will need to obtain these from base_t in the future
188  // and deprecate old behavior
189  using size_type = typename memory_space::size_type;
190  using value_type = typename traits::value_type;
191  // pointer_type can be different from element_type*
192  using pointer_type = decltype(Impl::ptr_from_data_handle(
193  std::declval<typename base_t::data_handle_type>()));
194 
195  private:
196  using raw_allocation_value_type = std::remove_pointer_t<pointer_type>;
197 
198  public:
199  using scalar_array_type = typename traits::scalar_array_type;
200  using const_scalar_array_type = typename traits::const_scalar_array_type;
201  using non_const_scalar_array_type =
202  typename traits::non_const_scalar_array_type;
203 
204  // typedefs from BasicView
205  using typename base_t::mdspan_type;
206  using reference_type = typename base_t::reference;
207 
208  //----------------------------------------
209  // Compatible view of array of scalar types
210  using array_type =
211  View<typename traits::scalar_array_type, typename traits::array_layout,
212  typename traits::device_type, typename traits::hooks_policy,
213  typename traits::memory_traits>;
214 
215  // Compatible view of const data type
216  using const_type =
217  View<typename traits::const_data_type, typename traits::array_layout,
218  typename traits::device_type, typename traits::hooks_policy,
219  typename traits::memory_traits>;
220 
221  // Compatible view of non-const data type
222  using non_const_type =
223  View<typename traits::non_const_data_type, typename traits::array_layout,
224  typename traits::device_type, typename traits::hooks_policy,
225  typename traits::memory_traits>;
226 
227  // Compatible HostMirror view
228  using host_mirror_type =
229  View<typename traits::non_const_data_type, typename traits::array_layout,
230  Device<DefaultHostExecutionSpace,
231  typename traits::host_mirror_space::memory_space>,
232  typename traits::hooks_policy>;
233 
234  // Compatible HostMirror view
235  using HostMirror = host_mirror_type;
236 
237  // Unified types
238  using uniform_type = typename Impl::ViewUniformType<View, 0>::type;
239  using uniform_const_type =
240  typename Impl::ViewUniformType<View, 0>::const_type;
241  using uniform_runtime_type =
242  typename Impl::ViewUniformType<View, 0>::runtime_type;
243  using uniform_runtime_const_type =
244  typename Impl::ViewUniformType<View, 0>::runtime_const_type;
245  using uniform_nomemspace_type =
246  typename Impl::ViewUniformType<View, 0>::nomemspace_type;
247  using uniform_const_nomemspace_type =
248  typename Impl::ViewUniformType<View, 0>::const_nomemspace_type;
249  using uniform_runtime_nomemspace_type =
250  typename Impl::ViewUniformType<View, 0>::runtime_nomemspace_type;
251  using uniform_runtime_const_nomemspace_type =
252  typename Impl::ViewUniformType<View, 0>::runtime_const_nomemspace_type;
253 
254  //----------------------------------------
255  // Domain rank and extents
256 
257  static constexpr Impl::integral_constant<size_t, base_t::rank()> rank = {};
258  static constexpr Impl::integral_constant<size_t, base_t::rank_dynamic()>
259  rank_dynamic = {};
260 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
261  enum {Rank KOKKOS_DEPRECATED_WITH_COMMENT("Use rank instead.") = rank()};
262 #endif
263 
264  KOKKOS_INLINE_FUNCTION constexpr array_layout layout() const {
265  return Impl::array_layout_from_mapping<array_layout, mdspan_type>(
266  base_t::mapping());
267  }
268 
269  KOKKOS_FUNCTION constexpr size_t stride_0() const { return stride(0); }
270  KOKKOS_FUNCTION constexpr size_t stride_1() const { return stride(1); }
271  KOKKOS_FUNCTION constexpr size_t stride_2() const { return stride(2); }
272  KOKKOS_FUNCTION constexpr size_t stride_3() const { return stride(3); }
273  KOKKOS_FUNCTION constexpr size_t stride_4() const { return stride(4); }
274  KOKKOS_FUNCTION constexpr size_t stride_5() const { return stride(5); }
275  KOKKOS_FUNCTION constexpr size_t stride_6() const { return stride(6); }
276  KOKKOS_FUNCTION constexpr size_t stride_7() const { return stride(7); }
277 
278  template <typename iType>
279  KOKKOS_INLINE_FUNCTION constexpr std::enable_if_t<std::is_integral_v<iType>,
280  size_t>
281  stride(iType r) const {
282  // base class doesn't have constraint
283  // FIXME: Eventually we need to deprecate this behavior and just use
284  // BasicView implementation
285 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
286  using LayoutType = typename mdspan_type::layout_type;
287  if (r >= static_cast<iType>(rank())) {
288  if constexpr (rank() == 0) return 1;
289  if constexpr (std::is_same_v<LayoutType, layout_right> ||
290  Impl::IsLayoutRightPadded<LayoutType>::value) {
291  return 1;
292  }
293  if constexpr (std::is_same_v<LayoutType, layout_left> ||
294  Impl::IsLayoutLeftPadded<LayoutType>::value) {
295  return base_t::stride(rank() - 1) * extent(rank() - 1);
296  }
297  if constexpr (std::is_same_v<LayoutType, layout_stride>) {
298  return 0;
299  }
300  }
301 #else
302  KOKKOS_ASSERT(r < static_cast<iType>(rank()));
303 #endif
304  return base_t::stride(r);
305  }
306 
307  template <typename iType>
308  KOKKOS_INLINE_FUNCTION void stride([[maybe_unused]] iType* const s) const {
309  if constexpr (rank() > 0) {
310  size_t max_stride = 0;
311  size_t max_stride_idx = 0;
312  for (size_t r = 0; r < rank(); r++) {
313  s[r] = base_t::stride(r);
314  if (s[r] > static_cast<iType>(max_stride)) {
315  max_stride = s[r];
316  max_stride_idx = r;
317  }
318  }
319  s[rank()] = max_stride * base_t::extent(max_stride_idx);
320  }
321  }
322 
323  //----------------------------------------
324  // Range span is the span which contains all members.
325 
326  static constexpr auto reference_type_is_lvalue_reference =
327  std::is_lvalue_reference_v<reference_type>;
328 
329  KOKKOS_INLINE_FUNCTION constexpr size_t span() const {
330  return base_t::mapping().required_span_size();
331  }
332  KOKKOS_INLINE_FUNCTION bool span_is_contiguous() const {
333  return base_t::is_exhaustive();
334  }
335  KOKKOS_INLINE_FUNCTION constexpr bool is_allocated() const {
336  return data() != nullptr;
337  }
338  KOKKOS_INLINE_FUNCTION constexpr pointer_type data() const {
339  return Impl::ptr_from_data_handle(base_t::data_handle());
340  }
341 
342  KOKKOS_INLINE_FUNCTION constexpr int extent_int(size_t r) const {
343  return static_cast<int>(base_t::extent(r));
344  }
345  //----------------------------------------
346  // Allow specializations to query their specialized map
347 
348  KOKKOS_INLINE_FUNCTION
349  auto impl_map() const {
350  using map_type =
351  Kokkos::Impl::ViewMapping<traits, typename traits::specialize>;
352  return map_type(Kokkos::view_wrap(data()), layout());
353  }
354 
355  KOKKOS_INLINE_FUNCTION
356  const Kokkos::Impl::SharedAllocationTracker& impl_track() const {
357  if constexpr (traits::is_managed) {
358  return base_t::data_handle().tracker();
359  } else {
360  static const Kokkos::Impl::SharedAllocationTracker empty_tracker = {};
361  return empty_tracker;
362  }
363  }
364  //----------------------------------------
365  // Operators always provided by View
366 
367  template <class OtherIndexType>
368  KOKKOS_FUNCTION constexpr reference_type operator[](
369  const OtherIndexType& idx) const {
370  return base_t::operator()(idx);
371  }
372 
373  private:
374 
375 #ifdef KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK
376  template <typename... Is>
377  static KOKKOS_FUNCTION void check_access_member_function_valid_args(
378  Is... is) {
379  // cast to int to work around pointless comparison of unsigned to 0 warning
380  static_assert(static_cast<int>(sizeof...(Is)) <=
381  static_cast<int>(8 - rank));
382  static_assert(Kokkos::Impl::are_integral<Is...>::value);
383  if (!((is == static_cast<Is>(0)) && ... && true))
384  Kokkos::abort("Extra arguments to Kokkos::access must be zero");
385  }
386 #else
387  template <typename... Is>
388  static KOKKOS_FUNCTION void check_access_member_function_valid_args(Is...) {
389  // cast to int to work around pointless comparison of unsigned to 0 warning
390  static_assert(static_cast<int>(sizeof...(Is)) <=
391  static_cast<int>(8 - rank));
392  static_assert(Kokkos::Impl::are_integral<Is...>::value);
393  }
394 #endif
395 
396  public:
397  //------------------------------
398  // Rank 0
399 
400  template <typename... Is>
401  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
402  (Kokkos::Impl::always_true<Is...>::value && (0 == rank)), reference_type>
403  access(Is... extra) const {
404  check_access_member_function_valid_args(extra...);
405  return base_t::operator()();
406  }
407 
408  //------------------------------
409  // Rank 1
410 
411  template <typename I0, typename... Is>
412  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
413  (Kokkos::Impl::always_true<I0, Is...>::value && (1 == rank)),
414  reference_type>
415  access(I0 i0, Is... extra) const {
416  check_access_member_function_valid_args(extra...);
417  return base_t::operator()(i0);
418  }
419 
420  //------------------------------
421  // Rank 2
422 
423  template <typename I0, typename I1, typename... Is>
424  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
425  (Kokkos::Impl::always_true<I0, I1, Is...>::value && (2 == rank)),
426  reference_type>
427  access(I0 i0, I1 i1, Is... extra) const {
428  check_access_member_function_valid_args(extra...);
429  return base_t::operator()(i0, i1);
430  }
431 
432  //------------------------------
433  // Rank 3
434 
435  template <typename I0, typename I1, typename I2, typename... Is>
436  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
437  (Kokkos::Impl::always_true<I0, I1, I2, Is...>::value && (3 == rank)),
438  reference_type>
439  access(I0 i0, I1 i1, I2 i2, Is... extra) const {
440  check_access_member_function_valid_args(extra...);
441  return base_t::operator()(i0, i1, i2);
442  }
443 
444  //------------------------------
445  // Rank 4
446 
447  template <typename I0, typename I1, typename I2, typename I3, typename... Is>
448  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
449  (Kokkos::Impl::always_true<I0, I1, I2, I3, Is...>::value && (4 == rank)),
450  reference_type>
451  access(I0 i0, I1 i1, I2 i2, I3 i3, Is... extra) const {
452  check_access_member_function_valid_args(extra...);
453  return base_t::operator()(i0, i1, i2, i3);
454  }
455 
456  //------------------------------
457  // Rank 5
458 
459  template <typename I0, typename I1, typename I2, typename I3, typename I4,
460  typename... Is>
461  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
462  (Kokkos::Impl::always_true<I0, I1, I2, I3, I4, Is...>::value &&
463  (5 == rank)),
464  reference_type>
465  access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, Is... extra) const {
466  check_access_member_function_valid_args(extra...);
467  return base_t::operator()(i0, i1, i2, i3, i4);
468  }
469 
470  //------------------------------
471  // Rank 6
472 
473  template <typename I0, typename I1, typename I2, typename I3, typename I4,
474  typename I5, typename... Is>
475  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
476  (Kokkos::Impl::always_true<I0, I1, I2, I3, I4, I5, Is...>::value &&
477  (6 == rank)),
478  reference_type>
479  access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, I5 i5, Is... extra) const {
480  check_access_member_function_valid_args(extra...);
481  return base_t::operator()(i0, i1, i2, i3, i4, i5);
482  }
483 
484  //------------------------------
485  // Rank 7
486 
487  template <typename I0, typename I1, typename I2, typename I3, typename I4,
488  typename I5, typename I6, typename... Is>
489  KOKKOS_FORCEINLINE_FUNCTION std::enable_if_t<
490  (Kokkos::Impl::always_true<I0, I1, I2, I3, I4, I5, I6, Is...>::value &&
491  (7 == rank)),
492  reference_type>
493  access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, I5 i5, I6 i6, Is... extra) const {
494  check_access_member_function_valid_args(extra...);
495  return base_t::operator()(i0, i1, i2, i3, i4, i5, i6);
496  }
497 
498  //------------------------------
499  // Rank 8
500 
501  template <typename I0, typename I1, typename I2, typename I3, typename I4,
502  typename I5, typename I6, typename I7, typename... Is>
503  KOKKOS_FORCEINLINE_FUNCTION
504  std::enable_if_t<(Kokkos::Impl::always_true<I0, I1, I2, I3, I4, I5, I6,
505  I7, Is...>::value &&
506  (8 == rank)),
507  reference_type>
508  access(I0 i0, I1 i1, I2 i2, I3 i3, I4 i4, I5 i5, I6 i6, I7 i7,
509  Is... extra) const {
510  check_access_member_function_valid_args(extra...);
511  return base_t::operator()(i0, i1, i2, i3, i4, i5, i6, i7);
512  }
513 
514  //----------------------------------------
515  // Standard destructor, constructors, and assignment operators
516 
517  KOKKOS_DEFAULTED_FUNCTION
518  ~View() = default;
519 
520  KOKKOS_DEFAULTED_FUNCTION
521  View() = default;
522 
523  KOKKOS_DEFAULTED_FUNCTION
524  View(const View& other) = default;
525 
526  KOKKOS_DEFAULTED_FUNCTION
527  View(View&& other) = default;
528 
529  KOKKOS_DEFAULTED_FUNCTION
530  View& operator=(const View& other) = default;
531 
532  KOKKOS_DEFAULTED_FUNCTION
533  View& operator=(View&& other) = default;
534 
535  KOKKOS_FUNCTION
536  View(typename base_t::data_handle_type p,
537  const typename base_t::mapping_type& m)
538  : base_t(p, m) {}
539 
540  //----------------------------------------
541  // Compatible view copy constructor and assignment
542  // may assign unmanaged from managed.
543 
544  template <class OtherT, class... OtherArgs>
545  // requires(std::is_constructible_v<
546  // mdspan_type, typename View<OtherT, OtherArgs...>::mdspan_type>)
547  KOKKOS_INLINE_FUNCTION View(
548  const View<OtherT, OtherArgs...>& other,
549  std::enable_if_t<
550  std::is_constructible_v<
551  mdspan_type, typename View<OtherT, OtherArgs...>::mdspan_type>,
552  void*> = nullptr)
553  : base_t(static_cast<typename mdspan_type::data_handle_type>(
554  other.data_handle()),
555  static_cast<typename mdspan_type::mapping_type>(other.mapping()),
556  static_cast<typename mdspan_type::accessor_type>(
557  other.accessor())) {
558  base_t::check_basic_view_constructibility(other.mapping());
559  }
560 
561  //----------------------------------------
562  // Compatible subview constructor
563  // may assign unmanaged from managed.
564 
565  template <class RT, class... RP, class Arg0, class... Args>
566  KOKKOS_INLINE_FUNCTION View(const View<RT, RP...>& src_view, const Arg0 arg0,
567  Args... args)
568  : base_t(Impl::subview_ctor_tag, src_view, arg0, args...) {}
569 
570  //----------------------------------------
571  // Allocation according to allocation properties and array layout
572 
573  template <class... P>
574  explicit View(const Impl::ViewCtorProp<P...>& arg_prop,
575  std::enable_if_t<!Impl::ViewCtorProp<P...>::has_pointer,
576  const typename traits::array_layout&>
577  arg_layout)
578  : base_t(
579  arg_prop,
580  Impl::mapping_from_array_layout<typename mdspan_type::mapping_type>(
581  arg_layout)) {
582  static_assert(traits::is_managed,
583  "Can't construct managed View with unmanaged memory trait!");
584  }
585 
586  template <class... P>
587  KOKKOS_FUNCTION explicit View(
588  const Impl::ViewCtorProp<P...>& arg_prop,
589  std::enable_if_t<Impl::ViewCtorProp<P...>::has_pointer,
590  const typename traits::array_layout&>
591  arg_layout)
592  : base_t(
593  arg_prop,
594  Impl::mapping_from_array_layout<typename mdspan_type::mapping_type>(
595  arg_layout)) {}
596 
597 #ifdef KOKKOS_ENABLE_CXX17
598  template <class Layout>
599  KOKKOS_FUNCTION explicit View(
600  const typename base_t::data_handle_type& handle, const Layout& arg_layout,
601  std::enable_if_t<
602  (std::is_same_v<Layout, LayoutStride> &&
603  std::is_same_v<typename base_t::layout_type, layout_stride>) ||
604  (std::is_same_v<Layout, LayoutLeft> &&
605  std::is_same_v<typename base_t::layout_type, layout_left>) ||
606  (std::is_same_v<Layout, LayoutLeft> &&
607  std::is_same_v<typename base_t::layout_type,
608  Experimental::layout_left_padded<> >) ||
609  (std::is_same_v<Layout, LayoutRight> &&
610  std::is_same_v<typename base_t::layout_type, layout_right>) ||
611  (std::is_same_v<Layout, LayoutRight> &&
612  std::is_same_v<typename base_t::layout_type,
613  Experimental::layout_right_padded<> >),
614  void*> = nullptr)
615  : base_t(
616  handle,
617  Impl::mapping_from_array_layout<typename mdspan_type::mapping_type>(
618  arg_layout)) {}
619 #else
620  // Constructors from legacy layouts when using Views of the new layouts
621  // LayoutLeft -> layout_left, layout_left_padded
622  // LayoutRight -> layout_right, layout_right_padded
623  // LayoutStride -> layout_stride
624  KOKKOS_FUNCTION
625  explicit View(const typename base_t::data_handle_type& handle,
626  const LayoutStride& arg_layout)
627  requires(std::is_same_v<typename base_t::layout_type, layout_stride>)
628  : base_t(
629  handle,
630  Impl::mapping_from_array_layout<typename mdspan_type::mapping_type>(
631  arg_layout)) {}
632 
633  KOKKOS_FUNCTION
634  explicit View(const typename base_t::data_handle_type& handle,
635  const LayoutLeft& arg_layout)
636  requires(std::is_same_v<typename base_t::layout_type,
637  Experimental::layout_left_padded<> >)
638  : base_t(
639  handle,
640  Impl::mapping_from_array_layout<typename mdspan_type::mapping_type>(
641  arg_layout)) {}
642 
643  KOKKOS_FUNCTION
644  explicit View(const typename base_t::data_handle_type& handle,
645  const LayoutRight& arg_layout)
646  requires(std::is_same_v<typename base_t::layout_type,
647  Experimental::layout_right_padded<> >)
648  : base_t(
649  handle,
650  Impl::mapping_from_array_layout<typename mdspan_type::mapping_type>(
651  arg_layout)) {}
652 
653  KOKKOS_FUNCTION
654  explicit View(const typename base_t::data_handle_type& handle,
655  const LayoutLeft& arg_layout)
656  requires(std::is_same_v<typename base_t::layout_type, layout_left>)
657  : base_t(
658  handle,
659  Impl::mapping_from_array_layout<typename mdspan_type::mapping_type>(
660  arg_layout)) {}
661 
662  KOKKOS_FUNCTION
663  explicit View(const typename base_t::data_handle_type& handle,
664  const LayoutRight& arg_layout)
665  requires(std::is_same_v<typename base_t::layout_type, layout_right>)
666  : base_t(
667  handle,
668  Impl::mapping_from_array_layout<typename mdspan_type::mapping_type>(
669  arg_layout)) {}
670 #endif
671 
672 #ifndef KOKKOS_ENABLE_CXX17
673  template <class P, class... Args>
674  requires(!std::is_null_pointer_v<P> &&
675  std::is_constructible_v<typename base_t::data_handle_type, P> &&
676  sizeof...(Args) != rank() + 1)
677  KOKKOS_FUNCTION View(P ptr_, Args... args)
678  : View(Kokkos::view_wrap(static_cast<pointer_type>(ptr_)), args...) {}
679 
680  // Special function to be preferred over the above for string literals
681  // when pointer type is char*
682  template <class L, class... Args>
683  requires(std::is_same_v<pointer_type, char*> &&
684  std::is_same_v<const char*, L>)
685  explicit View(L label, Args... args)
686  : View(Kokkos::view_alloc(std::string(label)), args...) {}
687 
688  // Special function to be preferred over the above for passing in 0, NULL or
689  // nullptr when pointer type is char*
690  template <class... Args>
691  explicit View(decltype(nullptr), Args... args)
692  : View(Kokkos::view_wrap(pointer_type(nullptr)), args...) {}
693 #else
694  // FIXME: The std::is_null_pointer_v<P> condition is to workaround a GCC8 bug
695  // in overload resolution
696  // FIXME: why does modernize-type-traits have a false positive here?
697  // NOLINTBEGIN(modernize-type-traits)
698  template <class P, class... Args,
699  std::enable_if_t<!std::is_null_pointer_v<P> &&
700  std::is_constructible_v<
701  typename base_t::data_handle_type, P> &&
702  sizeof...(Args) != rank() + 1,
703  size_t> = 0ul>
704  // NOLINTEND(modernize-type-traits)
705  KOKKOS_FUNCTION View(P ptr_, Args... args)
706  : View(Kokkos::view_wrap(static_cast<pointer_type>(ptr_)), args...) {}
707 
708  // Special function to be preferred over the above for string literals
709  // when pointer type is char*
710  // The typename P = pointer_type is a workaround for an nvcc 11.0 bug
711  // where the compiler performs substitution earlier when the class is
712  // instantiated instead of at function instantiation and therefore errors out
713  // on these enable_ifs
714  // FIXME: why does modernize-type-traits have a false positive here?
715  // NOLINTBEGIN(modernize-type-traits)
716  template <class L, class... Args, typename P = pointer_type,
717  std::enable_if_t<(std::is_same_v<P, char*> &&
718  std::is_same_v<const char*, L>),
719  size_t> = 0ul>
720  // NOLINTEND(modernize-type-traits)
721  explicit View(L label, Args... args)
722  : View(Kokkos::view_alloc(std::string(label)), args...) {}
723 
724  // Special function to be preferred over the above for passing in 0, NULL or
725  // nullptr when pointer type is char*
726  template <class... Args>
727  explicit View(decltype(nullptr), Args... args)
728  : View(Kokkos::view_wrap(pointer_type(nullptr)), args...) {}
729 #endif
730 
731  // FIXME: Constructor which allows always 8 sizes should be deprecated
732  template <class... P>
733  explicit View(
734  const Impl::ViewCtorProp<P...>& arg_prop,
735  std::enable_if_t<!Impl::ViewCtorProp<P...>::has_pointer, const size_t>
736  arg_N0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
737  const size_t arg_N1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
738  const size_t arg_N2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
739  const size_t arg_N3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
740  const size_t arg_N4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
741  const size_t arg_N5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
742  const size_t arg_N6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
743  const size_t arg_N7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
744  : base_t(arg_prop,
745  Impl::mapping_from_ctor_and_8sizes<
746  typename mdspan_type::mapping_type, sizeof(value_type)>(
747  arg_prop, arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5,
748  arg_N6, arg_N7)) {
749 #ifdef KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK
750  if constexpr (std::is_same_v<typename traits::array_layout,
752  std::is_same_v<typename traits::array_layout,
754  std::is_same_v<typename traits::array_layout,
756  auto prop_copy = Impl::with_properties_if_unset(arg_prop, std::string{});
757  const std::string& alloc_name =
758  Impl::get_property<Impl::LabelTag>(prop_copy);
759 
760  Impl::runtime_check_rank(*this, !traits::impl_is_customized, arg_N0,
761  arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6,
762  arg_N7, alloc_name.c_str());
763  }
764 #endif
765  static_assert(traits::array_layout::is_extent_constructible,
766  "Layout is not constructible from extent arguments. Use "
767  "overload taking a layout object instead.");
768  static_assert(traits::is_managed,
769  "Can't construct managed View with unmanaged memory trait!");
770  }
771 
772  template <class... P>
773  KOKKOS_FUNCTION explicit View(
774  const Impl::ViewCtorProp<P...>& arg_prop,
775  std::enable_if_t<Impl::ViewCtorProp<P...>::has_pointer, const size_t>
776  arg_N0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
777  const size_t arg_N1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
778  const size_t arg_N2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
779  const size_t arg_N3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
780  const size_t arg_N4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
781  const size_t arg_N5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
782  const size_t arg_N6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
783  const size_t arg_N7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
784  : base_t(arg_prop,
785  Impl::mapping_from_ctor_and_8sizes<
786  typename mdspan_type::mapping_type, sizeof(value_type)>(
787  arg_prop, arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5,
788  arg_N6, arg_N7)) {
789 #ifdef KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK
790  if constexpr (std::is_same_v<typename traits::array_layout,
792  std::is_same_v<typename traits::array_layout,
794  std::is_same_v<typename traits::array_layout,
796  Impl::runtime_check_rank(*this, !traits::impl_is_customized, arg_N0,
797  arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6,
798  arg_N7, "UNMANAGED");
799  }
800 #endif
801  static_assert(traits::array_layout::is_extent_constructible,
802  "Layout is not constructible from extent arguments. Use "
803  "overload taking a layout object instead.");
804  }
805 
806  // Allocate with label and layout
807  template <typename Label>
808  explicit View(
809  const Label& arg_label,
810  std::enable_if_t<Kokkos::Impl::is_view_label<Label>::value,
811  typename traits::array_layout> const& arg_layout)
812  : View(Impl::ViewCtorProp<std::string>(arg_label), arg_layout) {}
813 
814 #ifdef KOKKOS_COMPILER_MSVC // FIXME_MSVC
815  // MSVC had pack expansion issues with the condition inside the enable_if
816  private:
817  template <class... Args>
818  static constexpr bool msvc_workaround_ctor_condition_1() {
819  size_t num_args = sizeof...(Args);
820  bool are_constructible =
821  (std::is_constructible_v<size_t, Args> && ... && true);
822  return (num_args != rank() + 1) && are_constructible;
823  }
824 
825  public:
826 #endif
827 
828  template <class... Args>
829  View(std::enable_if_t<
830 #ifndef KOKKOS_COMPILER_MSVC
831  ((sizeof...(Args)) != rank() + 1) &&
832  (std::is_constructible_v<size_t, Args> && ... && true),
833 #else
834  msvc_workaround_ctor_condition_1<Args...>(),
835 #endif
836  const std::string&>
837  arg_label,
838  const Args... args)
839 #ifdef KOKKOS_COMPILER_INTEL_LLVM // FIXME_INTEL
840  // Eventually we want to get rid of the array_layout thing entirely.
841  // For now this avoids a bug in the intel compiler 2024.2, and 2025 tested
842  // that only happens with O2 or higher and makes some extents not being
843  // set See https://github.com/kokkos/kokkos/pull/8202
844  : View(Impl::ViewCtorProp<std::string>(arg_label),
845  typename traits::array_layout(args...)) {
846 #else
847  : View(Impl::ViewCtorProp<std::string>(arg_label), args...) {
848 #endif
849  }
850 
851  private:
852  // Special thing for Sacado taking rank()+1 integers, where the last integer
853  // is the FAD dimension
854  template <class... Args, size_t... Idx>
855  static auto view_alloc_from_label_and_integrals(std::true_type,
856  const std::string& arg_label,
857  std::index_sequence<Idx...>,
858  Args... args) {
859  return view_alloc(arg_label, Impl::AccessorArg_t{static_cast<size_t>(
860  ((Idx == rank() ? args : 0) + ... + 0))});
861  }
862 
863  template <class... Args, size_t... Idx>
864  static auto view_alloc_from_label_and_integrals(std::false_type,
865  const std::string& arg_label,
866  std::index_sequence<Idx...>,
867  Args...) {
868  return view_alloc(arg_label);
869  }
870 
871 #ifdef KOKKOS_COMPILER_MSVC // FIXME_MSVC
872  // Same as above but checking for num_args equal to rank()+1
873  template <class... Args>
874  static constexpr bool msvc_workaround_ctor_condition_2() {
875  size_t num_args = sizeof...(Args);
876  bool are_constructible =
877  (std::is_constructible_v<size_t, Args> && ... && true);
878  return (num_args == rank() + 1) && are_constructible;
879  }
880 #endif
881 
882  public:
883  template <class... Args>
884  View(std::enable_if_t<
885 #ifndef KOKKOS_COMPILER_MSVC
886  ((sizeof...(Args)) == rank() + 1) &&
887  (std::is_constructible_v<size_t, Args> && ... && true),
888 #else
889  msvc_workaround_ctor_condition_2<Args...>(),
890 #endif
891  const std::string&>
892  arg_label,
893  const Args... args)
894  : View(
895  view_alloc_from_label_and_integrals(
896  std::bool_constant<traits::impl_is_customized>(), arg_label,
897  std::make_index_sequence<sizeof...(Args)>(), args...),
898 #ifdef KOKKOS_COMPILER_INTEL_LLVM // FIXME_INTEL
899  // Eventually we want to get rid of the array_layout thing entirely.
900  // For now this avoids a bug in the intel compiler 2024.2, and 2025
901  // tested that only happens with O2 or higher and makes some extents
902  // not being set See https://github.com/kokkos/kokkos/pull/8202
903  typename traits::array_layout(args...)) {
904 #else
905  args...) {
906 #endif
907  }
908 
909  template <class... Args>
910  View(std::enable_if_t<
911 #ifndef KOKKOS_COMPILER_MSVC
912  ((sizeof...(Args)) == rank() + 1) &&
913  (std::is_constructible_v<size_t, Args> && ... && true),
914 #else
915  msvc_workaround_ctor_condition_2<Args...>(),
916 #endif
917  const pointer_type&>
918  arg_ptr,
919  const Args... args)
920  : View(
921  Kokkos::view_wrap(arg_ptr,
922  Kokkos::Impl::AccessorArg_t{
923  Kokkos::Array<size_t, sizeof...(Args)>{
924  static_cast<size_t>(args)...}[rank()]}),
925 #ifdef KOKKOS_COMPILER_INTEL_LLVM // FIXME_INTEL
926  // Eventually we want to get rid of the array_layout thing entirely.
927  // For now this avoids a bug in the intel compiler 2024.2, and 2025
928  // tested that only happens with O2 or higher and makes some extents
929  // not being set See https://github.com/kokkos/kokkos/pull/8202
930  typename traits::array_layout(args...)) {
931 #else
932  args...) {
933 #endif
934  }
935 
936  //----------------------------------------
937  // Memory span required to wrap these dimensions.
938  KOKKOS_FUNCTION
939  static constexpr size_t required_allocation_size(
940  typename traits::array_layout const& layout) {
941  return Impl::mapping_from_array_layout<typename base_t::mapping_type>(
942  layout)
943  .required_span_size() *
944  sizeof(raw_allocation_value_type);
945  }
946 
947  KOKKOS_FUNCTION
948  static constexpr size_t required_allocation_size(
949  const size_t arg_N0 = 0, const size_t arg_N1 = 0, const size_t arg_N2 = 0,
950  const size_t arg_N3 = 0, const size_t arg_N4 = 0, const size_t arg_N5 = 0,
951  const size_t arg_N6 = 0, const size_t arg_N7 = 0) {
952  static_assert(traits::array_layout::is_extent_constructible,
953  "Layout is not constructible from extent arguments. Use "
954  "overload taking a layout object instead.");
955  return required_allocation_size(typename traits::array_layout(
956  arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7));
957  }
958 
959  //----------------------------------------
960  // Shared scratch memory constructor
961 
962  static KOKKOS_INLINE_FUNCTION size_t
963  shmem_size(const size_t arg_N0 = KOKKOS_INVALID_INDEX,
964  const size_t arg_N1 = KOKKOS_INVALID_INDEX,
965  const size_t arg_N2 = KOKKOS_INVALID_INDEX,
966  const size_t arg_N3 = KOKKOS_INVALID_INDEX,
967  const size_t arg_N4 = KOKKOS_INVALID_INDEX,
968  const size_t arg_N5 = KOKKOS_INVALID_INDEX,
969  const size_t arg_N6 = KOKKOS_INVALID_INDEX,
970  const size_t arg_N7 = KOKKOS_INVALID_INDEX) {
971  static_assert(traits::array_layout::is_extent_constructible,
972  "Layout is not constructible from extent arguments. Use "
973  "overload taking a layout object instead.");
974  const size_t num_passed_args = Impl::count_valid_integers(
975  arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7);
976 
977  // Special case to cover sacado which passes in an extra integer
978  if (traits::impl_is_customized && num_passed_args == rank_dynamic + 1) {
979  size_t extra_dim = 0;
980  switch (rank_dynamic) {
981  case 0: extra_dim = arg_N0; break;
982  case 1: extra_dim = arg_N1; break;
983  case 2: extra_dim = arg_N2; break;
984  case 3: extra_dim = arg_N3; break;
985  case 4: extra_dim = arg_N4; break;
986  case 5: extra_dim = arg_N5; break;
987  case 6: extra_dim = arg_N6; break;
988  case 7: extra_dim = arg_N7; break;
989  default:
990  Kokkos::abort("This can't happen: rank_dynamic is smaller than 8");
991  }
992  return View::shmem_size(
993  typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3, arg_N4,
994  arg_N5, arg_N6, arg_N7),
995  extra_dim);
996  } else {
997  if (num_passed_args != rank_dynamic) {
998  Kokkos::abort(
999  "Kokkos::View::shmem_size() rank_dynamic != number of "
1000  "arguments.\n");
1001  }
1002  return View::shmem_size(
1003  typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3, arg_N4,
1004  arg_N5, arg_N6, arg_N7),
1005  1);
1006  }
1007  }
1008 
1009  static KOKKOS_INLINE_FUNCTION size_t
1010  shmem_size(typename traits::array_layout const& arg_layout) {
1011  return shmem_size(arg_layout, 1);
1012  }
1013 
1014  private:
1015  // Want to be able to align to minimum scratch alignment or sizeof or alignof
1016  // elements
1017  static constexpr size_t scratch_value_alignment = max(
1018  {sizeof(raw_allocation_value_type), alignof(raw_allocation_value_type),
1019  static_cast<size_t>(
1020  traits::execution_space::scratch_memory_space::ALIGN)});
1021 
1022  static KOKKOS_INLINE_FUNCTION size_t shmem_size(
1023  typename traits::array_layout const& arg_layout, size_t extra_dim) {
1024  return Impl::mapping_from_array_layout<typename base_t::mapping_type>(
1025  arg_layout)
1026  .required_span_size() *
1027  sizeof(raw_allocation_value_type) * extra_dim +
1028  scratch_value_alignment;
1029  }
1030 
1031  public:
1032  explicit KOKKOS_INLINE_FUNCTION View(
1033  const typename traits::execution_space::scratch_memory_space& arg_space,
1034  const typename traits::array_layout& arg_layout)
1035  : View(Impl::ViewCtorProp<pointer_type>(
1036  static_cast<pointer_type>(arg_space.get_shmem_aligned(
1037  Kokkos::Impl::ViewMapping<
1038  traits,
1039  typename traits::specialize>::memory_span(arg_layout),
1040  scratch_value_alignment))),
1041  arg_layout) {}
1042 
1043  explicit KOKKOS_INLINE_FUNCTION View(
1044  const typename traits::execution_space::scratch_memory_space& arg_space,
1045  const size_t arg_N0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1046  const size_t arg_N1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1047  const size_t arg_N2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1048  const size_t arg_N3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1049  const size_t arg_N4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1050  const size_t arg_N5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1051  const size_t arg_N6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1052  const size_t arg_N7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
1053  : View(Impl::ViewCtorProp<pointer_type>(
1054  static_cast<pointer_type>(arg_space.get_shmem_aligned(
1055  required_allocation_size(typename traits::array_layout(
1056  arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6,
1057  arg_N7)),
1058  scratch_value_alignment))),
1059  typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3,
1060  arg_N4, arg_N5, arg_N6, arg_N7)) {
1061  static_assert(traits::array_layout::is_extent_constructible,
1062  "Layout is not constructible from extent arguments. Use "
1063  "overload taking a layout object instead.");
1064  }
1065 
1066  public:
1067  //----------------------------------------
1068  // Allocation tracking properties
1069  std::string label() const {
1070  if constexpr (traits::is_managed) {
1071  return this->data_handle().get_label();
1072  } else {
1073  return "";
1074  }
1075  }
1076 
1077  int use_count() const {
1078  if constexpr (traits::is_managed) {
1079  return this->data_handle().use_count();
1080  } else {
1081  return 0;
1082  }
1083  }
1084 
1085  KOKKOS_FUNCTION
1086  constexpr typename base_t::index_type extent(size_t r) const noexcept {
1087  // casting to int to avoid warning for pointless comparison of unsigned
1088  // with 0
1089  if (static_cast<int>(r) >= static_cast<int>(base_t::extents_type::rank()))
1090  return 1;
1091  return base_t::extent(r);
1092  }
1093 
1094  KOKKOS_FUNCTION
1095  static constexpr size_t static_extent(size_t r) noexcept {
1096  // casting to int to avoid warning for pointless comparison of unsigned
1097  // with 0
1098  if (static_cast<int>(r) >= static_cast<int>(base_t::extents_type::rank()))
1099  return 1;
1100  size_t value = base_t::extents_type::static_extent(r);
1101  return value == Kokkos::dynamic_extent ? 0 : value;
1102  }
1103 };
1104 
1105 template <typename D, class... P>
1106 KOKKOS_INLINE_FUNCTION constexpr unsigned rank(const View<D, P...>&) {
1107  return View<D, P...>::rank();
1108 }
1109 
1110 namespace Impl {
1111 
1112 template <typename ValueType, unsigned int Rank>
1113 struct RankDataType {
1114  using type = typename RankDataType<ValueType, Rank - 1>::type*;
1115 };
1116 
1117 template <typename ValueType>
1118 struct RankDataType<ValueType, 0> {
1119  using type = ValueType;
1120 };
1121 
1122 template <unsigned N, typename... Args>
1123 KOKKOS_FUNCTION std::enable_if_t<
1124  N == View<Args...>::rank() &&
1125  std::is_same_v<typename ViewTraits<Args...>::specialize, void>,
1126  View<Args...> >
1127 as_view_of_rank_n(View<Args...> v) {
1128  return v;
1129 }
1130 
1131 // Placeholder implementation to compile generic code for DynRankView; should
1132 // never be called
1133 template <unsigned N, typename T, typename... Args>
1134 KOKKOS_FUNCTION std::enable_if_t<
1135  N != View<T, Args...>::rank() &&
1136  std::is_same_v<typename ViewTraits<T, Args...>::specialize, void>,
1137  View<typename RankDataType<typename View<T, Args...>::value_type, N>::type,
1138  Args...> >
1139 as_view_of_rank_n(View<T, Args...>) {
1140  Kokkos::abort("Trying to get at a View of the wrong rank");
1141  return {};
1142 }
1143 
1144 template <typename ViewType>
1145 struct ApplyToViewOfStaticRank {
1146  template <typename Function>
1147  static void apply(Function&& f, ViewType a) {
1148  f(a);
1149  }
1150 };
1151 
1152 } // namespace Impl
1153 //----------------------------------------------------------------------------
1154 //----------------------------------------------------------------------------
1155 
1156 template <class D, class... P, class... Args>
1157 KOKKOS_INLINE_FUNCTION auto subview(const View<D, P...>& src, Args... args) {
1158  static_assert(View<D, P...>::rank == sizeof...(Args),
1159  "subview requires one argument for each source View rank");
1160 
1161  return typename Kokkos::Impl::ViewMapping<
1162  void /* deduce subview type from source view traits */
1163  ,
1164  typename Impl::RemoveAlignedMemoryTrait<D, P...>::type,
1165  Args...>::type(src, args...);
1166 }
1167 
1168 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
1169 template <class MemoryTraits, class D, class... P, class... Args>
1170 KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION auto subview(const View<D, P...>& src,
1171  Args... args) {
1172  static_assert(View<D, P...>::rank == sizeof...(Args),
1173  "subview requires one argument for each source View rank");
1174  static_assert(Kokkos::is_memory_traits<MemoryTraits>::value);
1175 
1176  return typename Kokkos::Impl::ViewMapping<
1177  void /* deduce subview type from source view traits */
1178  ,
1179  typename Impl::RemoveAlignedMemoryTrait<D, P..., MemoryTraits>::type,
1180  Args...>::type(src, args...);
1181 }
1182 #endif
1183 
1184 template <class V, class... Args>
1185 using Subview = decltype(subview(std::declval<V>(), std::declval<Args>()...));
1186 
1187 } /* namespace Kokkos */
1188 
1189 //----------------------------------------------------------------------------
1190 //----------------------------------------------------------------------------
1191 
1192 namespace Kokkos {
1193 
1194 template <class LT, class... LP, class RT, class... RP>
1195 KOKKOS_INLINE_FUNCTION bool operator==(const View<LT, LP...>& lhs,
1196  const View<RT, RP...>& rhs) {
1197  // Same data, layout, dimensions
1198  using lhs_traits = ViewTraits<LT, LP...>;
1199  using rhs_traits = ViewTraits<RT, RP...>;
1200 
1201  return std::is_same_v<typename lhs_traits::const_value_type,
1202  typename rhs_traits::const_value_type> &&
1203  std::is_same_v<typename lhs_traits::array_layout,
1204  typename rhs_traits::array_layout> &&
1205  std::is_same_v<typename lhs_traits::memory_space,
1206  typename rhs_traits::memory_space> &&
1207  View<LT, LP...>::rank() == View<RT, RP...>::rank() &&
1208  lhs.data() == rhs.data() && lhs.span() == rhs.span() &&
1209  lhs.extent(0) == rhs.extent(0) && lhs.extent(1) == rhs.extent(1) &&
1210  lhs.extent(2) == rhs.extent(2) && lhs.extent(3) == rhs.extent(3) &&
1211  lhs.extent(4) == rhs.extent(4) && lhs.extent(5) == rhs.extent(5) &&
1212  lhs.extent(6) == rhs.extent(6) && lhs.extent(7) == rhs.extent(7);
1213 }
1214 
1215 template <class LT, class... LP, class RT, class... RP>
1216 KOKKOS_INLINE_FUNCTION bool operator!=(const View<LT, LP...>& lhs,
1217  const View<RT, RP...>& rhs) {
1218  return !(operator==(lhs, rhs));
1219 }
1220 
1221 } /* namespace Kokkos */
1222 
1223 // FIXME: https://github.com/kokkos/kokkos/issues/7736 We may want to move these
1224 // out
1225 #include <View/Kokkos_ViewCommonType.hpp>
1226 #include <View/Kokkos_ViewUniformType.hpp>
1227 #include <View/Kokkos_ViewAtomic.hpp>
1228 
1229 //----------------------------------------------------------------------------
1230 //----------------------------------------------------------------------------
1231 
1232 #endif /* KOKKOS_ENABLE_IMPL_VIEW_LEGACY */
1233 #endif /* #ifndef KOKKOS_VIEW_HPP */
Memory layout tag indicating left-to-right (Fortran scheme) striding of multi-indices.
Derived from the C++17 &#39;std::array&#39;. Dropping the iterator interface.
Memory layout tag indicated arbitrarily strided multi-index mapping into contiguous memory...
Memory layout tag indicating right-to-left (C or lexigraphical scheme) striding of multi-indices...