Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Kokkos_DynRankView.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 
22 
23 #ifndef KOKKOS_DYNRANKVIEW_HPP
24 #define KOKKOS_DYNRANKVIEW_HPP
25 #ifndef KOKKOS_IMPL_PUBLIC_INCLUDE
26 #define KOKKOS_IMPL_PUBLIC_INCLUDE
27 #define KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_DYNRANKVIEW
28 #endif
29 
30 #include <Kokkos_Core.hpp>
31 #include <KokkosExp_InterOp.hpp>
32 #include <impl/Kokkos_Error.hpp>
33 #include <type_traits>
34 
35 namespace Kokkos {
36 
37 template <typename DataType, class... Properties>
38 class DynRankView; // forward declare
39 
40 namespace Impl {
41 
42 template <class T, size_t Rank>
43 struct ViewDataTypeFromRank {
44  using type = typename ViewDataTypeFromRank<T, Rank - 1>::type*;
45 };
46 
47 template <class T>
48 struct ViewDataTypeFromRank<T, 0> {
49  using type = T;
50 };
51 
52 template <unsigned N, typename T, typename... Args>
53 KOKKOS_FUNCTION View<typename ViewDataTypeFromRank<T, N>::type, Args...>
54 as_view_of_rank_n(
55  DynRankView<T, Args...> v,
56  std::enable_if_t<std::is_same_v<typename ViewTraits<T, Args...>::specialize,
57  void>>* = nullptr);
58 
59 // TODO: Replace this specialized with a bool
60 template <typename Specialize>
61 struct DynRankDimTraits {
62  enum : size_t { unspecified = KOKKOS_INVALID_INDEX };
63 
64  // Compute the rank of the view from the nonzero dimension arguments.
65  KOKKOS_INLINE_FUNCTION
66  static size_t computeRank(const size_t N0, const size_t N1, const size_t N2,
67  const size_t N3, const size_t N4, const size_t N5,
68  const size_t N6, const size_t /* N7 */) {
69  return (
70  (N6 == unspecified && N5 == unspecified && N4 == unspecified &&
71  N3 == unspecified && N2 == unspecified && N1 == unspecified &&
72  N0 == unspecified)
73  ? 0
74  : ((N6 == unspecified && N5 == unspecified && N4 == unspecified &&
75  N3 == unspecified && N2 == unspecified && N1 == unspecified)
76  ? 1
77  : ((N6 == unspecified && N5 == unspecified &&
78  N4 == unspecified && N3 == unspecified &&
79  N2 == unspecified)
80  ? 2
81  : ((N6 == unspecified && N5 == unspecified &&
82  N4 == unspecified && N3 == unspecified)
83  ? 3
84  : ((N6 == unspecified && N5 == unspecified &&
85  N4 == unspecified)
86  ? 4
87  : ((N6 == unspecified &&
88  N5 == unspecified)
89  ? 5
90  : ((N6 == unspecified)
91  ? 6
92  : 7)))))));
93  }
94 
95  // Compute the rank of the view from the nonzero layout arguments.
96  template <typename Layout>
97  KOKKOS_INLINE_FUNCTION static size_t computeRank(const Layout& layout) {
98  return computeRank(layout.dimension[0], layout.dimension[1],
99  layout.dimension[2], layout.dimension[3],
100  layout.dimension[4], layout.dimension[5],
101  layout.dimension[6], layout.dimension[7]);
102  }
103 
104  // Extra overload to match that for specialize types v2
105  template <typename Layout, typename... P>
106  KOKKOS_INLINE_FUNCTION static size_t computeRank(
107  const Kokkos::Impl::ViewCtorProp<P...>& /* prop */,
108  const Layout& layout) {
109  return computeRank(layout);
110  }
111 
112  // Create the layout for the rank-7 view.
113  // Because the underlying View is rank-7, preserve "unspecified" for
114  // dimension 8.
115 
116  // Non-strided Layout
117  template <typename Layout>
118  KOKKOS_INLINE_FUNCTION static std::enable_if_t<
119  (std::is_same_v<Layout, Kokkos::LayoutRight> ||
120  std::is_same_v<Layout, Kokkos::LayoutLeft>),
121  Layout>
122  createLayout(const Layout& layout) {
123  Layout new_layout(
124  layout.dimension[0] != unspecified ? layout.dimension[0] : 1,
125  layout.dimension[1] != unspecified ? layout.dimension[1] : 1,
126  layout.dimension[2] != unspecified ? layout.dimension[2] : 1,
127  layout.dimension[3] != unspecified ? layout.dimension[3] : 1,
128  layout.dimension[4] != unspecified ? layout.dimension[4] : 1,
129  layout.dimension[5] != unspecified ? layout.dimension[5] : 1,
130  layout.dimension[6] != unspecified ? layout.dimension[6] : 1,
131  layout.dimension[7] != unspecified ? layout.dimension[7] : unspecified);
132 
133 #ifndef KOKKOS_ENABLE_IMPL_VIEW_LEGACY
134  // In order to have a valid LayoutRight stride when Sacado passes through
135  // extra integer arguments, we need to set it to the dimension[6] for the
136  // rank-7 view coming out of here. Only if the original layout was already
137  // rank-7 we can preserve the stride.
138  // FIXME_SACADO
139  if constexpr (!std::is_same_v<Specialize, void> &&
140  std::is_same_v<Layout, Kokkos::LayoutRight>) {
141  if (layout.dimension[6] == unspecified) {
142  new_layout.stride = unspecified;
143  } else {
144  new_layout.stride = layout.stride;
145  }
146  } else
147 #endif
148  new_layout.stride = layout.stride;
149  return new_layout;
150  }
151 
152  // LayoutStride
153  template <typename Layout>
154  KOKKOS_INLINE_FUNCTION static std::enable_if_t<
155  (std::is_same_v<Layout, Kokkos::LayoutStride>), Layout>
156  createLayout(const Layout& layout) {
157  return Layout(
158  layout.dimension[0] != unspecified ? layout.dimension[0] : 1,
159  layout.stride[0],
160  layout.dimension[1] != unspecified ? layout.dimension[1] : 1,
161  layout.stride[1],
162  layout.dimension[2] != unspecified ? layout.dimension[2] : 1,
163  layout.stride[2],
164  layout.dimension[3] != unspecified ? layout.dimension[3] : 1,
165  layout.stride[3],
166  layout.dimension[4] != unspecified ? layout.dimension[4] : 1,
167  layout.stride[4],
168  layout.dimension[5] != unspecified ? layout.dimension[5] : 1,
169  layout.stride[5],
170  layout.dimension[6] != unspecified ? layout.dimension[6] : 1,
171  layout.stride[6],
172  layout.dimension[7] != unspecified ? layout.dimension[7] : unspecified,
173  layout.stride[7]);
174  }
175 
176  // Extra overload to match that for specialize types
177  template <typename Traits, typename... P>
178  KOKKOS_INLINE_FUNCTION static std::enable_if_t<
179  (std::is_same_v<typename Traits::array_layout, Kokkos::LayoutRight> ||
180  std::is_same_v<typename Traits::array_layout, Kokkos::LayoutLeft> ||
181  std::is_same_v<typename Traits::array_layout, Kokkos::LayoutStride>),
182  typename Traits::array_layout>
183  createLayout([[maybe_unused]] const Kokkos::Impl::ViewCtorProp<P...>& prop,
184  typename Traits::array_layout layout) {
185 // FIXME_SACADO this is only needed for special extra int treatment
186 #ifndef KOKKOS_ENABLE_IMPL_VIEW_LEGACY
187  if constexpr (Traits::impl_is_customized &&
188  !Kokkos::Impl::ViewCtorProp<P...>::has_accessor_arg) {
189  auto rank = computeRank(prop, layout) - 1;
190  layout.dimension[rank] = unspecified;
191  }
192 #endif
193  return createLayout(layout);
194  }
195 
196  // Create a view from the given dimension arguments.
197  // This is only necessary because the shmem constructor doesn't take a layout.
198  // NDE shmem View's are not compatible with the added view_alloc value_type
199  // / fad_dim deduction functionality
200  template <typename ViewType, typename ViewArg>
201  static ViewType createView(const ViewArg& arg, const size_t N0,
202  const size_t N1, const size_t N2, const size_t N3,
203  const size_t N4, const size_t N5, const size_t N6,
204  const size_t N7) {
205  return ViewType(arg, N0 != unspecified ? N0 : 1, N1 != unspecified ? N1 : 1,
206  N2 != unspecified ? N2 : 1, N3 != unspecified ? N3 : 1,
207  N4 != unspecified ? N4 : 1, N5 != unspecified ? N5 : 1,
208  N6 != unspecified ? N6 : 1, N7 != unspecified ? N7 : 1);
209  }
210 };
211 
212 // Non-strided Layout
213 template <typename Layout, typename iType>
214 KOKKOS_INLINE_FUNCTION std::enable_if_t<
215  (std::is_same_v<Layout, Kokkos::LayoutRight> ||
216  std::is_same_v<Layout, Kokkos::LayoutLeft>)&&std::is_integral_v<iType>,
217  Layout>
218 reconstructLayout(const Layout& layout, iType dynrank) {
219  return Layout(dynrank > 0 ? layout.dimension[0] : KOKKOS_INVALID_INDEX,
220  dynrank > 1 ? layout.dimension[1] : KOKKOS_INVALID_INDEX,
221  dynrank > 2 ? layout.dimension[2] : KOKKOS_INVALID_INDEX,
222  dynrank > 3 ? layout.dimension[3] : KOKKOS_INVALID_INDEX,
223  dynrank > 4 ? layout.dimension[4] : KOKKOS_INVALID_INDEX,
224  dynrank > 5 ? layout.dimension[5] : KOKKOS_INVALID_INDEX,
225  dynrank > 6 ? layout.dimension[6] : KOKKOS_INVALID_INDEX,
226  dynrank > 7 ? layout.dimension[7] : KOKKOS_INVALID_INDEX);
227 }
228 
229 // LayoutStride
230 template <typename Layout, typename iType>
231 KOKKOS_INLINE_FUNCTION std::enable_if_t<
232  (std::is_same_v<Layout, Kokkos::LayoutStride>)&&std::is_integral_v<iType>,
233  Layout>
234 reconstructLayout(const Layout& layout, iType dynrank) {
235  return Layout(dynrank > 0 ? layout.dimension[0] : KOKKOS_INVALID_INDEX,
236  dynrank > 0 ? layout.stride[0] : (0),
237  dynrank > 1 ? layout.dimension[1] : KOKKOS_INVALID_INDEX,
238  dynrank > 1 ? layout.stride[1] : (0),
239  dynrank > 2 ? layout.dimension[2] : KOKKOS_INVALID_INDEX,
240  dynrank > 2 ? layout.stride[2] : (0),
241  dynrank > 3 ? layout.dimension[3] : KOKKOS_INVALID_INDEX,
242  dynrank > 3 ? layout.stride[3] : (0),
243  dynrank > 4 ? layout.dimension[4] : KOKKOS_INVALID_INDEX,
244  dynrank > 4 ? layout.stride[4] : (0),
245  dynrank > 5 ? layout.dimension[5] : KOKKOS_INVALID_INDEX,
246  dynrank > 5 ? layout.stride[5] : (0),
247  dynrank > 6 ? layout.dimension[6] : KOKKOS_INVALID_INDEX,
248  dynrank > 6 ? layout.stride[6] : (0),
249  dynrank > 7 ? layout.dimension[7] : KOKKOS_INVALID_INDEX,
250  dynrank > 7 ? layout.stride[7] : (0));
251 }
252 
254 // Enhanced debug checking - most infrastructure matches that of functions in
255 // Kokkos_ViewMapping; additional checks for extra arguments beyond rank are 0
256 template <unsigned, typename iType0, class MapType>
257 KOKKOS_INLINE_FUNCTION bool dyn_rank_view_verify_operator_bounds(
258  const iType0&, const MapType&) {
259  return true;
260 }
261 
262 template <unsigned R, typename iType0, class MapType, typename iType1,
263  class... Args>
264 KOKKOS_INLINE_FUNCTION bool dyn_rank_view_verify_operator_bounds(
265  const iType0& rank, const MapType& map, const iType1& i, Args... args) {
266  if (static_cast<iType0>(R) < rank) {
267  return (size_t(i) < map.extent(R)) &&
268  dyn_rank_view_verify_operator_bounds<R + 1>(rank, map, args...);
269  } else if (i != 0) {
270  Kokkos::printf(
271  "DynRankView Debug Bounds Checking Error: at rank %u\n Extra "
272  "arguments beyond the rank must be zero \n",
273  R);
274  return (false) &&
275  dyn_rank_view_verify_operator_bounds<R + 1>(rank, map, args...);
276  } else {
277  return (true) &&
278  dyn_rank_view_verify_operator_bounds<R + 1>(rank, map, args...);
279  }
280 }
281 
282 template <unsigned, class MapType>
283 inline void dyn_rank_view_error_operator_bounds(char*, int, const MapType&) {}
284 
285 template <unsigned R, class MapType, class iType, class... Args>
286 inline void dyn_rank_view_error_operator_bounds(char* buf, int len,
287  const MapType& map,
288  const iType& i, Args... args) {
289  const int n = snprintf(
290  buf, len, " %ld < %ld %c", static_cast<unsigned long>(i),
291  static_cast<unsigned long>(map.extent(R)), (sizeof...(Args) ? ',' : ')'));
292  dyn_rank_view_error_operator_bounds<R + 1>(buf + n, len - n, map, args...);
293 }
294 
295 // op_rank = rank of the operator version that was called
296 template <typename MemorySpace, typename iType0, typename iType1, class MapType,
297  class... Args>
298 KOKKOS_INLINE_FUNCTION void dyn_rank_view_verify_operator_bounds(
299  const iType0& op_rank, const iType1& rank,
300  const Kokkos::Impl::SharedAllocationTracker& tracker, const MapType& map,
301  Args... args) {
302  if (static_cast<iType0>(rank) > op_rank) {
303  Kokkos::abort(
304  "DynRankView Bounds Checking Error: Need at least rank arguments to "
305  "the operator()");
306  }
307 
308  if (!dyn_rank_view_verify_operator_bounds<0>(rank, map, args...)) {
309  KOKKOS_IF_ON_HOST(
310  (enum {LEN = 1024}; char buffer[LEN];
311  const std::string label = tracker.template get_label<MemorySpace>();
312  int n = snprintf(buffer, LEN, "DynRankView bounds error of view %s (",
313  label.c_str());
314  dyn_rank_view_error_operator_bounds<0>(buffer + n, LEN - n, map,
315  args...);
316  Kokkos::Impl::throw_runtime_exception(std::string(buffer));))
317 
318  KOKKOS_IF_ON_DEVICE(
319  ((void)tracker; Kokkos::abort("DynRankView bounds error");))
320  }
321 }
322 
324 struct ViewToDynRankViewTag {};
325 
326 } // namespace Impl
327 
328 namespace Impl {
329 
330 template <class DstTraits, class SrcTraits>
331 class ViewMapping<
332  DstTraits, SrcTraits,
333  std::enable_if_t<
334  (std::is_same_v<typename DstTraits::memory_space,
335  typename SrcTraits::memory_space> &&
336  std::is_void_v<typename DstTraits::specialize> &&
337  std::is_void_v<typename SrcTraits::specialize> &&
338  (std::is_same_v<typename DstTraits::array_layout,
339  typename SrcTraits::array_layout> ||
340  ((std::is_same_v<typename DstTraits::array_layout,
341  Kokkos::LayoutLeft> ||
342  std::is_same_v<typename DstTraits::array_layout,
343  Kokkos::LayoutRight> ||
344  std::is_same_v<
345  typename DstTraits::array_layout,
346  Kokkos::LayoutStride>)&&(std::is_same_v<typename SrcTraits::
347  array_layout,
348  Kokkos::LayoutLeft> ||
349  std::is_same_v<
350  typename SrcTraits::array_layout,
351  Kokkos::LayoutRight> ||
352  std::is_same_v<
353  typename SrcTraits::array_layout,
354  Kokkos::LayoutStride>)))),
355  Kokkos::Impl::ViewToDynRankViewTag>> {
356  private:
357  enum {
358  is_assignable_value_type =
359  std::is_same_v<typename DstTraits::value_type,
360  typename SrcTraits::value_type> ||
361  std::is_same_v<typename DstTraits::value_type,
362  typename SrcTraits::const_value_type>
363  };
364 
365  enum {
366  is_assignable_layout =
367  std::is_same_v<typename DstTraits::array_layout,
368  typename SrcTraits::array_layout> ||
369  std::is_same_v<typename DstTraits::array_layout, Kokkos::LayoutStride>
370  };
371 
372  public:
373  enum { is_assignable = is_assignable_value_type && is_assignable_layout };
374 
375  using DstType = ViewMapping<DstTraits, typename DstTraits::specialize>;
376  using SrcType = ViewMapping<SrcTraits, typename SrcTraits::specialize>;
377 
378  template <typename DT, typename... DP, typename ST, typename... SP>
379  KOKKOS_INLINE_FUNCTION static void assign(
380  Kokkos::DynRankView<DT, DP...>& dst, const Kokkos::View<ST, SP...>& src) {
381  static_assert(
382  is_assignable_value_type,
383  "View assignment must have same value type or const = non-const");
384 
385  static_assert(
386  is_assignable_layout,
387  "View assignment must have compatible layout or have rank <= 1");
388 
389  // Removed dimension checks...
390 
391  using dst_offset_type = typename DstType::offset_type;
392  dst.m_map.m_impl_offset = dst_offset_type(
393  std::integral_constant<unsigned, 0>(),
394  src.layout()); // Check this for integer input1 for padding, etc
395  dst.m_map.m_impl_handle = Kokkos::Impl::ViewDataHandle<DstTraits>::assign(
396  src.m_map.m_impl_handle, src.m_track.m_tracker);
397  dst.m_track.m_tracker.assign(src.m_track.m_tracker, DstTraits::is_managed);
398  dst.m_rank = Kokkos::View<ST, SP...>::rank();
399  }
400 };
401 
402 } // namespace Impl
403 
404 /* \class DynRankView
405  * \brief Container that creates a Kokkos view with rank determined at runtime.
406  * Essentially this is a rank 7 view
407  *
408  * Changes from View
409  * 1. The rank of the DynRankView is returned by the method rank()
410  * 2. Max rank of a DynRankView is 7
411  * 3. subview called with 'subview(...)' or 'subdynrankview(...)' (backward
412  * compatibility)
413  * 4. Every subview is returned with LayoutStride
414  * 5. Copy and Copy-Assign View to DynRankView
415  * 6. deep_copy between Views and DynRankViews
416  * 7. rank( view ); returns the rank of View or DynRankView
417  *
418  */
419 
420 template <class>
421 struct is_dyn_rank_view : public std::false_type {};
422 
423 template <class D, class... P>
424 struct is_dyn_rank_view<Kokkos::DynRankView<D, P...>> : public std::true_type {
425 };
426 
427 template <class T>
428 inline constexpr bool is_dyn_rank_view_v = is_dyn_rank_view<T>::value;
429 
430 // Inherit privately from View, this way we don't import anything funky
431 // for example the rank member vs the rank() function of DynRankView
432 template <typename DataType, class... Properties>
433 class DynRankView : private View<DataType*******, Properties...> {
434  static_assert(!std::is_array_v<DataType> && !std::is_pointer_v<DataType>,
435  "Cannot template DynRankView with array or pointer datatype - "
436  "must be pod");
437 
438  private:
439  template <class, class...>
440  friend class DynRankView;
441  template <class, class...>
442  friend class Kokkos::Impl::ViewMapping;
443 
444  size_t m_rank{};
445 
446  public:
447  using drvtraits = ViewTraits<DataType, Properties...>;
448 
449  using view_type = View<DataType*******, Properties...>;
450 
451  private:
452 #ifdef KOKKOS_ENABLE_IMPL_VIEW_LEGACY
453  using drdtraits = Impl::DynRankDimTraits<typename view_type::specialize>;
454 #else
455  using drdtraits = Impl::DynRankDimTraits<
456  std::conditional_t<view_type::traits::impl_is_customized, bool, void>>;
457 #endif
458  public:
459  // typedefs from ViewTraits, overriden
460  using data_type = typename drvtraits::data_type;
461  using const_data_type = typename drvtraits::const_data_type;
462  using non_const_data_type = typename drvtraits::non_const_data_type;
463 
464  // typedefs from ViewTraits not overriden
465  using value_type = typename view_type::value_type;
466  using const_value_type = typename view_type::const_value_type;
467  using non_const_value_type = typename view_type::non_const_value_type;
468  using traits = typename view_type::traits;
469  using array_layout = typename view_type::array_layout;
470 
471  using execution_space = typename view_type::execution_space;
472  using memory_space = typename view_type::memory_space;
473  using device_type = typename view_type::device_type;
474 
475  using memory_traits = typename view_type::memory_traits;
476  using host_mirror_space = typename view_type::host_mirror_space;
477  using size_type = typename view_type::size_type;
478 
479  using reference_type = typename view_type::reference_type;
480  using pointer_type = typename view_type::pointer_type;
481 
482  using scalar_array_type = value_type;
483  using const_scalar_array_type = const_value_type;
484  using non_const_scalar_array_type = non_const_value_type;
485 #ifndef KOKKOS_ENABLE_IMPL_VIEW_LEGACY
486 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
487  using specialize KOKKOS_DEPRECATED = void;
488 #endif
489 #else
490  using specialize = typename view_type::specialize;
491 #endif
492 
493  // typedefs in View for mdspan compatibility
494  // cause issues with MSVC+CUDA
495  // using layout_type = typename view_type::layout_type;
496  using index_type = typename view_type::index_type;
497  using element_type = typename view_type::element_type;
498  using rank_type = typename view_type::rank_type;
499  using reference = reference_type;
500  using data_handle_type = pointer_type;
501 
502  KOKKOS_FUNCTION
503  view_type& DownCast() const { return (view_type&)(*this); }
504 
505  // FIXME: this function make NO sense, the above one already is marked const
506  // Maybe one would want to get back a view of const??
507  KOKKOS_FUNCTION
508  const view_type& ConstDownCast() const { return (const view_type&)(*this); }
509 
510  // FIXME: deprecate DownCast in favor of to_view
511  // KOKKOS_FUNCTION
512  // view_type to_view() const { return *this; }
513 
514  // Types below - at least the HostMirror requires the value_type, NOT the rank
515  // 7 data_type of the traits
516 
518  using array_type = DynRankView<
519  typename drvtraits::scalar_array_type, typename drvtraits::array_layout,
520  typename drvtraits::device_type, typename drvtraits::memory_traits>;
521 
523  using const_type = DynRankView<
524  typename drvtraits::const_data_type, typename drvtraits::array_layout,
525  typename drvtraits::device_type, typename drvtraits::memory_traits>;
526 
528  using non_const_type = DynRankView<
529  typename drvtraits::non_const_data_type, typename drvtraits::array_layout,
530  typename drvtraits::device_type, typename drvtraits::memory_traits>;
531 
533  using HostMirror = DynRankView<typename drvtraits::non_const_data_type,
534  typename drvtraits::array_layout,
535  typename drvtraits::host_mirror_space>;
536 
537  using host_mirror_type = HostMirror;
538  //----------------------------------------
539  // Domain rank and extents
540 
541  // enum { Rank = map_type::Rank }; //Will be dyn rank of 7 always, keep the
542  // enum?
543 
544  //----------------------------------------
545  /* Deprecate all 'dimension' functions in favor of
546  * ISO/C++ vocabulary 'extent'.
547  */
548 
549  //----------------------------------------
550 
551  private:
552  enum {
553  is_layout_left =
554  std::is_same_v<typename traits::array_layout, Kokkos::LayoutLeft>,
555 
556  is_layout_right =
557  std::is_same_v<typename traits::array_layout, Kokkos::LayoutRight>,
558 
559  is_layout_stride =
560  std::is_same_v<typename traits::array_layout, Kokkos::LayoutStride>,
561 
562  is_default_map = std::is_void_v<typename traits::specialize> &&
563  (is_layout_left || is_layout_right || is_layout_stride),
564 
565  is_default_access =
566  is_default_map && std::is_same_v<reference_type, element_type&>
567  };
568 
569 // Bounds checking macros
570 #if defined(KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK)
571 
572 // rank of the calling operator - included as first argument in ARG
573 #define KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(ARG) \
574  Kokkos::Impl::runtime_check_memory_access_violation< \
575  typename traits::memory_space>( \
576  "Kokkos::DynRankView ERROR: attempt to access inaccessible memory " \
577  "space"); \
578  Kokkos::Impl::dyn_rank_view_verify_operator_bounds< \
579  typename traits::memory_space> \
580  ARG;
581 
582 #else
583 
584 #define KOKKOS_IMPL_VIEW_OPERATOR_VERIFY(ARG) \
585  Kokkos::Impl::runtime_check_memory_access_violation< \
586  typename traits::memory_space>( \
587  "Kokkos::DynRankView ERROR: attempt to access inaccessible memory " \
588  "space");
589 
590 #endif
591 
592  public:
593  KOKKOS_FUNCTION
594  constexpr unsigned rank() const { return m_rank; }
595 
596 #ifndef KOKKOS_ENABLE_IMPL_VIEW_LEGACY
597  using view_type::accessor; // FIXME: not tested
598  using view_type::mapping; // FIXME: not tested
599 #endif
600  using view_type::data;
601  using view_type::extent;
602  using view_type::extent_int; // FIXME: not tested
603  using view_type::impl_map; // FIXME: not tested
604  using view_type::is_allocated;
605  using view_type::label;
606  using view_type::size;
607  using view_type::span;
608  using view_type::span_is_contiguous; // FIXME: not tested
609  using view_type::stride; // FIXME: not tested
610  using view_type::stride_0; // FIXME: not tested
611  using view_type::stride_1; // FIXME: not tested
612  using view_type::stride_2; // FIXME: not tested
613  using view_type::stride_3; // FIXME: not tested
614  using view_type::stride_4; // FIXME: not tested
615  using view_type::stride_5; // FIXME: not tested
616  using view_type::stride_6; // FIXME: not tested
617  using view_type::stride_7; // FIXME: not tested
618  using view_type::use_count;
619 
620 #ifdef KOKKOS_ENABLE_CUDA
621  KOKKOS_FUNCTION reference_type
622  operator()(index_type i0 = 0, index_type i1 = 0, index_type i2 = 0,
623  index_type i3 = 0, index_type i4 = 0, index_type i5 = 0,
624  index_type i6 = 0) const {
625  return view_type::operator()(i0, i1, i2, i3, i4, i5, i6);
626  }
627 #else
628  // Adding shortcut operators for rank-0 to rank-3 for default layouts
629  // and access modalities.
630  // This removes performance overhead for always using rank-7 mapping.
631  // See https://github.com/kokkos/kokkos/issues/7604
632  // When boundschecking is enabled we still go through the underlying
633  // rank-7 View to leverage the error checks there.
634 
635  KOKKOS_FUNCTION reference_type operator()() const {
636 #ifdef KOKKOS_ENABLE_DEBUG
637  if (rank() != 0u)
638  Kokkos::abort(
639  "DynRankView rank 0 operator() called with invalid number of "
640  "arguments.");
641 #endif
642 #ifndef KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK
643  if constexpr (is_default_access) {
644  return view_type::data()[0];
645  } else
646 #endif
647  {
648  return view_type::operator()(0, 0, 0, 0, 0, 0, 0);
649  }
650  }
651 
652  KOKKOS_FUNCTION reference_type operator()(index_type i0) const {
653 #ifdef KOKKOS_ENABLE_DEBUG
654  // FIXME: Should be equal, only access(...) allows mismatch of rank and
655  // index args
656  if (rank() > 1u)
657  Kokkos::abort(
658  "DynRankView rank 1 operator() called with invalid number of "
659  "arguments.");
660 #endif
661 #ifndef KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK
662  if constexpr (is_default_access) {
663  if constexpr (is_layout_stride) {
664  return view_type::data()[i0 * view_type::stride(0)];
665  } else {
666  return view_type::data()[i0];
667  }
668  } else
669 #endif
670  {
671  return view_type::operator()(i0, 0, 0, 0, 0, 0, 0);
672  }
673 #if defined(KOKKOS_COMPILER_NVCC) && KOKKOS_COMPILER_NVCC >= 1130 && \
674  !defined(KOKKOS_COMPILER_MSVC)
675  __builtin_unreachable();
676 #endif
677  }
678 
679  KOKKOS_FUNCTION reference_type operator()(index_type i0,
680  index_type i1) const {
681 #ifdef KOKKOS_ENABLE_DEBUG
682  // FIXME: Should be equal, only access(...) allows mismatch of rank and
683  // index args
684  if (rank() > 2u)
685  Kokkos::abort(
686  "DynRankView rank 2 operator() called with invalid number of "
687  "arguments.");
688 #endif
689 #ifndef KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK
690  if constexpr (is_default_access) {
691  if constexpr (is_layout_left) {
692  return view_type::data()[i0 + i1 * view_type::stride(1)];
693  } else if constexpr (is_layout_right) {
694  return view_type::data()[i0 * view_type::extent(1) + i1];
695  } else {
696  return view_type::data()[i0 * view_type::stride(0) +
697  i1 * view_type::stride(1)];
698  }
699  } else
700 #endif
701  {
702  return view_type::operator()(i0, i1, 0, 0, 0, 0, 0);
703  }
704 #if defined(KOKKOS_COMPILER_NVCC) && KOKKOS_COMPILER_NVCC >= 1130 && \
705  !defined(KOKKOS_COMPILER_MSVC)
706  __builtin_unreachable();
707 #endif
708  }
709 
710  KOKKOS_FUNCTION reference_type operator()(index_type i0, index_type i1,
711  index_type i2) const {
712 #ifdef KOKKOS_ENABLE_DEBUG
713  // FIXME: Should be equal, only access(...) allows mismatch of rank and
714  // index args
715  if (rank() > 3u)
716  Kokkos::abort(
717  "DynRankView rank 3 operator() called with invalid number of "
718  "arguments.");
719 #endif
720 #ifndef KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK
721  if constexpr (is_default_access) {
722  if constexpr (is_layout_left) {
723  return view_type::data()[i0 + view_type::stride(1) *
724  (i1 + i2 * view_type::extent(1))];
725  } else if constexpr (is_layout_right) {
726  return view_type::data()[(i0 * view_type::extent(1) + i1) *
727  view_type::extent(2) +
728  i2];
729  } else {
730  return view_type::data()[i0 * view_type::stride(0) +
731  i1 * view_type::stride(1) +
732  i2 * view_type::stride(2)];
733  }
734  } else
735 #endif
736  {
737  return view_type::operator()(i0, i1, i2, 0, 0, 0, 0);
738  }
739 #if defined(KOKKOS_COMPILER_NVCC) && KOKKOS_COMPILER_NVCC >= 1130 && \
740  !defined(KOKKOS_COMPILER_MSVC)
741  __builtin_unreachable();
742 #endif
743  }
744 
745  KOKKOS_FUNCTION reference_type operator()(index_type i0, index_type i1,
746  index_type i2, index_type i3,
747  index_type i4 = 0,
748  index_type i5 = 0,
749  index_type i6 = 0) const {
750  return view_type::operator()(i0, i1, i2, i3, i4, i5, i6);
751  }
752 #endif
753 
754 // This is an accomodation for Phalanx, that is usint the operator[] to access
755 // all elements in a linear fashion even when the rank is not 1
756 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
757  KOKKOS_FUNCTION reference_type operator[](index_type i0) const {
758  if constexpr (std::is_same_v<typename drvtraits::value_type,
759  typename drvtraits::scalar_array_type>) {
760  return view_type::data()[i0];
761  } else {
762  const size_t dim_scalar = view_type::impl_map().dimension_scalar();
763  const size_t bytes = view_type::span() / dim_scalar;
764 
765  using tmp_view_type =
766  Kokkos::View<DataType*, typename traits::array_layout,
767  typename traits::device_type,
768  Kokkos::MemoryTraits<traits::memory_traits::impl_value |
769  unsigned(Kokkos::Unmanaged)>>;
770  tmp_view_type rankone_view(view_type::data(), bytes, dim_scalar);
771  return rankone_view(i0);
772  }
773  }
774 #else
775  KOKKOS_FUNCTION reference_type operator[](index_type i0) const {
776 #ifdef KOKKOS_ENABLE_DEBUG
777  if (rank() != 1u)
778  Kokkos::abort("DynRankView operator[] can only be used for rank-1");
779 #endif
780  return view_type::operator()(i0, 0, 0, 0, 0, 0, 0);
781  }
782 #endif
783 
784  KOKKOS_FUNCTION reference_type access(index_type i0 = 0, index_type i1 = 0,
785  index_type i2 = 0, index_type i3 = 0,
786  index_type i4 = 0, index_type i5 = 0,
787  index_type i6 = 0) const {
788  return view_type::operator()(i0, i1, i2, i3, i4, i5, i6);
789  }
790 
791  //----------------------------------------
792  // Standard constructor, destructor, and assignment operators...
793 
794  KOKKOS_DEFAULTED_FUNCTION
795  ~DynRankView() = default;
796 
797  KOKKOS_DEFAULTED_FUNCTION DynRankView() = default;
798 
799  //----------------------------------------
800  // Compatible view copy constructor and assignment
801  // may assign unmanaged from managed.
802  // Make this conditionally explicit?
803  template <class RT, class... RP>
804  KOKKOS_FUNCTION DynRankView(const DynRankView<RT, RP...>& rhs)
805  : view_type(rhs), m_rank(rhs.m_rank) {}
806 
807  KOKKOS_INLINE_FUNCTION DynRankView(view_type rhs, size_t new_rank)
808  : view_type(rhs), m_rank(new_rank) {
809  if (new_rank > view_type::rank())
810  Kokkos::abort(
811  "Attempting to construct DynRankView from View and new rank, with "
812  "the new rank being too large.");
813 
814  bool invalid_extent = false;
815  for (size_t r = new_rank; r < view_type::rank(); r++)
816  if (rhs.extent(r) != 1) invalid_extent = true;
817  if (invalid_extent)
818  Kokkos::abort(
819  "Attempting to construct DynRankView from View with incompatible "
820  "extents. (Extents for dimensions larger than the provided rank are "
821  "not equal to 1).");
822  }
823 
824  template <class RT, class... RP>
825  KOKKOS_FUNCTION DynRankView& operator=(const DynRankView<RT, RP...>& rhs) {
826  view_type::operator=(rhs);
827  m_rank = rhs.m_rank;
828  return *this;
829  }
830 
831 #ifndef KOKKOS_ENABLE_IMPL_VIEW_LEGACY
832  private:
833  template <class Ext>
834  KOKKOS_FUNCTION typename view_type::extents_type create_rank7_extents(
835  const Ext& ext) {
836  return typename view_type::extents_type(
837  ext.rank() > 0 ? ext.extent(0) : 1, ext.rank() > 1 ? ext.extent(1) : 1,
838  ext.rank() > 2 ? ext.extent(2) : 1, ext.rank() > 3 ? ext.extent(3) : 1,
839  ext.rank() > 4 ? ext.extent(4) : 1, ext.rank() > 5 ? ext.extent(5) : 1,
840  ext.rank() > 6 ? ext.extent(6) : 1);
841  }
842 
843  public:
844  // Copy/Assign View to DynRankView
845  template <class RT, class... RP>
846  KOKKOS_INLINE_FUNCTION DynRankView(const View<RT, RP...>& rhs,
847  size_t new_rank)
848  : view_type(rhs.data_handle(),
849  Impl::mapping_from_array_layout<
850  typename view_type::mdspan_type::mapping_type>(
851  drdtraits::createLayout(rhs.layout())),
852  rhs.accessor()),
853  m_rank(new_rank) {
854  if (new_rank > View<RT, RP...>::rank())
855  Kokkos::abort(
856  "Attempting to construct DynRankView from View and new rank, with "
857  "the new rank being too large.");
858  }
859 
860  template <class RT, class... RP>
861  KOKKOS_INLINE_FUNCTION DynRankView& operator=(const View<RT, RP...>& rhs) {
862  view_type::operator=(
863  view_type(rhs.data_handle(),
864  Impl::mapping_from_array_layout<
865  typename view_type::mdspan_type::mapping_type>(
866  drdtraits::createLayout(rhs.layout())),
867  rhs.accessor()));
868  m_rank = rhs.rank();
869  return *this;
870  }
871 #else
872  template <class RT, class... RP>
873  KOKKOS_FUNCTION DynRankView(const View<RT, RP...>& rhs, size_t new_rank) {
874  using SrcTraits = typename View<RT, RP...>::traits;
875  using Mapping =
876  Kokkos::Impl::ViewMapping<traits, SrcTraits,
878  static_assert(Mapping::is_assignable,
879  "Incompatible View to DynRankView copy assignment");
880  if (new_rank > View<RT, RP...>::rank())
881  Kokkos::abort(
882  "Attempting to construct DynRankView from View and new rank, with "
883  "the new rank being too large.");
884  Mapping::assign(*this, rhs);
885  m_rank = new_rank;
886  }
887 
888  template <class RT, class... RP>
889  KOKKOS_FUNCTION DynRankView& operator=(const View<RT, RP...>& rhs) {
890  using SrcTraits = typename View<RT, RP...>::traits;
891  using Mapping =
892  Kokkos::Impl::ViewMapping<traits, SrcTraits,
893  Kokkos::Impl::ViewToDynRankViewTag>;
894  static_assert(Mapping::is_assignable,
895  "Incompatible View to DynRankView copy assignment");
896  Mapping::assign(*this, rhs);
897  m_rank = View<RT, RP...>::rank();
898  return *this;
899  }
900 #endif
901 
902  template <class RT, class... RP>
903  KOKKOS_FUNCTION DynRankView(const View<RT, RP...>& rhs)
904  : DynRankView(rhs, View<RT, RP...>::rank()) {}
905 
906  //----------------------------------------
907  // Allocation tracking properties
908 
909  //----------------------------------------
910  // Allocation according to allocation properties and array layout
911  // unused arg_layout dimensions must be set to KOKKOS_INVALID_INDEX so that
912  // rank deduction can properly take place
913  // We need two variants to avoid calling host function from host device
914  // function warnings
915 
916 #ifndef KOKKOS_ENABLE_IMPL_VIEW_LEGACY
917  private:
918  // Need a host only and a host/device function to deal with labels.
919  template <class... P>
920  KOKKOS_FUNCTION auto attach_accessor_arg_if_needed(
921  const Impl::ViewCtorProp<P...>& arg_prop,
922  std::enable_if_t<((!std::is_same_v<P, std::string>)&&...),
923  const typename traits::array_layout&>
924  layout) {
925  if constexpr (traits::impl_is_customized) {
926  int r = 0;
927  while (r < 7 && layout.dimension[r] != KOKKOS_INVALID_INDEX) r++;
928 
929  // Can't use with_properties_if_unset since its a host only function!
930  return view_wrap(
931  static_cast<const Impl::ViewCtorProp<void, P>&>(arg_prop).value...,
932  Impl::AccessorArg_t{r > 0 ? size_t(layout.dimension[r - 1]) : 0ul});
933  } else {
934  return arg_prop;
935  }
936  }
937  template <class... P>
938  auto attach_accessor_arg_if_needed(
939  const Impl::ViewCtorProp<P...>& arg_prop,
940  std::enable_if_t<(std::is_same_v<P, std::string> || ...),
941  const typename traits::array_layout&>
942  layout) {
943  if constexpr (traits::impl_is_customized &&
944  !Impl::ViewCtorProp<P...>::has_accessor_arg) {
945  int r = 0;
946  while (r < 7 && layout.dimension[r] != KOKKOS_INVALID_INDEX) r++;
947  // Could use with_properties_if_unset, but rather keep same as above.
948  return view_alloc(
949  static_cast<const Impl::ViewCtorProp<void, P>&>(arg_prop).value...,
950  Impl::AccessorArg_t{r > 0 ? size_t(layout.dimension[r - 1]) : 0ul});
951  } else {
952  return arg_prop;
953  }
954  }
955 
956  public:
957 #endif
958 
959  // With NVCC 11.0 and 11.2 (and others likely) using GCC 8.5 a DynRankView
960  // test fails at runtime where construction from layout drops some extents.
961  // The bug goes away with O1.
962  // FIXME: NVCC GCC8 optimization bug DynRankView
963 #if defined(KOKKOS_ENABLE_CUDA) && defined(KOKKOS_COMPILER_GNU)
964 #if KOKKOS_COMPILER_GNU < 900
965 #define KOKKOS_IMPL_SKIP_OPTIMIZATION
966 #endif
967 #endif
968 
969 #ifdef KOKKOS_IMPL_SKIP_OPTIMIZATION
970 // Also need to suppress warning about unrecognized GCC optimize pragma
971 #pragma push
972 #pragma diag_suppress = unrecognized_gcc_pragma
973 #pragma GCC push_options
974 #pragma GCC optimize("O1")
975 #endif
976  template <class... P>
977  explicit KOKKOS_FUNCTION DynRankView(
978  const Kokkos::Impl::ViewCtorProp<P...>& arg_prop,
979  std::enable_if_t<Kokkos::Impl::ViewCtorProp<P...>::has_pointer,
980  typename traits::array_layout const&>
981  arg_layout)
982 #ifndef KOKKOS_ENABLE_IMPL_VIEW_LEGACY
983  : view_type(attach_accessor_arg_if_needed(arg_prop, arg_layout),
984  drdtraits::template createLayout<traits, P...>(arg_prop,
985  arg_layout)),
986  m_rank(drdtraits::computeRank(arg_prop, arg_layout) -
987  (traits::impl_is_customized ? 1 : 0)){}
988 #else
989  : view_type(arg_prop, drdtraits::template createLayout<traits, P...>(
990  arg_prop, arg_layout)),
991  m_rank(drdtraits::computeRank(arg_prop, arg_layout)) {
992  }
993 #endif
994 
995  template <class... P>
996  explicit DynRankView(
997  const Kokkos::Impl::ViewCtorProp<P...>& arg_prop,
998  std::enable_if_t<!Kokkos::Impl::ViewCtorProp<P...>::has_pointer,
999  typename traits::array_layout const&>
1000  arg_layout)
1001 #ifndef KOKKOS_ENABLE_IMPL_VIEW_LEGACY
1002  : view_type(attach_accessor_arg_if_needed(arg_prop, arg_layout),
1003  drdtraits::template createLayout<traits, P...>(arg_prop,
1004  arg_layout)),
1005  m_rank(drdtraits::computeRank(arg_prop, arg_layout) -
1006  (traits::impl_is_customized &&
1007  !Kokkos::Impl::ViewCtorProp<P...>::has_accessor_arg
1008  ? 1
1009  : 0)){}
1010 #else
1011  : view_type(arg_prop, drdtraits::template createLayout<traits, P...>(
1012  arg_prop, arg_layout)),
1013  m_rank(drdtraits::computeRank(arg_prop, arg_layout)) {
1014  }
1015 #endif
1016 
1017 #ifdef KOKKOS_IMPL_SKIP_OPTIMIZATION
1018 #pragma GCC pop_options
1019 #pragma pop
1020 #undef KOKKOS_IMPL_SKIP_OPTIMIZATION
1021 #endif
1022 
1023  //----------------------------------------
1024  // Constructor(s)
1025 
1026  // Simple dimension-only layout
1027  // We need two variants to avoid calling host function from host device
1028  // function warnings
1029  template <class... P>
1030  explicit KOKKOS_FUNCTION DynRankView(
1031  const Kokkos::Impl::ViewCtorProp<P...>& arg_prop,
1032  std::enable_if_t<Kokkos::Impl::ViewCtorProp<P...>::has_pointer,
1033  const size_t>
1034  arg_N0 = KOKKOS_INVALID_INDEX,
1035  const size_t arg_N1 = KOKKOS_INVALID_INDEX,
1036  const size_t arg_N2 = KOKKOS_INVALID_INDEX,
1037  const size_t arg_N3 = KOKKOS_INVALID_INDEX,
1038  const size_t arg_N4 = KOKKOS_INVALID_INDEX,
1039  const size_t arg_N5 = KOKKOS_INVALID_INDEX,
1040  const size_t arg_N6 = KOKKOS_INVALID_INDEX,
1041  const size_t arg_N7 = KOKKOS_INVALID_INDEX)
1042  : DynRankView(arg_prop, typename traits::array_layout(
1043  arg_N0, arg_N1, arg_N2, arg_N3, arg_N4,
1044  arg_N5, arg_N6, arg_N7)) {
1045  }
1046 
1047  template <class... P>
1048  explicit DynRankView(
1049  const Kokkos::Impl::ViewCtorProp<P...>& arg_prop,
1050  std::enable_if_t<!Kokkos::Impl::ViewCtorProp<P...>::has_pointer,
1051  const size_t>
1052  arg_N0 = KOKKOS_INVALID_INDEX,
1053  const size_t arg_N1 = KOKKOS_INVALID_INDEX,
1054  const size_t arg_N2 = KOKKOS_INVALID_INDEX,
1055  const size_t arg_N3 = KOKKOS_INVALID_INDEX,
1056  const size_t arg_N4 = KOKKOS_INVALID_INDEX,
1057  const size_t arg_N5 = KOKKOS_INVALID_INDEX,
1058  const size_t arg_N6 = KOKKOS_INVALID_INDEX,
1059  const size_t arg_N7 = KOKKOS_INVALID_INDEX)
1060  : DynRankView(arg_prop, typename traits::array_layout(
1061  arg_N0, arg_N1, arg_N2, arg_N3, arg_N4,
1062  arg_N5, arg_N6, arg_N7)) {}
1063 
1064  // Allocate with label and layout
1065  template <typename Label>
1066  explicit inline DynRankView(
1067  const Label& arg_label,
1068  std::enable_if_t<Kokkos::Impl::is_view_label<Label>::value,
1069  typename traits::array_layout> const& arg_layout)
1070  : DynRankView(Kokkos::Impl::ViewCtorProp<std::string>(arg_label),
1071  arg_layout) {}
1072 
1073  // Allocate label and layout, must disambiguate from subview constructor
1074  template <typename Label>
1075  explicit inline DynRankView(
1076  const Label& arg_label,
1077  std::enable_if_t<Kokkos::Impl::is_view_label<Label>::value, const size_t>
1078  arg_N0 = KOKKOS_INVALID_INDEX,
1079  const size_t arg_N1 = KOKKOS_INVALID_INDEX,
1080  const size_t arg_N2 = KOKKOS_INVALID_INDEX,
1081  const size_t arg_N3 = KOKKOS_INVALID_INDEX,
1082  const size_t arg_N4 = KOKKOS_INVALID_INDEX,
1083  const size_t arg_N5 = KOKKOS_INVALID_INDEX,
1084  const size_t arg_N6 = KOKKOS_INVALID_INDEX,
1085  const size_t arg_N7 = KOKKOS_INVALID_INDEX)
1086  : DynRankView(
1087  Kokkos::Impl::ViewCtorProp<std::string>(arg_label),
1088  typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3,
1089  arg_N4, arg_N5, arg_N6, arg_N7)) {}
1090 
1091  //----------------------------------------
1092  // Memory span required to wrap these dimensions.
1093  // FIXME: this function needs to be tested
1094  static constexpr size_t required_allocation_size(
1095  const size_t arg_N0 = 1, const size_t arg_N1 = 1, const size_t arg_N2 = 1,
1096  const size_t arg_N3 = 1, const size_t arg_N4 = 1, const size_t arg_N5 = 1,
1097  const size_t arg_N6 = 1,
1098  [[maybe_unused]] const size_t arg_N7 = KOKKOS_INVALID_INDEX) {
1099  // FIXME: check that arg_N7 is not set by user (in debug mode)
1100  return view_type::required_allocation_size(arg_N0, arg_N1, arg_N2, arg_N3,
1101  arg_N4, arg_N5, arg_N6);
1102  }
1103 
1104  explicit KOKKOS_FUNCTION DynRankView(
1105  typename view_type::pointer_type arg_ptr,
1106  const size_t arg_N0 = KOKKOS_INVALID_INDEX,
1107  const size_t arg_N1 = KOKKOS_INVALID_INDEX,
1108  const size_t arg_N2 = KOKKOS_INVALID_INDEX,
1109  const size_t arg_N3 = KOKKOS_INVALID_INDEX,
1110  const size_t arg_N4 = KOKKOS_INVALID_INDEX,
1111  const size_t arg_N5 = KOKKOS_INVALID_INDEX,
1112  const size_t arg_N6 = KOKKOS_INVALID_INDEX,
1113  const size_t arg_N7 = KOKKOS_INVALID_INDEX)
1114  : DynRankView(
1115  Kokkos::Impl::ViewCtorProp<typename view_type::pointer_type>(
1116  arg_ptr),
1117  arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7) {}
1118 
1119  explicit KOKKOS_FUNCTION DynRankView(
1120  typename view_type::pointer_type arg_ptr,
1121  typename traits::array_layout& arg_layout)
1122  : DynRankView(
1123  Kokkos::Impl::ViewCtorProp<typename view_type::pointer_type>(
1124  arg_ptr),
1125  arg_layout) {}
1126 
1127  //----------------------------------------
1128  // Shared scratch memory constructor
1129 
1130  // Note: We must pass 7 valid args since view_type is rank 7
1131  static inline size_t shmem_size(
1132  const size_t arg_N0 = 1, const size_t arg_N1 = 1, const size_t arg_N2 = 1,
1133  const size_t arg_N3 = 1, const size_t arg_N4 = 1, const size_t arg_N5 = 1,
1134  const size_t arg_N6 = 1, const size_t arg_N7 = KOKKOS_INVALID_INDEX) {
1135  return view_type::shmem_size(arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5,
1136  arg_N6, arg_N7);
1137  }
1138 
1139  explicit KOKKOS_FUNCTION DynRankView(
1140  const typename traits::execution_space::scratch_memory_space& arg_space,
1141  const typename traits::array_layout& arg_layout)
1142  : view_type(arg_space, drdtraits::createLayout(arg_layout)),
1143  m_rank(drdtraits::computeRank(arg_layout)) {}
1144 
1145  explicit KOKKOS_FUNCTION DynRankView(
1146  const typename traits::execution_space::scratch_memory_space& arg_space,
1147  const size_t arg_N0 = KOKKOS_INVALID_INDEX,
1148  const size_t arg_N1 = KOKKOS_INVALID_INDEX,
1149  const size_t arg_N2 = KOKKOS_INVALID_INDEX,
1150  const size_t arg_N3 = KOKKOS_INVALID_INDEX,
1151  const size_t arg_N4 = KOKKOS_INVALID_INDEX,
1152  const size_t arg_N5 = KOKKOS_INVALID_INDEX,
1153  const size_t arg_N6 = KOKKOS_INVALID_INDEX,
1154  const size_t arg_N7 = KOKKOS_INVALID_INDEX)
1155 
1156  : DynRankView(arg_space, typename traits::array_layout(
1157  arg_N0, arg_N1, arg_N2, arg_N3, arg_N4,
1158  arg_N5, arg_N6, arg_N7)) {}
1159 
1160  KOKKOS_FUNCTION constexpr auto layout() const {
1161  switch (rank()) {
1162  case 0: return Impl::as_view_of_rank_n<0>(*this).layout();
1163  case 1: return Impl::as_view_of_rank_n<1>(*this).layout();
1164  case 2: return Impl::as_view_of_rank_n<2>(*this).layout();
1165  case 3: return Impl::as_view_of_rank_n<3>(*this).layout();
1166  case 4: return Impl::as_view_of_rank_n<4>(*this).layout();
1167  case 5: return Impl::as_view_of_rank_n<5>(*this).layout();
1168  case 6: return Impl::as_view_of_rank_n<6>(*this).layout();
1169  case 7: return Impl::as_view_of_rank_n<7>(*this).layout();
1170  default:
1171  KOKKOS_IF_ON_HOST(
1172  Kokkos::abort(
1173  std::string(
1174  "Calling DynRankView::layout on DRV of unexpected rank " +
1175  std::to_string(rank()))
1176  .c_str());)
1177  KOKKOS_IF_ON_DEVICE(
1178  Kokkos::abort(
1179  "Calling DynRankView::layout on DRV of unexpected rank");)
1180  }
1181  // control flow should never reach here
1182  return view_type::layout();
1183  }
1184 };
1185 
1186 template <typename D, class... P>
1187 KOKKOS_FUNCTION constexpr unsigned rank(const DynRankView<D, P...>& DRV) {
1188  return DRV.rank();
1189 } // needed for transition to common constexpr method in view and dynrankview
1190  // to return rank
1191 
1192 //----------------------------------------------------------------------------
1193 // Subview mapping.
1194 // Deduce destination view type from source view traits and subview arguments
1195 
1196 namespace Impl {
1197 
1198 struct DynRankSubviewTag {};
1199 
1200 } // namespace Impl
1201 
1202 template <class V, class... Args>
1203 using Subdynrankview =
1204  typename Kokkos::Impl::ViewMapping<Kokkos::Impl::DynRankSubviewTag, V,
1205  Args...>::ret_type;
1206 
1207 template <class... DRVArgs, class SubArg0 = int, class SubArg1 = int,
1208  class SubArg2 = int, class SubArg3 = int, class SubArg4 = int,
1209  class SubArg5 = int, class SubArg6 = int>
1210 KOKKOS_INLINE_FUNCTION auto subdynrankview(
1211  const DynRankView<DRVArgs...>& drv, SubArg0 arg0 = SubArg0{},
1212  SubArg1 arg1 = SubArg1{}, SubArg2 arg2 = SubArg2{},
1213  SubArg3 arg3 = SubArg3{}, SubArg4 arg4 = SubArg4{},
1214  SubArg5 arg5 = SubArg5{}, SubArg6 arg6 = SubArg6{}) {
1215  auto sub = subview(drv.DownCast(), arg0, arg1, arg2, arg3, arg4, arg5, arg6);
1216  using sub_t = decltype(sub);
1217  size_t new_rank = (drv.rank() > 0 && !std::is_integral_v<SubArg0> ? 1 : 0) +
1218  (drv.rank() > 1 && !std::is_integral_v<SubArg1> ? 1 : 0) +
1219  (drv.rank() > 2 && !std::is_integral_v<SubArg2> ? 1 : 0) +
1220  (drv.rank() > 3 && !std::is_integral_v<SubArg3> ? 1 : 0) +
1221  (drv.rank() > 4 && !std::is_integral_v<SubArg4> ? 1 : 0) +
1222  (drv.rank() > 5 && !std::is_integral_v<SubArg5> ? 1 : 0) +
1223  (drv.rank() > 6 && !std::is_integral_v<SubArg6> ? 1 : 0);
1224 
1225  using return_type =
1226  DynRankView<typename sub_t::value_type, Kokkos::LayoutStride,
1227  typename sub_t::device_type, typename sub_t::memory_traits>;
1228  return static_cast<return_type>(
1229  DynRankView<typename sub_t::value_type, typename sub_t::array_layout,
1230  typename sub_t::device_type, typename sub_t::memory_traits>(
1231  sub, new_rank));
1232 }
1233 template <class... DRVArgs, class SubArg0 = int, class SubArg1 = int,
1234  class SubArg2 = int, class SubArg3 = int, class SubArg4 = int,
1235  class SubArg5 = int, class SubArg6 = int>
1236 KOKKOS_INLINE_FUNCTION auto subview(
1237  const DynRankView<DRVArgs...>& drv, SubArg0 arg0 = SubArg0{},
1238  SubArg1 arg1 = SubArg1{}, SubArg2 arg2 = SubArg2{},
1239  SubArg3 arg3 = SubArg3{}, SubArg4 arg4 = SubArg4{},
1240  SubArg5 arg5 = SubArg5{}, SubArg6 arg6 = SubArg6{}) {
1241  return subdynrankview(drv, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
1242 }
1243 
1244 } // namespace Kokkos
1245 
1246 namespace Kokkos {
1247 
1248 // overload == and !=
1249 template <class LT, class... LP, class RT, class... RP>
1250 KOKKOS_INLINE_FUNCTION bool operator==(const DynRankView<LT, LP...>& lhs,
1251  const DynRankView<RT, RP...>& rhs) {
1252  // Same data, layout, dimensions
1253  using lhs_traits = ViewTraits<LT, LP...>;
1254  using rhs_traits = ViewTraits<RT, RP...>;
1255 
1256  return std::is_same_v<typename lhs_traits::const_value_type,
1257  typename rhs_traits::const_value_type> &&
1258  std::is_same_v<typename lhs_traits::array_layout,
1259  typename rhs_traits::array_layout> &&
1260  std::is_same_v<typename lhs_traits::memory_space,
1261  typename rhs_traits::memory_space> &&
1262  lhs.rank() == rhs.rank() && lhs.data() == rhs.data() &&
1263  lhs.span() == rhs.span() && lhs.extent(0) == rhs.extent(0) &&
1264  lhs.extent(1) == rhs.extent(1) && lhs.extent(2) == rhs.extent(2) &&
1265  lhs.extent(3) == rhs.extent(3) && lhs.extent(4) == rhs.extent(4) &&
1266  lhs.extent(5) == rhs.extent(5) && lhs.extent(6) == rhs.extent(6) &&
1267  lhs.extent(7) == rhs.extent(7);
1268 }
1269 
1270 template <class LT, class... LP, class RT, class... RP>
1271 KOKKOS_INLINE_FUNCTION bool operator!=(const DynRankView<LT, LP...>& lhs,
1272  const DynRankView<RT, RP...>& rhs) {
1273  return !(operator==(lhs, rhs));
1274 }
1275 
1276 } // namespace Kokkos
1277 
1278 //----------------------------------------------------------------------------
1279 //----------------------------------------------------------------------------
1280 namespace Kokkos {
1281 namespace Impl {
1282 
1283 template <class OutputView, class InputView,
1284  class ExecSpace = typename OutputView::execution_space>
1285 struct DynRankViewRemap {
1286  const OutputView output;
1287  const InputView input;
1288  const size_t n0;
1289  const size_t n1;
1290  const size_t n2;
1291  const size_t n3;
1292  const size_t n4;
1293  const size_t n5;
1294  const size_t n6;
1295  const size_t n7;
1296 
1297  DynRankViewRemap(const ExecSpace& exec_space, const OutputView& arg_out,
1298  const InputView& arg_in)
1299  : output(arg_out),
1300  input(arg_in),
1301  n0(std::min((size_t)arg_out.extent(0), (size_t)arg_in.extent(0))),
1302  n1(std::min((size_t)arg_out.extent(1), (size_t)arg_in.extent(1))),
1303  n2(std::min((size_t)arg_out.extent(2), (size_t)arg_in.extent(2))),
1304  n3(std::min((size_t)arg_out.extent(3), (size_t)arg_in.extent(3))),
1305  n4(std::min((size_t)arg_out.extent(4), (size_t)arg_in.extent(4))),
1306  n5(std::min((size_t)arg_out.extent(5), (size_t)arg_in.extent(5))),
1307  n6(std::min((size_t)arg_out.extent(6), (size_t)arg_in.extent(6))),
1308  n7(std::min((size_t)arg_out.extent(7), (size_t)arg_in.extent(7))) {
1309  using Policy = Kokkos::RangePolicy<ExecSpace>;
1310 
1311  Kokkos::parallel_for("Kokkos::DynRankViewRemap", Policy(exec_space, 0, n0),
1312  *this);
1313  }
1314 
1315  DynRankViewRemap(const OutputView& arg_out, const InputView& arg_in)
1316  : output(arg_out),
1317  input(arg_in),
1318  n0(std::min((size_t)arg_out.extent(0), (size_t)arg_in.extent(0))),
1319  n1(std::min((size_t)arg_out.extent(1), (size_t)arg_in.extent(1))),
1320  n2(std::min((size_t)arg_out.extent(2), (size_t)arg_in.extent(2))),
1321  n3(std::min((size_t)arg_out.extent(3), (size_t)arg_in.extent(3))),
1322  n4(std::min((size_t)arg_out.extent(4), (size_t)arg_in.extent(4))),
1323  n5(std::min((size_t)arg_out.extent(5), (size_t)arg_in.extent(5))),
1324  n6(std::min((size_t)arg_out.extent(6), (size_t)arg_in.extent(6))),
1325  n7(std::min((size_t)arg_out.extent(7), (size_t)arg_in.extent(7))) {
1326  using Policy = Kokkos::RangePolicy<ExecSpace>;
1327 
1328  Kokkos::parallel_for("Kokkos::DynRankViewRemap", Policy(0, n0), *this);
1329  }
1330 
1331  KOKKOS_INLINE_FUNCTION
1332  void operator()(const size_t i0) const {
1333  for (size_t i1 = 0; i1 < n1; ++i1) {
1334  for (size_t i2 = 0; i2 < n2; ++i2) {
1335  for (size_t i3 = 0; i3 < n3; ++i3) {
1336  for (size_t i4 = 0; i4 < n4; ++i4) {
1337  for (size_t i5 = 0; i5 < n5; ++i5) {
1338  for (size_t i6 = 0; i6 < n6; ++i6) {
1339  output.access(i0, i1, i2, i3, i4, i5, i6) =
1340  input.access(i0, i1, i2, i3, i4, i5, i6);
1341  }
1342  }
1343  }
1344  }
1345  }
1346  }
1347  }
1348 };
1349 
1350 } /* namespace Impl */
1351 } /* namespace Kokkos */
1352 
1353 namespace Kokkos {
1354 
1355 namespace Impl {
1356 
1357 /* \brief Returns a View of the requested rank, aliasing the
1358  underlying memory, to facilitate implementation of deep_copy() and
1359  other routines that are defined on View */
1360 template <unsigned N, typename T, typename... Args>
1361 KOKKOS_FUNCTION View<typename ViewDataTypeFromRank<T, N>::type, Args...>
1362 as_view_of_rank_n(
1363  DynRankView<T, Args...> v,
1364  std::enable_if_t<
1365  std::is_same_v<typename ViewTraits<T, Args...>::specialize, void>>*) {
1366  if (v.rank() != N) {
1367  KOKKOS_IF_ON_HOST(
1368  const std::string message =
1369  "Converting DynRankView of rank " + std::to_string(v.rank()) +
1370  " to a View of mis-matched rank " + std::to_string(N) + "!";
1371  Kokkos::abort(message.c_str());)
1372  KOKKOS_IF_ON_DEVICE(
1373  Kokkos::abort("Converting DynRankView to a View of mis-matched rank!");)
1374  }
1375 
1376  auto layout = v.DownCast().layout();
1377 
1378  if constexpr (std::is_same_v<decltype(layout), Kokkos::LayoutLeft> ||
1379  std::is_same_v<decltype(layout), Kokkos::LayoutRight> ||
1380  std::is_same_v<decltype(layout), Kokkos::LayoutStride>) {
1381  for (int i = N; i < 7; ++i)
1382  layout.dimension[i] = KOKKOS_IMPL_CTOR_DEFAULT_ARG;
1383  }
1384 
1385 #ifndef KOKKOS_ENABLE_IMPL_VIEW_LEGACY
1386  if constexpr (ViewTraits<T, Args...>::impl_is_customized) {
1387  return View<typename RankDataType<T, N>::type, Args...>(
1388  Kokkos::view_wrap(
1389  v.data(), Kokkos::Impl::AccessorArg_t{v.accessor().fad_size() + 1}),
1390  layout);
1391  } else
1392 #endif
1393  return View<typename RankDataType<T, N>::type, Args...>(v.data(), layout);
1394 }
1395 
1396 template <typename... Args>
1397 struct ApplyToViewOfStaticRank<DynRankView<Args...>> {
1398  template <typename Function>
1399  static void apply(Function&& f, DynRankView<Args...> a) {
1400  switch (rank(a)) {
1401  case 0: f(as_view_of_rank_n<0>(a)); break;
1402  case 1: f(as_view_of_rank_n<1>(a)); break;
1403  case 2: f(as_view_of_rank_n<2>(a)); break;
1404  case 3: f(as_view_of_rank_n<3>(a)); break;
1405  case 4: f(as_view_of_rank_n<4>(a)); break;
1406  case 5: f(as_view_of_rank_n<5>(a)); break;
1407  case 6: f(as_view_of_rank_n<6>(a)); break;
1408  case 7: f(as_view_of_rank_n<7>(a)); break;
1409  default:
1410  KOKKOS_IF_ON_HOST(
1411  Kokkos::abort(
1412  std::string(
1413  "Trying to apply a function to a view of unexpected rank " +
1414  std::to_string(rank(a)))
1415  .c_str());)
1416  KOKKOS_IF_ON_DEVICE(
1417  Kokkos::abort(
1418  "Trying to apply a function to a view of unexpected rank");)
1419  }
1420  }
1421 };
1422 
1423 } // namespace Impl
1424 
1426 template <class ExecSpace, class DT, class... DP>
1427 inline void deep_copy(
1428  const ExecSpace& e, const DynRankView<DT, DP...>& dst,
1429  typename ViewTraits<DT, DP...>::const_value_type& value,
1430  std::enable_if_t<std::is_same_v<typename ViewTraits<DT, DP...>::specialize,
1431  void>>* = nullptr) {
1432  static_assert(
1433  std::is_same_v<typename ViewTraits<DT, DP...>::non_const_value_type,
1434  typename ViewTraits<DT, DP...>::value_type>,
1435  "deep_copy requires non-const type");
1436 
1437  Impl::ApplyToViewOfStaticRank<DynRankView<DT, DP...>>::apply(
1438  [=](auto view) { deep_copy(e, view, value); }, dst);
1439 }
1440 
1441 template <class DT, class... DP>
1442 inline void deep_copy(
1443  const DynRankView<DT, DP...>& dst,
1444  typename ViewTraits<DT, DP...>::const_value_type& value,
1445  std::enable_if_t<std::is_same_v<typename ViewTraits<DT, DP...>::specialize,
1446  void>>* = nullptr) {
1447  Impl::ApplyToViewOfStaticRank<DynRankView<DT, DP...>>::apply(
1448  [=](auto view) { deep_copy(view, value); }, dst);
1449 }
1450 
1452 template <class ExecSpace, class ST, class... SP>
1453 inline void deep_copy(
1454  const ExecSpace& e,
1455  typename ViewTraits<ST, SP...>::non_const_value_type& dst,
1456  const DynRankView<ST, SP...>& src,
1457  std::enable_if_t<std::is_same_v<typename ViewTraits<ST, SP...>::specialize,
1458  void>>* = 0) {
1459  deep_copy(e, dst, Impl::as_view_of_rank_n<0>(src));
1460 }
1461 
1462 template <class ST, class... SP>
1463 inline void deep_copy(
1464  typename ViewTraits<ST, SP...>::non_const_value_type& dst,
1465  const DynRankView<ST, SP...>& src,
1466  std::enable_if_t<std::is_same_v<typename ViewTraits<ST, SP...>::specialize,
1467  void>>* = 0) {
1468  deep_copy(dst, Impl::as_view_of_rank_n<0>(src));
1469 }
1470 
1471 //----------------------------------------------------------------------------
1477 template <class ExecSpace, class DstType, class SrcType>
1478 inline void deep_copy(
1479  const ExecSpace& exec_space, const DstType& dst, const SrcType& src,
1480  std::enable_if_t<(std::is_void_v<typename DstType::traits::specialize> &&
1481  std::is_void_v<typename SrcType::traits::specialize> &&
1482  (Kokkos::is_dyn_rank_view<DstType>::value ||
1483  Kokkos::is_dyn_rank_view<SrcType>::value))>* = nullptr) {
1484  static_assert(std::is_same_v<typename DstType::traits::value_type,
1485  typename DstType::traits::non_const_value_type>,
1486  "deep_copy requires non-const destination type");
1487 
1488  switch (rank(dst)) {
1489  case 0:
1490  deep_copy(exec_space, Impl::as_view_of_rank_n<0>(dst),
1491  Impl::as_view_of_rank_n<0>(src));
1492  break;
1493  case 1:
1494  deep_copy(exec_space, Impl::as_view_of_rank_n<1>(dst),
1495  Impl::as_view_of_rank_n<1>(src));
1496  break;
1497  case 2:
1498  deep_copy(exec_space, Impl::as_view_of_rank_n<2>(dst),
1499  Impl::as_view_of_rank_n<2>(src));
1500  break;
1501  case 3:
1502  deep_copy(exec_space, Impl::as_view_of_rank_n<3>(dst),
1503  Impl::as_view_of_rank_n<3>(src));
1504  break;
1505  case 4:
1506  deep_copy(exec_space, Impl::as_view_of_rank_n<4>(dst),
1507  Impl::as_view_of_rank_n<4>(src));
1508  break;
1509  case 5:
1510  deep_copy(exec_space, Impl::as_view_of_rank_n<5>(dst),
1511  Impl::as_view_of_rank_n<5>(src));
1512  break;
1513  case 6:
1514  deep_copy(exec_space, Impl::as_view_of_rank_n<6>(dst),
1515  Impl::as_view_of_rank_n<6>(src));
1516  break;
1517  case 7:
1518  deep_copy(exec_space, Impl::as_view_of_rank_n<7>(dst),
1519  Impl::as_view_of_rank_n<7>(src));
1520  break;
1521  default:
1522  Kokkos::Impl::throw_runtime_exception(
1523  "Calling DynRankView deep_copy with a view of unexpected rank " +
1524  std::to_string(rank(dst)));
1525  }
1526 }
1527 
1528 template <class DstType, class SrcType>
1529 inline void deep_copy(
1530  const DstType& dst, const SrcType& src,
1531  std::enable_if_t<(std::is_void_v<typename DstType::traits::specialize> &&
1532  std::is_void_v<typename SrcType::traits::specialize> &&
1533  (Kokkos::is_dyn_rank_view<DstType>::value ||
1534  Kokkos::is_dyn_rank_view<SrcType>::value))>* = nullptr) {
1535  static_assert(std::is_same_v<typename DstType::traits::value_type,
1536  typename DstType::traits::non_const_value_type>,
1537  "deep_copy requires non-const destination type");
1538 
1539  switch (rank(dst)) {
1540  case 0:
1541  deep_copy(Impl::as_view_of_rank_n<0>(dst),
1542  Impl::as_view_of_rank_n<0>(src));
1543  break;
1544  case 1:
1545  deep_copy(Impl::as_view_of_rank_n<1>(dst),
1546  Impl::as_view_of_rank_n<1>(src));
1547  break;
1548  case 2:
1549  deep_copy(Impl::as_view_of_rank_n<2>(dst),
1550  Impl::as_view_of_rank_n<2>(src));
1551  break;
1552  case 3:
1553  deep_copy(Impl::as_view_of_rank_n<3>(dst),
1554  Impl::as_view_of_rank_n<3>(src));
1555  break;
1556  case 4:
1557  deep_copy(Impl::as_view_of_rank_n<4>(dst),
1558  Impl::as_view_of_rank_n<4>(src));
1559  break;
1560  case 5:
1561  deep_copy(Impl::as_view_of_rank_n<5>(dst),
1562  Impl::as_view_of_rank_n<5>(src));
1563  break;
1564  case 6:
1565  deep_copy(Impl::as_view_of_rank_n<6>(dst),
1566  Impl::as_view_of_rank_n<6>(src));
1567  break;
1568  case 7:
1569  deep_copy(Impl::as_view_of_rank_n<7>(dst),
1570  Impl::as_view_of_rank_n<7>(src));
1571  break;
1572  default:
1573  Kokkos::Impl::throw_runtime_exception(
1574  "Calling DynRankView deep_copy with a view of unexpected rank " +
1575  std::to_string(rank(dst)));
1576  }
1577 }
1578 
1579 } // namespace Kokkos
1580 
1581 //----------------------------------------------------------------------------
1582 //----------------------------------------------------------------------------
1583 
1584 namespace Kokkos {
1585 namespace Impl {
1586 
1587 // Deduce Mirror Types
1588 template <class Space, class T, class... P>
1589 struct MirrorDRViewType {
1590  // The incoming view_type
1591  using src_view_type = typename Kokkos::DynRankView<T, P...>;
1592  // The memory space for the mirror view
1593  using memory_space = typename Space::memory_space;
1594  // Check whether it is the same memory space
1595  enum {
1596  is_same_memspace =
1597  std::is_same_v<memory_space, typename src_view_type::memory_space>
1598  };
1599  // The array_layout
1600  using array_layout = typename src_view_type::array_layout;
1601  // The data type (we probably want it non-const since otherwise we can't even
1602  // deep_copy to it.
1603  using data_type = typename src_view_type::non_const_data_type;
1604  // The destination view type if it is not the same memory space
1605  using dest_view_type = Kokkos::DynRankView<data_type, array_layout, Space>;
1606  // If it is the same memory_space return the existsing view_type
1607  // This will also keep the unmanaged trait if necessary
1608  using view_type =
1609  std::conditional_t<is_same_memspace, src_view_type, dest_view_type>;
1610 };
1611 
1612 } // namespace Impl
1613 
1614 namespace Impl {
1615 
1616 // create a mirror
1617 // private interface that accepts arbitrary view constructor args passed by a
1618 // view_alloc
1619 template <class T, class... P, class... ViewCtorArgs>
1620 inline auto create_mirror(const DynRankView<T, P...>& src,
1621  const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop) {
1622  check_view_ctor_args_create_mirror<ViewCtorArgs...>();
1623 
1624  auto prop_copy = Impl::with_properties_if_unset(
1625  arg_prop, std::string(src.label()).append("_mirror"));
1626 
1627  if constexpr (Impl::ViewCtorProp<ViewCtorArgs...>::has_memory_space) {
1628  using dst_type = typename Impl::MirrorDRViewType<
1629  typename Impl::ViewCtorProp<ViewCtorArgs...>::memory_space, T,
1630  P...>::dest_view_type;
1631  return dst_type(prop_copy,
1632  Impl::reconstructLayout(src.layout(), src.rank()));
1633  } else {
1634  using src_type = DynRankView<T, P...>;
1635  using dst_type = typename src_type::HostMirror;
1636 
1637  return dst_type(prop_copy,
1638  Impl::reconstructLayout(src.layout(), src.rank()));
1639  }
1640 #if defined(KOKKOS_COMPILER_NVCC) && KOKKOS_COMPILER_NVCC >= 1130 && \
1641  !defined(KOKKOS_COMPILER_MSVC)
1642  __builtin_unreachable();
1643 #endif
1644 }
1645 
1646 } // namespace Impl
1647 
1648 // public interface
1649 template <class T, class... P,
1650  class Enable = std::enable_if_t<
1651  std::is_void_v<typename ViewTraits<T, P...>::specialize>>>
1652 inline auto create_mirror(const DynRankView<T, P...>& src) {
1653  return Impl::create_mirror(src, Kokkos::view_alloc());
1654 }
1655 
1656 // public interface that accepts a without initializing flag
1657 template <class T, class... P,
1658  class Enable = std::enable_if_t<
1659  std::is_void_v<typename ViewTraits<T, P...>::specialize>>>
1660 inline auto create_mirror(Kokkos::Impl::WithoutInitializing_t wi,
1661  const DynRankView<T, P...>& src) {
1662  return Impl::create_mirror(src, Kokkos::view_alloc(wi));
1663 }
1664 
1665 // public interface that accepts a space
1666 template <class Space, class T, class... P,
1667  class Enable = std::enable_if_t<
1668  Kokkos::is_space<Space>::value &&
1669  std::is_void_v<typename ViewTraits<T, P...>::specialize>>>
1670 inline auto create_mirror(const Space&,
1671  const Kokkos::DynRankView<T, P...>& src) {
1672  return Impl::create_mirror(
1673  src, Kokkos::view_alloc(typename Space::memory_space{}));
1674 }
1675 
1676 // public interface that accepts a space and a without initializing flag
1677 template <class Space, class T, class... P,
1678  class Enable = std::enable_if_t<
1679  Kokkos::is_space<Space>::value &&
1680  std::is_void_v<typename ViewTraits<T, P...>::specialize>>>
1681 inline auto create_mirror(Kokkos::Impl::WithoutInitializing_t wi, const Space&,
1682  const Kokkos::DynRankView<T, P...>& src) {
1683  return Impl::create_mirror(
1684  src, Kokkos::view_alloc(wi, typename Space::memory_space{}));
1685 }
1686 
1687 // public interface that accepts arbitrary view constructor args passed by a
1688 // view_alloc
1689 template <class T, class... P, class... ViewCtorArgs,
1690  typename Enable = std::enable_if_t<
1691  std::is_void_v<typename ViewTraits<T, P...>::specialize>>>
1692 inline auto create_mirror(const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
1693  const DynRankView<T, P...>& src) {
1694  return Impl::create_mirror(src, arg_prop);
1695 }
1696 
1697 namespace Impl {
1698 
1699 // create a mirror view
1700 // private interface that accepts arbitrary view constructor args passed by a
1701 // view_alloc
1702 template <class T, class... P, class... ViewCtorArgs>
1703 inline auto create_mirror_view(
1704  const DynRankView<T, P...>& src,
1705  [[maybe_unused]] const typename Impl::ViewCtorProp<ViewCtorArgs...>&
1706  arg_prop) {
1707  if constexpr (!Impl::ViewCtorProp<ViewCtorArgs...>::has_memory_space) {
1708  if constexpr (std::is_same_v<typename DynRankView<T, P...>::memory_space,
1709  typename DynRankView<
1710  T, P...>::HostMirror::memory_space> &&
1711  std::is_same_v<
1712  typename DynRankView<T, P...>::data_type,
1713  typename DynRankView<T, P...>::HostMirror::data_type>) {
1714  return typename DynRankView<T, P...>::HostMirror(src);
1715  } else {
1716  return Kokkos::Impl::choose_create_mirror(src, arg_prop);
1717  }
1718  } else {
1719  if constexpr (Impl::MirrorDRViewType<typename Impl::ViewCtorProp<
1720  ViewCtorArgs...>::memory_space,
1721  T, P...>::is_same_memspace) {
1722  return typename Impl::MirrorDRViewType<
1723  typename Impl::ViewCtorProp<ViewCtorArgs...>::memory_space, T,
1724  P...>::view_type(src);
1725  } else {
1726  return Kokkos::Impl::choose_create_mirror(src, arg_prop);
1727  }
1728  }
1729 #if defined(KOKKOS_COMPILER_NVCC) && KOKKOS_COMPILER_NVCC >= 1130 && \
1730  !defined(KOKKOS_COMPILER_MSVC)
1731  __builtin_unreachable();
1732 #endif
1733 }
1734 
1735 } // namespace Impl
1736 
1737 // public interface
1738 template <class T, class... P>
1739 inline auto create_mirror_view(const Kokkos::DynRankView<T, P...>& src) {
1740  return Impl::create_mirror_view(src, Kokkos::view_alloc());
1741 }
1742 
1743 // public interface that accepts a without initializing flag
1744 template <class T, class... P>
1745 inline auto create_mirror_view(Kokkos::Impl::WithoutInitializing_t wi,
1746  const DynRankView<T, P...>& src) {
1747  return Impl::create_mirror_view(src, Kokkos::view_alloc(wi));
1748 }
1749 
1750 // public interface that accepts a space
1751 template <class Space, class T, class... P,
1752  class Enable = std::enable_if_t<Kokkos::is_space<Space>::value>>
1753 inline auto create_mirror_view(const Space&,
1754  const Kokkos::DynRankView<T, P...>& src) {
1755  return Impl::create_mirror_view(
1756  src, Kokkos::view_alloc(typename Space::memory_space()));
1757 }
1758 
1759 // public interface that accepts a space and a without initializing flag
1760 template <class Space, class T, class... P,
1761  typename Enable = std::enable_if_t<Kokkos::is_space<Space>::value>>
1762 inline auto create_mirror_view(Kokkos::Impl::WithoutInitializing_t wi,
1763  const Space&,
1764  const Kokkos::DynRankView<T, P...>& src) {
1765  return Impl::create_mirror_view(
1766  src, Kokkos::view_alloc(typename Space::memory_space{}, wi));
1767 }
1768 
1769 // public interface that accepts arbitrary view constructor args passed by a
1770 // view_alloc
1771 template <class T, class... P, class... ViewCtorArgs>
1772 inline auto create_mirror_view(
1773  const typename Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
1774  const Kokkos::DynRankView<T, P...>& src) {
1775  return Impl::create_mirror_view(src, arg_prop);
1776 }
1777 
1778 // create a mirror view and deep copy it
1779 // public interface that accepts arbitrary view constructor args passed by a
1780 // view_alloc
1781 template <class... ViewCtorArgs, class T, class... P,
1782  class Enable = std::enable_if_t<
1783  std::is_void_v<typename ViewTraits<T, P...>::specialize>>>
1784 auto create_mirror_view_and_copy(
1785  [[maybe_unused]] const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
1786  const Kokkos::DynRankView<T, P...>& src) {
1787  using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
1788 
1789  Impl::check_view_ctor_args_create_mirror_view_and_copy<ViewCtorArgs...>();
1790 
1791  if constexpr (Impl::MirrorDRViewType<
1792  typename Impl::ViewCtorProp<ViewCtorArgs...>::memory_space,
1793  T, P...>::is_same_memspace) {
1794  // same behavior as deep_copy(src, src)
1795  if constexpr (!alloc_prop_input::has_execution_space)
1796  fence(
1797  "Kokkos::create_mirror_view_and_copy: fence before returning src "
1798  "view");
1799  return src;
1800  } else {
1801  using Space = typename alloc_prop_input::memory_space;
1802  using Mirror = typename Impl::MirrorDRViewType<Space, T, P...>::view_type;
1803 
1804  auto arg_prop_copy = Impl::with_properties_if_unset(
1805  arg_prop, std::string{}, WithoutInitializing,
1806  typename Space::execution_space{});
1807 
1808  std::string& label = Impl::get_property<Impl::LabelTag>(arg_prop_copy);
1809  if (label.empty()) label = src.label();
1810  auto mirror = typename Mirror::non_const_type{
1811  arg_prop_copy, Impl::reconstructLayout(src.layout(), src.rank())};
1812  if constexpr (alloc_prop_input::has_execution_space) {
1813  deep_copy(Impl::get_property<Impl::ExecutionSpaceTag>(arg_prop_copy),
1814  mirror, src);
1815  } else
1816  deep_copy(mirror, src);
1817  return mirror;
1818  }
1819 #if defined(KOKKOS_COMPILER_NVCC) && KOKKOS_COMPILER_NVCC >= 1130 && \
1820  !defined(KOKKOS_COMPILER_MSVC)
1821  __builtin_unreachable();
1822 #endif
1823 }
1824 
1825 template <class Space, class T, class... P>
1826 auto create_mirror_view_and_copy(const Space&,
1827  const Kokkos::DynRankView<T, P...>& src,
1828  std::string const& name = "") {
1829  return create_mirror_view_and_copy(
1830  Kokkos::view_alloc(typename Space::memory_space{}, name), src);
1831 }
1832 
1833 } // namespace Kokkos
1834 
1835 //----------------------------------------------------------------------------
1836 //----------------------------------------------------------------------------
1837 
1838 namespace Kokkos {
1841 template <class... ViewCtorArgs, class T, class... P>
1842 inline void impl_resize(const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
1843  DynRankView<T, P...>& v, const size_t n0,
1844  const size_t n1, const size_t n2, const size_t n3,
1845  const size_t n4, const size_t n5, const size_t n6,
1846  const size_t n7) {
1847  using drview_type = DynRankView<T, P...>;
1848  using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
1849 
1850  static_assert(Kokkos::ViewTraits<T, P...>::is_managed,
1851  "Can only resize managed views");
1852  static_assert(!alloc_prop_input::has_label,
1853  "The view constructor arguments passed to Kokkos::resize "
1854  "must not include a label!");
1855  static_assert(!alloc_prop_input::has_pointer,
1856  "The view constructor arguments passed to Kokkos::resize must "
1857  "not include a pointer!");
1858  static_assert(!alloc_prop_input::has_memory_space,
1859  "The view constructor arguments passed to Kokkos::resize must "
1860  "not include a memory space instance!");
1861 
1862  auto prop_copy = Impl::with_properties_if_unset(
1863  arg_prop, v.label(), typename drview_type::execution_space{});
1864 
1865  drview_type v_resized(prop_copy, n0, n1, n2, n3, n4, n5, n6, n7);
1866 
1867  if constexpr (alloc_prop_input::has_execution_space)
1868  Kokkos::Impl::DynRankViewRemap<drview_type, drview_type>(
1869  Impl::get_property<Impl::ExecutionSpaceTag>(prop_copy), v_resized, v);
1870  else {
1871  // NOLINTNEXTLINE(bugprone-unused-raii)
1872  Kokkos::Impl::DynRankViewRemap<drview_type, drview_type>(v_resized, v);
1873  Kokkos::fence("Kokkos::resize(DynRankView)");
1874  }
1875  v = v_resized;
1876 }
1877 
1878 template <class T, class... P>
1879 inline void resize(DynRankView<T, P...>& v,
1880  const size_t n0 = KOKKOS_INVALID_INDEX,
1881  const size_t n1 = KOKKOS_INVALID_INDEX,
1882  const size_t n2 = KOKKOS_INVALID_INDEX,
1883  const size_t n3 = KOKKOS_INVALID_INDEX,
1884  const size_t n4 = KOKKOS_INVALID_INDEX,
1885  const size_t n5 = KOKKOS_INVALID_INDEX,
1886  const size_t n6 = KOKKOS_INVALID_INDEX,
1887  const size_t n7 = KOKKOS_INVALID_INDEX) {
1888  impl_resize(Impl::ViewCtorProp<>{}, v, n0, n1, n2, n3, n4, n5, n6, n7);
1889 }
1890 
1891 template <class... ViewCtorArgs, class T, class... P>
1892 void resize(const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
1893  DynRankView<T, P...>& v,
1894  const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1895  const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1896  const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1897  const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1898  const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1899  const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1900  const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
1901  const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
1902  impl_resize(arg_prop, v, n0, n1, n2, n3, n4, n5, n6, n7);
1903 }
1904 
1905 template <class I, class T, class... P>
1906 inline std::enable_if_t<Impl::is_view_ctor_property<I>::value> resize(
1907  const I& arg_prop, DynRankView<T, P...>& v,
1908  const size_t n0 = KOKKOS_INVALID_INDEX,
1909  const size_t n1 = KOKKOS_INVALID_INDEX,
1910  const size_t n2 = KOKKOS_INVALID_INDEX,
1911  const size_t n3 = KOKKOS_INVALID_INDEX,
1912  const size_t n4 = KOKKOS_INVALID_INDEX,
1913  const size_t n5 = KOKKOS_INVALID_INDEX,
1914  const size_t n6 = KOKKOS_INVALID_INDEX,
1915  const size_t n7 = KOKKOS_INVALID_INDEX) {
1916  impl_resize(Kokkos::view_alloc(arg_prop), v, n0, n1, n2, n3, n4, n5, n6, n7);
1917 }
1918 
1921 template <class... ViewCtorArgs, class T, class... P>
1922 inline void impl_realloc(DynRankView<T, P...>& v, const size_t n0,
1923  const size_t n1, const size_t n2, const size_t n3,
1924  const size_t n4, const size_t n5, const size_t n6,
1925  const size_t n7,
1926  const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop) {
1927  using drview_type = DynRankView<T, P...>;
1928  using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
1929 
1930  static_assert(Kokkos::ViewTraits<T, P...>::is_managed,
1931  "Can only realloc managed views");
1932  static_assert(!alloc_prop_input::has_label,
1933  "The view constructor arguments passed to Kokkos::realloc must "
1934  "not include a label!");
1935  static_assert(!alloc_prop_input::has_pointer,
1936  "The view constructor arguments passed to Kokkos::realloc must "
1937  "not include a pointer!");
1938  static_assert(!alloc_prop_input::has_memory_space,
1939  "The view constructor arguments passed to Kokkos::realloc must "
1940  "not include a memory space instance!");
1941 
1942  auto arg_prop_copy = Impl::with_properties_if_unset(arg_prop, v.label());
1943 
1944  v = drview_type(); // Deallocate first, if the only view to allocation
1945  v = drview_type(arg_prop_copy, n0, n1, n2, n3, n4, n5, n6, n7);
1946 }
1947 
1948 template <class T, class... P, class... ViewCtorArgs>
1949 inline void realloc(const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
1950  DynRankView<T, P...>& v,
1951  const size_t n0 = KOKKOS_INVALID_INDEX,
1952  const size_t n1 = KOKKOS_INVALID_INDEX,
1953  const size_t n2 = KOKKOS_INVALID_INDEX,
1954  const size_t n3 = KOKKOS_INVALID_INDEX,
1955  const size_t n4 = KOKKOS_INVALID_INDEX,
1956  const size_t n5 = KOKKOS_INVALID_INDEX,
1957  const size_t n6 = KOKKOS_INVALID_INDEX,
1958  const size_t n7 = KOKKOS_INVALID_INDEX) {
1959  impl_realloc(v, n0, n1, n2, n3, n4, n5, n6, n7, arg_prop);
1960 }
1961 
1962 template <class T, class... P>
1963 inline void realloc(DynRankView<T, P...>& v,
1964  const size_t n0 = KOKKOS_INVALID_INDEX,
1965  const size_t n1 = KOKKOS_INVALID_INDEX,
1966  const size_t n2 = KOKKOS_INVALID_INDEX,
1967  const size_t n3 = KOKKOS_INVALID_INDEX,
1968  const size_t n4 = KOKKOS_INVALID_INDEX,
1969  const size_t n5 = KOKKOS_INVALID_INDEX,
1970  const size_t n6 = KOKKOS_INVALID_INDEX,
1971  const size_t n7 = KOKKOS_INVALID_INDEX) {
1972  impl_realloc(v, n0, n1, n2, n3, n4, n5, n6, n7, Impl::ViewCtorProp<>{});
1973 }
1974 
1975 template <class I, class T, class... P>
1976 inline std::enable_if_t<Impl::is_view_ctor_property<I>::value> realloc(
1977  const I& arg_prop, DynRankView<T, P...>& v,
1978  const size_t n0 = KOKKOS_INVALID_INDEX,
1979  const size_t n1 = KOKKOS_INVALID_INDEX,
1980  const size_t n2 = KOKKOS_INVALID_INDEX,
1981  const size_t n3 = KOKKOS_INVALID_INDEX,
1982  const size_t n4 = KOKKOS_INVALID_INDEX,
1983  const size_t n5 = KOKKOS_INVALID_INDEX,
1984  const size_t n6 = KOKKOS_INVALID_INDEX,
1985  const size_t n7 = KOKKOS_INVALID_INDEX) {
1986  impl_realloc(v, n0, n1, n2, n3, n4, n5, n6, n7, Kokkos::view_alloc(arg_prop));
1987 }
1988 
1989 namespace Experimental {
1990 template <class T, class... P>
1991 struct python_view_type<DynRankView<T, P...>> {
1992  using type = Kokkos::Impl::python_view_type_impl_t<
1993  typename DynRankView<T, P...>::array_type>;
1994 };
1995 } // namespace Experimental
1996 
1997 } // namespace Kokkos
1998 
1999 #ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_DYNRANKVIEW
2000 #undef KOKKOS_IMPL_PUBLIC_INCLUDE
2001 #undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_DYNRANKVIEW
2002 #endif
2003 #endif
Memory layout tag indicating left-to-right (Fortran scheme) striding of multi-indices.
KOKKOS_INLINE_FUNCTION bool dyn_rank_view_verify_operator_bounds(const iType0 &, const MapType &)
Debug bounds-checking routines.
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...
Assign compatible default mappings.
Execution policy for work over a range of an integral type.