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